@contractspec/lib.contracts-transformers 1.44.1 → 1.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,7 @@ import { DataViewRegistry } from "@contractspec/lib.contracts";
8
8
  */
9
9
  interface ExportedDataView {
10
10
  name: string;
11
- version: number;
11
+ version: string;
12
12
  description?: string;
13
13
  stability?: string;
14
14
  entity: string;
@@ -16,11 +16,11 @@ interface ExportedDataView {
16
16
  source: {
17
17
  primary: {
18
18
  key: string;
19
- version: number;
19
+ version: string;
20
20
  };
21
21
  item?: {
22
22
  key: string;
23
- version: number;
23
+ version: string;
24
24
  };
25
25
  };
26
26
  fields: unknown[];
@@ -1 +1 @@
1
- {"version":3,"file":"data-views.js","names":["registrations: string[]"],"sources":["../../../src/openapi/exporter/data-views.ts"],"sourcesContent":["/**\n * Data views exporter - exports DataViewSpec to OpenAPI extensions.\n */\nimport type { DataViewRegistry } from '@contractspec/lib.contracts';\nimport type { GeneratedRegistryCode } from '../types';\n\n/**\n * Exported data view structure for OpenAPI extensions.\n */\nexport interface ExportedDataView {\n name: string;\n version: number;\n description?: string;\n stability?: string;\n entity: string;\n kind: 'list' | 'detail' | 'table' | 'grid';\n source: {\n primary: { key: string; version: number };\n item?: { key: string; version: number };\n };\n fields: unknown[];\n}\n\n/**\n * Export data views to OpenAPI extension format.\n */\nexport function exportDataViews(\n registry: DataViewRegistry\n): ExportedDataView[] {\n return registry.list().map((dv) => ({\n name: dv.meta.key,\n version: dv.meta.version,\n description: dv.meta.description,\n stability: dv.meta.stability,\n entity: dv.meta.entity,\n kind: dv.view.kind,\n source: dv.source,\n fields: dv.view.fields,\n }));\n}\n\n/**\n * Generate TypeScript code for data views registry.\n */\nexport function generateDataViewsRegistry(\n registry: DataViewRegistry\n): GeneratedRegistryCode {\n const dataViews = registry.list();\n const imports = new Set<string>();\n const registrations: string[] = [];\n\n for (const dv of dataViews) {\n const dvVarName = dv.meta.key.replace(/\\./g, '_') + `_v${dv.meta.version}`;\n imports.add(\n `import { ${dvVarName} } from './${dv.meta.key.split('.')[0]}';`\n );\n registrations.push(` .register(${dvVarName})`);\n }\n\n const code = `/**\n * Auto-generated data views registry.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\nimport { DataViewRegistry } from '@contractspec/lib.contracts';\n\n${Array.from(imports).join('\\n')}\n\nexport const dataViewsRegistry = new DataViewRegistry()\n${registrations.join('\\n')};\n`;\n\n return {\n code,\n fileName: 'dataviews-registry.ts',\n };\n}\n"],"mappings":";;;;AA0BA,SAAgB,gBACd,UACoB;AACpB,QAAO,SAAS,MAAM,CAAC,KAAK,QAAQ;EAClC,MAAM,GAAG,KAAK;EACd,SAAS,GAAG,KAAK;EACjB,aAAa,GAAG,KAAK;EACrB,WAAW,GAAG,KAAK;EACnB,QAAQ,GAAG,KAAK;EAChB,MAAM,GAAG,KAAK;EACd,QAAQ,GAAG;EACX,QAAQ,GAAG,KAAK;EACjB,EAAE;;;;;AAML,SAAgB,0BACd,UACuB;CACvB,MAAM,YAAY,SAAS,MAAM;CACjC,MAAM,0BAAU,IAAI,KAAa;CACjC,MAAMA,gBAA0B,EAAE;AAElC,MAAK,MAAM,MAAM,WAAW;EAC1B,MAAM,YAAY,GAAG,KAAK,IAAI,QAAQ,OAAO,IAAI,GAAG,KAAK,GAAG,KAAK;AACjE,UAAQ,IACN,YAAY,UAAU,aAAa,GAAG,KAAK,IAAI,MAAM,IAAI,CAAC,GAAG,IAC9D;AACD,gBAAc,KAAK,eAAe,UAAU,GAAG;;AAejD,QAAO;EACL,MAbW;;;;;;EAMb,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAAC;;;EAG/B,cAAc,KAAK,KAAK,CAAC;;EAKvB,UAAU;EACX"}
1
+ {"version":3,"file":"data-views.js","names":["registrations: string[]"],"sources":["../../../src/openapi/exporter/data-views.ts"],"sourcesContent":["/**\n * Data views exporter - exports DataViewSpec to OpenAPI extensions.\n */\nimport type { DataViewRegistry } from '@contractspec/lib.contracts';\nimport type { GeneratedRegistryCode } from '../types';\n\n/**\n * Exported data view structure for OpenAPI extensions.\n */\nexport interface ExportedDataView {\n name: string;\n version: string;\n description?: string;\n stability?: string;\n entity: string;\n kind: 'list' | 'detail' | 'table' | 'grid';\n source: {\n primary: { key: string; version: string };\n item?: { key: string; version: string };\n };\n fields: unknown[];\n}\n\n/**\n * Export data views to OpenAPI extension format.\n */\nexport function exportDataViews(\n registry: DataViewRegistry\n): ExportedDataView[] {\n return registry.list().map((dv) => ({\n name: dv.meta.key,\n version: dv.meta.version,\n description: dv.meta.description,\n stability: dv.meta.stability,\n entity: dv.meta.entity,\n kind: dv.view.kind,\n source: dv.source,\n fields: dv.view.fields,\n }));\n}\n\n/**\n * Generate TypeScript code for data views registry.\n */\nexport function generateDataViewsRegistry(\n registry: DataViewRegistry\n): GeneratedRegistryCode {\n const dataViews = registry.list();\n const imports = new Set<string>();\n const registrations: string[] = [];\n\n for (const dv of dataViews) {\n const dvVarName = dv.meta.key.replace(/\\./g, '_') + `_v${dv.meta.version}`;\n imports.add(\n `import { ${dvVarName} } from './${dv.meta.key.split('.')[0]}';`\n );\n registrations.push(` .register(${dvVarName})`);\n }\n\n const code = `/**\n * Auto-generated data views registry.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\nimport { DataViewRegistry } from '@contractspec/lib.contracts';\n\n${Array.from(imports).join('\\n')}\n\nexport const dataViewsRegistry = new DataViewRegistry()\n${registrations.join('\\n')};\n`;\n\n return {\n code,\n fileName: 'dataviews-registry.ts',\n };\n}\n"],"mappings":";;;;AA0BA,SAAgB,gBACd,UACoB;AACpB,QAAO,SAAS,MAAM,CAAC,KAAK,QAAQ;EAClC,MAAM,GAAG,KAAK;EACd,SAAS,GAAG,KAAK;EACjB,aAAa,GAAG,KAAK;EACrB,WAAW,GAAG,KAAK;EACnB,QAAQ,GAAG,KAAK;EAChB,MAAM,GAAG,KAAK;EACd,QAAQ,GAAG;EACX,QAAQ,GAAG,KAAK;EACjB,EAAE;;;;;AAML,SAAgB,0BACd,UACuB;CACvB,MAAM,YAAY,SAAS,MAAM;CACjC,MAAM,0BAAU,IAAI,KAAa;CACjC,MAAMA,gBAA0B,EAAE;AAElC,MAAK,MAAM,MAAM,WAAW;EAC1B,MAAM,YAAY,GAAG,KAAK,IAAI,QAAQ,OAAO,IAAI,GAAG,KAAK,GAAG,KAAK;AACjE,UAAQ,IACN,YAAY,UAAU,aAAa,GAAG,KAAK,IAAI,MAAM,IAAI,CAAC,GAAG,IAC9D;AACD,gBAAc,KAAK,eAAe,UAAU,GAAG;;AAejD,QAAO;EACL,MAbW;;;;;;EAMb,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAAC;;;EAG/B,cAAc,KAAK,KAAK,CAAC;;EAKvB,UAAU;EACX"}
@@ -10,8 +10,8 @@ type OpenApiSchemaObject = Record<string, unknown>;
10
10
  */
11
11
  interface ExportedEvent {
12
12
  name: string;
13
- version: number;
14
- description?: string;
13
+ version: string;
14
+ description: string;
15
15
  payload: OpenApiSchemaObject | null;
16
16
  pii?: string[];
17
17
  }
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","names":[],"sources":["../../../src/openapi/exporter/events.ts"],"sourcesContent":[],"mappings":";;;;;;AAaA,KALK,mBAAA,GAAsB,MAShB,CAAA,MAAA,EAAA,OAAA,CAAA;AAOX;;;AAEG,UAbc,aAAA,CAad;EAAa,IAAA,EAAA,MAAA;EAeA,OAAA,EAAA,MAAA;EACI,WAAA,CAAA,EAAA,MAAA;EAAV,OAAA,EAzBC,mBAyBD,GAAA,IAAA;EACP,GAAA,CAAA,EAAA,MAAA,EAAA;;;;;iBAnBa,YAAA,SACN,UAAU,oBACjB;;;;iBAea,qBAAA,SACN,UAAU,oBACjB"}
1
+ {"version":3,"file":"events.d.ts","names":[],"sources":["../../../src/openapi/exporter/events.ts"],"sourcesContent":[],"mappings":";;;;;;AAaA,KALK,mBAAA,GAAsB,MAShB,CAAA,MAAA,EAAA,OAAA,CAAA;AAOX;;;AAEG,UAbc,aAAA,CAad;EAAa,IAAA,EAAA,MAAA;EAeA,OAAA,EAAA,MAAA;EACI,WAAA,EAAA,MAAA;EAAV,OAAA,EAzBC,mBAyBD,GAAA,IAAA;EACP,GAAA,CAAA,EAAA,MAAA,EAAA;;;;;iBAnBa,YAAA,SACN,UAAU,oBACjB;;;;iBAea,qBAAA,SACN,UAAU,oBACjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","names":["eventExports: string[]"],"sources":["../../../src/openapi/exporter/events.ts"],"sourcesContent":["/**\n * Events exporter - exports EventSpec to OpenAPI extensions.\n */\nimport type { EventSpec } from '@contractspec/lib.contracts';\nimport type { AnySchemaModel } from '@contractspec/lib.schema';\nimport { z } from 'zod';\nimport type { GeneratedRegistryCode } from '../types';\n\ntype OpenApiSchemaObject = Record<string, unknown>;\n\n/**\n * Exported event structure for OpenAPI extensions.\n */\nexport interface ExportedEvent {\n name: string;\n version: number;\n description?: string;\n payload: OpenApiSchemaObject | null;\n pii?: string[];\n}\n\n/**\n * Export events to OpenAPI extension format.\n */\nexport function exportEvents(\n events: EventSpec<AnySchemaModel>[]\n): ExportedEvent[] {\n return events.map((event) => ({\n name: event.meta.key,\n version: event.meta.version,\n description: event.meta.description,\n payload: event.payload\n ? (z.toJSONSchema(event.payload.getZod()) as OpenApiSchemaObject)\n : null,\n pii: event.pii,\n }));\n}\n\n/**\n * Generate TypeScript code for events exports.\n */\nexport function generateEventsExports(\n events: EventSpec<AnySchemaModel>[]\n): GeneratedRegistryCode {\n const eventExports: string[] = [];\n\n for (const event of events) {\n const eventVarName =\n event.meta.key.replace(/\\./g, '_') + `_v${event.meta.version}`;\n eventExports.push(\n `export { ${eventVarName} } from './${event.meta.key.split('.')[0]}';`\n );\n }\n\n const code = `/**\n * Auto-generated events exports.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\n\n${eventExports.join('\\n')}\n`;\n\n return {\n code,\n fileName: 'events-exports.ts',\n };\n}\n"],"mappings":";;;;;;AAwBA,SAAgB,aACd,QACiB;AACjB,QAAO,OAAO,KAAK,WAAW;EAC5B,MAAM,MAAM,KAAK;EACjB,SAAS,MAAM,KAAK;EACpB,aAAa,MAAM,KAAK;EACxB,SAAS,MAAM,UACV,EAAE,aAAa,MAAM,QAAQ,QAAQ,CAAC,GACvC;EACJ,KAAK,MAAM;EACZ,EAAE;;;;;AAML,SAAgB,sBACd,QACuB;CACvB,MAAMA,eAAyB,EAAE;AAEjC,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,eACJ,MAAM,KAAK,IAAI,QAAQ,OAAO,IAAI,GAAG,KAAK,MAAM,KAAK;AACvD,eAAa,KACX,YAAY,aAAa,aAAa,MAAM,KAAK,IAAI,MAAM,IAAI,CAAC,GAAG,IACpE;;AAWH,QAAO;EACL,MATW;;;;;EAKb,aAAa,KAAK,KAAK,CAAC;;EAKtB,UAAU;EACX"}
1
+ {"version":3,"file":"events.js","names":["eventExports: string[]"],"sources":["../../../src/openapi/exporter/events.ts"],"sourcesContent":["/**\n * Events exporter - exports EventSpec to OpenAPI extensions.\n */\nimport type { EventSpec } from '@contractspec/lib.contracts';\nimport type { AnySchemaModel } from '@contractspec/lib.schema';\nimport { z } from 'zod';\nimport type { GeneratedRegistryCode } from '../types';\n\ntype OpenApiSchemaObject = Record<string, unknown>;\n\n/**\n * Exported event structure for OpenAPI extensions.\n */\nexport interface ExportedEvent {\n name: string;\n version: string;\n description: string;\n payload: OpenApiSchemaObject | null;\n pii?: string[];\n}\n\n/**\n * Export events to OpenAPI extension format.\n */\nexport function exportEvents(\n events: EventSpec<AnySchemaModel>[]\n): ExportedEvent[] {\n return events.map((event) => ({\n name: event.meta.key,\n version: event.meta.version,\n description: event.meta.description,\n payload: event.payload\n ? (z.toJSONSchema(event.payload.getZod()) as OpenApiSchemaObject)\n : null,\n pii: event.pii,\n }));\n}\n\n/**\n * Generate TypeScript code for events exports.\n */\nexport function generateEventsExports(\n events: EventSpec<AnySchemaModel>[]\n): GeneratedRegistryCode {\n const eventExports: string[] = [];\n\n for (const event of events) {\n const eventVarName =\n event.meta.key.replace(/\\./g, '_') + `_v${event.meta.version}`;\n eventExports.push(\n `export { ${eventVarName} } from './${event.meta.key.split('.')[0]}';`\n );\n }\n\n const code = `/**\n * Auto-generated events exports.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\n\n${eventExports.join('\\n')}\n`;\n\n return {\n code,\n fileName: 'events-exports.ts',\n };\n}\n"],"mappings":";;;;;;AAwBA,SAAgB,aACd,QACiB;AACjB,QAAO,OAAO,KAAK,WAAW;EAC5B,MAAM,MAAM,KAAK;EACjB,SAAS,MAAM,KAAK;EACpB,aAAa,MAAM,KAAK;EACxB,SAAS,MAAM,UACV,EAAE,aAAa,MAAM,QAAQ,QAAQ,CAAC,GACvC;EACJ,KAAK,MAAM;EACZ,EAAE;;;;;AAML,SAAgB,sBACd,QACuB;CACvB,MAAMA,eAAyB,EAAE;AAEjC,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,eACJ,MAAM,KAAK,IAAI,QAAQ,OAAO,IAAI,GAAG,KAAK,MAAM,KAAK;AACvD,eAAa,KACX,YAAY,aAAa,aAAa,MAAM,KAAK,IAAI,MAAM,IAAI,CAAC,GAAG,IACpE;;AAWH,QAAO;EACL,MATW;;;;;EAKb,aAAa,KAAK,KAAK,CAAC;;EAKtB,UAAU;EACX"}
@@ -13,15 +13,15 @@ interface ExportedFeature {
13
13
  stability?: string;
14
14
  operations?: {
15
15
  key: string;
16
- version: number;
16
+ version: string;
17
17
  }[];
18
18
  events?: {
19
19
  key: string;
20
- version: number;
20
+ version: string;
21
21
  }[];
22
22
  presentations?: {
23
23
  key: string;
24
- version: number;
24
+ version: string;
25
25
  }[];
26
26
  }
27
27
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"features.js","names":["registrations: string[]"],"sources":["../../../src/openapi/exporter/features.ts"],"sourcesContent":["/**\n * Features exporter - exports FeatureModuleSpec to OpenAPI extensions.\n */\nimport type { FeatureRegistry } from '@contractspec/lib.contracts';\nimport type { GeneratedRegistryCode } from '../types';\n\n/**\n * Exported feature structure for OpenAPI extensions.\n */\nexport interface ExportedFeature {\n key: string;\n description?: string;\n owners?: string[];\n stability?: string;\n operations?: { key: string; version: number }[];\n events?: { key: string; version: number }[];\n presentations?: { key: string; version: number }[];\n}\n\n/**\n * Export features to OpenAPI extension format.\n */\nexport function exportFeatures(registry: FeatureRegistry): ExportedFeature[] {\n return registry.list().map((feature) => ({\n key: feature.meta.key,\n description: feature.meta.description,\n owners: feature.meta.owners,\n stability: feature.meta.stability,\n operations: feature.operations,\n events: feature.events,\n presentations: feature.presentations,\n }));\n}\n\n/**\n * Generate TypeScript code for features registry.\n */\nexport function generateFeaturesRegistry(\n registry: FeatureRegistry\n): GeneratedRegistryCode {\n const features = registry.list();\n const imports = new Set<string>();\n const registrations: string[] = [];\n\n for (const feature of features) {\n const featureVarName = feature.meta.key.replace(/-/g, '_');\n imports.add(`import { ${featureVarName} } from './${feature.meta.key}';`);\n registrations.push(` .register(${featureVarName})`);\n }\n\n const code = `/**\n * Auto-generated features registry.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\nimport { FeatureRegistry } from '@contractspec/lib.contracts';\n\n${Array.from(imports).join('\\n')}\n\nexport const featuresRegistry = new FeatureRegistry()\n${registrations.join('\\n')};\n`;\n\n return {\n code,\n fileName: 'features-registry.ts',\n };\n}\n"],"mappings":";;;;AAsBA,SAAgB,eAAe,UAA8C;AAC3E,QAAO,SAAS,MAAM,CAAC,KAAK,aAAa;EACvC,KAAK,QAAQ,KAAK;EAClB,aAAa,QAAQ,KAAK;EAC1B,QAAQ,QAAQ,KAAK;EACrB,WAAW,QAAQ,KAAK;EACxB,YAAY,QAAQ;EACpB,QAAQ,QAAQ;EAChB,eAAe,QAAQ;EACxB,EAAE;;;;;AAML,SAAgB,yBACd,UACuB;CACvB,MAAM,WAAW,SAAS,MAAM;CAChC,MAAM,0BAAU,IAAI,KAAa;CACjC,MAAMA,gBAA0B,EAAE;AAElC,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,iBAAiB,QAAQ,KAAK,IAAI,QAAQ,MAAM,IAAI;AAC1D,UAAQ,IAAI,YAAY,eAAe,aAAa,QAAQ,KAAK,IAAI,IAAI;AACzE,gBAAc,KAAK,eAAe,eAAe,GAAG;;AAetD,QAAO;EACL,MAbW;;;;;;EAMb,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAAC;;;EAG/B,cAAc,KAAK,KAAK,CAAC;;EAKvB,UAAU;EACX"}
1
+ {"version":3,"file":"features.js","names":["registrations: string[]"],"sources":["../../../src/openapi/exporter/features.ts"],"sourcesContent":["/**\n * Features exporter - exports FeatureModuleSpec to OpenAPI extensions.\n */\nimport type { FeatureRegistry } from '@contractspec/lib.contracts';\nimport type { GeneratedRegistryCode } from '../types';\n\n/**\n * Exported feature structure for OpenAPI extensions.\n */\nexport interface ExportedFeature {\n key: string;\n description?: string;\n owners?: string[];\n stability?: string;\n operations?: { key: string; version: string }[];\n events?: { key: string; version: string }[];\n presentations?: { key: string; version: string }[];\n}\n\n/**\n * Export features to OpenAPI extension format.\n */\nexport function exportFeatures(registry: FeatureRegistry): ExportedFeature[] {\n return registry.list().map((feature) => ({\n key: feature.meta.key,\n description: feature.meta.description,\n owners: feature.meta.owners,\n stability: feature.meta.stability,\n operations: feature.operations,\n events: feature.events,\n presentations: feature.presentations,\n }));\n}\n\n/**\n * Generate TypeScript code for features registry.\n */\nexport function generateFeaturesRegistry(\n registry: FeatureRegistry\n): GeneratedRegistryCode {\n const features = registry.list();\n const imports = new Set<string>();\n const registrations: string[] = [];\n\n for (const feature of features) {\n const featureVarName = feature.meta.key.replace(/-/g, '_');\n imports.add(`import { ${featureVarName} } from './${feature.meta.key}';`);\n registrations.push(` .register(${featureVarName})`);\n }\n\n const code = `/**\n * Auto-generated features registry.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\nimport { FeatureRegistry } from '@contractspec/lib.contracts';\n\n${Array.from(imports).join('\\n')}\n\nexport const featuresRegistry = new FeatureRegistry()\n${registrations.join('\\n')};\n`;\n\n return {\n code,\n fileName: 'features-registry.ts',\n };\n}\n"],"mappings":";;;;AAsBA,SAAgB,eAAe,UAA8C;AAC3E,QAAO,SAAS,MAAM,CAAC,KAAK,aAAa;EACvC,KAAK,QAAQ,KAAK;EAClB,aAAa,QAAQ,KAAK;EAC1B,QAAQ,QAAQ,KAAK;EACrB,WAAW,QAAQ,KAAK;EACxB,YAAY,QAAQ;EACpB,QAAQ,QAAQ;EAChB,eAAe,QAAQ;EACxB,EAAE;;;;;AAML,SAAgB,yBACd,UACuB;CACvB,MAAM,WAAW,SAAS,MAAM;CAChC,MAAM,0BAAU,IAAI,KAAa;CACjC,MAAMA,gBAA0B,EAAE;AAElC,MAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,iBAAiB,QAAQ,KAAK,IAAI,QAAQ,MAAM,IAAI;AAC1D,UAAQ,IAAI,YAAY,eAAe,aAAa,QAAQ,KAAK,IAAI,IAAI;AACzE,gBAAc,KAAK,eAAe,eAAe,GAAG;;AAetD,QAAO;EACL,MAbW;;;;;;EAMb,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAAC;;;EAG/B,cAAc,KAAK,KAAK,CAAC;;EAKvB,UAAU;EACX"}
@@ -1,5 +1,5 @@
1
1
  import { GeneratedRegistryCode } from "../types.js";
2
- import { FormRegistry } from "@contractspec/lib.contracts";
2
+ import { FormRegistry, Stability } from "@contractspec/lib.contracts";
3
3
 
4
4
  //#region src/openapi/exporter/forms.d.ts
5
5
 
@@ -9,9 +9,9 @@ type OpenApiSchemaObject = Record<string, unknown>;
9
9
  */
10
10
  interface ExportedForm {
11
11
  key: string;
12
- version: number;
13
- description?: string;
14
- stability?: string;
12
+ version: string;
13
+ description: string;
14
+ stability: Stability;
15
15
  owners?: string[];
16
16
  fields: unknown[];
17
17
  model: OpenApiSchemaObject | null;
@@ -1 +1 @@
1
- {"version":3,"file":"forms.d.ts","names":[],"sources":["../../../src/openapi/exporter/forms.ts"],"sourcesContent":[],"mappings":";;;;;AAaA,KALK,mBAAA,GAAsB,MAYlB,CAAA,MAAA,EAAA,OAAA,CAAA;AAOT;AAoBA;;UAlCiB,YAAA;;;;;;;SAOR;;;;;;iBAOO,WAAA,WAAsB,eAAe;;;;iBAoBrC,qBAAA,WACJ,eACT"}
1
+ {"version":3,"file":"forms.d.ts","names":[],"sources":["../../../src/openapi/exporter/forms.ts"],"sourcesContent":[],"mappings":";;;;;AAaA,KALK,mBAAA,GAAsB,MASd,CAAA,MAAA,EAGJ,OAAA,CAAA;AAOT;AAoBA;;UAlCiB,YAAA;;;;aAIJ;;;SAGJ;;;;;;iBAOO,WAAA,WAAsB,eAAe;;;;iBAoBrC,qBAAA,WACJ,eACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"forms.js","names":["registrations: string[]"],"sources":["../../../src/openapi/exporter/forms.ts"],"sourcesContent":["/**\n * Forms exporter - exports FormSpec to OpenAPI extensions.\n */\nimport type { FormRegistry } from '@contractspec/lib.contracts';\nimport type { AnySchemaModel } from '@contractspec/lib.schema';\nimport { z } from 'zod';\nimport type { GeneratedRegistryCode } from '../types';\n\ntype OpenApiSchemaObject = Record<string, unknown>;\n\n/**\n * Exported form structure for OpenAPI extensions.\n */\nexport interface ExportedForm {\n key: string;\n version: number;\n description?: string;\n stability?: string;\n owners?: string[];\n fields: unknown[];\n model: OpenApiSchemaObject | null;\n actions?: unknown[];\n}\n\n/**\n * Export forms to OpenAPI extension format.\n */\nexport function exportForms(registry: FormRegistry): ExportedForm[] {\n return registry.list().map((form) => ({\n key: form.meta.key,\n version: form.meta.version,\n description: form.meta.description,\n stability: form.meta.stability,\n owners: form.meta.owners,\n fields: form.fields,\n model: form.model\n ? (z.toJSONSchema(\n (form.model as AnySchemaModel).getZod()\n ) as OpenApiSchemaObject)\n : null,\n actions: form.actions,\n }));\n}\n\n/**\n * Generate TypeScript code for forms registry.\n */\nexport function generateFormsRegistry(\n registry: FormRegistry\n): GeneratedRegistryCode {\n const forms = registry.list();\n const imports = new Set<string>();\n const registrations: string[] = [];\n\n for (const form of forms) {\n const formVarName =\n form.meta.key.replace(/-/g, '_') + `_v${form.meta.version}`;\n imports.add(`import { ${formVarName} } from './${form.meta.key}';`);\n registrations.push(` .register(${formVarName})`);\n }\n\n const code = `/**\n * Auto-generated forms registry.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\nimport { FormRegistry } from '@contractspec/lib.contracts';\n\n${Array.from(imports).join('\\n')}\n\nexport const formsRegistry = new FormRegistry()\n${registrations.join('\\n')};\n`;\n\n return {\n code,\n fileName: 'forms-registry.ts',\n };\n}\n"],"mappings":";;;;;;AA2BA,SAAgB,YAAY,UAAwC;AAClE,QAAO,SAAS,MAAM,CAAC,KAAK,UAAU;EACpC,KAAK,KAAK,KAAK;EACf,SAAS,KAAK,KAAK;EACnB,aAAa,KAAK,KAAK;EACvB,WAAW,KAAK,KAAK;EACrB,QAAQ,KAAK,KAAK;EAClB,QAAQ,KAAK;EACb,OAAO,KAAK,QACP,EAAE,aACA,KAAK,MAAyB,QAAQ,CACxC,GACD;EACJ,SAAS,KAAK;EACf,EAAE;;;;;AAML,SAAgB,sBACd,UACuB;CACvB,MAAM,QAAQ,SAAS,MAAM;CAC7B,MAAM,0BAAU,IAAI,KAAa;CACjC,MAAMA,gBAA0B,EAAE;AAElC,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,cACJ,KAAK,KAAK,IAAI,QAAQ,MAAM,IAAI,GAAG,KAAK,KAAK,KAAK;AACpD,UAAQ,IAAI,YAAY,YAAY,aAAa,KAAK,KAAK,IAAI,IAAI;AACnE,gBAAc,KAAK,eAAe,YAAY,GAAG;;AAenD,QAAO;EACL,MAbW;;;;;;EAMb,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAAC;;;EAG/B,cAAc,KAAK,KAAK,CAAC;;EAKvB,UAAU;EACX"}
1
+ {"version":3,"file":"forms.js","names":["registrations: string[]"],"sources":["../../../src/openapi/exporter/forms.ts"],"sourcesContent":["/**\n * Forms exporter - exports FormSpec to OpenAPI extensions.\n */\nimport type { FormRegistry, Stability } from '@contractspec/lib.contracts';\nimport type { AnySchemaModel } from '@contractspec/lib.schema';\nimport { z } from 'zod';\nimport type { GeneratedRegistryCode } from '../types';\n\ntype OpenApiSchemaObject = Record<string, unknown>;\n\n/**\n * Exported form structure for OpenAPI extensions.\n */\nexport interface ExportedForm {\n key: string;\n version: string;\n description: string;\n stability: Stability;\n owners?: string[];\n fields: unknown[];\n model: OpenApiSchemaObject | null;\n actions?: unknown[];\n}\n\n/**\n * Export forms to OpenAPI extension format.\n */\nexport function exportForms(registry: FormRegistry): ExportedForm[] {\n return registry.list().map((form) => ({\n key: form.meta.key,\n version: form.meta.version,\n description: form.meta.description,\n stability: form.meta.stability,\n owners: form.meta.owners,\n fields: form.fields,\n model: form.model\n ? (z.toJSONSchema(\n (form.model as AnySchemaModel).getZod()\n ) as OpenApiSchemaObject)\n : null,\n actions: form.actions,\n }));\n}\n\n/**\n * Generate TypeScript code for forms registry.\n */\nexport function generateFormsRegistry(\n registry: FormRegistry\n): GeneratedRegistryCode {\n const forms = registry.list();\n const imports = new Set<string>();\n const registrations: string[] = [];\n\n for (const form of forms) {\n const formVarName =\n form.meta.key.replace(/-/g, '_') + `_v${form.meta.version}`;\n imports.add(`import { ${formVarName} } from './${form.meta.key}';`);\n registrations.push(` .register(${formVarName})`);\n }\n\n const code = `/**\n * Auto-generated forms registry.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\nimport { FormRegistry } from '@contractspec/lib.contracts';\n\n${Array.from(imports).join('\\n')}\n\nexport const formsRegistry = new FormRegistry()\n${registrations.join('\\n')};\n`;\n\n return {\n code,\n fileName: 'forms-registry.ts',\n };\n}\n"],"mappings":";;;;;;AA2BA,SAAgB,YAAY,UAAwC;AAClE,QAAO,SAAS,MAAM,CAAC,KAAK,UAAU;EACpC,KAAK,KAAK,KAAK;EACf,SAAS,KAAK,KAAK;EACnB,aAAa,KAAK,KAAK;EACvB,WAAW,KAAK,KAAK;EACrB,QAAQ,KAAK,KAAK;EAClB,QAAQ,KAAK;EACb,OAAO,KAAK,QACP,EAAE,aACA,KAAK,MAAyB,QAAQ,CACxC,GACD;EACJ,SAAS,KAAK;EACf,EAAE;;;;;AAML,SAAgB,sBACd,UACuB;CACvB,MAAM,QAAQ,SAAS,MAAM;CAC7B,MAAM,0BAAU,IAAI,KAAa;CACjC,MAAMA,gBAA0B,EAAE;AAElC,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,cACJ,KAAK,KAAK,IAAI,QAAQ,MAAM,IAAI,GAAG,KAAK,KAAK,KAAK;AACpD,UAAQ,IAAI,YAAY,YAAY,aAAa,KAAK,KAAK,IAAI,IAAI;AACnE,gBAAc,KAAK,eAAe,YAAY,GAAG;;AAenD,QAAO;EACL,MAbW;;;;;;EAMb,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAAC;;;EAG/B,cAAc,KAAK,KAAK,CAAC;;EAKvB,UAAU;EACX"}
@@ -8,11 +8,11 @@ type OpenApiSchemaObject = Record<string, unknown>;
8
8
  /**
9
9
  * Convert a spec name and version to an operationId.
10
10
  */
11
- declare function toOperationId(name: string, version: number): string;
11
+ declare function toOperationId(name: string, version: string): string;
12
12
  /**
13
13
  * Convert a spec name and version to a schema name.
14
14
  */
15
- declare function toSchemaName(prefix: 'Input' | 'Output', name: string, version: number): string;
15
+ declare function toSchemaName(prefix: 'Input' | 'Output', name: string, version: string): string;
16
16
  /**
17
17
  * Determine HTTP method from spec kind and override.
18
18
  */
@@ -20,7 +20,7 @@ declare function toHttpMethod(kind: 'command' | 'query', override?: 'GET' | 'POS
20
20
  /**
21
21
  * Generate default REST path from spec name and version.
22
22
  */
23
- declare function defaultRestPath(name: string, version: number): string;
23
+ declare function defaultRestPath(name: string, version: string): string;
24
24
  /**
25
25
  * Get REST path from spec, using transport override or default.
26
26
  */
@@ -34,7 +34,7 @@ interface SpecJsonSchema {
34
34
  output: OpenApiSchemaObject | null;
35
35
  meta: {
36
36
  key: string;
37
- version: number;
37
+ version: string;
38
38
  kind: 'command' | 'query';
39
39
  description: string;
40
40
  tags: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"operations.d.ts","names":[],"sources":["../../../src/openapi/exporter/operations.ts"],"sourcesContent":[],"mappings":";;;;;;AAiBA,KALK,mBAAA,GAAsB,MAKE,CAAA,MAAA,EAAA,OAAA,CAAA;AAO7B;AAWA;AAWA;AAOgB,iBApCA,aAAA,CAoCiB,IAAA,EAAA,MAAgB,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,MAAA;AAUjD;AAKC;AAkBD;AACsB,iBA/DN,YAAA,CA+DM,MAAA,EAAA,OAAA,GAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,MAAA;;;;AACL,iBArDD,YAAA,CAqDC,IAAA,EAAA,SAAA,GAAA,OAAA,EAAA,QAAA,CAAA,EAAA,KAAA,GAAA,MAAA,CAAA,EAAA,MAAA;AAkBjB;;;AAE0B,iBA9DV,eAAA,CA8DU,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,MAAA;;;AAM1B;AAoFgB,iBAjJA,UAAA,CAiJ0B,IAAA,EAjJT,gBAkJrB,CAAA,EAAA,MAAA;;;;iBAxII,uBAAA,SACN,wBACP;UAKO,cAAA;SACD;UACC;;;;;;;;;;;;;iBAcM,iBAAA,OACR,cAAc,gBAAgB,kBACnC;;;;UAkBc,sBAAA;SACR,eAAe;WACb,eAAe;;;;;iBAMV,gBAAA,WACJ,wBACT;;;;iBAkFa,0BAAA,WACJ,wBACT"}
1
+ {"version":3,"file":"operations.d.ts","names":[],"sources":["../../../src/openapi/exporter/operations.ts"],"sourcesContent":[],"mappings":";;;;;;AAkBA,KALK,mBAAA,GAAsB,MAKE,CAAA,MAAA,EAAA,OAAA,CAAA;AAO7B;AAWA;AAWA;AAOgB,iBApCA,aAAA,CAoCiB,IAAA,EAAA,MAAgB,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,MAAA;AAUjD;AAKC;AAkBD;AACsB,iBA/DN,YAAA,CA+DM,MAAA,EAAA,OAAA,GAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,MAAA;;;;AACL,iBArDD,YAAA,CAqDC,IAAA,EAAA,SAAA,GAAA,OAAA,EAAA,QAAA,CAAA,EAAA,KAAA,GAAA,MAAA,CAAA,EAAA,MAAA;AAkBjB;;;AAE0B,iBA9DV,eAAA,CA8DU,IAAA,EAAA,MAAA,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,MAAA;;;AAM1B;AAoFgB,iBAjJA,UAAA,CAiJ0B,IAAA,EAjJT,gBAkJrB,CAAA,EAAA,MAAA;;;;iBAxII,uBAAA,SACN,wBACP;UAKO,cAAA;SACD;UACC;;;;;;;;;;;;;iBAcM,iBAAA,OACR,cAAc,gBAAgB,kBACnC;;;;UAkBc,sBAAA;SACR,eAAe;WACb,eAAe;;;;;iBAMV,gBAAA,WACJ,wBACT;;;;iBAkFa,0BAAA,WACJ,wBACT"}
@@ -1,11 +1,12 @@
1
1
  import { z } from "zod";
2
+ import { compareVersions } from "compare-versions";
2
3
 
3
4
  //#region src/openapi/exporter/operations.ts
4
5
  /**
5
6
  * Convert a spec name and version to an operationId.
6
7
  */
7
8
  function toOperationId(name, version) {
8
- return `${name.replace(/\./g, "_")}_v${version}`;
9
+ return `${name.replace(/\./g, "_")}_v${version.replace(/\./g, "_")}`;
9
10
  }
10
11
  /**
11
12
  * Convert a spec name and version to a schema name.
@@ -60,9 +61,9 @@ function jsonSchemaForSpec(spec) {
60
61
  * Export operations from a registry to OpenAPI paths and schemas.
61
62
  */
62
63
  function exportOperations(registry) {
63
- const specs = registry.listSpecs().filter((s) => s.meta.kind === "command" || s.meta.kind === "query").slice().sort((a, b) => {
64
+ const specs = Array.from(registry.list().values()).filter((s) => s.meta.kind === "command" || s.meta.kind === "query").sort((a, b) => {
64
65
  const byName = a.meta.key.localeCompare(b.meta.key);
65
- return byName !== 0 ? byName : a.meta.version - b.meta.version;
66
+ return byName !== 0 ? byName : compareVersions(a.meta.version, b.meta.version);
66
67
  });
67
68
  const paths = {};
68
69
  const schemas = {};
@@ -113,11 +114,11 @@ function exportOperations(registry) {
113
114
  * Generate TypeScript code for operations registry.
114
115
  */
115
116
  function generateOperationsRegistry(registry) {
116
- const specs = registry.listSpecs();
117
+ const specs = Array.from(registry.list().values());
117
118
  const imports = /* @__PURE__ */ new Set();
118
119
  const registrations = [];
119
120
  for (const spec of specs) {
120
- const specVarName = spec.meta.key.replace(/\./g, "_") + `_v${spec.meta.version}`;
121
+ const specVarName = spec.meta.key.replace(/\./g, "_") + `_v${spec.meta.version.replace(/\./g, "_")}`;
121
122
  imports.add(`import { ${specVarName} } from './${spec.meta.key.split(".")[0]}';`);
122
123
  registrations.push(` .register(${specVarName})`);
123
124
  }
@@ -1 +1 @@
1
- {"version":3,"file":"operations.js","names":["paths: Record<string, Record<string, unknown>>","schemas: Record<string, OpenApiSchemaObject>","op: Record<string, unknown>","responses: Record<string, unknown>","registrations: string[]"],"sources":["../../../src/openapi/exporter/operations.ts"],"sourcesContent":["/**\n * Operations exporter - exports OperationSpec to OpenAPI paths.\n */\nimport type {\n AnyOperationSpec,\n OperationSpec,\n OperationSpecRegistry,\n} from '@contractspec/lib.contracts';\nimport type { AnySchemaModel } from '@contractspec/lib.schema';\nimport { z } from 'zod';\nimport type { GeneratedRegistryCode } from '../types';\n\ntype OpenApiSchemaObject = Record<string, unknown>;\n\n/**\n * Convert a spec name and version to an operationId.\n */\nexport function toOperationId(name: string, version: number): string {\n return `${name.replace(/\\./g, '_')}_v${version}`;\n}\n\n/**\n * Convert a spec name and version to a schema name.\n */\nexport function toSchemaName(\n prefix: 'Input' | 'Output',\n name: string,\n version: number\n): string {\n return `${prefix}_${toOperationId(name, version)}`;\n}\n\n/**\n * Determine HTTP method from spec kind and override.\n */\nexport function toHttpMethod(\n kind: 'command' | 'query',\n override?: 'GET' | 'POST'\n): string {\n const method = override ?? (kind === 'query' ? 'GET' : 'POST');\n return method.toLowerCase();\n}\n\n/**\n * Generate default REST path from spec name and version.\n */\nexport function defaultRestPath(name: string, version: number): string {\n return `/${name.replace(/\\./g, '/')}/v${version}`;\n}\n\n/**\n * Get REST path from spec, using transport override or default.\n */\nexport function toRestPath(spec: AnyOperationSpec): string {\n const path =\n spec.transport?.rest?.path ??\n defaultRestPath(spec.meta.key, spec.meta.version);\n return path.startsWith('/') ? path : `/${path}`;\n}\n\n/**\n * Convert a SchemaModel to JSON Schema using Zod.\n */\nexport function schemaModelToJsonSchema(\n schema: AnySchemaModel | null\n): OpenApiSchemaObject | null {\n if (!schema) return null;\n return z.toJSONSchema(schema.getZod()) as OpenApiSchemaObject;\n}\n\ninterface SpecJsonSchema {\n input: OpenApiSchemaObject | null;\n output: OpenApiSchemaObject | null;\n meta: {\n key: string;\n version: number;\n kind: 'command' | 'query';\n description: string;\n tags: string[];\n stability: string;\n };\n}\n\n/**\n * Extract JSON Schema for a spec's input and output.\n */\nexport function jsonSchemaForSpec(\n spec: OperationSpec<AnySchemaModel, AnySchemaModel>\n): SpecJsonSchema {\n return {\n input: schemaModelToJsonSchema(spec.io.input),\n output: schemaModelToJsonSchema(spec.io.output as AnySchemaModel | null),\n meta: {\n key: spec.meta.key,\n version: spec.meta.version,\n kind: spec.meta.kind,\n description: spec.meta.description,\n tags: spec.meta.tags ?? [],\n stability: spec.meta.stability ?? 'stable',\n },\n };\n}\n\n/**\n * Result of exporting operations to OpenAPI format.\n */\nexport interface OperationsExportResult {\n paths: Record<string, Record<string, unknown>>;\n schemas: Record<string, OpenApiSchemaObject>;\n}\n\n/**\n * Export operations from a registry to OpenAPI paths and schemas.\n */\nexport function exportOperations(\n registry: OperationSpecRegistry\n): OperationsExportResult {\n const specs = registry\n .listSpecs()\n .filter(\n (s): s is AnyOperationSpec =>\n s.meta.kind === 'command' || s.meta.kind === 'query'\n )\n .slice()\n .sort((a, b) => {\n const byName = a.meta.key.localeCompare(b.meta.key);\n return byName !== 0 ? byName : a.meta.version - b.meta.version;\n });\n\n const paths: Record<string, Record<string, unknown>> = {};\n const schemas: Record<string, OpenApiSchemaObject> = {};\n\n for (const spec of specs) {\n const schema = jsonSchemaForSpec(\n spec as unknown as OperationSpec<AnySchemaModel, AnySchemaModel>\n );\n const method = toHttpMethod(spec.meta.kind, spec.transport?.rest?.method);\n const path = toRestPath(spec);\n\n const operationId = toOperationId(spec.meta.key, spec.meta.version);\n\n const pathItem = (paths[path] ??= {});\n const op: Record<string, unknown> = {\n operationId,\n summary: spec.meta.description ?? spec.meta.key,\n description: spec.meta.description,\n tags: spec.meta.tags ?? [],\n 'x-contractspec': {\n name: spec.meta.key,\n version: spec.meta.version,\n kind: spec.meta.kind,\n },\n responses: {},\n };\n\n if (schema.input) {\n const inputName = toSchemaName('Input', spec.meta.key, spec.meta.version);\n schemas[inputName] = schema.input;\n op['requestBody'] = {\n required: true,\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${inputName}` },\n },\n },\n };\n }\n\n const responses: Record<string, unknown> = {};\n if (schema.output) {\n const outputName = toSchemaName(\n 'Output',\n spec.meta.key,\n spec.meta.version\n );\n schemas[outputName] = schema.output;\n responses['200'] = {\n description: 'OK',\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${outputName}` },\n },\n },\n };\n } else {\n responses['200'] = { description: 'OK' };\n }\n op['responses'] = responses;\n\n pathItem[method] = op;\n }\n\n return { paths, schemas };\n}\n\n/**\n * Generate TypeScript code for operations registry.\n */\nexport function generateOperationsRegistry(\n registry: OperationSpecRegistry\n): GeneratedRegistryCode {\n const specs = registry.listSpecs();\n\n const imports = new Set<string>();\n const registrations: string[] = [];\n\n for (const spec of specs) {\n const specVarName =\n spec.meta.key.replace(/\\./g, '_') + `_v${spec.meta.version}`;\n imports.add(\n `import { ${specVarName} } from './${spec.meta.key.split('.')[0]}';`\n );\n registrations.push(` .register(${specVarName})`);\n }\n\n const code = `/**\n * Auto-generated operations registry.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\nimport { OperationSpecRegistry } from '@contractspec/lib.contracts';\n\n${Array.from(imports).join('\\n')}\n\nexport const operationsRegistry = new OperationSpecRegistry()\n${registrations.join('\\n')};\n`;\n\n return {\n code,\n fileName: 'operations-registry.ts',\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"operations.js","names":["paths: Record<string, Record<string, unknown>>","schemas: Record<string, OpenApiSchemaObject>","op: Record<string, unknown>","responses: Record<string, unknown>","registrations: string[]"],"sources":["../../../src/openapi/exporter/operations.ts"],"sourcesContent":["/**\n * Operations exporter - exports OperationSpec to OpenAPI paths.\n */\nimport type {\n AnyOperationSpec,\n OperationSpec,\n OperationSpecRegistry,\n} from '@contractspec/lib.contracts';\nimport type { AnySchemaModel } from '@contractspec/lib.schema';\nimport { z } from 'zod';\nimport { compareVersions } from 'compare-versions';\nimport type { GeneratedRegistryCode } from '../types';\n\ntype OpenApiSchemaObject = Record<string, unknown>;\n\n/**\n * Convert a spec name and version to an operationId.\n */\nexport function toOperationId(name: string, version: string): string {\n return `${name.replace(/\\./g, '_')}_v${version.replace(/\\./g, '_')}`;\n}\n\n/**\n * Convert a spec name and version to a schema name.\n */\nexport function toSchemaName(\n prefix: 'Input' | 'Output',\n name: string,\n version: string\n): string {\n return `${prefix}_${toOperationId(name, version)}`;\n}\n\n/**\n * Determine HTTP method from spec kind and override.\n */\nexport function toHttpMethod(\n kind: 'command' | 'query',\n override?: 'GET' | 'POST'\n): string {\n const method = override ?? (kind === 'query' ? 'GET' : 'POST');\n return method.toLowerCase();\n}\n\n/**\n * Generate default REST path from spec name and version.\n */\nexport function defaultRestPath(name: string, version: string): string {\n return `/${name.replace(/\\./g, '/')}/v${version}`;\n}\n\n/**\n * Get REST path from spec, using transport override or default.\n */\nexport function toRestPath(spec: AnyOperationSpec): string {\n const path =\n spec.transport?.rest?.path ??\n defaultRestPath(spec.meta.key, spec.meta.version);\n return path.startsWith('/') ? path : `/${path}`;\n}\n\n/**\n * Convert a SchemaModel to JSON Schema using Zod.\n */\nexport function schemaModelToJsonSchema(\n schema: AnySchemaModel | null\n): OpenApiSchemaObject | null {\n if (!schema) return null;\n return z.toJSONSchema(schema.getZod()) as OpenApiSchemaObject;\n}\n\ninterface SpecJsonSchema {\n input: OpenApiSchemaObject | null;\n output: OpenApiSchemaObject | null;\n meta: {\n key: string;\n version: string;\n kind: 'command' | 'query';\n description: string;\n tags: string[];\n stability: string;\n };\n}\n\n/**\n * Extract JSON Schema for a spec's input and output.\n */\nexport function jsonSchemaForSpec(\n spec: OperationSpec<AnySchemaModel, AnySchemaModel>\n): SpecJsonSchema {\n return {\n input: schemaModelToJsonSchema(spec.io.input),\n output: schemaModelToJsonSchema(spec.io.output as AnySchemaModel | null),\n meta: {\n key: spec.meta.key,\n version: spec.meta.version,\n kind: spec.meta.kind,\n description: spec.meta.description,\n tags: spec.meta.tags ?? [],\n stability: spec.meta.stability ?? 'stable',\n },\n };\n}\n\n/**\n * Result of exporting operations to OpenAPI format.\n */\nexport interface OperationsExportResult {\n paths: Record<string, Record<string, unknown>>;\n schemas: Record<string, OpenApiSchemaObject>;\n}\n\n/**\n * Export operations from a registry to OpenAPI paths and schemas.\n */\nexport function exportOperations(\n registry: OperationSpecRegistry\n): OperationsExportResult {\n const specs = Array.from(registry.list().values())\n .filter(\n (s): s is AnyOperationSpec =>\n s.meta.kind === 'command' || s.meta.kind === 'query'\n )\n .sort((a, b) => {\n const byName = a.meta.key.localeCompare(b.meta.key);\n return byName !== 0\n ? byName\n : compareVersions(a.meta.version, b.meta.version);\n });\n\n const paths: Record<string, Record<string, unknown>> = {};\n const schemas: Record<string, OpenApiSchemaObject> = {};\n\n for (const spec of specs) {\n const schema = jsonSchemaForSpec(\n spec as unknown as OperationSpec<AnySchemaModel, AnySchemaModel>\n );\n const method = toHttpMethod(spec.meta.kind, spec.transport?.rest?.method);\n const path = toRestPath(spec);\n\n const operationId = toOperationId(spec.meta.key, spec.meta.version);\n\n const pathItem = (paths[path] ??= {});\n const op: Record<string, unknown> = {\n operationId,\n summary: spec.meta.description ?? spec.meta.key,\n description: spec.meta.description,\n tags: spec.meta.tags ?? [],\n 'x-contractspec': {\n name: spec.meta.key,\n version: spec.meta.version,\n kind: spec.meta.kind,\n },\n responses: {},\n };\n\n if (schema.input) {\n const inputName = toSchemaName('Input', spec.meta.key, spec.meta.version);\n schemas[inputName] = schema.input;\n op['requestBody'] = {\n required: true,\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${inputName}` },\n },\n },\n };\n }\n\n const responses: Record<string, unknown> = {};\n if (schema.output) {\n const outputName = toSchemaName(\n 'Output',\n spec.meta.key,\n spec.meta.version\n );\n schemas[outputName] = schema.output;\n responses['200'] = {\n description: 'OK',\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${outputName}` },\n },\n },\n };\n } else {\n responses['200'] = { description: 'OK' };\n }\n op['responses'] = responses;\n\n pathItem[method] = op;\n }\n\n return { paths, schemas };\n}\n\n/**\n * Generate TypeScript code for operations registry.\n */\nexport function generateOperationsRegistry(\n registry: OperationSpecRegistry\n): GeneratedRegistryCode {\n const specs = Array.from(registry.list().values());\n\n const imports = new Set<string>();\n const registrations: string[] = [];\n\n for (const spec of specs) {\n const specVarName =\n spec.meta.key.replace(/\\./g, '_') +\n `_v${spec.meta.version.replace(/\\./g, '_')}`;\n imports.add(\n `import { ${specVarName} } from './${spec.meta.key.split('.')[0]}';`\n );\n registrations.push(` .register(${specVarName})`);\n }\n\n const code = `/**\n * Auto-generated operations registry.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\nimport { OperationSpecRegistry } from '@contractspec/lib.contracts';\n\n${Array.from(imports).join('\\n')}\n\nexport const operationsRegistry = new OperationSpecRegistry()\n${registrations.join('\\n')};\n`;\n\n return {\n code,\n fileName: 'operations-registry.ts',\n };\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { GeneratedRegistryCode } from "../types.js";
2
- import { PresentationRegistry, PresentationSpec } from "@contractspec/lib.contracts";
2
+ import { PresentationRegistry, PresentationSpec, Stability } from "@contractspec/lib.contracts";
3
3
 
4
4
  //#region src/openapi/exporter/presentations.d.ts
5
5
 
@@ -8,9 +8,9 @@ import { PresentationRegistry, PresentationSpec } from "@contractspec/lib.contra
8
8
  */
9
9
  interface ExportedPresentation {
10
10
  name: string;
11
- version: number;
12
- description?: string;
13
- stability?: string;
11
+ version: string;
12
+ description: string;
13
+ stability: Stability;
14
14
  sourceType: 'component' | 'blocknotejs';
15
15
  targets: string[];
16
16
  tags?: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"presentations.d.ts","names":[],"sources":["../../../src/openapi/exporter/presentations.ts"],"sourcesContent":[],"mappings":";;;;;AAyBA;AAiBA;AAiBA;UA/CiB,oBAAA;;;;;;;;;;;;iBAaD,mBAAA,WACJ,uBACT;;;;iBAea,4BAAA,cACD,qBACZ;;;;iBAea,6BAAA,WACJ,uBACT"}
1
+ {"version":3,"file":"presentations.d.ts","names":[],"sources":["../../../src/openapi/exporter/presentations.ts"],"sourcesContent":[],"mappings":";;;;;AA0BA;AAiBA;AAiBA;UA/CiB,oBAAA;;;;aAIJ;;;;;;;;iBASG,mBAAA,WACJ,uBACT;;;;iBAea,4BAAA,cACD,qBACZ;;;;iBAea,6BAAA,WACJ,uBACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"presentations.js","names":["registrations: string[]"],"sources":["../../../src/openapi/exporter/presentations.ts"],"sourcesContent":["/**\n * Presentations exporter - exports PresentationSpec to OpenAPI extensions.\n */\nimport type {\n PresentationSpec,\n PresentationRegistry,\n} from '@contractspec/lib.contracts';\nimport type { GeneratedRegistryCode } from '../types';\n\n/**\n * Exported presentation structure for OpenAPI extensions.\n */\nexport interface ExportedPresentation {\n name: string;\n version: number;\n description?: string;\n stability?: string;\n sourceType: 'component' | 'blocknotejs';\n targets: string[];\n tags?: string[];\n}\n\n/**\n * Export presentations to OpenAPI extension format.\n */\nexport function exportPresentations(\n registry: PresentationRegistry\n): ExportedPresentation[] {\n return registry.list().map((pres) => ({\n name: pres.meta.key,\n version: pres.meta.version,\n description: pres.meta.description,\n stability: pres.meta.stability,\n sourceType: pres.source.type,\n targets: pres.targets,\n tags: pres.meta.tags,\n }));\n}\n\n/**\n * Export presentations from an array.\n */\nexport function exportPresentationsFromArray(\n descriptors: PresentationSpec[]\n): ExportedPresentation[] {\n return descriptors.map((desc) => ({\n name: desc.meta.key,\n version: desc.meta.version,\n description: desc.meta.description,\n stability: desc.meta.stability,\n sourceType: desc.source.type,\n targets: desc.targets,\n tags: desc.meta.tags,\n }));\n}\n\n/**\n * Generate TypeScript code for presentations registry.\n */\nexport function generatePresentationsRegistry(\n registry: PresentationRegistry\n): GeneratedRegistryCode {\n const presentations = registry.list();\n const imports = new Set<string>();\n const registrations: string[] = [];\n\n for (const pres of presentations) {\n const presVarName =\n pres.meta.key.replace(/\\./g, '_') + `_v${pres.meta.version}`;\n imports.add(\n `import { ${presVarName} } from './${pres.meta.key.split('.')[0]}';`\n );\n registrations.push(` .register(${presVarName})`);\n }\n\n const code = `/**\n * Auto-generated presentations registry.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\nimport { PresentationRegistry } from '@contractspec/lib.contracts';\n\n${Array.from(imports).join('\\n')}\n\nexport const presentationsRegistry = new PresentationRegistry()\n${registrations.join('\\n')};\n`;\n\n return {\n code,\n fileName: 'presentations-registry.ts',\n };\n}\n"],"mappings":";;;;AAyBA,SAAgB,oBACd,UACwB;AACxB,QAAO,SAAS,MAAM,CAAC,KAAK,UAAU;EACpC,MAAM,KAAK,KAAK;EAChB,SAAS,KAAK,KAAK;EACnB,aAAa,KAAK,KAAK;EACvB,WAAW,KAAK,KAAK;EACrB,YAAY,KAAK,OAAO;EACxB,SAAS,KAAK;EACd,MAAM,KAAK,KAAK;EACjB,EAAE;;;;;AAML,SAAgB,6BACd,aACwB;AACxB,QAAO,YAAY,KAAK,UAAU;EAChC,MAAM,KAAK,KAAK;EAChB,SAAS,KAAK,KAAK;EACnB,aAAa,KAAK,KAAK;EACvB,WAAW,KAAK,KAAK;EACrB,YAAY,KAAK,OAAO;EACxB,SAAS,KAAK;EACd,MAAM,KAAK,KAAK;EACjB,EAAE;;;;;AAML,SAAgB,8BACd,UACuB;CACvB,MAAM,gBAAgB,SAAS,MAAM;CACrC,MAAM,0BAAU,IAAI,KAAa;CACjC,MAAMA,gBAA0B,EAAE;AAElC,MAAK,MAAM,QAAQ,eAAe;EAChC,MAAM,cACJ,KAAK,KAAK,IAAI,QAAQ,OAAO,IAAI,GAAG,KAAK,KAAK,KAAK;AACrD,UAAQ,IACN,YAAY,YAAY,aAAa,KAAK,KAAK,IAAI,MAAM,IAAI,CAAC,GAAG,IAClE;AACD,gBAAc,KAAK,eAAe,YAAY,GAAG;;AAenD,QAAO;EACL,MAbW;;;;;;EAMb,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAAC;;;EAG/B,cAAc,KAAK,KAAK,CAAC;;EAKvB,UAAU;EACX"}
1
+ {"version":3,"file":"presentations.js","names":["registrations: string[]"],"sources":["../../../src/openapi/exporter/presentations.ts"],"sourcesContent":["/**\n * Presentations exporter - exports PresentationSpec to OpenAPI extensions.\n */\nimport type {\n PresentationSpec,\n PresentationRegistry,\n Stability,\n} from '@contractspec/lib.contracts';\nimport type { GeneratedRegistryCode } from '../types';\n\n/**\n * Exported presentation structure for OpenAPI extensions.\n */\nexport interface ExportedPresentation {\n name: string;\n version: string;\n description: string; // Changed from description?: string;\n stability: Stability; // Changed from stability?: string;\n sourceType: 'component' | 'blocknotejs';\n targets: string[];\n tags?: string[];\n}\n\n/**\n * Export presentations to OpenAPI extension format.\n */\nexport function exportPresentations(\n registry: PresentationRegistry\n): ExportedPresentation[] {\n return registry.list().map((pres) => ({\n name: pres.meta.key,\n version: pres.meta.version,\n description: pres.meta.description,\n stability: pres.meta.stability,\n sourceType: pres.source.type,\n targets: pres.targets,\n tags: pres.meta.tags,\n }));\n}\n\n/**\n * Export presentations from an array.\n */\nexport function exportPresentationsFromArray(\n descriptors: PresentationSpec[]\n): ExportedPresentation[] {\n return descriptors.map((desc) => ({\n name: desc.meta.key,\n version: desc.meta.version,\n description: desc.meta.description,\n stability: desc.meta.stability,\n sourceType: desc.source.type,\n targets: desc.targets,\n tags: desc.meta.tags,\n }));\n}\n\n/**\n * Generate TypeScript code for presentations registry.\n */\nexport function generatePresentationsRegistry(\n registry: PresentationRegistry\n): GeneratedRegistryCode {\n const presentations = registry.list();\n const imports = new Set<string>();\n const registrations: string[] = [];\n\n for (const pres of presentations) {\n const presVarName =\n pres.meta.key.replace(/\\./g, '_') + `_v${pres.meta.version}`;\n imports.add(\n `import { ${presVarName} } from './${pres.meta.key.split('.')[0]}';`\n );\n registrations.push(` .register(${presVarName})`);\n }\n\n const code = `/**\n * Auto-generated presentations registry.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\nimport { PresentationRegistry } from '@contractspec/lib.contracts';\n\n${Array.from(imports).join('\\n')}\n\nexport const presentationsRegistry = new PresentationRegistry()\n${registrations.join('\\n')};\n`;\n\n return {\n code,\n fileName: 'presentations-registry.ts',\n };\n}\n"],"mappings":";;;;AA0BA,SAAgB,oBACd,UACwB;AACxB,QAAO,SAAS,MAAM,CAAC,KAAK,UAAU;EACpC,MAAM,KAAK,KAAK;EAChB,SAAS,KAAK,KAAK;EACnB,aAAa,KAAK,KAAK;EACvB,WAAW,KAAK,KAAK;EACrB,YAAY,KAAK,OAAO;EACxB,SAAS,KAAK;EACd,MAAM,KAAK,KAAK;EACjB,EAAE;;;;;AAML,SAAgB,6BACd,aACwB;AACxB,QAAO,YAAY,KAAK,UAAU;EAChC,MAAM,KAAK,KAAK;EAChB,SAAS,KAAK,KAAK;EACnB,aAAa,KAAK,KAAK;EACvB,WAAW,KAAK,KAAK;EACrB,YAAY,KAAK,OAAO;EACxB,SAAS,KAAK;EACd,MAAM,KAAK,KAAK;EACjB,EAAE;;;;;AAML,SAAgB,8BACd,UACuB;CACvB,MAAM,gBAAgB,SAAS,MAAM;CACrC,MAAM,0BAAU,IAAI,KAAa;CACjC,MAAMA,gBAA0B,EAAE;AAElC,MAAK,MAAM,QAAQ,eAAe;EAChC,MAAM,cACJ,KAAK,KAAK,IAAI,QAAQ,OAAO,IAAI,GAAG,KAAK,KAAK,KAAK;AACrD,UAAQ,IACN,YAAY,YAAY,aAAa,KAAK,KAAK,IAAI,MAAM,IAAI,CAAC,GAAG,IAClE;AACD,gBAAc,KAAK,eAAe,YAAY,GAAG;;AAenD,QAAO;EACL,MAbW;;;;;;EAMb,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAAC;;;EAG/B,cAAc,KAAK,KAAK,CAAC;;EAKvB,UAAU;EACX"}
@@ -8,7 +8,7 @@ import { WorkflowRegistry } from "@contractspec/lib.contracts";
8
8
  */
9
9
  interface ExportedWorkflow {
10
10
  name: string;
11
- version: number;
11
+ version: string;
12
12
  description?: string;
13
13
  stability?: string;
14
14
  owners?: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"workflows.js","names":["registrations: string[]"],"sources":["../../../src/openapi/exporter/workflows.ts"],"sourcesContent":["/**\n * Workflows exporter - exports WorkflowSpec to OpenAPI extensions.\n */\nimport type { WorkflowRegistry } from '@contractspec/lib.contracts';\nimport type { GeneratedRegistryCode } from '../types';\n\n/**\n * Exported workflow structure for OpenAPI extensions.\n */\nexport interface ExportedWorkflow {\n name: string;\n version: number;\n description?: string;\n stability?: string;\n owners?: string[];\n steps: {\n id: string;\n type: 'human' | 'automation' | 'decision';\n label: string;\n }[];\n transitions: {\n from: string;\n to: string;\n label?: string;\n }[];\n}\n\n/**\n * Export workflows to OpenAPI extension format.\n */\nexport function exportWorkflows(\n registry: WorkflowRegistry\n): ExportedWorkflow[] {\n return registry.list().map((wf) => ({\n name: wf.meta.key,\n version: wf.meta.version,\n description: wf.meta.description,\n stability: wf.meta.stability,\n owners: wf.meta.owners,\n steps: wf.definition.steps.map((s) => ({\n id: s.id,\n type: s.type,\n label: s.label,\n })),\n transitions: wf.definition.transitions.map((t) => ({\n from: t.from,\n to: t.to,\n label: t.label,\n })),\n }));\n}\n\n/**\n * Generate TypeScript code for workflows registry.\n */\nexport function generateWorkflowsRegistry(\n registry: WorkflowRegistry\n): GeneratedRegistryCode {\n const workflows = registry.list();\n const imports = new Set<string>();\n const registrations: string[] = [];\n\n for (const wf of workflows) {\n const wfVarName = wf.meta.key.replace(/\\./g, '_') + `_v${wf.meta.version}`;\n imports.add(\n `import { ${wfVarName} } from './${wf.meta.key.split('.')[0]}';`\n );\n registrations.push(` .register(${wfVarName})`);\n }\n\n const code = `/**\n * Auto-generated workflows registry.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\nimport { WorkflowRegistry } from '@contractspec/lib.contracts';\n\n${Array.from(imports).join('\\n')}\n\nexport const workflowsRegistry = new WorkflowRegistry()\n${registrations.join('\\n')};\n`;\n\n return {\n code,\n fileName: 'workflows-registry.ts',\n };\n}\n"],"mappings":";;;;AA8BA,SAAgB,gBACd,UACoB;AACpB,QAAO,SAAS,MAAM,CAAC,KAAK,QAAQ;EAClC,MAAM,GAAG,KAAK;EACd,SAAS,GAAG,KAAK;EACjB,aAAa,GAAG,KAAK;EACrB,WAAW,GAAG,KAAK;EACnB,QAAQ,GAAG,KAAK;EAChB,OAAO,GAAG,WAAW,MAAM,KAAK,OAAO;GACrC,IAAI,EAAE;GACN,MAAM,EAAE;GACR,OAAO,EAAE;GACV,EAAE;EACH,aAAa,GAAG,WAAW,YAAY,KAAK,OAAO;GACjD,MAAM,EAAE;GACR,IAAI,EAAE;GACN,OAAO,EAAE;GACV,EAAE;EACJ,EAAE;;;;;AAML,SAAgB,0BACd,UACuB;CACvB,MAAM,YAAY,SAAS,MAAM;CACjC,MAAM,0BAAU,IAAI,KAAa;CACjC,MAAMA,gBAA0B,EAAE;AAElC,MAAK,MAAM,MAAM,WAAW;EAC1B,MAAM,YAAY,GAAG,KAAK,IAAI,QAAQ,OAAO,IAAI,GAAG,KAAK,GAAG,KAAK;AACjE,UAAQ,IACN,YAAY,UAAU,aAAa,GAAG,KAAK,IAAI,MAAM,IAAI,CAAC,GAAG,IAC9D;AACD,gBAAc,KAAK,eAAe,UAAU,GAAG;;AAejD,QAAO;EACL,MAbW;;;;;;EAMb,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAAC;;;EAG/B,cAAc,KAAK,KAAK,CAAC;;EAKvB,UAAU;EACX"}
1
+ {"version":3,"file":"workflows.js","names":["registrations: string[]"],"sources":["../../../src/openapi/exporter/workflows.ts"],"sourcesContent":["/**\n * Workflows exporter - exports WorkflowSpec to OpenAPI extensions.\n */\nimport type { WorkflowRegistry } from '@contractspec/lib.contracts';\nimport type { GeneratedRegistryCode } from '../types';\n\n/**\n * Exported workflow structure for OpenAPI extensions.\n */\nexport interface ExportedWorkflow {\n name: string;\n version: string;\n description?: string;\n stability?: string;\n owners?: string[];\n steps: {\n id: string;\n type: 'human' | 'automation' | 'decision';\n label: string;\n }[];\n transitions: {\n from: string;\n to: string;\n label?: string;\n }[];\n}\n\n/**\n * Export workflows to OpenAPI extension format.\n */\nexport function exportWorkflows(\n registry: WorkflowRegistry\n): ExportedWorkflow[] {\n return registry.list().map((wf) => ({\n name: wf.meta.key,\n version: wf.meta.version,\n description: wf.meta.description,\n stability: wf.meta.stability,\n owners: wf.meta.owners,\n steps: wf.definition.steps.map((s) => ({\n id: s.id,\n type: s.type,\n label: s.label,\n })),\n transitions: wf.definition.transitions.map((t) => ({\n from: t.from,\n to: t.to,\n label: t.label,\n })),\n }));\n}\n\n/**\n * Generate TypeScript code for workflows registry.\n */\nexport function generateWorkflowsRegistry(\n registry: WorkflowRegistry\n): GeneratedRegistryCode {\n const workflows = registry.list();\n const imports = new Set<string>();\n const registrations: string[] = [];\n\n for (const wf of workflows) {\n const wfVarName = wf.meta.key.replace(/\\./g, '_') + `_v${wf.meta.version}`;\n imports.add(\n `import { ${wfVarName} } from './${wf.meta.key.split('.')[0]}';`\n );\n registrations.push(` .register(${wfVarName})`);\n }\n\n const code = `/**\n * Auto-generated workflows registry.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\nimport { WorkflowRegistry } from '@contractspec/lib.contracts';\n\n${Array.from(imports).join('\\n')}\n\nexport const workflowsRegistry = new WorkflowRegistry()\n${registrations.join('\\n')};\n`;\n\n return {\n code,\n fileName: 'workflows-registry.ts',\n };\n}\n"],"mappings":";;;;AA8BA,SAAgB,gBACd,UACoB;AACpB,QAAO,SAAS,MAAM,CAAC,KAAK,QAAQ;EAClC,MAAM,GAAG,KAAK;EACd,SAAS,GAAG,KAAK;EACjB,aAAa,GAAG,KAAK;EACrB,WAAW,GAAG,KAAK;EACnB,QAAQ,GAAG,KAAK;EAChB,OAAO,GAAG,WAAW,MAAM,KAAK,OAAO;GACrC,IAAI,EAAE;GACN,MAAM,EAAE;GACR,OAAO,EAAE;GACV,EAAE;EACH,aAAa,GAAG,WAAW,YAAY,KAAK,OAAO;GACjD,MAAM,EAAE;GACR,IAAI,EAAE;GACN,OAAO,EAAE;GACV,EAAE;EACJ,EAAE;;;;;AAML,SAAgB,0BACd,UACuB;CACvB,MAAM,YAAY,SAAS,MAAM;CACjC,MAAM,0BAAU,IAAI,KAAa;CACjC,MAAMA,gBAA0B,EAAE;AAElC,MAAK,MAAM,MAAM,WAAW;EAC1B,MAAM,YAAY,GAAG,KAAK,IAAI,QAAQ,OAAO,IAAI,GAAG,KAAK,GAAG,KAAK;AACjE,UAAQ,IACN,YAAY,UAAU,aAAa,GAAG,KAAK,IAAI,MAAM,IAAI,CAAC,GAAG,IAC9D;AACD,gBAAc,KAAK,eAAe,UAAU,GAAG;;AAejD,QAAO;EACL,MAbW;;;;;;EAMb,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAAC;;;EAG/B,cAAc,KAAK,KAAK,CAAC;;EAKvB,UAAU;EACX"}
@@ -27,7 +27,7 @@ ${payloadModel.code}
27
27
  export const ${eventName} = defineEvent({
28
28
  meta: {
29
29
  key: '${event.name}',
30
- version: 1,
30
+ version: '1.0.0',
31
31
  description: ${JSON.stringify(event.description ?? "")},
32
32
  },
33
33
  payload: ${payloadModel.name},
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","names":[],"sources":["../../../src/openapi/importer/events.ts"],"sourcesContent":["import type { ParsedEvent } from '../types';\nimport { generateImports, generateSchemaModelCode } from '../schema-converter';\nimport { toPascalCase, toValidIdentifier } from '../../common/utils';\nimport type { ContractsrcConfig } from '@contractspec/lib.contracts';\n\n/**\n * Generate code for an event.\n */\nexport function generateEventCode(\n event: ParsedEvent,\n options: ContractsrcConfig\n): string {\n const eventName = toValidIdentifier(event.name);\n const modelName = toPascalCase(eventName) + 'Payload';\n\n const schemaFormat = options.schemaFormat || 'contractspec';\n // Generate payload model inline or referenced?\n // Let's generate the payload schema definition first\n const payloadModel = generateSchemaModelCode(\n event.payload,\n modelName,\n schemaFormat,\n options\n );\n\n const imports = new Set<string>();\n imports.add(\n \"import { defineEvent, type EventSpec } from '@contractspec/lib.contracts';\"\n );\n\n if (payloadModel.imports && payloadModel.imports.length > 0) {\n payloadModel.imports.forEach((i) => imports.add(i));\n } else if (payloadModel.fields && payloadModel.fields.length > 0) {\n const modelImports = generateImports(payloadModel.fields, options);\n // Merge imports - this is a bit hacky string manipulation but works for now\n modelImports\n .split('\\n')\n .filter(Boolean)\n .forEach((i) => imports.add(i));\n }\n\n // If payloadModel is a reference (empty fields and different name), import it\n if (payloadModel.name !== modelName) {\n const modelsDir = `../${options.conventions.models}`;\n const kebabName = payloadModel.name\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase();\n imports.add(\n `import { ${payloadModel.name} } from '${modelsDir}/${kebabName}';`\n );\n }\n\n const allImports = Array.from(imports).join('\\n');\n\n return `\n${allImports}\n\n${payloadModel.code}\n\nexport const ${eventName} = defineEvent({\n meta: {\n key: '${event.name}',\n version: 1,\n description: ${JSON.stringify(event.description ?? '')},\n },\n payload: ${payloadModel.name},\n});\n`.trim();\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,kBACd,OACA,SACQ;CACR,MAAM,YAAY,kBAAkB,MAAM,KAAK;CAC/C,MAAM,YAAY,aAAa,UAAU,GAAG;CAE5C,MAAM,eAAe,QAAQ,gBAAgB;CAG7C,MAAM,eAAe,wBACnB,MAAM,SACN,WACA,cACA,QACD;CAED,MAAM,0BAAU,IAAI,KAAa;AACjC,SAAQ,IACN,6EACD;AAED,KAAI,aAAa,WAAW,aAAa,QAAQ,SAAS,EACxD,cAAa,QAAQ,SAAS,MAAM,QAAQ,IAAI,EAAE,CAAC;UAC1C,aAAa,UAAU,aAAa,OAAO,SAAS,EAG7D,CAFqB,gBAAgB,aAAa,QAAQ,QAAQ,CAG/D,MAAM,KAAK,CACX,OAAO,QAAQ,CACf,SAAS,MAAM,QAAQ,IAAI,EAAE,CAAC;AAInC,KAAI,aAAa,SAAS,WAAW;EACnC,MAAM,YAAY,MAAM,QAAQ,YAAY;EAC5C,MAAM,YAAY,aAAa,KAC5B,QAAQ,sBAAsB,QAAQ,CACtC,aAAa;AAChB,UAAQ,IACN,YAAY,aAAa,KAAK,WAAW,UAAU,GAAG,UAAU,IACjE;;AAKH,QAAO;EAFY,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAGtC;;EAEX,aAAa,KAAK;;eAEL,UAAU;;YAEb,MAAM,KAAK;;mBAEJ,KAAK,UAAU,MAAM,eAAe,GAAG,CAAC;;aAE9C,aAAa,KAAK;;EAE7B,MAAM"}
1
+ {"version":3,"file":"events.js","names":[],"sources":["../../../src/openapi/importer/events.ts"],"sourcesContent":["import type { ParsedEvent } from '../types';\nimport { generateImports, generateSchemaModelCode } from '../schema-converter';\nimport { toPascalCase, toValidIdentifier } from '../../common/utils';\nimport type { ContractsrcConfig } from '@contractspec/lib.contracts';\n\n/**\n * Generate code for an event.\n */\nexport function generateEventCode(\n event: ParsedEvent,\n options: ContractsrcConfig\n): string {\n const eventName = toValidIdentifier(event.name);\n const modelName = toPascalCase(eventName) + 'Payload';\n\n const schemaFormat = options.schemaFormat || 'contractspec';\n // Generate payload model inline or referenced?\n // Let's generate the payload schema definition first\n const payloadModel = generateSchemaModelCode(\n event.payload,\n modelName,\n schemaFormat,\n options\n );\n\n const imports = new Set<string>();\n imports.add(\n \"import { defineEvent, type EventSpec } from '@contractspec/lib.contracts';\"\n );\n\n if (payloadModel.imports && payloadModel.imports.length > 0) {\n payloadModel.imports.forEach((i) => imports.add(i));\n } else if (payloadModel.fields && payloadModel.fields.length > 0) {\n const modelImports = generateImports(payloadModel.fields, options);\n // Merge imports - this is a bit hacky string manipulation but works for now\n modelImports\n .split('\\n')\n .filter(Boolean)\n .forEach((i) => imports.add(i));\n }\n\n // If payloadModel is a reference (empty fields and different name), import it\n if (payloadModel.name !== modelName) {\n const modelsDir = `../${options.conventions.models}`;\n const kebabName = payloadModel.name\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .toLowerCase();\n imports.add(\n `import { ${payloadModel.name} } from '${modelsDir}/${kebabName}';`\n );\n }\n\n const allImports = Array.from(imports).join('\\n');\n\n return `\n${allImports}\n\n${payloadModel.code}\n\nexport const ${eventName} = defineEvent({\n meta: {\n key: '${event.name}',\n version: '1.0.0',\n description: ${JSON.stringify(event.description ?? '')},\n },\n payload: ${payloadModel.name},\n});\n`.trim();\n}\n"],"mappings":";;;;;;;AAQA,SAAgB,kBACd,OACA,SACQ;CACR,MAAM,YAAY,kBAAkB,MAAM,KAAK;CAC/C,MAAM,YAAY,aAAa,UAAU,GAAG;CAE5C,MAAM,eAAe,QAAQ,gBAAgB;CAG7C,MAAM,eAAe,wBACnB,MAAM,SACN,WACA,cACA,QACD;CAED,MAAM,0BAAU,IAAI,KAAa;AACjC,SAAQ,IACN,6EACD;AAED,KAAI,aAAa,WAAW,aAAa,QAAQ,SAAS,EACxD,cAAa,QAAQ,SAAS,MAAM,QAAQ,IAAI,EAAE,CAAC;UAC1C,aAAa,UAAU,aAAa,OAAO,SAAS,EAG7D,CAFqB,gBAAgB,aAAa,QAAQ,QAAQ,CAG/D,MAAM,KAAK,CACX,OAAO,QAAQ,CACf,SAAS,MAAM,QAAQ,IAAI,EAAE,CAAC;AAInC,KAAI,aAAa,SAAS,WAAW;EACnC,MAAM,YAAY,MAAM,QAAQ,YAAY;EAC5C,MAAM,YAAY,aAAa,KAC5B,QAAQ,sBAAsB,QAAQ,CACtC,aAAa;AAChB,UAAQ,IACN,YAAY,aAAa,KAAK,WAAW,UAAU,GAAG,UAAU,IACjE;;AAKH,QAAO;EAFY,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,CAGtC;;EAEX,aAAa,KAAK;;eAEL,UAAU;;YAEb,MAAM,KAAK;;mBAEJ,KAAK,UAAU,MAAM,eAAe,GAAG,CAAC;;aAE9C,aAAa,KAAK;;EAE7B,MAAM"}
@@ -70,7 +70,7 @@ function generateSpecCode(operation, contractspecConfig, options = {}, inputMode
70
70
  lines.push(`export const ${safeName}Spec = ${defineFunc}({`);
71
71
  lines.push(" meta: {");
72
72
  lines.push(` key: '${specKey}',`);
73
- lines.push(" version: 1,");
73
+ lines.push(" version: '1.0.0',");
74
74
  lines.push(` stability: '${options.defaultStability ?? "stable"}',`);
75
75
  lines.push(` owners: [${(options.defaultOwners ?? []).map((o) => `'${o}'`).join(", ")}],`);
76
76
  lines.push(` tags: [${operation.tags.map((t) => `'${t}'`).join(", ")}],`);
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","names":["lines: string[]"],"sources":["../../../src/openapi/importer/generator.ts"],"sourcesContent":["import type { ParsedOperation } from '../types';\nimport { toPascalCase, toSpecKey, toValidIdentifier } from '../../common/utils';\nimport { type GeneratedModel, generateImports } from '../schema-converter';\nimport { inferAuthLevel, inferOpKind } from './analyzer';\nimport type {\n ContractsrcConfig,\n OpenApiSourceConfig,\n} from '@contractspec/lib.contracts';\n\n/**\n * Generate ContractSpec TypeScript code for an operation.\n */\nexport function generateSpecCode(\n operation: ParsedOperation,\n contractspecConfig: ContractsrcConfig,\n options: Partial<OpenApiSourceConfig> = {},\n inputModel: GeneratedModel | null,\n outputModel: GeneratedModel | null,\n queryModel: GeneratedModel | null = null,\n paramsModel: GeneratedModel | null = null,\n headersModel: GeneratedModel | null = null\n): string {\n const specKey = toSpecKey(operation.operationId, options.prefix);\n const kind = inferOpKind(operation.method);\n const auth = inferAuthLevel(operation, options.defaultAuth ?? 'user');\n\n const lines: string[] = [];\n\n // Imports\n lines.push(\n \"import { defineCommand, defineQuery } from '@contractspec/lib.contracts';\"\n );\n if (inputModel || outputModel || queryModel || paramsModel || headersModel) {\n const collectedImports = new Set<string>();\n const models = [\n inputModel,\n outputModel,\n queryModel,\n paramsModel,\n headersModel,\n ].filter((m): m is GeneratedModel => !!m);\n\n // Add explicit imports from generators (e.g. Zod, JsonSchema)\n models.forEach((m) => {\n if (m.imports && m.imports.length > 0) {\n m.imports.forEach((i) => collectedImports.add(i));\n }\n });\n\n // Add legacy fields-based imports (ContractSpec format)\n const legacyModels = models.filter(\n (m) => !m.imports || m.imports.length === 0\n );\n const legacyFields = legacyModels.flatMap((m) => m.fields);\n\n if (legacyFields.length > 0) {\n const legacyImportStr = generateImports(\n legacyFields,\n contractspecConfig,\n false\n );\n legacyImportStr\n .split('\\n')\n .filter(Boolean)\n .forEach((i) => collectedImports.add(i));\n }\n\n if (collectedImports.size > 0) {\n lines.push(Array.from(collectedImports).sort().join('\\n'));\n }\n }\n lines.push('');\n\n // Generate schemas\n const schemaSections = [\n { label: 'Input schema', model: inputModel },\n { label: 'Query schema', model: queryModel },\n { label: 'Path schema', model: paramsModel },\n { label: 'Header schema', model: headersModel },\n { label: 'Output schema', model: outputModel },\n ];\n\n for (const section of schemaSections) {\n if (section.model && section.model.code) {\n lines.push(`// ${section.label}`);\n lines.push(section.model.code);\n lines.push('');\n }\n }\n\n // Generate spec\n const defineFunc = kind === 'command' ? 'defineCommand' : 'defineQuery';\n const safeName = toValidIdentifier(toPascalCase(operation.operationId));\n\n lines.push(`/**`);\n lines.push(` * ${operation.summary ?? operation.operationId}`);\n if (operation.description) {\n lines.push(` *`);\n lines.push(` * ${operation.description}`);\n }\n lines.push(` *`);\n lines.push(\n ` * @source OpenAPI: ${operation.method.toUpperCase()} ${operation.path}`\n );\n lines.push(` */`);\n lines.push(`export const ${safeName}Spec = ${defineFunc}({`);\n\n // Meta\n lines.push(' meta: {');\n lines.push(` key: '${specKey}',`);\n lines.push(' version: 1,');\n lines.push(` stability: '${options.defaultStability ?? 'stable'}',`);\n lines.push(\n ` owners: [${(options.defaultOwners ?? []).map((o) => `'${o}'`).join(', ')}],`\n );\n lines.push(` tags: [${operation.tags.map((t) => `'${t}'`).join(', ')}],`);\n lines.push(\n ` description: ${JSON.stringify(operation.summary ?? operation.operationId)},`\n );\n lines.push(\n ` goal: ${JSON.stringify(operation.description ?? 'Imported from OpenAPI')},`\n );\n lines.push(\n ` context: 'Imported from OpenAPI: ${operation.method.toUpperCase()} ${operation.path}',`\n );\n lines.push(' },');\n\n // IO\n lines.push(' io: {');\n lines.push(` input: ${inputModel?.name ?? 'null'},`);\n if (queryModel) lines.push(` query: ${queryModel.name},`);\n if (paramsModel) lines.push(` params: ${paramsModel.name},`);\n if (headersModel) lines.push(` headers: ${headersModel.name},`);\n\n if (outputModel) {\n lines.push(` output: ${outputModel.name},`);\n } else {\n lines.push(' output: null, // TODO: Define output schema');\n }\n lines.push(' },');\n\n // Policy\n lines.push(' policy: {');\n lines.push(` auth: '${auth}',`);\n lines.push(' },');\n\n // Transport hints\n const httpMethod = operation.method.toUpperCase();\n const restMethod = httpMethod === 'GET' ? 'GET' : 'POST';\n lines.push(' transport: {');\n lines.push(' rest: {');\n lines.push(` method: '${restMethod}',`);\n lines.push(` path: '${operation.path}',`);\n lines.push(' },');\n lines.push(' },');\n\n lines.push('});');\n\n return lines.join('\\n');\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"generator.js","names":["lines: string[]"],"sources":["../../../src/openapi/importer/generator.ts"],"sourcesContent":["import type { ParsedOperation } from '../types';\nimport { toPascalCase, toSpecKey, toValidIdentifier } from '../../common/utils';\nimport { type GeneratedModel, generateImports } from '../schema-converter';\nimport { inferAuthLevel, inferOpKind } from './analyzer';\nimport type {\n ContractsrcConfig,\n OpenApiSourceConfig,\n} from '@contractspec/lib.contracts';\n\n/**\n * Generate ContractSpec TypeScript code for an operation.\n */\nexport function generateSpecCode(\n operation: ParsedOperation,\n contractspecConfig: ContractsrcConfig,\n options: Partial<OpenApiSourceConfig> = {},\n inputModel: GeneratedModel | null,\n outputModel: GeneratedModel | null,\n queryModel: GeneratedModel | null = null,\n paramsModel: GeneratedModel | null = null,\n headersModel: GeneratedModel | null = null\n): string {\n const specKey = toSpecKey(operation.operationId, options.prefix);\n const kind = inferOpKind(operation.method);\n const auth = inferAuthLevel(operation, options.defaultAuth ?? 'user');\n\n const lines: string[] = [];\n\n // Imports\n lines.push(\n \"import { defineCommand, defineQuery } from '@contractspec/lib.contracts';\"\n );\n if (inputModel || outputModel || queryModel || paramsModel || headersModel) {\n const collectedImports = new Set<string>();\n const models = [\n inputModel,\n outputModel,\n queryModel,\n paramsModel,\n headersModel,\n ].filter((m): m is GeneratedModel => !!m);\n\n // Add explicit imports from generators (e.g. Zod, JsonSchema)\n models.forEach((m) => {\n if (m.imports && m.imports.length > 0) {\n m.imports.forEach((i) => collectedImports.add(i));\n }\n });\n\n // Add legacy fields-based imports (ContractSpec format)\n const legacyModels = models.filter(\n (m) => !m.imports || m.imports.length === 0\n );\n const legacyFields = legacyModels.flatMap((m) => m.fields);\n\n if (legacyFields.length > 0) {\n const legacyImportStr = generateImports(\n legacyFields,\n contractspecConfig,\n false\n );\n legacyImportStr\n .split('\\n')\n .filter(Boolean)\n .forEach((i) => collectedImports.add(i));\n }\n\n if (collectedImports.size > 0) {\n lines.push(Array.from(collectedImports).sort().join('\\n'));\n }\n }\n lines.push('');\n\n // Generate schemas\n const schemaSections = [\n { label: 'Input schema', model: inputModel },\n { label: 'Query schema', model: queryModel },\n { label: 'Path schema', model: paramsModel },\n { label: 'Header schema', model: headersModel },\n { label: 'Output schema', model: outputModel },\n ];\n\n for (const section of schemaSections) {\n if (section.model && section.model.code) {\n lines.push(`// ${section.label}`);\n lines.push(section.model.code);\n lines.push('');\n }\n }\n\n // Generate spec\n const defineFunc = kind === 'command' ? 'defineCommand' : 'defineQuery';\n const safeName = toValidIdentifier(toPascalCase(operation.operationId));\n\n lines.push(`/**`);\n lines.push(` * ${operation.summary ?? operation.operationId}`);\n if (operation.description) {\n lines.push(` *`);\n lines.push(` * ${operation.description}`);\n }\n lines.push(` *`);\n lines.push(\n ` * @source OpenAPI: ${operation.method.toUpperCase()} ${operation.path}`\n );\n lines.push(` */`);\n lines.push(`export const ${safeName}Spec = ${defineFunc}({`);\n\n // Meta\n lines.push(' meta: {');\n lines.push(` key: '${specKey}',`);\n lines.push(\" version: '1.0.0',\");\n lines.push(` stability: '${options.defaultStability ?? 'stable'}',`);\n lines.push(\n ` owners: [${(options.defaultOwners ?? []).map((o) => `'${o}'`).join(', ')}],`\n );\n lines.push(` tags: [${operation.tags.map((t) => `'${t}'`).join(', ')}],`);\n lines.push(\n ` description: ${JSON.stringify(operation.summary ?? operation.operationId)},`\n );\n lines.push(\n ` goal: ${JSON.stringify(operation.description ?? 'Imported from OpenAPI')},`\n );\n lines.push(\n ` context: 'Imported from OpenAPI: ${operation.method.toUpperCase()} ${operation.path}',`\n );\n lines.push(' },');\n\n // IO\n lines.push(' io: {');\n lines.push(` input: ${inputModel?.name ?? 'null'},`);\n if (queryModel) lines.push(` query: ${queryModel.name},`);\n if (paramsModel) lines.push(` params: ${paramsModel.name},`);\n if (headersModel) lines.push(` headers: ${headersModel.name},`);\n\n if (outputModel) {\n lines.push(` output: ${outputModel.name},`);\n } else {\n lines.push(' output: null, // TODO: Define output schema');\n }\n lines.push(' },');\n\n // Policy\n lines.push(' policy: {');\n lines.push(` auth: '${auth}',`);\n lines.push(' },');\n\n // Transport hints\n const httpMethod = operation.method.toUpperCase();\n const restMethod = httpMethod === 'GET' ? 'GET' : 'POST';\n lines.push(' transport: {');\n lines.push(' rest: {');\n lines.push(` method: '${restMethod}',`);\n lines.push(` path: '${operation.path}',`);\n lines.push(' },');\n lines.push(' },');\n\n lines.push('});');\n\n return lines.join('\\n');\n}\n"],"mappings":"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"}
@@ -112,7 +112,7 @@ interface ParsedOperation {
112
112
  /** ContractSpec extension data if present */
113
113
  contractSpecMeta?: {
114
114
  name: string;
115
- version: number;
115
+ version: string;
116
116
  kind: 'command' | 'query';
117
117
  };
118
118
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/lib.contracts-transformers",
3
- "version": "1.44.1",
3
+ "version": "1.45.0",
4
4
  "description": "Contract format transformations: import/export between ContractSpec and external formats (OpenAPI, AsyncAPI, etc.)",
5
5
  "keywords": [
6
6
  "contractspec",
@@ -25,15 +25,15 @@
25
25
  "test": "bun test"
26
26
  },
27
27
  "dependencies": {
28
- "@contractspec/lib.contracts": "1.44.1",
29
- "@contractspec/lib.schema": "1.44.1",
28
+ "@contractspec/lib.contracts": "1.45.0",
29
+ "@contractspec/lib.schema": "1.45.0",
30
30
  "openapi-types": "^12.1.3",
31
31
  "yaml": "^2.7.1",
32
32
  "zod": "^4.1.13"
33
33
  },
34
34
  "devDependencies": {
35
- "@contractspec/tool.tsdown": "1.44.1",
36
- "@contractspec/tool.typescript": "1.44.1",
35
+ "@contractspec/tool.tsdown": "1.45.0",
36
+ "@contractspec/tool.typescript": "1.45.0",
37
37
  "tsdown": "^0.18.3",
38
38
  "typescript": "^5.9.3"
39
39
  },