@lssm/lib.contracts-transformers 1.42.10 → 1.43.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -49,6 +49,7 @@ const importResult = importFromOpenApi(openApiDoc, {
49
49
  prefix: 'myApi',
50
50
  tags: ['users', 'orders'], // Optional: filter by tags
51
51
  exclude: ['deprecated_endpoint'], // Optional: exclude by operationId
52
+ schemaFormat: 'contractspec', // Optional: 'contractspec' | 'zod' | 'json-schema' | 'graphql'
52
53
  });
53
54
 
54
55
  // importResult contains generated spec code as strings
package/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@ import { ExportedForm, exportForms, generateFormsRegistry } from "./openapi/expo
12
12
  import { ExportedDataView, exportDataViews, generateDataViewsRegistry } from "./openapi/exporter/data-views.js";
13
13
  import { ExportedWorkflow, exportWorkflows, generateWorkflowsRegistry } from "./openapi/exporter/workflows.js";
14
14
  import { RegistryGenerationOptions, generateRegistryIndex } from "./openapi/exporter/registries.js";
15
- import { GeneratedModel, SchemaField, TypescriptType, generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToField, jsonSchemaToType } from "./openapi/schema-converter.js";
15
+ import { GeneratedModel, SchemaField, TypescriptType, generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToType } from "./openapi/schema-converter.js";
16
16
  import { importFromOpenApi, importOperation } from "./openapi/importer/index.js";
17
17
  import { DiffOptions, createSpecDiff, diffAll, diffSpecVsOperation, diffSpecs, formatDiffChanges } from "./openapi/differ.js";
18
- export { ContractSpecOpenApiDocument, ContractSpecRegistries, DiffChange, DiffChangeType, DiffOptions, ExportedDataView, ExportedEvent, ExportedFeature, ExportedForm, ExportedPresentation, ExportedWorkflow, GeneratedModel, HttpMethod, ImportResult, ImportedOperationSpec, OpenApiDocument, OpenApiExportOptions, OpenApiOperation, OpenApiParameter, OpenApiParseOptions, OpenApiSchema, OpenApiServer, OpenApiSource, OpenApiTransportHints, OpenApiVersion, OperationsExportResult, ParameterLocation, ParseResult, ParsedOperation, ParsedParameter, RegistryGenerationOptions, SchemaField, SpecDiff, SpecSource, SyncResult, TransportHints, TypescriptType, ValidationResult, contractSpecToJson, contractSpecToYaml, createSpecDiff, deepEqual, defaultRestPath, detectFormat, detectVersion, diffAll, diffSpecVsOperation, diffSpecs, exportContractSpec, exportDataViews, exportEvents, exportFeatures, exportForms, exportOperations, exportPresentations, exportPresentationsFromArray, exportWorkflows, extractPathParams, formatDiffChanges, generateDataViewsRegistry, generateEventsExports, generateFeaturesRegistry, generateFormsRegistry, generateImports, generateOperationsRegistry, generatePresentationsRegistry, generateRegistryIndex, generateSchemaModelCode, generateWorkflowsRegistry, getByPath, getScalarType, importFromOpenApi, importOperation, jsonSchemaForSpec, jsonSchemaToField, jsonSchemaToType, normalizePath, openApiForRegistry, openApiToJson, openApiToYaml, parseOpenApi, parseOpenApiDocument, parseOpenApiString, schemaModelToJsonSchema, toCamelCase, toFileName, toHttpMethod, toKebabCase, toOperationId, toPascalCase, toRestPath, toSchemaName, toSnakeCase, toSpecKey, toValidIdentifier };
18
+ export { ContractSpecOpenApiDocument, ContractSpecRegistries, DiffChange, DiffChangeType, DiffOptions, ExportedDataView, ExportedEvent, ExportedFeature, ExportedForm, ExportedPresentation, ExportedWorkflow, GeneratedModel, HttpMethod, ImportResult, ImportedOperationSpec, OpenApiDocument, OpenApiExportOptions, OpenApiOperation, OpenApiParameter, OpenApiParseOptions, OpenApiSchema, OpenApiServer, OpenApiSource, OpenApiTransportHints, OpenApiVersion, OperationsExportResult, ParameterLocation, ParseResult, ParsedOperation, ParsedParameter, RegistryGenerationOptions, SchemaField, SpecDiff, SpecSource, SyncResult, TransportHints, TypescriptType, ValidationResult, contractSpecToJson, contractSpecToYaml, createSpecDiff, deepEqual, defaultRestPath, detectFormat, detectVersion, diffAll, diffSpecVsOperation, diffSpecs, exportContractSpec, exportDataViews, exportEvents, exportFeatures, exportForms, exportOperations, exportPresentations, exportPresentationsFromArray, exportWorkflows, extractPathParams, formatDiffChanges, generateDataViewsRegistry, generateEventsExports, generateFeaturesRegistry, generateFormsRegistry, generateImports, generateOperationsRegistry, generatePresentationsRegistry, generateRegistryIndex, generateSchemaModelCode, generateWorkflowsRegistry, getByPath, getScalarType, importFromOpenApi, importOperation, jsonSchemaForSpec, jsonSchemaToType, normalizePath, openApiForRegistry, openApiToJson, openApiToYaml, parseOpenApi, parseOpenApiDocument, parseOpenApiString, schemaModelToJsonSchema, toCamelCase, toFileName, toHttpMethod, toKebabCase, toOperationId, toPascalCase, toRestPath, toSchemaName, toSnakeCase, toSpecKey, toValidIdentifier };
package/dist/index.js CHANGED
@@ -10,9 +10,9 @@ import { exportWorkflows, generateWorkflowsRegistry } from "./openapi/exporter/w
10
10
  import { generateRegistryIndex } from "./openapi/exporter/registries.js";
11
11
  import { contractSpecToJson, contractSpecToYaml, exportContractSpec, openApiForRegistry, openApiToJson, openApiToYaml } from "./openapi/exporter.js";
12
12
  import { deepEqual, extractPathParams, getByPath, normalizePath, toCamelCase, toFileName, toKebabCase, toPascalCase, toSnakeCase, toSpecKey, toValidIdentifier } from "./common/utils.js";
13
- import { generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToField, jsonSchemaToType } from "./openapi/schema-converter.js";
13
+ import { generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToType } from "./openapi/schema-converter.js";
14
14
  import { importFromOpenApi, importOperation } from "./openapi/importer/index.js";
15
15
  import { createSpecDiff, diffAll, diffSpecVsOperation, diffSpecs, formatDiffChanges } from "./openapi/differ.js";
16
16
  import "./openapi/index.js";
17
17
 
