@lssm/lib.contracts-transformers 0.0.0-canary-20251221114240 → 0.0.0-canary-20251221144710

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.
Files changed (53) hide show
  1. package/dist/common/types.d.ts +2 -0
  2. package/dist/common/types.d.ts.map +1 -1
  3. package/dist/index.d.ts +10 -2
  4. package/dist/index.js +10 -2
  5. package/dist/openapi/exporter/data-views.d.ts +38 -0
  6. package/dist/openapi/exporter/data-views.d.ts.map +1 -0
  7. package/dist/openapi/exporter/data-views.js +47 -0
  8. package/dist/openapi/exporter/data-views.js.map +1 -0
  9. package/dist/openapi/exporter/events.d.ts +28 -0
  10. package/dist/openapi/exporter/events.d.ts.map +1 -0
  11. package/dist/openapi/exporter/events.js +39 -0
  12. package/dist/openapi/exporter/events.js.map +1 -0
  13. package/dist/openapi/exporter/features.d.ts +37 -0
  14. package/dist/openapi/exporter/features.d.ts.map +1 -0
  15. package/dist/openapi/exporter/features.js +46 -0
  16. package/dist/openapi/exporter/features.js.map +1 -0
  17. package/dist/openapi/exporter/forms.d.ts +30 -0
  18. package/dist/openapi/exporter/forms.d.ts.map +1 -0
  19. package/dist/openapi/exporter/forms.js +49 -0
  20. package/dist/openapi/exporter/forms.js.map +1 -0
  21. package/dist/openapi/exporter/index.js +8 -0
  22. package/dist/openapi/exporter/operations.d.ts +65 -0
  23. package/dist/openapi/exporter/operations.d.ts.map +1 -0
  24. package/dist/openapi/exporter/operations.js +142 -0
  25. package/dist/openapi/exporter/operations.js.map +1 -0
  26. package/dist/openapi/exporter/presentations.d.ts +48 -0
  27. package/dist/openapi/exporter/presentations.d.ts.map +1 -0
  28. package/dist/openapi/exporter/presentations.js +66 -0
  29. package/dist/openapi/exporter/presentations.js.map +1 -0
  30. package/dist/openapi/exporter/registries.d.ts +23 -0
  31. package/dist/openapi/exporter/registries.d.ts.map +1 -0
  32. package/dist/openapi/exporter/registries.js +29 -0
  33. package/dist/openapi/exporter/registries.js.map +1 -0
  34. package/dist/openapi/exporter/workflows.d.ts +36 -0
  35. package/dist/openapi/exporter/workflows.d.ts.map +1 -0
  36. package/dist/openapi/exporter/workflows.js +54 -0
  37. package/dist/openapi/exporter/workflows.js.map +1 -0
  38. package/dist/openapi/exporter.d.ts +29 -9
  39. package/dist/openapi/exporter.d.ts.map +1 -1
  40. package/dist/openapi/exporter.js +76 -102
  41. package/dist/openapi/exporter.js.map +1 -1
  42. package/dist/openapi/importer/grouping.js +73 -0
  43. package/dist/openapi/importer/grouping.js.map +1 -0
  44. package/dist/openapi/importer/index.d.ts.map +1 -1
  45. package/dist/openapi/importer/index.js +7 -0
  46. package/dist/openapi/importer/index.js.map +1 -1
  47. package/dist/openapi/index.d.ts +10 -2
  48. package/dist/openapi/index.js +11 -2
  49. package/dist/openapi/schema-converter.d.ts.map +1 -1
  50. package/dist/openapi/schema-converter.js.map +1 -1
  51. package/dist/openapi/types.d.ts +62 -1
  52. package/dist/openapi/types.d.ts.map +1 -1
  53. package/package.json +5 -5
