{"owner":"acacode","repo":"swagger-typescript-api","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["CLAUDE.md"],"files":{"CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nswagger-typescript-api generates TypeScript API clients (Fetch or Axios) from OpenAPI 2.0/3.0 specifications. It works as both a CLI tool (`sta generate` / `swagger-typescript-api generate`) and a library (`generateApi()`). The package outputs dual ESM/CJS formats.\n\n## Common Commands\n\n```bash\nbun install --frozen-lockfile                   # Install dependencies\nbun run build                                   # Build with tsdown (dist/index.mjs, dist/index.cjs, dist/cli.mjs, dist/cli.cjs)\nbun run test                                    # Run all tests (vitest, 30s timeout)\nbun run test -- tests/simple.test.ts            # Run a specific test file\nbun run test -- tests/spec/axios/basic.test.ts  # Run a single spec test\nbun run test -- -t \"axios\"                      # Run tests matching a name pattern\nbun run test -- --update                        # Update snapshots\nbun run lint                                    # Lint with biome check\nbun run format                                  # Format with biome format --write\nbun run format:check                            # Check formatting\n```\n\n## Architecture\n\n### Code Generation Pipeline (CodeGenProcess.start)\n\n1. **Template resolution** — `TemplatesWorker` loads templates from `templates/base/`, `templates/default/` (or `templates/modular/`), and optional custom templates. Priority: custom > base > original.\n2. **Schema fetching** — `SwaggerSchemaResolver` loads specs from file/URL/inline, supports JSON and YAML.\n3. **Swagger 2→3 conversion** — Swagger 2.0 specs are converted to OpenAPI 3.0 via `swagger2openapi`.\n4. **Component registration** — `SchemaComponentsMap` registers all `#/components/schemas/*` entries with discriminators and enums sorted first.\n5. **Schema parsing** — `SchemaParserFabric` creates type-specific parsers (`MonoSchemaParser` subclasses in `src/schema-parser/base-schema-parsers/` and `complex-schema-parsers/`). Each parser handles one type: enum, object, array, primitive, discriminator, oneOf, anyOf, allOf, not.\n6. **Route parsing** — `SchemaRoutes` (`src/schema-routes/schema-routes.ts`) walks all paths/methods to create `ParsedRoute` objects with request/response types, parameters, and module grouping.\n7. **Template rendering** — Eta engine renders `.ejs` templates. Templates use `includeFile()` with path prefixes (`@base/`, `@default/`, `@modular/`, `@custom/`).\n8. **Formatting** — `CodeFormatter` removes unused imports via TypeScript LanguageService, then formats with Biome.\n9. **Optional JS translation** — `JavascriptTranslator` compiles TS output to JS + `.d.ts` using the TypeScript compiler API.\n\n### Key Entry Points\n\n- `index.ts` (root) — CLI entry point using citty\n- `src/index.ts` — Library entry, exports `generateApi()`, `generateTemplates()`, constants\n- `src/code-gen-process.ts` — Main orchestrator class\n- `src/configuration.ts` — `CodeGenConfig` with all options and `Ts` code generation constructs\n- `types/index.ts` — All public TypeScript type definitions\n\n### Extension Points\n\n- **13 lifecycle hooks** — `onInit`, `onCreateComponent`, `onPreParseSchema`, `onParseSchema`, `onCreateRoute`, `onPrepareConfig`, `onFormatTypeName`, `onFormatRouteName`, `onCreateRouteName`, `onCreateRequestParams`, `onPreBuildRoutePath`, `onBuildRoutePath`, `onInsertPathParam`\n- **Custom schema parsers** — Override via `config.schemaParsers` with `MonoSchemaParser` subclasses\n- **Custom templates** — User-provided templates override by matching filename\n- **Code generation constructs** — `codeGenConstructs` option overrides TS primitives (`ArrayType`, `UnionType`, `IntersectionType`, `RecordType`, etc.)\n- **Patchable instances** — `PATCHABLE_INSTANCES` in `CodeGenProcess` allows cross-instance injection\n\n### Template System\n\nTemplates live in `templates/` with three tiers:\n\n- `base/` — Shared templates (data-contracts, http-client, route-docs, jsdoc)\n- `default/` — Single-file output mode (api.ejs, procedure-call.ejs, route-types.ejs)\n- `modular/` — Multi-file output mode (`--modular` flag, generates separate files per route module)\n\nTemplates receive `it.config`, `it.modelTypes`, `it.routes`, `it.utils` as context variables.\n\n### Test Structure\n\n- `tests/simple.test.ts` — Snapshot tests running all fixture schemas (v2.0 + v3.0) with basic options\n- `tests/extended.test.ts` — Same schemas with all extraction options enabled\n- `tests/spec/{feature}/basic.test.ts` — 44 feature-specific tests, each with its own schema.json and snapshot\n- Tests call `generateApi()`, read output files, and compare against vitest snapshots\n\n## Technical Details\n\n- **Package manager:** Bun\n- **Module system:** ESM (`\"type\": \"module\"`)\n- **Build:** tsdown (esbuild-based, outputs ESM + CJS with `.d.ts`)\n- **Node requirement:** >=20\n- **Linting/Formatting:** Biome (not ESLint/Prettier)\n- **Config file support:** `swagger-typescript-api.config.{ts,js,json}` via c12\n- **CI:** Tests across Node 20, 22, 24, 25; format check → build → test\n\n## Style Guide\n\n### Formatting\n\nBiome handles all formatting. Do not manually adjust formatting — run `bun run format` and accept the result. Key settings (via `.editorconfig`): 2-space indentation, LF line endings, UTF-8 encoding.\n\n### Imports\n\n- Use `import type` for type-only imports. Keep type imports separate from value imports.\n- Use namespace imports (`import * as`) for Node.js built-in modules.\n- Use named imports for specific utilities from libraries.\n- All relative imports must include the `.js` extension (ESM requirement, even for `.ts` source files).\n- Order: Node builtins first, then external packages, then internal modules. Biome enforces this.\n\n```typescript\nimport * as fs from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { compact, merge } from \"es-toolkit\";\nimport type { GenerateApiConfiguration } from \"../types/index.js\";\nimport { CodeFormatter } from \"./code-formatter.js\";\n```\n\n### Utilities\n\n- Use `es-toolkit` (and `es-toolkit/compat`) instead of lodash. The `createLodashCompat()` function exists only for backwards compatibility in templates — do not use it in source code.\n- Use `consola` for all logging (`consola.info`, `consola.debug`, `consola.warn`, `consola.success`). Do not use `console.log`.\n\n### Comments\n\n- Avoid comments that restate the type signature or function name. A comment like `/** Returns the schema */` on `getSchema()` adds no value.\n- Use comments to explain _why_, not _what_. If the code is doing something non-obvious or working around a known issue, explain the reasoning.\n- When documentation seems redundant with the type signature, it is still acceptable in broadly-used public API surfaces.\n\n### Defensive Practices\n\n- Prefer `unknown` over `any`. Use `any` only when interfacing with untyped external APIs where `unknown` would require excessive casting.\n- Avoid `@ts-ignore` — use `@ts-expect-error` with the specific error code instead, so the suppression breaks when the underlying issue is fixed.\n- Avoid catch-all pattern matches. Prefer exhaustive handling to enable compiler warnings when new variants are added.\n- Use labeled arguments (object parameters) for functions with multiple parameters of the same type to prevent argument transposition.\n- Annotate the types of ignored return values to catch signature changes at compile time.\n\n## Commit Messages\n\nDo **not** use Conventional Commits format (e.g., `feat:`, `fix:`, `chore:`).\n\n- Use imperative mood: \"Add feature\" not \"Added feature\" or \"Adds feature\"\n- Focus on **what** changed, not implementation details\n- Keep the subject line under 72 characters\n- Do not start with \"This commit...\" or \"I changed...\"\n\nGood: `Add retry logic for failed API calls`\nBad: `feat: add retry logic`\n\n## Pull Requests\n\nPR titles follow the same rules as commit messages (no Conventional Commits, imperative mood).\n\nPR descriptions should be detailed enough that a reader can understand the change without external context. Include:\n\n- **Problem**: Define the issue clearly. Describe symptoms (errors, crashes, performance degradation) that justify the change.\n- **Solution**: Explain the approach taken and why it was chosen over alternatives.\n- **Verification**: How to test the change. Include specific steps or evidence (screenshots, metrics).\n- **Performance claims**: Back up with concrete numbers (before/after benchmarks).\n\nKeep descriptions self-contained. When linking to issues or discussions, summarize the relevant points rather than relying on the reader to follow links.\n\n### Reduce reviewer cognitive load\n\n- Break large changes into smaller, focused PRs that each address a single concern.\n- Structure commits to tell a story: each commit should be a logical, reviewable unit.\n- If a PR requires significant context, add inline comments on your own diff to guide the reviewer through complex sections.\n"}}