@lssm/lib.contracts-transformers 1.42.9 → 1.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,12 @@
1
- import { toCamelCase, toPascalCase, toValidIdentifier } from "../common/utils.js";
1
+ import { toPascalCase } from "../common/utils.js";
2
+ import { createSchemaGenerator } from "./schema-generators/index.js";
2
3
 
3
4
  //#region src/openapi/schema-converter.ts
4
5
  /**
6
+ * JSON Schema to SchemaModel conversion utilities.
7
+ * Converts OpenAPI JSON Schema to ContractSpec SchemaModel definitions.
8
+ */
9
+ /**
5
10
  * Map JSON Schema types to ContractSpec ScalarTypeEnum values.
6
11
  */
7
12
  const JSON_SCHEMA_TO_SCALAR = {
@@ -19,7 +24,7 @@ const JSON_SCHEMA_TO_SCALAR = {
19
24
  * Check if a schema is a reference object.
20
25
  */
21
26
  function isReference(schema) {
22
- return "$ref" in schema;
27
+ return typeof schema === "object" && schema !== null && "$ref" in schema;
23
28
  }
24
29
  /**
25
30
  * Extract type name from a $ref.
@@ -62,20 +67,23 @@ function jsonSchemaToType(schema, name) {
62
67
  type: "unknown",
63
68
  optional: nullable ?? false,
64
69
  array: true,
65
- primitive: false
70
+ primitive: false,
71
+ isReference: true
66
72
  };
67
73
  }
68
74
  if (type === "object" || schemaObj["properties"]) return {
69
75
  type: name ? toPascalCase(name) : "Record<string, unknown>",
70
76
  optional: nullable ?? false,
71
77
  array: false,
72
- primitive: false
78
+ primitive: false,
79
+ isReference: true
73
80
  };
74
81
  if (schemaObj["enum"]) return {
75
82
  type: name ? toPascalCase(name) : "string",
76
83
  optional: nullable ?? false,
77
84
  array: false,
78
- primitive: false
85
+ primitive: false,
86
+ isReference: true
79
87
  };
80
88
  const scalarKey = format ? `${type}:${format}` : type;
81
89
  if (scalarKey === "string") return {
@@ -100,7 +108,8 @@ function jsonSchemaToType(schema, name) {
100
108
  type: "unknown",
101
109
  optional: nullable ?? false,
102
110
  array: false,
103
- primitive: false
111
+ primitive: false,
112
+ isReference: true
104
113
  };
105
114
  }
106
115
  /**
@@ -117,169 +126,23 @@ function getScalarType(schema) {
117
126
  if (items) return getScalarType(items);
118
127
  return;
119
128
  }
120
- return JSON_SCHEMA_TO_SCALAR[format ? `${type}:${format}` : type] ?? JSON_SCHEMA_TO_SCALAR[type];
129
+ return JSON_SCHEMA_TO_SCALAR[format ? `${type}:${format}` : type] ?? JSON_SCHEMA_TO_SCALAR[type] ?? void 0;
121
130
  }
122
131
  /**
123
- * Convert a JSON Schema to a SchemaModel field definition.
132
+ * Generate code for a schema model using the specified format.
124
133
  */
125
- function jsonSchemaToField(schema, fieldName, required) {
126
- const type = jsonSchemaToType(schema, fieldName);
127
- const scalarType = getScalarType(schema);
128
- let enumValues;
129
- if (!isReference(schema)) {
130
- const enumArr = schema["enum"];
131
- if (enumArr) enumValues = enumArr.map(String);
132
- }
134
+ function generateSchemaModelCode(schema, modelName, indent = 0, schemaFormat = "contractspec", config) {
135
+ const result = createSchemaGenerator(schemaFormat, config).generateModel(schema, modelName, { description: schema["description"] });
133
136
  return {
134
- name: toValidIdentifier(toCamelCase(fieldName)),
135
- type: {
136
- ...type,
137
- optional: !required || type.optional,
138
- description: !isReference(schema) ? schema["description"] : void 0
139
- },
140
- scalarType,
141
- enumValues
142
- };
143
- }
144
- /**
145
- * Generate SchemaModel TypeScript code for a JSON Schema object.
146
- */
147
- function generateSchemaModelCode(schema, modelName, indent = 0) {
148
- const spaces = " ".repeat(indent);
149
- const fields = [];
150
- if (isReference(schema)) return {
151
- name: toPascalCase(typeNameFromRef(schema.$ref)),
137
+ name: result.name,
138
+ description: schema["description"],
152
139
  fields: [],
153
- code: `// Reference to ${schema.$ref}`
140
+ code: result.code,
141
+ imports: result.imports
154
142
  };
155
- const schemaObj = schema;
156
- const description = schemaObj["description"];
157
- const properties = schemaObj["properties"];
158
- const required = schemaObj["required"] ?? [];
159
- const enumValues = schemaObj["enum"];
160
- if (enumValues && enumValues.length > 0) {
161
- const safeModelName$1 = toPascalCase(toValidIdentifier(modelName));
162
- return {
163
- name: safeModelName$1,
164
- description,
165
- fields: [],
166
- code: [
167
- `${spaces}/**`,
168
- `${spaces} * Enum type: ${safeModelName$1}`,
169
- description ? `${spaces} * ${description}` : null,
170
- `${spaces} */`,
171
- `${spaces}export const ${safeModelName$1} = new EnumType('${safeModelName$1}', [${enumValues.map((v) => `'${String(v)}'`).join(", ")}]);`
172
- ].filter((line) => line !== null).join("\n")
173
- };
174
- }
175
- const schemaType = schemaObj["type"];
176
- if (schemaType && !properties && !enumValues) {
177
- const safeModelName$1 = toPascalCase(toValidIdentifier(modelName));
178
- const format = schemaObj["format"];
179
- const scalarType = JSON_SCHEMA_TO_SCALAR[format ? `${schemaType}:${format}` : schemaType] ?? JSON_SCHEMA_TO_SCALAR[schemaType];
180
- if (scalarType) return {
181
- name: safeModelName$1,
182
- description,
183
- fields: [],
184
- code: [
185
- `${spaces}/**`,
186
- `${spaces} * Type alias: ${safeModelName$1}`,
187
- description ? `${spaces} * ${description}` : null,
188
- `${spaces} * Underlying type: ${scalarType}`,
189
- `${spaces} */`,
190
- `${spaces}export const ${safeModelName$1} = defineSchemaModel({`,
191
- `${spaces} name: '${safeModelName$1}',`,
192
- description ? `${spaces} description: ${JSON.stringify(description)},` : null,
193
- `${spaces} fields: {`,
194
- `${spaces} value: {`,
195
- `${spaces} type: ${scalarType}(),`,
196
- `${spaces} isOptional: false,`,
197
- `${spaces} },`,
198
- `${spaces} },`,
199
- `${spaces}});`
200
- ].filter((line) => line !== null).join("\n")
201
- };
202
- }
203
- if (schemaObj["additionalProperties"] && !properties) {
204
- const safeModelName$1 = toPascalCase(toValidIdentifier(modelName));
205
- return {
206
- name: safeModelName$1,
207
- description,
208
- fields: [],
209
- code: [
210
- `${spaces}/**`,
211
- `${spaces} * Dictionary/Record type: ${safeModelName$1}`,
212
- description ? `${spaces} * ${description}` : null,
213
- `${spaces} * Use as: Record<string, unknown> - access via record[key]`,
214
- `${spaces} */`,
215
- `${spaces}export const ${safeModelName$1} = ScalarTypeEnum.JSONObject();`
216
- ].filter((line) => line !== null).join("\n")
217
- };
218
- }
219
- if (!properties) {
220
- const safeModelName$1 = toPascalCase(toValidIdentifier(modelName));
221
- return {
222
- name: safeModelName$1,
223
- description,
224
- fields: [],
225
- code: [
226
- `${spaces}export const ${safeModelName$1} = defineSchemaModel({`,
227
- `${spaces} name: '${safeModelName$1}',`,
228
- description ? `${spaces} description: ${JSON.stringify(description)},` : null,
229
- `${spaces} fields: {},`,
230
- `${spaces}});`
231
- ].filter((line) => line !== null).join("\n")
232
- };
233
- }
234
- for (const [propName, propSchema] of Object.entries(properties)) {
235
- const isRequired = required.includes(propName);
236
- fields.push(jsonSchemaToField(propSchema, propName, isRequired));
237
- }
238
- const lines = [];
239
- const safeModelName = toPascalCase(toValidIdentifier(modelName));
240
- lines.push(`${spaces}export const ${safeModelName} = defineSchemaModel({`);
241
- lines.push(`${spaces} name: '${safeModelName}',`);
242
- if (description) lines.push(`${spaces} description: ${JSON.stringify(description)},`);
243
- lines.push(`${spaces} fields: {`);
244
- for (const field of fields) {
245
- const fieldLines = generateFieldCode(field, indent + 2);
246
- lines.push(fieldLines);
247
- }
248
- lines.push(`${spaces} },`);
249
- lines.push(`${spaces}});`);
250
- return {
251
- name: safeModelName,
252
- description,
253
- fields,
254
- code: lines.join("\n")
255
- };
256
- }
257
- /**
258
- * Generate TypeScript code for a single field.
259
- */
260
- function generateFieldCode(field, indent) {
261
- const spaces = " ".repeat(indent);
262
- const lines = [];
263
- lines.push(`${spaces}${field.name}: {`);
264
- if (field.enumValues) {
265
- const enumName = toPascalCase(field.name) + "Enum";
266
- lines.push(`${spaces} type: new EnumType('${enumName}', [${field.enumValues.map((v) => `'${v}'`).join(", ")}]),`);
267
- } else if (field.scalarType) lines.push(`${spaces} type: ${field.scalarType}(),`);
268
- else if (field.type.primitive) {
269
- const fallbackScalar = field.type.type === "number" ? "ScalarTypeEnum.Float_unsecure" : field.type.type === "boolean" ? "ScalarTypeEnum.Boolean_unsecure" : "ScalarTypeEnum.String_unsecure";
270
- lines.push(`${spaces} type: ${fallbackScalar}(),`);
271
- } else if (field.type.isReference) lines.push(`${spaces} type: ${field.type.type},`);
272
- else lines.push(`${spaces} type: ScalarTypeEnum.JSONObject(), // TODO: Define nested model for ${field.type.type}`);
273
- lines.push(`${spaces} isOptional: ${field.type.optional},`);
274
- if (field.type.array) lines.push(`${spaces} isArray: true,`);
275
- lines.push(`${spaces}},`);
276
- return lines.join("\n");
277
143
  }
278
144
  /**
279
145
  * Generate import statements for a SchemaModel.
280
- * @param fields - The fields to generate imports for
281
- * @param options - Configuration for import generation
282
- * @param sameDirectory - If true, imports use './' (for model-to-model). If false, uses '../models/' (for operations/events)
283
146
  */
284
147
  function generateImports(fields, options, sameDirectory = true) {
285
148
  const imports = /* @__PURE__ */ new Set();
@@ -294,5 +157,5 @@ function generateImports(fields, options, sameDirectory = true) {
294
157
  }
295
158
 
296
159
  //#endregion
297
- export { generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToField, jsonSchemaToType };
160
+ export { generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToType };
298
161
  //# sourceMappingURL=schema-converter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema-converter.js","names":["JSON_SCHEMA_TO_SCALAR: Record<string, string>","enumValues: string[] | undefined","fields: SchemaField[]","safeModelName","lines: string[]"],"sources":["../../src/openapi/schema-converter.ts"],"sourcesContent":["/**\n * JSON Schema to SchemaModel conversion utilities.\n * Converts OpenAPI JSON Schema to ContractSpec SchemaModel definitions.\n */\n\nimport type { OpenApiSchema } from './types';\nimport { toCamelCase, toPascalCase, toValidIdentifier } from '../common/utils';\nimport type { ContractsrcConfig } from '@lssm/lib.contracts';\n\n/**\n * TypeScript type representation for code generation.\n */\nexport interface TypescriptType {\n /** The type expression (e.g., \"string\", \"number\", \"MyModel\") */\n type: string;\n /** Whether the type is optional */\n optional: boolean;\n /** Whether the type is an array */\n array: boolean;\n /** Whether this is a primitive type */\n primitive: boolean;\n /** Description for documentation */\n description?: string;\n /** Whether this type is a reference to another schema (needs import) vs inline */\n isReference?: boolean;\n}\n\n/**\n * SchemaModel field representation for code generation.\n */\nexport interface SchemaField {\n /** Field name */\n name: string;\n /** Field type */\n type: TypescriptType;\n /** Scalar type enum value (for FieldType) */\n scalarType?: string;\n /** Enum values if this is an enum type */\n enumValues?: string[];\n /** Nested model if this is an object type */\n nestedModel?: GeneratedModel;\n}\n\n/**\n * Generated model representation.\n */\nexport interface GeneratedModel {\n /** Model name (PascalCase) */\n name: string;\n /** Model description */\n description?: string;\n /** Fields */\n fields: SchemaField[];\n /** Generated TypeScript code */\n code: string;\n}\n\n/**\n * Map JSON Schema types to ContractSpec ScalarTypeEnum values.\n */\nconst JSON_SCHEMA_TO_SCALAR: Record<string, string> = {\n string: 'ScalarTypeEnum.String_unsecure',\n integer: 'ScalarTypeEnum.Int_unsecure',\n number: 'ScalarTypeEnum.Float_unsecure',\n boolean: 'ScalarTypeEnum.Boolean',\n // Special formats\n 'string:date': 'ScalarTypeEnum.Date',\n 'string:date-time': 'ScalarTypeEnum.DateTime',\n 'string:email': 'ScalarTypeEnum.EmailAddress',\n 'string:uri': 'ScalarTypeEnum.URL',\n 'string:uuid': 'ScalarTypeEnum.ID',\n};\n\n/**\n * Check if a schema is a reference object.\n */\nfunction isReference(schema: OpenApiSchema): schema is { $ref: string } {\n return '$ref' in schema;\n}\n\n/**\n * Extract type name from a $ref.\n */\nfunction typeNameFromRef(ref: string): string {\n const parts = ref.split('/');\n return parts[parts.length - 1] ?? 'Unknown';\n}\n\n/**\n * Convert a JSON Schema to a TypeScript type representation.\n */\nexport function jsonSchemaToType(\n schema: OpenApiSchema,\n name?: string\n): TypescriptType {\n if (isReference(schema)) {\n return {\n type: toPascalCase(typeNameFromRef(schema.$ref)),\n optional: false,\n array: false,\n primitive: false,\n isReference: true,\n };\n }\n\n const schemaObj = schema as Record<string, unknown>;\n const type = schemaObj['type'] as string | undefined;\n const format = schemaObj['format'] as string | undefined;\n const nullable = schemaObj['nullable'] as boolean | undefined;\n\n // Check if this schema was dereferenced from a $ref - use the original type name\n const originalTypeName = schemaObj['_originalTypeName'] as string | undefined;\n if (originalTypeName) {\n return {\n type: toPascalCase(originalTypeName),\n optional: nullable ?? false,\n array: false,\n primitive: false,\n isReference: true,\n };\n }\n\n // Handle arrays\n if (type === 'array') {\n const items = schemaObj['items'] as OpenApiSchema | undefined;\n if (items) {\n const itemType = jsonSchemaToType(items, name);\n return {\n ...itemType,\n array: true,\n optional: nullable ?? false,\n };\n }\n return {\n type: 'unknown',\n optional: nullable ?? false,\n array: true,\n primitive: false,\n };\n }\n\n // Handle objects\n if (type === 'object' || schemaObj['properties']) {\n return {\n type: name ? toPascalCase(name) : 'Record<string, unknown>',\n optional: nullable ?? false,\n array: false,\n primitive: false,\n };\n }\n\n // Handle enums\n if (schemaObj['enum']) {\n return {\n type: name ? toPascalCase(name) : 'string',\n optional: nullable ?? false,\n array: false,\n primitive: false,\n };\n }\n\n // Handle primitives\n const scalarKey = format ? `${type}:${format}` : type;\n if (scalarKey === 'string') {\n return {\n type: 'string',\n optional: nullable ?? false,\n array: false,\n primitive: true,\n };\n }\n if (scalarKey === 'integer' || type === 'number') {\n return {\n type: 'number',\n optional: nullable ?? false,\n array: false,\n primitive: true,\n };\n }\n if (scalarKey === 'boolean') {\n return {\n type: 'boolean',\n optional: nullable ?? false,\n array: false,\n primitive: true,\n };\n }\n\n // Default to unknown\n return {\n type: 'unknown',\n optional: nullable ?? false,\n array: false,\n primitive: false,\n };\n}\n\n/**\n * Get the ScalarTypeEnum value for a JSON Schema type.\n */\nexport function getScalarType(schema: OpenApiSchema): string | undefined {\n if (isReference(schema)) {\n return undefined;\n }\n\n const schemaObj = schema as Record<string, unknown>;\n const type = schemaObj['type'] as string | undefined;\n const format = schemaObj['format'] as string | undefined;\n\n if (!type) return undefined;\n\n // For arrays, get the scalar type of the items\n if (type === 'array') {\n const items = schemaObj['items'] as OpenApiSchema | undefined;\n if (items) {\n return getScalarType(items);\n }\n return undefined;\n }\n\n const key = format ? `${type}:${format}` : type;\n return JSON_SCHEMA_TO_SCALAR[key] ?? JSON_SCHEMA_TO_SCALAR[type];\n}\n\n/**\n * Convert a JSON Schema to a SchemaModel field definition.\n */\nexport function jsonSchemaToField(\n schema: OpenApiSchema,\n fieldName: string,\n required: boolean\n): SchemaField {\n const type = jsonSchemaToType(schema, fieldName);\n const scalarType = getScalarType(schema);\n\n // Handle enums\n let enumValues: string[] | undefined;\n if (!isReference(schema)) {\n const schemaObj = schema as Record<string, unknown>;\n const enumArr = schemaObj['enum'] as unknown[] | undefined;\n if (enumArr) {\n enumValues = enumArr.map(String);\n }\n }\n\n return {\n name: toValidIdentifier(toCamelCase(fieldName)),\n type: {\n ...type,\n optional: !required || type.optional,\n description: !isReference(schema)\n ? ((schema as Record<string, unknown>)['description'] as string)\n : undefined,\n },\n scalarType,\n enumValues,\n };\n}\n\n/**\n * Generate SchemaModel TypeScript code for a JSON Schema object.\n */\nexport function generateSchemaModelCode(\n schema: OpenApiSchema,\n modelName: string,\n indent = 0\n): GeneratedModel {\n const spaces = ' '.repeat(indent);\n const fields: SchemaField[] = [];\n\n if (isReference(schema)) {\n // Reference type - just use the referenced type\n return {\n name: toPascalCase(typeNameFromRef(schema.$ref)),\n fields: [],\n code: `// Reference to ${schema.$ref}`,\n };\n }\n\n const schemaObj = schema as Record<string, unknown>;\n const description = schemaObj['description'] as string | undefined;\n const properties = schemaObj['properties'] as\n | Record<string, OpenApiSchema>\n | undefined;\n const required = (schemaObj['required'] as string[]) ?? [];\n\n // Handle enum types (generate an EnumType export instead of a model)\n const enumValues = schemaObj['enum'] as unknown[] | undefined;\n if (enumValues && enumValues.length > 0) {\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n const enumCode = [\n `${spaces}/**`,\n `${spaces} * Enum type: ${safeModelName}`,\n description ? `${spaces} * ${description}` : null,\n `${spaces} */`,\n `${spaces}export const ${safeModelName} = new EnumType('${safeModelName}', [${enumValues.map((v) => `'${String(v)}'`).join(', ')}]);`,\n ]\n .filter((line) => line !== null)\n .join('\\n');\n\n return {\n name: safeModelName,\n description,\n fields: [],\n code: enumCode,\n };\n }\n\n // Handle primitive types (string, number, boolean) - generate type alias\n const schemaType = schemaObj['type'] as string | undefined;\n if (schemaType && !properties && !enumValues) {\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n const format = schemaObj['format'] as string | undefined;\n const scalarKey = format ? `${schemaType}:${format}` : schemaType;\n const scalarType =\n JSON_SCHEMA_TO_SCALAR[scalarKey] ?? JSON_SCHEMA_TO_SCALAR[schemaType];\n\n if (scalarType) {\n const aliasCode = [\n `${spaces}/**`,\n `${spaces} * Type alias: ${safeModelName}`,\n description ? `${spaces} * ${description}` : null,\n `${spaces} * Underlying type: ${scalarType}`,\n `${spaces} */`,\n `${spaces}export const ${safeModelName} = defineSchemaModel({`,\n `${spaces} name: '${safeModelName}',`,\n description\n ? `${spaces} description: ${JSON.stringify(description)},`\n : null,\n `${spaces} fields: {`,\n `${spaces} value: {`,\n `${spaces} type: ${scalarType}(),`,\n `${spaces} isOptional: false,`,\n `${spaces} },`,\n `${spaces} },`,\n `${spaces}});`,\n ]\n .filter((line) => line !== null)\n .join('\\n');\n\n return {\n name: safeModelName,\n description,\n fields: [],\n code: aliasCode,\n };\n }\n }\n\n // Handle additionalProperties (dictionary/map types)\n const additionalProperties = schemaObj['additionalProperties'];\n if (additionalProperties && !properties) {\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n\n // For dictionary types, we use JSONObject which is Record<string, unknown>\n // This is the correct representation in the schema library\n const dictCode = [\n `${spaces}/**`,\n `${spaces} * Dictionary/Record type: ${safeModelName}`,\n description ? `${spaces} * ${description}` : null,\n `${spaces} * Use as: Record<string, unknown> - access via record[key]`,\n `${spaces} */`,\n `${spaces}export const ${safeModelName} = ScalarTypeEnum.JSONObject();`,\n ]\n .filter((line) => line !== null)\n .join('\\n');\n\n return {\n name: safeModelName,\n description,\n fields: [],\n code: dictCode,\n };\n }\n\n if (!properties) {\n // No properties - generate an empty model (for empty object response types)\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n const emptyModelCode = [\n `${spaces}export const ${safeModelName} = defineSchemaModel({`,\n `${spaces} name: '${safeModelName}',`,\n description\n ? `${spaces} description: ${JSON.stringify(description)},`\n : null,\n `${spaces} fields: {},`,\n `${spaces}});`,\n ]\n .filter((line) => line !== null)\n .join('\\n');\n\n return {\n name: safeModelName,\n description,\n fields: [],\n code: emptyModelCode,\n };\n }\n\n // Generate fields\n for (const [propName, propSchema] of Object.entries(properties)) {\n const isRequired = required.includes(propName);\n fields.push(jsonSchemaToField(propSchema, propName, isRequired));\n }\n\n // Generate code\n const lines: string[] = [];\n\n // Model definition\n const safeModelName = toPascalCase(toValidIdentifier(modelName));\n lines.push(`${spaces}export const ${safeModelName} = defineSchemaModel({`);\n lines.push(`${spaces} name: '${safeModelName}',`);\n if (description) {\n lines.push(`${spaces} description: ${JSON.stringify(description)},`);\n }\n lines.push(`${spaces} fields: {`);\n\n for (const field of fields) {\n const fieldLines = generateFieldCode(field, indent + 2);\n lines.push(fieldLines);\n }\n\n lines.push(`${spaces} },`);\n lines.push(`${spaces}});`);\n\n return {\n name: safeModelName,\n description,\n fields,\n code: lines.join('\\n'),\n };\n}\n\n/**\n * Generate TypeScript code for a single field.\n */\nfunction generateFieldCode(field: SchemaField, indent: number): string {\n const spaces = ' '.repeat(indent);\n const lines: string[] = [];\n\n lines.push(`${spaces}${field.name}: {`);\n\n // Type\n if (field.enumValues) {\n // Enum type\n // Generate a name based on the field name\n const enumName = toPascalCase(field.name) + 'Enum';\n lines.push(\n `${spaces} type: new EnumType('${enumName}', [${field.enumValues.map((v) => `'${v}'`).join(', ')}]),`\n );\n } else if (field.scalarType) {\n // Scalar type\n lines.push(`${spaces} type: ${field.scalarType}(),`);\n } else if (field.type.primitive) {\n // Primitive type without a specific scalar mapping - use generic fallback\n const fallbackScalar =\n field.type.type === 'number'\n ? 'ScalarTypeEnum.Float_unsecure'\n : field.type.type === 'boolean'\n ? 'ScalarTypeEnum.Boolean_unsecure'\n : 'ScalarTypeEnum.String_unsecure';\n lines.push(`${spaces} type: ${fallbackScalar}(),`);\n } else if (field.type.isReference) {\n // Reference to another schema model\n lines.push(`${spaces} type: ${field.type.type},`);\n } else {\n // Inline nested object - TODO: Generate nested model\n lines.push(\n `${spaces} type: ScalarTypeEnum.JSONObject(), // TODO: Define nested model for ${field.type.type}`\n );\n }\n\n // Optional\n lines.push(`${spaces} isOptional: ${field.type.optional},`);\n\n // Array\n if (field.type.array) {\n lines.push(`${spaces} isArray: true,`);\n }\n\n lines.push(`${spaces}},`);\n\n return lines.join('\\n');\n}\n\n/**\n * Generate import statements for a SchemaModel.\n * @param fields - The fields to generate imports for\n * @param options - Configuration for import generation\n * @param sameDirectory - If true, imports use './' (for model-to-model). If false, uses '../models/' (for operations/events)\n */\nexport function generateImports(\n fields: SchemaField[],\n options: ContractsrcConfig,\n sameDirectory = true\n): string {\n const imports = new Set<string>();\n // Determine import path based on whether we're in the same directory\n const modelsDir = sameDirectory ? '.' : `../${options.conventions.models}`;\n\n imports.add(\n \"import { defineSchemaModel, ScalarTypeEnum, EnumType } from '@lssm/lib.schema';\"\n );\n\n // Check if we need any custom type imports\n for (const field of fields) {\n // If it's a reference (represented as a custom type not being scalar or enum)\n // In our simplified generator, referencing models often means just using the type name.\n // If we assume all models are generated in the same directory or available via barrel export,\n // we might not need explicit imports if we are in the same module,\n // BUT ContractSpec usually requires importing dependencies.\n // For now, let's assume we import from specific files.\n\n // Only import fields that are actual references to other schemas (not inline types)\n // Check isReference flag which is set when type came from $ref or _originalTypeName\n if (\n field.type.isReference &&\n !field.type.primitive &&\n !field.enumValues &&\n !field.scalarType &&\n !field.nestedModel\n ) {\n // This is a reference to another schema model\n const modelName = field.type.type;\n // Convert PascalCase model name to kebab-case file name\n const kebabName = modelName\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase();\n imports.add(`import { ${modelName} } from '${modelsDir}/${kebabName}';`);\n }\n }\n\n return Array.from(imports).join('\\n');\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"schema-converter.js","names":["JSON_SCHEMA_TO_SCALAR: Record<string, string>"],"sources":["../../src/openapi/schema-converter.ts"],"sourcesContent":["/**\n * JSON Schema to SchemaModel conversion utilities.\n * Converts OpenAPI JSON Schema to ContractSpec SchemaModel definitions.\n */\n\nimport { createSchemaGenerator } from './schema-generators';\nimport type { SchemaFormat, ContractsrcConfig } from '@lssm/lib.contracts';\nimport type { OpenApiSchema } from './types';\nimport { toCamelCase, toPascalCase, toValidIdentifier } from '../common/utils';\n\n/**\n * Map JSON Schema types to ContractSpec ScalarTypeEnum values.\n */\nconst JSON_SCHEMA_TO_SCALAR: Record<string, string> = {\n string: 'ScalarTypeEnum.String_unsecure',\n integer: 'ScalarTypeEnum.Int_unsecure',\n number: 'ScalarTypeEnum.Float_unsecure',\n boolean: 'ScalarTypeEnum.Boolean',\n // Special formats\n 'string:date': 'ScalarTypeEnum.Date',\n 'string:date-time': 'ScalarTypeEnum.DateTime',\n 'string:email': 'ScalarTypeEnum.EmailAddress',\n 'string:uri': 'ScalarTypeEnum.URL',\n 'string:uuid': 'ScalarTypeEnum.ID',\n};\n\n/**\n * TypeScript type representation for code generation.\n */\nexport interface TypescriptType {\n /** The type expression (e.g., \"string\", \"number\", \"MyModel\") */\n type: string;\n /** Whether the type is optional */\n optional: boolean;\n /** Whether the type is an array */\n array: boolean;\n /** Whether this is a primitive type */\n primitive: boolean;\n /** Description for documentation */\n description?: string;\n /** Whether this type is a reference to another schema (needs import) vs inline */\n isReference?: boolean;\n}\n\n/**\n * SchemaModel field representation for code generation.\n */\nexport interface SchemaField {\n /** Field name */\n name: string;\n /** Field type */\n type: TypescriptType;\n /** Scalar type enum value (for FieldType) */\n scalarType?: string;\n /** Enum values if this is an enum type */\n enumValues?: string[];\n /** Nested model if this is an object type */\n nestedModel?: GeneratedModel;\n}\n\n/**\n * Generated model representation.\n */\nexport interface GeneratedModel {\n /** Model name (PascalCase) */\n name: string;\n /** Model description */\n description?: string;\n /** Fields */\n fields: SchemaField[];\n /** Generated TypeScript code */\n code: string;\n /** Required imports */\n imports?: string[];\n}\n\n/**\n * Check if a schema is a reference object.\n */\nfunction isReference(schema: OpenApiSchema): schema is { $ref: string } {\n return typeof schema === 'object' && schema !== null && '$ref' in schema;\n}\n\n/**\n * Extract type name from a $ref.\n */\nfunction typeNameFromRef(ref: string): string {\n const parts = ref.split('/');\n return parts[parts.length - 1] ?? 'Unknown';\n}\n\n/**\n * Convert a JSON Schema to a TypeScript type representation.\n */\nexport function jsonSchemaToType(\n schema: OpenApiSchema,\n name?: string\n): TypescriptType {\n if (isReference(schema)) {\n return {\n type: toPascalCase(typeNameFromRef(schema.$ref)),\n optional: false,\n array: false,\n primitive: false,\n isReference: true,\n };\n }\n\n const schemaObj = schema as Record<string, unknown>;\n const type = schemaObj['type'] as string | undefined;\n const format = schemaObj['format'] as string | undefined;\n const nullable = schemaObj['nullable'] as boolean | undefined;\n\n // Check if this schema was dereferenced from a $ref - use the original type name\n const originalTypeName = schemaObj['_originalTypeName'] as string | undefined;\n if (originalTypeName) {\n return {\n type: toPascalCase(originalTypeName),\n optional: nullable ?? false,\n array: false,\n primitive: false,\n isReference: true,\n };\n }\n\n // Handle arrays\n if (type === 'array') {\n const items = schemaObj['items'] as OpenApiSchema | undefined;\n if (items) {\n const itemType = jsonSchemaToType(items, name);\n return {\n ...itemType,\n array: true,\n optional: nullable ?? false,\n };\n }\n return {\n type: 'unknown',\n optional: nullable ?? false,\n array: true,\n primitive: false,\n isReference: true,\n };\n }\n\n // Handle objects\n if (type === 'object' || schemaObj['properties']) {\n return {\n type: name ? toPascalCase(name) : 'Record<string, unknown>',\n optional: nullable ?? false,\n array: false,\n primitive: false,\n isReference: true,\n };\n }\n\n // Handle enums\n if (schemaObj['enum']) {\n return {\n type: name ? toPascalCase(name) : 'string',\n optional: nullable ?? false,\n array: false,\n primitive: false,\n isReference: true,\n };\n }\n\n // Handle primitives\n const scalarKey = format ? `${type}:${format}` : type;\n if (scalarKey === 'string') {\n return {\n type: 'string',\n optional: nullable ?? false,\n array: false,\n primitive: true,\n };\n }\n if (scalarKey === 'integer' || type === 'number') {\n return {\n type: 'number',\n optional: nullable ?? false,\n array: false,\n primitive: true,\n };\n }\n if (scalarKey === 'boolean') {\n return {\n type: 'boolean',\n optional: nullable ?? false,\n array: false,\n primitive: true,\n };\n }\n\n // Default to unknown\n return {\n type: 'unknown',\n optional: nullable ?? false,\n array: false,\n primitive: false,\n isReference: true,\n };\n}\n\n/**\n * Get the ScalarTypeEnum value for a JSON Schema type.\n */\nexport function getScalarType(schema: OpenApiSchema): string | undefined {\n if (isReference(schema)) {\n return undefined;\n }\n\n const schemaObj = schema as Record<string, unknown>;\n const type = schemaObj['type'] as string | undefined;\n const format = schemaObj['format'] as string | undefined;\n\n if (!type) return undefined;\n\n // For arrays, get the scalar type of the items\n if (type === 'array') {\n const items = schemaObj['items'] as OpenApiSchema | undefined;\n if (items) {\n return getScalarType(items);\n }\n return undefined;\n }\n\n const key = format ? `${type}:${format}` : type;\n return JSON_SCHEMA_TO_SCALAR[key] ?? JSON_SCHEMA_TO_SCALAR[type] ?? undefined;\n}\n\n/**\n * Generate code for a schema model using the specified format.\n */\nexport function generateSchemaModelCode(\n schema: OpenApiSchema,\n modelName: string,\n indent = 0,\n schemaFormat: SchemaFormat = 'contractspec',\n config?: ContractsrcConfig\n): GeneratedModel {\n const generator = createSchemaGenerator(schemaFormat, config);\n const result = generator.generateModel(schema, modelName, {\n description: (schema as Record<string, unknown>)['description'] as string,\n });\n\n return {\n name: result.name,\n description: (schema as Record<string, unknown>)['description'] as string,\n fields: [], // fields are processed internally by generators now\n code: result.code,\n imports: result.imports,\n };\n}\n\n/**\n * Generate import statements for a SchemaModel.\n */\nexport function generateImports(\n fields: SchemaField[],\n options: ContractsrcConfig,\n sameDirectory = true\n): string {\n const imports = new Set<string>();\n const modelsDir = sameDirectory ? '.' : `../${options.conventions.models}`;\n\n imports.add(\n \"import { defineSchemaModel, ScalarTypeEnum, EnumType } from '@lssm/lib.schema';\"\n );\n\n for (const field of fields) {\n // Only import fields that are actual references to other schemas (not inline types)\n if (\n field.type.isReference &&\n !field.type.primitive &&\n !field.enumValues &&\n !field.scalarType &&\n !field.nestedModel\n ) {\n // This is a reference to another schema model\n const modelName = field.type.type;\n const kebabName = modelName\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase();\n imports.add(`import { ${modelName} } from '${modelsDir}/${kebabName}';`);\n }\n }\n\n return Array.from(imports).join('\\n');\n}\n"],"mappings":"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"}