@@ -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 = 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>","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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"}
@@ -210,7 +210,68 @@ interface ContractSpecOpenApiDocument {
210
210
  components: {
211
211
  schemas: Record<string, Record<string, unknown>>;
212
212
  };
213
+ /** ContractSpec extensions for features */
214
+ 'x-contractspec-features'?: unknown[];
215
+ /** ContractSpec extensions for events */
216
+ 'x-contractspec-events'?: unknown[];
217
+ /** ContractSpec extensions for presentations */
218
+ 'x-contractspec-presentations'?: unknown[];
219
+ /** ContractSpec extensions for forms */
220
+ 'x-contractspec-forms'?: unknown[];
221
+ /** ContractSpec extensions for data views */
222
+ 'x-contractspec-dataviews'?: unknown[];
223
+ /** ContractSpec extensions for workflows */
224
+ 'x-contractspec-workflows'?: unknown[];
225
+ }
226
+ /**
227
+ * Unified export options for all ContractSpec surfaces.
228
+ */
229
+ interface ContractSpecExportOptions extends OpenApiExportOptions {
230
+ /** Include operations in export (default: true) */
231
+ operations?: boolean;
232
+ /** Include events in export (default: true) */
233
+ events?: boolean;
234
+ /** Include features in export (default: true) */
235
+ features?: boolean;
236
+ /** Include presentations (V1 and V2) in export (default: true) */
237
+ presentations?: boolean;
238
+ /** Include forms in export (default: true) */
239
+ forms?: boolean;
240
+ /** Include data views in export (default: true) */
241
+ dataViews?: boolean;
242
+ /** Include workflows in export (default: true) */
243
+ workflows?: boolean;
244
+ /** Generate TypeScript registry code (default: true) */
245
+ generateRegistries?: boolean;
246
+ }
247
+ /**
248
+ * Generated registry code for a specific surface.
249
+ */
250
+ interface GeneratedRegistryCode {
251
+ /** The generated TypeScript code */
252
+ code: string;
253
+ /** Suggested filename for the registry */
254
+ fileName: string;
255
+ }
256
+ /**
257
+ * Result of unified ContractSpec export.
258
+ */
259
+ interface ContractSpecExportResult {
260
+ /** OpenAPI document with ContractSpec extensions */
261
+ openApi: ContractSpecOpenApiDocument;
262
+ /** Generated TypeScript code for registries */
263
+ registries?: {
264
+ operations?: GeneratedRegistryCode;
265
+ events?: GeneratedRegistryCode;
266
+ features?: GeneratedRegistryCode;
267
+ presentations?: GeneratedRegistryCode;
268
+ forms?: GeneratedRegistryCode;
269
+ dataViews?: GeneratedRegistryCode;
270
+ workflows?: GeneratedRegistryCode;
271
+ /** Index file that re-exports all registries */
272
+ index?: GeneratedRegistryCode;
273
+ };
213
274
  }
214
275
  //#endregion
