@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 +3 -2
- package/dist/index.cjs +114 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +111 -29
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
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
|
-
|
|
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
|
-
|
|
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(
|
|
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/
|
|
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 =
|
|
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 =
|
|
950
|
-
const relativePath =
|
|
951
|
-
if (!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 =
|
|
968
|
-
|
|
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,
|
|
1058
|
+
await (0, import_promises3.rm)(outputDir, { force: true, recursive: true });
|
|
975
1059
|
}
|
|
976
|
-
await (0,
|
|
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
|
-
|
|
1071
|
+
const resolvedFiles = resolveGeneratedFiles(outputDir, files);
|
|
1072
|
+
await validateOutputPaths(outputDir, resolvedFiles);
|
|
1073
|
+
for (const file of resolvedFiles) {
|
|
993
1074
|
try {
|
|
994
|
-
if (await (0,
|
|
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
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
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, {
|
package/dist/index.cjs.map
CHANGED
|
@@ -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;
|