@minkinad/api-sdk-generator-core 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @minkinad/api-sdk-generator-core
2
2
 
3
3
  Generate a TypeScript fetch SDK from an OpenAPI JSON or YAML document.
4
- Requires Node.js 20 or later. Supports ESM and CommonJS.
4
+ Requires Node.js 20.19 or later. Supports ESM and CommonJS.
5
5
 
6
6
  ```bash
7
7
  npm install @minkinad/api-sdk-generator-core
@@ -18,7 +18,8 @@ console.log(result.operations);
18
18
  ```
19
19
 
20
20
  Use `input: { url: 'https://example.com/openapi.json' }` for remote schemas.
21
- Set `dryRun: true` to get formatted files in `result.files` without writing them.
21
+ Remote schemas have a 30-second deadline; use `schemaTimeoutMs` to customize it
22
+ and `signal` to cancel a download. Set `dryRun: true` to get formatted files in `result.files` without writing them.
22
23
  Set `check: true` to compare with disk; `result.changedFiles` contains missing or
23
24
  outdated files. Check mode does not modify files, even when `clean` is enabled.
24
25
 
package/dist/index.cjs CHANGED
@@ -88,9 +88,6 @@ var OutputWriteError = class extends ApiSdkGeneratorError {
88
88
  }
89
89
  };
90
90
 
91
- // src/generate-sdk.ts
92
- var import_node_path3 = __toESM(require("path"), 1);
93
-
94
91
  // src/formatter.ts
95
92
  var import_prettier = __toESM(require("prettier"), 1);