215
- export { ContractSpecOpenApiDocument, HttpMethod, OpenApiDocument, OpenApiExportOptions, OpenApiOperation, OpenApiParameter, OpenApiParseOptions, OpenApiSchema, OpenApiServer, OpenApiSource, OpenApiTransportHints, OpenApiVersion, ParameterLocation, ParseResult, ParsedOperation, ParsedParameter };
276
+ export { ContractSpecExportOptions, ContractSpecExportResult, ContractSpecOpenApiDocument, GeneratedRegistryCode, HttpMethod, OpenApiDocument, OpenApiExportOptions, OpenApiOperation, OpenApiParameter, OpenApiParseOptions, OpenApiSchema, OpenApiServer, OpenApiSource, OpenApiTransportHints, OpenApiVersion, ParameterLocation, ParseResult, ParsedOperation, ParsedParameter };
216
277
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/openapi/types.ts"],"sourcesContent":[],"mappings":";;;;;;AAiDA;;AAEI,KA5BQ,cAAA,GA4BI,KAAA,GAAA,KAAA;;;;AAOJ,KA9BA,eAAA,GAAkB,SAAA,CAAU,QA8BlB,GA9B6B,WAAA,CAAY,QA8BzC;AAatB;AAKA;AAgBA;AAgBiB,KA3EL,gBAAA,GACR,SAAA,CAAU,eA0EsB,GAzEhC,WAAA,CAAY,eAyEoB;AAYpC;;;AAgBe,KAhGH,aAAA,GACR,SAAA,CAAU,YA+FC,GA9FX,WAAA,CAAY,YA8FD,GA7FX,SAAA,CAAU,eA6FC,GA5FX,WAAA,CAAY,eA4FD;;;;AAgBA,KAvGH,gBAAA,GACR,SAAA,CAAU,eAsGC,GArGX,WAAA,CAAY,eAqGD,GApGX,SAAA,CAAU,eAoGC,GAnGX,WAAA,CAAY,eAmGD;;;;AAmBE,KAjHL,UAAA,GAiHoB,KAAA,GAAA,MAI1B,GAAA,KAAA,GAAA,QAMI,GAAA,OAAa,GAAA,MAAA,GAAA,SAAA,GAAA,OAAA;AAQvB;;;AAYc,KAlIF,iBAAA,GAkIE,MAAA,GAAA,OAAA,GAAA,QAAA,GAAA,QAAA;;;;AAQJ,UArIO,aAAA,CAqIP;EAAW,GAAA,EAAA,MAAA;EAMJ,WAAA,CAAA,EAAW,MAAA;EAYX,SAAA,CAAA,EApJH,MAoJG,CAAA,MAAsB,EAAA;IAgBtB,OAAA,EAAA,MAAc;IAYd,IAAA,CAAA,EAAA,MAAA,EAAA;IAOL,WAAA,CAAA,EAAA,MAAA;EACY,CAAA,CAAA;;;;;UA3KP,oBAAA;;;;;;;;YAQL;;eAEG;;;;;UAME,mBAAA;;;;;;;;;;;UAYA,eAAA;;;;UAIP;;;;;;;;;;cAUI;;eAEC;;gBAEC;;gBAEA;;;;YAIJ;;;;aAIC;;aAIE;;;;;;aAOF;;;;;;;;;;;UAYI,eAAA;;;;MAIX;;;;;;UAMI;;;;;;;UAQO,WAAA;;YAEL;;WAED;;;;;;;;cAQG;;WAEH,eAAe;;WAEf;;;;UAID;;;;;UAMO,WAAA;;;;;;WAMN;;;;;UAMM,qBAAA,SAA8B;;;;;;;;;;;;;;;UAgB9B,aAAA,SAAsB;;;kBAGrB;;;;;;;;UASD,2BAAA;;;;;;;YAOL;SACH,eAAe;;aAEX,eAAe"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/openapi/types.ts"],"sourcesContent":[],"mappings":";;;;;;AAiDA;;AAEI,KA5BQ,cAAA,GA4BI,KAAA,GAAA,KAAA;;;;AAOJ,KA9BA,eAAA,GAAkB,SAAA,CAAU,QA8BlB,GA9B6B,WAAA,CAAY,QA8BzC;AAatB;AAKA;AAgBA;AAgBiB,KA3EL,gBAAA,GACR,SAAA,CAAU,eA0EsB,GAzEhC,WAAA,CAAY,eAyEoB;AAYpC;;;AAgBe,KAhGH,aAAA,GACR,SAAA,CAAU,YA+FC,GA9FX,WAAA,CAAY,YA8FD,GA7FX,SAAA,CAAU,eA6FC,GA5FX,WAAA,CAAY,eA4FD;;;;AAgBA,KAvGH,gBAAA,GACR,SAAA,CAAU,eAsGC,GArGX,WAAA,CAAY,eAqGD,GApGX,SAAA,CAAU,eAoGC,GAnGX,WAAA,CAAY,eAmGD;;;;AAmBE,KAjHL,UAAA,GAiHoB,KAAA,GAAA,MAI1B,GAAA,KAAA,GAAA,QAMI,GAAA,OAAa,GAAA,MAAA,GAAA,SAAA,GAAA,OAAA;AAQvB;;;AAYc,KAlIF,iBAAA,GAkIE,MAAA,GAAA,OAAA,GAAA,QAAA,GAAA,QAAA;;;;AAQJ,UArIO,aAAA,CAqIP;EAAW,GAAA,EAAA,MAAA;EAMJ,WAAA,CAAA,EAAW,MAAA;EAYX,SAAA,CAAA,EApJH,MAoJG,CAAA,MAAsB,EAAA;IAgBtB,OAAA,EAAA,MAAc;IAYd,IAAA,CAAA,EAAA,MAAA,EAAA;IAOL,WAAA,CAAA,EAAA,MAAA;EACY,CAAA,CAAA;;;;;AAqBP,UAhMA,oBAAA,CAgM0B;EAsB1B;EAUA,KAAA,CAAA,EAAA,MAAA;EAEN;EAGM,OAAA,CAAA,EAAA,MAAA;EACJ;EACE,WAAA,CAAA,EAAA,MAAA;EACK;EACR,OAAA,CAAA,EAjOA,aAiOA,EAAA;EACI;EACA,UAAA,CAAA,EAjOD,MAiOC,CAAA,MAAA,EAAA,OAAA,CAAA;;;;;UA3NC,mBAAA;;;;;;;;;;;UAYA,eAAA;;;;UAIP;;;;;;;;;;cAUI;;eAEC;;gBAEC;;gBAEA;;;;YAIJ;;;;aAIC;;aAIE;;;;;;aAOF;;;;;;;;;;;UAYI,eAAA;;;;MAIX;;;;;;UAMI;;;;;;;UAQO,WAAA;;YAEL;;WAED;;;;;;;;cAQG;;WAEH,eAAe;;WAEf;;;;UAID;;;;;UAMO,WAAA;;;;;;WAMN;;;;;UAMM,qBAAA,SAA8B;;;;;;;;;;;;;;;UAgB9B,aAAA,SAAsB;;;kBAGrB;;;;;;;;UASD,2BAAA;;;;;;;YAOL;SACH,eAAe;;aAEX,eAAe;;;;;;;;;;;;;;;;;;UAmBX,yBAAA,SAAkC;;;;;;;;;;;;;;;;;;;;;UAsBlC,qBAAA;;;;;;;;;UAUA,wBAAA;;WAEN;;;iBAGM;aACJ;eACE;oBACK;YACR;gBACI;gBACA;;YAEJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lssm/lib.contracts-transformers",
3
- "version": "0.0.0-canary-20251221114240",
3
+ "version": "0.0.0-canary-20251221144710",
4
4
  "description": "Contract format transformations: import/export between ContractSpec and external formats (OpenAPI, AsyncAPI, etc.)",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -17,15 +17,15 @@
17
17
  "test": "bun test"
18
18
  },
19
19
  "dependencies": {
20
- "@lssm/lib.contracts": "0.0.0-canary-20251221114240",
21
- "@lssm/lib.schema": "0.0.0-canary-20251221114240",
20
+ "@lssm/lib.contracts": "0.0.0-canary-20251221144710",
21
+ "@lssm/lib.schema": "0.0.0-canary-20251221144710",
22
22
  "openapi-types": "^12.1.3",
23
23
  "yaml": "^2.7.1",
24
24
  "zod": "^4.1.13"
25
25
  },
26
26
  "devDependencies": {
27
- "@lssm/tool.tsdown": "0.0.0-canary-20251221114240",
28
- "@lssm/tool.typescript": "0.0.0-canary-20251221114240",
27
+ "@lssm/tool.tsdown": "0.0.0-canary-20251221144710",
28
+ "@lssm/tool.typescript": "0.0.0-canary-20251221144710",
29
29
  "tsdown": "^0.18.1",
30
30
  "typescript": "^5.9.3"
31
31
  },