18
- export { contractSpecToJson, contractSpecToYaml, createSpecDiff, deepEqual, defaultRestPath, detectFormat, detectVersion, diffAll, diffSpecVsOperation, diffSpecs, exportContractSpec, exportDataViews, exportEvents, exportFeatures, exportForms, exportOperations, exportPresentations, exportPresentationsFromArray, exportWorkflows, extractPathParams, formatDiffChanges, generateDataViewsRegistry, generateEventsExports, generateFeaturesRegistry, generateFormsRegistry, generateImports, generateOperationsRegistry, generatePresentationsRegistry, generateRegistryIndex, generateSchemaModelCode, generateWorkflowsRegistry, getByPath, getScalarType, importFromOpenApi, importOperation, jsonSchemaForSpec, jsonSchemaToField, jsonSchemaToType, normalizePath, openApiForRegistry, openApiToJson, openApiToYaml, parseOpenApi, parseOpenApiDocument, parseOpenApiString, schemaModelToJsonSchema, toCamelCase, toFileName, toHttpMethod, toKebabCase, toOperationId, toPascalCase, toRestPath, toSchemaName, toSnakeCase, toSpecKey, toValidIdentifier };
18
+ export { contractSpecToJson, contractSpecToYaml, createSpecDiff, deepEqual, defaultRestPath, detectFormat, detectVersion, diffAll, diffSpecVsOperation, diffSpecs, exportContractSpec, exportDataViews, exportEvents, exportFeatures, exportForms, exportOperations, exportPresentations, exportPresentationsFromArray, exportWorkflows, extractPathParams, formatDiffChanges, generateDataViewsRegistry, generateEventsExports, generateFeaturesRegistry, generateFormsRegistry, generateImports, generateOperationsRegistry, generatePresentationsRegistry, generateRegistryIndex, generateSchemaModelCode, generateWorkflowsRegistry, getByPath, getScalarType, importFromOpenApi, importOperation, jsonSchemaForSpec, jsonSchemaToType, normalizePath, openApiForRegistry, openApiToJson, openApiToYaml, parseOpenApi, parseOpenApiDocument, parseOpenApiString, schemaModelToJsonSchema, toCamelCase, toFileName, toHttpMethod, toKebabCase, toOperationId, toPascalCase, toRestPath, toSchemaName, toSnakeCase, toSpecKey, toValidIdentifier };
@@ -8,10 +8,12 @@ import { generateImports, generateSchemaModelCode } from "../schema-converter.js
8
8
  function generateEventCode(event, options) {
9
9
  const eventName = toValidIdentifier(event.name);
10
10
  const modelName = toPascalCase(eventName) + "Payload";
11
- const payloadModel = generateSchemaModelCode(event.payload, modelName);
11
+ const schemaFormat = options.schemaFormat || "contractspec";
12
+ const payloadModel = generateSchemaModelCode(event.payload, modelName, schemaFormat, options);
12
13
  const imports = /* @__PURE__ */ new Set();
13
14
  imports.add("import { defineEvent, type EventSpec } from '@lssm/lib.contracts';");
14
- generateImports(payloadModel.fields, options).split("\n").filter(Boolean).forEach((i) => imports.add(i));
15
+ if (payloadModel.imports && payloadModel.imports.length > 0) payloadModel.imports.forEach((i) => imports.add(i));
16
+ else if (payloadModel.fields && payloadModel.fields.length > 0) generateImports(payloadModel.fields, options).split("\n").filter(Boolean).forEach((i) => imports.add(i));
15
17
  if (payloadModel.name !== modelName) {
16
18
  const modelsDir = `../${options.conventions.models}`;
17
19
  const kebabName = payloadModel.name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","names":[],"sources":["../../../src/openapi/importer/events.ts"],"sourcesContent":["import type { ParsedEvent } from '../types';\nimport { generateImports, generateSchemaModelCode } from '../schema-converter';\nimport { toPascalCase, toValidIdentifier } from '../../common/utils';\nimport type { ContractsrcConfig } from '@lssm/lib.contracts';\n\n/**\n * Generate code for an event.\n */\nexport function generateEventCode(\n event: ParsedEvent,\n options: ContractsrcConfig\n): string {\n const eventName = toValidIdentifier(event.name);\n const modelName = toPascalCase(eventName) + 'Payload';\n\n // Generate payload model inline or referenced?\n // Let's generate the payload schema definition first\n const payloadModel = generateSchemaModelCode(event.payload, modelName);\n\n const imports = new Set<string>();\n imports.add(\n \"import { defineEvent, type EventSpec } from '@lssm/lib.contracts';\"\n );\n\n const modelImports = generateImports(payloadModel.fields, options);\n // Merge imports - this is a bit hacky string manipulation but works for now\n modelImports\n .split('\\n')\n .filter(Boolean)\n .forEach((i) => imports.add(i));\n\n // If payloadModel is a reference (empty fields and different name), import it\n if (payloadModel.name !== modelName) {\n const modelsDir = `../${options.conventions.models}`;\n const kebabName = payloadModel.name\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase();\n imports.add(\n `import { ${payloadModel.name} } from '${modelsDir}/${kebabName}';`\n );\n }\n\n const allImports = Array.from(imports).join('\\n');\n\n return `\n${allImports}\n\n${payloadModel.code}\n\nexport const ${eventName} = defineEvent({\n meta: {\n key: '${event.name}',\n version: 1,\n description: ${JSON.stringify(event.description ?? '')},\n },\n payload: ${payloadModel.name},\n});\n`.trim();\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,kBACd,OACA,SACQ;CACR,MAAM,YAAY,kBAAkB,MAAM,KAAK;CAC/C,MAAM,YAAY,aAAa,UAAU,GAAG;CAI5C,MAAM,eAAe,wBAAwB,MAAM,SAAS,UAAU;CAEtE,MAAM,0BAAU,IAAI,KAAa;AACjC,SAAQ,IACN,qEACD;AAID,CAFqB,gBAAgB,aAAa,QAAQ,QAAQ,CAG/D,MAAM,KAAK,CACX,OAAO,QAAQ,CACf,SAAS,MAAM,QAAQ,IAAI,EAAE,CAAC;AAGjC,KAAI,aAAa,SAAS,WAAW;EACnC,MAAM,YAAY,MAAM,QAAQ,YAAY;EAC5C,MAAM,YAAY,aAAa,KAC5B,QAAQ,sBAAsB,QAAQ,CACtC,aAAa;AAChB,UAAQ,IACN,YAAY,aAAa,KAAK,WAAW,UAAU,GAAG,UAAU,IACjE;;AAKH,QAAO;EAFY,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAGtC;;EAEX,aAAa,KAAK;;eAEL,UAAU;;YAEb,MAAM,KAAK;;mBAEJ,KAAK,UAAU,MAAM,eAAe,GAAG,CAAC;;aAE9C,aAAa,KAAK;;EAE7B,MAAM"}
1
+ {"version":3,"file":"events.js","names":[],"sources":["../../../src/openapi/importer/events.ts"],"sourcesContent":["import type { ParsedEvent } from '../types';\nimport { generateImports, generateSchemaModelCode } from '../schema-converter';\nimport { toPascalCase, toValidIdentifier } from '../../common/utils';\nimport type { ContractsrcConfig } from '@lssm/lib.contracts';\n\n/**\n * Generate code for an event.\n */\nexport function generateEventCode(\n event: ParsedEvent,\n options: ContractsrcConfig\n): string {\n const eventName = toValidIdentifier(event.name);\n const modelName = toPascalCase(eventName) + 'Payload';\n\n const schemaFormat = options.schemaFormat || 'contractspec';\n // Generate payload model inline or referenced?\n // Let's generate the payload schema definition first\n const payloadModel = generateSchemaModelCode(\n event.payload,\n modelName,\n schemaFormat,\n options\n );\n\n const imports = new Set<string>();\n imports.add(\n \"import { defineEvent, type EventSpec } from '@lssm/lib.contracts';\"\n );\n\n if (payloadModel.imports && payloadModel.imports.length > 0) {\n payloadModel.imports.forEach((i) => imports.add(i));\n } else if (payloadModel.fields && payloadModel.fields.length > 0) {\n const modelImports = generateImports(payloadModel.fields, options);\n // Merge imports - this is a bit hacky string manipulation but works for now\n modelImports\n .split('\\n')\n .filter(Boolean)\n .forEach((i) => imports.add(i));\n }\n\n // If payloadModel is a reference (empty fields and different name), import it\n if (payloadModel.name !== modelName) {\n const modelsDir = `../${options.conventions.models}`;\n const kebabName = payloadModel.name\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase();\n imports.add(\n `import { ${payloadModel.name} } from '${modelsDir}/${kebabName}';`\n );\n }\n\n const allImports = Array.from(imports).join('\\n');\n\n return `\n${allImports}\n\n${payloadModel.code}\n\nexport const ${eventName} = defineEvent({\n meta: {\n key: '${event.name}',\n version: 1,\n description: ${JSON.stringify(event.description ?? '')},\n },\n payload: ${payloadModel.name},\n});\n`.trim();\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,kBACd,OACA,SACQ;CACR,MAAM,YAAY,kBAAkB,MAAM,KAAK;CAC/C,MAAM,YAAY,aAAa,UAAU,GAAG;CAE5C,MAAM,eAAe,QAAQ,gBAAgB;CAG7C,MAAM,eAAe,wBACnB,MAAM,SACN,WACA,cACA,QACD;CAED,MAAM,0BAAU,IAAI,KAAa;AACjC,SAAQ,IACN,qEACD;AAED,KAAI,aAAa,WAAW,aAAa,QAAQ,SAAS,EACxD,cAAa,QAAQ,SAAS,MAAM,QAAQ,IAAI,EAAE,CAAC;UAC1C,aAAa,UAAU,aAAa,OAAO,SAAS,EAG7D,CAFqB,gBAAgB,aAAa,QAAQ,QAAQ,CAG/D,MAAM,KAAK,CACX,OAAO,QAAQ,CACf,SAAS,MAAM,QAAQ,IAAI,EAAE,CAAC;AAInC,KAAI,aAAa,SAAS,WAAW;EACnC,MAAM,YAAY,MAAM,QAAQ,YAAY;EAC5C,MAAM,YAAY,aAAa,KAC5B,QAAQ,sBAAsB,QAAQ,CACtC,aAAa;AAChB,UAAQ,IACN,YAAY,aAAa,KAAK,WAAW,UAAU,GAAG,UAAU,IACjE;;AAKH,QAAO;EAFY,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAGtC;;EAEX,aAAa,KAAK;;eAEL,UAAU;;YAEb,MAAM,KAAK;;mBAEJ,KAAK,UAAU,MAAM,eAAe,GAAG,CAAC;;aAE9C,aAAa,KAAK;;EAE7B,MAAM"}
@@ -6,22 +6,54 @@ import { inferAuthLevel, inferOpKind } from "./analyzer.js";
6
6
  /**
7
7
  * Generate ContractSpec TypeScript code for an operation.
8
8
  */
9
- function generateSpecCode(operation, contractspecConfig, options = {}, inputModel, outputModel) {
9
+ function generateSpecCode(operation, contractspecConfig, options = {}, inputModel, outputModel, queryModel = null, paramsModel = null, headersModel = null) {
10
10
  const specKey = toSpecKey(operation.operationId, options.prefix);
11
11
  const kind = inferOpKind(operation.method);
12
12
  const auth = inferAuthLevel(operation, options.defaultAuth ?? "user");
13
13
  const lines = [];
14
14
  lines.push("import { defineCommand, defineQuery } from '@lssm/lib.contracts';");
15
- if (inputModel || outputModel) lines.push(generateImports([...inputModel?.fields ?? [], ...outputModel?.fields ?? []], contractspecConfig, false));
16
- lines.push("");
17
- if (inputModel && inputModel.code) {
18
- lines.push("// Input schema");
19
- lines.push(inputModel.code);
20
- lines.push("");
15
+ if (inputModel || outputModel || queryModel || paramsModel || headersModel) {
16
+ const collectedImports = /* @__PURE__ */ new Set();
17
+ const models = [
18
+ inputModel,
19
+ outputModel,
20
+ queryModel,
21
+ paramsModel,
22
+ headersModel
23
+ ].filter((m) => !!m);
24
+ models.forEach((m) => {
25
+ if (m.imports && m.imports.length > 0) m.imports.forEach((i) => collectedImports.add(i));
26
+ });
27
+ const legacyFields = models.filter((m) => !m.imports || m.imports.length === 0).flatMap((m) => m.fields);
28
+ if (legacyFields.length > 0) generateImports(legacyFields, contractspecConfig, false).split("\n").filter(Boolean).forEach((i) => collectedImports.add(i));
29
+ if (collectedImports.size > 0) lines.push(Array.from(collectedImports).sort().join("\n"));
21
30
  }
22
- if (outputModel && outputModel.code) {
23
- lines.push("// Output schema");
24
- lines.push(outputModel.code);
31
+ lines.push("");
32
+ const schemaSections = [
33
+ {
34
+ label: "Input schema",
35
+ model: inputModel
36
+ },
37
+ {
38
+ label: "Query schema",
39
+ model: queryModel
40
+ },
41
+ {
42
+ label: "Path schema",
43
+ model: paramsModel
44
+ },
45
+ {
46
+ label: "Header schema",
47
+ model: headersModel
48
+ },
49
+ {
50
+ label: "Output schema",
51
+ model: outputModel
52
+ }
53
+ ];
54
+ for (const section of schemaSections) if (section.model && section.model.code) {
55
+ lines.push(`// ${section.label}`);
56
+ lines.push(section.model.code);
25
57
  lines.push("");
26
58
  }
27
59
  const defineFunc = kind === "command" ? "defineCommand" : "defineQuery";
@@ -47,8 +79,10 @@ function generateSpecCode(operation, contractspecConfig, options = {}, inputMode
47
79
  lines.push(` context: 'Imported from OpenAPI: ${operation.method.toUpperCase()} ${operation.path}',`);
48
80
  lines.push(" },");
49
81
  lines.push(" io: {");
50
- if (inputModel) lines.push(` input: ${inputModel.name},`);
51
- else lines.push(" input: null,");
82
+ lines.push(` input: ${inputModel?.name ?? "null"},`);
83
+ if (queryModel) lines.push(` query: ${queryModel.name},`);
84
+ if (paramsModel) lines.push(` params: ${paramsModel.name},`);
85
+ if (headersModel) lines.push(` headers: ${headersModel.name},`);
52
86
  if (outputModel) lines.push(` output: ${outputModel.name},`);
53
87
  else lines.push(" output: null, // TODO: Define output schema");
54
88
  lines.push(" },");
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","names":["lines: string[]"],"sources":["../../../src/openapi/importer/generator.ts"],"sourcesContent":["import type { ParsedOperation } from '../types';\nimport { toPascalCase, toSpecKey, toValidIdentifier } from '../../common/utils';\nimport { type GeneratedModel, generateImports } from '../schema-converter';\nimport { inferAuthLevel, inferOpKind } from './analyzer';\nimport type {\n ContractsrcConfig,\n OpenApiSourceConfig,\n} from '@lssm/lib.contracts';\n\n/**\n * Generate ContractSpec TypeScript code for an operation.\n */\nexport function generateSpecCode(\n operation: ParsedOperation,\n contractspecConfig: ContractsrcConfig,\n options: Partial<OpenApiSourceConfig> = {},\n inputModel: GeneratedModel | null,\n outputModel: GeneratedModel | null\n): string {\n const specKey = toSpecKey(operation.operationId, options.prefix);\n const kind = inferOpKind(operation.method);\n const auth = inferAuthLevel(operation, options.defaultAuth ?? 'user');\n\n const lines: string[] = [];\n\n // Imports\n lines.push(\n \"import { defineCommand, defineQuery } from '@lssm/lib.contracts';\"\n );\n if (inputModel || outputModel) {\n lines.push(\n generateImports(\n [...(inputModel?.fields ?? []), ...(outputModel?.fields ?? [])],\n contractspecConfig,\n false // operations import from ../models, not same directory\n )\n );\n }\n lines.push('');\n\n // Generate input model if present\n if (inputModel && inputModel.code) {\n lines.push('// Input schema');\n lines.push(inputModel.code);\n lines.push('');\n }\n\n // Generate output model if present\n if (outputModel && outputModel.code) {\n lines.push('// Output schema');\n lines.push(outputModel.code);\n lines.push('');\n }\n\n // Generate spec\n const defineFunc = kind === 'command' ? 'defineCommand' : 'defineQuery';\n const safeName = toValidIdentifier(toPascalCase(operation.operationId));\n\n lines.push(`/**`);\n lines.push(` * ${operation.summary ?? operation.operationId}`);\n if (operation.description) {\n lines.push(` *`);\n lines.push(` * ${operation.description}`);\n }\n lines.push(` *`);\n lines.push(\n ` * @source OpenAPI: ${operation.method.toUpperCase()} ${operation.path}`\n );\n lines.push(` */`);\n lines.push(`export const ${safeName}Spec = ${defineFunc}({`);\n\n // Meta\n lines.push(' meta: {');\n lines.push(` key: '${specKey}',`);\n lines.push(' version: 1,');\n lines.push(` stability: '${options.defaultStability ?? 'stable'}',`);\n lines.push(\n ` owners: [${(options.defaultOwners ?? []).map((o) => `'${o}'`).join(', ')}],`\n );\n lines.push(` tags: [${operation.tags.map((t) => `'${t}'`).join(', ')}],`);\n lines.push(\n ` description: ${JSON.stringify(operation.summary ?? operation.operationId)},`\n );\n lines.push(\n ` goal: ${JSON.stringify(operation.description ?? 'Imported from OpenAPI')},`\n );\n lines.push(\n ` context: 'Imported from OpenAPI: ${operation.method.toUpperCase()} ${operation.path}',`\n );\n lines.push(' },');\n\n // IO\n lines.push(' io: {');\n if (inputModel) {\n lines.push(` input: ${inputModel.name},`);\n } else {\n lines.push(' input: null,');\n }\n if (outputModel) {\n lines.push(` output: ${outputModel.name},`);\n } else {\n lines.push(' output: null, // TODO: Define output schema');\n }\n lines.push(' },');\n\n // Policy\n lines.push(' policy: {');\n lines.push(` auth: '${auth}',`);\n lines.push(' },');\n\n // Transport hints\n // ContractSpec only supports GET and POST - map other methods appropriately\n const httpMethod = operation.method.toUpperCase();\n const restMethod = httpMethod === 'GET' ? 'GET' : 'POST'; // GET stays GET, everything else becomes POST\n lines.push(' transport: {');\n lines.push(' rest: {');\n lines.push(` method: '${restMethod}',`);\n lines.push(` path: '${operation.path}',`);\n lines.push(' },');\n lines.push(' },');\n\n lines.push('});');\n\n return lines.join('\\n');\n}\n"],"mappings":";;;;;;;;AAYA,SAAgB,iBACd,WACA,oBACA,UAAwC,EAAE,EAC1C,YACA,aACQ;CACR,MAAM,UAAU,UAAU,UAAU,aAAa,QAAQ,OAAO;CAChE,MAAM,OAAO,YAAY,UAAU,OAAO;CAC1C,MAAM,OAAO,eAAe,WAAW,QAAQ,eAAe,OAAO;CAErE,MAAMA,QAAkB,EAAE;AAG1B,OAAM,KACJ,oEACD;AACD,KAAI,cAAc,YAChB,OAAM,KACJ,gBACE,CAAC,GAAI,YAAY,UAAU,EAAE,EAAG,GAAI,aAAa,UAAU,EAAE,CAAE,EAC/D,oBACA,MACD,CACF;AAEH,OAAM,KAAK,GAAG;AAGd,KAAI,cAAc,WAAW,MAAM;AACjC,QAAM,KAAK,kBAAkB;AAC7B,QAAM,KAAK,WAAW,KAAK;AAC3B,QAAM,KAAK,GAAG;;AAIhB,KAAI,eAAe,YAAY,MAAM;AACnC,QAAM,KAAK,mBAAmB;AAC9B,QAAM,KAAK,YAAY,KAAK;AAC5B,QAAM,KAAK,GAAG;;CAIhB,MAAM,aAAa,SAAS,YAAY,kBAAkB;CAC1D,MAAM,WAAW,kBAAkB,aAAa,UAAU,YAAY,CAAC;AAEvE,OAAM,KAAK,MAAM;AACjB,OAAM,KAAK,MAAM,UAAU,WAAW,UAAU,cAAc;AAC9D,KAAI,UAAU,aAAa;AACzB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,MAAM,UAAU,cAAc;;AAE3C,OAAM,KAAK,KAAK;AAChB,OAAM,KACJ,uBAAuB,UAAU,OAAO,aAAa,CAAC,GAAG,UAAU,OACpE;AACD,OAAM,KAAK,MAAM;AACjB,OAAM,KAAK,gBAAgB,SAAS,SAAS,WAAW,IAAI;AAG5D,OAAM,KAAK,YAAY;AACvB,OAAM,KAAK,aAAa,QAAQ,IAAI;AACpC,OAAM,KAAK,kBAAkB;AAC7B,OAAM,KAAK,mBAAmB,QAAQ,oBAAoB,SAAS,IAAI;AACvE,OAAM,KACJ,iBAAiB,QAAQ,iBAAiB,EAAE,EAAE,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC,IAC/E;AACD,OAAM,KAAK,cAAc,UAAU,KAAK,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI;AAC5E,OAAM,KACJ,oBAAoB,KAAK,UAAU,UAAU,WAAW,UAAU,YAAY,CAAC,GAChF;AACD,OAAM,KACJ,aAAa,KAAK,UAAU,UAAU,eAAe,wBAAwB,CAAC,GAC/E;AACD,OAAM,KACJ,wCAAwC,UAAU,OAAO,aAAa,CAAC,GAAG,UAAU,KAAK,IAC1F;AACD,OAAM,KAAK,OAAO;AAGlB,OAAM,KAAK,UAAU;AACrB,KAAI,WACF,OAAM,KAAK,cAAc,WAAW,KAAK,GAAG;KAE5C,OAAM,KAAK,mBAAmB;AAEhC,KAAI,YACF,OAAM,KAAK,eAAe,YAAY,KAAK,GAAG;KAE9C,OAAM,KAAK,kDAAkD;AAE/D,OAAM,KAAK,OAAO;AAGlB,OAAM,KAAK,cAAc;AACzB,OAAM,KAAK,cAAc,KAAK,IAAI;AAClC,OAAM,KAAK,OAAO;CAKlB,MAAM,aADa,UAAU,OAAO,aAAa,KACf,QAAQ,QAAQ;AAClD,OAAM,KAAK,iBAAiB;AAC5B,OAAM,KAAK,cAAc;AACzB,OAAM,KAAK,kBAAkB,WAAW,IAAI;AAC5C,OAAM,KAAK,gBAAgB,UAAU,KAAK,IAAI;AAC9C,OAAM,KAAK,SAAS;AACpB,OAAM,KAAK,OAAO;AAElB,OAAM,KAAK,MAAM;AAEjB,QAAO,MAAM,KAAK,KAAK"}
1
+ {"version":3,"file":"generator.js","names":["lines: string[]"],"sources":["../../../src/openapi/importer/generator.ts"],"sourcesContent":["import type { ParsedOperation } from '../types';\nimport { toPascalCase, toSpecKey, toValidIdentifier } from '../../common/utils';\nimport { type GeneratedModel, generateImports } from '../schema-converter';\nimport { inferAuthLevel, inferOpKind } from './analyzer';\nimport type {\n ContractsrcConfig,\n OpenApiSourceConfig,\n} from '@lssm/lib.contracts';\n\n/**\n * Generate ContractSpec TypeScript code for an operation.\n */\nexport function generateSpecCode(\n operation: ParsedOperation,\n contractspecConfig: ContractsrcConfig,\n options: Partial<OpenApiSourceConfig> = {},\n inputModel: GeneratedModel | null,\n outputModel: GeneratedModel | null,\n queryModel: GeneratedModel | null = null,\n paramsModel: GeneratedModel | null = null,\n headersModel: GeneratedModel | null = null\n): string {\n const specKey = toSpecKey(operation.operationId, options.prefix);\n const kind = inferOpKind(operation.method);\n const auth = inferAuthLevel(operation, options.defaultAuth ?? 'user');\n\n const lines: string[] = [];\n\n // Imports\n lines.push(\n \"import { defineCommand, defineQuery } from '@lssm/lib.contracts';\"\n );\n if (inputModel || outputModel || queryModel || paramsModel || headersModel) {\n const collectedImports = new Set<string>();\n const models = [\n inputModel,\n outputModel,\n queryModel,\n paramsModel,\n headersModel,\n ].filter((m): m is GeneratedModel => !!m);\n\n // Add explicit imports from generators (e.g. Zod, JsonSchema)\n models.forEach((m) => {\n if (m.imports && m.imports.length > 0) {\n m.imports.forEach((i) => collectedImports.add(i));\n }\n });\n\n // Add legacy fields-based imports (ContractSpec format)\n const legacyModels = models.filter(\n (m) => !m.imports || m.imports.length === 0\n );\n const legacyFields = legacyModels.flatMap((m) => m.fields);\n\n if (legacyFields.length > 0) {\n const legacyImportStr = generateImports(\n legacyFields,\n contractspecConfig,\n false\n );\n legacyImportStr\n .split('\\n')\n .filter(Boolean)\n .forEach((i) => collectedImports.add(i));\n }\n\n if (collectedImports.size > 0) {\n lines.push(Array.from(collectedImports).sort().join('\\n'));\n }\n }\n lines.push('');\n\n // Generate schemas\n const schemaSections = [\n { label: 'Input schema', model: inputModel },\n { label: 'Query schema', model: queryModel },\n { label: 'Path schema', model: paramsModel },\n { label: 'Header schema', model: headersModel },\n { label: 'Output schema', model: outputModel },\n ];\n\n for (const section of schemaSections) {\n if (section.model && section.model.code) {\n lines.push(`// ${section.label}`);\n lines.push(section.model.code);\n lines.push('');\n }\n }\n\n // Generate spec\n const defineFunc = kind === 'command' ? 'defineCommand' : 'defineQuery';\n const safeName = toValidIdentifier(toPascalCase(operation.operationId));\n\n lines.push(`/**`);\n lines.push(` * ${operation.summary ?? operation.operationId}`);\n if (operation.description) {\n lines.push(` *`);\n lines.push(` * ${operation.description}`);\n }\n lines.push(` *`);\n lines.push(\n ` * @source OpenAPI: ${operation.method.toUpperCase()} ${operation.path}`\n );\n lines.push(` */`);\n lines.push(`export const ${safeName}Spec = ${defineFunc}({`);\n\n // Meta\n lines.push(' meta: {');\n lines.push(` key: '${specKey}',`);\n lines.push(' version: 1,');\n lines.push(` stability: '${options.defaultStability ?? 'stable'}',`);\n lines.push(\n ` owners: [${(options.defaultOwners ?? []).map((o) => `'${o}'`).join(', ')}],`\n );\n lines.push(` tags: [${operation.tags.map((t) => `'${t}'`).join(', ')}],`);\n lines.push(\n ` description: ${JSON.stringify(operation.summary ?? operation.operationId)},`\n );\n lines.push(\n ` goal: ${JSON.stringify(operation.description ?? 'Imported from OpenAPI')},`\n );\n lines.push(\n ` context: 'Imported from OpenAPI: ${operation.method.toUpperCase()} ${operation.path}',`\n );\n lines.push(' },');\n\n // IO\n lines.push(' io: {');\n lines.push(` input: ${inputModel?.name ?? 'null'},`);\n if (queryModel) lines.push(` query: ${queryModel.name},`);\n if (paramsModel) lines.push(` params: ${paramsModel.name},`);\n if (headersModel) lines.push(` headers: ${headersModel.name},`);\n\n if (outputModel) {\n lines.push(` output: ${outputModel.name},`);\n } else {\n lines.push(' output: null, // TODO: Define output schema');\n }\n lines.push(' },');\n\n // Policy\n lines.push(' policy: {');\n lines.push(` auth: '${auth}',`);\n lines.push(' },');\n\n // Transport hints\n const httpMethod = operation.method.toUpperCase();\n const restMethod = httpMethod === 'GET' ? 'GET' : 'POST';\n lines.push(' transport: {');\n lines.push(' rest: {');\n lines.push(` method: '${restMethod}',`);\n lines.push(` path: '${operation.path}',`);\n lines.push(' },');\n lines.push(' },');\n\n lines.push('});');\n\n return lines.join('\\n');\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/openapi/importer/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAyPgB,cAxNH,iBAwNkB,EAAA,CAAA,WAAA,EAvNhB,WAuNgB,EAAA,mBAAA,EAtNR,iBAsNQ,EAAA,aAAA,CAAA,EArNd,OAqNc,CArNN,mBAqNM,CAAA,EAAA,GApN5B,YAoN4B;;;;AAGR,iBAHP,eAAA,CAGO,SAAA,EAFV,eAEU,EAAA,OAAA,EADZ,OACY,CADJ,mBACI,CAAA,GAAA,SAAA,EAAA,mBAAA,EAAA,iBAAA,CAAA,EAAA,MAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/openapi/importer/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAgTgB,cA/QH,iBA+QkB,EAAA,CAAA,WAAA,EA9QhB,WA8QgB,EAAA,mBAAA,EA7QR,iBA6QQ,EAAA,aAAA,CAAA,EA5Qd,OA4Qc,CA5QN,mBA4QM,CAAA,EAAA,GA3Q5B,YA2Q4B;;;;AAGR,iBAHP,eAAA,CAGO,SAAA,EAFV,eAEU,EAAA,OAAA,EADZ,OACY,CADJ,mBACI,CAAA,GAAA,SAAA,EAAA,mBAAA,EAAA,iBAAA,CAAA,EAAA,MAAA"}
@@ -1,6 +1,6 @@
1
1
  import { toFileName, toSpecKey } from "../../common/utils.js";
2
2
  import { generateSchemaModelCode } from "../schema-converter.js";
3
- import { buildInputSchema, getOutputSchema } from "./schemas.js";
3
+ import { buildInputSchemas, getOutputSchema } from "./schemas.js";
4
4
  import { COMMAND_METHODS, inferAuthLevel, inferOpKind } from "./analyzer.js";
5
5
  import { generateSpecCode } from "./generator.js";
6
6
  import { generateModelCode } from "./models.js";
@@ -49,12 +49,16 @@ const importFromOpenApi = (parseResult, contractspecOptions, importOptions = {})
49
49
  continue;
50
50
  }
51
51
  try {
52
- const { schema: inputSchema } = buildInputSchema(operation);
53
- const inputModel = inputSchema ? generateSchemaModelCode(inputSchema, `${operation.operationId}Input`) : null;
52
+ const inputSchemas = buildInputSchemas(operation);
53
+ const schemaFormat = importOptions.schemaFormat || contractspecOptions.schemaFormat || "contractspec";
54
+ const inputModel = inputSchemas.body ? generateSchemaModelCode(inputSchemas.body, `${operation.operationId}Input`, schemaFormat, contractspecOptions) : null;
55
+ const queryModel = inputSchemas.query ? generateSchemaModelCode(inputSchemas.query, `${operation.operationId}Query`, schemaFormat, contractspecOptions) : null;
56
+ const paramsModel = inputSchemas.params ? generateSchemaModelCode(inputSchemas.params, `${operation.operationId}Params`, schemaFormat, contractspecOptions) : null;
57
+ const headersModel = inputSchemas.headers ? generateSchemaModelCode(inputSchemas.headers, `${operation.operationId}Headers`, schemaFormat, contractspecOptions) : null;
54
58
  const outputSchema = getOutputSchema(operation);
55
- let outputModel = outputSchema ? generateSchemaModelCode(outputSchema, `${operation.operationId}Output`) : null;
56
- if (outputModel && !outputModel.code.includes("defineSchemaModel")) outputModel = null;
57
- const code = generateSpecCode(operation, contractspecOptions, importOptions, inputModel, outputModel);
59
+ let outputModel = outputSchema ? generateSchemaModelCode(outputSchema, `${operation.operationId}Output`, schemaFormat, contractspecOptions) : null;
60
+ if (outputModel && schemaFormat === "contractspec" && !outputModel.code.includes("defineSchemaModel")) outputModel = null;
61
+ const code = generateSpecCode(operation, contractspecOptions, importOptions, inputModel, outputModel, queryModel, paramsModel, headersModel);
58
62
  const fileName = toFileName(toSpecKey(operation.operationId, importOptions.prefix));
59
63
  const transportHints = { rest: {
60
64
  method: operation.method.toUpperCase(),
@@ -89,7 +93,10 @@ const importFromOpenApi = (parseResult, contractspecOptions, importOptions = {})
89
93
  }
90
94
  }
91
95
  for (const [name, schema] of Object.entries(parseResult.schemas)) try {
92
- const code = generateModelCode(name, schema, contractspecOptions);
96
+ const code = generateModelCode(name, schema, {
97
+ ...contractspecOptions,
98
+ schemaFormat: importOptions.schemaFormat || contractspecOptions.schemaFormat
99
+ });
93
100
  const fileName = toFileName(toSpecKey(name, importOptions.prefix));
94
101
  const groupFolder = resolveModelGroupFolder(name, contractspecOptions.conventions);
95
102
  specs.push({
@@ -112,7 +119,10 @@ const importFromOpenApi = (parseResult, contractspecOptions, importOptions = {})
112
119
  });
113
120
  }
114
121
  for (const event of parseResult.events) try {
115
- const code = generateEventCode(event, contractspecOptions);
122
+ const code = generateEventCode(event, {
123
+ ...contractspecOptions,
124
+ schemaFormat: importOptions.schemaFormat || contractspecOptions.schemaFormat
125
+ });
116
126
  const fileName = toFileName(toSpecKey(event.name, importOptions.prefix));
117
127
  const groupFolder = resolveEventGroupFolder(event.name, contractspecOptions.conventions);
118
128
  specs.push({
@@ -150,10 +160,14 @@ const importFromOpenApi = (parseResult, contractspecOptions, importOptions = {})
150
160
  * Import a single operation to ContractSpec code.
151
161
  */
152
162
  function importOperation(operation, options = {}, contractspecOptions) {
153
- const { schema: inputSchema } = buildInputSchema(operation);
154
- const inputModel = inputSchema ? generateSchemaModelCode(inputSchema, `${operation.operationId}Input`) : null;
163
+ const inputSchemas = buildInputSchemas(operation);
164
+ const schemaFormat = options.schemaFormat || contractspecOptions.schemaFormat || "contractspec";
165
+ const inputModel = inputSchemas.body ? generateSchemaModelCode(inputSchemas.body, `${operation.operationId}Input`, schemaFormat, contractspecOptions) : null;
166
+ const queryModel = inputSchemas.query ? generateSchemaModelCode(inputSchemas.query, `${operation.operationId}Query`, schemaFormat, contractspecOptions) : null;
167
+ const paramsModel = inputSchemas.params ? generateSchemaModelCode(inputSchemas.params, `${operation.operationId}Params`, schemaFormat, contractspecOptions) : null;
168
+ const headersModel = inputSchemas.headers ? generateSchemaModelCode(inputSchemas.headers, `${operation.operationId}Headers`, schemaFormat, contractspecOptions) : null;
155
169
  const outputSchema = getOutputSchema(operation);
156
- return generateSpecCode(operation, contractspecOptions, options, inputModel, outputSchema ? generateSchemaModelCode(outputSchema, `${operation.operationId}Output`) : null);
170
+ return generateSpecCode(operation, contractspecOptions, options, inputModel, outputSchema ? generateSchemaModelCode(outputSchema, `${operation.operationId}Output`, schemaFormat, contractspecOptions) : null, queryModel, paramsModel, headersModel);
157
171
  }
158
172
 
159
173
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["specs: ImportedOperationSpec[]","skipped: ImportResult['skipped']","errors: ImportResult['errors']","transportHints: OpenApiTransportHints","source: OpenApiSource"],"sources":["../../../src/openapi/importer/index.ts"],"sourcesContent":["import type {\n OpenApiSource,\n OpenApiTransportHints,\n ParsedOperation,\n ParseResult,\n} from '../types';\nimport type { ImportedOperationSpec, ImportResult } from '../../common/types';\nimport { toFileName, toSpecKey } from '../../common/utils';\nimport { generateSchemaModelCode } from '../schema-converter';\nimport { buildInputSchema, getOutputSchema } from './schemas';\nimport { generateSpecCode } from './generator';\nimport { generateModelCode } from './models';\nimport { generateEventCode } from './events';\nimport {\n resolveOperationGroupFolder,\n resolveModelGroupFolder,\n resolveEventGroupFolder,\n} from './grouping';\nimport type {\n ContractsrcConfig,\n OpenApiSourceConfig,\n} from '@lssm/lib.contracts';\n\nexport * from './analyzer';\nexport * from './schemas';\nexport * from './generator';\nexport * from './models';\nexport * from './events';\nexport * from './grouping';\n\n/**\n * Import operations from a parsed OpenAPI document.\n */\nexport const importFromOpenApi = (\n parseResult: ParseResult,\n contractspecOptions: ContractsrcConfig,\n importOptions: Partial<OpenApiSourceConfig> = {}\n): ImportResult => {\n const { tags, exclude = [], include } = importOptions;\n const specs: ImportedOperationSpec[] = [];\n const skipped: ImportResult['skipped'] = [];\n const errors: ImportResult['errors'] = [];\n\n for (const operation of parseResult.operations) {\n // Filter by tags if specified\n if (tags && tags.length > 0) {\n const hasMatchingTag = operation.tags.some((t) => tags.includes(t));\n if (!hasMatchingTag) {\n skipped.push({\n sourceId: operation.operationId,\n reason: `No matching tags (has: ${operation.tags.join(', ')})`,\n });\n continue;\n }\n }\n\n // Filter by include/exclude\n if (include && include.length > 0) {\n if (!include.includes(operation.operationId)) {\n skipped.push({\n sourceId: operation.operationId,\n reason: 'Not in include list',\n });\n continue;\n }\n } else if (exclude.includes(operation.operationId)) {\n skipped.push({\n sourceId: operation.operationId,\n reason: 'In exclude list',\n });\n continue;\n }\n\n // Skip deprecated operations by default\n if (\n operation.deprecated &&\n importOptions.defaultStability !== 'deprecated'\n ) {\n skipped.push({\n sourceId: operation.operationId,\n reason: 'Deprecated operation',\n });\n continue;\n }\n\n try {\n // Build input schema\n const { schema: inputSchema } = buildInputSchema(operation);\n const inputModel = inputSchema\n ? generateSchemaModelCode(inputSchema, `${operation.operationId}Input`)\n : null;\n\n // Get output schema\n const outputSchema = getOutputSchema(operation);\n let outputModel = outputSchema\n ? generateSchemaModelCode(\n outputSchema,\n `${operation.operationId}Output`\n )\n : null;\n\n // Filter out empty/comment-only output models\n if (outputModel && !outputModel.code.includes('defineSchemaModel')) {\n outputModel = null;\n }\n\n // Generate spec code\n const code = generateSpecCode(\n operation,\n contractspecOptions,\n importOptions,\n inputModel,\n outputModel\n );\n const specName = toSpecKey(operation.operationId, importOptions.prefix);\n const fileName = toFileName(specName);\n\n // Build transport hints\n const transportHints: OpenApiTransportHints = {\n rest: {\n method:\n operation.method.toUpperCase() as OpenApiTransportHints['rest']['method'],\n path: operation.path,\n params: {\n path: operation.pathParams.map((p) => p.name),\n query: operation.queryParams.map((p) => p.name),\n header: operation.headerParams.map((p) => p.name),\n cookie: operation.cookieParams.map((p) => p.name),\n },\n },\n };\n\n // Build source info\n const source: OpenApiSource = {\n type: 'openapi',\n sourceId: operation.operationId,\n operationId: operation.operationId,\n openApiVersion: parseResult.version,\n importedAt: new Date(),\n };\n\n // Resolve group folder based on config\n const groupFolder = resolveOperationGroupFolder(\n operation,\n contractspecOptions.conventions\n );\n\n specs.push({\n code,\n fileName,\n groupFolder: groupFolder || undefined,\n source,\n transportHints,\n });\n } catch (error) {\n errors.push({\n sourceId: operation.operationId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Import standalone models\n for (const [name, schema] of Object.entries(parseResult.schemas)) {\n try {\n const code = generateModelCode(name, schema, contractspecOptions);\n const fileName = toFileName(toSpecKey(name, importOptions.prefix));\n const groupFolder = resolveModelGroupFolder(\n name,\n contractspecOptions.conventions\n );\n\n specs.push({\n code,\n fileName,\n groupFolder: groupFolder || undefined,\n source: {\n type: 'openapi',\n sourceId: name,\n operationId: name,\n openApiVersion: parseResult.version,\n importedAt: new Date(),\n } as OpenApiSource,\n transportHints: {},\n });\n } catch (error) {\n errors.push({\n sourceId: name,\n error:\n error instanceof Error\n ? 'Model conversion failed: ' + error.message\n : String(error),\n });\n }\n }\n\n // Import events\n for (const event of parseResult.events) {\n try {\n const code = generateEventCode(event, contractspecOptions);\n const fileName = toFileName(toSpecKey(event.name, importOptions.prefix));\n const groupFolder = resolveEventGroupFolder(\n event.name,\n contractspecOptions.conventions\n );\n\n specs.push({\n code,\n fileName,\n groupFolder: groupFolder || undefined,\n source: {\n type: 'openapi',\n sourceId: event.name,\n operationId: event.name,\n openApiVersion: parseResult.version,\n importedAt: new Date(),\n } as OpenApiSource,\n transportHints: {},\n });\n } catch (error) {\n errors.push({\n sourceId: event.name,\n error:\n error instanceof Error\n ? 'Event conversion failed: ' + error.message\n : String(error),\n });\n }\n }\n\n return {\n operationSpecs: specs,\n skipped,\n errors,\n summary: {\n total:\n parseResult.operations.length +\n Object.keys(parseResult.schemas).length +\n parseResult.events.length,\n imported: specs.length,\n skipped: skipped.length,\n errors: errors.length,\n },\n };\n};\n\n/**\n * Import a single operation to ContractSpec code.\n */\nexport function importOperation(\n operation: ParsedOperation,\n options: Partial<OpenApiSourceConfig> = {},\n contractspecOptions: ContractsrcConfig\n): string {\n const { schema: inputSchema } = buildInputSchema(operation);\n const inputModel = inputSchema\n ? generateSchemaModelCode(inputSchema, `${operation.operationId}Input`)\n : null;\n\n const outputSchema = getOutputSchema(operation);\n const outputModel = outputSchema\n ? generateSchemaModelCode(outputSchema, `${operation.operationId}Output`)\n : null;\n\n return generateSpecCode(\n operation,\n contractspecOptions,\n options,\n inputModel,\n outputModel\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAiCA,MAAa,qBACX,aACA,qBACA,gBAA8C,EAAE,KAC/B;CACjB,MAAM,EAAE,MAAM,UAAU,EAAE,EAAE,YAAY;CACxC,MAAMA,QAAiC,EAAE;CACzC,MAAMC,UAAmC,EAAE;CAC3C,MAAMC,SAAiC,EAAE;AAEzC,MAAK,MAAM,aAAa,YAAY,YAAY;AAE9C,MAAI,QAAQ,KAAK,SAAS,GAExB;OAAI,CADmB,UAAU,KAAK,MAAM,MAAM,KAAK,SAAS,EAAE,CAAC,EAC9C;AACnB,YAAQ,KAAK;KACX,UAAU,UAAU;KACpB,QAAQ,0BAA0B,UAAU,KAAK,KAAK,KAAK,CAAC;KAC7D,CAAC;AACF;;;AAKJ,MAAI,WAAW,QAAQ,SAAS,GAC9B;OAAI,CAAC,QAAQ,SAAS,UAAU,YAAY,EAAE;AAC5C,YAAQ,KAAK;KACX,UAAU,UAAU;KACpB,QAAQ;KACT,CAAC;AACF;;aAEO,QAAQ,SAAS,UAAU,YAAY,EAAE;AAClD,WAAQ,KAAK;IACX,UAAU,UAAU;IACpB,QAAQ;IACT,CAAC;AACF;;AAIF,MACE,UAAU,cACV,cAAc,qBAAqB,cACnC;AACA,WAAQ,KAAK;IACX,UAAU,UAAU;IACpB,QAAQ;IACT,CAAC;AACF;;AAGF,MAAI;GAEF,MAAM,EAAE,QAAQ,gBAAgB,iBAAiB,UAAU;GAC3D,MAAM,aAAa,cACf,wBAAwB,aAAa,GAAG,UAAU,YAAY,OAAO,GACrE;GAGJ,MAAM,eAAe,gBAAgB,UAAU;GAC/C,IAAI,cAAc,eACd,wBACE,cACA,GAAG,UAAU,YAAY,QAC1B,GACD;AAGJ,OAAI,eAAe,CAAC,YAAY,KAAK,SAAS,oBAAoB,CAChE,eAAc;GAIhB,MAAM,OAAO,iBACX,WACA,qBACA,eACA,YACA,YACD;GAED,MAAM,WAAW,WADA,UAAU,UAAU,aAAa,cAAc,OAAO,CAClC;GAGrC,MAAMC,iBAAwC,EAC5C,MAAM;IACJ,QACE,UAAU,OAAO,aAAa;IAChC,MAAM,UAAU;IAChB,QAAQ;KACN,MAAM,UAAU,WAAW,KAAK,MAAM,EAAE,KAAK;KAC7C,OAAO,UAAU,YAAY,KAAK,MAAM,EAAE,KAAK;KAC/C,QAAQ,UAAU,aAAa,KAAK,MAAM,EAAE,KAAK;KACjD,QAAQ,UAAU,aAAa,KAAK,MAAM,EAAE,KAAK;KAClD;IACF,EACF;GAGD,MAAMC,SAAwB;IAC5B,MAAM;IACN,UAAU,UAAU;IACpB,aAAa,UAAU;IACvB,gBAAgB,YAAY;IAC5B,4BAAY,IAAI,MAAM;IACvB;GAGD,MAAM,cAAc,4BAClB,WACA,oBAAoB,YACrB;AAED,SAAM,KAAK;IACT;IACA;IACA,aAAa,eAAe;IAC5B;IACA;IACD,CAAC;WACK,OAAO;AACd,UAAO,KAAK;IACV,UAAU,UAAU;IACpB,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;IAC9D,CAAC;;;AAKN,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,YAAY,QAAQ,CAC9D,KAAI;EACF,MAAM,OAAO,kBAAkB,MAAM,QAAQ,oBAAoB;EACjE,MAAM,WAAW,WAAW,UAAU,MAAM,cAAc,OAAO,CAAC;EAClE,MAAM,cAAc,wBAClB,MACA,oBAAoB,YACrB;AAED,QAAM,KAAK;GACT;GACA;GACA,aAAa,eAAe;GAC5B,QAAQ;IACN,MAAM;IACN,UAAU;IACV,aAAa;IACb,gBAAgB,YAAY;IAC5B,4BAAY,IAAI,MAAM;IACvB;GACD,gBAAgB,EAAE;GACnB,CAAC;UACK,OAAO;AACd,SAAO,KAAK;GACV,UAAU;GACV,OACE,iBAAiB,QACb,8BAA8B,MAAM,UACpC,OAAO,MAAM;GACpB,CAAC;;AAKN,MAAK,MAAM,SAAS,YAAY,OAC9B,KAAI;EACF,MAAM,OAAO,kBAAkB,OAAO,oBAAoB;EAC1D,MAAM,WAAW,WAAW,UAAU,MAAM,MAAM,cAAc,OAAO,CAAC;EACxE,MAAM,cAAc,wBAClB,MAAM,MACN,oBAAoB,YACrB;AAED,QAAM,KAAK;GACT;GACA;GACA,aAAa,eAAe;GAC5B,QAAQ;IACN,MAAM;IACN,UAAU,MAAM;IAChB,aAAa,MAAM;IACnB,gBAAgB,YAAY;IAC5B,4BAAY,IAAI,MAAM;IACvB;GACD,gBAAgB,EAAE;GACnB,CAAC;UACK,OAAO;AACd,SAAO,KAAK;GACV,UAAU,MAAM;GAChB,OACE,iBAAiB,QACb,8BAA8B,MAAM,UACpC,OAAO,MAAM;GACpB,CAAC;;AAIN,QAAO;EACL,gBAAgB;EAChB;EACA;EACA,SAAS;GACP,OACE,YAAY,WAAW,SACvB,OAAO,KAAK,YAAY,QAAQ,CAAC,SACjC,YAAY,OAAO;GACrB,UAAU,MAAM;GAChB,SAAS,QAAQ;GACjB,QAAQ,OAAO;GAChB;EACF;;;;;AAMH,SAAgB,gBACd,WACA,UAAwC,EAAE,EAC1C,qBACQ;CACR,MAAM,EAAE,QAAQ,gBAAgB,iBAAiB,UAAU;CAC3D,MAAM,aAAa,cACf,wBAAwB,aAAa,GAAG,UAAU,YAAY,OAAO,GACrE;CAEJ,MAAM,eAAe,gBAAgB,UAAU;AAK/C,QAAO,iBACL,WACA,qBACA,SACA,YARkB,eAChB,wBAAwB,cAAc,GAAG,UAAU,YAAY,QAAQ,GACvE,KAQH"}
1
+ {"version":3,"file":"index.js","names":["specs: ImportedOperationSpec[]","skipped: ImportResult['skipped']","errors: ImportResult['errors']","transportHints: OpenApiTransportHints","source: OpenApiSource"],"sources":["../../../src/openapi/importer/index.ts"],"sourcesContent":["import type {\n OpenApiSource,\n OpenApiTransportHints,\n ParsedOperation,\n ParseResult,\n} from '../types';\nimport type { ImportedOperationSpec, ImportResult } from '../../common/types';\nimport { toFileName, toSpecKey } from '../../common/utils';\nimport { generateSchemaModelCode } from '../schema-converter';\nimport { buildInputSchemas, getOutputSchema } from './schemas';\nimport { generateSpecCode } from './generator';\nimport { generateModelCode } from './models';\nimport { generateEventCode } from './events';\nimport {\n resolveEventGroupFolder,\n resolveModelGroupFolder,\n resolveOperationGroupFolder,\n} from './grouping';\nimport type {\n ContractsrcConfig,\n OpenApiSourceConfig,\n} from '@lssm/lib.contracts';\n\nexport * from './analyzer';\nexport * from './schemas';\nexport * from './generator';\nexport * from './models';\nexport * from './events';\nexport * from './grouping';\n\n/**\n * Import operations from a parsed OpenAPI document.\n */\nexport const importFromOpenApi = (\n parseResult: ParseResult,\n contractspecOptions: ContractsrcConfig,\n importOptions: Partial<OpenApiSourceConfig> = {}\n): ImportResult => {\n const { tags, exclude = [], include } = importOptions;\n const specs: ImportedOperationSpec[] = [];\n const skipped: ImportResult['skipped'] = [];\n const errors: ImportResult['errors'] = [];\n\n for (const operation of parseResult.operations) {\n // Filter by tags if specified\n if (tags && tags.length > 0) {\n const hasMatchingTag = operation.tags.some((t) => tags.includes(t));\n if (!hasMatchingTag) {\n skipped.push({\n sourceId: operation.operationId,\n reason: `No matching tags (has: ${operation.tags.join(', ')})`,\n });\n continue;\n }\n }\n\n // Filter by include/exclude\n if (include && include.length > 0) {\n if (!include.includes(operation.operationId)) {\n skipped.push({\n sourceId: operation.operationId,\n reason: 'Not in include list',\n });\n continue;\n }\n } else if (exclude.includes(operation.operationId)) {\n skipped.push({\n sourceId: operation.operationId,\n reason: 'In exclude list',\n });\n continue;\n }\n\n // Skip deprecated operations by default\n if (\n operation.deprecated &&\n importOptions.defaultStability !== 'deprecated'\n ) {\n skipped.push({\n sourceId: operation.operationId,\n reason: 'Deprecated operation',\n });\n continue;\n }\n\n try {\n // Build input schemas\n const inputSchemas = buildInputSchemas(operation);\n const schemaFormat =\n importOptions.schemaFormat ||\n contractspecOptions.schemaFormat ||\n 'contractspec';\n\n // Generate models for each input source\n const inputModel = inputSchemas.body\n ? generateSchemaModelCode(\n inputSchemas.body,\n `${operation.operationId}Input`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const queryModel = inputSchemas.query\n ? generateSchemaModelCode(\n inputSchemas.query,\n `${operation.operationId}Query`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const paramsModel = inputSchemas.params\n ? generateSchemaModelCode(\n inputSchemas.params,\n `${operation.operationId}Params`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const headersModel = inputSchemas.headers\n ? generateSchemaModelCode(\n inputSchemas.headers,\n `${operation.operationId}Headers`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n // Get output schema\n const outputSchema = getOutputSchema(operation);\n let outputModel = outputSchema\n ? generateSchemaModelCode(\n outputSchema,\n `${operation.operationId}Output`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n // Filter out empty/comment-only output models ONLY for ContractSpec format\n if (\n outputModel &&\n schemaFormat === 'contractspec' &&\n !outputModel.code.includes('defineSchemaModel')\n ) {\n outputModel = null;\n }\n\n // Generate spec code\n const code = generateSpecCode(\n operation,\n contractspecOptions,\n importOptions,\n inputModel,\n outputModel,\n queryModel,\n paramsModel,\n headersModel\n );\n const specName = toSpecKey(operation.operationId, importOptions.prefix);\n const fileName = toFileName(specName);\n\n // Build transport hints\n const transportHints: OpenApiTransportHints = {\n rest: {\n method:\n operation.method.toUpperCase() as OpenApiTransportHints['rest']['method'],\n path: operation.path,\n params: {\n path: operation.pathParams.map((p) => p.name),\n query: operation.queryParams.map((p) => p.name),\n header: operation.headerParams.map((p) => p.name),\n cookie: operation.cookieParams.map((p) => p.name),\n },\n },\n };\n\n // Build source info\n const source: OpenApiSource = {\n type: 'openapi',\n sourceId: operation.operationId,\n operationId: operation.operationId,\n openApiVersion: parseResult.version,\n importedAt: new Date(),\n };\n\n // Resolve group folder based on config\n const groupFolder = resolveOperationGroupFolder(\n operation,\n contractspecOptions.conventions\n );\n\n specs.push({\n code,\n fileName,\n groupFolder: groupFolder || undefined,\n source,\n transportHints,\n });\n } catch (error) {\n errors.push({\n sourceId: operation.operationId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Import standalone models\n for (const [name, schema] of Object.entries(parseResult.schemas)) {\n try {\n const code = generateModelCode(name, schema, {\n ...contractspecOptions,\n schemaFormat:\n importOptions.schemaFormat || contractspecOptions.schemaFormat,\n });\n const fileName = toFileName(toSpecKey(name, importOptions.prefix));\n const groupFolder = resolveModelGroupFolder(\n name,\n contractspecOptions.conventions\n );\n\n specs.push({\n code,\n fileName,\n groupFolder: groupFolder || undefined,\n source: {\n type: 'openapi',\n sourceId: name,\n operationId: name,\n openApiVersion: parseResult.version,\n importedAt: new Date(),\n } as OpenApiSource,\n transportHints: {},\n });\n } catch (error) {\n errors.push({\n sourceId: name,\n error:\n error instanceof Error\n ? 'Model conversion failed: ' + error.message\n : String(error),\n });\n }\n }\n\n // Import events\n for (const event of parseResult.events) {\n try {\n const code = generateEventCode(event, {\n ...contractspecOptions,\n schemaFormat:\n importOptions.schemaFormat || contractspecOptions.schemaFormat,\n });\n const fileName = toFileName(toSpecKey(event.name, importOptions.prefix));\n const groupFolder = resolveEventGroupFolder(\n event.name,\n contractspecOptions.conventions\n );\n\n specs.push({\n code,\n fileName,\n groupFolder: groupFolder || undefined,\n source: {\n type: 'openapi',\n sourceId: event.name,\n operationId: event.name,\n openApiVersion: parseResult.version,\n importedAt: new Date(),\n } as OpenApiSource,\n transportHints: {},\n });\n } catch (error) {\n errors.push({\n sourceId: event.name,\n error:\n error instanceof Error\n ? 'Event conversion failed: ' + error.message\n : String(error),\n });\n }\n }\n\n return {\n operationSpecs: specs,\n skipped,\n errors,\n summary: {\n total:\n parseResult.operations.length +\n Object.keys(parseResult.schemas).length +\n parseResult.events.length,\n imported: specs.length,\n skipped: skipped.length,\n errors: errors.length,\n },\n };\n};\n\n/**\n * Import a single operation to ContractSpec code.\n */\nexport function importOperation(\n operation: ParsedOperation,\n options: Partial<OpenApiSourceConfig> = {},\n contractspecOptions: ContractsrcConfig\n): string {\n // Build input schemas\n const inputSchemas = buildInputSchemas(operation);\n const schemaFormat =\n options.schemaFormat || contractspecOptions.schemaFormat || 'contractspec';\n\n // Generate models for each input source\n const inputModel = inputSchemas.body\n ? generateSchemaModelCode(\n inputSchemas.body,\n `${operation.operationId}Input`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const queryModel = inputSchemas.query\n ? generateSchemaModelCode(\n inputSchemas.query,\n `${operation.operationId}Query`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const paramsModel = inputSchemas.params\n ? generateSchemaModelCode(\n inputSchemas.params,\n `${operation.operationId}Params`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const headersModel = inputSchemas.headers\n ? generateSchemaModelCode(\n inputSchemas.headers,\n `${operation.operationId}Headers`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n const outputSchema = getOutputSchema(operation);\n const outputModel = outputSchema\n ? generateSchemaModelCode(\n outputSchema,\n `${operation.operationId}Output`,\n schemaFormat,\n contractspecOptions\n )\n : null;\n\n return generateSpecCode(\n operation,\n contractspecOptions,\n options,\n inputModel,\n outputModel,\n queryModel,\n paramsModel,\n headersModel\n );\n}\n"],"mappings":"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"}
@@ -6,9 +6,12 @@ import { generateImports, generateSchemaModelCode } from "../schema-converter.js
6
6
  * Generate code for a standalone model.
7
7
  */
8
8
  function generateModelCode(name, schema, options) {
9
- const model = generateSchemaModelCode(schema, toPascalCase(toValidIdentifier(name)));
9
+ const model = generateSchemaModelCode(schema, toPascalCase(toValidIdentifier(name)), options.schemaFormat || "contractspec", options);
10
+ let imports = "";
11
+ if (model.imports && model.imports.length > 0) imports = model.imports.join("\n");
12
+ else if (model.fields.length > 0) imports = generateImports(model.fields, options);
10
13
  return `
11
- ${generateImports(model.fields, options)}
14
+ ${imports}
12
15
 
13
16
  ${model.code}
14
17
  `.trim();
@@ -1 +1 @@
1
- {"version":3,"file":"models.js","names":[],"sources":["../../../src/openapi/importer/models.ts"],"sourcesContent":["import type { OpenApiSchema } from '../types';\nimport { generateImports, generateSchemaModelCode } from '../schema-converter';\nimport { toPascalCase, toValidIdentifier } from '../../common/utils';\nimport type { ContractsrcConfig } from '@lssm/lib.contracts';\n\n/**\n * Generate code for a standalone model.\n */\nexport function generateModelCode(\n name: string,\n schema: OpenApiSchema,\n options: ContractsrcConfig\n): string {\n const modelName = toPascalCase(toValidIdentifier(name));\n const model = generateSchemaModelCode(schema, modelName);\n\n const imports = generateImports(model.fields, options);\n\n return `\n${imports}\n\n${model.code}\n`.trim();\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,kBACd,MACA,QACA,SACQ;CAER,MAAM,QAAQ,wBAAwB,QADpB,aAAa,kBAAkB,KAAK,CAAC,CACC;AAIxD,QAAO;EAFS,gBAAgB,MAAM,QAAQ,QAAQ,CAG9C;;EAER,MAAM,KAAK;EACX,MAAM"}
1
+ {"version":3,"file":"models.js","names":[],"sources":["../../../src/openapi/importer/models.ts"],"sourcesContent":["import type { OpenApiSchema } from '../types';\nimport { generateImports, generateSchemaModelCode } from '../schema-converter';\nimport { toPascalCase, toValidIdentifier } from '../../common/utils';\nimport type { ContractsrcConfig } from '@lssm/lib.contracts';\n\n/**\n * Generate code for a standalone model.\n */\nexport function generateModelCode(\n name: string,\n schema: OpenApiSchema,\n options: ContractsrcConfig\n): string {\n const modelName = toPascalCase(toValidIdentifier(name));\n const schemaFormat = options.schemaFormat || 'contractspec';\n\n const model = generateSchemaModelCode(\n schema,\n modelName,\n schemaFormat,\n options\n );\n\n let imports = '';\n if (model.imports && model.imports.length > 0) {\n imports = model.imports.join('\\n');\n } else if (model.fields.length > 0) {\n imports = generateImports(model.fields, options);\n }\n\n return `\n${imports}\n\n${model.code}\n`.trim();\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,kBACd,MACA,QACA,SACQ;CAIR,MAAM,QAAQ,wBACZ,QAJgB,aAAa,kBAAkB,KAAK,CAAC,EAClC,QAAQ,gBAAgB,gBAM3C,QACD;CAED,IAAI,UAAU;AACd,KAAI,MAAM,WAAW,MAAM,QAAQ,SAAS,EAC1C,WAAU,MAAM,QAAQ,KAAK,KAAK;UACzB,MAAM,OAAO,SAAS,EAC/B,WAAU,gBAAgB,MAAM,QAAQ,QAAQ;AAGlD,QAAO;EACP,QAAQ;;EAER,MAAM,KAAK;EACX,MAAM"}
@@ -1,62 +1,42 @@
1
1
  //#region src/openapi/importer/schemas.ts
2
2
  /**
3
- * Build a merged input schema from all parameter sources.
3
+ * Build separate input schemas for each parameter source.
4
4
  */
5
- function buildInputSchema(operation) {
6
- const fields = [];
7
- for (const param of operation.pathParams) fields.push({
8
- name: param.name,
9
- schema: param.schema,
10
- required: true
11
- });
12
- for (const param of operation.queryParams) fields.push({
13
- name: param.name,
14
- schema: param.schema,
15
- required: param.required
16
- });
5
+ function buildInputSchemas(operation) {
6
+ const result = {};
7
+ if (operation.pathParams.length > 0) result.params = {
8
+ type: "object",
9
+ properties: operation.pathParams.reduce((acc, p) => {
10
+ acc[p.name] = p.schema;
11
+ return acc;
12
+ }, {}),
13
+ required: operation.pathParams.map((p) => p.name)
14
+ };
15
+ if (operation.queryParams.length > 0) result.query = {
16
+ type: "object",
17
+ properties: operation.queryParams.reduce((acc, p) => {
18
+ acc[p.name] = p.schema;
19
+ return acc;
20
+ }, {}),
21
+ required: operation.queryParams.filter((p) => p.required).map((p) => p.name)
22
+ };
17
23
  const excludedHeaders = [
18
24
  "authorization",
19
25
  "content-type",
20
26
  "accept",
21
27
  "user-agent"
22
28
  ];
23
- for (const param of operation.headerParams) if (!excludedHeaders.includes(param.name.toLowerCase())) fields.push({
24
- name: param.name,
25
- schema: param.schema,
26
- required: param.required
27
- });
28
- if (operation.requestBody?.schema) {
29
- const bodySchema = operation.requestBody.schema;
30
- if (!("$ref" in bodySchema)) {
31
- const schemaObj = bodySchema;
32
- const properties = schemaObj["properties"];
33
- const required = schemaObj["required"] ?? [];
34
- if (properties) for (const [propName, propSchema] of Object.entries(properties)) fields.push({
35
- name: propName,
36
- schema: propSchema,
37
- required: required.includes(propName)
38
- });
39
- } else fields.push({
40
- name: "body",
41
- schema: bodySchema,
42
- required: operation.requestBody.required
43
- });
44
- }
45
- if (fields.length === 0) return {
46
- schema: null,
47
- fields: []
48
- };
49
- return {
50
- schema: {
51
- type: "object",
52
- properties: fields.reduce((acc, f) => {
53
- acc[f.name] = f.schema;
54
- return acc;
55
- }, {}),
56
- required: fields.filter((f) => f.required).map((f) => f.name)
57
- },
58
- fields
29
+ const actualHeaders = operation.headerParams.filter((p) => !excludedHeaders.includes(p.name.toLowerCase()));
30
+ if (actualHeaders.length > 0) result.headers = {
31
+ type: "object",
32
+ properties: actualHeaders.reduce((acc, p) => {
33
+ acc[p.name] = p.schema;
34
+ return acc;
35
+ }, {}),
36
+ required: actualHeaders.filter((p) => p.required).map((p) => p.name)
59
37
  };
38
+ if (operation.requestBody?.schema) result.body = operation.requestBody.schema;
39
+ return result;
60
40
  }
61
41
  /**
62
42
  * Get the output schema from the operation responses.
@@ -76,5 +56,5 @@ function getOutputSchema(operation) {
76
56
  }
77
57
 
78
58
  //#endregion
79
- export { buildInputSchema, getOutputSchema };
59
+ export { buildInputSchemas, getOutputSchema };
80
60
  //# sourceMappingURL=schemas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.js","names":["fields: {\n name: string;\n schema: OpenApiSchema;\n required: boolean;\n }[]"],"sources":["../../../src/openapi/importer/schemas.ts"],"sourcesContent":["import type { ParsedOperation, OpenApiSchema } from '../types';\n\n/**\n * Build a merged input schema from all parameter sources.\n */\nexport function buildInputSchema(operation: ParsedOperation): {\n schema: OpenApiSchema | null;\n fields: { name: string; schema: OpenApiSchema; required: boolean }[];\n} {\n const fields: {\n name: string;\n schema: OpenApiSchema;\n required: boolean;\n }[] = [];\n\n // Add path parameters\n for (const param of operation.pathParams) {\n fields.push({\n name: param.name,\n schema: param.schema,\n required: true, // Path params are always required\n });\n }\n\n // Add query parameters\n for (const param of operation.queryParams) {\n fields.push({\n name: param.name,\n schema: param.schema,\n required: param.required,\n });\n }\n\n // Add header parameters (excluding common headers)\n const excludedHeaders = [\n 'authorization',\n 'content-type',\n 'accept',\n 'user-agent',\n ];\n for (const param of operation.headerParams) {\n if (!excludedHeaders.includes(param.name.toLowerCase())) {\n fields.push({\n name: param.name,\n schema: param.schema,\n required: param.required,\n });\n }\n }\n\n // Add request body fields\n if (operation.requestBody?.schema) {\n const bodySchema = operation.requestBody.schema;\n if (!('$ref' in bodySchema)) {\n const schemaObj = bodySchema as Record<string, unknown>;\n const properties = schemaObj['properties'] as\n | Record<string, OpenApiSchema>\n | undefined;\n const required = (schemaObj['required'] as string[]) ?? [];\n\n if (properties) {\n for (const [propName, propSchema] of Object.entries(properties)) {\n fields.push({\n name: propName,\n schema: propSchema,\n required: required.includes(propName),\n });\n }\n }\n } else {\n // Reference to a schema - add as a single field\n fields.push({\n name: 'body',\n schema: bodySchema,\n required: operation.requestBody.required,\n });\n }\n }\n\n if (fields.length === 0) {\n return { schema: null, fields: [] };\n }\n\n // Build a merged schema\n const mergedSchema: OpenApiSchema = {\n type: 'object',\n properties: fields.reduce(\n (acc, f) => {\n acc[f.name] = f.schema;\n return acc;\n },\n {} as Record<string, OpenApiSchema>\n ),\n required: fields.filter((f) => f.required).map((f) => f.name),\n } as unknown as OpenApiSchema;\n\n return { schema: mergedSchema, fields };\n}\n\n/**\n * Get the output schema from the operation responses.\n */\nexport function getOutputSchema(\n operation: ParsedOperation\n): OpenApiSchema | null {\n // Prefer 200, then 201, then 2xx responses\n const successCodes = ['200', '201', '202', '204'];\n\n for (const code of successCodes) {\n const response = operation.responses[code];\n if (response?.schema) {\n return response.schema;\n }\n }\n\n // Check for any 2xx response\n for (const [code, response] of Object.entries(operation.responses)) {\n if (code.startsWith('2') && response.schema) {\n return response.schema;\n }\n }\n\n return null;\n}\n"],"mappings":";;;;AAKA,SAAgB,iBAAiB,WAG/B;CACA,MAAMA,SAIA,EAAE;AAGR,MAAK,MAAM,SAAS,UAAU,WAC5B,QAAO,KAAK;EACV,MAAM,MAAM;EACZ,QAAQ,MAAM;EACd,UAAU;EACX,CAAC;AAIJ,MAAK,MAAM,SAAS,UAAU,YAC5B,QAAO,KAAK;EACV,MAAM,MAAM;EACZ,QAAQ,MAAM;EACd,UAAU,MAAM;EACjB,CAAC;CAIJ,MAAM,kBAAkB;EACtB;EACA;EACA;EACA;EACD;AACD,MAAK,MAAM,SAAS,UAAU,aAC5B,KAAI,CAAC,gBAAgB,SAAS,MAAM,KAAK,aAAa,CAAC,CACrD,QAAO,KAAK;EACV,MAAM,MAAM;EACZ,QAAQ,MAAM;EACd,UAAU,MAAM;EACjB,CAAC;AAKN,KAAI,UAAU,aAAa,QAAQ;EACjC,MAAM,aAAa,UAAU,YAAY;AACzC,MAAI,EAAE,UAAU,aAAa;GAC3B,MAAM,YAAY;GAClB,MAAM,aAAa,UAAU;GAG7B,MAAM,WAAY,UAAU,eAA4B,EAAE;AAE1D,OAAI,WACF,MAAK,MAAM,CAAC,UAAU,eAAe,OAAO,QAAQ,WAAW,CAC7D,QAAO,KAAK;IACV,MAAM;IACN,QAAQ;IACR,UAAU,SAAS,SAAS,SAAS;IACtC,CAAC;QAKN,QAAO,KAAK;GACV,MAAM;GACN,QAAQ;GACR,UAAU,UAAU,YAAY;GACjC,CAAC;;AAIN,KAAI,OAAO,WAAW,EACpB,QAAO;EAAE,QAAQ;EAAM,QAAQ,EAAE;EAAE;AAgBrC,QAAO;EAAE,QAZ2B;GAClC,MAAM;GACN,YAAY,OAAO,QAChB,KAAK,MAAM;AACV,QAAI,EAAE,QAAQ,EAAE;AAChB,WAAO;MAET,EAAE,CACH;GACD,UAAU,OAAO,QAAQ,MAAM,EAAE,SAAS,CAAC,KAAK,MAAM,EAAE,KAAK;GAC9D;EAE8B;EAAQ;;;;;AAMzC,SAAgB,gBACd,WACsB;AAItB,MAAK,MAAM,QAFU;EAAC;EAAO;EAAO;EAAO;EAAM,EAEhB;EAC/B,MAAM,WAAW,UAAU,UAAU;AACrC,MAAI,UAAU,OACZ,QAAO,SAAS;;AAKpB,MAAK,MAAM,CAAC,MAAM,aAAa,OAAO,QAAQ,UAAU,UAAU,CAChE,KAAI,KAAK,WAAW,IAAI,IAAI,SAAS,OACnC,QAAO,SAAS;AAIpB,QAAO"}
1
+ {"version":3,"file":"schemas.js","names":["result: {\n body?: OpenApiSchema;\n query?: OpenApiSchema;\n params?: OpenApiSchema;\n headers?: OpenApiSchema;\n }"],"sources":["../../../src/openapi/importer/schemas.ts"],"sourcesContent":["import type { OpenApiSchema, ParsedOperation } from '../types';\n\n/**\n * Build separate input schemas for each parameter source.\n */\nexport function buildInputSchemas(operation: ParsedOperation): {\n body?: OpenApiSchema;\n query?: OpenApiSchema;\n params?: OpenApiSchema;\n headers?: OpenApiSchema;\n} {\n const result: {\n body?: OpenApiSchema;\n query?: OpenApiSchema;\n params?: OpenApiSchema;\n headers?: OpenApiSchema;\n } = {};\n\n // Path parameters -> params\n if (operation.pathParams.length > 0) {\n result.params = {\n type: 'object',\n properties: operation.pathParams.reduce(\n (acc, p) => {\n acc[p.name] = p.schema;\n return acc;\n },\n {} as Record<string, OpenApiSchema>\n ),\n required: operation.pathParams.map((p) => p.name),\n } as unknown as OpenApiSchema;\n }\n\n // Query parameters -> query\n if (operation.queryParams.length > 0) {\n result.query = {\n type: 'object',\n properties: operation.queryParams.reduce(\n (acc, p) => {\n acc[p.name] = p.schema;\n return acc;\n },\n {} as Record<string, OpenApiSchema>\n ),\n required: operation.queryParams\n .filter((p) => p.required)\n .map((p) => p.name),\n } as unknown as OpenApiSchema;\n }\n\n // Header parameters -> headers\n const excludedHeaders = [\n 'authorization',\n 'content-type',\n 'accept',\n 'user-agent',\n ];\n const actualHeaders = operation.headerParams.filter(\n (p) => !excludedHeaders.includes(p.name.toLowerCase())\n );\n if (actualHeaders.length > 0) {\n result.headers = {\n type: 'object',\n properties: actualHeaders.reduce(\n (acc, p) => {\n acc[p.name] = p.schema;\n return acc;\n },\n {} as Record<string, OpenApiSchema>\n ),\n required: actualHeaders.filter((p) => p.required).map((p) => p.name),\n } as unknown as OpenApiSchema;\n }\n\n // Request body -> body\n if (operation.requestBody?.schema) {\n result.body = operation.requestBody.schema;\n }\n\n return result;\n}\n\n/**\n * Get the output schema from the operation responses.\n */\nexport function getOutputSchema(\n operation: ParsedOperation\n): OpenApiSchema | null {\n // Prefer 200, then 201, then 2xx responses\n const successCodes = ['200', '201', '202', '204'];\n\n for (const code of successCodes) {\n const response = operation.responses[code];\n if (response?.schema) {\n return response.schema;\n }\n }\n\n // Check for any 2xx response\n for (const [code, response] of Object.entries(operation.responses)) {\n if (code.startsWith('2') && response.schema) {\n return response.schema;\n }\n }\n\n return null;\n}\n"],"mappings":";;;;AAKA,SAAgB,kBAAkB,WAKhC;CACA,MAAMA,SAKF,EAAE;AAGN,KAAI,UAAU,WAAW,SAAS,EAChC,QAAO,SAAS;EACd,MAAM;EACN,YAAY,UAAU,WAAW,QAC9B,KAAK,MAAM;AACV,OAAI,EAAE,QAAQ,EAAE;AAChB,UAAO;KAET,EAAE,CACH;EACD,UAAU,UAAU,WAAW,KAAK,MAAM,EAAE,KAAK;EAClD;AAIH,KAAI,UAAU,YAAY,SAAS,EACjC,QAAO,QAAQ;EACb,MAAM;EACN,YAAY,UAAU,YAAY,QAC/B,KAAK,MAAM;AACV,OAAI,EAAE,QAAQ,EAAE;AAChB,UAAO;KAET,EAAE,CACH;EACD,UAAU,UAAU,YACjB,QAAQ,MAAM,EAAE,SAAS,CACzB,KAAK,MAAM,EAAE,KAAK;EACtB;CAIH,MAAM,kBAAkB;EACtB;EACA;EACA;EACA;EACD;CACD,MAAM,gBAAgB,UAAU,aAAa,QAC1C,MAAM,CAAC,gBAAgB,SAAS,EAAE,KAAK,aAAa,CAAC,CACvD;AACD,KAAI,cAAc,SAAS,EACzB,QAAO,UAAU;EACf,MAAM;EACN,YAAY,cAAc,QACvB,KAAK,MAAM;AACV,OAAI,EAAE,QAAQ,EAAE;AAChB,UAAO;KAET,EAAE,CACH;EACD,UAAU,cAAc,QAAQ,MAAM,EAAE,SAAS,CAAC,KAAK,MAAM,EAAE,KAAK;EACrE;AAIH,KAAI,UAAU,aAAa,OACzB,QAAO,OAAO,UAAU,YAAY;AAGtC,QAAO;;;;;AAMT,SAAgB,gBACd,WACsB;AAItB,MAAK,MAAM,QAFU;EAAC;EAAO;EAAO;EAAO;EAAM,EAEhB;EAC/B,MAAM,WAAW,UAAU,UAAU;AACrC,MAAI,UAAU,OACZ,QAAO,SAAS;;AAKpB,MAAK,MAAM,CAAC,MAAM,aAAa,OAAO,QAAQ,UAAU,UAAU,CAChE,KAAI,KAAK,WAAW,IAAI,IAAI,SAAS,OACnC,QAAO,SAAS;AAIpB,QAAO"}
@@ -10,7 +10,7 @@ import { ExportedForm, exportForms, generateFormsRegistry } from "./exporter/for
10
10
  import { ExportedDataView, exportDataViews, generateDataViewsRegistry } from "./exporter/data-views.js";
11
11
  import { ExportedWorkflow, exportWorkflows, generateWorkflowsRegistry } from "./exporter/workflows.js";
12
12
  import { RegistryGenerationOptions, generateRegistryIndex } from "./exporter/registries.js";
13
- import { GeneratedModel, SchemaField, TypescriptType, generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToField, jsonSchemaToType } from "./schema-converter.js";
13
+ import { GeneratedModel, SchemaField, TypescriptType, generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToType } from "./schema-converter.js";
14
14
  import { importFromOpenApi, importOperation } from "./importer/index.js";
15
15
  import { DiffOptions, createSpecDiff, diffAll, diffSpecVsOperation, diffSpecs, formatDiffChanges } from "./differ.js";
16
- export { type ContractSpecOpenApiDocument, type ContractSpecRegistries, type DiffOptions, ExportedDataView, ExportedEvent, ExportedFeature, ExportedForm, ExportedPresentation, ExportedWorkflow, type GeneratedModel, type HttpMethod, type OpenApiDocument, type OpenApiExportOptions, type OpenApiOperation, type OpenApiParameter, type OpenApiParseOptions, type OpenApiSchema, type OpenApiServer, type OpenApiSource, type OpenApiTransportHints, type OpenApiVersion, OperationsExportResult, type ParameterLocation, type ParseResult, type ParsedOperation, type ParsedParameter, RegistryGenerationOptions, type SchemaField, type TypescriptType, contractSpecToJson, contractSpecToYaml, createSpecDiff, defaultRestPath, detectFormat, detectVersion, diffAll, diffSpecVsOperation, diffSpecs, exportContractSpec, exportDataViews, exportEvents, exportFeatures, exportForms, exportOperations, exportPresentations, exportPresentationsFromArray, exportWorkflows, formatDiffChanges, generateDataViewsRegistry, generateEventsExports, generateFeaturesRegistry, generateFormsRegistry, generateImports, generateOperationsRegistry, generatePresentationsRegistry, generateRegistryIndex, generateSchemaModelCode, generateWorkflowsRegistry, getScalarType, importFromOpenApi, importOperation, jsonSchemaForSpec, jsonSchemaToField, jsonSchemaToType, openApiForRegistry, openApiToJson, openApiToYaml, parseOpenApi, parseOpenApiDocument, parseOpenApiString, schemaModelToJsonSchema, toHttpMethod, toOperationId, toRestPath, toSchemaName };
16
+ export { type ContractSpecOpenApiDocument, type ContractSpecRegistries, type DiffOptions, ExportedDataView, ExportedEvent, ExportedFeature, ExportedForm, ExportedPresentation, ExportedWorkflow, type GeneratedModel, type HttpMethod, type OpenApiDocument, type OpenApiExportOptions, type OpenApiOperation, type OpenApiParameter, type OpenApiParseOptions, type OpenApiSchema, type OpenApiServer, type OpenApiSource, type OpenApiTransportHints, type OpenApiVersion, OperationsExportResult, type ParameterLocation, type ParseResult, type ParsedOperation, type ParsedParameter, RegistryGenerationOptions, type SchemaField, type TypescriptType, contractSpecToJson, contractSpecToYaml, createSpecDiff, defaultRestPath, detectFormat, detectVersion, diffAll, diffSpecVsOperation, diffSpecs, exportContractSpec, exportDataViews, exportEvents, exportFeatures, exportForms, exportOperations, exportPresentations, exportPresentationsFromArray, exportWorkflows, formatDiffChanges, generateDataViewsRegistry, generateEventsExports, generateFeaturesRegistry, generateFormsRegistry, generateImports, generateOperationsRegistry, generatePresentationsRegistry, generateRegistryIndex, generateSchemaModelCode, generateWorkflowsRegistry, getScalarType, importFromOpenApi, importOperation, jsonSchemaForSpec, jsonSchemaToType, openApiForRegistry, openApiToJson, openApiToYaml, parseOpenApi, parseOpenApiDocument, parseOpenApiString, schemaModelToJsonSchema, toHttpMethod, toOperationId, toRestPath, toSchemaName };
@@ -1,5 +1,6 @@
1
1
  import { detectFormat, detectVersion, parseOpenApiString } from "./parser/utils.js";
2
2
  import { parseOpenApi, parseOpenApiDocument } from "./parser/document.js";
3
+ import "./parser.js";
3
4
  import { defaultRestPath, exportOperations, generateOperationsRegistry, jsonSchemaForSpec, schemaModelToJsonSchema, toHttpMethod, toOperationId, toRestPath, toSchemaName } from "./exporter/operations.js";
4
5
  import { exportEvents, generateEventsExports } from "./exporter/events.js";
5
6
  import { exportFeatures, generateFeaturesRegistry } from "./exporter/features.js";
@@ -10,8 +11,8 @@ import { exportWorkflows, generateWorkflowsRegistry } from "./exporter/workflows
10
11
  import { generateRegistryIndex } from "./exporter/registries.js";
11
12
  import { contractSpecToJson, contractSpecToYaml, exportContractSpec, openApiForRegistry, openApiToJson, openApiToYaml } from "./exporter.js";
12
13
  import "./exporter/index.js";
13
- import { generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToField, jsonSchemaToType } from "./schema-converter.js";
14
+ import { generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToType } from "./schema-converter.js";
14
15
  import { importFromOpenApi, importOperation } from "./importer/index.js";
15
16
  import { createSpecDiff, diffAll, diffSpecVsOperation, diffSpecs, formatDiffChanges } from "./differ.js";
16
17
 
17
- export { contractSpecToJson, contractSpecToYaml, createSpecDiff, defaultRestPath, detectFormat, detectVersion, diffAll, diffSpecVsOperation, diffSpecs, exportContractSpec, exportDataViews, exportEvents, exportFeatures, exportForms, exportOperations, exportPresentations, exportPresentationsFromArray, exportWorkflows, formatDiffChanges, generateDataViewsRegistry, generateEventsExports, generateFeaturesRegistry, generateFormsRegistry, generateImports, generateOperationsRegistry, generatePresentationsRegistry, generateRegistryIndex, generateSchemaModelCode, generateWorkflowsRegistry, getScalarType, importFromOpenApi, importOperation, jsonSchemaForSpec, jsonSchemaToField, jsonSchemaToType, openApiForRegistry, openApiToJson, openApiToYaml, parseOpenApi, parseOpenApiDocument, parseOpenApiString, schemaModelToJsonSchema, toHttpMethod, toOperationId, toRestPath, toSchemaName };
18
+ export { contractSpecToJson, contractSpecToYaml, createSpecDiff, defaultRestPath, detectFormat, detectVersion, diffAll, diffSpecVsOperation, diffSpecs, exportContractSpec, exportDataViews, exportEvents, exportFeatures, exportForms, exportOperations, exportPresentations, exportPresentationsFromArray, exportWorkflows, formatDiffChanges, generateDataViewsRegistry, generateEventsExports, generateFeaturesRegistry, generateFormsRegistry, generateImports, generateOperationsRegistry, generatePresentationsRegistry, generateRegistryIndex, generateSchemaModelCode, generateWorkflowsRegistry, getScalarType, importFromOpenApi, importOperation, jsonSchemaForSpec, jsonSchemaToType, openApiForRegistry, openApiToJson, openApiToYaml, parseOpenApi, parseOpenApiDocument, parseOpenApiString, schemaModelToJsonSchema, toHttpMethod, toOperationId, toRestPath, toSchemaName };
@@ -0,0 +1,5 @@
1
+ import { HTTP_METHODS, detectFormat, detectVersion, generateOperationId, parseOpenApiString } from "./utils.js";
2
+ import { dereferenceSchema, isReference, resolveRef } from "./resolvers.js";
3
+ import { parseParameters } from "./parameters.js";
4
+ import { parseOperation } from "./operation.js";
5
+ import { parseOpenApi, parseOpenApiDocument } from "./document.js";
@@ -0,0 +1,6 @@
1
+ import { HTTP_METHODS, detectFormat, detectVersion, generateOperationId, parseOpenApiString } from "./parser/utils.js";
2
+ import { dereferenceSchema, isReference, resolveRef } from "./parser/resolvers.js";
3
+ import { parseParameters } from "./parser/parameters.js";
4
+ import { parseOperation } from "./parser/operation.js";
5
+ import { parseOpenApi, parseOpenApiDocument } from "./parser/document.js";
6
+ import "./parser/index.js";
@@ -1,5 +1,5 @@
1
1
  import { OpenApiSchema } from "./types.js";
2
- import { ContractsrcConfig } from "@lssm/lib.contracts";
2
+ import { ContractsrcConfig, SchemaFormat } from "@lssm/lib.contracts";
3
3
 
4
4
  //#region src/openapi/schema-converter.d.ts
5
5
 
@@ -47,6 +47,8 @@ interface GeneratedModel {
47
47
  fields: SchemaField[];
48
48
  /** Generated TypeScript code */
49
49
  code: string;
50
+ /** Required imports */
51
+ imports?: string[];
50
52
  }
51
53
  /**
52
54
  * Convert a JSON Schema to a TypeScript type representation.
@@ -57,20 +59,13 @@ declare function jsonSchemaToType(schema: OpenApiSchema, name?: string): Typescr
57
59
  */
58
60
  declare function getScalarType(schema: OpenApiSchema): string | undefined;
59
61
  /**
60
- * Convert a JSON Schema to a SchemaModel field definition.
62
+ * Generate code for a schema model using the specified format.
61
63
  */
62
- declare function jsonSchemaToField(schema: OpenApiSchema, fieldName: string, required: boolean): SchemaField;
63
- /**
64
- * Generate SchemaModel TypeScript code for a JSON Schema object.
65
- */
66
- declare function generateSchemaModelCode(schema: OpenApiSchema, modelName: string, indent?: number): GeneratedModel;
64
+ declare function generateSchemaModelCode(schema: OpenApiSchema, modelName: string, schemaFormat?: SchemaFormat, config?: ContractsrcConfig): GeneratedModel;
67
65
  /**
68
66
  * Generate import statements for a SchemaModel.
69
- * @param fields - The fields to generate imports for
70
- * @param options - Configuration for import generation
71
- * @param sameDirectory - If true, imports use './' (for model-to-model). If false, uses '../models/' (for operations/events)
72
67
  */
73
68
  declare function generateImports(fields: SchemaField[], options: ContractsrcConfig, sameDirectory?: boolean): string;
74
69
  //#endregion
75
- export { GeneratedModel, SchemaField, TypescriptType, generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToField, jsonSchemaToType };
70
+ export { GeneratedModel, SchemaField, TypescriptType, generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToType };
76
71
  //# sourceMappingURL=schema-converter.d.ts.map