96
93
  var GENERATED_FORMAT_OPTIONS = {
@@ -637,7 +634,21 @@ function parseSchema(content) {
637
634
  if (parsed.errors.length > 0) {
638
635
  throw new SchemaLoadError(`Invalid JSON or YAML: ${parsed.errors[0].message}`);
639
636
  }
640
- return validateOpenApiDocument(parsed.toJS({ maxAliasCount: 100 }));
637
+ const document = parsed.toJS({ maxAliasCount: 100 });
638
+ rejectAliasCycles(document);
639
+ return validateOpenApiDocument(document);
640
+ }
641
+ function rejectAliasCycles(value, active = /* @__PURE__ */ new WeakSet(), seen = /* @__PURE__ */ new WeakSet()) {
642
+ if (typeof value !== "object" || value === null) return;
643
+ if (active.has(value))
644
+ throw new SchemaLoadError(
645
+ "Cyclic YAML aliases are unsupported. Use OpenAPI $ref for recursive models."
646
+ );
647
+ if (seen.has(value)) return;
648
+ active.add(value);
649
+ for (const child of Object.values(value)) rejectAliasCycles(child, active, seen);
650
+ active.delete(value);
651
+ seen.add(value);
641
652
  }
642
653
  async function loadOpenApiDocument(input, options = {}) {
643
654
  const sources = [input.file, input.url].filter(Boolean);
@@ -647,7 +658,12 @@ async function loadOpenApiDocument(input, options = {}) {
647
658
  if (input.file) {
648
659
  return loadOpenApiDocumentFromFile(input.file, options.logger);
649
660
  }
650
- return loadOpenApiDocumentFromUrl(input.url, options.fetchImplementation, options.logger);
661
+ return loadOpenApiDocumentFromUrl(
662
+ input.url,
663
+ options.fetchImplementation,
664
+ options.logger,
665
+ options
666
+ );
651
667
  }
652
668
  async function loadOpenApiDocumentFromFile(filePath, logger) {
653
669
  try {
@@ -664,14 +680,26 @@ async function loadOpenApiDocumentFromFile(filePath, logger) {
664
680
  );
665
681
  }
666
682
  }
667
- async function loadOpenApiDocumentFromUrl(url, fetchImplementation, logger) {
683
+ async function loadOpenApiDocumentFromUrl(url, fetchImplementation, logger, options = {}) {
668
684
  const runtimeFetch = fetchImplementation ?? globalThis.fetch;
685
+ const timeoutMs = options.timeoutMs ?? 3e4;
686
+ if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2147483647) {
687
+ throw new SchemaLoadError(
688
+ "Schema timeout must be a positive integer no greater than 2147483647 milliseconds."
689
+ );
690
+ }
691
+ const timeoutSignal = AbortSignal.timeout(timeoutMs);
692
+ const signal = options.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal;
669
693
  if (!runtimeFetch) {
670
694
  throw new SchemaLoadError("Fetch API is not available in the current runtime.");
671
695
  }
672
696
  try {
697
+ if (!["http:", "https:"].includes(new URL(url).protocol)) {
698
+ throw new SchemaLoadError("Schema URLs must use HTTP or HTTPS.");
699
+ }
700
+ signal.throwIfAborted();
673
701
  logger?.debug(`Loading OpenAPI schema from URL: ${url}`);
674
- const response = await runtimeFetch(url);
702
+ const response = await runtimeFetch(url, { signal });
675
703
  if (!response.ok) {
676
704
  throw new SchemaLoadError(
677
705
  `Failed to fetch OpenAPI schema from "${url}". HTTP ${response.status}.`
@@ -682,6 +710,12 @@ async function loadOpenApiDocumentFromUrl(url, fetchImplementation, logger) {
682
710
  if (error instanceof ApiSdkGeneratorError) {
683
711
  throw error;
684
712
  }
713
+ if (timeoutSignal.aborted && !options.signal?.aborted) {
714
+ throw new SchemaLoadError(
715
+ `Timed out loading OpenAPI schema after ${timeoutMs} milliseconds.`,
716
+ error
717
+ );
718
+ }
685
719
  throw new SchemaLoadError(`Failed to load OpenAPI schema from URL "${url}".`, error);
686
720
  }
687
721
  }
@@ -938,17 +972,37 @@ function parseDocument(document, options = {}) {
938
972
  };
939
973
  }
940
974
 
941
- // src/writer.ts
975
+ // src/paths.ts
942
976
  var import_promises2 = require("fs/promises");
943
- var import_node_os = __toESM(require("os"), 1);
944
977
  var import_node_path2 = __toESM(require("path"), 1);
978
+ function isWithinDirectory(root, target) {
979
+ const relative = import_node_path2.default.relative(root, target);
980
+ return relative !== ".." && !relative.startsWith(`..${import_node_path2.default.sep}`) && !import_node_path2.default.isAbsolute(relative);
981
+ }
982
+ async function canonicalPath(target) {
983
+ const absolute = import_node_path2.default.resolve(target);
984
+ try {
985
+ return await (0, import_promises2.realpath)(absolute);
986
+ } catch (error) {
987
+ if (error.code !== "ENOENT") throw error;
988
+ const parent = import_node_path2.default.dirname(absolute);
989
+ if (parent === absolute) throw error;
990
+ return import_node_path2.default.join(await canonicalPath(parent), import_node_path2.default.basename(absolute));
991
+ }
992
+ }
993
+
994
+ // src/writer.ts
995
+ var import_node_crypto = require("crypto");
996
+ var import_promises3 = require("fs/promises");
997
+ var import_node_os = __toESM(require("os"), 1);
998
+ var import_node_path3 = __toESM(require("path"), 1);
945
999
  function resolveGeneratedFiles(outputDir, files) {
946
- const outputRoot = import_node_path2.default.resolve(outputDir);
1000
+ const outputRoot = import_node_path3.default.resolve(outputDir);
947
1001
  const seenPaths = /* @__PURE__ */ new Set();
948
1002
  return files.map((file) => {
949
- const fullPath = import_node_path2.default.resolve(outputRoot, file.path);
950
- const relativePath = import_node_path2.default.relative(outputRoot, fullPath);
951
- if (!relativePath || relativePath === ".." || relativePath.startsWith(`..${import_node_path2.default.sep}`) || import_node_path2.default.isAbsolute(relativePath)) {
1003
+ const fullPath = import_node_path3.default.resolve(outputRoot, file.path);
1004
+ const relativePath = import_node_path3.default.relative(outputRoot, fullPath);
1005
+ if (!relativePath || !isWithinDirectory(outputRoot, fullPath)) {
952
1006
  throw new OutputWriteError(
953
1007
  `Generated file path "${file.path}" must stay within the output directory.`
954
1008
  );
@@ -960,26 +1014,51 @@ function resolveGeneratedFiles(outputDir, files) {
960
1014
  return { ...file, fullPath };
961
1015
  });
962
1016
  }
1017
+ async function rejectSymlink(target) {
1018
+ try {
1019
+ if ((await (0, import_promises3.lstat)(target)).isSymbolicLink()) {
1020
+ throw new OutputWriteError(`Refusing to write through symbolic link "${target}".`);
1021
+ }
1022
+ } catch (error) {
1023
+ if (error.code !== "ENOENT") throw error;
1024
+ }
1025
+ }
1026
+ async function validateOutputPaths(outputDir, files) {
1027
+ const root = import_node_path3.default.resolve(outputDir);
1028
+ await rejectSymlink(root);
1029
+ for (const file of files) {
1030
+ let current = root;
1031
+ for (const segment of import_node_path3.default.relative(root, file.fullPath).split(import_node_path3.default.sep)) {
1032
+ current = import_node_path3.default.join(current, segment);
1033
+ await rejectSymlink(current);
1034
+ }
1035
+ }
1036
+ }
1037
+ async function writeFileAtomically(file) {
1038
+ await (0, import_promises3.mkdir)(import_node_path3.default.dirname(file.fullPath), { recursive: true });
1039
+ const temporaryPath = `${file.fullPath}.${(0, import_node_crypto.randomUUID)()}.tmp`;
1040
+ try {
1041
+ await (0, import_promises3.writeFile)(temporaryPath, file.content, { encoding: "utf8", flag: "wx" });
1042
+ await (0, import_promises3.rename)(temporaryPath, file.fullPath);
1043
+ } finally {
1044
+ await (0, import_promises3.rm)(temporaryPath, { force: true });
1045
+ }
1046
+ }
963
1047
  async function writeGeneratedFiles(outputDir, files, clean = false) {
964
1048
  try {
965
1049
  const resolvedFiles = resolveGeneratedFiles(outputDir, files);
1050
+ await validateOutputPaths(outputDir, resolvedFiles);
966
1051
  if (clean) {
967
- const outputRoot = import_node_path2.default.resolve(outputDir);
968
- const relativeCwd = import_node_path2.default.relative(outputRoot, process.cwd());
969
- if (outputRoot === import_node_os.default.homedir() || relativeCwd === "" || relativeCwd !== ".." && !relativeCwd.startsWith(`..${import_node_path2.default.sep}`) && !import_node_path2.default.isAbsolute(relativeCwd)) {
1052
+ const outputRoot = await canonicalPath(outputDir);
1053
+ if (outputRoot === await canonicalPath(import_node_os.default.homedir()) || isWithinDirectory(outputRoot, await canonicalPath(process.cwd()))) {
970
1054
  throw new OutputWriteError(
971
1055
  "Refusing to clean the home directory, working directory, or its ancestors."
972
1056
  );
973
1057
  }
974
- await (0, import_promises2.rm)(outputDir, { force: true, recursive: true });
1058
+ await (0, import_promises3.rm)(outputDir, { force: true, recursive: true });
975
1059
  }
976
- await (0, import_promises2.mkdir)(outputDir, { recursive: true });
977
- await Promise.all(
978
- resolvedFiles.map(async (file) => {
979
- await (0, import_promises2.mkdir)(import_node_path2.default.dirname(file.fullPath), { recursive: true });
980
- await (0, import_promises2.writeFile)(file.fullPath, file.content, "utf8");
981
- })
982
- );
1060
+ await (0, import_promises3.mkdir)(outputDir, { recursive: true });
1061
+ await Promise.all(resolvedFiles.map(writeFileAtomically));
983
1062
  } catch (error) {
984
1063
  if (error instanceof OutputWriteError) {
985
1064
  throw error;
@@ -989,9 +1068,11 @@ async function writeGeneratedFiles(outputDir, files, clean = false) {
989
1068
  }
990
1069
  async function compareGeneratedFiles(outputDir, files) {
991
1070
  const changedFiles = [];
992
- for (const file of resolveGeneratedFiles(outputDir, files)) {
1071
+ const resolvedFiles = resolveGeneratedFiles(outputDir, files);
1072
+ await validateOutputPaths(outputDir, resolvedFiles);
1073
+ for (const file of resolvedFiles) {
993
1074
  try {
994
- if (await (0, import_promises2.readFile)(file.fullPath, "utf8") !== file.content) {
1075
+ if (await (0, import_promises3.readFile)(file.fullPath, "utf8") !== file.content) {
995
1076
  changedFiles.push(file.path);
996
1077
  }
997
1078
  } catch (error) {
@@ -1012,18 +1093,19 @@ async function generateSdk(options) {
1012
1093
  throw new OutputWriteError("The check and dryRun options cannot be combined.");
1013
1094
  }
1014
1095
  if (options.clean && !options.check && !options.dryRun && options.input.file) {
1015
- const relative = import_node_path3.default.relative(
1016
- import_node_path3.default.resolve(options.outputDir),
1017
- import_node_path3.default.resolve(options.input.file)
1018
- );
1019
- if (relative !== ".." && !relative.startsWith(`..${import_node_path3.default.sep}`) && !import_node_path3.default.isAbsolute(relative)) {
1096
+ if (isWithinDirectory(
1097
+ await canonicalPath(options.outputDir),
1098
+ await canonicalPath(options.input.file)
1099
+ )) {
1020
1100
  throw new OutputWriteError("Cannot clean an output directory containing the input schema.");
1021
1101
  }
1022
1102
  }
1023
1103
  logger.info("Loading OpenAPI document");
1024
1104
  const document = await loadOpenApiDocument(options.input, {
1025
1105
  fetchImplementation: options.fetchImplementation,
1026
- logger
1106
+ logger,
1107
+ signal: options.signal,
1108
+ timeoutMs: options.schemaTimeoutMs
1027
1109
  });
1028
1110
  logger.info("Parsing OpenAPI document");
1029
1111
  const parsed = parseDocument(document, {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/generate-sdk.ts","../src/formatter.ts","../src/naming.ts","../src/generator/client-generator.ts","../src/generator/index-generator.ts","../src/generator/readme-generator.ts","../src/resolver.ts","../src/validator.ts","../src/generator/type-generator.ts","../src/loader.ts","../src/logger.ts","../src/parser.ts","../src/writer.ts"],"sourcesContent":["export * from './errors.js';\nexport * from './generate-sdk.js';\nexport * from './loader.js';\nexport * from './logger.js';\nexport * from './naming.js';\nexport * from './parser.js';\nexport * from './resolver.js';\nexport * from './types.js';\nexport * from './validator.js';\n","export class ApiSdkGeneratorError extends Error {\n public readonly code: string;\n\n public constructor(message: string, code = 'API_SDK_GENERATOR_ERROR', cause?: unknown) {\n super(message, cause instanceof Error ? { cause } : undefined);\n this.name = new.target.name;\n this.code = code;\n }\n}\n\nexport class SchemaLoadError extends ApiSdkGeneratorError {\n public constructor(message: string, cause?: unknown) {\n super(message, 'SCHEMA_LOAD_ERROR', cause);\n }\n}\n\nexport class SchemaValidationError extends ApiSdkGeneratorError {\n public constructor(message: string, cause?: unknown) {\n super(message, 'SCHEMA_VALIDATION_ERROR', cause);\n }\n}\n\nexport class UnsupportedSchemaError extends ApiSdkGeneratorError {\n public constructor(message: string, cause?: unknown) {\n super(message, 'UNSUPPORTED_SCHEMA_ERROR', cause);\n }\n}\n\nexport class OutputWriteError extends ApiSdkGeneratorError {\n public constructor(message: string, cause?: unknown) {\n super(message, 'OUTPUT_WRITE_ERROR', cause);\n }\n}\n","import path from 'node:path';\n\nimport { OutputWriteError } from './errors.js';\nimport { formatGeneratedFiles } from './formatter.js';\nimport { generateClientSource } from './generator/client-generator.js';\nimport { generateIndexSource } from './generator/index-generator.js';\nimport { generateGeneratedReadme } from './generator/readme-generator.js';\nimport { generateTypesSource } from './generator/type-generator.js';\nimport { loadOpenApiDocument } from './loader.js';\nimport { noopLogger } from './logger.js';\nimport { parseDocument } from './parser.js';\nimport type { GenerateSdkOptions, GenerateSdkResult } from './types.js';\nimport { compareGeneratedFiles, writeGeneratedFiles } from './writer.js';\n\nexport async function generateSdk(options: GenerateSdkOptions): Promise<GenerateSdkResult> {\n const logger = options.logger ?? noopLogger;\n\n if (options.check && options.dryRun) {\n throw new OutputWriteError('The check and dryRun options cannot be combined.');\n }\n if (options.clean && !options.check && !options.dryRun && options.input.file) {\n const relative = path.relative(\n path.resolve(options.outputDir),\n path.resolve(options.input.file),\n );\n if (relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative)) {\n throw new OutputWriteError('Cannot clean an output directory containing the input schema.');\n }\n }\n\n logger.info('Loading OpenAPI document');\n const document = await loadOpenApiDocument(options.input, {\n fetchImplementation: options.fetchImplementation,\n logger,\n });\n\n logger.info('Parsing OpenAPI document');\n const parsed = parseDocument(document, {\n baseUrl: options.baseUrl,\n sdkName: options.sdkName,\n });\n\n logger.info(`Generating SDK for ${parsed.operations.length} operations`);\n const files = await formatGeneratedFiles([\n {\n content: generateTypesSource(parsed),\n path: 'types.ts',\n },\n {\n content: generateClientSource(parsed),\n path: 'client.ts',\n },\n {\n content: generateIndexSource(),\n path: 'index.ts',\n },\n {\n content: generateGeneratedReadme(parsed),\n path: 'README.md',\n },\n ]);\n\n const changedFiles = options.check ? await compareGeneratedFiles(options.outputDir, files) : [];\n if (!options.check && !options.dryRun) {\n logger.info(`Writing SDK to ${options.outputDir}`);\n await writeGeneratedFiles(options.outputDir, files, options.clean);\n }\n\n return {\n changedFiles,\n files,\n operations: parsed.operations.length,\n outputDir: options.outputDir,\n sdkName: parsed.sdkName,\n };\n}\n","import prettier, { type Options } from 'prettier';\n\nimport type { GeneratedFile } from './types.js';\n\nconst GENERATED_FORMAT_OPTIONS = {\n printWidth: 100,\n semi: true,\n singleQuote: true,\n trailingComma: 'all',\n} satisfies Options;\n\nfunction getParser(filePath: string): 'markdown' | 'typescript' {\n return filePath.endsWith('.md') ? 'markdown' : 'typescript';\n}\n\nexport async function formatGeneratedFiles(files: GeneratedFile[]): Promise<GeneratedFile[]> {\n return Promise.all(\n files.map(async (file) => ({\n ...file,\n content: await prettier.format(file.content, {\n ...GENERATED_FORMAT_OPTIONS,\n parser: getParser(file.path),\n }),\n })),\n );\n}\n","import type { HttpMethod } from './types.js';\n\nconst RESERVED_WORDS = new Set([\n 'default',\n 'function',\n 'class',\n 'switch',\n 'case',\n 'var',\n 'const',\n 'let',\n 'new',\n 'delete',\n 'return',\n]);\n\nfunction splitWords(input: string): string[] {\n return input\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .split(/[^A-Za-z0-9]+/)\n .map((part) => part.trim())\n .filter(Boolean);\n}\n\nfunction capitalize(value: string): string {\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nexport function toPascalCase(input: string): string {\n const words = splitWords(input);\n const pascal = words.map((word) => capitalize(word.toLowerCase())).join('');\n return pascal || 'GeneratedType';\n}\n\nexport function toCamelCase(input: string): string {\n const pascal = toPascalCase(input);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n\nexport function sanitizeIdentifier(input: string): string {\n const camel = toCamelCase(input).replace(/[^A-Za-z0-9_$]/g, '');\n const normalized = camel.match(/^[A-Za-z_$]/) ? camel : `_${camel}`;\n return RESERVED_WORDS.has(normalized) ? `${normalized}Value` : normalized;\n}\n\nexport function toTypeName(input: string): string {\n const pascal = toPascalCase(input).replace(/[^A-Za-z0-9_$]/g, '');\n return pascal.match(/^[A-Za-z_$]/) ? pascal : `T${pascal}`;\n}\n\nexport function toPropertyAccessor(name: string): string {\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);\n}\n\nexport function createFunctionName(method: HttpMethod, path: string, operationId?: string): string {\n if (operationId) {\n return sanitizeIdentifier(operationId);\n }\n\n const segments = path.split('/').filter(Boolean);\n const pieces: string[] = [method.toLowerCase()];\n const paramNames: string[] = [];\n\n for (const segment of segments) {\n const match = segment.match(/^\\{(.+)\\}$/);\n\n if (match) {\n paramNames.push(toPascalCase(match[1]));\n continue;\n }\n\n pieces.push(toPascalCase(segment));\n }\n\n if (paramNames.length > 0) {\n pieces.push(`By${paramNames.join('And')}`);\n }\n\n return sanitizeIdentifier(pieces.join(' '));\n}\n\nexport function deriveSdkName(input?: string): string {\n return input ? toTypeName(input) : 'GeneratedSdk';\n}\n","import { toTypeName } from '../naming.js';\nimport type { ParsedDocument, ParsedOperation } from '../types.js';\n\nfunction renderTemplatePath(path: string, operation: ParsedOperation): string {\n const parts: string[] = [];\n let offset = 0;\n for (const match of path.matchAll(/\\{([^}]+)\\}/g)) {\n const parameter = operation.pathParameters.find((item) => item.name === match[1]);\n if (!parameter) continue;\n parts.push(JSON.stringify(path.slice(offset, match.index)));\n parts.push(`encodeURIComponent(String(request[${JSON.stringify(parameter.name)}]))`);\n offset = match.index + match[0].length;\n }\n parts.push(JSON.stringify(path.slice(offset)));\n return parts.join(' + ');\n}\n\nfunction renderQueryLines(operation: ParsedOperation): string[] {\n return operation.queryParameters.map((parameter) => {\n const style = parameter.style ?? 'form';\n const explode = parameter.explode ?? style === 'form';\n const separator = style === 'spaceDelimited' ? ' ' : style === 'pipeDelimited' ? '|' : ',';\n return ` appendQueryParameter(searchParams, ${JSON.stringify(parameter.name)}, request[${JSON.stringify(parameter.name)}], ${explode}, ${JSON.stringify(separator)});`;\n });\n}\n\nfunction renderMethodSignature(operation: ParsedOperation): string {\n if (!operation.hasRequestShape) {\n return `${operation.functionName}(init?: RequestInit): Promise<${operation.responseTypeName}>;`;\n }\n\n if (operation.hasRequiredRequestFields) {\n return `${operation.functionName}(request: ${operation.requestTypeName}, init?: RequestInit): Promise<${operation.responseTypeName}>;`;\n }\n\n return `${operation.functionName}(request?: ${operation.requestTypeName}, init?: RequestInit): Promise<${operation.responseTypeName}>;`;\n}\n\nfunction renderMethodImplementation(operation: ParsedOperation): string {\n const requestParameter = operation.hasRequestShape\n ? operation.hasRequiredRequestFields\n ? 'request'\n : 'request = {}'\n : '';\n const queryLines = renderQueryLines(operation);\n const bodyContent =\n operation.requestBody?.contentType === 'application/json' ||\n operation.requestBody?.contentType?.endsWith('+json')\n ? [\n ' const body = request.body !== undefined ? JSON.stringify(request.body) : undefined;',\n ' if (body !== undefined && !headers.has(\"content-type\")) {',\n ` headers.set(\"content-type\", ${JSON.stringify(operation.requestBody.contentType)});`,\n ' }',\n ].join('\\n')\n : ' const body = undefined;';\n\n return [\n ` async ${operation.functionName}(${requestParameter}${requestParameter ? ', ' : ''}init?: RequestInit): Promise<${operation.responseTypeName}> {`,\n ` const url = resolveRequestUrl(resolveBaseUrl(config.baseUrl), ${renderTemplatePath(operation.path, operation)});`,\n ' const searchParams = url.searchParams;',\n ...(queryLines.length > 0 ? queryLines : [' void searchParams;']),\n ' const headers = new Headers(config.headers);',\n bodyContent,\n ' const response = await runtimeFetch(url, {',\n ' ...init,',\n ` method: ${JSON.stringify(operation.method.toUpperCase())},`,\n ' body,',\n ' headers: mergeHeaders(headers, init?.headers),',\n ' });',\n '',\n ' if (!response.ok) {',\n ' throw await ApiError.fromResponse(response);',\n ' }',\n '',\n ` return parseResponse<${operation.responseTypeName}>(response);`,\n ' },',\n ].join('\\n');\n}\n\nexport function generateClientSource(parsed: ParsedDocument): string {\n const clientName = `${toTypeName(parsed.sdkName)}Client`;\n const interfaceLines = parsed.operations.map(\n (operation) => ` ${renderMethodSignature(operation)}`,\n );\n const methodLines = parsed.operations.map((operation) => renderMethodImplementation(operation));\n\n return [\n '/* eslint-disable */',\n '/**',\n ' * Auto-generated by api-sdk-generator.',\n ' * Do not edit manually.',\n ' */',\n '',\n ...(parsed.operations.length > 0\n ? [\n 'import type {',\n ...parsed.operations.flatMap((operation) => [\n ...(operation.hasRequestShape ? [` ${operation.requestTypeName},`] : []),\n ` ${operation.responseTypeName},`,\n ]),\n \"} from './types.js';\",\n '',\n ]\n : []),\n 'export interface ClientConfig {',\n ' baseUrl?: string;',\n ' fetch?: typeof fetch;',\n ' headers?: HeadersInit;',\n '}',\n '',\n `export interface ${clientName} {`,\n ...interfaceLines,\n '}',\n '',\n 'export class ApiError extends Error {',\n ' public readonly body: unknown;',\n ' public readonly status: number;',\n ' public readonly headers: Headers;',\n '',\n ' public constructor(status: number, message: string, body: unknown, headers: Headers = new Headers()) {',\n ' super(message);',\n ' this.name = \"ApiError\";',\n ' this.status = status;',\n ' this.body = body;',\n ' this.headers = headers;',\n ' }',\n '',\n ' public static async fromResponse(response: Response): Promise<ApiError> {',\n ' const body = await parseResponseBody(response.clone()).catch(() => response.text());',\n ' return new ApiError(response.status, `Request failed with status ${response.status}`, body, response.headers);',\n ' }',\n '}',\n '',\n 'export function createClient(config: ClientConfig = {}): ' + clientName + ' {',\n ' const runtimeFetch = config.fetch ?? globalThis.fetch;',\n '',\n ' if (!runtimeFetch) {',\n ' throw new Error(\"Fetch API is not available in the current runtime.\");',\n ' }',\n '',\n ' return {',\n ...methodLines,\n ' };',\n '}',\n '',\n ...(parsed.operations.length > 0\n ? [\n 'function resolveBaseUrl(baseUrl?: string): string {',\n ` return baseUrl ?? ${JSON.stringify(parsed.defaultBaseUrl ?? 'http://localhost')};`,\n '}',\n '',\n 'function resolveRequestUrl(baseUrl: string, requestPath: string): URL {',\n ' const normalizedBaseUrl = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;',\n ' return new URL(requestPath.replace(/^\\\\/+/, \"\"), normalizedBaseUrl);',\n '}',\n '',\n 'async function parseResponse<T>(response: Response): Promise<T> {',\n ' return (await parseResponseBody(response)) as T;',\n '}',\n '',\n ]\n : []),\n 'async function parseResponseBody(response: Response): Promise<unknown> {',\n ' if (response.status === 204 || response.status === 205) {',\n ' return undefined;',\n ' }',\n '',\n ' const body = await response.text();',\n '',\n ' if (!body) {',\n ' return undefined;',\n ' }',\n '',\n ' const contentType = response.headers.get(\"content-type\") ?? \"\";',\n ' return isJsonContentType(contentType) ? (JSON.parse(body) as unknown) : body;',\n '}',\n '',\n 'function isJsonContentType(contentType: string): boolean {',\n ' const mediaType = contentType.split(\";\", 1)[0].trim().toLowerCase();',\n ' return mediaType === \"application/json\" || mediaType.endsWith(\"+json\");',\n '}',\n '',\n ...(parsed.operations.some((operation) => operation.queryParameters.length > 0)\n ? [\n 'function appendQueryParameter(params: URLSearchParams, name: string, value: unknown, explode: boolean, separator: string): void {',\n ' if (value === undefined) return;',\n ' if (Array.isArray(value)) {',\n ' if (explode) {',\n ' for (const item of value) params.append(name, String(item));',\n ' } else {',\n ' params.set(name, value.map(String).join(separator));',\n ' }',\n ' } else {',\n ' params.set(name, String(value));',\n ' }',\n '}',\n '',\n ]\n : []),\n ...(parsed.operations.length > 0\n ? [\n 'function mergeHeaders(baseHeaders: Headers, initHeaders?: HeadersInit): Headers {',\n ' const merged = new Headers(baseHeaders);',\n '',\n ' if (initHeaders) {',\n ' const overlay = new Headers(initHeaders);',\n ' overlay.forEach((value, key) => merged.set(key, value));',\n ' }',\n '',\n ' return merged;',\n '}',\n '',\n ]\n : []),\n ].join('\\n');\n}\n","export function generateIndexSource(): string {\n return [\"export * from './types.js';\", \"export * from './client.js';\", ''].join('\\n');\n}\n","import type { ParsedDocument } from '../types.js';\n\nexport function generateGeneratedReadme(parsed: ParsedDocument): string {\n const exampleOperation = parsed.operations[0];\n const exampleCall = exampleOperation?.hasRequestShape\n ? `${exampleOperation.functionName}({ /* request */ })`\n : `${exampleOperation?.functionName ?? 'listResources'}()`;\n\n return [\n `# ${parsed.sdkName}`,\n '',\n 'This SDK was generated by `api-sdk-generator`.',\n '',\n '## Usage',\n '',\n '```ts',\n \"import { createClient } from './index';\",\n '',\n 'const client = createClient({',\n ` baseUrl: ${JSON.stringify(parsed.defaultBaseUrl ?? 'https://api.example.com')},`,\n '});',\n '',\n `await client.${exampleCall};`,\n '```',\n '',\n ].join('\\n');\n}\n","import type { OpenAPIV3 } from 'openapi-types';\n\nimport { SchemaValidationError } from './errors.js';\nimport type { OpenApiDocument, SchemaLike } from './types.js';\n\nexport function isReferenceObject(schema: SchemaLike): schema is OpenAPIV3.ReferenceObject {\n return '$ref' in schema;\n}\n\nexport function getReferenceName(ref: string): string {\n const match = ref.match(/^#\\/components\\/schemas\\/(.+)$/);\n\n if (!match) {\n throw new SchemaValidationError(\n `Only local component schema refs are supported. Received \"${ref}\".`,\n );\n }\n\n return decodePointerToken(match[1]);\n}\n\nexport function resolveSchema(\n document: OpenApiDocument,\n schema: SchemaLike,\n): OpenAPIV3.SchemaObject {\n if (!isReferenceObject(schema)) {\n return schema;\n }\n\n return resolveLocalComponent<OpenAPIV3.SchemaObject>(\n schema,\n document.components?.schemas,\n 'schemas',\n );\n}\n\nfunction decodePointerToken(token: string): string {\n return token.replace(/~1/g, '/').replace(/~0/g, '~');\n}\n\n/** Follow local component aliases while rejecting dangling or cyclic references. */\nexport function resolveLocalComponent<T extends object>(\n reference: OpenAPIV3.ReferenceObject,\n collection: Record<string, T | OpenAPIV3.ReferenceObject> | undefined,\n section: string,\n): T {\n const seen = new Set<string>();\n let current = reference;\n const prefix = `#/components/${section}/`;\n for (;;) {\n if (!current.$ref.startsWith(prefix)) {\n throw new SchemaValidationError(\n `Only local ${section} refs are supported. Received \"${current.$ref}\".`,\n );\n }\n if (seen.has(current.$ref)) {\n throw new SchemaValidationError(`Circular component reference \"${current.$ref}\".`);\n }\n seen.add(current.$ref);\n const name = decodePointerToken(current.$ref.slice(prefix.length));\n const resolved = collection && Object.hasOwn(collection, name) ? collection[name] : undefined;\n if (!resolved) {\n throw new SchemaValidationError(`Unable to resolve ${section} reference \"${current.$ref}\".`);\n }\n if ('$ref' in resolved) {\n current = resolved;\n } else {\n return resolved;\n }\n }\n}\n","import type { OpenAPIV3 } from 'openapi-types';\n\nimport { SchemaValidationError } from './errors.js';\nimport type { OpenApiDocument } from './types.js';\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function validateOpenApiDocument(value: unknown): OpenApiDocument {\n if (!isObject(value)) {\n throw new SchemaValidationError('OpenAPI document must be a JSON object.');\n }\n\n if (typeof value.openapi !== 'string' || !value.openapi.startsWith('3.')) {\n throw new SchemaValidationError('Only OpenAPI 3.x documents are supported.');\n }\n\n if (!isObject(value.info) || typeof value.info.title !== 'string') {\n throw new SchemaValidationError('OpenAPI document must contain info.title.');\n }\n\n if (!isObject(value.paths)) {\n throw new SchemaValidationError('OpenAPI document must contain a paths object.');\n }\n\n return value as unknown as OpenApiDocument;\n}\n\nexport function isSchemaObject(value: unknown): value is OpenAPIV3.SchemaObject {\n return isObject(value) && !('$ref' in value);\n}\n","import type { OpenAPIV3 } from 'openapi-types';\n\nimport { UnsupportedSchemaError } from '../errors.js';\nimport { toPropertyAccessor, toTypeName } from '../naming.js';\nimport { getReferenceName, isReferenceObject, resolveSchema } from '../resolver.js';\nimport type { OpenApiDocument, ParsedDocument, ParsedOperation, SchemaLike } from '../types.js';\nimport { isSchemaObject } from '../validator.js';\n\ninterface TypeRenderContext {\n document: OpenApiDocument;\n}\n\nfunction quoteEnumValue(value: string | number | boolean | null): string {\n return typeof value === 'string' ? JSON.stringify(value) : String(value);\n}\n\nfunction normalizeNullable(rendered: string, schema: OpenAPIV3.SchemaObject): string {\n return schema.nullable ? `${rendered} | null` : rendered;\n}\n\nfunction renderObjectType(schema: OpenAPIV3.SchemaObject, context: TypeRenderContext): string {\n const required = new Set(schema.required ?? []);\n const properties = schema.properties ?? {};\n const propertyEntries = Object.entries(properties);\n\n if (propertyEntries.length === 0) {\n if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {\n return `Record<string, ${renderSchema(schema.additionalProperties, context)}>`;\n }\n\n return schema.additionalProperties === false\n ? 'Record<string, never>'\n : 'Record<string, unknown>';\n }\n\n const lines = propertyEntries.map(([name, propertySchema]) => {\n const propertyType = renderSchema(propertySchema, context);\n const optionalToken = required.has(name) ? '' : '?';\n return ` ${toPropertyAccessor(name)}${optionalToken}: ${propertyType};`;\n });\n\n const objectType = ['{', ...lines, '}'].join('\\n');\n if (schema.additionalProperties) {\n const valueType =\n schema.additionalProperties === true\n ? 'unknown'\n : renderSchema(schema.additionalProperties, context);\n return `${objectType} & Record<string, ${valueType}>`;\n }\n return objectType;\n}\n\nexport function renderSchema(schema: SchemaLike, context: TypeRenderContext): string {\n if (isReferenceObject(schema)) {\n resolveSchema(context.document, schema);\n return toTypeName(getReferenceName(schema.$ref));\n }\n\n if (schema.enum && schema.enum.length > 0) {\n return normalizeNullable(schema.enum.map(quoteEnumValue).join(' | '), schema);\n }\n\n if (schema.oneOf && schema.oneOf.length > 0) {\n return normalizeNullable(\n schema.oneOf.map((item) => renderSchema(item, context)).join(' | '),\n schema,\n );\n }\n\n if (schema.anyOf && schema.anyOf.length > 0) {\n return normalizeNullable(\n schema.anyOf.map((item) => `(${renderSchema(item, context)})`).join(' | '),\n schema,\n );\n }\n\n if (schema.allOf && schema.allOf.length > 0) {\n return normalizeNullable(\n schema.allOf.map((item) => `(${renderSchema(item, context)})`).join(' & '),\n schema,\n );\n }\n\n if (schema.type === 'array') {\n if (!schema.items) {\n throw new UnsupportedSchemaError('Array schema must define items.');\n }\n\n return normalizeNullable(`Array<${renderSchema(schema.items, context)}>`, schema);\n }\n\n if (schema.type === 'object' || schema.properties || schema.additionalProperties) {\n return normalizeNullable(renderObjectType(schema, context), schema);\n }\n\n if (schema.type === 'string') {\n return normalizeNullable('string', schema);\n }\n\n if (schema.type === 'number' || schema.type === 'integer') {\n return normalizeNullable('number', schema);\n }\n\n if (schema.type === 'boolean') {\n return normalizeNullable('boolean', schema);\n }\n\n return 'unknown';\n}\n\nfunction renderNamedSchemaExport(\n name: string,\n schema: SchemaLike,\n context: TypeRenderContext,\n): string {\n if (isReferenceObject(schema)) {\n return `export type ${toTypeName(name)} = ${renderSchema(schema, context)};`;\n }\n\n const resolved = resolveSchema(context.document, schema);\n\n const rendered = renderSchema(resolved, context);\n if (\n rendered.startsWith('{') &&\n rendered.endsWith('}') &&\n !resolved.nullable &&\n !resolved.allOf &&\n !resolved.oneOf &&\n !resolved.anyOf &&\n !resolved.additionalProperties\n ) {\n return `export interface ${toTypeName(name)} ${rendered}`;\n }\n\n return `export type ${toTypeName(name)} = ${rendered};`;\n}\n\nfunction createRequestSchema(operation: ParsedOperation): OpenAPIV3.SchemaObject | undefined {\n const properties: Record<string, SchemaLike> = Object.create(null) as Record<string, SchemaLike>;\n const required: string[] = [];\n\n for (const parameter of [...operation.pathParameters, ...operation.queryParameters]) {\n properties[parameter.name] = parameter.schema;\n if (parameter.required) {\n required.push(parameter.name);\n }\n }\n\n if (operation.requestBody) {\n properties.body = operation.requestBody.schema;\n if (operation.requestBody.required) {\n required.push('body');\n }\n }\n\n if (Object.keys(properties).length === 0) {\n return undefined;\n }\n\n return {\n properties,\n required,\n type: 'object',\n };\n}\n\nfunction createResponseSchema(operation: ParsedOperation): SchemaLike | undefined {\n return operation.response.schema;\n}\n\nfunction renderOperationTypes(parsed: ParsedDocument, context: TypeRenderContext): string[] {\n const blocks: string[] = [];\n\n for (const operation of parsed.operations) {\n const requestSchema = createRequestSchema(operation);\n\n if (requestSchema) {\n blocks.push(renderNamedSchemaExport(operation.requestTypeName, requestSchema, context));\n } else {\n blocks.push(`export type ${operation.requestTypeName} = void;`);\n }\n\n const responseSchema = createResponseSchema(operation);\n\n if (responseSchema) {\n blocks.push(renderNamedSchemaExport(operation.responseTypeName, responseSchema, context));\n } else {\n blocks.push(`export type ${operation.responseTypeName} = void;`);\n }\n }\n\n return blocks;\n}\n\nexport function generateTypesSource(parsed: ParsedDocument): string {\n const context: TypeRenderContext = {\n document: parsed.document,\n };\n const componentBlocks = Object.entries(parsed.componentSchemas)\n .sort(([left], [right]) => left.localeCompare(right))\n .filter(([, schema]) => isReferenceObject(schema) || isSchemaObject(schema))\n .map(([name, schema]) => renderNamedSchemaExport(name, schema, context));\n const operationBlocks = renderOperationTypes(parsed, context);\n\n return [\n '/* eslint-disable */',\n '/**',\n ' * Auto-generated by api-sdk-generator.',\n ' * Do not edit manually.',\n ' */',\n '',\n 'export {};',\n '',\n ...componentBlocks,\n '',\n ...operationBlocks,\n '',\n ].join('\\n');\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { parseDocument as parseYamlDocument } from 'yaml';\n\nimport { ApiSdkGeneratorError, SchemaLoadError } from './errors.js';\nimport type { Logger } from './logger.js';\nimport type { GenerateSdkInput, OpenApiDocument } from './types.js';\nimport { validateOpenApiDocument } from './validator.js';\n\nexport interface LoadSchemaOptions {\n fetchImplementation?: typeof fetch;\n logger?: Logger;\n}\n\nfunction parseSchema(content: string): OpenApiDocument {\n // JSON is a YAML subset. Limit aliases and reject duplicate keys rather than\n // silently replacing definitions in an API contract.\n const parsed = parseYamlDocument(content, { uniqueKeys: true });\n if (parsed.errors.length > 0) {\n throw new SchemaLoadError(`Invalid JSON or YAML: ${parsed.errors[0].message}`);\n }\n return validateOpenApiDocument(parsed.toJS({ maxAliasCount: 100 }) as unknown);\n}\n\nexport async function loadOpenApiDocument(\n input: GenerateSdkInput,\n options: LoadSchemaOptions = {},\n): Promise<OpenApiDocument> {\n const sources = [input.file, input.url].filter(Boolean);\n\n if (sources.length !== 1) {\n throw new SchemaLoadError('Exactly one input source must be provided: either file or url.');\n }\n\n if (input.file) {\n return loadOpenApiDocumentFromFile(input.file, options.logger);\n }\n\n return loadOpenApiDocumentFromUrl(input.url!, options.fetchImplementation, options.logger);\n}\n\nexport async function loadOpenApiDocumentFromFile(\n filePath: string,\n logger?: Logger,\n): Promise<OpenApiDocument> {\n try {\n logger?.debug(`Loading OpenAPI schema from file: ${filePath}`);\n const content = await readFile(filePath, 'utf8');\n return parseSchema(content);\n } catch (error) {\n if (error instanceof ApiSdkGeneratorError) {\n throw error;\n }\n\n throw new SchemaLoadError(\n `Failed to load OpenAPI schema from file \"${path.resolve(filePath)}\".`,\n error,\n );\n }\n}\n\nexport async function loadOpenApiDocumentFromUrl(\n url: string,\n fetchImplementation?: typeof fetch,\n logger?: Logger,\n): Promise<OpenApiDocument> {\n const runtimeFetch = fetchImplementation ?? globalThis.fetch;\n\n if (!runtimeFetch) {\n throw new SchemaLoadError('Fetch API is not available in the current runtime.');\n }\n\n try {\n logger?.debug(`Loading OpenAPI schema from URL: ${url}`);\n const response = await runtimeFetch(url);\n\n if (!response.ok) {\n throw new SchemaLoadError(\n `Failed to fetch OpenAPI schema from \"${url}\". HTTP ${response.status}.`,\n );\n }\n\n return parseSchema(await response.text());\n } catch (error) {\n if (error instanceof ApiSdkGeneratorError) {\n throw error;\n }\n\n throw new SchemaLoadError(`Failed to load OpenAPI schema from URL \"${url}\".`, error);\n }\n}\n","export interface Logger {\n info(message: string): void;\n warn(message: string): void;\n error(message: string): void;\n debug(message: string): void;\n}\n\nexport interface CreateLoggerOptions {\n sink?: Pick<typeof console, 'info' | 'warn' | 'error'>;\n verbose?: boolean;\n}\n\nclass NoopLogger implements Logger {\n public info(): void {}\n\n public warn(): void {}\n\n public error(): void {}\n\n public debug(): void {}\n}\n\nexport const noopLogger: Logger = new NoopLogger();\n\nexport function createLogger(options: CreateLoggerOptions = {}): Logger {\n const sink = options.sink ?? console;\n const verbose = options.verbose ?? false;\n\n return {\n debug(message: string): void {\n if (verbose) {\n sink.info(message);\n }\n },\n error(message: string): void {\n sink.error(message);\n },\n info(message: string): void {\n sink.info(message);\n },\n warn(message: string): void {\n sink.warn(message);\n },\n };\n}\n","import type { OpenAPIV3 } from 'openapi-types';\n\nimport { SchemaValidationError, UnsupportedSchemaError } from './errors.js';\nimport { createFunctionName, deriveSdkName, toTypeName } from './naming.js';\nimport { resolveLocalComponent, resolveSchema } from './resolver.js';\nimport type {\n HttpMethod,\n OpenApiDocument,\n ParsedDocument,\n ParsedOperation,\n ParsedParameter,\n ParsedRequestBody,\n ParsedResponse,\n SchemaLike,\n} from './types.js';\n\nconst SUPPORTED_METHODS: readonly HttpMethod[] = [\n 'get',\n 'post',\n 'put',\n 'patch',\n 'delete',\n 'head',\n 'options',\n];\n\nfunction getParameterSchema(\n document: OpenApiDocument,\n parameter: OpenAPIV3.ParameterObject,\n): SchemaLike {\n if (!parameter.schema) {\n throw new UnsupportedSchemaError(\n `Parameter \"${parameter.name}\" in \"${parameter.in}\" is missing schema definition.`,\n );\n }\n\n resolveSchema(document, parameter.schema);\n return parameter.schema;\n}\n\nfunction dereferenceParameter(\n document: OpenApiDocument,\n parameter: OpenAPIV3.ReferenceObject | OpenAPIV3.ParameterObject,\n): OpenAPIV3.ParameterObject {\n if (!('$ref' in parameter)) {\n return parameter;\n }\n\n return resolveLocalComponent(parameter, document.components?.parameters, 'parameters');\n}\n\nfunction extractParameters(\n document: OpenApiDocument,\n parameters: Array<OpenAPIV3.ReferenceObject | OpenAPIV3.ParameterObject> | undefined,\n): ParsedParameter[] {\n return (parameters ?? [])\n .map((parameter) => dereferenceParameter(document, parameter))\n .filter((parameter) => parameter.in === 'path' || parameter.in === 'query')\n .map((parameter) => ({\n description: parameter.description,\n explode: parameter.explode,\n style: parameter.style,\n in: parameter.in === 'path' ? 'path' : 'query',\n name: parameter.name,\n required: parameter.in === 'path' ? true : (parameter.required ?? false),\n schema: getParameterSchema(document, parameter),\n }));\n}\n\nfunction mergeParameters(\n document: OpenApiDocument,\n pathParameters: Array<OpenAPIV3.ReferenceObject | OpenAPIV3.ParameterObject> | undefined,\n operationParameters: Array<OpenAPIV3.ReferenceObject | OpenAPIV3.ParameterObject> | undefined,\n): ParsedParameter[] {\n const merged = new Map<string, ParsedParameter>();\n\n for (const parameter of extractParameters(document, pathParameters)) {\n merged.set(`${parameter.in}:${parameter.name}`, parameter);\n }\n\n for (const parameter of extractParameters(document, operationParameters)) {\n merged.set(`${parameter.in}:${parameter.name}`, parameter);\n }\n\n return [...merged.values()];\n}\n\nfunction getJsonContent<TContent>(container: { content?: Record<string, TContent> }): {\n contentType: string;\n value: TContent;\n} | null {\n const content = container.content ?? {};\n const entries = Object.entries(content);\n\n for (const [contentType, value] of entries) {\n if (contentType === 'application/json' || contentType.endsWith('+json')) {\n return { contentType, value };\n }\n }\n\n return null;\n}\n\nfunction extractRequestBody(\n document: OpenApiDocument,\n requestBody: OpenAPIV3.ReferenceObject | OpenAPIV3.RequestBodyObject | undefined,\n): ParsedRequestBody | undefined {\n if (!requestBody) {\n return undefined;\n }\n\n const resolved = '$ref' in requestBody ? resolveRequestBody(document, requestBody) : requestBody;\n const jsonContent = getJsonContent(resolved);\n\n if (!jsonContent) {\n throw new UnsupportedSchemaError('Only JSON request bodies are supported.');\n }\n\n const schema = jsonContent.value.schema;\n\n if (!schema) {\n throw new UnsupportedSchemaError('JSON request body must include a schema.');\n }\n\n return {\n contentType: jsonContent.contentType,\n required: resolved.required ?? false,\n schema,\n };\n}\n\nfunction resolveRequestBody(\n document: OpenApiDocument,\n requestBody: OpenAPIV3.ReferenceObject,\n): OpenAPIV3.RequestBodyObject {\n return resolveLocalComponent(requestBody, document.components?.requestBodies, 'requestBodies');\n}\n\nfunction extractResponse(operation: OpenAPIV3.OperationObject): {\n response: OpenAPIV3.ReferenceObject | OpenAPIV3.ResponseObject;\n statusCode: string;\n} {\n const entries = Object.entries(operation.responses ?? {});\n const successfulEntry = entries.find(([status]) => /^2(?:\\d\\d|XX)$/i.test(status)) ?? entries[0];\n\n if (!successfulEntry) {\n return {\n response: {\n description: 'No content',\n },\n statusCode: '204',\n };\n }\n\n return {\n response: successfulEntry[1],\n statusCode: successfulEntry[0],\n };\n}\n\nfunction resolveResponse(\n document: OpenApiDocument,\n response: OpenAPIV3.ReferenceObject | OpenAPIV3.ResponseObject,\n): OpenAPIV3.ResponseObject {\n if (!('$ref' in response)) {\n return response;\n }\n\n return resolveLocalComponent(response, document.components?.responses, 'responses');\n}\n\nfunction parseResponse(\n document: OpenApiDocument,\n operation: OpenAPIV3.OperationObject,\n): ParsedResponse {\n const { response, statusCode } = extractResponse(operation);\n const resolved = resolveResponse(document, response);\n const jsonContent = getJsonContent(resolved);\n\n return {\n contentType: jsonContent?.contentType,\n description: resolved.description,\n schema: jsonContent?.value.schema,\n statusCode,\n };\n}\n\nfunction hasRequiredRequestFields(\n parameters: ParsedParameter[],\n requestBody?: ParsedRequestBody,\n): boolean {\n return parameters.some((parameter) => parameter.required) || Boolean(requestBody?.required);\n}\n\nexport function parseDocument(\n document: OpenApiDocument,\n options: {\n baseUrl?: string;\n sdkName?: string;\n } = {},\n): ParsedDocument {\n const operations: ParsedOperation[] = [];\n const functionNames = new Set<string>();\n const typeNames = new Set<string>([\n 'ClientConfig',\n 'ApiError',\n `${deriveSdkName(options.sdkName ?? document.info.title)}Client`,\n ]);\n for (const name of Object.keys(document.components?.schemas ?? {})) {\n const typeName = toTypeName(name);\n if (typeNames.has(typeName)) {\n throw new SchemaValidationError(`Duplicate or reserved generated type name \"${typeName}\".`);\n }\n typeNames.add(typeName);\n }\n\n for (const [pathKey, pathItem] of Object.entries(document.paths ?? {})) {\n if (!pathItem || '$ref' in pathItem) {\n throw new UnsupportedSchemaError(`Path-level $ref is not supported for path \"${pathKey}\".`);\n }\n\n if (pathItem.trace) {\n throw new UnsupportedSchemaError('TRACE operations are not supported by the Fetch API.');\n }\n for (const method of SUPPORTED_METHODS) {\n const operation = pathItem[method];\n\n if (!operation) {\n continue;\n }\n\n const functionName = createFunctionName(method, pathKey, operation.operationId);\n\n if (functionNames.has(functionName)) {\n throw new SchemaValidationError(\n `Duplicate generated operation name \"${functionName}\". Use unique operationId values.`,\n );\n }\n functionNames.add(functionName);\n const allocateTypeName = (base: string): string => {\n let name = base;\n let suffix = 2;\n while (typeNames.has(name)) name = `${base}${suffix++}`;\n typeNames.add(name);\n return name;\n };\n const requestTypeName = allocateTypeName(`${toTypeName(functionName)}Request`);\n const responseTypeName = allocateTypeName(`${toTypeName(functionName)}Response`);\n const mergedParameters = mergeParameters(document, pathItem.parameters, operation.parameters);\n const queryParameters = mergedParameters.filter((parameter) => parameter.in === 'query');\n const extractedPathParameters = mergedParameters.filter(\n (parameter) => parameter.in === 'path',\n );\n const requestBody = extractRequestBody(document, operation.requestBody);\n const response = parseResponse(document, operation);\n const requestNames = new Set<string>();\n for (const parameter of mergedParameters) {\n if (requestNames.has(parameter.name) || (parameter.name === 'body' && requestBody)) {\n throw new UnsupportedSchemaError(\n `Request field \"${parameter.name}\" collides in ${method.toUpperCase()} ${pathKey}.`,\n );\n }\n requestNames.add(parameter.name);\n if (parameter.in === 'query') {\n const schema = resolveSchema(document, parameter.schema);\n const style = parameter.style ?? 'form';\n if (\n schema.type === 'object' ||\n schema.properties ||\n !['form', 'spaceDelimited', 'pipeDelimited'].includes(style)\n ) {\n throw new UnsupportedSchemaError(\n `Unsupported query serialization for \"${parameter.name}\": ${style}.`,\n );\n }\n }\n }\n for (const match of pathKey.matchAll(/\\{([^}]+)\\}/g)) {\n if (!extractedPathParameters.some((parameter) => parameter.name === match[1])) {\n throw new SchemaValidationError(\n `Missing path parameter \"${match[1]}\" in ${method.toUpperCase()} ${pathKey}.`,\n );\n }\n }\n const hasRequestShape =\n extractedPathParameters.length + queryParameters.length > 0 || Boolean(requestBody);\n\n operations.push({\n description: operation.description,\n functionName,\n hasRequiredRequestFields: hasRequiredRequestFields(mergedParameters, requestBody),\n hasRequestShape,\n method,\n operationId: operation.operationId,\n path: pathKey,\n pathParameters: extractedPathParameters,\n queryParameters,\n requestBody,\n requestTypeName,\n response,\n responseTypeName,\n summary: operation.summary,\n });\n }\n }\n\n const sdkName = deriveSdkName(options.sdkName ?? document.info.title);\n const defaultBaseUrl = options.baseUrl ?? document.servers?.[0]?.url;\n\n return {\n componentSchemas: document.components?.schemas ?? {},\n defaultBaseUrl,\n document,\n operations,\n sdkName,\n };\n}\n","import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { OutputWriteError } from './errors.js';\nimport type { GeneratedFile } from './types.js';\n\ninterface ResolvedGeneratedFile extends GeneratedFile {\n fullPath: string;\n}\n\nfunction resolveGeneratedFiles(outputDir: string, files: GeneratedFile[]): ResolvedGeneratedFile[] {\n const outputRoot = path.resolve(outputDir);\n const seenPaths = new Set<string>();\n\n return files.map((file) => {\n const fullPath = path.resolve(outputRoot, file.path);\n const relativePath = path.relative(outputRoot, fullPath);\n\n if (\n !relativePath ||\n relativePath === '..' ||\n relativePath.startsWith(`..${path.sep}`) ||\n path.isAbsolute(relativePath)\n ) {\n throw new OutputWriteError(\n `Generated file path \"${file.path}\" must stay within the output directory.`,\n );\n }\n\n if (seenPaths.has(fullPath)) {\n throw new OutputWriteError(`Duplicate generated file path \"${file.path}\".`);\n }\n\n seenPaths.add(fullPath);\n return { ...file, fullPath };\n });\n}\n\nexport async function writeGeneratedFiles(\n outputDir: string,\n files: GeneratedFile[],\n clean = false,\n): Promise<void> {\n try {\n const resolvedFiles = resolveGeneratedFiles(outputDir, files);\n\n if (clean) {\n const outputRoot = path.resolve(outputDir);\n const relativeCwd = path.relative(outputRoot, process.cwd());\n if (\n outputRoot === os.homedir() ||\n relativeCwd === '' ||\n (relativeCwd !== '..' &&\n !relativeCwd.startsWith(`..${path.sep}`) &&\n !path.isAbsolute(relativeCwd))\n ) {\n throw new OutputWriteError(\n 'Refusing to clean the home directory, working directory, or its ancestors.',\n );\n }\n await rm(outputDir, { force: true, recursive: true });\n }\n\n await mkdir(outputDir, { recursive: true });\n\n await Promise.all(\n resolvedFiles.map(async (file) => {\n await mkdir(path.dirname(file.fullPath), { recursive: true });\n await writeFile(file.fullPath, file.content, 'utf8');\n }),\n );\n } catch (error) {\n if (error instanceof OutputWriteError) {\n throw error;\n }\n\n throw new OutputWriteError(`Failed to write generated SDK to \"${outputDir}\".`, error);\n }\n}\n\n/** Compare only generated files; unrelated files are left alone. */\nexport async function compareGeneratedFiles(\n outputDir: string,\n files: GeneratedFile[],\n): Promise<string[]> {\n const changedFiles: string[] = [];\n for (const file of resolveGeneratedFiles(outputDir, files)) {\n try {\n if ((await readFile(file.fullPath, 'utf8')) !== file.content) {\n changedFiles.push(file.path);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n changedFiles.push(file.path);\n } else {\n throw new OutputWriteError(`Failed to compare generated file \"${file.fullPath}\".`, error);\n }\n }\n }\n return changedFiles;\n}\n"],"mappings":"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","names":["import_node_path","prettier","path","path","parseYamlDocument","path","import_promises","import_node_path","path","os","path"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/formatter.ts","../src/naming.ts","../src/generator/client-generator.ts","../src/generator/index-generator.ts","../src/generator/readme-generator.ts","../src/resolver.ts","../src/validator.ts","../src/generator/type-generator.ts","../src/loader.ts","../src/logger.ts","../src/parser.ts","../src/paths.ts","../src/writer.ts","../src/generate-sdk.ts"],"sourcesContent":["export * from './errors.js';\nexport * from './generate-sdk.js';\nexport * from './loader.js';\nexport * from './logger.js';\nexport * from './naming.js';\nexport * from './parser.js';\nexport * from './resolver.js';\nexport * from './types.js';\nexport * from './validator.js';\n","export class ApiSdkGeneratorError extends Error {\n public readonly code: string;\n\n public constructor(message: string, code = 'API_SDK_GENERATOR_ERROR', cause?: unknown) {\n super(message, cause instanceof Error ? { cause } : undefined);\n this.name = new.target.name;\n this.code = code;\n }\n}\n\nexport class SchemaLoadError extends ApiSdkGeneratorError {\n public constructor(message: string, cause?: unknown) {\n super(message, 'SCHEMA_LOAD_ERROR', cause);\n }\n}\n\nexport class SchemaValidationError extends ApiSdkGeneratorError {\n public constructor(message: string, cause?: unknown) {\n super(message, 'SCHEMA_VALIDATION_ERROR', cause);\n }\n}\n\nexport class UnsupportedSchemaError extends ApiSdkGeneratorError {\n public constructor(message: string, cause?: unknown) {\n super(message, 'UNSUPPORTED_SCHEMA_ERROR', cause);\n }\n}\n\nexport class OutputWriteError extends ApiSdkGeneratorError {\n public constructor(message: string, cause?: unknown) {\n super(message, 'OUTPUT_WRITE_ERROR', cause);\n }\n}\n","import prettier, { type Options } from 'prettier';\n\nimport type { GeneratedFile } from './types.js';\n\nconst GENERATED_FORMAT_OPTIONS = {\n printWidth: 100,\n semi: true,\n singleQuote: true,\n trailingComma: 'all',\n} satisfies Options;\n\nfunction getParser(filePath: string): 'markdown' | 'typescript' {\n return filePath.endsWith('.md') ? 'markdown' : 'typescript';\n}\n\nexport async function formatGeneratedFiles(files: GeneratedFile[]): Promise<GeneratedFile[]> {\n return Promise.all(\n files.map(async (file) => ({\n ...file,\n content: await prettier.format(file.content, {\n ...GENERATED_FORMAT_OPTIONS,\n parser: getParser(file.path),\n }),\n })),\n );\n}\n","import type { HttpMethod } from './types.js';\n\nconst RESERVED_WORDS = new Set([\n 'default',\n 'function',\n 'class',\n 'switch',\n 'case',\n 'var',\n 'const',\n 'let',\n 'new',\n 'delete',\n 'return',\n]);\n\nfunction splitWords(input: string): string[] {\n return input\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .split(/[^A-Za-z0-9]+/)\n .map((part) => part.trim())\n .filter(Boolean);\n}\n\nfunction capitalize(value: string): string {\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nexport function toPascalCase(input: string): string {\n const words = splitWords(input);\n const pascal = words.map((word) => capitalize(word.toLowerCase())).join('');\n return pascal || 'GeneratedType';\n}\n\nexport function toCamelCase(input: string): string {\n const pascal = toPascalCase(input);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n}\n\nexport function sanitizeIdentifier(input: string): string {\n const camel = toCamelCase(input).replace(/[^A-Za-z0-9_$]/g, '');\n const normalized = camel.match(/^[A-Za-z_$]/) ? camel : `_${camel}`;\n return RESERVED_WORDS.has(normalized) ? `${normalized}Value` : normalized;\n}\n\nexport function toTypeName(input: string): string {\n const pascal = toPascalCase(input).replace(/[^A-Za-z0-9_$]/g, '');\n return pascal.match(/^[A-Za-z_$]/) ? pascal : `T${pascal}`;\n}\n\nexport function toPropertyAccessor(name: string): string {\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);\n}\n\nexport function createFunctionName(method: HttpMethod, path: string, operationId?: string): string {\n if (operationId) {\n return sanitizeIdentifier(operationId);\n }\n\n const segments = path.split('/').filter(Boolean);\n const pieces: string[] = [method.toLowerCase()];\n const paramNames: string[] = [];\n\n for (const segment of segments) {\n const match = segment.match(/^\\{(.+)\\}$/);\n\n if (match) {\n paramNames.push(toPascalCase(match[1]));\n continue;\n }\n\n pieces.push(toPascalCase(segment));\n }\n\n if (paramNames.length > 0) {\n pieces.push(`By${paramNames.join('And')}`);\n }\n\n return sanitizeIdentifier(pieces.join(' '));\n}\n\nexport function deriveSdkName(input?: string): string {\n return input ? toTypeName(input) : 'GeneratedSdk';\n}\n","import { toTypeName } from '../naming.js';\nimport type { ParsedDocument, ParsedOperation } from '../types.js';\n\nfunction renderTemplatePath(path: string, operation: ParsedOperation): string {\n const parts: string[] = [];\n let offset = 0;\n for (const match of path.matchAll(/\\{([^}]+)\\}/g)) {\n const parameter = operation.pathParameters.find((item) => item.name === match[1]);\n if (!parameter) continue;\n parts.push(JSON.stringify(path.slice(offset, match.index)));\n parts.push(`encodeURIComponent(String(request[${JSON.stringify(parameter.name)}]))`);\n offset = match.index + match[0].length;\n }\n parts.push(JSON.stringify(path.slice(offset)));\n return parts.join(' + ');\n}\n\nfunction renderQueryLines(operation: ParsedOperation): string[] {\n return operation.queryParameters.map((parameter) => {\n const style = parameter.style ?? 'form';\n const explode = parameter.explode ?? style === 'form';\n const separator = style === 'spaceDelimited' ? ' ' : style === 'pipeDelimited' ? '|' : ',';\n return ` appendQueryParameter(searchParams, ${JSON.stringify(parameter.name)}, request[${JSON.stringify(parameter.name)}], ${explode}, ${JSON.stringify(separator)});`;\n });\n}\n\nfunction renderMethodSignature(operation: ParsedOperation): string {\n if (!operation.hasRequestShape) {\n return `${operation.functionName}(init?: RequestInit): Promise<${operation.responseTypeName}>;`;\n }\n\n if (operation.hasRequiredRequestFields) {\n return `${operation.functionName}(request: ${operation.requestTypeName}, init?: RequestInit): Promise<${operation.responseTypeName}>;`;\n }\n\n return `${operation.functionName}(request?: ${operation.requestTypeName}, init?: RequestInit): Promise<${operation.responseTypeName}>;`;\n}\n\nfunction renderMethodImplementation(operation: ParsedOperation): string {\n const requestParameter = operation.hasRequestShape\n ? operation.hasRequiredRequestFields\n ? 'request'\n : 'request = {}'\n : '';\n const queryLines = renderQueryLines(operation);\n const bodyContent =\n operation.requestBody?.contentType === 'application/json' ||\n operation.requestBody?.contentType?.endsWith('+json')\n ? [\n ' const body = request.body !== undefined ? JSON.stringify(request.body) : undefined;',\n ' if (body !== undefined && !headers.has(\"content-type\")) {',\n ` headers.set(\"content-type\", ${JSON.stringify(operation.requestBody.contentType)});`,\n ' }',\n ].join('\\n')\n : ' const body = undefined;';\n\n return [\n ` async ${operation.functionName}(${requestParameter}${requestParameter ? ', ' : ''}init?: RequestInit): Promise<${operation.responseTypeName}> {`,\n ` const url = resolveRequestUrl(resolveBaseUrl(config.baseUrl), ${renderTemplatePath(operation.path, operation)});`,\n ' const searchParams = url.searchParams;',\n ...(queryLines.length > 0 ? queryLines : [' void searchParams;']),\n ' const headers = new Headers(config.headers);',\n bodyContent,\n ' const response = await runtimeFetch(url, {',\n ' ...init,',\n ` method: ${JSON.stringify(operation.method.toUpperCase())},`,\n ' body,',\n ' headers: mergeHeaders(headers, init?.headers),',\n ' });',\n '',\n ' if (!response.ok) {',\n ' throw await ApiError.fromResponse(response);',\n ' }',\n '',\n ` return parseResponse<${operation.responseTypeName}>(response);`,\n ' },',\n ].join('\\n');\n}\n\nexport function generateClientSource(parsed: ParsedDocument): string {\n const clientName = `${toTypeName(parsed.sdkName)}Client`;\n const interfaceLines = parsed.operations.map(\n (operation) => ` ${renderMethodSignature(operation)}`,\n );\n const methodLines = parsed.operations.map((operation) => renderMethodImplementation(operation));\n\n return [\n '/* eslint-disable */',\n '/**',\n ' * Auto-generated by api-sdk-generator.',\n ' * Do not edit manually.',\n ' */',\n '',\n ...(parsed.operations.length > 0\n ? [\n 'import type {',\n ...parsed.operations.flatMap((operation) => [\n ...(operation.hasRequestShape ? [` ${operation.requestTypeName},`] : []),\n ` ${operation.responseTypeName},`,\n ]),\n \"} from './types.js';\",\n '',\n ]\n : []),\n 'export interface ClientConfig {',\n ' baseUrl?: string;',\n ' fetch?: typeof fetch;',\n ' headers?: HeadersInit;',\n '}',\n '',\n `export interface ${clientName} {`,\n ...interfaceLines,\n '}',\n '',\n 'export class ApiError extends Error {',\n ' public readonly body: unknown;',\n ' public readonly status: number;',\n ' public readonly headers: Headers;',\n '',\n ' public constructor(status: number, message: string, body: unknown, headers: Headers = new Headers()) {',\n ' super(message);',\n ' this.name = \"ApiError\";',\n ' this.status = status;',\n ' this.body = body;',\n ' this.headers = headers;',\n ' }',\n '',\n ' public static async fromResponse(response: Response): Promise<ApiError> {',\n ' const body = await parseResponseBody(response.clone()).catch(() => response.text());',\n ' return new ApiError(response.status, `Request failed with status ${response.status}`, body, response.headers);',\n ' }',\n '}',\n '',\n 'export function createClient(config: ClientConfig = {}): ' + clientName + ' {',\n ' const runtimeFetch = config.fetch ?? globalThis.fetch;',\n '',\n ' if (!runtimeFetch) {',\n ' throw new Error(\"Fetch API is not available in the current runtime.\");',\n ' }',\n '',\n ' return {',\n ...methodLines,\n ' };',\n '}',\n '',\n ...(parsed.operations.length > 0\n ? [\n 'function resolveBaseUrl(baseUrl?: string): string {',\n ` return baseUrl ?? ${JSON.stringify(parsed.defaultBaseUrl ?? 'http://localhost')};`,\n '}',\n '',\n 'function resolveRequestUrl(baseUrl: string, requestPath: string): URL {',\n ' const normalizedBaseUrl = baseUrl.endsWith(\"/\") ? baseUrl : `${baseUrl}/`;',\n ' return new URL(requestPath.replace(/^\\\\/+/, \"\"), normalizedBaseUrl);',\n '}',\n '',\n 'async function parseResponse<T>(response: Response): Promise<T> {',\n ' return (await parseResponseBody(response)) as T;',\n '}',\n '',\n ]\n : []),\n 'async function parseResponseBody(response: Response): Promise<unknown> {',\n ' if (response.status === 204 || response.status === 205) {',\n ' return undefined;',\n ' }',\n '',\n ' const body = await response.text();',\n '',\n ' if (!body) {',\n ' return undefined;',\n ' }',\n '',\n ' const contentType = response.headers.get(\"content-type\") ?? \"\";',\n ' return isJsonContentType(contentType) ? (JSON.parse(body) as unknown) : body;',\n '}',\n '',\n 'function isJsonContentType(contentType: string): boolean {',\n ' const mediaType = contentType.split(\";\", 1)[0].trim().toLowerCase();',\n ' return mediaType === \"application/json\" || mediaType.endsWith(\"+json\");',\n '}',\n '',\n ...(parsed.operations.some((operation) => operation.queryParameters.length > 0)\n ? [\n 'function appendQueryParameter(params: URLSearchParams, name: string, value: unknown, explode: boolean, separator: string): void {',\n ' if (value === undefined) return;',\n ' if (Array.isArray(value)) {',\n ' if (explode) {',\n ' for (const item of value) params.append(name, String(item));',\n ' } else {',\n ' params.set(name, value.map(String).join(separator));',\n ' }',\n ' } else {',\n ' params.set(name, String(value));',\n ' }',\n '}',\n '',\n ]\n : []),\n ...(parsed.operations.length > 0\n ? [\n 'function mergeHeaders(baseHeaders: Headers, initHeaders?: HeadersInit): Headers {',\n ' const merged = new Headers(baseHeaders);',\n '',\n ' if (initHeaders) {',\n ' const overlay = new Headers(initHeaders);',\n ' overlay.forEach((value, key) => merged.set(key, value));',\n ' }',\n '',\n ' return merged;',\n '}',\n '',\n ]\n : []),\n ].join('\\n');\n}\n","export function generateIndexSource(): string {\n return [\"export * from './types.js';\", \"export * from './client.js';\", ''].join('\\n');\n}\n","import type { ParsedDocument } from '../types.js';\n\nexport function generateGeneratedReadme(parsed: ParsedDocument): string {\n const exampleOperation = parsed.operations[0];\n const exampleCall = exampleOperation?.hasRequestShape\n ? `${exampleOperation.functionName}({ /* request */ })`\n : `${exampleOperation?.functionName ?? 'listResources'}()`;\n\n return [\n `# ${parsed.sdkName}`,\n '',\n 'This SDK was generated by `api-sdk-generator`.',\n '',\n '## Usage',\n '',\n '```ts',\n \"import { createClient } from './index';\",\n '',\n 'const client = createClient({',\n ` baseUrl: ${JSON.stringify(parsed.defaultBaseUrl ?? 'https://api.example.com')},`,\n '});',\n '',\n `await client.${exampleCall};`,\n '```',\n '',\n ].join('\\n');\n}\n","import type { OpenAPIV3 } from 'openapi-types';\n\nimport { SchemaValidationError } from './errors.js';\nimport type { OpenApiDocument, SchemaLike } from './types.js';\n\nexport function isReferenceObject(schema: SchemaLike): schema is OpenAPIV3.ReferenceObject {\n return '$ref' in schema;\n}\n\nexport function getReferenceName(ref: string): string {\n const match = ref.match(/^#\\/components\\/schemas\\/(.+)$/);\n\n if (!match) {\n throw new SchemaValidationError(\n `Only local component schema refs are supported. Received \"${ref}\".`,\n );\n }\n\n return decodePointerToken(match[1]);\n}\n\nexport function resolveSchema(\n document: OpenApiDocument,\n schema: SchemaLike,\n): OpenAPIV3.SchemaObject {\n if (!isReferenceObject(schema)) {\n return schema;\n }\n\n return resolveLocalComponent<OpenAPIV3.SchemaObject>(\n schema,\n document.components?.schemas,\n 'schemas',\n );\n}\n\nfunction decodePointerToken(token: string): string {\n return token.replace(/~1/g, '/').replace(/~0/g, '~');\n}\n\n/** Follow local component aliases while rejecting dangling or cyclic references. */\nexport function resolveLocalComponent<T extends object>(\n reference: OpenAPIV3.ReferenceObject,\n collection: Record<string, T | OpenAPIV3.ReferenceObject> | undefined,\n section: string,\n): T {\n const seen = new Set<string>();\n let current = reference;\n const prefix = `#/components/${section}/`;\n for (;;) {\n if (!current.$ref.startsWith(prefix)) {\n throw new SchemaValidationError(\n `Only local ${section} refs are supported. Received \"${current.$ref}\".`,\n );\n }\n if (seen.has(current.$ref)) {\n throw new SchemaValidationError(`Circular component reference \"${current.$ref}\".`);\n }\n seen.add(current.$ref);\n const name = decodePointerToken(current.$ref.slice(prefix.length));\n const resolved = collection && Object.hasOwn(collection, name) ? collection[name] : undefined;\n if (!resolved) {\n throw new SchemaValidationError(`Unable to resolve ${section} reference \"${current.$ref}\".`);\n }\n if ('$ref' in resolved) {\n current = resolved;\n } else {\n return resolved;\n }\n }\n}\n","import type { OpenAPIV3 } from 'openapi-types';\n\nimport { SchemaValidationError } from './errors.js';\nimport type { OpenApiDocument } from './types.js';\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function validateOpenApiDocument(value: unknown): OpenApiDocument {\n if (!isObject(value)) {\n throw new SchemaValidationError('OpenAPI document must be a JSON object.');\n }\n\n if (typeof value.openapi !== 'string' || !value.openapi.startsWith('3.')) {\n throw new SchemaValidationError('Only OpenAPI 3.x documents are supported.');\n }\n\n if (!isObject(value.info) || typeof value.info.title !== 'string') {\n throw new SchemaValidationError('OpenAPI document must contain info.title.');\n }\n\n if (!isObject(value.paths)) {\n throw new SchemaValidationError('OpenAPI document must contain a paths object.');\n }\n\n return value as unknown as OpenApiDocument;\n}\n\nexport function isSchemaObject(value: unknown): value is OpenAPIV3.SchemaObject {\n return isObject(value) && !('$ref' in value);\n}\n","import type { OpenAPIV3 } from 'openapi-types';\n\nimport { UnsupportedSchemaError } from '../errors.js';\nimport { toPropertyAccessor, toTypeName } from '../naming.js';\nimport { getReferenceName, isReferenceObject, resolveSchema } from '../resolver.js';\nimport type { OpenApiDocument, ParsedDocument, ParsedOperation, SchemaLike } from '../types.js';\nimport { isSchemaObject } from '../validator.js';\n\ninterface TypeRenderContext {\n document: OpenApiDocument;\n}\n\nfunction quoteEnumValue(value: string | number | boolean | null): string {\n return typeof value === 'string' ? JSON.stringify(value) : String(value);\n}\n\nfunction normalizeNullable(rendered: string, schema: OpenAPIV3.SchemaObject): string {\n return schema.nullable ? `${rendered} | null` : rendered;\n}\n\nfunction renderObjectType(schema: OpenAPIV3.SchemaObject, context: TypeRenderContext): string {\n const required = new Set(schema.required ?? []);\n const properties = schema.properties ?? {};\n const propertyEntries = Object.entries(properties);\n\n if (propertyEntries.length === 0) {\n if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {\n return `Record<string, ${renderSchema(schema.additionalProperties, context)}>`;\n }\n\n return schema.additionalProperties === false\n ? 'Record<string, never>'\n : 'Record<string, unknown>';\n }\n\n const lines = propertyEntries.map(([name, propertySchema]) => {\n const propertyType = renderSchema(propertySchema, context);\n const optionalToken = required.has(name) ? '' : '?';\n return ` ${toPropertyAccessor(name)}${optionalToken}: ${propertyType};`;\n });\n\n const objectType = ['{', ...lines, '}'].join('\\n');\n if (schema.additionalProperties) {\n const valueType =\n schema.additionalProperties === true\n ? 'unknown'\n : renderSchema(schema.additionalProperties, context);\n return `${objectType} & Record<string, ${valueType}>`;\n }\n return objectType;\n}\n\nexport function renderSchema(schema: SchemaLike, context: TypeRenderContext): string {\n if (isReferenceObject(schema)) {\n resolveSchema(context.document, schema);\n return toTypeName(getReferenceName(schema.$ref));\n }\n\n if (schema.enum && schema.enum.length > 0) {\n return normalizeNullable(schema.enum.map(quoteEnumValue).join(' | '), schema);\n }\n\n if (schema.oneOf && schema.oneOf.length > 0) {\n return normalizeNullable(\n schema.oneOf.map((item) => renderSchema(item, context)).join(' | '),\n schema,\n );\n }\n\n if (schema.anyOf && schema.anyOf.length > 0) {\n return normalizeNullable(\n schema.anyOf.map((item) => `(${renderSchema(item, context)})`).join(' | '),\n schema,\n );\n }\n\n if (schema.allOf && schema.allOf.length > 0) {\n return normalizeNullable(\n schema.allOf.map((item) => `(${renderSchema(item, context)})`).join(' & '),\n schema,\n );\n }\n\n if (schema.type === 'array') {\n if (!schema.items) {\n throw new UnsupportedSchemaError('Array schema must define items.');\n }\n\n return normalizeNullable(`Array<${renderSchema(schema.items, context)}>`, schema);\n }\n\n if (schema.type === 'object' || schema.properties || schema.additionalProperties) {\n return normalizeNullable(renderObjectType(schema, context), schema);\n }\n\n if (schema.type === 'string') {\n return normalizeNullable('string', schema);\n }\n\n if (schema.type === 'number' || schema.type === 'integer') {\n return normalizeNullable('number', schema);\n }\n\n if (schema.type === 'boolean') {\n return normalizeNullable('boolean', schema);\n }\n\n return 'unknown';\n}\n\nfunction renderNamedSchemaExport(\n name: string,\n schema: SchemaLike,\n context: TypeRenderContext,\n): string {\n if (isReferenceObject(schema)) {\n return `export type ${toTypeName(name)} = ${renderSchema(schema, context)};`;\n }\n\n const resolved = resolveSchema(context.document, schema);\n\n const rendered = renderSchema(resolved, context);\n if (\n rendered.startsWith('{') &&\n rendered.endsWith('}') &&\n !resolved.nullable &&\n !resolved.allOf &&\n !resolved.oneOf &&\n !resolved.anyOf &&\n !resolved.additionalProperties\n ) {\n return `export interface ${toTypeName(name)} ${rendered}`;\n }\n\n return `export type ${toTypeName(name)} = ${rendered};`;\n}\n\nfunction createRequestSchema(operation: ParsedOperation): OpenAPIV3.SchemaObject | undefined {\n const properties: Record<string, SchemaLike> = Object.create(null) as Record<string, SchemaLike>;\n const required: string[] = [];\n\n for (const parameter of [...operation.pathParameters, ...operation.queryParameters]) {\n properties[parameter.name] = parameter.schema;\n if (parameter.required) {\n required.push(parameter.name);\n }\n }\n\n if (operation.requestBody) {\n properties.body = operation.requestBody.schema;\n if (operation.requestBody.required) {\n required.push('body');\n }\n }\n\n if (Object.keys(properties).length === 0) {\n return undefined;\n }\n\n return {\n properties,\n required,\n type: 'object',\n };\n}\n\nfunction createResponseSchema(operation: ParsedOperation): SchemaLike | undefined {\n return operation.response.schema;\n}\n\nfunction renderOperationTypes(parsed: ParsedDocument, context: TypeRenderContext): string[] {\n const blocks: string[] = [];\n\n for (const operation of parsed.operations) {\n const requestSchema = createRequestSchema(operation);\n\n if (requestSchema) {\n blocks.push(renderNamedSchemaExport(operation.requestTypeName, requestSchema, context));\n } else {\n blocks.push(`export type ${operation.requestTypeName} = void;`);\n }\n\n const responseSchema = createResponseSchema(operation);\n\n if (responseSchema) {\n blocks.push(renderNamedSchemaExport(operation.responseTypeName, responseSchema, context));\n } else {\n blocks.push(`export type ${operation.responseTypeName} = void;`);\n }\n }\n\n return blocks;\n}\n\nexport function generateTypesSource(parsed: ParsedDocument): string {\n const context: TypeRenderContext = {\n document: parsed.document,\n };\n const componentBlocks = Object.entries(parsed.componentSchemas)\n .sort(([left], [right]) => left.localeCompare(right))\n .filter(([, schema]) => isReferenceObject(schema) || isSchemaObject(schema))\n .map(([name, schema]) => renderNamedSchemaExport(name, schema, context));\n const operationBlocks = renderOperationTypes(parsed, context);\n\n return [\n '/* eslint-disable */',\n '/**',\n ' * Auto-generated by api-sdk-generator.',\n ' * Do not edit manually.',\n ' */',\n '',\n 'export {};',\n '',\n ...componentBlocks,\n '',\n ...operationBlocks,\n '',\n ].join('\\n');\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { parseDocument as parseYamlDocument } from 'yaml';\n\nimport { ApiSdkGeneratorError, SchemaLoadError } from './errors.js';\nimport type { Logger } from './logger.js';\nimport type { GenerateSdkInput, OpenApiDocument } from './types.js';\nimport { validateOpenApiDocument } from './validator.js';\n\nexport interface LoadSchemaOptions {\n fetchImplementation?: typeof fetch;\n logger?: Logger;\n signal?: AbortSignal;\n /** Maximum time for fetching a schema, including reading its body. */\n timeoutMs?: number;\n}\n\nfunction parseSchema(content: string): OpenApiDocument {\n // JSON is a YAML subset. Limit aliases and reject duplicate keys rather than\n // silently replacing definitions in an API contract.\n const parsed = parseYamlDocument(content, { uniqueKeys: true });\n if (parsed.errors.length > 0) {\n throw new SchemaLoadError(`Invalid JSON or YAML: ${parsed.errors[0].message}`);\n }\n const document = parsed.toJS({ maxAliasCount: 100 }) as unknown;\n rejectAliasCycles(document);\n return validateOpenApiDocument(document);\n}\n\nfunction rejectAliasCycles(\n value: unknown,\n active = new WeakSet<object>(),\n seen = new WeakSet<object>(),\n): void {\n if (typeof value !== 'object' || value === null) return;\n if (active.has(value))\n throw new SchemaLoadError(\n 'Cyclic YAML aliases are unsupported. Use OpenAPI $ref for recursive models.',\n );\n if (seen.has(value)) return;\n active.add(value);\n for (const child of Object.values(value)) rejectAliasCycles(child, active, seen);\n active.delete(value);\n seen.add(value);\n}\n\nexport async function loadOpenApiDocument(\n input: GenerateSdkInput,\n options: LoadSchemaOptions = {},\n): Promise<OpenApiDocument> {\n const sources = [input.file, input.url].filter(Boolean);\n\n if (sources.length !== 1) {\n throw new SchemaLoadError('Exactly one input source must be provided: either file or url.');\n }\n\n if (input.file) {\n return loadOpenApiDocumentFromFile(input.file, options.logger);\n }\n\n return loadOpenApiDocumentFromUrl(\n input.url!,\n options.fetchImplementation,\n options.logger,\n options,\n );\n}\n\nexport async function loadOpenApiDocumentFromFile(\n filePath: string,\n logger?: Logger,\n): Promise<OpenApiDocument> {\n try {\n logger?.debug(`Loading OpenAPI schema from file: ${filePath}`);\n const content = await readFile(filePath, 'utf8');\n return parseSchema(content);\n } catch (error) {\n if (error instanceof ApiSdkGeneratorError) {\n throw error;\n }\n\n throw new SchemaLoadError(\n `Failed to load OpenAPI schema from file \"${path.resolve(filePath)}\".`,\n error,\n );\n }\n}\n\nexport async function loadOpenApiDocumentFromUrl(\n url: string,\n fetchImplementation?: typeof fetch,\n logger?: Logger,\n options: Pick<LoadSchemaOptions, 'signal' | 'timeoutMs'> = {},\n): Promise<OpenApiDocument> {\n const runtimeFetch = fetchImplementation ?? globalThis.fetch;\n const timeoutMs = options.timeoutMs ?? 30_000;\n if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2_147_483_647) {\n throw new SchemaLoadError(\n 'Schema timeout must be a positive integer no greater than 2147483647 milliseconds.',\n );\n }\n const timeoutSignal = AbortSignal.timeout(timeoutMs);\n const signal = options.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal;\n\n if (!runtimeFetch) {\n throw new SchemaLoadError('Fetch API is not available in the current runtime.');\n }\n\n try {\n if (!['http:', 'https:'].includes(new URL(url).protocol)) {\n throw new SchemaLoadError('Schema URLs must use HTTP or HTTPS.');\n }\n signal.throwIfAborted();\n logger?.debug(`Loading OpenAPI schema from URL: ${url}`);\n const response = await runtimeFetch(url, { signal });\n\n if (!response.ok) {\n throw new SchemaLoadError(\n `Failed to fetch OpenAPI schema from \"${url}\". HTTP ${response.status}.`,\n );\n }\n\n return parseSchema(await response.text());\n } catch (error) {\n if (error instanceof ApiSdkGeneratorError) {\n throw error;\n }\n\n if (timeoutSignal.aborted && !options.signal?.aborted) {\n throw new SchemaLoadError(\n `Timed out loading OpenAPI schema after ${timeoutMs} milliseconds.`,\n error,\n );\n }\n\n throw new SchemaLoadError(`Failed to load OpenAPI schema from URL \"${url}\".`, error);\n }\n}\n","export interface Logger {\n info(message: string): void;\n warn(message: string): void;\n error(message: string): void;\n debug(message: string): void;\n}\n\nexport interface CreateLoggerOptions {\n sink?: Pick<typeof console, 'info' | 'warn' | 'error'>;\n verbose?: boolean;\n}\n\nclass NoopLogger implements Logger {\n public info(): void {}\n\n public warn(): void {}\n\n public error(): void {}\n\n public debug(): void {}\n}\n\nexport const noopLogger: Logger = new NoopLogger();\n\nexport function createLogger(options: CreateLoggerOptions = {}): Logger {\n const sink = options.sink ?? console;\n const verbose = options.verbose ?? false;\n\n return {\n debug(message: string): void {\n if (verbose) {\n sink.info(message);\n }\n },\n error(message: string): void {\n sink.error(message);\n },\n info(message: string): void {\n sink.info(message);\n },\n warn(message: string): void {\n sink.warn(message);\n },\n };\n}\n","import type { OpenAPIV3 } from 'openapi-types';\n\nimport { SchemaValidationError, UnsupportedSchemaError } from './errors.js';\nimport { createFunctionName, deriveSdkName, toTypeName } from './naming.js';\nimport { resolveLocalComponent, resolveSchema } from './resolver.js';\nimport type {\n HttpMethod,\n OpenApiDocument,\n ParsedDocument,\n ParsedOperation,\n ParsedParameter,\n ParsedRequestBody,\n ParsedResponse,\n SchemaLike,\n} from './types.js';\n\nconst SUPPORTED_METHODS: readonly HttpMethod[] = [\n 'get',\n 'post',\n 'put',\n 'patch',\n 'delete',\n 'head',\n 'options',\n];\n\nfunction getParameterSchema(\n document: OpenApiDocument,\n parameter: OpenAPIV3.ParameterObject,\n): SchemaLike {\n if (!parameter.schema) {\n throw new UnsupportedSchemaError(\n `Parameter \"${parameter.name}\" in \"${parameter.in}\" is missing schema definition.`,\n );\n }\n\n resolveSchema(document, parameter.schema);\n return parameter.schema;\n}\n\nfunction dereferenceParameter(\n document: OpenApiDocument,\n parameter: OpenAPIV3.ReferenceObject | OpenAPIV3.ParameterObject,\n): OpenAPIV3.ParameterObject {\n if (!('$ref' in parameter)) {\n return parameter;\n }\n\n return resolveLocalComponent(parameter, document.components?.parameters, 'parameters');\n}\n\nfunction extractParameters(\n document: OpenApiDocument,\n parameters: Array<OpenAPIV3.ReferenceObject | OpenAPIV3.ParameterObject> | undefined,\n): ParsedParameter[] {\n return (parameters ?? [])\n .map((parameter) => dereferenceParameter(document, parameter))\n .filter((parameter) => parameter.in === 'path' || parameter.in === 'query')\n .map((parameter) => ({\n description: parameter.description,\n explode: parameter.explode,\n style: parameter.style,\n in: parameter.in === 'path' ? 'path' : 'query',\n name: parameter.name,\n required: parameter.in === 'path' ? true : (parameter.required ?? false),\n schema: getParameterSchema(document, parameter),\n }));\n}\n\nfunction mergeParameters(\n document: OpenApiDocument,\n pathParameters: Array<OpenAPIV3.ReferenceObject | OpenAPIV3.ParameterObject> | undefined,\n operationParameters: Array<OpenAPIV3.ReferenceObject | OpenAPIV3.ParameterObject> | undefined,\n): ParsedParameter[] {\n const merged = new Map<string, ParsedParameter>();\n\n for (const parameter of extractParameters(document, pathParameters)) {\n merged.set(`${parameter.in}:${parameter.name}`, parameter);\n }\n\n for (const parameter of extractParameters(document, operationParameters)) {\n merged.set(`${parameter.in}:${parameter.name}`, parameter);\n }\n\n return [...merged.values()];\n}\n\nfunction getJsonContent<TContent>(container: { content?: Record<string, TContent> }): {\n contentType: string;\n value: TContent;\n} | null {\n const content = container.content ?? {};\n const entries = Object.entries(content);\n\n for (const [contentType, value] of entries) {\n if (contentType === 'application/json' || contentType.endsWith('+json')) {\n return { contentType, value };\n }\n }\n\n return null;\n}\n\nfunction extractRequestBody(\n document: OpenApiDocument,\n requestBody: OpenAPIV3.ReferenceObject | OpenAPIV3.RequestBodyObject | undefined,\n): ParsedRequestBody | undefined {\n if (!requestBody) {\n return undefined;\n }\n\n const resolved = '$ref' in requestBody ? resolveRequestBody(document, requestBody) : requestBody;\n const jsonContent = getJsonContent(resolved);\n\n if (!jsonContent) {\n throw new UnsupportedSchemaError('Only JSON request bodies are supported.');\n }\n\n const schema = jsonContent.value.schema;\n\n if (!schema) {\n throw new UnsupportedSchemaError('JSON request body must include a schema.');\n }\n\n return {\n contentType: jsonContent.contentType,\n required: resolved.required ?? false,\n schema,\n };\n}\n\nfunction resolveRequestBody(\n document: OpenApiDocument,\n requestBody: OpenAPIV3.ReferenceObject,\n): OpenAPIV3.RequestBodyObject {\n return resolveLocalComponent(requestBody, document.components?.requestBodies, 'requestBodies');\n}\n\nfunction extractResponse(operation: OpenAPIV3.OperationObject): {\n response: OpenAPIV3.ReferenceObject | OpenAPIV3.ResponseObject;\n statusCode: string;\n} {\n const entries = Object.entries(operation.responses ?? {});\n const successfulEntry = entries.find(([status]) => /^2(?:\\d\\d|XX)$/i.test(status)) ?? entries[0];\n\n if (!successfulEntry) {\n return {\n response: {\n description: 'No content',\n },\n statusCode: '204',\n };\n }\n\n return {\n response: successfulEntry[1],\n statusCode: successfulEntry[0],\n };\n}\n\nfunction resolveResponse(\n document: OpenApiDocument,\n response: OpenAPIV3.ReferenceObject | OpenAPIV3.ResponseObject,\n): OpenAPIV3.ResponseObject {\n if (!('$ref' in response)) {\n return response;\n }\n\n return resolveLocalComponent(response, document.components?.responses, 'responses');\n}\n\nfunction parseResponse(\n document: OpenApiDocument,\n operation: OpenAPIV3.OperationObject,\n): ParsedResponse {\n const { response, statusCode } = extractResponse(operation);\n const resolved = resolveResponse(document, response);\n const jsonContent = getJsonContent(resolved);\n\n return {\n contentType: jsonContent?.contentType,\n description: resolved.description,\n schema: jsonContent?.value.schema,\n statusCode,\n };\n}\n\nfunction hasRequiredRequestFields(\n parameters: ParsedParameter[],\n requestBody?: ParsedRequestBody,\n): boolean {\n return parameters.some((parameter) => parameter.required) || Boolean(requestBody?.required);\n}\n\nexport function parseDocument(\n document: OpenApiDocument,\n options: {\n baseUrl?: string;\n sdkName?: string;\n } = {},\n): ParsedDocument {\n const operations: ParsedOperation[] = [];\n const functionNames = new Set<string>();\n const typeNames = new Set<string>([\n 'ClientConfig',\n 'ApiError',\n `${deriveSdkName(options.sdkName ?? document.info.title)}Client`,\n ]);\n for (const name of Object.keys(document.components?.schemas ?? {})) {\n const typeName = toTypeName(name);\n if (typeNames.has(typeName)) {\n throw new SchemaValidationError(`Duplicate or reserved generated type name \"${typeName}\".`);\n }\n typeNames.add(typeName);\n }\n\n for (const [pathKey, pathItem] of Object.entries(document.paths ?? {})) {\n if (!pathItem || '$ref' in pathItem) {\n throw new UnsupportedSchemaError(`Path-level $ref is not supported for path \"${pathKey}\".`);\n }\n\n if (pathItem.trace) {\n throw new UnsupportedSchemaError('TRACE operations are not supported by the Fetch API.');\n }\n for (const method of SUPPORTED_METHODS) {\n const operation = pathItem[method];\n\n if (!operation) {\n continue;\n }\n\n const functionName = createFunctionName(method, pathKey, operation.operationId);\n\n if (functionNames.has(functionName)) {\n throw new SchemaValidationError(\n `Duplicate generated operation name \"${functionName}\". Use unique operationId values.`,\n );\n }\n functionNames.add(functionName);\n const allocateTypeName = (base: string): string => {\n let name = base;\n let suffix = 2;\n while (typeNames.has(name)) name = `${base}${suffix++}`;\n typeNames.add(name);\n return name;\n };\n const requestTypeName = allocateTypeName(`${toTypeName(functionName)}Request`);\n const responseTypeName = allocateTypeName(`${toTypeName(functionName)}Response`);\n const mergedParameters = mergeParameters(document, pathItem.parameters, operation.parameters);\n const queryParameters = mergedParameters.filter((parameter) => parameter.in === 'query');\n const extractedPathParameters = mergedParameters.filter(\n (parameter) => parameter.in === 'path',\n );\n const requestBody = extractRequestBody(document, operation.requestBody);\n const response = parseResponse(document, operation);\n const requestNames = new Set<string>();\n for (const parameter of mergedParameters) {\n if (requestNames.has(parameter.name) || (parameter.name === 'body' && requestBody)) {\n throw new UnsupportedSchemaError(\n `Request field \"${parameter.name}\" collides in ${method.toUpperCase()} ${pathKey}.`,\n );\n }\n requestNames.add(parameter.name);\n if (parameter.in === 'query') {\n const schema = resolveSchema(document, parameter.schema);\n const style = parameter.style ?? 'form';\n if (\n schema.type === 'object' ||\n schema.properties ||\n !['form', 'spaceDelimited', 'pipeDelimited'].includes(style)\n ) {\n throw new UnsupportedSchemaError(\n `Unsupported query serialization for \"${parameter.name}\": ${style}.`,\n );\n }\n }\n }\n for (const match of pathKey.matchAll(/\\{([^}]+)\\}/g)) {\n if (!extractedPathParameters.some((parameter) => parameter.name === match[1])) {\n throw new SchemaValidationError(\n `Missing path parameter \"${match[1]}\" in ${method.toUpperCase()} ${pathKey}.`,\n );\n }\n }\n const hasRequestShape =\n extractedPathParameters.length + queryParameters.length > 0 || Boolean(requestBody);\n\n operations.push({\n description: operation.description,\n functionName,\n hasRequiredRequestFields: hasRequiredRequestFields(mergedParameters, requestBody),\n hasRequestShape,\n method,\n operationId: operation.operationId,\n path: pathKey,\n pathParameters: extractedPathParameters,\n queryParameters,\n requestBody,\n requestTypeName,\n response,\n responseTypeName,\n summary: operation.summary,\n });\n }\n }\n\n const sdkName = deriveSdkName(options.sdkName ?? document.info.title);\n const defaultBaseUrl = options.baseUrl ?? document.servers?.[0]?.url;\n\n return {\n componentSchemas: document.components?.schemas ?? {},\n defaultBaseUrl,\n document,\n operations,\n sdkName,\n };\n}\n","import { realpath } from 'node:fs/promises';\nimport path from 'node:path';\n\nexport function isWithinDirectory(root: string, target: string): boolean {\n const relative = path.relative(root, target);\n return relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);\n}\n\n/** Resolve symlinks in existing ancestors, including when the output does not exist yet. */\nexport async function canonicalPath(target: string): Promise<string> {\n const absolute = path.resolve(target);\n try {\n return await realpath(absolute);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n const parent = path.dirname(absolute);\n if (parent === absolute) throw error;\n return path.join(await canonicalPath(parent), path.basename(absolute));\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { lstat, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { OutputWriteError } from './errors.js';\nimport { canonicalPath, isWithinDirectory } from './paths.js';\nimport type { GeneratedFile } from './types.js';\n\ninterface ResolvedGeneratedFile extends GeneratedFile {\n fullPath: string;\n}\n\nfunction resolveGeneratedFiles(outputDir: string, files: GeneratedFile[]): ResolvedGeneratedFile[] {\n const outputRoot = path.resolve(outputDir);\n const seenPaths = new Set<string>();\n\n return files.map((file) => {\n const fullPath = path.resolve(outputRoot, file.path);\n const relativePath = path.relative(outputRoot, fullPath);\n\n if (!relativePath || !isWithinDirectory(outputRoot, fullPath)) {\n throw new OutputWriteError(\n `Generated file path \"${file.path}\" must stay within the output directory.`,\n );\n }\n\n if (seenPaths.has(fullPath)) {\n throw new OutputWriteError(`Duplicate generated file path \"${file.path}\".`);\n }\n\n seenPaths.add(fullPath);\n return { ...file, fullPath };\n });\n}\n\nasync function rejectSymlink(target: string): Promise<void> {\n try {\n if ((await lstat(target)).isSymbolicLink()) {\n throw new OutputWriteError(`Refusing to write through symbolic link \"${target}\".`);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n}\n\nasync function validateOutputPaths(\n outputDir: string,\n files: ResolvedGeneratedFile[],\n): Promise<void> {\n const root = path.resolve(outputDir);\n await rejectSymlink(root);\n for (const file of files) {\n let current = root;\n for (const segment of path.relative(root, file.fullPath).split(path.sep)) {\n current = path.join(current, segment);\n await rejectSymlink(current);\n }\n }\n}\n\nasync function writeFileAtomically(file: ResolvedGeneratedFile): Promise<void> {\n await mkdir(path.dirname(file.fullPath), { recursive: true });\n const temporaryPath = `${file.fullPath}.${randomUUID()}.tmp`;\n try {\n await writeFile(temporaryPath, file.content, { encoding: 'utf8', flag: 'wx' });\n await rename(temporaryPath, file.fullPath);\n } finally {\n await rm(temporaryPath, { force: true });\n }\n}\n\nexport async function writeGeneratedFiles(\n outputDir: string,\n files: GeneratedFile[],\n clean = false,\n): Promise<void> {\n try {\n const resolvedFiles = resolveGeneratedFiles(outputDir, files);\n await validateOutputPaths(outputDir, resolvedFiles);\n\n if (clean) {\n const outputRoot = await canonicalPath(outputDir);\n if (\n outputRoot === (await canonicalPath(os.homedir())) ||\n isWithinDirectory(outputRoot, await canonicalPath(process.cwd()))\n ) {\n throw new OutputWriteError(\n 'Refusing to clean the home directory, working directory, or its ancestors.',\n );\n }\n await rm(outputDir, { force: true, recursive: true });\n }\n\n await mkdir(outputDir, { recursive: true });\n\n await Promise.all(resolvedFiles.map(writeFileAtomically));\n } catch (error) {\n if (error instanceof OutputWriteError) {\n throw error;\n }\n\n throw new OutputWriteError(`Failed to write generated SDK to \"${outputDir}\".`, error);\n }\n}\n\n/** Compare only generated files; unrelated files are left alone. */\nexport async function compareGeneratedFiles(\n outputDir: string,\n files: GeneratedFile[],\n): Promise<string[]> {\n const changedFiles: string[] = [];\n const resolvedFiles = resolveGeneratedFiles(outputDir, files);\n await validateOutputPaths(outputDir, resolvedFiles);\n for (const file of resolvedFiles) {\n try {\n if ((await readFile(file.fullPath, 'utf8')) !== file.content) {\n changedFiles.push(file.path);\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n changedFiles.push(file.path);\n } else {\n throw new OutputWriteError(`Failed to compare generated file \"${file.fullPath}\".`, error);\n }\n }\n }\n return changedFiles;\n}\n","import { OutputWriteError } from './errors.js';\nimport { formatGeneratedFiles } from './formatter.js';\nimport { generateClientSource } from './generator/client-generator.js';\nimport { generateIndexSource } from './generator/index-generator.js';\nimport { generateGeneratedReadme } from './generator/readme-generator.js';\nimport { generateTypesSource } from './generator/type-generator.js';\nimport { loadOpenApiDocument } from './loader.js';\nimport { noopLogger } from './logger.js';\nimport { parseDocument } from './parser.js';\nimport { canonicalPath, isWithinDirectory } from './paths.js';\nimport type { GenerateSdkOptions, GenerateSdkResult } from './types.js';\nimport { compareGeneratedFiles, writeGeneratedFiles } from './writer.js';\n\nexport async function generateSdk(options: GenerateSdkOptions): Promise<GenerateSdkResult> {\n const logger = options.logger ?? noopLogger;\n\n if (options.check && options.dryRun) {\n throw new OutputWriteError('The check and dryRun options cannot be combined.');\n }\n if (options.clean && !options.check && !options.dryRun && options.input.file) {\n if (\n isWithinDirectory(\n await canonicalPath(options.outputDir),\n await canonicalPath(options.input.file),\n )\n ) {\n throw new OutputWriteError('Cannot clean an output directory containing the input schema.');\n }\n }\n\n logger.info('Loading OpenAPI document');\n const document = await loadOpenApiDocument(options.input, {\n fetchImplementation: options.fetchImplementation,\n logger,\n signal: options.signal,\n timeoutMs: options.schemaTimeoutMs,\n });\n\n logger.info('Parsing OpenAPI document');\n const parsed = parseDocument(document, {\n baseUrl: options.baseUrl,\n sdkName: options.sdkName,\n });\n\n logger.info(`Generating SDK for ${parsed.operations.length} operations`);\n const files = await formatGeneratedFiles([\n {\n content: generateTypesSource(parsed),\n path: 'types.ts',\n },\n {\n content: generateClientSource(parsed),\n path: 'client.ts',\n },\n {\n content: generateIndexSource(),\n path: 'index.ts',\n },\n {\n content: generateGeneratedReadme(parsed),\n path: 'README.md',\n },\n ]);\n\n const changedFiles = options.check ? await compareGeneratedFiles(options.outputDir, files) : [];\n if (!options.check && !options.dryRun) {\n logger.info(`Writing SDK to ${options.outputDir}`);\n await writeGeneratedFiles(options.outputDir, files, options.clean);\n }\n\n return {\n changedFiles,\n files,\n operations: parsed.operations.length,\n outputDir: options.outputDir,\n sdkName: parsed.sdkName,\n };\n}\n"],"mappings":"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","names":["prettier","path","path","parseYamlDocument","path","import_promises","import_node_path","path","import_promises","import_node_path","path","os"]}
package/dist/index.d.cts CHANGED
@@ -50,6 +50,8 @@ interface GenerateSdkOptions {
50
50
  /** Compare generated files with disk without writing them. */
51
51
  check?: boolean;
52
52
  fetchImplementation?: typeof fetch;
53
+ signal?: AbortSignal;
54
+ schemaTimeoutMs?: number;
53
55
  logger?: Logger;
54
56
  }
55
57
  interface GeneratedFile {
@@ -113,10 +115,13 @@ declare function generateSdk(options: GenerateSdkOptions): Promise<GenerateSdkRe
113
115
  interface LoadSchemaOptions {
114
116
  fetchImplementation?: typeof fetch;
115
117
  logger?: Logger;
118
+ signal?: AbortSignal;
119
+ /** Maximum time for fetching a schema, including reading its body. */
120
+ timeoutMs?: number;
116
121
  }
117
122
  declare function loadOpenApiDocument(input: GenerateSdkInput, options?: LoadSchemaOptions): Promise<OpenApiDocument>;
118
123
  declare function loadOpenApiDocumentFromFile(filePath: string, logger?: Logger): Promise<OpenApiDocument>;
119
- declare function loadOpenApiDocumentFromUrl(url: string, fetchImplementation?: typeof fetch, logger?: Logger): Promise<OpenApiDocument>;
124
+ declare function loadOpenApiDocumentFromUrl(url: string, fetchImplementation?: typeof fetch, logger?: Logger, options?: Pick<LoadSchemaOptions, 'signal' | 'timeoutMs'>): Promise<OpenApiDocument>;
120
125
 
121
126
  declare function toPascalCase(input: string): string;
122
127
  declare function toCamelCase(input: string): string;