@eulerstream/openapi-generator-examples
Advanced tools
| // src/languages/registry.ts | ||
| var byId = /* @__PURE__ */ new Map(); | ||
| var byGenerator = /* @__PURE__ */ new Map(); | ||
| function registerLanguage(adapter) { | ||
| byId.set(adapter.id, adapter); | ||
| for (const gen of adapter.generatorNames) { | ||
| byGenerator.set(gen, adapter); | ||
| } | ||
| } | ||
| function getLanguageByGenerator(generatorName) { | ||
| return byGenerator.get(generatorName); | ||
| } | ||
| function getLanguageById(id) { | ||
| return byId.get(id); | ||
| } | ||
| function getAllLanguages() { | ||
| return [...byId.values()]; | ||
| } | ||
| // src/spec/parser.ts | ||
| import * as fs from "fs"; | ||
| import { parse as parseYaml } from "yaml"; | ||
| function parseSpec(specPath) { | ||
| const raw = fs.readFileSync(specPath, "utf-8"); | ||
| const spec = specPath.endsWith(".json") ? JSON.parse(raw) : parseYaml(raw); | ||
| return extractOperations(spec); | ||
| } | ||
| function extractOperations(spec) { | ||
| const paths = spec.paths; | ||
| if (!paths) return []; | ||
| const operations = []; | ||
| for (const [urlPath, methods] of Object.entries(paths)) { | ||
| for (const [method, opDef] of Object.entries(methods)) { | ||
| if (["get", "post", "put", "patch", "delete", "head", "options"].indexOf(method) === -1) { | ||
| continue; | ||
| } | ||
| const op = opDef; | ||
| if (!op.operationId) continue; | ||
| operations.push({ | ||
| operationId: op.operationId, | ||
| tag: (op.tags ?? ["Default"])[0], | ||
| httpMethod: method.toUpperCase(), | ||
| path: urlPath, | ||
| description: op.description, | ||
| parameters: normalizeParams(op.parameters, spec), | ||
| requestBody: normalizeRequestBody(op.requestBody, spec), | ||
| responseType: extractResponseType(op.responses, spec), | ||
| security: extractSecurity(op.security) | ||
| }); | ||
| } | ||
| } | ||
| return operations; | ||
| } | ||
| function normalizeParams(params, spec) { | ||
| if (!params) return []; | ||
| return params.map((p) => { | ||
| const param = resolveRef(p, spec); | ||
| const schema = resolveRef( | ||
| param.schema ?? { type: "string" }, | ||
| spec | ||
| ); | ||
| return { | ||
| name: param.name, | ||
| in: param.in, | ||
| required: param.required ?? false, | ||
| schema: normalizeSchema(schema, spec), | ||
| description: param.description, | ||
| example: param.example, | ||
| deprecated: param.deprecated ?? false | ||
| }; | ||
| }); | ||
| } | ||
| function normalizeRequestBody(body, spec) { | ||
| if (!body) return void 0; | ||
| const resolved = resolveRef(body, spec); | ||
| const content = resolved.content; | ||
| if (!content) return void 0; | ||
| const jsonContent = content["application/json"] ?? Object.values(content)[0]; | ||
| if (!jsonContent?.schema) return void 0; | ||
| const rawSchema = jsonContent.schema; | ||
| const schemaName = extractRefName(rawSchema); | ||
| const resolvedSchema = resolveRef(rawSchema, spec); | ||
| return { | ||
| required: resolved.required ?? false, | ||
| schemaName, | ||
| schema: normalizeSchema(resolvedSchema, spec) | ||
| }; | ||
| } | ||
| function normalizeSchema(schema, spec) { | ||
| const resolved = resolveRef(schema, spec); | ||
| const result = { | ||
| type: resolved.type ?? "object" | ||
| }; | ||
| if (resolved.format) result.format = resolved.format; | ||
| if (resolved.enum) result.enum = resolved.enum; | ||
| if (resolved.default !== void 0) result.default = resolved.default; | ||
| if (resolved.description) result.description = resolved.description; | ||
| if (resolved.items) { | ||
| result.items = normalizeSchema( | ||
| resolveRef(resolved.items, spec), | ||
| spec | ||
| ); | ||
| } | ||
| if (resolved.properties) { | ||
| const props = resolved.properties; | ||
| result.properties = {}; | ||
| for (const [name, propSchema] of Object.entries(props)) { | ||
| result.properties[name] = normalizeSchema( | ||
| resolveRef(propSchema, spec), | ||
| spec | ||
| ); | ||
| } | ||
| result.required = resolved.required ?? []; | ||
| } | ||
| return result; | ||
| } | ||
| function extractResponseType(responses, spec) { | ||
| if (!responses) return void 0; | ||
| const successResponse = responses["200"] ?? responses["201"]; | ||
| if (!successResponse) return void 0; | ||
| const resolved = resolveRef(successResponse, spec); | ||
| const content = resolved.content; | ||
| if (!content) return void 0; | ||
| const jsonContent = content["application/json"] ?? Object.values(content)[0]; | ||
| if (!jsonContent?.schema) return void 0; | ||
| return extractRefName(jsonContent.schema) ?? jsonContent.schema.type; | ||
| } | ||
| function extractSecurity(security) { | ||
| if (!security) return []; | ||
| const names = []; | ||
| for (const scheme of security) { | ||
| names.push(...Object.keys(scheme)); | ||
| } | ||
| return [...new Set(names)]; | ||
| } | ||
| function resolveRef(obj, spec) { | ||
| if (!obj || typeof obj !== "object") return obj; | ||
| const ref = obj["$ref"]; | ||
| if (!ref) return obj; | ||
| const parts = ref.replace(/^#\//, "").split("/"); | ||
| let current = spec; | ||
| for (const part of parts) { | ||
| if (current && typeof current === "object") { | ||
| current = current[part]; | ||
| } else { | ||
| return obj; | ||
| } | ||
| } | ||
| if (current && typeof current === "object") { | ||
| return current; | ||
| } | ||
| return obj; | ||
| } | ||
| function extractRefName(schema) { | ||
| const ref = schema["$ref"]; | ||
| if (!ref) return void 0; | ||
| const parts = ref.split("/"); | ||
| return parts[parts.length - 1]; | ||
| } | ||
| // src/templates/context.ts | ||
| function buildTemplateContext(op, config, adapter) { | ||
| const methodName = adapter.toMethodName(op.operationId); | ||
| const apiProperty = resolveApiProperty(op.tag, config.apiClassMap); | ||
| const apiClassName = adapter.toApiClassName(op.tag); | ||
| const params = op.parameters.filter((p) => !p.deprecated).map((p) => { | ||
| const override = resolveValueOverride(p.name, op.operationId, op.tag, config); | ||
| return toTemplateParam(p, adapter, override); | ||
| }); | ||
| const requiredParams = params.filter((p) => p.required); | ||
| const optionalParams = params.filter((p) => !p.required); | ||
| const paramDeclarations = op.parameters.filter((p) => !p.deprecated && p.required).map((p) => { | ||
| const override = resolveValueOverride(p.name, op.operationId, op.tag, config); | ||
| return adapter.buildParamDeclaration(p, override); | ||
| }).filter(Boolean).join("\n"); | ||
| const hasBody = !!op.requestBody; | ||
| const bodyTypeName = op.requestBody?.schemaName ?? ""; | ||
| const bodyOverrides = resolveBodyOverrides(op.requestBody, op.operationId, op.tag, config); | ||
| const bodyConstruction = op.requestBody ? adapter.buildBodyConstruction(op.requestBody, bodyOverrides) : ""; | ||
| const argParts = []; | ||
| for (const p of op.parameters.filter((p2) => !p2.deprecated && p2.required)) { | ||
| argParts.push(p.name); | ||
| } | ||
| if (hasBody) { | ||
| argParts.push("body"); | ||
| } | ||
| const args = argParts.join(", "); | ||
| const clientVar = config.variables.clientVar ?? "client"; | ||
| const apiAccessPattern = config.variables.apiAccessPattern ?? "dot"; | ||
| const methodCall = adapter.buildMethodCall({ | ||
| clientVar, | ||
| apiProperty, | ||
| methodName, | ||
| args, | ||
| apiAccessPattern | ||
| }); | ||
| const resultLine = adapter.buildResultLine(methodCall, op.responseType); | ||
| return { | ||
| operationId: op.operationId, | ||
| methodName, | ||
| tag: op.tag, | ||
| httpMethod: op.httpMethod, | ||
| path: op.path, | ||
| description: op.description ?? "", | ||
| apiProperty, | ||
| apiClassName, | ||
| params, | ||
| hasParams: params.length > 0, | ||
| requiredParams, | ||
| optionalParams, | ||
| hasRequiredParams: requiredParams.length > 0, | ||
| hasOptionalParams: optionalParams.length > 0, | ||
| hasBody, | ||
| bodyTypeName, | ||
| bodyConstruction, | ||
| paramDeclarations, | ||
| methodCall, | ||
| resultLine, | ||
| variables: config.variables, | ||
| boilerplate: config.boilerplate, | ||
| codeBlockLang: adapter.codeBlockLang | ||
| }; | ||
| } | ||
| function resolveApiProperty(tag, apiClassMap) { | ||
| if (apiClassMap[tag]) return apiClassMap[tag]; | ||
| return tag.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[A-Z]/, (c) => c.toLowerCase()); | ||
| } | ||
| function resolveValueOverride(paramName, operationId, tag, config) { | ||
| const ov = config.paramOverrides; | ||
| return ov.operations[operationId]?.[paramName] ?? ov.tags[tag]?.[paramName] ?? ov.global[paramName]; | ||
| } | ||
| function resolveBodyOverrides(body, operationId, tag, config) { | ||
| if (!body?.schema.properties) return void 0; | ||
| const result = {}; | ||
| let hasAny = false; | ||
| for (const propName of Object.keys(body.schema.properties)) { | ||
| const override = resolveValueOverride(propName, operationId, tag, config); | ||
| if (override !== void 0) { | ||
| result[propName] = override; | ||
| hasAny = true; | ||
| } | ||
| } | ||
| return hasAny ? result : void 0; | ||
| } | ||
| function toTemplateParam(param, adapter, valueOverride) { | ||
| return { | ||
| name: param.name, | ||
| type: adapter.mapType(param.schema), | ||
| description: param.description ?? "", | ||
| required: param.required, | ||
| defaultValue: param.schema.default != null ? String(param.schema.default) : "", | ||
| exampleValue: valueOverride ?? adapter.exampleValue(param), | ||
| hasDefault: param.schema.default != null | ||
| }; | ||
| } | ||
| // src/templates/renderer.ts | ||
| import * as fs2 from "fs"; | ||
| import * as path from "path"; | ||
| import Mustache from "mustache"; | ||
| Mustache.escape = (text) => text; | ||
| var templateCache = /* @__PURE__ */ new Map(); | ||
| function renderTemplate(templatePath, context) { | ||
| const template = loadTemplate(templatePath); | ||
| const rendered = Mustache.render(template, context); | ||
| return rendered.replace(/\n{3,}/g, "\n\n").trim() + "\n"; | ||
| } | ||
| function getDefaultTemplatePath(languageId) { | ||
| const srcPath = path.resolve( | ||
| import.meta.dirname ?? __dirname, | ||
| "defaults", | ||
| `${languageId}.mustache` | ||
| ); | ||
| if (fs2.existsSync(srcPath)) return srcPath; | ||
| const distPath = path.resolve( | ||
| import.meta.dirname ?? __dirname, | ||
| "..", | ||
| "templates", | ||
| "defaults", | ||
| `${languageId}.mustache` | ||
| ); | ||
| if (fs2.existsSync(distPath)) return distPath; | ||
| throw new Error( | ||
| `No default template found for language "${languageId}". Searched: ${srcPath}, ${distPath}` | ||
| ); | ||
| } | ||
| function loadTemplate(templatePath) { | ||
| const cached = templateCache.get(templatePath); | ||
| if (cached) return cached; | ||
| if (!fs2.existsSync(templatePath)) { | ||
| throw new Error(`Template not found: ${templatePath}`); | ||
| } | ||
| const content = fs2.readFileSync(templatePath, "utf-8"); | ||
| templateCache.set(templatePath, content); | ||
| return content; | ||
| } | ||
| // src/generator/pipeline.ts | ||
| import * as path3 from "path"; | ||
| // src/generator/writer.ts | ||
| import * as fs3 from "fs"; | ||
| import * as path2 from "path"; | ||
| function writeOperationFile(outputDir, op, renderedExample, context, adapter, formats) { | ||
| const tagDir = adapter.toTagDirectory(op.tag); | ||
| const fileName = adapter.toFileName(op.operationId); | ||
| const dirPath = path2.join(outputDir, adapter.id, tagDir); | ||
| fs3.mkdirSync(dirPath, { recursive: true }); | ||
| const filesWritten = []; | ||
| let json; | ||
| if (formats.includes("md")) { | ||
| const mdPath = path2.join(dirPath, fileName + ".md"); | ||
| const md = buildMarkdown(op, renderedExample, context); | ||
| fs3.writeFileSync(mdPath, md, "utf-8"); | ||
| filesWritten.push(mdPath); | ||
| } | ||
| if (formats.includes("json")) { | ||
| json = buildJson(op, renderedExample, context); | ||
| const jsonPath = path2.join(dirPath, fileName + ".json"); | ||
| fs3.writeFileSync(jsonPath, JSON.stringify(json, null, 2) + "\n", "utf-8"); | ||
| filesWritten.push(jsonPath); | ||
| } | ||
| return { filesWritten, json }; | ||
| } | ||
| function writeJsonIndex(outputDir, adapter, entries) { | ||
| const dirPath = path2.join(outputDir, adapter.id); | ||
| fs3.mkdirSync(dirPath, { recursive: true }); | ||
| fs3.writeFileSync( | ||
| path2.join(dirPath, "index.json"), | ||
| JSON.stringify(entries, null, 2) + "\n", | ||
| "utf-8" | ||
| ); | ||
| } | ||
| function writeLanguageIndex(outputDir, adapter, operations) { | ||
| const dirPath = path2.join(outputDir, adapter.id); | ||
| fs3.mkdirSync(dirPath, { recursive: true }); | ||
| const byTag = /* @__PURE__ */ new Map(); | ||
| for (const op of operations) { | ||
| const tag = op.tag; | ||
| if (!byTag.has(tag)) byTag.set(tag, []); | ||
| byTag.get(tag).push(op); | ||
| } | ||
| const lines = [`# Usage Examples (${adapter.id})`, ""]; | ||
| for (const [tag, ops] of byTag) { | ||
| const tagDir = adapter.toTagDirectory(tag); | ||
| lines.push(`## ${tag}`, ""); | ||
| lines.push("| Operation | Method | Path |"); | ||
| lines.push("|-----------|--------|------|"); | ||
| for (const op of ops) { | ||
| const fileName = adapter.toFileName(op.operationId); | ||
| lines.push(`| [${op.operationId}](./${tagDir}/${fileName}.md) | ${op.httpMethod} | \`${op.path}\` |`); | ||
| } | ||
| lines.push(""); | ||
| } | ||
| fs3.writeFileSync(path2.join(dirPath, "index.md"), lines.join("\n"), "utf-8"); | ||
| } | ||
| function buildJson(op, renderedExample, context) { | ||
| const json = { | ||
| operationId: op.operationId, | ||
| tag: op.tag, | ||
| httpMethod: op.httpMethod, | ||
| path: op.path, | ||
| description: op.description ?? "", | ||
| example: renderedExample.trimEnd(), | ||
| codeBlockLang: context.codeBlockLang, | ||
| parameters: context.params.map((p) => ({ | ||
| name: p.name, | ||
| type: p.type, | ||
| required: p.required, | ||
| description: p.description | ||
| })) | ||
| }; | ||
| if (context.hasBody && context.bodyTypeName) { | ||
| json.requestBody = { | ||
| typeName: context.bodyTypeName, | ||
| construction: context.bodyConstruction | ||
| }; | ||
| } | ||
| return json; | ||
| } | ||
| function buildMarkdown(op, renderedExample, context) { | ||
| const lines = []; | ||
| lines.push(`# ${op.operationId}`); | ||
| lines.push(""); | ||
| if (op.description) { | ||
| lines.push(op.description); | ||
| lines.push(""); | ||
| } | ||
| lines.push(`\`${op.httpMethod} ${op.path}\``); | ||
| lines.push(""); | ||
| lines.push("## Example"); | ||
| lines.push(""); | ||
| lines.push(`\`\`\`${context.codeBlockLang}`); | ||
| lines.push(renderedExample.trimEnd()); | ||
| lines.push("```"); | ||
| lines.push(""); | ||
| if (context.params.length > 0) { | ||
| lines.push("## Parameters"); | ||
| lines.push(""); | ||
| lines.push("| Name | Type | Required | Description |"); | ||
| lines.push("|------|------|----------|-------------|"); | ||
| for (const p of context.params) { | ||
| const req = p.required ? "Yes" : "No"; | ||
| const desc = p.description || "-"; | ||
| lines.push(`| \`${p.name}\` | \`${p.type}\` | ${req} | ${desc} |`); | ||
| } | ||
| lines.push(""); | ||
| } | ||
| if (context.hasBody) { | ||
| lines.push("## Request Body"); | ||
| lines.push(""); | ||
| lines.push(`Type: \`${context.bodyTypeName}\``); | ||
| lines.push(""); | ||
| } | ||
| return lines.join("\n"); | ||
| } | ||
| // src/generator/pipeline.ts | ||
| function generate(options) { | ||
| const { inputSpec, generator, outputDir, config } = options; | ||
| const adapter = getLanguageByGenerator(generator) ?? getLanguageById(generator); | ||
| if (!adapter) { | ||
| const msg = `Unknown generator/language: "${generator}". No language adapter registered for this identifier.`; | ||
| throw new Error(msg); | ||
| } | ||
| const usageDir = config.output ? path3.resolve(config.output) : path3.resolve(outputDir, "usage"); | ||
| const operations = parseSpec(inputSpec); | ||
| if (operations.length === 0) { | ||
| console.warn("No operations found in the OpenAPI spec."); | ||
| return { languageId: adapter.id, filesWritten: [], operationCount: 0 }; | ||
| } | ||
| const templatePath = config.templatePath ? path3.resolve(config.templatePath) : getDefaultTemplatePath(adapter.id); | ||
| const formats = config.outputFormats.length > 0 ? config.outputFormats : ["md"]; | ||
| const filesWritten = []; | ||
| const jsonEntries = []; | ||
| for (const op of operations) { | ||
| const context = buildTemplateContext(op, config, adapter); | ||
| const rendered = renderTemplate(templatePath, context); | ||
| const result = writeOperationFile(usageDir, op, rendered, context, adapter, formats); | ||
| filesWritten.push(...result.filesWritten); | ||
| if (result.json) jsonEntries.push(result.json); | ||
| } | ||
| writeLanguageIndex(usageDir, adapter, operations); | ||
| if (formats.includes("json") && jsonEntries.length > 0) { | ||
| writeJsonIndex(usageDir, adapter, jsonEntries); | ||
| } | ||
| return { | ||
| languageId: adapter.id, | ||
| filesWritten, | ||
| operationCount: operations.length | ||
| }; | ||
| } | ||
| // src/config/schema.ts | ||
| import { z } from "zod"; | ||
| var BoilerplateSchema = z.object({ | ||
| showTryCatch: z.boolean().default(false), | ||
| showImports: z.boolean().default(true), | ||
| showApiKeyConfig: z.boolean().default(false), | ||
| showFullClass: z.boolean().default(false) | ||
| }).default({}); | ||
| var ParamOverridesSchema = z.object({ | ||
| /** Global overrides applied to all operations */ | ||
| global: z.record(z.string(), z.string()).default({}), | ||
| /** Per-tag overrides (tag name → param name → value) */ | ||
| tags: z.record(z.string(), z.record(z.string(), z.string())).default({}), | ||
| /** Per-operation overrides (operationId → param name → value), highest priority */ | ||
| operations: z.record(z.string(), z.record(z.string(), z.string())).default({}) | ||
| }).default({}); | ||
| var ExamplesConfigSchema = z.object({ | ||
| /** Output directory for generated examples (default: ./usage relative to -o) */ | ||
| output: z.string().optional(), | ||
| /** Boilerplate control flags */ | ||
| boilerplate: BoilerplateSchema, | ||
| /** | ||
| * Template variables available in mustache templates. | ||
| * Well-known keys: | ||
| * sdkImport - import statement(s) for the SDK | ||
| * clientConstruction - code to construct the client instance | ||
| * clientVar - variable name for client (default: "client") | ||
| * apiKeyPlaceholder - placeholder for API key (default: "YOUR_API_KEY") | ||
| * apiAccessPattern - "dot" (client.api.method) or "call" (client.api().method) | ||
| */ | ||
| variables: z.record(z.string(), z.string()).default({}), | ||
| /** Maps OpenAPI tags -> wrapper property names (e.g., "TikTok LIVE": "webcast") */ | ||
| apiClassMap: z.record(z.string(), z.string()).default({}), | ||
| /** Path to a custom mustache template (overrides the built-in default for this language) */ | ||
| templatePath: z.string().optional(), | ||
| /** Output formats: "md" (markdown), "json", or both. Default: ["md"] */ | ||
| outputFormats: z.array(z.enum(["md", "json"])).default(["md"]), | ||
| /** | ||
| * Override example values for parameters and body properties. | ||
| * Values are raw code strings used as-is (no quoting/processing). | ||
| * Precedence: operations > tags > global (most-specific-wins). | ||
| */ | ||
| paramOverrides: ParamOverridesSchema | ||
| }); | ||
| // src/config/loader.ts | ||
| import * as fs4 from "fs"; | ||
| import { parse as parseYaml2 } from "yaml"; | ||
| var DEFAULTS = { | ||
| variables: { | ||
| clientVar: "apiInstance", | ||
| apiKeyPlaceholder: "YOUR_API_KEY", | ||
| apiAccessPattern: "direct", | ||
| sdkPackage: "./api" | ||
| } | ||
| }; | ||
| function loadConfig(configPath) { | ||
| if (!fs4.existsSync(configPath)) { | ||
| throw new Error(`Config file not found: ${configPath}`); | ||
| } | ||
| const raw = fs4.readFileSync(configPath, "utf-8"); | ||
| const parsed = parseYaml2(raw); | ||
| const merged = { | ||
| ...parsed, | ||
| variables: { | ||
| ...DEFAULTS.variables, | ||
| ...parsed?.variables | ||
| } | ||
| }; | ||
| const result = ExamplesConfigSchema.safeParse(merged); | ||
| if (!result.success) { | ||
| const issues = result.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n"); | ||
| throw new Error(`Invalid config: | ||
| ${issues}`); | ||
| } | ||
| return result.data; | ||
| } | ||
| function loadConfigOrDefault(configPath) { | ||
| if (configPath) { | ||
| return loadConfig(configPath); | ||
| } | ||
| return ExamplesConfigSchema.parse({ | ||
| variables: { ...DEFAULTS.variables } | ||
| }); | ||
| } | ||
| // src/languages/typescript.ts | ||
| function toCamelCase(str) { | ||
| if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toLowerCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[A-Z]/, (c) => c.toLowerCase()); | ||
| } | ||
| function toKebabCase(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").toLowerCase().replace(/^-|-$/g, ""); | ||
| } | ||
| function wrapOverrideForType(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "new Date()"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildObjectLiteral(schema, 0); | ||
| } | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema(schema.items, "item"); | ||
| return `[${itemValue}]`; | ||
| } | ||
| return "[]"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildObjectLiteral(schema, depth, valueOverrides) { | ||
| const props = schema.properties ?? {}; | ||
| const required = schema.required ?? []; | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = valueOverrides?.[propName]; | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildObjectLiteral(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${propName}: ${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{}"; | ||
| return "{\n" + entries.join("\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var typescriptAdapter = { | ||
| id: "typescript", | ||
| generatorNames: ["typescript-axios", "typescript-fetch", "typescript-angular", "typescript-node", "typescript"], | ||
| codeBlockLang: "typescript", | ||
| toMethodName(operationId) { | ||
| return toCamelCase(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toCamelCase(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toKebabCase(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "Date"; | ||
| } | ||
| return "string"; | ||
| case "integer": | ||
| case "number": | ||
| return "number"; | ||
| case "boolean": | ||
| return "boolean"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `${this.mapType(schema.items)}[]`; | ||
| } | ||
| return "unknown[]"; | ||
| case "object": | ||
| return "Record<string, unknown>"; | ||
| default: | ||
| return "unknown"; | ||
| } | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const tsType = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `let ${param.name}: ${tsType} = ${value};`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const objectLiteral = buildObjectLiteral(body.schema, 0, valueOverrides); | ||
| const opening = body.schemaName ? `const body: ${body.schemaName} = ` : `const body = `; | ||
| return opening + objectLiteral + ";"; | ||
| }, | ||
| buildResultLine(call, returnType) { | ||
| if (returnType) { | ||
| return `const { status, data } = await ${call};`; | ||
| } | ||
| return `await ${call};`; | ||
| } | ||
| }; | ||
| registerLanguage(typescriptAdapter); | ||
| // src/languages/python.ts | ||
| function toSnakeCase(str) { | ||
| return str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").toLowerCase().replace(/^_|_$/g, ""); | ||
| } | ||
| function toPascalCase(str) { | ||
| return str.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| } | ||
| function wrapOverrideForType2(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema2(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "datetime.now()"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "True"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildObjectLiteral2(schema, 0); | ||
| } | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema2(schema.items, "item"); | ||
| return `[${itemValue}]`; | ||
| } | ||
| return "[]"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildObjectLiteral2(schema, depth, valueOverrides, schemaName) { | ||
| const props = schema.properties ?? {}; | ||
| const required = schema.required ?? []; | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = valueOverrides?.[propName]; | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType2(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildObjectLiteral2(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema2(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${propName}=${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) { | ||
| return schemaName ? `${schemaName}()` : "{}"; | ||
| } | ||
| const opener = schemaName ? `${schemaName}( | ||
| ` : "{\n"; | ||
| const closer = schemaName ? `${closingIndent})` : `${closingIndent}}`; | ||
| return opener + entries.join("\n") + "\n" + closer; | ||
| } | ||
| var pythonAdapter = { | ||
| id: "python", | ||
| generatorNames: ["python", "python-pydantic-v1", "python-nextgen", "python-prior"], | ||
| codeBlockLang: "python", | ||
| toMethodName(operationId) { | ||
| return toSnakeCase(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toSnakeCase(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toSnakeCase(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = toPascalCase(tag); | ||
| const capitalized = stripped.charAt(0).toUpperCase() + stripped.slice(1); | ||
| return capitalized + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "datetime"; | ||
| } | ||
| return "str"; | ||
| case "integer": | ||
| return "int"; | ||
| case "number": | ||
| return "float"; | ||
| case "boolean": | ||
| return "bool"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `list[${this.mapType(schema.items)}]`; | ||
| } | ||
| return "list"; | ||
| case "object": | ||
| return "dict"; | ||
| default: | ||
| return "object"; | ||
| } | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema2(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const pyType = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType2(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${param.name}: ${pyType} = ${value}`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const literal = buildObjectLiteral2(body.schema, 0, valueOverrides, body.schemaName); | ||
| return `body = ${literal}`; | ||
| }, | ||
| buildResultLine(call, _returnType) { | ||
| return `result = ${call}`; | ||
| } | ||
| }; | ||
| registerLanguage(pythonAdapter); | ||
| // src/languages/java.ts | ||
| function toCamelCase2(str) { | ||
| if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toLowerCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[A-Z]/, (c) => c.toLowerCase()); | ||
| } | ||
| function toKebabCase2(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").toLowerCase().replace(/^-|-$/g, ""); | ||
| } | ||
| function toPascalCase2(str) { | ||
| return str.charAt(0).toUpperCase() + str.slice(1); | ||
| } | ||
| function wrapOverrideForType3(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function mapTypeForSchema(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date") return "LocalDate"; | ||
| if (schema.format === "date-time") return "OffsetDateTime"; | ||
| return "String"; | ||
| case "integer": | ||
| if (schema.format === "int64") return "Long"; | ||
| return "Integer"; | ||
| case "number": | ||
| return "Double"; | ||
| case "boolean": | ||
| return "Boolean"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `List<${mapTypeForSchema(schema.items)}>`; | ||
| } | ||
| return "List<Object>"; | ||
| case "object": | ||
| return "Object"; | ||
| default: | ||
| return "Object"; | ||
| } | ||
| } | ||
| function exampleValueForSchema3(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date") return "LocalDate.now()"; | ||
| if (schema.format === "date-time") return "OffsetDateTime.now()"; | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| return "0"; | ||
| case "number": | ||
| return "0D"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema3(schema.items, "item"); | ||
| return `Arrays.asList(${itemValue})`; | ||
| } | ||
| return "Arrays.asList()"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildSetterBody(body, valueOverrides) { | ||
| const schema = body.schema; | ||
| const typeName = body.schemaName ?? "Object"; | ||
| const props = schema.properties ?? {}; | ||
| const required = schema.required ?? []; | ||
| const lines = []; | ||
| lines.push(`${typeName} body = new ${typeName}();`); | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const setter = `set${toPascalCase2(propName)}`; | ||
| const override = valueOverrides?.[propName]; | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType3(override, propSchema); | ||
| } else { | ||
| value = exampleValueForSchema3(propSchema, propName); | ||
| } | ||
| lines.push(`body.${setter}(${value});`); | ||
| } | ||
| } | ||
| return lines.join("\n"); | ||
| } | ||
| var javaAdapter = { | ||
| id: "java", | ||
| generatorNames: ["java", "java-helidon-client", "java-helidon-server", "java-micronaut-client"], | ||
| codeBlockLang: "java", | ||
| toMethodName(operationId) { | ||
| return toCamelCase2(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toCamelCase2(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toKebabCase2(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| if (schema.type === "object" && schema.properties) { | ||
| return "Object"; | ||
| } | ||
| return mapTypeForSchema(schema); | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema3(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const javaType = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType3(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${javaType} ${param.name} = ${value};`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| return buildSetterBody(body, valueOverrides); | ||
| }, | ||
| buildResultLine(call, returnType) { | ||
| if (returnType) { | ||
| return `${returnType} result = ${call};`; | ||
| } | ||
| return `${call};`; | ||
| } | ||
| }; | ||
| registerLanguage(javaAdapter); | ||
| // src/languages/csharp.ts | ||
| function toPascalCase3(str) { | ||
| if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toUpperCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/[^a-zA-Z0-9]+/g, "").replace(/^[a-z]/, (c) => c.toUpperCase()); | ||
| } | ||
| function toTagDirectoryName(str) { | ||
| return str.split(/\s+/).map((word, i) => { | ||
| if (i === 0) return word; | ||
| return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); | ||
| }).join(""); | ||
| } | ||
| function csharpType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") return "DateTime"; | ||
| return "string"; | ||
| case "integer": | ||
| if (schema.format === "int64") return "long"; | ||
| return "int"; | ||
| case "number": | ||
| return "double"; | ||
| case "boolean": | ||
| return "bool"; | ||
| case "array": | ||
| if (schema.items) return `List<${csharpType(schema.items)}>`; | ||
| return "List<object>"; | ||
| case "object": | ||
| return "object"; | ||
| default: | ||
| return "object"; | ||
| } | ||
| } | ||
| function wrapOverrideForType4(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema4(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "DateTime.Now"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| return "0"; | ||
| case "number": | ||
| return "0.0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildObjectInitializer(schema, 0); | ||
| } | ||
| return "new { }"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemType = csharpType(schema.items); | ||
| const itemValue = exampleValueForSchema4(schema.items, "item"); | ||
| return `new List<${itemType}> { ${itemValue} }`; | ||
| } | ||
| return "new List<object>()"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildObjectInitializer(schema, depth, valueOverrides) { | ||
| const props = schema.properties ?? {}; | ||
| const required = schema.required ?? []; | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = valueOverrides?.[propName]; | ||
| const pascalName = propName.charAt(0).toUpperCase() + propName.slice(1); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType4(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = "new\n" + indent + buildObjectInitializer(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema4(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${pascalName} = ${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{ }"; | ||
| return "{\n" + entries.join("\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var csharpAdapter = { | ||
| id: "csharp", | ||
| generatorNames: ["csharp", "csharp-netcore", "csharp-functions"], | ||
| codeBlockLang: "csharp", | ||
| toMethodName(operationId) { | ||
| return toPascalCase3(operationId) + "Async"; | ||
| }, | ||
| toFileName(operationId) { | ||
| return toPascalCase3(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toTagDirectoryName(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| return csharpType(schema); | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema4(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const type = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType4(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${type} ${param.name} = ${value};`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const initializer = buildObjectInitializer(body.schema, 0, valueOverrides); | ||
| const typeName = body.schemaName ? ` ${body.schemaName}` : ""; | ||
| return `var body = new${typeName} | ||
| ${initializer};`; | ||
| }, | ||
| buildResultLine(call, returnType) { | ||
| if (returnType) { | ||
| return `var result = await ${call};`; | ||
| } | ||
| return `await ${call};`; | ||
| } | ||
| }; | ||
| registerLanguage(csharpAdapter); | ||
| // src/languages/go.ts | ||
| function toPascalCase4(str) { | ||
| if (/^[A-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str; | ||
| } | ||
| if (/^[a-z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toUpperCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[a-z]/, (c) => c.toUpperCase()); | ||
| } | ||
| function toSnakeCase2(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").toLowerCase().replace(/^_|_$/g, ""); | ||
| } | ||
| function wrapOverrideForType5(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema5(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "time.Now()"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildStructLiteral(schema, 0); | ||
| } | ||
| return "map[string]interface{}{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema5(schema.items, "item"); | ||
| return `[]${mapGoType(schema.items)}{${itemValue}}`; | ||
| } | ||
| return "[]interface{}{}"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function mapGoType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "time.Time"; | ||
| } | ||
| return "string"; | ||
| case "integer": | ||
| if (schema.format === "int32") { | ||
| return "int32"; | ||
| } | ||
| return "int64"; | ||
| case "number": | ||
| return "float64"; | ||
| case "boolean": | ||
| return "bool"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `[]${mapGoType(schema.items)}`; | ||
| } | ||
| return "[]interface{}"; | ||
| case "object": | ||
| return "map[string]interface{}"; | ||
| default: | ||
| return "interface{}"; | ||
| } | ||
| } | ||
| function buildStructLiteral(schema, depth, valueOverrides) { | ||
| const props = schema.properties ?? {}; | ||
| const required = schema.required ?? []; | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = valueOverrides?.[propName]; | ||
| const fieldName = toPascalCase4(propName); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType5(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildStructLiteral(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema5(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${fieldName}: ${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{}"; | ||
| return "{\n" + entries.join("\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var goAdapter = { | ||
| id: "go", | ||
| generatorNames: ["go", "go-server", "go-gin-server"], | ||
| codeBlockLang: "go", | ||
| toMethodName(operationId) { | ||
| return toPascalCase4(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toSnakeCase2(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toSnakeCase2(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "API"; | ||
| }, | ||
| mapType(schema) { | ||
| return mapGoType(schema); | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema5(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const value = valueOverride != null ? wrapOverrideForType5(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${param.name} := ${value}`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| const ctxArgs = args ? `context.Background(), ${args}` : "context.Background()"; | ||
| let call; | ||
| if (apiAccessPattern === "direct") { | ||
| call = `${clientVar}.${methodName}(${ctxArgs})`; | ||
| } else if (apiAccessPattern === "call") { | ||
| call = `${clientVar}.${apiProperty}().${methodName}(${ctxArgs})`; | ||
| } else { | ||
| call = `${clientVar}.${apiProperty}.${methodName}(${ctxArgs})`; | ||
| } | ||
| return `${call}.Execute()`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| if (!body.schemaName) { | ||
| const literal2 = buildStructLiteral(body.schema, 0, valueOverrides); | ||
| return `body := map[string]interface{}${literal2}`; | ||
| } | ||
| const literal = buildStructLiteral(body.schema, 0, valueOverrides); | ||
| return `body := openapi.${body.schemaName}${literal}`; | ||
| }, | ||
| buildResultLine(call, _returnType) { | ||
| return `resp, r, err := ${call}`; | ||
| } | ||
| }; | ||
| registerLanguage(goAdapter); | ||
| // src/languages/curl.ts | ||
| function toKebabCase3(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").toLowerCase().replace(/^-|-$/g, ""); | ||
| } | ||
| var currentParams = []; | ||
| function wrapOverrideForType6(override, schema) { | ||
| if (schema.type === "string") { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema6(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return schema.enum[0]; | ||
| } | ||
| if (schema.default != null) { | ||
| return String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "2024-01-01"; | ||
| } | ||
| return `${name}_value`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| return "{}"; | ||
| case "array": | ||
| return "[]"; | ||
| default: | ||
| return `${name}_value`; | ||
| } | ||
| } | ||
| function jsonValue(schema, name, depth) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return '"2024-01-01"'; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildJsonObject(schema, depth); | ||
| } | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `[${jsonValue(schema.items, "item", depth)}]`; | ||
| } | ||
| return "[]"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildJsonObject(schema, depth, valueOverrides) { | ||
| const props = schema.properties ?? {}; | ||
| const required = schema.required ?? []; | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = " ".repeat(depth); | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = valueOverrides?.[propName]; | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType6(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildJsonObject(propSchema, depth + 1); | ||
| } else { | ||
| value = jsonValue(propSchema, propName, depth + 1); | ||
| } | ||
| entries.push(`${indent}"${propName}": ${value}`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{}"; | ||
| return "{\n" + entries.join(",\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var curlAdapter = { | ||
| id: "curl", | ||
| generatorNames: ["curl"], | ||
| codeBlockLang: "bash", | ||
| toMethodName(operationId) { | ||
| return toKebabCase3(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toKebabCase3(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toKebabCase3(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| return tag; | ||
| }, | ||
| mapType(schema) { | ||
| return schema.type || "string"; | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return String(param.example); | ||
| } | ||
| return exampleValueForSchema6(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const value = valueOverride ?? this.exampleValue(param); | ||
| currentParams.push({ param, value }); | ||
| return `# ${param.name} = ${value}`; | ||
| }, | ||
| buildMethodCall(_opts) { | ||
| const queryParams = currentParams.filter(({ param }) => param.in === "query").map(({ param, value }) => `${param.name}=${encodeURIComponent(value)}`).join("&"); | ||
| currentParams = []; | ||
| return queryParams ? `?${queryParams}` : ""; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const json = buildJsonObject(body.schema, 1, valueOverrides); | ||
| return ` -d '${json}'`; | ||
| }, | ||
| buildResultLine(_call, _returnType) { | ||
| return ""; | ||
| } | ||
| }; | ||
| registerLanguage(curlAdapter); | ||
| // src/languages/python-opc.ts | ||
| function toSnakeCase3(str) { | ||
| return str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").toLowerCase().replace(/^_|_$/g, ""); | ||
| } | ||
| function wrapOverrideForType7(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema7(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "datetime.now()"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "True"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildObjectLiteral3(schema, 0); | ||
| } | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema7(schema.items, "item"); | ||
| return `[${itemValue}]`; | ||
| } | ||
| return "[]"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function mapPythonType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "datetime"; | ||
| } | ||
| return "str"; | ||
| case "integer": | ||
| return "int"; | ||
| case "number": | ||
| return "float"; | ||
| case "boolean": | ||
| return "bool"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `list[${mapPythonType(schema.items)}]`; | ||
| } | ||
| return "list"; | ||
| case "object": | ||
| return "dict"; | ||
| default: | ||
| return "object"; | ||
| } | ||
| } | ||
| function buildObjectLiteral3(schema, depth, valueOverrides, schemaName) { | ||
| const props = schema.properties ?? {}; | ||
| const required = schema.required ?? []; | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = valueOverrides?.[propName]; | ||
| const fieldName = toSnakeCase3(propName); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType7(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildObjectLiteral3(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema7(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${fieldName}=${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) { | ||
| return schemaName ? `${schemaName}()` : "{}"; | ||
| } | ||
| const opener = schemaName ? `${schemaName}( | ||
| ` : "{\n"; | ||
| const closer = schemaName ? `${closingIndent})` : `${closingIndent}}`; | ||
| return opener + entries.join("\n") + "\n" + closer; | ||
| } | ||
| var pythonOpcAdapter = { | ||
| id: "python-opc", | ||
| generatorNames: ["openapi-python-client"], | ||
| codeBlockLang: "python", | ||
| toMethodName(operationId) { | ||
| return toSnakeCase3(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toSnakeCase3(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toSnakeCase3(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| return toSnakeCase3(tag); | ||
| }, | ||
| mapType(schema) { | ||
| return mapPythonType(schema); | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema7(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const pyType = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType7(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${toSnakeCase3(param.name)}: ${pyType} = ${value}`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, methodName, args } = opts; | ||
| const kwargParts = [`client=${clientVar}`]; | ||
| if (args) { | ||
| for (const arg of args.split(", ").filter(Boolean)) { | ||
| const snaked = toSnakeCase3(arg); | ||
| kwargParts.push(`${snaked}=${snaked}`); | ||
| } | ||
| } | ||
| return `${methodName}.sync(${kwargParts.join(", ")})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const literal = buildObjectLiteral3(body.schema, 0, valueOverrides, body.schemaName); | ||
| return `body = ${literal}`; | ||
| }, | ||
| buildResultLine(call, _returnType) { | ||
| return `result = ${call}`; | ||
| } | ||
| }; | ||
| registerLanguage(pythonOpcAdapter); | ||
| export { | ||
| registerLanguage, | ||
| getLanguageByGenerator, | ||
| getLanguageById, | ||
| getAllLanguages, | ||
| parseSpec, | ||
| buildTemplateContext, | ||
| renderTemplate, | ||
| getDefaultTemplatePath, | ||
| generate, | ||
| ParamOverridesSchema, | ||
| ExamplesConfigSchema, | ||
| loadConfig, | ||
| loadConfigOrDefault | ||
| }; | ||
| //# sourceMappingURL=chunk-PW5OH5KT.js.map |
Sorry, the diff of this file is too big to display
| "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/languages/registry.ts | ||
| var byId = /* @__PURE__ */ new Map(); | ||
| var byGenerator = /* @__PURE__ */ new Map(); | ||
| function registerLanguage(adapter) { | ||
| byId.set(adapter.id, adapter); | ||
| for (const gen of adapter.generatorNames) { | ||
| byGenerator.set(gen, adapter); | ||
| } | ||
| } | ||
| function getLanguageByGenerator(generatorName) { | ||
| return byGenerator.get(generatorName); | ||
| } | ||
| function getLanguageById(id) { | ||
| return byId.get(id); | ||
| } | ||
| function getAllLanguages() { | ||
| return [...byId.values()]; | ||
| } | ||
| // src/spec/parser.ts | ||
| var _fs = require('fs'); var fs = _interopRequireWildcard(_fs); var fs2 = _interopRequireWildcard(_fs); var fs3 = _interopRequireWildcard(_fs); var fs4 = _interopRequireWildcard(_fs); | ||
| var _yaml = require('yaml'); | ||
| function parseSpec(specPath) { | ||
| const raw = fs.readFileSync(specPath, "utf-8"); | ||
| const spec = specPath.endsWith(".json") ? JSON.parse(raw) : _yaml.parse.call(void 0, raw); | ||
| return extractOperations(spec); | ||
| } | ||
| function extractOperations(spec) { | ||
| const paths = spec.paths; | ||
| if (!paths) return []; | ||
| const operations = []; | ||
| for (const [urlPath, methods] of Object.entries(paths)) { | ||
| for (const [method, opDef] of Object.entries(methods)) { | ||
| if (["get", "post", "put", "patch", "delete", "head", "options"].indexOf(method) === -1) { | ||
| continue; | ||
| } | ||
| const op = opDef; | ||
| if (!op.operationId) continue; | ||
| operations.push({ | ||
| operationId: op.operationId, | ||
| tag: (_nullishCoalesce(op.tags, () => ( ["Default"])))[0], | ||
| httpMethod: method.toUpperCase(), | ||
| path: urlPath, | ||
| description: op.description, | ||
| parameters: normalizeParams(op.parameters, spec), | ||
| requestBody: normalizeRequestBody(op.requestBody, spec), | ||
| responseType: extractResponseType(op.responses, spec), | ||
| security: extractSecurity(op.security) | ||
| }); | ||
| } | ||
| } | ||
| return operations; | ||
| } | ||
| function normalizeParams(params, spec) { | ||
| if (!params) return []; | ||
| return params.map((p) => { | ||
| const param = resolveRef(p, spec); | ||
| const schema = resolveRef( | ||
| _nullishCoalesce(param.schema, () => ( { type: "string" })), | ||
| spec | ||
| ); | ||
| return { | ||
| name: param.name, | ||
| in: param.in, | ||
| required: _nullishCoalesce(param.required, () => ( false)), | ||
| schema: normalizeSchema(schema, spec), | ||
| description: param.description, | ||
| example: param.example, | ||
| deprecated: _nullishCoalesce(param.deprecated, () => ( false)) | ||
| }; | ||
| }); | ||
| } | ||
| function normalizeRequestBody(body, spec) { | ||
| if (!body) return void 0; | ||
| const resolved = resolveRef(body, spec); | ||
| const content = resolved.content; | ||
| if (!content) return void 0; | ||
| const jsonContent = _nullishCoalesce(content["application/json"], () => ( Object.values(content)[0])); | ||
| if (!_optionalChain([jsonContent, 'optionalAccess', _2 => _2.schema])) return void 0; | ||
| const rawSchema = jsonContent.schema; | ||
| const schemaName = extractRefName(rawSchema); | ||
| const resolvedSchema = resolveRef(rawSchema, spec); | ||
| return { | ||
| required: _nullishCoalesce(resolved.required, () => ( false)), | ||
| schemaName, | ||
| schema: normalizeSchema(resolvedSchema, spec) | ||
| }; | ||
| } | ||
| function normalizeSchema(schema, spec) { | ||
| const resolved = resolveRef(schema, spec); | ||
| const result = { | ||
| type: _nullishCoalesce(resolved.type, () => ( "object")) | ||
| }; | ||
| if (resolved.format) result.format = resolved.format; | ||
| if (resolved.enum) result.enum = resolved.enum; | ||
| if (resolved.default !== void 0) result.default = resolved.default; | ||
| if (resolved.description) result.description = resolved.description; | ||
| if (resolved.items) { | ||
| result.items = normalizeSchema( | ||
| resolveRef(resolved.items, spec), | ||
| spec | ||
| ); | ||
| } | ||
| if (resolved.properties) { | ||
| const props = resolved.properties; | ||
| result.properties = {}; | ||
| for (const [name, propSchema] of Object.entries(props)) { | ||
| result.properties[name] = normalizeSchema( | ||
| resolveRef(propSchema, spec), | ||
| spec | ||
| ); | ||
| } | ||
| result.required = _nullishCoalesce(resolved.required, () => ( [])); | ||
| } | ||
| return result; | ||
| } | ||
| function extractResponseType(responses, spec) { | ||
| if (!responses) return void 0; | ||
| const successResponse = _nullishCoalesce(responses["200"], () => ( responses["201"])); | ||
| if (!successResponse) return void 0; | ||
| const resolved = resolveRef(successResponse, spec); | ||
| const content = resolved.content; | ||
| if (!content) return void 0; | ||
| const jsonContent = _nullishCoalesce(content["application/json"], () => ( Object.values(content)[0])); | ||
| if (!_optionalChain([jsonContent, 'optionalAccess', _3 => _3.schema])) return void 0; | ||
| return _nullishCoalesce(extractRefName(jsonContent.schema), () => ( jsonContent.schema.type)); | ||
| } | ||
| function extractSecurity(security) { | ||
| if (!security) return []; | ||
| const names = []; | ||
| for (const scheme of security) { | ||
| names.push(...Object.keys(scheme)); | ||
| } | ||
| return [...new Set(names)]; | ||
| } | ||
| function resolveRef(obj, spec) { | ||
| if (!obj || typeof obj !== "object") return obj; | ||
| const ref = obj["$ref"]; | ||
| if (!ref) return obj; | ||
| const parts = ref.replace(/^#\//, "").split("/"); | ||
| let current = spec; | ||
| for (const part of parts) { | ||
| if (current && typeof current === "object") { | ||
| current = current[part]; | ||
| } else { | ||
| return obj; | ||
| } | ||
| } | ||
| if (current && typeof current === "object") { | ||
| return current; | ||
| } | ||
| return obj; | ||
| } | ||
| function extractRefName(schema) { | ||
| const ref = schema["$ref"]; | ||
| if (!ref) return void 0; | ||
| const parts = ref.split("/"); | ||
| return parts[parts.length - 1]; | ||
| } | ||
| // src/templates/context.ts | ||
| function buildTemplateContext(op, config, adapter) { | ||
| const methodName = adapter.toMethodName(op.operationId); | ||
| const apiProperty = resolveApiProperty(op.tag, config.apiClassMap); | ||
| const apiClassName = adapter.toApiClassName(op.tag); | ||
| const params = op.parameters.filter((p) => !p.deprecated).map((p) => { | ||
| const override = resolveValueOverride(p.name, op.operationId, op.tag, config); | ||
| return toTemplateParam(p, adapter, override); | ||
| }); | ||
| const requiredParams = params.filter((p) => p.required); | ||
| const optionalParams = params.filter((p) => !p.required); | ||
| const paramDeclarations = op.parameters.filter((p) => !p.deprecated && p.required).map((p) => { | ||
| const override = resolveValueOverride(p.name, op.operationId, op.tag, config); | ||
| return adapter.buildParamDeclaration(p, override); | ||
| }).filter(Boolean).join("\n"); | ||
| const hasBody = !!op.requestBody; | ||
| const bodyTypeName = _nullishCoalesce(_optionalChain([op, 'access', _4 => _4.requestBody, 'optionalAccess', _5 => _5.schemaName]), () => ( "")); | ||
| const bodyOverrides = resolveBodyOverrides(op.requestBody, op.operationId, op.tag, config); | ||
| const bodyConstruction = op.requestBody ? adapter.buildBodyConstruction(op.requestBody, bodyOverrides) : ""; | ||
| const argParts = []; | ||
| for (const p of op.parameters.filter((p2) => !p2.deprecated && p2.required)) { | ||
| argParts.push(p.name); | ||
| } | ||
| if (hasBody) { | ||
| argParts.push("body"); | ||
| } | ||
| const args = argParts.join(", "); | ||
| const clientVar = _nullishCoalesce(config.variables.clientVar, () => ( "client")); | ||
| const apiAccessPattern = _nullishCoalesce(config.variables.apiAccessPattern, () => ( "dot")); | ||
| const methodCall = adapter.buildMethodCall({ | ||
| clientVar, | ||
| apiProperty, | ||
| methodName, | ||
| args, | ||
| apiAccessPattern | ||
| }); | ||
| const resultLine = adapter.buildResultLine(methodCall, op.responseType); | ||
| return { | ||
| operationId: op.operationId, | ||
| methodName, | ||
| tag: op.tag, | ||
| httpMethod: op.httpMethod, | ||
| path: op.path, | ||
| description: _nullishCoalesce(op.description, () => ( "")), | ||
| apiProperty, | ||
| apiClassName, | ||
| params, | ||
| hasParams: params.length > 0, | ||
| requiredParams, | ||
| optionalParams, | ||
| hasRequiredParams: requiredParams.length > 0, | ||
| hasOptionalParams: optionalParams.length > 0, | ||
| hasBody, | ||
| bodyTypeName, | ||
| bodyConstruction, | ||
| paramDeclarations, | ||
| methodCall, | ||
| resultLine, | ||
| variables: config.variables, | ||
| boilerplate: config.boilerplate, | ||
| codeBlockLang: adapter.codeBlockLang | ||
| }; | ||
| } | ||
| function resolveApiProperty(tag, apiClassMap) { | ||
| if (apiClassMap[tag]) return apiClassMap[tag]; | ||
| return tag.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[A-Z]/, (c) => c.toLowerCase()); | ||
| } | ||
| function resolveValueOverride(paramName, operationId, tag, config) { | ||
| const ov = config.paramOverrides; | ||
| return _nullishCoalesce(_nullishCoalesce(_optionalChain([ov, 'access', _6 => _6.operations, 'access', _7 => _7[operationId], 'optionalAccess', _8 => _8[paramName]]), () => ( _optionalChain([ov, 'access', _9 => _9.tags, 'access', _10 => _10[tag], 'optionalAccess', _11 => _11[paramName]]))), () => ( ov.global[paramName])); | ||
| } | ||
| function resolveBodyOverrides(body, operationId, tag, config) { | ||
| if (!_optionalChain([body, 'optionalAccess', _12 => _12.schema, 'access', _13 => _13.properties])) return void 0; | ||
| const result = {}; | ||
| let hasAny = false; | ||
| for (const propName of Object.keys(body.schema.properties)) { | ||
| const override = resolveValueOverride(propName, operationId, tag, config); | ||
| if (override !== void 0) { | ||
| result[propName] = override; | ||
| hasAny = true; | ||
| } | ||
| } | ||
| return hasAny ? result : void 0; | ||
| } | ||
| function toTemplateParam(param, adapter, valueOverride) { | ||
| return { | ||
| name: param.name, | ||
| type: adapter.mapType(param.schema), | ||
| description: _nullishCoalesce(param.description, () => ( "")), | ||
| required: param.required, | ||
| defaultValue: param.schema.default != null ? String(param.schema.default) : "", | ||
| exampleValue: _nullishCoalesce(valueOverride, () => ( adapter.exampleValue(param))), | ||
| hasDefault: param.schema.default != null | ||
| }; | ||
| } | ||
| // src/templates/renderer.ts | ||
| var _path = require('path'); var path = _interopRequireWildcard(_path); var path3 = _interopRequireWildcard(_path); var path2 = _interopRequireWildcard(_path); | ||
| var _mustache = require('mustache'); var _mustache2 = _interopRequireDefault(_mustache); | ||
| _mustache2.default.escape = (text) => text; | ||
| var templateCache = /* @__PURE__ */ new Map(); | ||
| function renderTemplate(templatePath, context) { | ||
| const template = loadTemplate(templatePath); | ||
| const rendered = _mustache2.default.render(template, context); | ||
| return rendered.replace(/\n{3,}/g, "\n\n").trim() + "\n"; | ||
| } | ||
| function getDefaultTemplatePath(languageId) { | ||
| const srcPath = path.resolve( | ||
| _nullishCoalesce(import.meta.dirname, () => ( __dirname)), | ||
| "defaults", | ||
| `${languageId}.mustache` | ||
| ); | ||
| if (fs2.existsSync(srcPath)) return srcPath; | ||
| const distPath = path.resolve( | ||
| _nullishCoalesce(import.meta.dirname, () => ( __dirname)), | ||
| "..", | ||
| "templates", | ||
| "defaults", | ||
| `${languageId}.mustache` | ||
| ); | ||
| if (fs2.existsSync(distPath)) return distPath; | ||
| throw new Error( | ||
| `No default template found for language "${languageId}". Searched: ${srcPath}, ${distPath}` | ||
| ); | ||
| } | ||
| function loadTemplate(templatePath) { | ||
| const cached = templateCache.get(templatePath); | ||
| if (cached) return cached; | ||
| if (!fs2.existsSync(templatePath)) { | ||
| throw new Error(`Template not found: ${templatePath}`); | ||
| } | ||
| const content = fs2.readFileSync(templatePath, "utf-8"); | ||
| templateCache.set(templatePath, content); | ||
| return content; | ||
| } | ||
| // src/generator/pipeline.ts | ||
| // src/generator/writer.ts | ||
| function writeOperationFile(outputDir, op, renderedExample, context, adapter, formats) { | ||
| const tagDir = adapter.toTagDirectory(op.tag); | ||
| const fileName = adapter.toFileName(op.operationId); | ||
| const dirPath = path2.join(outputDir, adapter.id, tagDir); | ||
| fs3.mkdirSync(dirPath, { recursive: true }); | ||
| const filesWritten = []; | ||
| let json; | ||
| if (formats.includes("md")) { | ||
| const mdPath = path2.join(dirPath, fileName + ".md"); | ||
| const md = buildMarkdown(op, renderedExample, context); | ||
| fs3.writeFileSync(mdPath, md, "utf-8"); | ||
| filesWritten.push(mdPath); | ||
| } | ||
| if (formats.includes("json")) { | ||
| json = buildJson(op, renderedExample, context); | ||
| const jsonPath = path2.join(dirPath, fileName + ".json"); | ||
| fs3.writeFileSync(jsonPath, JSON.stringify(json, null, 2) + "\n", "utf-8"); | ||
| filesWritten.push(jsonPath); | ||
| } | ||
| return { filesWritten, json }; | ||
| } | ||
| function writeJsonIndex(outputDir, adapter, entries) { | ||
| const dirPath = path2.join(outputDir, adapter.id); | ||
| fs3.mkdirSync(dirPath, { recursive: true }); | ||
| fs3.writeFileSync( | ||
| path2.join(dirPath, "index.json"), | ||
| JSON.stringify(entries, null, 2) + "\n", | ||
| "utf-8" | ||
| ); | ||
| } | ||
| function writeLanguageIndex(outputDir, adapter, operations) { | ||
| const dirPath = path2.join(outputDir, adapter.id); | ||
| fs3.mkdirSync(dirPath, { recursive: true }); | ||
| const byTag = /* @__PURE__ */ new Map(); | ||
| for (const op of operations) { | ||
| const tag = op.tag; | ||
| if (!byTag.has(tag)) byTag.set(tag, []); | ||
| byTag.get(tag).push(op); | ||
| } | ||
| const lines = [`# Usage Examples (${adapter.id})`, ""]; | ||
| for (const [tag, ops] of byTag) { | ||
| const tagDir = adapter.toTagDirectory(tag); | ||
| lines.push(`## ${tag}`, ""); | ||
| lines.push("| Operation | Method | Path |"); | ||
| lines.push("|-----------|--------|------|"); | ||
| for (const op of ops) { | ||
| const fileName = adapter.toFileName(op.operationId); | ||
| lines.push(`| [${op.operationId}](./${tagDir}/${fileName}.md) | ${op.httpMethod} | \`${op.path}\` |`); | ||
| } | ||
| lines.push(""); | ||
| } | ||
| fs3.writeFileSync(path2.join(dirPath, "index.md"), lines.join("\n"), "utf-8"); | ||
| } | ||
| function buildJson(op, renderedExample, context) { | ||
| const json = { | ||
| operationId: op.operationId, | ||
| tag: op.tag, | ||
| httpMethod: op.httpMethod, | ||
| path: op.path, | ||
| description: _nullishCoalesce(op.description, () => ( "")), | ||
| example: renderedExample.trimEnd(), | ||
| codeBlockLang: context.codeBlockLang, | ||
| parameters: context.params.map((p) => ({ | ||
| name: p.name, | ||
| type: p.type, | ||
| required: p.required, | ||
| description: p.description | ||
| })) | ||
| }; | ||
| if (context.hasBody && context.bodyTypeName) { | ||
| json.requestBody = { | ||
| typeName: context.bodyTypeName, | ||
| construction: context.bodyConstruction | ||
| }; | ||
| } | ||
| return json; | ||
| } | ||
| function buildMarkdown(op, renderedExample, context) { | ||
| const lines = []; | ||
| lines.push(`# ${op.operationId}`); | ||
| lines.push(""); | ||
| if (op.description) { | ||
| lines.push(op.description); | ||
| lines.push(""); | ||
| } | ||
| lines.push(`\`${op.httpMethod} ${op.path}\``); | ||
| lines.push(""); | ||
| lines.push("## Example"); | ||
| lines.push(""); | ||
| lines.push(`\`\`\`${context.codeBlockLang}`); | ||
| lines.push(renderedExample.trimEnd()); | ||
| lines.push("```"); | ||
| lines.push(""); | ||
| if (context.params.length > 0) { | ||
| lines.push("## Parameters"); | ||
| lines.push(""); | ||
| lines.push("| Name | Type | Required | Description |"); | ||
| lines.push("|------|------|----------|-------------|"); | ||
| for (const p of context.params) { | ||
| const req = p.required ? "Yes" : "No"; | ||
| const desc = p.description || "-"; | ||
| lines.push(`| \`${p.name}\` | \`${p.type}\` | ${req} | ${desc} |`); | ||
| } | ||
| lines.push(""); | ||
| } | ||
| if (context.hasBody) { | ||
| lines.push("## Request Body"); | ||
| lines.push(""); | ||
| lines.push(`Type: \`${context.bodyTypeName}\``); | ||
| lines.push(""); | ||
| } | ||
| return lines.join("\n"); | ||
| } | ||
| // src/generator/pipeline.ts | ||
| function generate(options) { | ||
| const { inputSpec, generator, outputDir, config } = options; | ||
| const adapter = _nullishCoalesce(getLanguageByGenerator(generator), () => ( getLanguageById(generator))); | ||
| if (!adapter) { | ||
| const msg = `Unknown generator/language: "${generator}". No language adapter registered for this identifier.`; | ||
| throw new Error(msg); | ||
| } | ||
| const usageDir = config.output ? path3.resolve(config.output) : path3.resolve(outputDir, "usage"); | ||
| const operations = parseSpec(inputSpec); | ||
| if (operations.length === 0) { | ||
| console.warn("No operations found in the OpenAPI spec."); | ||
| return { languageId: adapter.id, filesWritten: [], operationCount: 0 }; | ||
| } | ||
| const templatePath = config.templatePath ? path3.resolve(config.templatePath) : getDefaultTemplatePath(adapter.id); | ||
| const formats = config.outputFormats.length > 0 ? config.outputFormats : ["md"]; | ||
| const filesWritten = []; | ||
| const jsonEntries = []; | ||
| for (const op of operations) { | ||
| const context = buildTemplateContext(op, config, adapter); | ||
| const rendered = renderTemplate(templatePath, context); | ||
| const result = writeOperationFile(usageDir, op, rendered, context, adapter, formats); | ||
| filesWritten.push(...result.filesWritten); | ||
| if (result.json) jsonEntries.push(result.json); | ||
| } | ||
| writeLanguageIndex(usageDir, adapter, operations); | ||
| if (formats.includes("json") && jsonEntries.length > 0) { | ||
| writeJsonIndex(usageDir, adapter, jsonEntries); | ||
| } | ||
| return { | ||
| languageId: adapter.id, | ||
| filesWritten, | ||
| operationCount: operations.length | ||
| }; | ||
| } | ||
| // src/config/schema.ts | ||
| var _zod = require('zod'); | ||
| var BoilerplateSchema = _zod.z.object({ | ||
| showTryCatch: _zod.z.boolean().default(false), | ||
| showImports: _zod.z.boolean().default(true), | ||
| showApiKeyConfig: _zod.z.boolean().default(false), | ||
| showFullClass: _zod.z.boolean().default(false) | ||
| }).default({}); | ||
| var ParamOverridesSchema = _zod.z.object({ | ||
| /** Global overrides applied to all operations */ | ||
| global: _zod.z.record(_zod.z.string(), _zod.z.string()).default({}), | ||
| /** Per-tag overrides (tag name → param name → value) */ | ||
| tags: _zod.z.record(_zod.z.string(), _zod.z.record(_zod.z.string(), _zod.z.string())).default({}), | ||
| /** Per-operation overrides (operationId → param name → value), highest priority */ | ||
| operations: _zod.z.record(_zod.z.string(), _zod.z.record(_zod.z.string(), _zod.z.string())).default({}) | ||
| }).default({}); | ||
| var ExamplesConfigSchema = _zod.z.object({ | ||
| /** Output directory for generated examples (default: ./usage relative to -o) */ | ||
| output: _zod.z.string().optional(), | ||
| /** Boilerplate control flags */ | ||
| boilerplate: BoilerplateSchema, | ||
| /** | ||
| * Template variables available in mustache templates. | ||
| * Well-known keys: | ||
| * sdkImport - import statement(s) for the SDK | ||
| * clientConstruction - code to construct the client instance | ||
| * clientVar - variable name for client (default: "client") | ||
| * apiKeyPlaceholder - placeholder for API key (default: "YOUR_API_KEY") | ||
| * apiAccessPattern - "dot" (client.api.method) or "call" (client.api().method) | ||
| */ | ||
| variables: _zod.z.record(_zod.z.string(), _zod.z.string()).default({}), | ||
| /** Maps OpenAPI tags -> wrapper property names (e.g., "TikTok LIVE": "webcast") */ | ||
| apiClassMap: _zod.z.record(_zod.z.string(), _zod.z.string()).default({}), | ||
| /** Path to a custom mustache template (overrides the built-in default for this language) */ | ||
| templatePath: _zod.z.string().optional(), | ||
| /** Output formats: "md" (markdown), "json", or both. Default: ["md"] */ | ||
| outputFormats: _zod.z.array(_zod.z.enum(["md", "json"])).default(["md"]), | ||
| /** | ||
| * Override example values for parameters and body properties. | ||
| * Values are raw code strings used as-is (no quoting/processing). | ||
| * Precedence: operations > tags > global (most-specific-wins). | ||
| */ | ||
| paramOverrides: ParamOverridesSchema | ||
| }); | ||
| // src/config/loader.ts | ||
| var DEFAULTS = { | ||
| variables: { | ||
| clientVar: "apiInstance", | ||
| apiKeyPlaceholder: "YOUR_API_KEY", | ||
| apiAccessPattern: "direct", | ||
| sdkPackage: "./api" | ||
| } | ||
| }; | ||
| function loadConfig(configPath) { | ||
| if (!fs4.existsSync(configPath)) { | ||
| throw new Error(`Config file not found: ${configPath}`); | ||
| } | ||
| const raw = fs4.readFileSync(configPath, "utf-8"); | ||
| const parsed = _yaml.parse.call(void 0, raw); | ||
| const merged = { | ||
| ...parsed, | ||
| variables: { | ||
| ...DEFAULTS.variables, | ||
| ..._optionalChain([parsed, 'optionalAccess', _14 => _14.variables]) | ||
| } | ||
| }; | ||
| const result = ExamplesConfigSchema.safeParse(merged); | ||
| if (!result.success) { | ||
| const issues = result.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n"); | ||
| throw new Error(`Invalid config: | ||
| ${issues}`); | ||
| } | ||
| return result.data; | ||
| } | ||
| function loadConfigOrDefault(configPath) { | ||
| if (configPath) { | ||
| return loadConfig(configPath); | ||
| } | ||
| return ExamplesConfigSchema.parse({ | ||
| variables: { ...DEFAULTS.variables } | ||
| }); | ||
| } | ||
| // src/languages/typescript.ts | ||
| function toCamelCase(str) { | ||
| if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toLowerCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[A-Z]/, (c) => c.toLowerCase()); | ||
| } | ||
| function toKebabCase(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").toLowerCase().replace(/^-|-$/g, ""); | ||
| } | ||
| function wrapOverrideForType(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "new Date()"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildObjectLiteral(schema, 0); | ||
| } | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema(schema.items, "item"); | ||
| return `[${itemValue}]`; | ||
| } | ||
| return "[]"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildObjectLiteral(schema, depth, valueOverrides) { | ||
| const props = _nullishCoalesce(schema.properties, () => ( {})); | ||
| const required = _nullishCoalesce(schema.required, () => ( [])); | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = _optionalChain([valueOverrides, 'optionalAccess', _15 => _15[propName]]); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildObjectLiteral(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${propName}: ${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{}"; | ||
| return "{\n" + entries.join("\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var typescriptAdapter = { | ||
| id: "typescript", | ||
| generatorNames: ["typescript-axios", "typescript-fetch", "typescript-angular", "typescript-node", "typescript"], | ||
| codeBlockLang: "typescript", | ||
| toMethodName(operationId) { | ||
| return toCamelCase(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toCamelCase(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toKebabCase(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "Date"; | ||
| } | ||
| return "string"; | ||
| case "integer": | ||
| case "number": | ||
| return "number"; | ||
| case "boolean": | ||
| return "boolean"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `${this.mapType(schema.items)}[]`; | ||
| } | ||
| return "unknown[]"; | ||
| case "object": | ||
| return "Record<string, unknown>"; | ||
| default: | ||
| return "unknown"; | ||
| } | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const tsType = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `let ${param.name}: ${tsType} = ${value};`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const objectLiteral = buildObjectLiteral(body.schema, 0, valueOverrides); | ||
| const opening = body.schemaName ? `const body: ${body.schemaName} = ` : `const body = `; | ||
| return opening + objectLiteral + ";"; | ||
| }, | ||
| buildResultLine(call, returnType) { | ||
| if (returnType) { | ||
| return `const { status, data } = await ${call};`; | ||
| } | ||
| return `await ${call};`; | ||
| } | ||
| }; | ||
| registerLanguage(typescriptAdapter); | ||
| // src/languages/python.ts | ||
| function toSnakeCase(str) { | ||
| return str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").toLowerCase().replace(/^_|_$/g, ""); | ||
| } | ||
| function toPascalCase(str) { | ||
| return str.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| } | ||
| function wrapOverrideForType2(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema2(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "datetime.now()"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "True"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildObjectLiteral2(schema, 0); | ||
| } | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema2(schema.items, "item"); | ||
| return `[${itemValue}]`; | ||
| } | ||
| return "[]"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildObjectLiteral2(schema, depth, valueOverrides, schemaName) { | ||
| const props = _nullishCoalesce(schema.properties, () => ( {})); | ||
| const required = _nullishCoalesce(schema.required, () => ( [])); | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = _optionalChain([valueOverrides, 'optionalAccess', _16 => _16[propName]]); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType2(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildObjectLiteral2(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema2(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${propName}=${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) { | ||
| return schemaName ? `${schemaName}()` : "{}"; | ||
| } | ||
| const opener = schemaName ? `${schemaName}( | ||
| ` : "{\n"; | ||
| const closer = schemaName ? `${closingIndent})` : `${closingIndent}}`; | ||
| return opener + entries.join("\n") + "\n" + closer; | ||
| } | ||
| var pythonAdapter = { | ||
| id: "python", | ||
| generatorNames: ["python", "python-pydantic-v1", "python-nextgen", "python-prior"], | ||
| codeBlockLang: "python", | ||
| toMethodName(operationId) { | ||
| return toSnakeCase(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toSnakeCase(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toSnakeCase(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = toPascalCase(tag); | ||
| const capitalized = stripped.charAt(0).toUpperCase() + stripped.slice(1); | ||
| return capitalized + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "datetime"; | ||
| } | ||
| return "str"; | ||
| case "integer": | ||
| return "int"; | ||
| case "number": | ||
| return "float"; | ||
| case "boolean": | ||
| return "bool"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `list[${this.mapType(schema.items)}]`; | ||
| } | ||
| return "list"; | ||
| case "object": | ||
| return "dict"; | ||
| default: | ||
| return "object"; | ||
| } | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema2(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const pyType = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType2(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${param.name}: ${pyType} = ${value}`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const literal = buildObjectLiteral2(body.schema, 0, valueOverrides, body.schemaName); | ||
| return `body = ${literal}`; | ||
| }, | ||
| buildResultLine(call, _returnType) { | ||
| return `result = ${call}`; | ||
| } | ||
| }; | ||
| registerLanguage(pythonAdapter); | ||
| // src/languages/java.ts | ||
| function toCamelCase2(str) { | ||
| if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toLowerCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[A-Z]/, (c) => c.toLowerCase()); | ||
| } | ||
| function toKebabCase2(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").toLowerCase().replace(/^-|-$/g, ""); | ||
| } | ||
| function toPascalCase2(str) { | ||
| return str.charAt(0).toUpperCase() + str.slice(1); | ||
| } | ||
| function wrapOverrideForType3(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function mapTypeForSchema(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date") return "LocalDate"; | ||
| if (schema.format === "date-time") return "OffsetDateTime"; | ||
| return "String"; | ||
| case "integer": | ||
| if (schema.format === "int64") return "Long"; | ||
| return "Integer"; | ||
| case "number": | ||
| return "Double"; | ||
| case "boolean": | ||
| return "Boolean"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `List<${mapTypeForSchema(schema.items)}>`; | ||
| } | ||
| return "List<Object>"; | ||
| case "object": | ||
| return "Object"; | ||
| default: | ||
| return "Object"; | ||
| } | ||
| } | ||
| function exampleValueForSchema3(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date") return "LocalDate.now()"; | ||
| if (schema.format === "date-time") return "OffsetDateTime.now()"; | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| return "0"; | ||
| case "number": | ||
| return "0D"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema3(schema.items, "item"); | ||
| return `Arrays.asList(${itemValue})`; | ||
| } | ||
| return "Arrays.asList()"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildSetterBody(body, valueOverrides) { | ||
| const schema = body.schema; | ||
| const typeName = _nullishCoalesce(body.schemaName, () => ( "Object")); | ||
| const props = _nullishCoalesce(schema.properties, () => ( {})); | ||
| const required = _nullishCoalesce(schema.required, () => ( [])); | ||
| const lines = []; | ||
| lines.push(`${typeName} body = new ${typeName}();`); | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const setter = `set${toPascalCase2(propName)}`; | ||
| const override = _optionalChain([valueOverrides, 'optionalAccess', _17 => _17[propName]]); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType3(override, propSchema); | ||
| } else { | ||
| value = exampleValueForSchema3(propSchema, propName); | ||
| } | ||
| lines.push(`body.${setter}(${value});`); | ||
| } | ||
| } | ||
| return lines.join("\n"); | ||
| } | ||
| var javaAdapter = { | ||
| id: "java", | ||
| generatorNames: ["java", "java-helidon-client", "java-helidon-server", "java-micronaut-client"], | ||
| codeBlockLang: "java", | ||
| toMethodName(operationId) { | ||
| return toCamelCase2(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toCamelCase2(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toKebabCase2(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| if (schema.type === "object" && schema.properties) { | ||
| return "Object"; | ||
| } | ||
| return mapTypeForSchema(schema); | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema3(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const javaType = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType3(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${javaType} ${param.name} = ${value};`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| return buildSetterBody(body, valueOverrides); | ||
| }, | ||
| buildResultLine(call, returnType) { | ||
| if (returnType) { | ||
| return `${returnType} result = ${call};`; | ||
| } | ||
| return `${call};`; | ||
| } | ||
| }; | ||
| registerLanguage(javaAdapter); | ||
| // src/languages/csharp.ts | ||
| function toPascalCase3(str) { | ||
| if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toUpperCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/[^a-zA-Z0-9]+/g, "").replace(/^[a-z]/, (c) => c.toUpperCase()); | ||
| } | ||
| function toTagDirectoryName(str) { | ||
| return str.split(/\s+/).map((word, i) => { | ||
| if (i === 0) return word; | ||
| return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); | ||
| }).join(""); | ||
| } | ||
| function csharpType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") return "DateTime"; | ||
| return "string"; | ||
| case "integer": | ||
| if (schema.format === "int64") return "long"; | ||
| return "int"; | ||
| case "number": | ||
| return "double"; | ||
| case "boolean": | ||
| return "bool"; | ||
| case "array": | ||
| if (schema.items) return `List<${csharpType(schema.items)}>`; | ||
| return "List<object>"; | ||
| case "object": | ||
| return "object"; | ||
| default: | ||
| return "object"; | ||
| } | ||
| } | ||
| function wrapOverrideForType4(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema4(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "DateTime.Now"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| return "0"; | ||
| case "number": | ||
| return "0.0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildObjectInitializer(schema, 0); | ||
| } | ||
| return "new { }"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemType = csharpType(schema.items); | ||
| const itemValue = exampleValueForSchema4(schema.items, "item"); | ||
| return `new List<${itemType}> { ${itemValue} }`; | ||
| } | ||
| return "new List<object>()"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildObjectInitializer(schema, depth, valueOverrides) { | ||
| const props = _nullishCoalesce(schema.properties, () => ( {})); | ||
| const required = _nullishCoalesce(schema.required, () => ( [])); | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = _optionalChain([valueOverrides, 'optionalAccess', _18 => _18[propName]]); | ||
| const pascalName = propName.charAt(0).toUpperCase() + propName.slice(1); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType4(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = "new\n" + indent + buildObjectInitializer(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema4(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${pascalName} = ${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{ }"; | ||
| return "{\n" + entries.join("\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var csharpAdapter = { | ||
| id: "csharp", | ||
| generatorNames: ["csharp", "csharp-netcore", "csharp-functions"], | ||
| codeBlockLang: "csharp", | ||
| toMethodName(operationId) { | ||
| return toPascalCase3(operationId) + "Async"; | ||
| }, | ||
| toFileName(operationId) { | ||
| return toPascalCase3(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toTagDirectoryName(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| return csharpType(schema); | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema4(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const type = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType4(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${type} ${param.name} = ${value};`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const initializer = buildObjectInitializer(body.schema, 0, valueOverrides); | ||
| const typeName = body.schemaName ? ` ${body.schemaName}` : ""; | ||
| return `var body = new${typeName} | ||
| ${initializer};`; | ||
| }, | ||
| buildResultLine(call, returnType) { | ||
| if (returnType) { | ||
| return `var result = await ${call};`; | ||
| } | ||
| return `await ${call};`; | ||
| } | ||
| }; | ||
| registerLanguage(csharpAdapter); | ||
| // src/languages/go.ts | ||
| function toPascalCase4(str) { | ||
| if (/^[A-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str; | ||
| } | ||
| if (/^[a-z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toUpperCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[a-z]/, (c) => c.toUpperCase()); | ||
| } | ||
| function toSnakeCase2(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").toLowerCase().replace(/^_|_$/g, ""); | ||
| } | ||
| function wrapOverrideForType5(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema5(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "time.Now()"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildStructLiteral(schema, 0); | ||
| } | ||
| return "map[string]interface{}{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema5(schema.items, "item"); | ||
| return `[]${mapGoType(schema.items)}{${itemValue}}`; | ||
| } | ||
| return "[]interface{}{}"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function mapGoType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "time.Time"; | ||
| } | ||
| return "string"; | ||
| case "integer": | ||
| if (schema.format === "int32") { | ||
| return "int32"; | ||
| } | ||
| return "int64"; | ||
| case "number": | ||
| return "float64"; | ||
| case "boolean": | ||
| return "bool"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `[]${mapGoType(schema.items)}`; | ||
| } | ||
| return "[]interface{}"; | ||
| case "object": | ||
| return "map[string]interface{}"; | ||
| default: | ||
| return "interface{}"; | ||
| } | ||
| } | ||
| function buildStructLiteral(schema, depth, valueOverrides) { | ||
| const props = _nullishCoalesce(schema.properties, () => ( {})); | ||
| const required = _nullishCoalesce(schema.required, () => ( [])); | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = _optionalChain([valueOverrides, 'optionalAccess', _19 => _19[propName]]); | ||
| const fieldName = toPascalCase4(propName); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType5(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildStructLiteral(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema5(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${fieldName}: ${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{}"; | ||
| return "{\n" + entries.join("\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var goAdapter = { | ||
| id: "go", | ||
| generatorNames: ["go", "go-server", "go-gin-server"], | ||
| codeBlockLang: "go", | ||
| toMethodName(operationId) { | ||
| return toPascalCase4(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toSnakeCase2(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toSnakeCase2(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "API"; | ||
| }, | ||
| mapType(schema) { | ||
| return mapGoType(schema); | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema5(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const value = valueOverride != null ? wrapOverrideForType5(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${param.name} := ${value}`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| const ctxArgs = args ? `context.Background(), ${args}` : "context.Background()"; | ||
| let call; | ||
| if (apiAccessPattern === "direct") { | ||
| call = `${clientVar}.${methodName}(${ctxArgs})`; | ||
| } else if (apiAccessPattern === "call") { | ||
| call = `${clientVar}.${apiProperty}().${methodName}(${ctxArgs})`; | ||
| } else { | ||
| call = `${clientVar}.${apiProperty}.${methodName}(${ctxArgs})`; | ||
| } | ||
| return `${call}.Execute()`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| if (!body.schemaName) { | ||
| const literal2 = buildStructLiteral(body.schema, 0, valueOverrides); | ||
| return `body := map[string]interface{}${literal2}`; | ||
| } | ||
| const literal = buildStructLiteral(body.schema, 0, valueOverrides); | ||
| return `body := openapi.${body.schemaName}${literal}`; | ||
| }, | ||
| buildResultLine(call, _returnType) { | ||
| return `resp, r, err := ${call}`; | ||
| } | ||
| }; | ||
| registerLanguage(goAdapter); | ||
| // src/languages/curl.ts | ||
| function toKebabCase3(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").toLowerCase().replace(/^-|-$/g, ""); | ||
| } | ||
| var currentParams = []; | ||
| function wrapOverrideForType6(override, schema) { | ||
| if (schema.type === "string") { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema6(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return schema.enum[0]; | ||
| } | ||
| if (schema.default != null) { | ||
| return String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "2024-01-01"; | ||
| } | ||
| return `${name}_value`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| return "{}"; | ||
| case "array": | ||
| return "[]"; | ||
| default: | ||
| return `${name}_value`; | ||
| } | ||
| } | ||
| function jsonValue(schema, name, depth) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return '"2024-01-01"'; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildJsonObject(schema, depth); | ||
| } | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `[${jsonValue(schema.items, "item", depth)}]`; | ||
| } | ||
| return "[]"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildJsonObject(schema, depth, valueOverrides) { | ||
| const props = _nullishCoalesce(schema.properties, () => ( {})); | ||
| const required = _nullishCoalesce(schema.required, () => ( [])); | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = " ".repeat(depth); | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = _optionalChain([valueOverrides, 'optionalAccess', _20 => _20[propName]]); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType6(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildJsonObject(propSchema, depth + 1); | ||
| } else { | ||
| value = jsonValue(propSchema, propName, depth + 1); | ||
| } | ||
| entries.push(`${indent}"${propName}": ${value}`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{}"; | ||
| return "{\n" + entries.join(",\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var curlAdapter = { | ||
| id: "curl", | ||
| generatorNames: ["curl"], | ||
| codeBlockLang: "bash", | ||
| toMethodName(operationId) { | ||
| return toKebabCase3(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toKebabCase3(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toKebabCase3(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| return tag; | ||
| }, | ||
| mapType(schema) { | ||
| return schema.type || "string"; | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return String(param.example); | ||
| } | ||
| return exampleValueForSchema6(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const value = _nullishCoalesce(valueOverride, () => ( this.exampleValue(param))); | ||
| currentParams.push({ param, value }); | ||
| return `# ${param.name} = ${value}`; | ||
| }, | ||
| buildMethodCall(_opts) { | ||
| const queryParams = currentParams.filter(({ param }) => param.in === "query").map(({ param, value }) => `${param.name}=${encodeURIComponent(value)}`).join("&"); | ||
| currentParams = []; | ||
| return queryParams ? `?${queryParams}` : ""; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const json = buildJsonObject(body.schema, 1, valueOverrides); | ||
| return ` -d '${json}'`; | ||
| }, | ||
| buildResultLine(_call, _returnType) { | ||
| return ""; | ||
| } | ||
| }; | ||
| registerLanguage(curlAdapter); | ||
| // src/languages/python-opc.ts | ||
| function toSnakeCase3(str) { | ||
| return str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").toLowerCase().replace(/^_|_$/g, ""); | ||
| } | ||
| function wrapOverrideForType7(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema7(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "datetime.now()"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "True"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildObjectLiteral3(schema, 0); | ||
| } | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema7(schema.items, "item"); | ||
| return `[${itemValue}]`; | ||
| } | ||
| return "[]"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function mapPythonType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "datetime"; | ||
| } | ||
| return "str"; | ||
| case "integer": | ||
| return "int"; | ||
| case "number": | ||
| return "float"; | ||
| case "boolean": | ||
| return "bool"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `list[${mapPythonType(schema.items)}]`; | ||
| } | ||
| return "list"; | ||
| case "object": | ||
| return "dict"; | ||
| default: | ||
| return "object"; | ||
| } | ||
| } | ||
| function buildObjectLiteral3(schema, depth, valueOverrides, schemaName) { | ||
| const props = _nullishCoalesce(schema.properties, () => ( {})); | ||
| const required = _nullishCoalesce(schema.required, () => ( [])); | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = _optionalChain([valueOverrides, 'optionalAccess', _21 => _21[propName]]); | ||
| const fieldName = toSnakeCase3(propName); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType7(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildObjectLiteral3(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema7(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${fieldName}=${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) { | ||
| return schemaName ? `${schemaName}()` : "{}"; | ||
| } | ||
| const opener = schemaName ? `${schemaName}( | ||
| ` : "{\n"; | ||
| const closer = schemaName ? `${closingIndent})` : `${closingIndent}}`; | ||
| return opener + entries.join("\n") + "\n" + closer; | ||
| } | ||
| var pythonOpcAdapter = { | ||
| id: "python-opc", | ||
| generatorNames: ["openapi-python-client"], | ||
| codeBlockLang: "python", | ||
| toMethodName(operationId) { | ||
| return toSnakeCase3(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toSnakeCase3(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toSnakeCase3(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| return toSnakeCase3(tag); | ||
| }, | ||
| mapType(schema) { | ||
| return mapPythonType(schema); | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema7(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const pyType = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType7(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${toSnakeCase3(param.name)}: ${pyType} = ${value}`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, methodName, args } = opts; | ||
| const kwargParts = [`client=${clientVar}`]; | ||
| if (args) { | ||
| for (const arg of args.split(", ").filter(Boolean)) { | ||
| const snaked = toSnakeCase3(arg); | ||
| kwargParts.push(`${snaked}=${snaked}`); | ||
| } | ||
| } | ||
| return `${methodName}.sync(${kwargParts.join(", ")})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const literal = buildObjectLiteral3(body.schema, 0, valueOverrides, body.schemaName); | ||
| return `body = ${literal}`; | ||
| }, | ||
| buildResultLine(call, _returnType) { | ||
| return `result = ${call}`; | ||
| } | ||
| }; | ||
| registerLanguage(pythonOpcAdapter); | ||
| exports.registerLanguage = registerLanguage; exports.getLanguageByGenerator = getLanguageByGenerator; exports.getLanguageById = getLanguageById; exports.getAllLanguages = getAllLanguages; exports.parseSpec = parseSpec; exports.buildTemplateContext = buildTemplateContext; exports.renderTemplate = renderTemplate; exports.getDefaultTemplatePath = getDefaultTemplatePath; exports.generate = generate; exports.ParamOverridesSchema = ParamOverridesSchema; exports.ExamplesConfigSchema = ExamplesConfigSchema; exports.loadConfig = loadConfig; exports.loadConfigOrDefault = loadConfigOrDefault; | ||
| //# sourceMappingURL=chunk-X7BEAPLI.cjs.map |
Sorry, the diff of this file is too big to display
| from {{variables.sdkPackage}}.api.{{apiProperty}} import {{methodName}} | ||
| from {{variables.sdkPackage}}.client import AuthenticatedClient | ||
| client = AuthenticatedClient( | ||
| base_url="https://api.example.com", | ||
| token="YOUR_API_KEY", | ||
| ) | ||
| {{#hasRequiredParams}} | ||
| {{{paramDeclarations}}} | ||
| {{/hasRequiredParams}} | ||
| {{#hasBody}} | ||
| {{{bodyConstruction}}} | ||
| {{/hasBody}} | ||
| {{{resultLine}}} |
| from {{variables.sdkPackage}}.api.{{apiProperty}} import {{methodName}} | ||
| from {{variables.sdkPackage}}.client import AuthenticatedClient | ||
| client = AuthenticatedClient( | ||
| base_url="https://api.example.com", | ||
| token="YOUR_API_KEY", | ||
| ) | ||
| {{#hasRequiredParams}} | ||
| {{{paramDeclarations}}} | ||
| {{/hasRequiredParams}} | ||
| {{#hasBody}} | ||
| {{{bodyConstruction}}} | ||
| {{/hasBody}} | ||
| {{{resultLine}}} |
+3
-3
@@ -5,3 +5,3 @@ "use strict"; function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } | ||
| var _chunkW5UF3QWJcjs = require('./chunk-W5UF3QWJ.cjs'); | ||
| var _chunkX7BEAPLIcjs = require('./chunk-X7BEAPLI.cjs'); | ||
@@ -86,4 +86,4 @@ // src/cli.ts | ||
| } | ||
| const config = args.config ? _chunkW5UF3QWJcjs.loadConfig.call(void 0, args.config) : _chunkW5UF3QWJcjs.loadConfigOrDefault.call(void 0, ); | ||
| const result = _chunkW5UF3QWJcjs.generate.call(void 0, { | ||
| const config = args.config ? _chunkX7BEAPLIcjs.loadConfig.call(void 0, args.config) : _chunkX7BEAPLIcjs.loadConfigOrDefault.call(void 0, ); | ||
| const result = _chunkX7BEAPLIcjs.generate.call(void 0, { | ||
| inputSpec: args.input, | ||
@@ -90,0 +90,0 @@ generator: args.generator, |
+1
-1
@@ -6,3 +6,3 @@ #!/usr/bin/env node | ||
| loadConfigOrDefault | ||
| } from "./chunk-5HKEVUUN.js"; | ||
| } from "./chunk-PW5OH5KT.js"; | ||
@@ -9,0 +9,0 @@ // src/cli.ts |
+2
-2
@@ -15,3 +15,3 @@ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); | ||
| var _chunkW5UF3QWJcjs = require('./chunk-W5UF3QWJ.cjs'); | ||
| var _chunkX7BEAPLIcjs = require('./chunk-X7BEAPLI.cjs'); | ||
@@ -31,3 +31,3 @@ | ||
| exports.ExamplesConfigSchema = _chunkW5UF3QWJcjs.ExamplesConfigSchema; exports.ParamOverridesSchema = _chunkW5UF3QWJcjs.ParamOverridesSchema; exports.buildTemplateContext = _chunkW5UF3QWJcjs.buildTemplateContext; exports.generate = _chunkW5UF3QWJcjs.generate; exports.getAllLanguages = _chunkW5UF3QWJcjs.getAllLanguages; exports.getDefaultTemplatePath = _chunkW5UF3QWJcjs.getDefaultTemplatePath; exports.getLanguageByGenerator = _chunkW5UF3QWJcjs.getLanguageByGenerator; exports.getLanguageById = _chunkW5UF3QWJcjs.getLanguageById; exports.loadConfig = _chunkW5UF3QWJcjs.loadConfig; exports.loadConfigOrDefault = _chunkW5UF3QWJcjs.loadConfigOrDefault; exports.parseSpec = _chunkW5UF3QWJcjs.parseSpec; exports.registerLanguage = _chunkW5UF3QWJcjs.registerLanguage; exports.renderTemplate = _chunkW5UF3QWJcjs.renderTemplate; | ||
| exports.ExamplesConfigSchema = _chunkX7BEAPLIcjs.ExamplesConfigSchema; exports.ParamOverridesSchema = _chunkX7BEAPLIcjs.ParamOverridesSchema; exports.buildTemplateContext = _chunkX7BEAPLIcjs.buildTemplateContext; exports.generate = _chunkX7BEAPLIcjs.generate; exports.getAllLanguages = _chunkX7BEAPLIcjs.getAllLanguages; exports.getDefaultTemplatePath = _chunkX7BEAPLIcjs.getDefaultTemplatePath; exports.getLanguageByGenerator = _chunkX7BEAPLIcjs.getLanguageByGenerator; exports.getLanguageById = _chunkX7BEAPLIcjs.getLanguageById; exports.loadConfig = _chunkX7BEAPLIcjs.loadConfig; exports.loadConfigOrDefault = _chunkX7BEAPLIcjs.loadConfigOrDefault; exports.parseSpec = _chunkX7BEAPLIcjs.parseSpec; exports.registerLanguage = _chunkX7BEAPLIcjs.registerLanguage; exports.renderTemplate = _chunkX7BEAPLIcjs.renderTemplate; | ||
| //# sourceMappingURL=index.cjs.map |
+1
-1
@@ -15,3 +15,3 @@ import { | ||
| renderTemplate | ||
| } from "./chunk-5HKEVUUN.js"; | ||
| } from "./chunk-PW5OH5KT.js"; | ||
| export { | ||
@@ -18,0 +18,0 @@ ExamplesConfigSchema, |
+1
-1
| { | ||
| "name": "@eulerstream/openapi-generator-examples", | ||
| "version": "0.1.5", | ||
| "version": "0.2.0", | ||
| "description": "Generate clean, Stripe-like usage examples from OpenAPI specs with configurable Mustache templates", | ||
@@ -5,0 +5,0 @@ "type": "module", |
| // src/languages/registry.ts | ||
| var byId = /* @__PURE__ */ new Map(); | ||
| var byGenerator = /* @__PURE__ */ new Map(); | ||
| function registerLanguage(adapter) { | ||
| byId.set(adapter.id, adapter); | ||
| for (const gen of adapter.generatorNames) { | ||
| byGenerator.set(gen, adapter); | ||
| } | ||
| } | ||
| function getLanguageByGenerator(generatorName) { | ||
| return byGenerator.get(generatorName); | ||
| } | ||
| function getLanguageById(id) { | ||
| return byId.get(id); | ||
| } | ||
| function getAllLanguages() { | ||
| return [...byId.values()]; | ||
| } | ||
| // src/spec/parser.ts | ||
| import * as fs from "fs"; | ||
| import { parse as parseYaml } from "yaml"; | ||
| function parseSpec(specPath) { | ||
| const raw = fs.readFileSync(specPath, "utf-8"); | ||
| const spec = specPath.endsWith(".json") ? JSON.parse(raw) : parseYaml(raw); | ||
| return extractOperations(spec); | ||
| } | ||
| function extractOperations(spec) { | ||
| const paths = spec.paths; | ||
| if (!paths) return []; | ||
| const operations = []; | ||
| for (const [urlPath, methods] of Object.entries(paths)) { | ||
| for (const [method, opDef] of Object.entries(methods)) { | ||
| if (["get", "post", "put", "patch", "delete", "head", "options"].indexOf(method) === -1) { | ||
| continue; | ||
| } | ||
| const op = opDef; | ||
| if (!op.operationId) continue; | ||
| operations.push({ | ||
| operationId: op.operationId, | ||
| tag: (op.tags ?? ["Default"])[0], | ||
| httpMethod: method.toUpperCase(), | ||
| path: urlPath, | ||
| description: op.description, | ||
| parameters: normalizeParams(op.parameters, spec), | ||
| requestBody: normalizeRequestBody(op.requestBody, spec), | ||
| responseType: extractResponseType(op.responses, spec), | ||
| security: extractSecurity(op.security) | ||
| }); | ||
| } | ||
| } | ||
| return operations; | ||
| } | ||
| function normalizeParams(params, spec) { | ||
| if (!params) return []; | ||
| return params.map((p) => { | ||
| const param = resolveRef(p, spec); | ||
| const schema = resolveRef( | ||
| param.schema ?? { type: "string" }, | ||
| spec | ||
| ); | ||
| return { | ||
| name: param.name, | ||
| in: param.in, | ||
| required: param.required ?? false, | ||
| schema: normalizeSchema(schema, spec), | ||
| description: param.description, | ||
| example: param.example, | ||
| deprecated: param.deprecated ?? false | ||
| }; | ||
| }); | ||
| } | ||
| function normalizeRequestBody(body, spec) { | ||
| if (!body) return void 0; | ||
| const resolved = resolveRef(body, spec); | ||
| const content = resolved.content; | ||
| if (!content) return void 0; | ||
| const jsonContent = content["application/json"] ?? Object.values(content)[0]; | ||
| if (!jsonContent?.schema) return void 0; | ||
| const rawSchema = jsonContent.schema; | ||
| const schemaName = extractRefName(rawSchema); | ||
| const resolvedSchema = resolveRef(rawSchema, spec); | ||
| return { | ||
| required: resolved.required ?? false, | ||
| schemaName, | ||
| schema: normalizeSchema(resolvedSchema, spec) | ||
| }; | ||
| } | ||
| function normalizeSchema(schema, spec) { | ||
| const resolved = resolveRef(schema, spec); | ||
| const result = { | ||
| type: resolved.type ?? "object" | ||
| }; | ||
| if (resolved.format) result.format = resolved.format; | ||
| if (resolved.enum) result.enum = resolved.enum; | ||
| if (resolved.default !== void 0) result.default = resolved.default; | ||
| if (resolved.description) result.description = resolved.description; | ||
| if (resolved.items) { | ||
| result.items = normalizeSchema( | ||
| resolveRef(resolved.items, spec), | ||
| spec | ||
| ); | ||
| } | ||
| if (resolved.properties) { | ||
| const props = resolved.properties; | ||
| result.properties = {}; | ||
| for (const [name, propSchema] of Object.entries(props)) { | ||
| result.properties[name] = normalizeSchema( | ||
| resolveRef(propSchema, spec), | ||
| spec | ||
| ); | ||
| } | ||
| result.required = resolved.required ?? []; | ||
| } | ||
| return result; | ||
| } | ||
| function extractResponseType(responses, spec) { | ||
| if (!responses) return void 0; | ||
| const successResponse = responses["200"] ?? responses["201"]; | ||
| if (!successResponse) return void 0; | ||
| const resolved = resolveRef(successResponse, spec); | ||
| const content = resolved.content; | ||
| if (!content) return void 0; | ||
| const jsonContent = content["application/json"] ?? Object.values(content)[0]; | ||
| if (!jsonContent?.schema) return void 0; | ||
| return extractRefName(jsonContent.schema) ?? jsonContent.schema.type; | ||
| } | ||
| function extractSecurity(security) { | ||
| if (!security) return []; | ||
| const names = []; | ||
| for (const scheme of security) { | ||
| names.push(...Object.keys(scheme)); | ||
| } | ||
| return [...new Set(names)]; | ||
| } | ||
| function resolveRef(obj, spec) { | ||
| if (!obj || typeof obj !== "object") return obj; | ||
| const ref = obj["$ref"]; | ||
| if (!ref) return obj; | ||
| const parts = ref.replace(/^#\//, "").split("/"); | ||
| let current = spec; | ||
| for (const part of parts) { | ||
| if (current && typeof current === "object") { | ||
| current = current[part]; | ||
| } else { | ||
| return obj; | ||
| } | ||
| } | ||
| if (current && typeof current === "object") { | ||
| return current; | ||
| } | ||
| return obj; | ||
| } | ||
| function extractRefName(schema) { | ||
| const ref = schema["$ref"]; | ||
| if (!ref) return void 0; | ||
| const parts = ref.split("/"); | ||
| return parts[parts.length - 1]; | ||
| } | ||
| // src/templates/context.ts | ||
| function buildTemplateContext(op, config, adapter) { | ||
| const methodName = adapter.toMethodName(op.operationId); | ||
| const apiProperty = resolveApiProperty(op.tag, config.apiClassMap); | ||
| const apiClassName = adapter.toApiClassName(op.tag); | ||
| const params = op.parameters.filter((p) => !p.deprecated).map((p) => { | ||
| const override = resolveValueOverride(p.name, op.operationId, op.tag, config); | ||
| return toTemplateParam(p, adapter, override); | ||
| }); | ||
| const requiredParams = params.filter((p) => p.required); | ||
| const optionalParams = params.filter((p) => !p.required); | ||
| const paramDeclarations = op.parameters.filter((p) => !p.deprecated && p.required).map((p) => { | ||
| const override = resolveValueOverride(p.name, op.operationId, op.tag, config); | ||
| return adapter.buildParamDeclaration(p, override); | ||
| }).filter(Boolean).join("\n"); | ||
| const hasBody = !!op.requestBody; | ||
| const bodyTypeName = op.requestBody?.schemaName ?? ""; | ||
| const bodyOverrides = resolveBodyOverrides(op.requestBody, op.operationId, op.tag, config); | ||
| const bodyConstruction = op.requestBody ? adapter.buildBodyConstruction(op.requestBody, bodyOverrides) : ""; | ||
| const argParts = []; | ||
| for (const p of op.parameters.filter((p2) => !p2.deprecated && p2.required)) { | ||
| argParts.push(p.name); | ||
| } | ||
| if (hasBody) { | ||
| argParts.push("body"); | ||
| } | ||
| const args = argParts.join(", "); | ||
| const clientVar = config.variables.clientVar ?? "client"; | ||
| const apiAccessPattern = config.variables.apiAccessPattern ?? "dot"; | ||
| const methodCall = adapter.buildMethodCall({ | ||
| clientVar, | ||
| apiProperty, | ||
| methodName, | ||
| args, | ||
| apiAccessPattern | ||
| }); | ||
| const resultLine = adapter.buildResultLine(methodCall, op.responseType); | ||
| return { | ||
| operationId: op.operationId, | ||
| methodName, | ||
| tag: op.tag, | ||
| httpMethod: op.httpMethod, | ||
| path: op.path, | ||
| description: op.description ?? "", | ||
| apiProperty, | ||
| apiClassName, | ||
| params, | ||
| hasParams: params.length > 0, | ||
| requiredParams, | ||
| optionalParams, | ||
| hasRequiredParams: requiredParams.length > 0, | ||
| hasOptionalParams: optionalParams.length > 0, | ||
| hasBody, | ||
| bodyTypeName, | ||
| bodyConstruction, | ||
| paramDeclarations, | ||
| methodCall, | ||
| resultLine, | ||
| variables: config.variables, | ||
| boilerplate: config.boilerplate, | ||
| codeBlockLang: adapter.codeBlockLang | ||
| }; | ||
| } | ||
| function resolveApiProperty(tag, apiClassMap) { | ||
| if (apiClassMap[tag]) return apiClassMap[tag]; | ||
| return tag.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[A-Z]/, (c) => c.toLowerCase()); | ||
| } | ||
| function resolveValueOverride(paramName, operationId, tag, config) { | ||
| const ov = config.paramOverrides; | ||
| return ov.operations[operationId]?.[paramName] ?? ov.tags[tag]?.[paramName] ?? ov.global[paramName]; | ||
| } | ||
| function resolveBodyOverrides(body, operationId, tag, config) { | ||
| if (!body?.schema.properties) return void 0; | ||
| const result = {}; | ||
| let hasAny = false; | ||
| for (const propName of Object.keys(body.schema.properties)) { | ||
| const override = resolveValueOverride(propName, operationId, tag, config); | ||
| if (override !== void 0) { | ||
| result[propName] = override; | ||
| hasAny = true; | ||
| } | ||
| } | ||
| return hasAny ? result : void 0; | ||
| } | ||
| function toTemplateParam(param, adapter, valueOverride) { | ||
| return { | ||
| name: param.name, | ||
| type: adapter.mapType(param.schema), | ||
| description: param.description ?? "", | ||
| required: param.required, | ||
| defaultValue: param.schema.default != null ? String(param.schema.default) : "", | ||
| exampleValue: valueOverride ?? adapter.exampleValue(param), | ||
| hasDefault: param.schema.default != null | ||
| }; | ||
| } | ||
| // src/templates/renderer.ts | ||
| import * as fs2 from "fs"; | ||
| import * as path from "path"; | ||
| import Mustache from "mustache"; | ||
| Mustache.escape = (text) => text; | ||
| var templateCache = /* @__PURE__ */ new Map(); | ||
| function renderTemplate(templatePath, context) { | ||
| const template = loadTemplate(templatePath); | ||
| const rendered = Mustache.render(template, context); | ||
| return rendered.replace(/\n{3,}/g, "\n\n").trim() + "\n"; | ||
| } | ||
| function getDefaultTemplatePath(languageId) { | ||
| const srcPath = path.resolve( | ||
| import.meta.dirname ?? __dirname, | ||
| "defaults", | ||
| `${languageId}.mustache` | ||
| ); | ||
| if (fs2.existsSync(srcPath)) return srcPath; | ||
| const distPath = path.resolve( | ||
| import.meta.dirname ?? __dirname, | ||
| "..", | ||
| "templates", | ||
| "defaults", | ||
| `${languageId}.mustache` | ||
| ); | ||
| if (fs2.existsSync(distPath)) return distPath; | ||
| throw new Error( | ||
| `No default template found for language "${languageId}". Searched: ${srcPath}, ${distPath}` | ||
| ); | ||
| } | ||
| function loadTemplate(templatePath) { | ||
| const cached = templateCache.get(templatePath); | ||
| if (cached) return cached; | ||
| if (!fs2.existsSync(templatePath)) { | ||
| throw new Error(`Template not found: ${templatePath}`); | ||
| } | ||
| const content = fs2.readFileSync(templatePath, "utf-8"); | ||
| templateCache.set(templatePath, content); | ||
| return content; | ||
| } | ||
| // src/generator/pipeline.ts | ||
| import * as path3 from "path"; | ||
| // src/generator/writer.ts | ||
| import * as fs3 from "fs"; | ||
| import * as path2 from "path"; | ||
| function writeOperationFile(outputDir, op, renderedExample, context, adapter, formats) { | ||
| const tagDir = adapter.toTagDirectory(op.tag); | ||
| const fileName = adapter.toFileName(op.operationId); | ||
| const dirPath = path2.join(outputDir, adapter.id, tagDir); | ||
| fs3.mkdirSync(dirPath, { recursive: true }); | ||
| const filesWritten = []; | ||
| let json; | ||
| if (formats.includes("md")) { | ||
| const mdPath = path2.join(dirPath, fileName + ".md"); | ||
| const md = buildMarkdown(op, renderedExample, context); | ||
| fs3.writeFileSync(mdPath, md, "utf-8"); | ||
| filesWritten.push(mdPath); | ||
| } | ||
| if (formats.includes("json")) { | ||
| json = buildJson(op, renderedExample, context); | ||
| const jsonPath = path2.join(dirPath, fileName + ".json"); | ||
| fs3.writeFileSync(jsonPath, JSON.stringify(json, null, 2) + "\n", "utf-8"); | ||
| filesWritten.push(jsonPath); | ||
| } | ||
| return { filesWritten, json }; | ||
| } | ||
| function writeJsonIndex(outputDir, adapter, entries) { | ||
| const dirPath = path2.join(outputDir, adapter.id); | ||
| fs3.mkdirSync(dirPath, { recursive: true }); | ||
| fs3.writeFileSync( | ||
| path2.join(dirPath, "index.json"), | ||
| JSON.stringify(entries, null, 2) + "\n", | ||
| "utf-8" | ||
| ); | ||
| } | ||
| function writeLanguageIndex(outputDir, adapter, operations) { | ||
| const dirPath = path2.join(outputDir, adapter.id); | ||
| fs3.mkdirSync(dirPath, { recursive: true }); | ||
| const byTag = /* @__PURE__ */ new Map(); | ||
| for (const op of operations) { | ||
| const tag = op.tag; | ||
| if (!byTag.has(tag)) byTag.set(tag, []); | ||
| byTag.get(tag).push(op); | ||
| } | ||
| const lines = [`# Usage Examples (${adapter.id})`, ""]; | ||
| for (const [tag, ops] of byTag) { | ||
| const tagDir = adapter.toTagDirectory(tag); | ||
| lines.push(`## ${tag}`, ""); | ||
| lines.push("| Operation | Method | Path |"); | ||
| lines.push("|-----------|--------|------|"); | ||
| for (const op of ops) { | ||
| const fileName = adapter.toFileName(op.operationId); | ||
| lines.push(`| [${op.operationId}](./${tagDir}/${fileName}.md) | ${op.httpMethod} | \`${op.path}\` |`); | ||
| } | ||
| lines.push(""); | ||
| } | ||
| fs3.writeFileSync(path2.join(dirPath, "index.md"), lines.join("\n"), "utf-8"); | ||
| } | ||
| function buildJson(op, renderedExample, context) { | ||
| const json = { | ||
| operationId: op.operationId, | ||
| tag: op.tag, | ||
| httpMethod: op.httpMethod, | ||
| path: op.path, | ||
| description: op.description ?? "", | ||
| example: renderedExample.trimEnd(), | ||
| codeBlockLang: context.codeBlockLang, | ||
| parameters: context.params.map((p) => ({ | ||
| name: p.name, | ||
| type: p.type, | ||
| required: p.required, | ||
| description: p.description | ||
| })) | ||
| }; | ||
| if (context.hasBody && context.bodyTypeName) { | ||
| json.requestBody = { | ||
| typeName: context.bodyTypeName, | ||
| construction: context.bodyConstruction | ||
| }; | ||
| } | ||
| return json; | ||
| } | ||
| function buildMarkdown(op, renderedExample, context) { | ||
| const lines = []; | ||
| lines.push(`# ${op.operationId}`); | ||
| lines.push(""); | ||
| if (op.description) { | ||
| lines.push(op.description); | ||
| lines.push(""); | ||
| } | ||
| lines.push(`\`${op.httpMethod} ${op.path}\``); | ||
| lines.push(""); | ||
| lines.push("## Example"); | ||
| lines.push(""); | ||
| lines.push(`\`\`\`${context.codeBlockLang}`); | ||
| lines.push(renderedExample.trimEnd()); | ||
| lines.push("```"); | ||
| lines.push(""); | ||
| if (context.params.length > 0) { | ||
| lines.push("## Parameters"); | ||
| lines.push(""); | ||
| lines.push("| Name | Type | Required | Description |"); | ||
| lines.push("|------|------|----------|-------------|"); | ||
| for (const p of context.params) { | ||
| const req = p.required ? "Yes" : "No"; | ||
| const desc = p.description || "-"; | ||
| lines.push(`| \`${p.name}\` | \`${p.type}\` | ${req} | ${desc} |`); | ||
| } | ||
| lines.push(""); | ||
| } | ||
| if (context.hasBody) { | ||
| lines.push("## Request Body"); | ||
| lines.push(""); | ||
| lines.push(`Type: \`${context.bodyTypeName}\``); | ||
| lines.push(""); | ||
| } | ||
| return lines.join("\n"); | ||
| } | ||
| // src/generator/pipeline.ts | ||
| function generate(options) { | ||
| const { inputSpec, generator, outputDir, config } = options; | ||
| const adapter = getLanguageByGenerator(generator) ?? getLanguageById(generator); | ||
| if (!adapter) { | ||
| const msg = `Unknown generator/language: "${generator}". No language adapter registered for this identifier.`; | ||
| throw new Error(msg); | ||
| } | ||
| const usageDir = config.output ? path3.resolve(config.output) : path3.resolve(outputDir, "usage"); | ||
| const operations = parseSpec(inputSpec); | ||
| if (operations.length === 0) { | ||
| console.warn("No operations found in the OpenAPI spec."); | ||
| return { languageId: adapter.id, filesWritten: [], operationCount: 0 }; | ||
| } | ||
| const templatePath = config.templatePath ? path3.resolve(config.templatePath) : getDefaultTemplatePath(adapter.id); | ||
| const formats = config.outputFormats.length > 0 ? config.outputFormats : ["md"]; | ||
| const filesWritten = []; | ||
| const jsonEntries = []; | ||
| for (const op of operations) { | ||
| const context = buildTemplateContext(op, config, adapter); | ||
| const rendered = renderTemplate(templatePath, context); | ||
| const result = writeOperationFile(usageDir, op, rendered, context, adapter, formats); | ||
| filesWritten.push(...result.filesWritten); | ||
| if (result.json) jsonEntries.push(result.json); | ||
| } | ||
| writeLanguageIndex(usageDir, adapter, operations); | ||
| if (formats.includes("json") && jsonEntries.length > 0) { | ||
| writeJsonIndex(usageDir, adapter, jsonEntries); | ||
| } | ||
| return { | ||
| languageId: adapter.id, | ||
| filesWritten, | ||
| operationCount: operations.length | ||
| }; | ||
| } | ||
| // src/config/schema.ts | ||
| import { z } from "zod"; | ||
| var BoilerplateSchema = z.object({ | ||
| showTryCatch: z.boolean().default(false), | ||
| showImports: z.boolean().default(true), | ||
| showApiKeyConfig: z.boolean().default(false), | ||
| showFullClass: z.boolean().default(false) | ||
| }).default({}); | ||
| var ParamOverridesSchema = z.object({ | ||
| /** Global overrides applied to all operations */ | ||
| global: z.record(z.string(), z.string()).default({}), | ||
| /** Per-tag overrides (tag name → param name → value) */ | ||
| tags: z.record(z.string(), z.record(z.string(), z.string())).default({}), | ||
| /** Per-operation overrides (operationId → param name → value), highest priority */ | ||
| operations: z.record(z.string(), z.record(z.string(), z.string())).default({}) | ||
| }).default({}); | ||
| var ExamplesConfigSchema = z.object({ | ||
| /** Output directory for generated examples (default: ./usage relative to -o) */ | ||
| output: z.string().optional(), | ||
| /** Boilerplate control flags */ | ||
| boilerplate: BoilerplateSchema, | ||
| /** | ||
| * Template variables available in mustache templates. | ||
| * Well-known keys: | ||
| * sdkImport - import statement(s) for the SDK | ||
| * clientConstruction - code to construct the client instance | ||
| * clientVar - variable name for client (default: "client") | ||
| * apiKeyPlaceholder - placeholder for API key (default: "YOUR_API_KEY") | ||
| * apiAccessPattern - "dot" (client.api.method) or "call" (client.api().method) | ||
| */ | ||
| variables: z.record(z.string(), z.string()).default({}), | ||
| /** Maps OpenAPI tags -> wrapper property names (e.g., "TikTok LIVE": "webcast") */ | ||
| apiClassMap: z.record(z.string(), z.string()).default({}), | ||
| /** Path to a custom mustache template (overrides the built-in default for this language) */ | ||
| templatePath: z.string().optional(), | ||
| /** Output formats: "md" (markdown), "json", or both. Default: ["md"] */ | ||
| outputFormats: z.array(z.enum(["md", "json"])).default(["md"]), | ||
| /** | ||
| * Override example values for parameters and body properties. | ||
| * Values are raw code strings used as-is (no quoting/processing). | ||
| * Precedence: operations > tags > global (most-specific-wins). | ||
| */ | ||
| paramOverrides: ParamOverridesSchema | ||
| }); | ||
| // src/config/loader.ts | ||
| import * as fs4 from "fs"; | ||
| import { parse as parseYaml2 } from "yaml"; | ||
| var DEFAULTS = { | ||
| variables: { | ||
| clientVar: "apiInstance", | ||
| apiKeyPlaceholder: "YOUR_API_KEY", | ||
| apiAccessPattern: "direct", | ||
| sdkPackage: "./api" | ||
| } | ||
| }; | ||
| function loadConfig(configPath) { | ||
| if (!fs4.existsSync(configPath)) { | ||
| throw new Error(`Config file not found: ${configPath}`); | ||
| } | ||
| const raw = fs4.readFileSync(configPath, "utf-8"); | ||
| const parsed = parseYaml2(raw); | ||
| const merged = { | ||
| ...parsed, | ||
| variables: { | ||
| ...DEFAULTS.variables, | ||
| ...parsed?.variables | ||
| } | ||
| }; | ||
| const result = ExamplesConfigSchema.safeParse(merged); | ||
| if (!result.success) { | ||
| const issues = result.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n"); | ||
| throw new Error(`Invalid config: | ||
| ${issues}`); | ||
| } | ||
| return result.data; | ||
| } | ||
| function loadConfigOrDefault(configPath) { | ||
| if (configPath) { | ||
| return loadConfig(configPath); | ||
| } | ||
| return ExamplesConfigSchema.parse({ | ||
| variables: { ...DEFAULTS.variables } | ||
| }); | ||
| } | ||
| // src/languages/typescript.ts | ||
| function toCamelCase(str) { | ||
| if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toLowerCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[A-Z]/, (c) => c.toLowerCase()); | ||
| } | ||
| function toKebabCase(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").toLowerCase().replace(/^-|-$/g, ""); | ||
| } | ||
| function wrapOverrideForType(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "new Date()"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildObjectLiteral(schema, 0); | ||
| } | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema(schema.items, "item"); | ||
| return `[${itemValue}]`; | ||
| } | ||
| return "[]"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildObjectLiteral(schema, depth, valueOverrides) { | ||
| const props = schema.properties ?? {}; | ||
| const required = schema.required ?? []; | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = valueOverrides?.[propName]; | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildObjectLiteral(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${propName}: ${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{}"; | ||
| return "{\n" + entries.join("\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var typescriptAdapter = { | ||
| id: "typescript", | ||
| generatorNames: ["typescript-axios", "typescript-fetch", "typescript-angular", "typescript-node", "typescript"], | ||
| codeBlockLang: "typescript", | ||
| toMethodName(operationId) { | ||
| return toCamelCase(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toCamelCase(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toKebabCase(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "Date"; | ||
| } | ||
| return "string"; | ||
| case "integer": | ||
| case "number": | ||
| return "number"; | ||
| case "boolean": | ||
| return "boolean"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `${this.mapType(schema.items)}[]`; | ||
| } | ||
| return "unknown[]"; | ||
| case "object": | ||
| return "Record<string, unknown>"; | ||
| default: | ||
| return "unknown"; | ||
| } | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const tsType = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `let ${param.name}: ${tsType} = ${value};`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const objectLiteral = buildObjectLiteral(body.schema, 0, valueOverrides); | ||
| const opening = body.schemaName ? `const body: ${body.schemaName} = ` : `const body = `; | ||
| return opening + objectLiteral + ";"; | ||
| }, | ||
| buildResultLine(call, returnType) { | ||
| if (returnType) { | ||
| return `const { status, data } = await ${call};`; | ||
| } | ||
| return `await ${call};`; | ||
| } | ||
| }; | ||
| registerLanguage(typescriptAdapter); | ||
| // src/languages/python.ts | ||
| function toSnakeCase(str) { | ||
| return str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").toLowerCase().replace(/^_|_$/g, ""); | ||
| } | ||
| function toPascalCase(str) { | ||
| return str.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| } | ||
| function wrapOverrideForType2(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema2(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "datetime.now()"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "True"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildObjectLiteral2(schema, 0); | ||
| } | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema2(schema.items, "item"); | ||
| return `[${itemValue}]`; | ||
| } | ||
| return "[]"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildObjectLiteral2(schema, depth, valueOverrides, schemaName) { | ||
| const props = schema.properties ?? {}; | ||
| const required = schema.required ?? []; | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = valueOverrides?.[propName]; | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType2(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildObjectLiteral2(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema2(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${propName}=${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) { | ||
| return schemaName ? `${schemaName}()` : "{}"; | ||
| } | ||
| const opener = schemaName ? `${schemaName}( | ||
| ` : "{\n"; | ||
| const closer = schemaName ? `${closingIndent})` : `${closingIndent}}`; | ||
| return opener + entries.join("\n") + "\n" + closer; | ||
| } | ||
| var pythonAdapter = { | ||
| id: "python", | ||
| generatorNames: ["python", "python-pydantic-v1", "python-nextgen", "python-prior"], | ||
| codeBlockLang: "python", | ||
| toMethodName(operationId) { | ||
| return toSnakeCase(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toSnakeCase(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toSnakeCase(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = toPascalCase(tag); | ||
| const capitalized = stripped.charAt(0).toUpperCase() + stripped.slice(1); | ||
| return capitalized + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "datetime"; | ||
| } | ||
| return "str"; | ||
| case "integer": | ||
| return "int"; | ||
| case "number": | ||
| return "float"; | ||
| case "boolean": | ||
| return "bool"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `list[${this.mapType(schema.items)}]`; | ||
| } | ||
| return "list"; | ||
| case "object": | ||
| return "dict"; | ||
| default: | ||
| return "object"; | ||
| } | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema2(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const pyType = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType2(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${param.name}: ${pyType} = ${value}`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const literal = buildObjectLiteral2(body.schema, 0, valueOverrides, body.schemaName); | ||
| return `body = ${literal}`; | ||
| }, | ||
| buildResultLine(call, _returnType) { | ||
| return `result = ${call}`; | ||
| } | ||
| }; | ||
| registerLanguage(pythonAdapter); | ||
| // src/languages/java.ts | ||
| function toCamelCase2(str) { | ||
| if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toLowerCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[A-Z]/, (c) => c.toLowerCase()); | ||
| } | ||
| function toKebabCase2(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").toLowerCase().replace(/^-|-$/g, ""); | ||
| } | ||
| function toPascalCase2(str) { | ||
| return str.charAt(0).toUpperCase() + str.slice(1); | ||
| } | ||
| function wrapOverrideForType3(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function mapTypeForSchema(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date") return "LocalDate"; | ||
| if (schema.format === "date-time") return "OffsetDateTime"; | ||
| return "String"; | ||
| case "integer": | ||
| if (schema.format === "int64") return "Long"; | ||
| return "Integer"; | ||
| case "number": | ||
| return "Double"; | ||
| case "boolean": | ||
| return "Boolean"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `List<${mapTypeForSchema(schema.items)}>`; | ||
| } | ||
| return "List<Object>"; | ||
| case "object": | ||
| return "Object"; | ||
| default: | ||
| return "Object"; | ||
| } | ||
| } | ||
| function exampleValueForSchema3(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date") return "LocalDate.now()"; | ||
| if (schema.format === "date-time") return "OffsetDateTime.now()"; | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| return "0"; | ||
| case "number": | ||
| return "0D"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema3(schema.items, "item"); | ||
| return `Arrays.asList(${itemValue})`; | ||
| } | ||
| return "Arrays.asList()"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildSetterBody(body, valueOverrides) { | ||
| const schema = body.schema; | ||
| const typeName = body.schemaName ?? "Object"; | ||
| const props = schema.properties ?? {}; | ||
| const required = schema.required ?? []; | ||
| const lines = []; | ||
| lines.push(`${typeName} body = new ${typeName}();`); | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const setter = `set${toPascalCase2(propName)}`; | ||
| const override = valueOverrides?.[propName]; | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType3(override, propSchema); | ||
| } else { | ||
| value = exampleValueForSchema3(propSchema, propName); | ||
| } | ||
| lines.push(`body.${setter}(${value});`); | ||
| } | ||
| } | ||
| return lines.join("\n"); | ||
| } | ||
| var javaAdapter = { | ||
| id: "java", | ||
| generatorNames: ["java", "java-helidon-client", "java-helidon-server", "java-micronaut-client"], | ||
| codeBlockLang: "java", | ||
| toMethodName(operationId) { | ||
| return toCamelCase2(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toCamelCase2(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toKebabCase2(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| if (schema.type === "object" && schema.properties) { | ||
| return "Object"; | ||
| } | ||
| return mapTypeForSchema(schema); | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema3(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const javaType = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType3(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${javaType} ${param.name} = ${value};`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| return buildSetterBody(body, valueOverrides); | ||
| }, | ||
| buildResultLine(call, returnType) { | ||
| if (returnType) { | ||
| return `${returnType} result = ${call};`; | ||
| } | ||
| return `${call};`; | ||
| } | ||
| }; | ||
| registerLanguage(javaAdapter); | ||
| // src/languages/csharp.ts | ||
| function toPascalCase3(str) { | ||
| if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toUpperCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/[^a-zA-Z0-9]+/g, "").replace(/^[a-z]/, (c) => c.toUpperCase()); | ||
| } | ||
| function toTagDirectoryName(str) { | ||
| return str.split(/\s+/).map((word, i) => { | ||
| if (i === 0) return word; | ||
| return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); | ||
| }).join(""); | ||
| } | ||
| function csharpType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") return "DateTime"; | ||
| return "string"; | ||
| case "integer": | ||
| if (schema.format === "int64") return "long"; | ||
| return "int"; | ||
| case "number": | ||
| return "double"; | ||
| case "boolean": | ||
| return "bool"; | ||
| case "array": | ||
| if (schema.items) return `List<${csharpType(schema.items)}>`; | ||
| return "List<object>"; | ||
| case "object": | ||
| return "object"; | ||
| default: | ||
| return "object"; | ||
| } | ||
| } | ||
| function wrapOverrideForType4(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema4(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "DateTime.Now"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| return "0"; | ||
| case "number": | ||
| return "0.0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildObjectInitializer(schema, 0); | ||
| } | ||
| return "new { }"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemType = csharpType(schema.items); | ||
| const itemValue = exampleValueForSchema4(schema.items, "item"); | ||
| return `new List<${itemType}> { ${itemValue} }`; | ||
| } | ||
| return "new List<object>()"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildObjectInitializer(schema, depth, valueOverrides) { | ||
| const props = schema.properties ?? {}; | ||
| const required = schema.required ?? []; | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = valueOverrides?.[propName]; | ||
| const pascalName = propName.charAt(0).toUpperCase() + propName.slice(1); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType4(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = "new\n" + indent + buildObjectInitializer(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema4(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${pascalName} = ${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{ }"; | ||
| return "{\n" + entries.join("\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var csharpAdapter = { | ||
| id: "csharp", | ||
| generatorNames: ["csharp", "csharp-netcore", "csharp-functions"], | ||
| codeBlockLang: "csharp", | ||
| toMethodName(operationId) { | ||
| return toPascalCase3(operationId) + "Async"; | ||
| }, | ||
| toFileName(operationId) { | ||
| return toPascalCase3(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toTagDirectoryName(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| return csharpType(schema); | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema4(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const type = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType4(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${type} ${param.name} = ${value};`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const initializer = buildObjectInitializer(body.schema, 0, valueOverrides); | ||
| const typeName = body.schemaName ? ` ${body.schemaName}` : ""; | ||
| return `var body = new${typeName} | ||
| ${initializer};`; | ||
| }, | ||
| buildResultLine(call, returnType) { | ||
| if (returnType) { | ||
| return `var result = await ${call};`; | ||
| } | ||
| return `await ${call};`; | ||
| } | ||
| }; | ||
| registerLanguage(csharpAdapter); | ||
| // src/languages/go.ts | ||
| function toPascalCase4(str) { | ||
| if (/^[A-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str; | ||
| } | ||
| if (/^[a-z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toUpperCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[a-z]/, (c) => c.toUpperCase()); | ||
| } | ||
| function toSnakeCase2(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").toLowerCase().replace(/^_|_$/g, ""); | ||
| } | ||
| function wrapOverrideForType5(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema5(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "time.Now()"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildStructLiteral(schema, 0); | ||
| } | ||
| return "map[string]interface{}{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema5(schema.items, "item"); | ||
| return `[]${mapGoType(schema.items)}{${itemValue}}`; | ||
| } | ||
| return "[]interface{}{}"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function mapGoType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "time.Time"; | ||
| } | ||
| return "string"; | ||
| case "integer": | ||
| if (schema.format === "int32") { | ||
| return "int32"; | ||
| } | ||
| return "int64"; | ||
| case "number": | ||
| return "float64"; | ||
| case "boolean": | ||
| return "bool"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `[]${mapGoType(schema.items)}`; | ||
| } | ||
| return "[]interface{}"; | ||
| case "object": | ||
| return "map[string]interface{}"; | ||
| default: | ||
| return "interface{}"; | ||
| } | ||
| } | ||
| function buildStructLiteral(schema, depth, valueOverrides) { | ||
| const props = schema.properties ?? {}; | ||
| const required = schema.required ?? []; | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = valueOverrides?.[propName]; | ||
| const fieldName = toPascalCase4(propName); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType5(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildStructLiteral(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema5(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${fieldName}: ${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{}"; | ||
| return "{\n" + entries.join("\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var goAdapter = { | ||
| id: "go", | ||
| generatorNames: ["go", "go-server", "go-gin-server"], | ||
| codeBlockLang: "go", | ||
| toMethodName(operationId) { | ||
| return toPascalCase4(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toSnakeCase2(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toSnakeCase2(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "API"; | ||
| }, | ||
| mapType(schema) { | ||
| return mapGoType(schema); | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema5(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const value = valueOverride != null ? wrapOverrideForType5(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${param.name} := ${value}`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| const ctxArgs = args ? `context.Background(), ${args}` : "context.Background()"; | ||
| let call; | ||
| if (apiAccessPattern === "direct") { | ||
| call = `${clientVar}.${methodName}(${ctxArgs})`; | ||
| } else if (apiAccessPattern === "call") { | ||
| call = `${clientVar}.${apiProperty}().${methodName}(${ctxArgs})`; | ||
| } else { | ||
| call = `${clientVar}.${apiProperty}.${methodName}(${ctxArgs})`; | ||
| } | ||
| return `${call}.Execute()`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| if (!body.schemaName) { | ||
| const literal2 = buildStructLiteral(body.schema, 0, valueOverrides); | ||
| return `body := map[string]interface{}${literal2}`; | ||
| } | ||
| const literal = buildStructLiteral(body.schema, 0, valueOverrides); | ||
| return `body := openapi.${body.schemaName}${literal}`; | ||
| }, | ||
| buildResultLine(call, _returnType) { | ||
| return `resp, r, err := ${call}`; | ||
| } | ||
| }; | ||
| registerLanguage(goAdapter); | ||
| // src/languages/curl.ts | ||
| function toKebabCase3(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").toLowerCase().replace(/^-|-$/g, ""); | ||
| } | ||
| var currentParams = []; | ||
| function wrapOverrideForType6(override, schema) { | ||
| if (schema.type === "string") { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema6(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return schema.enum[0]; | ||
| } | ||
| if (schema.default != null) { | ||
| return String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "2024-01-01"; | ||
| } | ||
| return `${name}_value`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| return "{}"; | ||
| case "array": | ||
| return "[]"; | ||
| default: | ||
| return `${name}_value`; | ||
| } | ||
| } | ||
| function jsonValue(schema, name, depth) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return '"2024-01-01"'; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildJsonObject(schema, depth); | ||
| } | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `[${jsonValue(schema.items, "item", depth)}]`; | ||
| } | ||
| return "[]"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildJsonObject(schema, depth, valueOverrides) { | ||
| const props = schema.properties ?? {}; | ||
| const required = schema.required ?? []; | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = " ".repeat(depth); | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = valueOverrides?.[propName]; | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType6(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildJsonObject(propSchema, depth + 1); | ||
| } else { | ||
| value = jsonValue(propSchema, propName, depth + 1); | ||
| } | ||
| entries.push(`${indent}"${propName}": ${value}`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{}"; | ||
| return "{\n" + entries.join(",\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var curlAdapter = { | ||
| id: "curl", | ||
| generatorNames: ["curl"], | ||
| codeBlockLang: "bash", | ||
| toMethodName(operationId) { | ||
| return toKebabCase3(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toKebabCase3(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toKebabCase3(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| return tag; | ||
| }, | ||
| mapType(schema) { | ||
| return schema.type || "string"; | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return String(param.example); | ||
| } | ||
| return exampleValueForSchema6(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const value = valueOverride ?? this.exampleValue(param); | ||
| currentParams.push({ param, value }); | ||
| return `# ${param.name} = ${value}`; | ||
| }, | ||
| buildMethodCall(_opts) { | ||
| const queryParams = currentParams.filter(({ param }) => param.in === "query").map(({ param, value }) => `${param.name}=${encodeURIComponent(value)}`).join("&"); | ||
| currentParams = []; | ||
| return queryParams ? `?${queryParams}` : ""; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const json = buildJsonObject(body.schema, 1, valueOverrides); | ||
| return ` -d '${json}'`; | ||
| }, | ||
| buildResultLine(_call, _returnType) { | ||
| return ""; | ||
| } | ||
| }; | ||
| registerLanguage(curlAdapter); | ||
| export { | ||
| registerLanguage, | ||
| getLanguageByGenerator, | ||
| getLanguageById, | ||
| getAllLanguages, | ||
| parseSpec, | ||
| buildTemplateContext, | ||
| renderTemplate, | ||
| getDefaultTemplatePath, | ||
| generate, | ||
| ParamOverridesSchema, | ||
| ExamplesConfigSchema, | ||
| loadConfig, | ||
| loadConfigOrDefault | ||
| }; | ||
| //# sourceMappingURL=chunk-5HKEVUUN.js.map |
Sorry, the diff of this file is too big to display
| "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/languages/registry.ts | ||
| var byId = /* @__PURE__ */ new Map(); | ||
| var byGenerator = /* @__PURE__ */ new Map(); | ||
| function registerLanguage(adapter) { | ||
| byId.set(adapter.id, adapter); | ||
| for (const gen of adapter.generatorNames) { | ||
| byGenerator.set(gen, adapter); | ||
| } | ||
| } | ||
| function getLanguageByGenerator(generatorName) { | ||
| return byGenerator.get(generatorName); | ||
| } | ||
| function getLanguageById(id) { | ||
| return byId.get(id); | ||
| } | ||
| function getAllLanguages() { | ||
| return [...byId.values()]; | ||
| } | ||
| // src/spec/parser.ts | ||
| var _fs = require('fs'); var fs = _interopRequireWildcard(_fs); var fs2 = _interopRequireWildcard(_fs); var fs3 = _interopRequireWildcard(_fs); var fs4 = _interopRequireWildcard(_fs); | ||
| var _yaml = require('yaml'); | ||
| function parseSpec(specPath) { | ||
| const raw = fs.readFileSync(specPath, "utf-8"); | ||
| const spec = specPath.endsWith(".json") ? JSON.parse(raw) : _yaml.parse.call(void 0, raw); | ||
| return extractOperations(spec); | ||
| } | ||
| function extractOperations(spec) { | ||
| const paths = spec.paths; | ||
| if (!paths) return []; | ||
| const operations = []; | ||
| for (const [urlPath, methods] of Object.entries(paths)) { | ||
| for (const [method, opDef] of Object.entries(methods)) { | ||
| if (["get", "post", "put", "patch", "delete", "head", "options"].indexOf(method) === -1) { | ||
| continue; | ||
| } | ||
| const op = opDef; | ||
| if (!op.operationId) continue; | ||
| operations.push({ | ||
| operationId: op.operationId, | ||
| tag: (_nullishCoalesce(op.tags, () => ( ["Default"])))[0], | ||
| httpMethod: method.toUpperCase(), | ||
| path: urlPath, | ||
| description: op.description, | ||
| parameters: normalizeParams(op.parameters, spec), | ||
| requestBody: normalizeRequestBody(op.requestBody, spec), | ||
| responseType: extractResponseType(op.responses, spec), | ||
| security: extractSecurity(op.security) | ||
| }); | ||
| } | ||
| } | ||
| return operations; | ||
| } | ||
| function normalizeParams(params, spec) { | ||
| if (!params) return []; | ||
| return params.map((p) => { | ||
| const param = resolveRef(p, spec); | ||
| const schema = resolveRef( | ||
| _nullishCoalesce(param.schema, () => ( { type: "string" })), | ||
| spec | ||
| ); | ||
| return { | ||
| name: param.name, | ||
| in: param.in, | ||
| required: _nullishCoalesce(param.required, () => ( false)), | ||
| schema: normalizeSchema(schema, spec), | ||
| description: param.description, | ||
| example: param.example, | ||
| deprecated: _nullishCoalesce(param.deprecated, () => ( false)) | ||
| }; | ||
| }); | ||
| } | ||
| function normalizeRequestBody(body, spec) { | ||
| if (!body) return void 0; | ||
| const resolved = resolveRef(body, spec); | ||
| const content = resolved.content; | ||
| if (!content) return void 0; | ||
| const jsonContent = _nullishCoalesce(content["application/json"], () => ( Object.values(content)[0])); | ||
| if (!_optionalChain([jsonContent, 'optionalAccess', _2 => _2.schema])) return void 0; | ||
| const rawSchema = jsonContent.schema; | ||
| const schemaName = extractRefName(rawSchema); | ||
| const resolvedSchema = resolveRef(rawSchema, spec); | ||
| return { | ||
| required: _nullishCoalesce(resolved.required, () => ( false)), | ||
| schemaName, | ||
| schema: normalizeSchema(resolvedSchema, spec) | ||
| }; | ||
| } | ||
| function normalizeSchema(schema, spec) { | ||
| const resolved = resolveRef(schema, spec); | ||
| const result = { | ||
| type: _nullishCoalesce(resolved.type, () => ( "object")) | ||
| }; | ||
| if (resolved.format) result.format = resolved.format; | ||
| if (resolved.enum) result.enum = resolved.enum; | ||
| if (resolved.default !== void 0) result.default = resolved.default; | ||
| if (resolved.description) result.description = resolved.description; | ||
| if (resolved.items) { | ||
| result.items = normalizeSchema( | ||
| resolveRef(resolved.items, spec), | ||
| spec | ||
| ); | ||
| } | ||
| if (resolved.properties) { | ||
| const props = resolved.properties; | ||
| result.properties = {}; | ||
| for (const [name, propSchema] of Object.entries(props)) { | ||
| result.properties[name] = normalizeSchema( | ||
| resolveRef(propSchema, spec), | ||
| spec | ||
| ); | ||
| } | ||
| result.required = _nullishCoalesce(resolved.required, () => ( [])); | ||
| } | ||
| return result; | ||
| } | ||
| function extractResponseType(responses, spec) { | ||
| if (!responses) return void 0; | ||
| const successResponse = _nullishCoalesce(responses["200"], () => ( responses["201"])); | ||
| if (!successResponse) return void 0; | ||
| const resolved = resolveRef(successResponse, spec); | ||
| const content = resolved.content; | ||
| if (!content) return void 0; | ||
| const jsonContent = _nullishCoalesce(content["application/json"], () => ( Object.values(content)[0])); | ||
| if (!_optionalChain([jsonContent, 'optionalAccess', _3 => _3.schema])) return void 0; | ||
| return _nullishCoalesce(extractRefName(jsonContent.schema), () => ( jsonContent.schema.type)); | ||
| } | ||
| function extractSecurity(security) { | ||
| if (!security) return []; | ||
| const names = []; | ||
| for (const scheme of security) { | ||
| names.push(...Object.keys(scheme)); | ||
| } | ||
| return [...new Set(names)]; | ||
| } | ||
| function resolveRef(obj, spec) { | ||
| if (!obj || typeof obj !== "object") return obj; | ||
| const ref = obj["$ref"]; | ||
| if (!ref) return obj; | ||
| const parts = ref.replace(/^#\//, "").split("/"); | ||
| let current = spec; | ||
| for (const part of parts) { | ||
| if (current && typeof current === "object") { | ||
| current = current[part]; | ||
| } else { | ||
| return obj; | ||
| } | ||
| } | ||
| if (current && typeof current === "object") { | ||
| return current; | ||
| } | ||
| return obj; | ||
| } | ||
| function extractRefName(schema) { | ||
| const ref = schema["$ref"]; | ||
| if (!ref) return void 0; | ||
| const parts = ref.split("/"); | ||
| return parts[parts.length - 1]; | ||
| } | ||
| // src/templates/context.ts | ||
| function buildTemplateContext(op, config, adapter) { | ||
| const methodName = adapter.toMethodName(op.operationId); | ||
| const apiProperty = resolveApiProperty(op.tag, config.apiClassMap); | ||
| const apiClassName = adapter.toApiClassName(op.tag); | ||
| const params = op.parameters.filter((p) => !p.deprecated).map((p) => { | ||
| const override = resolveValueOverride(p.name, op.operationId, op.tag, config); | ||
| return toTemplateParam(p, adapter, override); | ||
| }); | ||
| const requiredParams = params.filter((p) => p.required); | ||
| const optionalParams = params.filter((p) => !p.required); | ||
| const paramDeclarations = op.parameters.filter((p) => !p.deprecated && p.required).map((p) => { | ||
| const override = resolveValueOverride(p.name, op.operationId, op.tag, config); | ||
| return adapter.buildParamDeclaration(p, override); | ||
| }).filter(Boolean).join("\n"); | ||
| const hasBody = !!op.requestBody; | ||
| const bodyTypeName = _nullishCoalesce(_optionalChain([op, 'access', _4 => _4.requestBody, 'optionalAccess', _5 => _5.schemaName]), () => ( "")); | ||
| const bodyOverrides = resolveBodyOverrides(op.requestBody, op.operationId, op.tag, config); | ||
| const bodyConstruction = op.requestBody ? adapter.buildBodyConstruction(op.requestBody, bodyOverrides) : ""; | ||
| const argParts = []; | ||
| for (const p of op.parameters.filter((p2) => !p2.deprecated && p2.required)) { | ||
| argParts.push(p.name); | ||
| } | ||
| if (hasBody) { | ||
| argParts.push("body"); | ||
| } | ||
| const args = argParts.join(", "); | ||
| const clientVar = _nullishCoalesce(config.variables.clientVar, () => ( "client")); | ||
| const apiAccessPattern = _nullishCoalesce(config.variables.apiAccessPattern, () => ( "dot")); | ||
| const methodCall = adapter.buildMethodCall({ | ||
| clientVar, | ||
| apiProperty, | ||
| methodName, | ||
| args, | ||
| apiAccessPattern | ||
| }); | ||
| const resultLine = adapter.buildResultLine(methodCall, op.responseType); | ||
| return { | ||
| operationId: op.operationId, | ||
| methodName, | ||
| tag: op.tag, | ||
| httpMethod: op.httpMethod, | ||
| path: op.path, | ||
| description: _nullishCoalesce(op.description, () => ( "")), | ||
| apiProperty, | ||
| apiClassName, | ||
| params, | ||
| hasParams: params.length > 0, | ||
| requiredParams, | ||
| optionalParams, | ||
| hasRequiredParams: requiredParams.length > 0, | ||
| hasOptionalParams: optionalParams.length > 0, | ||
| hasBody, | ||
| bodyTypeName, | ||
| bodyConstruction, | ||
| paramDeclarations, | ||
| methodCall, | ||
| resultLine, | ||
| variables: config.variables, | ||
| boilerplate: config.boilerplate, | ||
| codeBlockLang: adapter.codeBlockLang | ||
| }; | ||
| } | ||
| function resolveApiProperty(tag, apiClassMap) { | ||
| if (apiClassMap[tag]) return apiClassMap[tag]; | ||
| return tag.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[A-Z]/, (c) => c.toLowerCase()); | ||
| } | ||
| function resolveValueOverride(paramName, operationId, tag, config) { | ||
| const ov = config.paramOverrides; | ||
| return _nullishCoalesce(_nullishCoalesce(_optionalChain([ov, 'access', _6 => _6.operations, 'access', _7 => _7[operationId], 'optionalAccess', _8 => _8[paramName]]), () => ( _optionalChain([ov, 'access', _9 => _9.tags, 'access', _10 => _10[tag], 'optionalAccess', _11 => _11[paramName]]))), () => ( ov.global[paramName])); | ||
| } | ||
| function resolveBodyOverrides(body, operationId, tag, config) { | ||
| if (!_optionalChain([body, 'optionalAccess', _12 => _12.schema, 'access', _13 => _13.properties])) return void 0; | ||
| const result = {}; | ||
| let hasAny = false; | ||
| for (const propName of Object.keys(body.schema.properties)) { | ||
| const override = resolveValueOverride(propName, operationId, tag, config); | ||
| if (override !== void 0) { | ||
| result[propName] = override; | ||
| hasAny = true; | ||
| } | ||
| } | ||
| return hasAny ? result : void 0; | ||
| } | ||
| function toTemplateParam(param, adapter, valueOverride) { | ||
| return { | ||
| name: param.name, | ||
| type: adapter.mapType(param.schema), | ||
| description: _nullishCoalesce(param.description, () => ( "")), | ||
| required: param.required, | ||
| defaultValue: param.schema.default != null ? String(param.schema.default) : "", | ||
| exampleValue: _nullishCoalesce(valueOverride, () => ( adapter.exampleValue(param))), | ||
| hasDefault: param.schema.default != null | ||
| }; | ||
| } | ||
| // src/templates/renderer.ts | ||
| var _path = require('path'); var path = _interopRequireWildcard(_path); var path3 = _interopRequireWildcard(_path); var path2 = _interopRequireWildcard(_path); | ||
| var _mustache = require('mustache'); var _mustache2 = _interopRequireDefault(_mustache); | ||
| _mustache2.default.escape = (text) => text; | ||
| var templateCache = /* @__PURE__ */ new Map(); | ||
| function renderTemplate(templatePath, context) { | ||
| const template = loadTemplate(templatePath); | ||
| const rendered = _mustache2.default.render(template, context); | ||
| return rendered.replace(/\n{3,}/g, "\n\n").trim() + "\n"; | ||
| } | ||
| function getDefaultTemplatePath(languageId) { | ||
| const srcPath = path.resolve( | ||
| _nullishCoalesce(import.meta.dirname, () => ( __dirname)), | ||
| "defaults", | ||
| `${languageId}.mustache` | ||
| ); | ||
| if (fs2.existsSync(srcPath)) return srcPath; | ||
| const distPath = path.resolve( | ||
| _nullishCoalesce(import.meta.dirname, () => ( __dirname)), | ||
| "..", | ||
| "templates", | ||
| "defaults", | ||
| `${languageId}.mustache` | ||
| ); | ||
| if (fs2.existsSync(distPath)) return distPath; | ||
| throw new Error( | ||
| `No default template found for language "${languageId}". Searched: ${srcPath}, ${distPath}` | ||
| ); | ||
| } | ||
| function loadTemplate(templatePath) { | ||
| const cached = templateCache.get(templatePath); | ||
| if (cached) return cached; | ||
| if (!fs2.existsSync(templatePath)) { | ||
| throw new Error(`Template not found: ${templatePath}`); | ||
| } | ||
| const content = fs2.readFileSync(templatePath, "utf-8"); | ||
| templateCache.set(templatePath, content); | ||
| return content; | ||
| } | ||
| // src/generator/pipeline.ts | ||
| // src/generator/writer.ts | ||
| function writeOperationFile(outputDir, op, renderedExample, context, adapter, formats) { | ||
| const tagDir = adapter.toTagDirectory(op.tag); | ||
| const fileName = adapter.toFileName(op.operationId); | ||
| const dirPath = path2.join(outputDir, adapter.id, tagDir); | ||
| fs3.mkdirSync(dirPath, { recursive: true }); | ||
| const filesWritten = []; | ||
| let json; | ||
| if (formats.includes("md")) { | ||
| const mdPath = path2.join(dirPath, fileName + ".md"); | ||
| const md = buildMarkdown(op, renderedExample, context); | ||
| fs3.writeFileSync(mdPath, md, "utf-8"); | ||
| filesWritten.push(mdPath); | ||
| } | ||
| if (formats.includes("json")) { | ||
| json = buildJson(op, renderedExample, context); | ||
| const jsonPath = path2.join(dirPath, fileName + ".json"); | ||
| fs3.writeFileSync(jsonPath, JSON.stringify(json, null, 2) + "\n", "utf-8"); | ||
| filesWritten.push(jsonPath); | ||
| } | ||
| return { filesWritten, json }; | ||
| } | ||
| function writeJsonIndex(outputDir, adapter, entries) { | ||
| const dirPath = path2.join(outputDir, adapter.id); | ||
| fs3.mkdirSync(dirPath, { recursive: true }); | ||
| fs3.writeFileSync( | ||
| path2.join(dirPath, "index.json"), | ||
| JSON.stringify(entries, null, 2) + "\n", | ||
| "utf-8" | ||
| ); | ||
| } | ||
| function writeLanguageIndex(outputDir, adapter, operations) { | ||
| const dirPath = path2.join(outputDir, adapter.id); | ||
| fs3.mkdirSync(dirPath, { recursive: true }); | ||
| const byTag = /* @__PURE__ */ new Map(); | ||
| for (const op of operations) { | ||
| const tag = op.tag; | ||
| if (!byTag.has(tag)) byTag.set(tag, []); | ||
| byTag.get(tag).push(op); | ||
| } | ||
| const lines = [`# Usage Examples (${adapter.id})`, ""]; | ||
| for (const [tag, ops] of byTag) { | ||
| const tagDir = adapter.toTagDirectory(tag); | ||
| lines.push(`## ${tag}`, ""); | ||
| lines.push("| Operation | Method | Path |"); | ||
| lines.push("|-----------|--------|------|"); | ||
| for (const op of ops) { | ||
| const fileName = adapter.toFileName(op.operationId); | ||
| lines.push(`| [${op.operationId}](./${tagDir}/${fileName}.md) | ${op.httpMethod} | \`${op.path}\` |`); | ||
| } | ||
| lines.push(""); | ||
| } | ||
| fs3.writeFileSync(path2.join(dirPath, "index.md"), lines.join("\n"), "utf-8"); | ||
| } | ||
| function buildJson(op, renderedExample, context) { | ||
| const json = { | ||
| operationId: op.operationId, | ||
| tag: op.tag, | ||
| httpMethod: op.httpMethod, | ||
| path: op.path, | ||
| description: _nullishCoalesce(op.description, () => ( "")), | ||
| example: renderedExample.trimEnd(), | ||
| codeBlockLang: context.codeBlockLang, | ||
| parameters: context.params.map((p) => ({ | ||
| name: p.name, | ||
| type: p.type, | ||
| required: p.required, | ||
| description: p.description | ||
| })) | ||
| }; | ||
| if (context.hasBody && context.bodyTypeName) { | ||
| json.requestBody = { | ||
| typeName: context.bodyTypeName, | ||
| construction: context.bodyConstruction | ||
| }; | ||
| } | ||
| return json; | ||
| } | ||
| function buildMarkdown(op, renderedExample, context) { | ||
| const lines = []; | ||
| lines.push(`# ${op.operationId}`); | ||
| lines.push(""); | ||
| if (op.description) { | ||
| lines.push(op.description); | ||
| lines.push(""); | ||
| } | ||
| lines.push(`\`${op.httpMethod} ${op.path}\``); | ||
| lines.push(""); | ||
| lines.push("## Example"); | ||
| lines.push(""); | ||
| lines.push(`\`\`\`${context.codeBlockLang}`); | ||
| lines.push(renderedExample.trimEnd()); | ||
| lines.push("```"); | ||
| lines.push(""); | ||
| if (context.params.length > 0) { | ||
| lines.push("## Parameters"); | ||
| lines.push(""); | ||
| lines.push("| Name | Type | Required | Description |"); | ||
| lines.push("|------|------|----------|-------------|"); | ||
| for (const p of context.params) { | ||
| const req = p.required ? "Yes" : "No"; | ||
| const desc = p.description || "-"; | ||
| lines.push(`| \`${p.name}\` | \`${p.type}\` | ${req} | ${desc} |`); | ||
| } | ||
| lines.push(""); | ||
| } | ||
| if (context.hasBody) { | ||
| lines.push("## Request Body"); | ||
| lines.push(""); | ||
| lines.push(`Type: \`${context.bodyTypeName}\``); | ||
| lines.push(""); | ||
| } | ||
| return lines.join("\n"); | ||
| } | ||
| // src/generator/pipeline.ts | ||
| function generate(options) { | ||
| const { inputSpec, generator, outputDir, config } = options; | ||
| const adapter = _nullishCoalesce(getLanguageByGenerator(generator), () => ( getLanguageById(generator))); | ||
| if (!adapter) { | ||
| const msg = `Unknown generator/language: "${generator}". No language adapter registered for this identifier.`; | ||
| throw new Error(msg); | ||
| } | ||
| const usageDir = config.output ? path3.resolve(config.output) : path3.resolve(outputDir, "usage"); | ||
| const operations = parseSpec(inputSpec); | ||
| if (operations.length === 0) { | ||
| console.warn("No operations found in the OpenAPI spec."); | ||
| return { languageId: adapter.id, filesWritten: [], operationCount: 0 }; | ||
| } | ||
| const templatePath = config.templatePath ? path3.resolve(config.templatePath) : getDefaultTemplatePath(adapter.id); | ||
| const formats = config.outputFormats.length > 0 ? config.outputFormats : ["md"]; | ||
| const filesWritten = []; | ||
| const jsonEntries = []; | ||
| for (const op of operations) { | ||
| const context = buildTemplateContext(op, config, adapter); | ||
| const rendered = renderTemplate(templatePath, context); | ||
| const result = writeOperationFile(usageDir, op, rendered, context, adapter, formats); | ||
| filesWritten.push(...result.filesWritten); | ||
| if (result.json) jsonEntries.push(result.json); | ||
| } | ||
| writeLanguageIndex(usageDir, adapter, operations); | ||
| if (formats.includes("json") && jsonEntries.length > 0) { | ||
| writeJsonIndex(usageDir, adapter, jsonEntries); | ||
| } | ||
| return { | ||
| languageId: adapter.id, | ||
| filesWritten, | ||
| operationCount: operations.length | ||
| }; | ||
| } | ||
| // src/config/schema.ts | ||
| var _zod = require('zod'); | ||
| var BoilerplateSchema = _zod.z.object({ | ||
| showTryCatch: _zod.z.boolean().default(false), | ||
| showImports: _zod.z.boolean().default(true), | ||
| showApiKeyConfig: _zod.z.boolean().default(false), | ||
| showFullClass: _zod.z.boolean().default(false) | ||
| }).default({}); | ||
| var ParamOverridesSchema = _zod.z.object({ | ||
| /** Global overrides applied to all operations */ | ||
| global: _zod.z.record(_zod.z.string(), _zod.z.string()).default({}), | ||
| /** Per-tag overrides (tag name → param name → value) */ | ||
| tags: _zod.z.record(_zod.z.string(), _zod.z.record(_zod.z.string(), _zod.z.string())).default({}), | ||
| /** Per-operation overrides (operationId → param name → value), highest priority */ | ||
| operations: _zod.z.record(_zod.z.string(), _zod.z.record(_zod.z.string(), _zod.z.string())).default({}) | ||
| }).default({}); | ||
| var ExamplesConfigSchema = _zod.z.object({ | ||
| /** Output directory for generated examples (default: ./usage relative to -o) */ | ||
| output: _zod.z.string().optional(), | ||
| /** Boilerplate control flags */ | ||
| boilerplate: BoilerplateSchema, | ||
| /** | ||
| * Template variables available in mustache templates. | ||
| * Well-known keys: | ||
| * sdkImport - import statement(s) for the SDK | ||
| * clientConstruction - code to construct the client instance | ||
| * clientVar - variable name for client (default: "client") | ||
| * apiKeyPlaceholder - placeholder for API key (default: "YOUR_API_KEY") | ||
| * apiAccessPattern - "dot" (client.api.method) or "call" (client.api().method) | ||
| */ | ||
| variables: _zod.z.record(_zod.z.string(), _zod.z.string()).default({}), | ||
| /** Maps OpenAPI tags -> wrapper property names (e.g., "TikTok LIVE": "webcast") */ | ||
| apiClassMap: _zod.z.record(_zod.z.string(), _zod.z.string()).default({}), | ||
| /** Path to a custom mustache template (overrides the built-in default for this language) */ | ||
| templatePath: _zod.z.string().optional(), | ||
| /** Output formats: "md" (markdown), "json", or both. Default: ["md"] */ | ||
| outputFormats: _zod.z.array(_zod.z.enum(["md", "json"])).default(["md"]), | ||
| /** | ||
| * Override example values for parameters and body properties. | ||
| * Values are raw code strings used as-is (no quoting/processing). | ||
| * Precedence: operations > tags > global (most-specific-wins). | ||
| */ | ||
| paramOverrides: ParamOverridesSchema | ||
| }); | ||
| // src/config/loader.ts | ||
| var DEFAULTS = { | ||
| variables: { | ||
| clientVar: "apiInstance", | ||
| apiKeyPlaceholder: "YOUR_API_KEY", | ||
| apiAccessPattern: "direct", | ||
| sdkPackage: "./api" | ||
| } | ||
| }; | ||
| function loadConfig(configPath) { | ||
| if (!fs4.existsSync(configPath)) { | ||
| throw new Error(`Config file not found: ${configPath}`); | ||
| } | ||
| const raw = fs4.readFileSync(configPath, "utf-8"); | ||
| const parsed = _yaml.parse.call(void 0, raw); | ||
| const merged = { | ||
| ...parsed, | ||
| variables: { | ||
| ...DEFAULTS.variables, | ||
| ..._optionalChain([parsed, 'optionalAccess', _14 => _14.variables]) | ||
| } | ||
| }; | ||
| const result = ExamplesConfigSchema.safeParse(merged); | ||
| if (!result.success) { | ||
| const issues = result.error.issues.map((i) => ` - ${i.path.join(".")}: ${i.message}`).join("\n"); | ||
| throw new Error(`Invalid config: | ||
| ${issues}`); | ||
| } | ||
| return result.data; | ||
| } | ||
| function loadConfigOrDefault(configPath) { | ||
| if (configPath) { | ||
| return loadConfig(configPath); | ||
| } | ||
| return ExamplesConfigSchema.parse({ | ||
| variables: { ...DEFAULTS.variables } | ||
| }); | ||
| } | ||
| // src/languages/typescript.ts | ||
| function toCamelCase(str) { | ||
| if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toLowerCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[A-Z]/, (c) => c.toLowerCase()); | ||
| } | ||
| function toKebabCase(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").toLowerCase().replace(/^-|-$/g, ""); | ||
| } | ||
| function wrapOverrideForType(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "new Date()"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildObjectLiteral(schema, 0); | ||
| } | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema(schema.items, "item"); | ||
| return `[${itemValue}]`; | ||
| } | ||
| return "[]"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildObjectLiteral(schema, depth, valueOverrides) { | ||
| const props = _nullishCoalesce(schema.properties, () => ( {})); | ||
| const required = _nullishCoalesce(schema.required, () => ( [])); | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = _optionalChain([valueOverrides, 'optionalAccess', _15 => _15[propName]]); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildObjectLiteral(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${propName}: ${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{}"; | ||
| return "{\n" + entries.join("\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var typescriptAdapter = { | ||
| id: "typescript", | ||
| generatorNames: ["typescript-axios", "typescript-fetch", "typescript-angular", "typescript-node", "typescript"], | ||
| codeBlockLang: "typescript", | ||
| toMethodName(operationId) { | ||
| return toCamelCase(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toCamelCase(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toKebabCase(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "Date"; | ||
| } | ||
| return "string"; | ||
| case "integer": | ||
| case "number": | ||
| return "number"; | ||
| case "boolean": | ||
| return "boolean"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `${this.mapType(schema.items)}[]`; | ||
| } | ||
| return "unknown[]"; | ||
| case "object": | ||
| return "Record<string, unknown>"; | ||
| default: | ||
| return "unknown"; | ||
| } | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const tsType = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `let ${param.name}: ${tsType} = ${value};`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const objectLiteral = buildObjectLiteral(body.schema, 0, valueOverrides); | ||
| const opening = body.schemaName ? `const body: ${body.schemaName} = ` : `const body = `; | ||
| return opening + objectLiteral + ";"; | ||
| }, | ||
| buildResultLine(call, returnType) { | ||
| if (returnType) { | ||
| return `const { status, data } = await ${call};`; | ||
| } | ||
| return `await ${call};`; | ||
| } | ||
| }; | ||
| registerLanguage(typescriptAdapter); | ||
| // src/languages/python.ts | ||
| function toSnakeCase(str) { | ||
| return str.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").toLowerCase().replace(/^_|_$/g, ""); | ||
| } | ||
| function toPascalCase(str) { | ||
| return str.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| } | ||
| function wrapOverrideForType2(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema2(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "datetime.now()"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "True"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildObjectLiteral2(schema, 0); | ||
| } | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema2(schema.items, "item"); | ||
| return `[${itemValue}]`; | ||
| } | ||
| return "[]"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildObjectLiteral2(schema, depth, valueOverrides, schemaName) { | ||
| const props = _nullishCoalesce(schema.properties, () => ( {})); | ||
| const required = _nullishCoalesce(schema.required, () => ( [])); | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = _optionalChain([valueOverrides, 'optionalAccess', _16 => _16[propName]]); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType2(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildObjectLiteral2(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema2(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${propName}=${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) { | ||
| return schemaName ? `${schemaName}()` : "{}"; | ||
| } | ||
| const opener = schemaName ? `${schemaName}( | ||
| ` : "{\n"; | ||
| const closer = schemaName ? `${closingIndent})` : `${closingIndent}}`; | ||
| return opener + entries.join("\n") + "\n" + closer; | ||
| } | ||
| var pythonAdapter = { | ||
| id: "python", | ||
| generatorNames: ["python", "python-pydantic-v1", "python-nextgen", "python-prior"], | ||
| codeBlockLang: "python", | ||
| toMethodName(operationId) { | ||
| return toSnakeCase(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toSnakeCase(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toSnakeCase(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = toPascalCase(tag); | ||
| const capitalized = stripped.charAt(0).toUpperCase() + stripped.slice(1); | ||
| return capitalized + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "datetime"; | ||
| } | ||
| return "str"; | ||
| case "integer": | ||
| return "int"; | ||
| case "number": | ||
| return "float"; | ||
| case "boolean": | ||
| return "bool"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `list[${this.mapType(schema.items)}]`; | ||
| } | ||
| return "list"; | ||
| case "object": | ||
| return "dict"; | ||
| default: | ||
| return "object"; | ||
| } | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema2(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const pyType = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType2(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${param.name}: ${pyType} = ${value}`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const literal = buildObjectLiteral2(body.schema, 0, valueOverrides, body.schemaName); | ||
| return `body = ${literal}`; | ||
| }, | ||
| buildResultLine(call, _returnType) { | ||
| return `result = ${call}`; | ||
| } | ||
| }; | ||
| registerLanguage(pythonAdapter); | ||
| // src/languages/java.ts | ||
| function toCamelCase2(str) { | ||
| if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toLowerCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[A-Z]/, (c) => c.toLowerCase()); | ||
| } | ||
| function toKebabCase2(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").toLowerCase().replace(/^-|-$/g, ""); | ||
| } | ||
| function toPascalCase2(str) { | ||
| return str.charAt(0).toUpperCase() + str.slice(1); | ||
| } | ||
| function wrapOverrideForType3(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function mapTypeForSchema(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date") return "LocalDate"; | ||
| if (schema.format === "date-time") return "OffsetDateTime"; | ||
| return "String"; | ||
| case "integer": | ||
| if (schema.format === "int64") return "Long"; | ||
| return "Integer"; | ||
| case "number": | ||
| return "Double"; | ||
| case "boolean": | ||
| return "Boolean"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `List<${mapTypeForSchema(schema.items)}>`; | ||
| } | ||
| return "List<Object>"; | ||
| case "object": | ||
| return "Object"; | ||
| default: | ||
| return "Object"; | ||
| } | ||
| } | ||
| function exampleValueForSchema3(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date") return "LocalDate.now()"; | ||
| if (schema.format === "date-time") return "OffsetDateTime.now()"; | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| return "0"; | ||
| case "number": | ||
| return "0D"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema3(schema.items, "item"); | ||
| return `Arrays.asList(${itemValue})`; | ||
| } | ||
| return "Arrays.asList()"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildSetterBody(body, valueOverrides) { | ||
| const schema = body.schema; | ||
| const typeName = _nullishCoalesce(body.schemaName, () => ( "Object")); | ||
| const props = _nullishCoalesce(schema.properties, () => ( {})); | ||
| const required = _nullishCoalesce(schema.required, () => ( [])); | ||
| const lines = []; | ||
| lines.push(`${typeName} body = new ${typeName}();`); | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const setter = `set${toPascalCase2(propName)}`; | ||
| const override = _optionalChain([valueOverrides, 'optionalAccess', _17 => _17[propName]]); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType3(override, propSchema); | ||
| } else { | ||
| value = exampleValueForSchema3(propSchema, propName); | ||
| } | ||
| lines.push(`body.${setter}(${value});`); | ||
| } | ||
| } | ||
| return lines.join("\n"); | ||
| } | ||
| var javaAdapter = { | ||
| id: "java", | ||
| generatorNames: ["java", "java-helidon-client", "java-helidon-server", "java-micronaut-client"], | ||
| codeBlockLang: "java", | ||
| toMethodName(operationId) { | ||
| return toCamelCase2(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toCamelCase2(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toKebabCase2(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| if (schema.type === "object" && schema.properties) { | ||
| return "Object"; | ||
| } | ||
| return mapTypeForSchema(schema); | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema3(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const javaType = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType3(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${javaType} ${param.name} = ${value};`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| return buildSetterBody(body, valueOverrides); | ||
| }, | ||
| buildResultLine(call, returnType) { | ||
| if (returnType) { | ||
| return `${returnType} result = ${call};`; | ||
| } | ||
| return `${call};`; | ||
| } | ||
| }; | ||
| registerLanguage(javaAdapter); | ||
| // src/languages/csharp.ts | ||
| function toPascalCase3(str) { | ||
| if (/^[a-zA-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toUpperCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/[^a-zA-Z0-9]+/g, "").replace(/^[a-z]/, (c) => c.toUpperCase()); | ||
| } | ||
| function toTagDirectoryName(str) { | ||
| return str.split(/\s+/).map((word, i) => { | ||
| if (i === 0) return word; | ||
| return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase(); | ||
| }).join(""); | ||
| } | ||
| function csharpType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") return "DateTime"; | ||
| return "string"; | ||
| case "integer": | ||
| if (schema.format === "int64") return "long"; | ||
| return "int"; | ||
| case "number": | ||
| return "double"; | ||
| case "boolean": | ||
| return "bool"; | ||
| case "array": | ||
| if (schema.items) return `List<${csharpType(schema.items)}>`; | ||
| return "List<object>"; | ||
| case "object": | ||
| return "object"; | ||
| default: | ||
| return "object"; | ||
| } | ||
| } | ||
| function wrapOverrideForType4(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema4(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "DateTime.Now"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| return "0"; | ||
| case "number": | ||
| return "0.0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildObjectInitializer(schema, 0); | ||
| } | ||
| return "new { }"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemType = csharpType(schema.items); | ||
| const itemValue = exampleValueForSchema4(schema.items, "item"); | ||
| return `new List<${itemType}> { ${itemValue} }`; | ||
| } | ||
| return "new List<object>()"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildObjectInitializer(schema, depth, valueOverrides) { | ||
| const props = _nullishCoalesce(schema.properties, () => ( {})); | ||
| const required = _nullishCoalesce(schema.required, () => ( [])); | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = _optionalChain([valueOverrides, 'optionalAccess', _18 => _18[propName]]); | ||
| const pascalName = propName.charAt(0).toUpperCase() + propName.slice(1); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType4(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = "new\n" + indent + buildObjectInitializer(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema4(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${pascalName} = ${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{ }"; | ||
| return "{\n" + entries.join("\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var csharpAdapter = { | ||
| id: "csharp", | ||
| generatorNames: ["csharp", "csharp-netcore", "csharp-functions"], | ||
| codeBlockLang: "csharp", | ||
| toMethodName(operationId) { | ||
| return toPascalCase3(operationId) + "Async"; | ||
| }, | ||
| toFileName(operationId) { | ||
| return toPascalCase3(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toTagDirectoryName(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "Api"; | ||
| }, | ||
| mapType(schema) { | ||
| return csharpType(schema); | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema4(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const type = this.mapType(param.schema); | ||
| const value = valueOverride != null ? wrapOverrideForType4(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${type} ${param.name} = ${value};`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| if (apiAccessPattern === "direct") { | ||
| return `${clientVar}.${methodName}(${args})`; | ||
| } | ||
| if (apiAccessPattern === "call") { | ||
| return `${clientVar}.${apiProperty}().${methodName}(${args})`; | ||
| } | ||
| return `${clientVar}.${apiProperty}.${methodName}(${args})`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const initializer = buildObjectInitializer(body.schema, 0, valueOverrides); | ||
| const typeName = body.schemaName ? ` ${body.schemaName}` : ""; | ||
| return `var body = new${typeName} | ||
| ${initializer};`; | ||
| }, | ||
| buildResultLine(call, returnType) { | ||
| if (returnType) { | ||
| return `var result = await ${call};`; | ||
| } | ||
| return `await ${call};`; | ||
| } | ||
| }; | ||
| registerLanguage(csharpAdapter); | ||
| // src/languages/go.ts | ||
| function toPascalCase4(str) { | ||
| if (/^[A-Z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str; | ||
| } | ||
| if (/^[a-z][a-zA-Z0-9]*$/.test(str)) { | ||
| return str.charAt(0).toUpperCase() + str.slice(1); | ||
| } | ||
| return str.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/^[a-z]/, (c) => c.toUpperCase()); | ||
| } | ||
| function toSnakeCase2(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1_$2").replace(/[^a-zA-Z0-9]+/g, "_").toLowerCase().replace(/^_|_$/g, ""); | ||
| } | ||
| function wrapOverrideForType5(override, schema) { | ||
| if (schema.type === "string" && !(schema.format === "date" || schema.format === "date-time")) { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema5(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "time.Now()"; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildStructLiteral(schema, 0); | ||
| } | ||
| return "map[string]interface{}{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| const itemValue = exampleValueForSchema5(schema.items, "item"); | ||
| return `[]${mapGoType(schema.items)}{${itemValue}}`; | ||
| } | ||
| return "[]interface{}{}"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function mapGoType(schema) { | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "time.Time"; | ||
| } | ||
| return "string"; | ||
| case "integer": | ||
| if (schema.format === "int32") { | ||
| return "int32"; | ||
| } | ||
| return "int64"; | ||
| case "number": | ||
| return "float64"; | ||
| case "boolean": | ||
| return "bool"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `[]${mapGoType(schema.items)}`; | ||
| } | ||
| return "[]interface{}"; | ||
| case "object": | ||
| return "map[string]interface{}"; | ||
| default: | ||
| return "interface{}"; | ||
| } | ||
| } | ||
| function buildStructLiteral(schema, depth, valueOverrides) { | ||
| const props = _nullishCoalesce(schema.properties, () => ( {})); | ||
| const required = _nullishCoalesce(schema.required, () => ( [])); | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = depth > 0 ? " ".repeat(depth) : ""; | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = _optionalChain([valueOverrides, 'optionalAccess', _19 => _19[propName]]); | ||
| const fieldName = toPascalCase4(propName); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType5(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildStructLiteral(propSchema, depth + 1); | ||
| } else { | ||
| value = exampleValueForSchema5(propSchema, propName); | ||
| } | ||
| entries.push(`${indent}${fieldName}: ${value},`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{}"; | ||
| return "{\n" + entries.join("\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var goAdapter = { | ||
| id: "go", | ||
| generatorNames: ["go", "go-server", "go-gin-server"], | ||
| codeBlockLang: "go", | ||
| toMethodName(operationId) { | ||
| return toPascalCase4(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toSnakeCase2(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toSnakeCase2(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| const stripped = tag.replace(/\s+(.)/g, (_, c) => c.toUpperCase()).replace(/\s+/g, ""); | ||
| return stripped.charAt(0).toUpperCase() + stripped.slice(1) + "API"; | ||
| }, | ||
| mapType(schema) { | ||
| return mapGoType(schema); | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return typeof param.example === "string" ? `"${param.example}"` : String(param.example); | ||
| } | ||
| return exampleValueForSchema5(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const value = valueOverride != null ? wrapOverrideForType5(valueOverride, param.schema) : this.exampleValue(param); | ||
| return `${param.name} := ${value}`; | ||
| }, | ||
| buildMethodCall(opts) { | ||
| const { clientVar, apiProperty, methodName, args, apiAccessPattern } = opts; | ||
| const ctxArgs = args ? `context.Background(), ${args}` : "context.Background()"; | ||
| let call; | ||
| if (apiAccessPattern === "direct") { | ||
| call = `${clientVar}.${methodName}(${ctxArgs})`; | ||
| } else if (apiAccessPattern === "call") { | ||
| call = `${clientVar}.${apiProperty}().${methodName}(${ctxArgs})`; | ||
| } else { | ||
| call = `${clientVar}.${apiProperty}.${methodName}(${ctxArgs})`; | ||
| } | ||
| return `${call}.Execute()`; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| if (!body.schemaName) { | ||
| const literal2 = buildStructLiteral(body.schema, 0, valueOverrides); | ||
| return `body := map[string]interface{}${literal2}`; | ||
| } | ||
| const literal = buildStructLiteral(body.schema, 0, valueOverrides); | ||
| return `body := openapi.${body.schemaName}${literal}`; | ||
| }, | ||
| buildResultLine(call, _returnType) { | ||
| return `resp, r, err := ${call}`; | ||
| } | ||
| }; | ||
| registerLanguage(goAdapter); | ||
| // src/languages/curl.ts | ||
| function toKebabCase3(str) { | ||
| return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9]+/g, "-").toLowerCase().replace(/^-|-$/g, ""); | ||
| } | ||
| var currentParams = []; | ||
| function wrapOverrideForType6(override, schema) { | ||
| if (schema.type === "string") { | ||
| return `"${override}"`; | ||
| } | ||
| return override; | ||
| } | ||
| function exampleValueForSchema6(schema, name) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return schema.enum[0]; | ||
| } | ||
| if (schema.default != null) { | ||
| return String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return "2024-01-01"; | ||
| } | ||
| return `${name}_value`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| return "{}"; | ||
| case "array": | ||
| return "[]"; | ||
| default: | ||
| return `${name}_value`; | ||
| } | ||
| } | ||
| function jsonValue(schema, name, depth) { | ||
| if (schema.enum && schema.enum.length > 0) { | ||
| return `"${schema.enum[0]}"`; | ||
| } | ||
| if (schema.default != null) { | ||
| return typeof schema.default === "string" ? `"${schema.default}"` : String(schema.default); | ||
| } | ||
| switch (schema.type) { | ||
| case "string": | ||
| if (schema.format === "date" || schema.format === "date-time") { | ||
| return '"2024-01-01"'; | ||
| } | ||
| return `"${name}_value"`; | ||
| case "integer": | ||
| case "number": | ||
| return "0"; | ||
| case "boolean": | ||
| return "true"; | ||
| case "object": | ||
| if (schema.properties) { | ||
| return buildJsonObject(schema, depth); | ||
| } | ||
| return "{}"; | ||
| case "array": | ||
| if (schema.items) { | ||
| return `[${jsonValue(schema.items, "item", depth)}]`; | ||
| } | ||
| return "[]"; | ||
| default: | ||
| return `"${name}_value"`; | ||
| } | ||
| } | ||
| function buildJsonObject(schema, depth, valueOverrides) { | ||
| const props = _nullishCoalesce(schema.properties, () => ( {})); | ||
| const required = _nullishCoalesce(schema.required, () => ( [])); | ||
| const indent = " ".repeat(depth + 1); | ||
| const closingIndent = " ".repeat(depth); | ||
| const entries = []; | ||
| for (const [propName, propSchema] of Object.entries(props)) { | ||
| if (required.includes(propName)) { | ||
| const override = _optionalChain([valueOverrides, 'optionalAccess', _20 => _20[propName]]); | ||
| let value; | ||
| if (override != null) { | ||
| value = wrapOverrideForType6(override, propSchema); | ||
| } else if (propSchema.type === "object" && propSchema.properties) { | ||
| value = buildJsonObject(propSchema, depth + 1); | ||
| } else { | ||
| value = jsonValue(propSchema, propName, depth + 1); | ||
| } | ||
| entries.push(`${indent}"${propName}": ${value}`); | ||
| } | ||
| } | ||
| if (entries.length === 0) return "{}"; | ||
| return "{\n" + entries.join(",\n") + "\n" + closingIndent + "}"; | ||
| } | ||
| var curlAdapter = { | ||
| id: "curl", | ||
| generatorNames: ["curl"], | ||
| codeBlockLang: "bash", | ||
| toMethodName(operationId) { | ||
| return toKebabCase3(operationId); | ||
| }, | ||
| toFileName(operationId) { | ||
| return toKebabCase3(operationId); | ||
| }, | ||
| toTagDirectory(tag) { | ||
| return toKebabCase3(tag); | ||
| }, | ||
| toApiClassName(tag) { | ||
| return tag; | ||
| }, | ||
| mapType(schema) { | ||
| return schema.type || "string"; | ||
| }, | ||
| exampleValue(param) { | ||
| if (param.example != null) { | ||
| return String(param.example); | ||
| } | ||
| return exampleValueForSchema6(param.schema, param.name); | ||
| }, | ||
| buildParamDeclaration(param, valueOverride) { | ||
| const value = _nullishCoalesce(valueOverride, () => ( this.exampleValue(param))); | ||
| currentParams.push({ param, value }); | ||
| return `# ${param.name} = ${value}`; | ||
| }, | ||
| buildMethodCall(_opts) { | ||
| const queryParams = currentParams.filter(({ param }) => param.in === "query").map(({ param, value }) => `${param.name}=${encodeURIComponent(value)}`).join("&"); | ||
| currentParams = []; | ||
| return queryParams ? `?${queryParams}` : ""; | ||
| }, | ||
| buildBodyConstruction(body, valueOverrides) { | ||
| const json = buildJsonObject(body.schema, 1, valueOverrides); | ||
| return ` -d '${json}'`; | ||
| }, | ||
| buildResultLine(_call, _returnType) { | ||
| return ""; | ||
| } | ||
| }; | ||
| registerLanguage(curlAdapter); | ||
| exports.registerLanguage = registerLanguage; exports.getLanguageByGenerator = getLanguageByGenerator; exports.getLanguageById = getLanguageById; exports.getAllLanguages = getAllLanguages; exports.parseSpec = parseSpec; exports.buildTemplateContext = buildTemplateContext; exports.renderTemplate = renderTemplate; exports.getDefaultTemplatePath = getDefaultTemplatePath; exports.generate = generate; exports.ParamOverridesSchema = ParamOverridesSchema; exports.ExamplesConfigSchema = ExamplesConfigSchema; exports.loadConfig = loadConfig; exports.loadConfigOrDefault = loadConfigOrDefault; | ||
| //# sourceMappingURL=chunk-W5UF3QWJ.cjs.map |
Sorry, the diff of this file is too big to display
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
399983
7.22%31
6.9%3646
8.71%