@lssm/lib.contracts-transformers 0.0.0-canary-20251220041653 → 0.0.0-canary-20251221132705
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 +2 -2
- package/dist/common/index.d.ts +2 -2
- package/dist/common/types.d.ts +16 -10
- package/dist/common/types.d.ts.map +1 -1
- package/dist/index.d.ts +15 -6
- package/dist/index.js +13 -4
- package/dist/openapi/differ.d.ts +6 -6
- package/dist/openapi/differ.d.ts.map +1 -1
- package/dist/openapi/differ.js +11 -4
- package/dist/openapi/differ.js.map +1 -1
- package/dist/openapi/exporter/data-views.d.ts +38 -0
- package/dist/openapi/exporter/data-views.d.ts.map +1 -0
- package/dist/openapi/exporter/data-views.js +47 -0
- package/dist/openapi/exporter/data-views.js.map +1 -0
- package/dist/openapi/exporter/events.d.ts +28 -0
- package/dist/openapi/exporter/events.d.ts.map +1 -0
- package/dist/openapi/exporter/events.js +39 -0
- package/dist/openapi/exporter/events.js.map +1 -0
- package/dist/openapi/exporter/features.d.ts +37 -0
- package/dist/openapi/exporter/features.d.ts.map +1 -0
- package/dist/openapi/exporter/features.js +46 -0
- package/dist/openapi/exporter/features.js.map +1 -0
- package/dist/openapi/exporter/forms.d.ts +30 -0
- package/dist/openapi/exporter/forms.d.ts.map +1 -0
- package/dist/openapi/exporter/forms.js +49 -0
- package/dist/openapi/exporter/forms.js.map +1 -0
- package/dist/openapi/exporter/index.js +8 -0
- package/dist/openapi/exporter/operations.d.ts +65 -0
- package/dist/openapi/exporter/operations.d.ts.map +1 -0
- package/dist/openapi/exporter/operations.js +142 -0
- package/dist/openapi/exporter/operations.js.map +1 -0
- package/dist/openapi/exporter/presentations.d.ts +48 -0
- package/dist/openapi/exporter/presentations.d.ts.map +1 -0
- package/dist/openapi/exporter/presentations.js +66 -0
- package/dist/openapi/exporter/presentations.js.map +1 -0
- package/dist/openapi/exporter/registries.d.ts +23 -0
- package/dist/openapi/exporter/registries.d.ts.map +1 -0
- package/dist/openapi/exporter/registries.js +29 -0
- package/dist/openapi/exporter/registries.js.map +1 -0
- package/dist/openapi/exporter/workflows.d.ts +36 -0
- package/dist/openapi/exporter/workflows.d.ts.map +1 -0
- package/dist/openapi/exporter/workflows.js +54 -0
- package/dist/openapi/exporter/workflows.js.map +1 -0
- package/dist/openapi/exporter.d.ts +35 -15
- package/dist/openapi/exporter.d.ts.map +1 -1
- package/dist/openapi/exporter.js +78 -104
- package/dist/openapi/exporter.js.map +1 -1
- package/dist/openapi/importer/analyzer.js +28 -0
- package/dist/openapi/importer/analyzer.js.map +1 -0
- package/dist/openapi/importer/events.js +36 -0
- package/dist/openapi/importer/events.js.map +1 -0
- package/dist/openapi/importer/generator.js +71 -0
- package/dist/openapi/importer/generator.js.map +1 -0
- package/dist/openapi/importer/grouping.js +73 -0
- package/dist/openapi/importer/grouping.js.map +1 -0
- package/dist/openapi/importer/index.d.ts +17 -0
- package/dist/openapi/importer/index.d.ts.map +1 -0
- package/dist/openapi/importer/index.js +161 -0
- package/dist/openapi/importer/index.js.map +1 -0
- package/dist/openapi/importer/models.js +19 -0
- package/dist/openapi/importer/models.js.map +1 -0
- package/dist/openapi/importer/schemas.js +80 -0
- package/dist/openapi/importer/schemas.js.map +1 -0
- package/dist/openapi/index.d.ts +14 -5
- package/dist/openapi/index.js +15 -4
- package/dist/openapi/parser/document.d.ts +20 -0
- package/dist/openapi/parser/document.d.ts.map +1 -0
- package/dist/openapi/parser/document.js +95 -0
- package/dist/openapi/parser/document.js.map +1 -0
- package/dist/openapi/parser/index.js +5 -0
- package/dist/openapi/parser/operation.js +59 -0
- package/dist/openapi/parser/operation.js.map +1 -0
- package/dist/openapi/parser/parameters.js +37 -0
- package/dist/openapi/parser/parameters.js.map +1 -0
- package/dist/openapi/parser/resolvers.js +63 -0
- package/dist/openapi/parser/resolvers.js.map +1 -0
- package/dist/openapi/parser/utils.d.ts +19 -0
- package/dist/openapi/parser/utils.d.ts.map +1 -0
- package/dist/openapi/parser/utils.js +48 -0
- package/dist/openapi/parser/utils.js.map +1 -0
- package/dist/openapi/parser.js +6 -232
- package/dist/openapi/schema-converter.d.ts +7 -1
- package/dist/openapi/schema-converter.d.ts.map +1 -1
- package/dist/openapi/schema-converter.js +117 -20
- package/dist/openapi/schema-converter.js.map +1 -1
- package/dist/openapi/types.d.ts +75 -20
- package/dist/openapi/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/dist/openapi/importer.d.ts +0 -16
- package/dist/openapi/importer.d.ts.map +0 -1
- package/dist/openapi/importer.js +0 -265
- package/dist/openapi/importer.js.map +0 -1
- package/dist/openapi/parser.d.ts +0 -32
- package/dist/openapi/parser.d.ts.map +0 -1
- package/dist/openapi/parser.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-converter.js","names":["JSON_SCHEMA_TO_SCALAR: Record<string, string>","enumValues: string[] | undefined","fields: SchemaField[]","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';\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}\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',\n integer: 'ScalarTypeEnum.INT',\n number: 'ScalarTypeEnum.FLOAT',\n boolean: 'ScalarTypeEnum.BOOLEAN',\n // Special formats\n 'string:date': 'ScalarTypeEnum.DATE',\n 'string:date-time': 'ScalarTypeEnum.DATE_TIME',\n 'string:email': 'ScalarTypeEnum.EMAIL',\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 };\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 // 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 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 if (!properties) {\n // No properties - generate an empty model or type alias\n return {\n name: toPascalCase(modelName),\n description,\n fields: [],\n code: `${spaces}// Empty schema for ${modelName}`,\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 lines.push(\n `${spaces} type: new EnumType([${field.enumValues.map((v) => `'${v}'`).join(', ')}]),`\n );\n } else if (field.scalarType) {\n // Scalar type\n lines.push(`${spaces} type: ${field.scalarType},`);\n } else {\n // Nested model or reference\n lines.push(\n `${spaces} type: ${field.type.type}, // TODO: Define or import this type`\n );\n }\n\n // Optional\n if (field.type.optional) {\n lines.push(`${spaces} isOptional: true,`);\n }\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 */\nexport function generateImports(fields: SchemaField[]): string {\n const imports = new Set<string>();\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 (!field.type.primitive && !field.enumValues && !field.scalarType) {\n // This is a reference to another model - would need import\n // imports.add(`import { ${field.type.type} } from './${toKebabCase(field.type.type)}';`);\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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"}
|
package/dist/openapi/types.d.ts
CHANGED
|
@@ -58,25 +58,6 @@ interface OpenApiExportOptions {
|
|
|
58
58
|
/** Additional OpenAPI extensions */
|
|
59
59
|
extensions?: Record<string, unknown>;
|
|
60
60
|
}
|
|
61
|
-
/**
|
|
62
|
-
* Options for importing from OpenAPI.
|
|
63
|
-
*/
|
|
64
|
-
interface OpenApiImportOptions {
|
|
65
|
-
/** Prefix for generated spec names */
|
|
66
|
-
prefix?: string;
|
|
67
|
-
/** Only import operations with these tags */
|
|
68
|
-
tags?: string[];
|
|
69
|
-
/** Exclude operations with these operationIds */
|
|
70
|
-
exclude?: string[];
|
|
71
|
-
/** Include operations with these operationIds (overrides exclude) */
|
|
72
|
-
include?: string[];
|
|
73
|
-
/** Default stability for imported specs */
|
|
74
|
-
defaultStability?: 'experimental' | 'beta' | 'stable' | 'deprecated';
|
|
75
|
-
/** Default owners for imported specs */
|
|
76
|
-
defaultOwners?: string[];
|
|
77
|
-
/** Default auth level for imported specs */
|
|
78
|
-
defaultAuth?: 'anonymous' | 'user' | 'admin';
|
|
79
|
-
}
|
|
80
61
|
/**
|
|
81
62
|
* Options for parsing OpenAPI documents.
|
|
82
63
|
*/
|
|
@@ -174,6 +155,19 @@ interface ParseResult {
|
|
|
174
155
|
servers: OpenApiServer[];
|
|
175
156
|
/** Parse warnings */
|
|
176
157
|
warnings: string[];
|
|
158
|
+
/** Parsed events (webhooks) */
|
|
159
|
+
events: ParsedEvent[];
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Parsed event (webhook).
|
|
163
|
+
*/
|
|
164
|
+
interface ParsedEvent {
|
|
165
|
+
/** Event name */
|
|
166
|
+
name: string;
|
|
167
|
+
/** Event description */
|
|
168
|
+
description?: string;
|
|
169
|
+
/** Event payload schema */
|
|
170
|
+
payload: OpenApiSchema;
|
|
177
171
|
}
|
|
178
172
|
/**
|
|
179
173
|
* OpenAPI-specific transport hints.
|
|
@@ -216,7 +210,68 @@ interface ContractSpecOpenApiDocument {
|
|
|
216
210
|
components: {
|
|
217
211
|
schemas: Record<string, Record<string, unknown>>;
|
|
218
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
|
+
};
|
|
219
274
|
}
|
|
220
275
|
//#endregion
|
|
221
|
-
export { ContractSpecOpenApiDocument, HttpMethod, OpenApiDocument, OpenApiExportOptions,
|
|
276
|
+
export { ContractSpecExportOptions, ContractSpecExportResult, ContractSpecOpenApiDocument, GeneratedRegistryCode, HttpMethod, OpenApiDocument, OpenApiExportOptions, OpenApiOperation, OpenApiParameter, OpenApiParseOptions, OpenApiSchema, OpenApiServer, OpenApiSource, OpenApiTransportHints, OpenApiVersion, ParameterLocation, ParseResult, ParsedOperation, ParsedParameter };
|
|
222
277
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/openapi/types.ts"],"sourcesContent":[],"mappings":"
|
|
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-
|
|
3
|
+
"version": "0.0.0-canary-20251221132705",
|
|
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-
|
|
21
|
-
"@lssm/lib.schema": "0.0.0-canary-
|
|
20
|
+
"@lssm/lib.contracts": "0.0.0-canary-20251221132705",
|
|
21
|
+
"@lssm/lib.schema": "0.0.0-canary-20251221132705",
|
|
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-
|
|
28
|
-
"@lssm/tool.typescript": "0.0.0-canary-
|
|
27
|
+
"@lssm/tool.tsdown": "0.0.0-canary-20251221132705",
|
|
28
|
+
"@lssm/tool.typescript": "0.0.0-canary-20251221132705",
|
|
29
29
|
"tsdown": "^0.18.1",
|
|
30
30
|
"typescript": "^5.9.3"
|
|
31
31
|
},
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { ImportResult } from "../common/types.js";
|
|
2
|
-
import { OpenApiImportOptions, ParseResult, ParsedOperation } from "./types.js";
|
|
3
|
-
|
|
4
|
-
//#region src/openapi/importer.d.ts
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Import operations from a parsed OpenAPI document.
|
|
8
|
-
*/
|
|
9
|
-
declare function importFromOpenApi(parseResult: ParseResult, options?: OpenApiImportOptions): ImportResult;
|
|
10
|
-
/**
|
|
11
|
-
* Import a single operation to ContractSpec code.
|
|
12
|
-
*/
|
|
13
|
-
declare function importOperation(operation: ParsedOperation, options?: OpenApiImportOptions): string;
|
|
14
|
-
//#endregion
|
|
15
|
-
export { importFromOpenApi, importOperation };
|
|
16
|
-
//# sourceMappingURL=importer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"importer.d.ts","names":[],"sources":["../../src/openapi/importer.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAyagB,iBAjIA,iBAAA,CAkIH,WACF,EAlII,WAkIJ,EAAA,OAAyB,CAAA,EAjIzB,oBAiIyB,CAAA,EAhIjC,YAgIiC;;;;iBAFpB,eAAA,YACH,2BACF"}
|
package/dist/openapi/importer.js
DELETED
|
@@ -1,265 +0,0 @@
|
|
|
1
|
-
import { toFileName, toPascalCase, toSpecName, toValidIdentifier } from "../common/utils.js";
|
|
2
|
-
import { generateImports, generateSchemaModelCode } from "./schema-converter.js";
|
|
3
|
-
|
|
4
|
-
//#region src/openapi/importer.ts
|
|
5
|
-
/**
|
|
6
|
-
* HTTP methods that typically indicate a command (state-changing).
|
|
7
|
-
*/
|
|
8
|
-
const COMMAND_METHODS = [
|
|
9
|
-
"post",
|
|
10
|
-
"put",
|
|
11
|
-
"delete",
|
|
12
|
-
"patch"
|
|
13
|
-
];
|
|
14
|
-
/**
|
|
15
|
-
* Determine if an operation is a command or query based on HTTP method.
|
|
16
|
-
*/
|
|
17
|
-
function inferOpKind(method) {
|
|
18
|
-
return COMMAND_METHODS.includes(method.toLowerCase()) ? "command" : "query";
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Determine auth level based on security requirements.
|
|
22
|
-
*/
|
|
23
|
-
function inferAuthLevel(operation, defaultAuth) {
|
|
24
|
-
if (!operation.security || operation.security.length === 0) return defaultAuth;
|
|
25
|
-
for (const sec of operation.security) if (Object.keys(sec).length === 0) return "anonymous";
|
|
26
|
-
return "user";
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Build a merged input schema from all parameter sources.
|
|
30
|
-
*/
|
|
31
|
-
function buildInputSchema(operation) {
|
|
32
|
-
const fields = [];
|
|
33
|
-
for (const param of operation.pathParams) fields.push({
|
|
34
|
-
name: param.name,
|
|
35
|
-
schema: param.schema,
|
|
36
|
-
required: true
|
|
37
|
-
});
|
|
38
|
-
for (const param of operation.queryParams) fields.push({
|
|
39
|
-
name: param.name,
|
|
40
|
-
schema: param.schema,
|
|
41
|
-
required: param.required
|
|
42
|
-
});
|
|
43
|
-
const excludedHeaders = [
|
|
44
|
-
"authorization",
|
|
45
|
-
"content-type",
|
|
46
|
-
"accept",
|
|
47
|
-
"user-agent"
|
|
48
|
-
];
|
|
49
|
-
for (const param of operation.headerParams) if (!excludedHeaders.includes(param.name.toLowerCase())) fields.push({
|
|
50
|
-
name: param.name,
|
|
51
|
-
schema: param.schema,
|
|
52
|
-
required: param.required
|
|
53
|
-
});
|
|
54
|
-
if (operation.requestBody?.schema) {
|
|
55
|
-
const bodySchema = operation.requestBody.schema;
|
|
56
|
-
if (!("$ref" in bodySchema)) {
|
|
57
|
-
const schemaObj = bodySchema;
|
|
58
|
-
const properties = schemaObj["properties"];
|
|
59
|
-
const required = schemaObj["required"] ?? [];
|
|
60
|
-
if (properties) for (const [propName, propSchema] of Object.entries(properties)) fields.push({
|
|
61
|
-
name: propName,
|
|
62
|
-
schema: propSchema,
|
|
63
|
-
required: required.includes(propName)
|
|
64
|
-
});
|
|
65
|
-
} else fields.push({
|
|
66
|
-
name: "body",
|
|
67
|
-
schema: bodySchema,
|
|
68
|
-
required: operation.requestBody.required
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
if (fields.length === 0) return {
|
|
72
|
-
schema: null,
|
|
73
|
-
fields: []
|
|
74
|
-
};
|
|
75
|
-
return {
|
|
76
|
-
schema: {
|
|
77
|
-
type: "object",
|
|
78
|
-
properties: fields.reduce((acc, f) => {
|
|
79
|
-
acc[f.name] = f.schema;
|
|
80
|
-
return acc;
|
|
81
|
-
}, {}),
|
|
82
|
-
required: fields.filter((f) => f.required).map((f) => f.name)
|
|
83
|
-
},
|
|
84
|
-
fields
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Get the output schema from the operation responses.
|
|
89
|
-
*/
|
|
90
|
-
function getOutputSchema(operation) {
|
|
91
|
-
for (const code of [
|
|
92
|
-
"200",
|
|
93
|
-
"201",
|
|
94
|
-
"202",
|
|
95
|
-
"204"
|
|
96
|
-
]) {
|
|
97
|
-
const response = operation.responses[code];
|
|
98
|
-
if (response?.schema) return response.schema;
|
|
99
|
-
}
|
|
100
|
-
for (const [code, response] of Object.entries(operation.responses)) if (code.startsWith("2") && response.schema) return response.schema;
|
|
101
|
-
return null;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Generate ContractSpec TypeScript code for an operation.
|
|
105
|
-
*/
|
|
106
|
-
function generateSpecCode(operation, options, inputModel, outputModel) {
|
|
107
|
-
const specName = toSpecName(operation.operationId, options.prefix);
|
|
108
|
-
const kind = inferOpKind(operation.method);
|
|
109
|
-
const auth = inferAuthLevel(operation, options.defaultAuth ?? "user");
|
|
110
|
-
const lines = [];
|
|
111
|
-
lines.push("import { defineCommand, defineQuery } from '@lssm/lib.contracts';");
|
|
112
|
-
if (inputModel || outputModel) lines.push(generateImports([...inputModel?.fields ?? [], ...outputModel?.fields ?? []]));
|
|
113
|
-
lines.push("");
|
|
114
|
-
if (inputModel && inputModel.code) {
|
|
115
|
-
lines.push("// Input schema");
|
|
116
|
-
lines.push(inputModel.code);
|
|
117
|
-
lines.push("");
|
|
118
|
-
}
|
|
119
|
-
if (outputModel && outputModel.code) {
|
|
120
|
-
lines.push("// Output schema");
|
|
121
|
-
lines.push(outputModel.code);
|
|
122
|
-
lines.push("");
|
|
123
|
-
}
|
|
124
|
-
const defineFunc = kind === "command" ? "defineCommand" : "defineQuery";
|
|
125
|
-
const safeName = toValidIdentifier(toPascalCase(operation.operationId));
|
|
126
|
-
lines.push(`/**`);
|
|
127
|
-
lines.push(` * ${operation.summary ?? operation.operationId}`);
|
|
128
|
-
if (operation.description) {
|
|
129
|
-
lines.push(` *`);
|
|
130
|
-
lines.push(` * ${operation.description}`);
|
|
131
|
-
}
|
|
132
|
-
lines.push(` *`);
|
|
133
|
-
lines.push(` * @source OpenAPI: ${operation.method.toUpperCase()} ${operation.path}`);
|
|
134
|
-
lines.push(` */`);
|
|
135
|
-
lines.push(`export const ${safeName}Spec = ${defineFunc}({`);
|
|
136
|
-
lines.push(" meta: {");
|
|
137
|
-
lines.push(` name: '${specName}',`);
|
|
138
|
-
lines.push(" version: 1,");
|
|
139
|
-
lines.push(` stability: '${options.defaultStability ?? "stable"}',`);
|
|
140
|
-
lines.push(` owners: [${(options.defaultOwners ?? []).map((o) => `'${o}'`).join(", ")}],`);
|
|
141
|
-
lines.push(` tags: [${operation.tags.map((t) => `'${t}'`).join(", ")}],`);
|
|
142
|
-
lines.push(` description: ${JSON.stringify(operation.summary ?? operation.operationId)},`);
|
|
143
|
-
lines.push(` goal: ${JSON.stringify(operation.description ?? "Imported from OpenAPI")},`);
|
|
144
|
-
lines.push(` context: 'Imported from OpenAPI: ${operation.method.toUpperCase()} ${operation.path}',`);
|
|
145
|
-
lines.push(" },");
|
|
146
|
-
lines.push(" io: {");
|
|
147
|
-
if (inputModel) lines.push(` input: ${inputModel.name},`);
|
|
148
|
-
else lines.push(" input: null,");
|
|
149
|
-
if (outputModel) lines.push(` output: ${outputModel.name},`);
|
|
150
|
-
else lines.push(" output: null, // TODO: Define output schema");
|
|
151
|
-
lines.push(" },");
|
|
152
|
-
lines.push(" policy: {");
|
|
153
|
-
lines.push(` auth: '${auth}',`);
|
|
154
|
-
lines.push(" },");
|
|
155
|
-
lines.push(" transport: {");
|
|
156
|
-
lines.push(" rest: {");
|
|
157
|
-
lines.push(` method: '${operation.method.toUpperCase()}',`);
|
|
158
|
-
lines.push(` path: '${operation.path}',`);
|
|
159
|
-
lines.push(" },");
|
|
160
|
-
lines.push(" },");
|
|
161
|
-
lines.push("});");
|
|
162
|
-
return lines.join("\n");
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Import operations from a parsed OpenAPI document.
|
|
166
|
-
*/
|
|
167
|
-
function importFromOpenApi(parseResult, options = {}) {
|
|
168
|
-
const { tags, exclude = [], include } = options;
|
|
169
|
-
const specs = [];
|
|
170
|
-
const skipped = [];
|
|
171
|
-
const errors = [];
|
|
172
|
-
for (const operation of parseResult.operations) {
|
|
173
|
-
if (tags && tags.length > 0) {
|
|
174
|
-
if (!operation.tags.some((t) => tags.includes(t))) {
|
|
175
|
-
skipped.push({
|
|
176
|
-
sourceId: operation.operationId,
|
|
177
|
-
reason: `No matching tags (has: ${operation.tags.join(", ")})`
|
|
178
|
-
});
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
if (include && include.length > 0) {
|
|
183
|
-
if (!include.includes(operation.operationId)) {
|
|
184
|
-
skipped.push({
|
|
185
|
-
sourceId: operation.operationId,
|
|
186
|
-
reason: "Not in include list"
|
|
187
|
-
});
|
|
188
|
-
continue;
|
|
189
|
-
}
|
|
190
|
-
} else if (exclude.includes(operation.operationId)) {
|
|
191
|
-
skipped.push({
|
|
192
|
-
sourceId: operation.operationId,
|
|
193
|
-
reason: "In exclude list"
|
|
194
|
-
});
|
|
195
|
-
continue;
|
|
196
|
-
}
|
|
197
|
-
if (operation.deprecated && options.defaultStability !== "deprecated") {
|
|
198
|
-
skipped.push({
|
|
199
|
-
sourceId: operation.operationId,
|
|
200
|
-
reason: "Deprecated operation"
|
|
201
|
-
});
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
try {
|
|
205
|
-
const { schema: inputSchema } = buildInputSchema(operation);
|
|
206
|
-
const inputModel = inputSchema ? generateSchemaModelCode(inputSchema, `${operation.operationId}Input`) : null;
|
|
207
|
-
const outputSchema = getOutputSchema(operation);
|
|
208
|
-
const code = generateSpecCode(operation, options, inputModel, outputSchema ? generateSchemaModelCode(outputSchema, `${operation.operationId}Output`) : null);
|
|
209
|
-
const fileName = toFileName(toSpecName(operation.operationId, options.prefix));
|
|
210
|
-
const transportHints = { rest: {
|
|
211
|
-
method: operation.method.toUpperCase(),
|
|
212
|
-
path: operation.path,
|
|
213
|
-
params: {
|
|
214
|
-
path: operation.pathParams.map((p) => p.name),
|
|
215
|
-
query: operation.queryParams.map((p) => p.name),
|
|
216
|
-
header: operation.headerParams.map((p) => p.name),
|
|
217
|
-
cookie: operation.cookieParams.map((p) => p.name)
|
|
218
|
-
}
|
|
219
|
-
} };
|
|
220
|
-
const source = {
|
|
221
|
-
type: "openapi",
|
|
222
|
-
sourceId: operation.operationId,
|
|
223
|
-
operationId: operation.operationId,
|
|
224
|
-
openApiVersion: parseResult.version,
|
|
225
|
-
importedAt: /* @__PURE__ */ new Date()
|
|
226
|
-
};
|
|
227
|
-
specs.push({
|
|
228
|
-
spec: {},
|
|
229
|
-
code,
|
|
230
|
-
fileName,
|
|
231
|
-
source,
|
|
232
|
-
transportHints
|
|
233
|
-
});
|
|
234
|
-
} catch (error) {
|
|
235
|
-
errors.push({
|
|
236
|
-
sourceId: operation.operationId,
|
|
237
|
-
error: error instanceof Error ? error.message : String(error)
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
return {
|
|
242
|
-
specs,
|
|
243
|
-
skipped,
|
|
244
|
-
errors,
|
|
245
|
-
summary: {
|
|
246
|
-
total: parseResult.operations.length,
|
|
247
|
-
imported: specs.length,
|
|
248
|
-
skipped: skipped.length,
|
|
249
|
-
errors: errors.length
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Import a single operation to ContractSpec code.
|
|
255
|
-
*/
|
|
256
|
-
function importOperation(operation, options = {}) {
|
|
257
|
-
const { schema: inputSchema } = buildInputSchema(operation);
|
|
258
|
-
const inputModel = inputSchema ? generateSchemaModelCode(inputSchema, `${operation.operationId}Input`) : null;
|
|
259
|
-
const outputSchema = getOutputSchema(operation);
|
|
260
|
-
return generateSpecCode(operation, options, inputModel, outputSchema ? generateSchemaModelCode(outputSchema, `${operation.operationId}Output`) : null);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
//#endregion
|
|
264
|
-
export { importFromOpenApi, importOperation };
|
|
265
|
-
//# sourceMappingURL=importer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"importer.js","names":["fields: {\n name: string;\n schema: OpenApiSchema;\n required: boolean;\n }[]","lines: string[]","specs: ImportedSpec[]","skipped: ImportResult['skipped']","errors: ImportResult['errors']","transportHints: OpenApiTransportHints","source: OpenApiSource"],"sources":["../../src/openapi/importer.ts"],"sourcesContent":["/**\n * Import OpenAPI specifications into ContractSpec format.\n * Converts OpenAPI operations to ContractSpec command/query definitions.\n */\n\nimport type {\n OpenApiImportOptions,\n ParseResult,\n ParsedOperation,\n OpenApiSchema,\n OpenApiTransportHints,\n OpenApiSource,\n} from './types';\nimport type { ImportResult, ImportedSpec } from '../common/types';\nimport {\n toSpecName,\n toFileName,\n toPascalCase,\n toValidIdentifier,\n} from '../common/utils';\nimport {\n generateSchemaModelCode,\n generateImports,\n type GeneratedModel,\n} from './schema-converter';\n\n/**\n * HTTP methods that typically indicate a command (state-changing).\n */\nconst COMMAND_METHODS = ['post', 'put', 'delete', 'patch'];\n\n/**\n * Determine if an operation is a command or query based on HTTP method.\n */\nfunction inferOpKind(method: string): 'command' | 'query' {\n return COMMAND_METHODS.includes(method.toLowerCase()) ? 'command' : 'query';\n}\n\n/**\n * Determine auth level based on security requirements.\n */\nfunction inferAuthLevel(\n operation: ParsedOperation,\n defaultAuth: 'anonymous' | 'user' | 'admin'\n): 'anonymous' | 'user' | 'admin' {\n if (!operation.security || operation.security.length === 0) {\n // Check if any security scheme is present\n return defaultAuth;\n }\n\n // If there's an empty security requirement, it's anonymous\n for (const sec of operation.security) {\n if (Object.keys(sec).length === 0) {\n return 'anonymous';\n }\n }\n\n return 'user';\n}\n\n/**\n * Build a merged input schema from all parameter sources.\n */\nfunction 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 */\nfunction getOutputSchema(operation: ParsedOperation): 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\n/**\n * Generate ContractSpec TypeScript code for an operation.\n */\nfunction generateSpecCode(\n operation: ParsedOperation,\n options: OpenApiImportOptions,\n inputModel: GeneratedModel | null,\n outputModel: GeneratedModel | null\n): string {\n const specName = toSpecName(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 ?? []),\n ...(outputModel?.fields ?? []),\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(` name: '${specName}',`);\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 lines.push(' transport: {');\n lines.push(' rest: {');\n lines.push(` method: '${operation.method.toUpperCase()}',`);\n lines.push(` path: '${operation.path}',`);\n lines.push(' },');\n lines.push(' },');\n\n lines.push('});');\n\n return lines.join('\\n');\n}\n\n/**\n * Import operations from a parsed OpenAPI document.\n */\nexport function importFromOpenApi(\n parseResult: ParseResult,\n options: OpenApiImportOptions = {}\n): ImportResult {\n const { tags, exclude = [], include } = options;\n const specs: ImportedSpec[] = [];\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 (operation.deprecated && options.defaultStability !== 'deprecated') {\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 const outputModel = outputSchema\n ? generateSchemaModelCode(\n outputSchema,\n `${operation.operationId}Output`\n )\n : null;\n\n // Generate spec code\n const code = generateSpecCode(\n operation,\n options,\n inputModel,\n outputModel\n );\n const specName = toSpecName(operation.operationId, options.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 specs.push({\n spec: {} as ImportedSpec['spec'], // Placeholder - actual spec would be built at runtime\n code,\n fileName,\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 return {\n specs,\n skipped,\n errors,\n summary: {\n total: parseResult.operations.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: OpenApiImportOptions = {}\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(operation, options, inputModel, outputModel);\n}\n"],"mappings":"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"}
|
package/dist/openapi/parser.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { OpenApiDocument, OpenApiParseOptions, OpenApiVersion, ParseResult } from "./types.js";
|
|
2
|
-
|
|
3
|
-
//#region src/openapi/parser.d.ts
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Parse an OpenAPI document from a string (JSON or YAML).
|
|
7
|
-
*/
|
|
8
|
-
declare function parseOpenApiString(content: string, format?: 'json' | 'yaml'): OpenApiDocument;
|
|
9
|
-
/**
|
|
10
|
-
* Detect the format of content (JSON or YAML).
|
|
11
|
-
*/
|
|
12
|
-
declare function detectFormat(content: string): 'json' | 'yaml';
|
|
13
|
-
/**
|
|
14
|
-
* Detect OpenAPI version from document.
|
|
15
|
-
*/
|
|
16
|
-
declare function detectVersion(doc: OpenApiDocument): OpenApiVersion;
|
|
17
|
-
/**
|
|
18
|
-
* Parse an OpenAPI document into a structured result.
|
|
19
|
-
*/
|
|
20
|
-
declare function parseOpenApiDocument(doc: OpenApiDocument, _options?: OpenApiParseOptions): ParseResult;
|
|
21
|
-
/**
|
|
22
|
-
* Parse OpenAPI from a file path or URL.
|
|
23
|
-
* Note: This is an async function that requires I/O adapters.
|
|
24
|
-
* For pure parsing, use parseOpenApiString or parseOpenApiDocument.
|
|
25
|
-
*/
|
|
26
|
-
declare function parseOpenApi(source: string, options?: OpenApiParseOptions & {
|
|
27
|
-
fetch?: typeof globalThis.fetch;
|
|
28
|
-
readFile?: (path: string) => Promise<string>;
|
|
29
|
-
}): Promise<ParseResult>;
|
|
30
|
-
//#endregion
|
|
31
|
-
export { detectFormat, detectVersion, parseOpenApi, parseOpenApiDocument, parseOpenApiString };
|
|
32
|
-
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"parser.d.ts","names":[],"sources":["../../src/openapi/parser.ts"],"sourcesContent":[],"mappings":";;;;AA0DA;AAqNA;;AAEY,iBA/OI,kBAAA,CA+OJ,OAAA,EAAA,MAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,MAAA,CAAA,EA5OT,eA4OS;;;AA2EZ;AAEW,iBA/SK,YAAA,CA+SL,OAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,MAAA;;;;AAIR,iBAxSa,aAAA,CAwSb,GAAA,EAxSgC,eAwShC,CAAA,EAxSkD,cAwSlD;;;;iBAnFa,oBAAA,MACT,4BACK,sBACT;;;;;;iBA0EmB,YAAA,2BAEX;iBACQ,UAAA,CAAW;+BACG;IAE9B,QAAQ"}
|