@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.
Files changed (95) hide show
  1. package/README.md +2 -2
  2. package/dist/common/index.d.ts +2 -2
  3. package/dist/common/types.d.ts +16 -10
  4. package/dist/common/types.d.ts.map +1 -1
  5. package/dist/index.d.ts +15 -6
  6. package/dist/index.js +13 -4
  7. package/dist/openapi/differ.d.ts +6 -6
  8. package/dist/openapi/differ.d.ts.map +1 -1
  9. package/dist/openapi/differ.js +11 -4
  10. package/dist/openapi/differ.js.map +1 -1
  11. package/dist/openapi/exporter/data-views.d.ts +38 -0
  12. package/dist/openapi/exporter/data-views.d.ts.map +1 -0
  13. package/dist/openapi/exporter/data-views.js +47 -0
  14. package/dist/openapi/exporter/data-views.js.map +1 -0
  15. package/dist/openapi/exporter/events.d.ts +28 -0
  16. package/dist/openapi/exporter/events.d.ts.map +1 -0
  17. package/dist/openapi/exporter/events.js +39 -0
  18. package/dist/openapi/exporter/events.js.map +1 -0
  19. package/dist/openapi/exporter/features.d.ts +37 -0
  20. package/dist/openapi/exporter/features.d.ts.map +1 -0
  21. package/dist/openapi/exporter/features.js +46 -0
  22. package/dist/openapi/exporter/features.js.map +1 -0
  23. package/dist/openapi/exporter/forms.d.ts +30 -0
  24. package/dist/openapi/exporter/forms.d.ts.map +1 -0
  25. package/dist/openapi/exporter/forms.js +49 -0
  26. package/dist/openapi/exporter/forms.js.map +1 -0
  27. package/dist/openapi/exporter/index.js +8 -0
  28. package/dist/openapi/exporter/operations.d.ts +65 -0
  29. package/dist/openapi/exporter/operations.d.ts.map +1 -0
  30. package/dist/openapi/exporter/operations.js +142 -0
  31. package/dist/openapi/exporter/operations.js.map +1 -0
  32. package/dist/openapi/exporter/presentations.d.ts +48 -0
  33. package/dist/openapi/exporter/presentations.d.ts.map +1 -0
  34. package/dist/openapi/exporter/presentations.js +66 -0
  35. package/dist/openapi/exporter/presentations.js.map +1 -0
  36. package/dist/openapi/exporter/registries.d.ts +23 -0
  37. package/dist/openapi/exporter/registries.d.ts.map +1 -0
  38. package/dist/openapi/exporter/registries.js +29 -0
  39. package/dist/openapi/exporter/registries.js.map +1 -0
  40. package/dist/openapi/exporter/workflows.d.ts +36 -0
  41. package/dist/openapi/exporter/workflows.d.ts.map +1 -0
  42. package/dist/openapi/exporter/workflows.js +54 -0
  43. package/dist/openapi/exporter/workflows.js.map +1 -0
  44. package/dist/openapi/exporter.d.ts +35 -15
  45. package/dist/openapi/exporter.d.ts.map +1 -1
  46. package/dist/openapi/exporter.js +78 -104
  47. package/dist/openapi/exporter.js.map +1 -1
  48. package/dist/openapi/importer/analyzer.js +28 -0
  49. package/dist/openapi/importer/analyzer.js.map +1 -0
  50. package/dist/openapi/importer/events.js +36 -0
  51. package/dist/openapi/importer/events.js.map +1 -0
  52. package/dist/openapi/importer/generator.js +71 -0
  53. package/dist/openapi/importer/generator.js.map +1 -0
  54. package/dist/openapi/importer/grouping.js +73 -0
  55. package/dist/openapi/importer/grouping.js.map +1 -0
  56. package/dist/openapi/importer/index.d.ts +17 -0
  57. package/dist/openapi/importer/index.d.ts.map +1 -0
  58. package/dist/openapi/importer/index.js +161 -0
  59. package/dist/openapi/importer/index.js.map +1 -0
  60. package/dist/openapi/importer/models.js +19 -0
  61. package/dist/openapi/importer/models.js.map +1 -0
  62. package/dist/openapi/importer/schemas.js +80 -0
  63. package/dist/openapi/importer/schemas.js.map +1 -0
  64. package/dist/openapi/index.d.ts +14 -5
  65. package/dist/openapi/index.js +15 -4
  66. package/dist/openapi/parser/document.d.ts +20 -0
  67. package/dist/openapi/parser/document.d.ts.map +1 -0
  68. package/dist/openapi/parser/document.js +95 -0
  69. package/dist/openapi/parser/document.js.map +1 -0
  70. package/dist/openapi/parser/index.js +5 -0
  71. package/dist/openapi/parser/operation.js +59 -0
  72. package/dist/openapi/parser/operation.js.map +1 -0
  73. package/dist/openapi/parser/parameters.js +37 -0
  74. package/dist/openapi/parser/parameters.js.map +1 -0
  75. package/dist/openapi/parser/resolvers.js +63 -0
  76. package/dist/openapi/parser/resolvers.js.map +1 -0
  77. package/dist/openapi/parser/utils.d.ts +19 -0
  78. package/dist/openapi/parser/utils.d.ts.map +1 -0
  79. package/dist/openapi/parser/utils.js +48 -0
  80. package/dist/openapi/parser/utils.js.map +1 -0
  81. package/dist/openapi/parser.js +6 -232
  82. package/dist/openapi/schema-converter.d.ts +7 -1
  83. package/dist/openapi/schema-converter.d.ts.map +1 -1
  84. package/dist/openapi/schema-converter.js +117 -20
  85. package/dist/openapi/schema-converter.js.map +1 -1
  86. package/dist/openapi/types.d.ts +75 -20
  87. package/dist/openapi/types.d.ts.map +1 -1
  88. package/package.json +5 -5
  89. package/dist/openapi/importer.d.ts +0 -16
  90. package/dist/openapi/importer.d.ts.map +0 -1
  91. package/dist/openapi/importer.js +0 -265
  92. package/dist/openapi/importer.js.map +0 -1
  93. package/dist/openapi/parser.d.ts +0 -32
  94. package/dist/openapi/parser.d.ts.map +0 -1
  95. package/dist/openapi/parser.js.map +0 -1
package/README.md CHANGED
@@ -18,9 +18,9 @@ bun add @lssm/lib.contracts-transformers
18
18
 
19
19
  ```typescript
20
20
  import { openApiForRegistry } from '@lssm/lib.contracts-transformers/openapi';
21
- import { SpecRegistry } from '@lssm/lib.contracts';
21
+ import { OperationSpecRegistry } from '@lssm/lib.contracts';
22
22
 
23
- const registry = new SpecRegistry();
23
+ const registry = new OperationSpecRegistry();
24
24
  // ... register your specs ...
25
25
 
26
26
  const openApiDoc = openApiForRegistry(registry, {
@@ -1,3 +1,3 @@
1
- import { DiffChange, DiffChangeType, ImportResult, ImportedSpec, SpecDiff, SpecSource, SyncResult, TransportHints, ValidationResult } from "./types.js";
1
+ import { DiffChange, DiffChangeType, ImportResult, ImportedOperationSpec, SpecDiff, SpecSource, SyncResult, TransportHints, ValidationResult } from "./types.js";
2
2
  import { deepEqual, extractPathParams, getByPath, normalizePath, toCamelCase, toFileName, toKebabCase, toPascalCase, toSnakeCase, toSpecName, toValidIdentifier } from "./utils.js";
3
- export { DiffChange, DiffChangeType, ImportResult, ImportedSpec, SpecDiff, SpecSource, SyncResult, TransportHints, ValidationResult, deepEqual, extractPathParams, getByPath, normalizePath, toCamelCase, toFileName, toKebabCase, toPascalCase, toSnakeCase, toSpecName, toValidIdentifier };
3
+ export { DiffChange, DiffChangeType, ImportResult, ImportedOperationSpec, SpecDiff, SpecSource, SyncResult, TransportHints, ValidationResult, deepEqual, extractPathParams, getByPath, normalizePath, toCamelCase, toFileName, toKebabCase, toPascalCase, toSnakeCase, toSpecName, toValidIdentifier };
@@ -1,4 +1,4 @@
1
- import { AnyContractSpec } from "@lssm/lib.contracts";
1
+ import { AnyOperationSpec } from "@lssm/lib.contracts";
2
2
 
3
3
  //#region src/common/types.d.ts
4
4
 
@@ -40,13 +40,19 @@ interface TransportHints {
40
40
  /**
41
41
  * Result of importing a single spec from an external format.
42
42
  */
43
- interface ImportedSpec {
44
- /** The generated ContractSpec */
45
- spec: AnyContractSpec;
43
+ interface ImportedOperationSpec {
44
+ /**
45
+ * The generated ContractSpec.
46
+ * Optional because during code generation the actual spec object is not
47
+ * available until the generated code is executed at runtime.
48
+ */
49
+ operationSpec?: AnyOperationSpec;
46
50
  /** Generated TypeScript code for the spec */
47
51
  code: string;
48
52
  /** Suggested file name for the spec */
49
53
  fileName: string;
54
+ /** Group folder for organizing the file (based on grouping config) */
55
+ groupFolder?: string;
50
56
  /** Source information for provenance tracking */
51
57
  source: SpecSource;
52
58
  /** Transport hints for accurate round-trips */
@@ -57,7 +63,7 @@ interface ImportedSpec {
57
63
  */
58
64
  interface ImportResult {
59
65
  /** Successfully imported specs */
60
- specs: ImportedSpec[];
66
+ operationSpecs: ImportedOperationSpec[];
61
67
  /** Specs that were skipped (e.g., unsupported features) */
62
68
  skipped: {
63
69
  sourceId: string;
@@ -102,9 +108,9 @@ interface SpecDiff {
102
108
  /** Identifier for the operation */
103
109
  operationId: string;
104
110
  /** Existing ContractSpec (if any) */
105
- existing?: AnyContractSpec;
111
+ existing?: AnyOperationSpec;
106
112
  /** Incoming imported spec */
107
- incoming: ImportedSpec;
113
+ incoming: ImportedOperationSpec;
108
114
  /** List of detected changes */
109
115
  changes: DiffChange[];
110
116
  /** Whether specs are semantically equivalent */
@@ -117,10 +123,10 @@ interface SpecDiff {
117
123
  */
118
124
  interface SyncResult {
119
125
  /** Specs that were added (new imports) */
120
- added: ImportedSpec[];
126
+ added: ImportedOperationSpec[];
121
127
  /** Specs that were updated */
122
128
  updated: {
123
- spec: ImportedSpec;
129
+ spec: ImportedOperationSpec;
124
130
  changes: DiffChange[];
125
131
  }[];
126
132
  /** Specs that were kept unchanged */
@@ -149,5 +155,5 @@ interface ValidationResult {
149
155
  warnings: string[];
150
156
  }
151
157
  //#endregion
152
- export { DiffChange, DiffChangeType, ImportResult, ImportedSpec, SpecDiff, SpecSource, SyncResult, TransportHints, ValidationResult };
158
+ export { DiffChange, DiffChangeType, ImportResult, ImportedOperationSpec, SpecDiff, SpecSource, SyncResult, TransportHints, ValidationResult };
153
159
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/common/types.ts"],"sourcesContent":[],"mappings":";;;;AA0BA;AAoBA;;AAQU,UA7CO,UAAA,CA6CP;EAEQ;EAAc,IAAA,EAAA,SAAA,GAAA,UAAA,GAAA,SAAA,GAAA,UAAA;EAMf;EAyBL,GAAA,CAAA,EAAA,MAAA;EAUK;EAgBA,IAAA,CAAA,EAAA,MAAQ;EAIZ;EAED,QAAA,EAAA,MAAA;EAED;EAAU,UAAA,EAtGP,IAsGO;AAUrB;;;;;AAWqB,UApHJ,cAAA,CAoHI;EAaJ,IAAA,CAAA,EAAA;;;;;;;;;;;;;;;;;;UA7GA,YAAA;;QAET;;;;;;UAME;;kBAEQ;;;;;UAMD,YAAA;;SAER;;;;;;;;;;;;;;;;;;;;;;KAuBG,cAAA;;;;UAUK,UAAA;;;;QAIT;;;;;;;;;;;UAYS,QAAA;;;;aAIJ;;YAED;;WAED;;;;;;;;;UAUM,UAAA;;SAER;;;UAGC;aACG;;;;;aAKA;;;;;;;;;;;;UAaI,gBAAA;;;;SAIR"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/common/types.ts"],"sourcesContent":[],"mappings":";;;;AA0BA;AAoBA;;AAcU,UAnDO,UAAA,CAmDP;EAEQ;EAAc,IAAA,EAAA,SAAA,GAAA,UAAA,GAAA,SAAA,GAAA,UAAA;EAMf;EAyBL,GAAA,CAAA,EAAA,MAAA;EAUK;EAgBA,IAAA,CAAA,EAAA,MAAQ;EAIZ;EAED,QAAA,EAAA,MAAA;EAED;EAAU,UAAA,EA5GP,IA4GO;AAUrB;;;;;AAWqB,UA1HJ,cAAA,CA0HI;EAaJ,IAAA,CAAA,EAAA;;;;;;;;;;;;;;;;;;UAnHA,qBAAA;;;;;;kBAMC;;;;;;;;UAQR;;kBAEQ;;;;;UAMD,YAAA;;kBAEC;;;;;;;;;;;;;;;;;;;;;;KAuBN,cAAA;;;;UAUK,UAAA;;;;QAIT;;;;;;;;;;;UAYS,QAAA;;;;aAIJ;;YAED;;WAED;;;;;;;;;UAUM,UAAA;;SAER;;;UAGC;aACG;;;;;aAKA;;;;;;;;;;;;UAaI,gBAAA;;;;SAIR"}
package/dist/index.d.ts CHANGED
@@ -1,9 +1,18 @@
1
- import { DiffChange, DiffChangeType, ImportResult, ImportedSpec, SpecDiff, SpecSource, SyncResult, TransportHints, ValidationResult } from "./common/types.js";
1
+ import { DiffChange, DiffChangeType, ImportResult, ImportedOperationSpec, SpecDiff, SpecSource, SyncResult, TransportHints, ValidationResult } from "./common/types.js";
2
2
  import { deepEqual, extractPathParams, getByPath, normalizePath, toCamelCase, toFileName, toKebabCase, toPascalCase, toSnakeCase, toSpecName, toValidIdentifier } from "./common/utils.js";
3
- import { ContractSpecOpenApiDocument, HttpMethod, OpenApiDocument, OpenApiExportOptions, OpenApiImportOptions, OpenApiOperation, OpenApiParameter, OpenApiParseOptions, OpenApiSchema, OpenApiServer, OpenApiSource, OpenApiTransportHints, OpenApiVersion, ParameterLocation, ParseResult, ParsedOperation, ParsedParameter } from "./openapi/types.js";
4
- import { detectFormat, detectVersion, parseOpenApi, parseOpenApiDocument, parseOpenApiString } from "./openapi/parser.js";
5
- import { defaultRestPath, openApiForRegistry, openApiToJson, openApiToYaml } from "./openapi/exporter.js";
6
- import { importFromOpenApi, importOperation } from "./openapi/importer.js";
3
+ import { ContractSpecOpenApiDocument, HttpMethod, OpenApiDocument, OpenApiExportOptions, OpenApiOperation, OpenApiParameter, OpenApiParseOptions, OpenApiSchema, OpenApiServer, OpenApiSource, OpenApiTransportHints, OpenApiVersion, ParameterLocation, ParseResult, ParsedOperation, ParsedParameter } from "./openapi/types.js";
4
+ import { detectFormat, detectVersion, parseOpenApiString } from "./openapi/parser/utils.js";
5
+ import { parseOpenApi, parseOpenApiDocument } from "./openapi/parser/document.js";
6
+ import { OperationsExportResult, defaultRestPath, exportOperations, generateOperationsRegistry, jsonSchemaForSpec, schemaModelToJsonSchema, toHttpMethod, toOperationId, toRestPath, toSchemaName } from "./openapi/exporter/operations.js";
7
+ import { ContractSpecRegistries, contractSpecToJson, contractSpecToYaml, exportContractSpec, openApiForRegistry, openApiToJson, openApiToYaml } from "./openapi/exporter.js";
8
+ import { ExportedEvent, exportEvents, generateEventsExports } from "./openapi/exporter/events.js";
9
+ import { ExportedFeature, exportFeatures, generateFeaturesRegistry } from "./openapi/exporter/features.js";
10
+ import { ExportedPresentation, ExportedPresentationV2, exportPresentations, exportPresentationsV1, exportPresentationsV2, generatePresentationsRegistry } from "./openapi/exporter/presentations.js";
11
+ import { ExportedForm, exportForms, generateFormsRegistry } from "./openapi/exporter/forms.js";
12
+ import { ExportedDataView, exportDataViews, generateDataViewsRegistry } from "./openapi/exporter/data-views.js";
13
+ import { ExportedWorkflow, exportWorkflows, generateWorkflowsRegistry } from "./openapi/exporter/workflows.js";
14
+ import { RegistryGenerationOptions, generateRegistryIndex } from "./openapi/exporter/registries.js";
7
15
  import { GeneratedModel, SchemaField, TypescriptType, generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToField, jsonSchemaToType } from "./openapi/schema-converter.js";
16
+ import { importFromOpenApi, importOperation } from "./openapi/importer/index.js";
8
17
  import { DiffOptions, createSpecDiff, diffAll, diffSpecVsOperation, diffSpecs, formatDiffChanges } from "./openapi/differ.js";
9
- export { ContractSpecOpenApiDocument, DiffChange, DiffChangeType, DiffOptions, GeneratedModel, HttpMethod, ImportResult, ImportedSpec, OpenApiDocument, OpenApiExportOptions, OpenApiImportOptions, OpenApiOperation, OpenApiParameter, OpenApiParseOptions, OpenApiSchema, OpenApiServer, OpenApiSource, OpenApiTransportHints, OpenApiVersion, ParameterLocation, ParseResult, ParsedOperation, ParsedParameter, SchemaField, SpecDiff, SpecSource, SyncResult, TransportHints, TypescriptType, ValidationResult, createSpecDiff, deepEqual, defaultRestPath, detectFormat, detectVersion, diffAll, diffSpecVsOperation, diffSpecs, extractPathParams, formatDiffChanges, generateImports, generateSchemaModelCode, getByPath, getScalarType, importFromOpenApi, importOperation, jsonSchemaToField, jsonSchemaToType, normalizePath, openApiForRegistry, openApiToJson, openApiToYaml, parseOpenApi, parseOpenApiDocument, parseOpenApiString, toCamelCase, toFileName, toKebabCase, toPascalCase, toSnakeCase, toSpecName, toValidIdentifier };
18
+ export { ContractSpecOpenApiDocument, ContractSpecRegistries, DiffChange, DiffChangeType, DiffOptions, ExportedDataView, ExportedEvent, ExportedFeature, ExportedForm, ExportedPresentation, ExportedPresentationV2, ExportedWorkflow, GeneratedModel, HttpMethod, ImportResult, ImportedOperationSpec, OpenApiDocument, OpenApiExportOptions, OpenApiOperation, OpenApiParameter, OpenApiParseOptions, OpenApiSchema, OpenApiServer, OpenApiSource, OpenApiTransportHints, OpenApiVersion, OperationsExportResult, ParameterLocation, ParseResult, ParsedOperation, ParsedParameter, RegistryGenerationOptions, SchemaField, SpecDiff, SpecSource, SyncResult, TransportHints, TypescriptType, ValidationResult, contractSpecToJson, contractSpecToYaml, createSpecDiff, deepEqual, defaultRestPath, detectFormat, detectVersion, diffAll, diffSpecVsOperation, diffSpecs, exportContractSpec, exportDataViews, exportEvents, exportFeatures, exportForms, exportOperations, exportPresentations, exportPresentationsV1, exportPresentationsV2, exportWorkflows, extractPathParams, formatDiffChanges, generateDataViewsRegistry, generateEventsExports, generateFeaturesRegistry, generateFormsRegistry, generateImports, generateOperationsRegistry, generatePresentationsRegistry, generateRegistryIndex, generateSchemaModelCode, generateWorkflowsRegistry, getByPath, getScalarType, importFromOpenApi, importOperation, jsonSchemaForSpec, jsonSchemaToField, jsonSchemaToType, normalizePath, openApiForRegistry, openApiToJson, openApiToYaml, parseOpenApi, parseOpenApiDocument, parseOpenApiString, schemaModelToJsonSchema, toCamelCase, toFileName, toHttpMethod, toKebabCase, toOperationId, toPascalCase, toRestPath, toSchemaName, toSnakeCase, toSpecName, toValidIdentifier };
package/dist/index.js CHANGED
@@ -1,9 +1,18 @@
1
- import { detectFormat, detectVersion, parseOpenApi, parseOpenApiDocument, parseOpenApiString } from "./openapi/parser.js";
2
- import { defaultRestPath, openApiForRegistry, openApiToJson, openApiToYaml } from "./openapi/exporter.js";
1
+ import { detectFormat, detectVersion, parseOpenApiString } from "./openapi/parser/utils.js";
2
+ import { parseOpenApi, parseOpenApiDocument } from "./openapi/parser/document.js";
3
+ import { defaultRestPath, exportOperations, generateOperationsRegistry, jsonSchemaForSpec, schemaModelToJsonSchema, toHttpMethod, toOperationId, toRestPath, toSchemaName } from "./openapi/exporter/operations.js";
4
+ import { exportEvents, generateEventsExports } from "./openapi/exporter/events.js";
5
+ import { exportFeatures, generateFeaturesRegistry } from "./openapi/exporter/features.js";
6
+ import { exportPresentations, exportPresentationsV1, exportPresentationsV2, generatePresentationsRegistry } from "./openapi/exporter/presentations.js";
7
+ import { exportForms, generateFormsRegistry } from "./openapi/exporter/forms.js";
8
+ import { exportDataViews, generateDataViewsRegistry } from "./openapi/exporter/data-views.js";
9
+ import { exportWorkflows, generateWorkflowsRegistry } from "./openapi/exporter/workflows.js";
10
+ import { generateRegistryIndex } from "./openapi/exporter/registries.js";
11
+ import { contractSpecToJson, contractSpecToYaml, exportContractSpec, openApiForRegistry, openApiToJson, openApiToYaml } from "./openapi/exporter.js";
3
12
  import { deepEqual, extractPathParams, getByPath, normalizePath, toCamelCase, toFileName, toKebabCase, toPascalCase, toSnakeCase, toSpecName, toValidIdentifier } from "./common/utils.js";
4
13
  import { generateImports, generateSchemaModelCode, getScalarType, jsonSchemaToField, jsonSchemaToType } from "./openapi/schema-converter.js";
5
- import { importFromOpenApi, importOperation } from "./openapi/importer.js";
14
+ import { importFromOpenApi, importOperation } from "./openapi/importer/index.js";
6
15
  import { createSpecDiff, diffAll, diffSpecVsOperation, diffSpecs, formatDiffChanges } from "./openapi/differ.js";
7
16
  import "./openapi/index.js";
8
17
 
9
- export { createSpecDiff, deepEqual, defaultRestPath, detectFormat, detectVersion, diffAll, diffSpecVsOperation, diffSpecs, extractPathParams, formatDiffChanges, generateImports, generateSchemaModelCode, getByPath, getScalarType, importFromOpenApi, importOperation, jsonSchemaToField, jsonSchemaToType, normalizePath, openApiForRegistry, openApiToJson, openApiToYaml, parseOpenApi, parseOpenApiDocument, parseOpenApiString, toCamelCase, toFileName, toKebabCase, toPascalCase, toSnakeCase, toSpecName, toValidIdentifier };
18
+ export { contractSpecToJson, contractSpecToYaml, createSpecDiff, deepEqual, defaultRestPath, detectFormat, detectVersion, diffAll, diffSpecVsOperation, diffSpecs, exportContractSpec, exportDataViews, exportEvents, exportFeatures, exportForms, exportOperations, exportPresentations, exportPresentationsV1, exportPresentationsV2, exportWorkflows, extractPathParams, formatDiffChanges, generateDataViewsRegistry, generateEventsExports, generateFeaturesRegistry, generateFormsRegistry, generateImports, generateOperationsRegistry, generatePresentationsRegistry, generateRegistryIndex, generateSchemaModelCode, generateWorkflowsRegistry, getByPath, getScalarType, importFromOpenApi, importOperation, jsonSchemaForSpec, jsonSchemaToField, jsonSchemaToType, normalizePath, openApiForRegistry, openApiToJson, openApiToYaml, parseOpenApi, parseOpenApiDocument, parseOpenApiString, schemaModelToJsonSchema, toCamelCase, toFileName, toHttpMethod, toKebabCase, toOperationId, toPascalCase, toRestPath, toSchemaName, toSnakeCase, toSpecName, toValidIdentifier };
@@ -1,6 +1,6 @@
1
- import { DiffChange, ImportedSpec, SpecDiff } from "../common/types.js";
1
+ import { DiffChange, ImportedOperationSpec, SpecDiff } from "../common/types.js";
2
2
  import { ParsedOperation } from "./types.js";
3
- import { AnyContractSpec } from "@lssm/lib.contracts";
3
+ import { AnyOperationSpec } from "@lssm/lib.contracts";
4
4
 
5
5
  //#region src/openapi/differ.d.ts
6
6
 
@@ -20,19 +20,19 @@ interface DiffOptions {
20
20
  /**
21
21
  * Diff a ContractSpec against an OpenAPI operation.
22
22
  */
23
- declare function diffSpecVsOperation(spec: AnyContractSpec, operation: ParsedOperation, options?: DiffOptions): DiffChange[];
23
+ declare function diffSpecVsOperation(spec: AnyOperationSpec, operation: ParsedOperation, options?: DiffOptions): DiffChange[];
24
24
  /**
25
25
  * Diff two ContractSpecs.
26
26
  */
27
- declare function diffSpecs(oldSpec: AnyContractSpec, newSpec: AnyContractSpec, options?: DiffOptions): DiffChange[];
27
+ declare function diffSpecs(oldSpec: AnyOperationSpec, newSpec: AnyOperationSpec, options?: DiffOptions): DiffChange[];
28
28
  /**
29
29
  * Create a SpecDiff from an existing spec and an imported spec.
30
30
  */
31
- declare function createSpecDiff(operationId: string, existing: AnyContractSpec | undefined, incoming: ImportedSpec, options?: DiffOptions): SpecDiff;
31
+ declare function createSpecDiff(operationId: string, existing: AnyOperationSpec | undefined, incoming: ImportedOperationSpec, options?: DiffOptions): SpecDiff;
32
32
  /**
33
33
  * Batch diff multiple specs against OpenAPI operations.
34
34
  */
35
- declare function diffAll(existingSpecs: Map<string, AnyContractSpec>, importedSpecs: ImportedSpec[], options?: DiffOptions): SpecDiff[];
35
+ declare function diffAll(existingSpecs: Map<string, AnyOperationSpec>, importedSpecs: ImportedOperationSpec[], options?: DiffOptions): SpecDiff[];
36
36
  /**
37
37
  * Format diff changes for display.
38
38
  */
@@ -1 +1 @@
1
- {"version":3,"file":"differ.d.ts","names":[],"sources":["../../src/openapi/differ.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAwIG,UAtHc,WAAA,CAsHd;EAAU;EA2EG,kBAAS,CAAA,EAAA,OAAA;EACd;EACA,UAAA,CAAA,EAAA,OAAA;EACA;EACR,eAAA,CAAA,EAAA,OAAA;EAAU;EA+CG,WAAA,CAAA,EAAA,MAAc,EAAA;;;;;AAKnB,iBAvIK,mBAAA,CAuIL,IAAA,EAtIH,eAsIG,EAAA,SAAA,EArIE,eAqIF,EAAA,OAAA,CAAA,EApIA,WAoIA,CAAA,EAnIR,UAmIQ,EAAA;AAgCX;;;AAEiB,iBA1FD,SAAA,CA0FC,OAAA,EAzFN,eAyFM,EAAA,OAAA,EAxFN,eAwFM,EAAA,OAAA,CAAA,EAvFN,WAuFM,CAAA,EAtFd,UAsFc,EAAA;;;;AAsDD,iBA7FA,cAAA,CA6F2B,WAAU,EAAA,MAAA,EAAA,QAAA,EA3FzC,eA2FyC,GAAA,SAAA,EAAA,QAAA,EA1FzC,YA0FyC,EAAA,OAAA,CAAA,EAzF1C,WAyF0C,CAAA,EAxFlD,QAwFkD;;;;iBAxDrC,OAAA,gBACC,YAAY,iCACZ,0BACN,cACR;;;;iBAoDa,iBAAA,UAA2B"}
1
+ {"version":3,"file":"differ.d.ts","names":[],"sources":["../../src/openapi/differ.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAwIG,UAtHc,WAAA,CAsHd;EAAU;EA2EG,kBAAS,CAAA,EAAA,OAAA;EACd;EACA,UAAA,CAAA,EAAA,OAAA;EACA;EACR,eAAA,CAAA,EAAA,OAAA;EAAU;EA+CG,WAAA,CAAA,EAAA,MAAc,EAAA;;;;;AAKnB,iBAvIK,mBAAA,CAuIL,IAAA,EAtIH,gBAsIG,EAAA,SAAA,EArIE,eAqIF,EAAA,OAAA,CAAA,EApIA,WAoIA,CAAA,EAnIR,UAmIQ,EAAA;AA4CX;;;AAEiB,iBAtGD,SAAA,CAsGC,OAAA,EArGN,gBAqGM,EAAA,OAAA,EApGN,gBAoGM,EAAA,OAAA,CAAA,EAnGN,WAmGM,CAAA,EAlGd,UAkGc,EAAA;;;;AAsDD,iBAzGA,cAAA,CAyG2B,WAAU,EAAA,MAAA,EAAA,QAAA,EAvGzC,gBAuGyC,GAAA,SAAA,EAAA,QAAA,EAtGzC,qBAsGyC,EAAA,OAAA,CAAA,EArG1C,WAqG0C,CAAA,EApGlD,QAoGkD;;;;iBAxDrC,OAAA,gBACC,YAAY,kCACZ,mCACN,cACR;;;;iBAoDa,iBAAA,UAA2B"}
@@ -136,13 +136,20 @@ function diffSpecs(oldSpec, newSpec, options = {}) {
136
136
  function createSpecDiff(operationId, existing, incoming, options = {}) {
137
137
  let changes = [];
138
138
  let isEquivalent = false;
139
- if (existing) {
140
- changes = diffSpecs(existing, incoming.spec, options);
139
+ if (existing && incoming.operationSpec) {
140
+ changes = diffSpecs(existing, incoming.operationSpec, options);
141
141
  isEquivalent = changes.length === 0;
142
- } else changes = [{
142
+ } else if (existing && !incoming.operationSpec) changes = [{
143
+ path: "",
144
+ type: "modified",
145
+ oldValue: existing,
146
+ newValue: incoming.code,
147
+ description: "Spec code imported from OpenAPI (runtime comparison not available)"
148
+ }];
149
+ else changes = [{
143
150
  path: "",
144
151
  type: "added",
145
- newValue: incoming.spec,
152
+ newValue: incoming.operationSpec ?? incoming.code,
146
153
  description: "New spec imported from OpenAPI"
147
154
  }];
148
155
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"differ.js","names":["changeType: DiffChangeType","changes: DiffChange[]","diffs: SpecDiff[]","existing: AnyContractSpec | undefined","lines: string[]"],"sources":["../../src/openapi/differ.ts"],"sourcesContent":["/**\n * Diff ContractSpec specs against OpenAPI operations.\n * Used for sync operations to detect changes.\n */\n\nimport type { AnyContractSpec } from '@lssm/lib.contracts';\nimport type { ParsedOperation } from './types';\nimport type {\n SpecDiff,\n DiffChange,\n DiffChangeType,\n ImportedSpec,\n} from '../common/types';\nimport { deepEqual } from '../common/utils';\n\n/**\n * Options for diffing specs.\n */\nexport interface DiffOptions {\n /** Ignore description changes */\n ignoreDescriptions?: boolean;\n /** Ignore tag changes */\n ignoreTags?: boolean;\n /** Ignore transport changes (path, method) */\n ignoreTransport?: boolean;\n /** Custom paths to ignore */\n ignorePaths?: string[];\n}\n\n/**\n * Compare two values and generate a diff change if different.\n */\nfunction compareValues(\n path: string,\n oldValue: unknown,\n newValue: unknown,\n description: string\n): DiffChange | null {\n if (deepEqual(oldValue, newValue)) {\n return null;\n }\n\n let changeType: DiffChangeType = 'modified';\n if (oldValue === undefined || oldValue === null) {\n changeType = 'added';\n } else if (newValue === undefined || newValue === null) {\n changeType = 'removed';\n } else if (typeof oldValue !== typeof newValue) {\n changeType = 'type_changed';\n }\n\n return {\n path,\n type: changeType,\n oldValue,\n newValue,\n description,\n };\n}\n\n/**\n * Diff two objects recursively.\n */\nfunction diffObjects(\n path: string,\n oldObj: Record<string, unknown> | undefined,\n newObj: Record<string, unknown> | undefined,\n options: DiffOptions\n): DiffChange[] {\n const changes: DiffChange[] = [];\n\n if (!oldObj && !newObj) return changes;\n if (!oldObj) {\n changes.push({\n path,\n type: 'added',\n newValue: newObj,\n description: `Added ${path}`,\n });\n return changes;\n }\n if (!newObj) {\n changes.push({\n path,\n type: 'removed',\n oldValue: oldObj,\n description: `Removed ${path}`,\n });\n return changes;\n }\n\n const allKeys = new Set([...Object.keys(oldObj), ...Object.keys(newObj)]);\n\n for (const key of allKeys) {\n const keyPath = path ? `${path}.${key}` : key;\n\n // Skip ignored paths\n if (options.ignorePaths?.some((p) => keyPath.startsWith(p))) {\n continue;\n }\n\n const oldVal = oldObj[key];\n const newVal = newObj[key];\n\n if (typeof oldVal === 'object' && typeof newVal === 'object') {\n changes.push(\n ...diffObjects(\n keyPath,\n oldVal as Record<string, unknown>,\n newVal as Record<string, unknown>,\n options\n )\n );\n } else {\n const change = compareValues(\n keyPath,\n oldVal,\n newVal,\n `Changed ${keyPath}`\n );\n if (change) {\n changes.push(change);\n }\n }\n }\n\n return changes;\n}\n\n/**\n * Diff a ContractSpec against an OpenAPI operation.\n */\nexport function diffSpecVsOperation(\n spec: AnyContractSpec,\n operation: ParsedOperation,\n options: DiffOptions = {}\n): DiffChange[] {\n const changes: DiffChange[] = [];\n\n // Compare basic metadata\n if (!options.ignoreDescriptions) {\n const descChange = compareValues(\n 'meta.description',\n spec.meta.description,\n operation.summary ?? operation.description,\n 'Description changed'\n );\n if (descChange) changes.push(descChange);\n }\n\n if (!options.ignoreTags) {\n const oldTags = [...(spec.meta.tags ?? [])].sort();\n const newTags = [...operation.tags].sort();\n if (!deepEqual(oldTags, newTags)) {\n changes.push({\n path: 'meta.tags',\n type: 'modified',\n oldValue: oldTags,\n newValue: newTags,\n description: 'Tags changed',\n });\n }\n }\n\n // Compare transport\n if (!options.ignoreTransport) {\n const specMethod =\n spec.transport?.rest?.method ??\n (spec.meta.kind === 'query' ? 'GET' : 'POST');\n const opMethod = operation.method.toUpperCase();\n\n if (specMethod !== opMethod) {\n changes.push({\n path: 'transport.rest.method',\n type: 'modified',\n oldValue: specMethod,\n newValue: opMethod,\n description: 'HTTP method changed',\n });\n }\n\n const specPath = spec.transport?.rest?.path;\n if (specPath && specPath !== operation.path) {\n changes.push({\n path: 'transport.rest.path',\n type: 'modified',\n oldValue: specPath,\n newValue: operation.path,\n description: 'Path changed',\n });\n }\n }\n\n // Compare deprecation status\n const specDeprecated = spec.meta.stability === 'deprecated';\n if (specDeprecated !== operation.deprecated) {\n changes.push({\n path: 'meta.stability',\n type: 'modified',\n oldValue: spec.meta.stability,\n newValue: operation.deprecated ? 'deprecated' : 'stable',\n description: 'Deprecation status changed',\n });\n }\n\n return changes;\n}\n\n/**\n * Diff two ContractSpecs.\n */\nexport function diffSpecs(\n oldSpec: AnyContractSpec,\n newSpec: AnyContractSpec,\n options: DiffOptions = {}\n): DiffChange[] {\n const changes: DiffChange[] = [];\n\n // Compare meta\n const metaChanges = diffObjects(\n 'meta',\n oldSpec.meta as unknown as Record<string, unknown>,\n newSpec.meta as unknown as Record<string, unknown>,\n {\n ...options,\n ignorePaths: [\n ...(options.ignorePaths ?? []),\n ...(options.ignoreDescriptions\n ? ['meta.description', 'meta.goal', 'meta.context']\n : []),\n ...(options.ignoreTags ? ['meta.tags'] : []),\n ],\n }\n );\n changes.push(...metaChanges);\n\n // Compare transport\n if (!options.ignoreTransport) {\n const transportChanges = diffObjects(\n 'transport',\n oldSpec.transport as unknown as Record<string, unknown>,\n newSpec.transport as unknown as Record<string, unknown>,\n options\n );\n changes.push(...transportChanges);\n }\n\n // Compare policy\n const policyChanges = diffObjects(\n 'policy',\n oldSpec.policy as unknown as Record<string, unknown>,\n newSpec.policy as unknown as Record<string, unknown>,\n options\n );\n changes.push(...policyChanges);\n\n return changes;\n}\n\n/**\n * Create a SpecDiff from an existing spec and an imported spec.\n */\nexport function createSpecDiff(\n operationId: string,\n existing: AnyContractSpec | undefined,\n incoming: ImportedSpec,\n options: DiffOptions = {}\n): SpecDiff {\n let changes: DiffChange[] = [];\n let isEquivalent = false;\n\n if (existing) {\n // Compare existing vs incoming\n changes = diffSpecs(existing, incoming.spec, options);\n isEquivalent = changes.length === 0;\n } else {\n // New spec - mark as added\n changes = [\n {\n path: '',\n type: 'added',\n newValue: incoming.spec,\n description: 'New spec imported from OpenAPI',\n },\n ];\n }\n\n return {\n operationId,\n existing,\n incoming,\n changes,\n isEquivalent,\n };\n}\n\n/**\n * Batch diff multiple specs against OpenAPI operations.\n */\nexport function diffAll(\n existingSpecs: Map<string, AnyContractSpec>,\n importedSpecs: ImportedSpec[],\n options: DiffOptions = {}\n): SpecDiff[] {\n const diffs: SpecDiff[] = [];\n\n // Track which existing specs have been matched\n const matchedExisting = new Set<string>();\n\n for (const imported of importedSpecs) {\n const operationId = imported.source.sourceId;\n\n // Try to find matching existing spec\n // Match by operationId in x-contractspec extension or by name\n let existing: AnyContractSpec | undefined;\n\n for (const [key, spec] of existingSpecs) {\n // Check x-contractspec match or name match\n const specName = spec.meta.name;\n if (key === operationId || specName.includes(operationId)) {\n existing = spec;\n matchedExisting.add(key);\n break;\n }\n }\n\n diffs.push(createSpecDiff(operationId, existing, imported, options));\n }\n\n // Add diffs for existing specs that weren't matched (removed from OpenAPI)\n for (const [key, spec] of existingSpecs) {\n if (!matchedExisting.has(key)) {\n diffs.push({\n operationId: key,\n existing: spec,\n incoming: undefined as unknown as ImportedSpec,\n changes: [\n {\n path: '',\n type: 'removed',\n oldValue: spec,\n description: 'Spec no longer exists in OpenAPI source',\n },\n ],\n isEquivalent: false,\n });\n }\n }\n\n return diffs;\n}\n\n/**\n * Format diff changes for display.\n */\nexport function formatDiffChanges(changes: DiffChange[]): string {\n if (changes.length === 0) {\n return 'No changes detected';\n }\n\n const lines: string[] = [];\n\n for (const change of changes) {\n const prefix = {\n added: '+',\n removed: '-',\n modified: '~',\n type_changed: '!',\n required_changed: '?',\n }[change.type];\n\n lines.push(`${prefix} ${change.path}: ${change.description}`);\n\n if (change.type === 'modified' || change.type === 'type_changed') {\n lines.push(` old: ${JSON.stringify(change.oldValue)}`);\n lines.push(` new: ${JSON.stringify(change.newValue)}`);\n } else if (change.type === 'added') {\n lines.push(` value: ${JSON.stringify(change.newValue)}`);\n } else if (change.type === 'removed') {\n lines.push(` was: ${JSON.stringify(change.oldValue)}`);\n }\n }\n\n return lines.join('\\n');\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"differ.js","names":["changeType: DiffChangeType","changes: DiffChange[]","diffs: SpecDiff[]","existing: AnyOperationSpec | undefined","lines: string[]"],"sources":["../../src/openapi/differ.ts"],"sourcesContent":["/**\n * Diff ContractSpec specs against OpenAPI operations.\n * Used for sync operations to detect changes.\n */\n\nimport type { AnyOperationSpec } from '@lssm/lib.contracts';\nimport type { ParsedOperation } from './types';\nimport type {\n DiffChange,\n DiffChangeType,\n ImportedOperationSpec,\n SpecDiff,\n} from '../common/types';\nimport { deepEqual } from '../common/utils';\n\n/**\n * Options for diffing specs.\n */\nexport interface DiffOptions {\n /** Ignore description changes */\n ignoreDescriptions?: boolean;\n /** Ignore tag changes */\n ignoreTags?: boolean;\n /** Ignore transport changes (path, method) */\n ignoreTransport?: boolean;\n /** Custom paths to ignore */\n ignorePaths?: string[];\n}\n\n/**\n * Compare two values and generate a diff change if different.\n */\nfunction compareValues(\n path: string,\n oldValue: unknown,\n newValue: unknown,\n description: string\n): DiffChange | null {\n if (deepEqual(oldValue, newValue)) {\n return null;\n }\n\n let changeType: DiffChangeType = 'modified';\n if (oldValue === undefined || oldValue === null) {\n changeType = 'added';\n } else if (newValue === undefined || newValue === null) {\n changeType = 'removed';\n } else if (typeof oldValue !== typeof newValue) {\n changeType = 'type_changed';\n }\n\n return {\n path,\n type: changeType,\n oldValue,\n newValue,\n description,\n };\n}\n\n/**\n * Diff two objects recursively.\n */\nfunction diffObjects(\n path: string,\n oldObj: Record<string, unknown> | undefined,\n newObj: Record<string, unknown> | undefined,\n options: DiffOptions\n): DiffChange[] {\n const changes: DiffChange[] = [];\n\n if (!oldObj && !newObj) return changes;\n if (!oldObj) {\n changes.push({\n path,\n type: 'added',\n newValue: newObj,\n description: `Added ${path}`,\n });\n return changes;\n }\n if (!newObj) {\n changes.push({\n path,\n type: 'removed',\n oldValue: oldObj,\n description: `Removed ${path}`,\n });\n return changes;\n }\n\n const allKeys = new Set([...Object.keys(oldObj), ...Object.keys(newObj)]);\n\n for (const key of allKeys) {\n const keyPath = path ? `${path}.${key}` : key;\n\n // Skip ignored paths\n if (options.ignorePaths?.some((p) => keyPath.startsWith(p))) {\n continue;\n }\n\n const oldVal = oldObj[key];\n const newVal = newObj[key];\n\n if (typeof oldVal === 'object' && typeof newVal === 'object') {\n changes.push(\n ...diffObjects(\n keyPath,\n oldVal as Record<string, unknown>,\n newVal as Record<string, unknown>,\n options\n )\n );\n } else {\n const change = compareValues(\n keyPath,\n oldVal,\n newVal,\n `Changed ${keyPath}`\n );\n if (change) {\n changes.push(change);\n }\n }\n }\n\n return changes;\n}\n\n/**\n * Diff a ContractSpec against an OpenAPI operation.\n */\nexport function diffSpecVsOperation(\n spec: AnyOperationSpec,\n operation: ParsedOperation,\n options: DiffOptions = {}\n): DiffChange[] {\n const changes: DiffChange[] = [];\n\n // Compare basic metadata\n if (!options.ignoreDescriptions) {\n const descChange = compareValues(\n 'meta.description',\n spec.meta.description,\n operation.summary ?? operation.description,\n 'Description changed'\n );\n if (descChange) changes.push(descChange);\n }\n\n if (!options.ignoreTags) {\n const oldTags = [...(spec.meta.tags ?? [])].sort();\n const newTags = [...operation.tags].sort();\n if (!deepEqual(oldTags, newTags)) {\n changes.push({\n path: 'meta.tags',\n type: 'modified',\n oldValue: oldTags,\n newValue: newTags,\n description: 'Tags changed',\n });\n }\n }\n\n // Compare transport\n if (!options.ignoreTransport) {\n const specMethod =\n spec.transport?.rest?.method ??\n (spec.meta.kind === 'query' ? 'GET' : 'POST');\n const opMethod = operation.method.toUpperCase();\n\n if (specMethod !== opMethod) {\n changes.push({\n path: 'transport.rest.method',\n type: 'modified',\n oldValue: specMethod,\n newValue: opMethod,\n description: 'HTTP method changed',\n });\n }\n\n const specPath = spec.transport?.rest?.path;\n if (specPath && specPath !== operation.path) {\n changes.push({\n path: 'transport.rest.path',\n type: 'modified',\n oldValue: specPath,\n newValue: operation.path,\n description: 'Path changed',\n });\n }\n }\n\n // Compare deprecation status\n const specDeprecated = spec.meta.stability === 'deprecated';\n if (specDeprecated !== operation.deprecated) {\n changes.push({\n path: 'meta.stability',\n type: 'modified',\n oldValue: spec.meta.stability,\n newValue: operation.deprecated ? 'deprecated' : 'stable',\n description: 'Deprecation status changed',\n });\n }\n\n return changes;\n}\n\n/**\n * Diff two ContractSpecs.\n */\nexport function diffSpecs(\n oldSpec: AnyOperationSpec,\n newSpec: AnyOperationSpec,\n options: DiffOptions = {}\n): DiffChange[] {\n const changes: DiffChange[] = [];\n\n // Compare meta\n const metaChanges = diffObjects(\n 'meta',\n oldSpec.meta as unknown as Record<string, unknown>,\n newSpec.meta as unknown as Record<string, unknown>,\n {\n ...options,\n ignorePaths: [\n ...(options.ignorePaths ?? []),\n ...(options.ignoreDescriptions\n ? ['meta.description', 'meta.goal', 'meta.context']\n : []),\n ...(options.ignoreTags ? ['meta.tags'] : []),\n ],\n }\n );\n changes.push(...metaChanges);\n\n // Compare transport\n if (!options.ignoreTransport) {\n const transportChanges = diffObjects(\n 'transport',\n oldSpec.transport as unknown as Record<string, unknown>,\n newSpec.transport as unknown as Record<string, unknown>,\n options\n );\n changes.push(...transportChanges);\n }\n\n // Compare policy\n const policyChanges = diffObjects(\n 'policy',\n oldSpec.policy as unknown as Record<string, unknown>,\n newSpec.policy as unknown as Record<string, unknown>,\n options\n );\n changes.push(...policyChanges);\n\n return changes;\n}\n\n/**\n * Create a SpecDiff from an existing spec and an imported spec.\n */\nexport function createSpecDiff(\n operationId: string,\n existing: AnyOperationSpec | undefined,\n incoming: ImportedOperationSpec,\n options: DiffOptions = {}\n): SpecDiff {\n let changes: DiffChange[] = [];\n let isEquivalent = false;\n\n if (existing && incoming.operationSpec) {\n // Compare existing vs incoming\n changes = diffSpecs(existing, incoming.operationSpec, options);\n isEquivalent = changes.length === 0;\n } else if (existing && !incoming.operationSpec) {\n // Incoming has code but no runtime spec - can't compare directly\n changes = [\n {\n path: '',\n type: 'modified',\n oldValue: existing,\n newValue: incoming.code,\n description:\n 'Spec code imported from OpenAPI (runtime comparison not available)',\n },\n ];\n } else {\n // New spec - mark as added\n changes = [\n {\n path: '',\n type: 'added',\n newValue: incoming.operationSpec ?? incoming.code,\n description: 'New spec imported from OpenAPI',\n },\n ];\n }\n\n return {\n operationId,\n existing,\n incoming,\n changes,\n isEquivalent,\n };\n}\n\n/**\n * Batch diff multiple specs against OpenAPI operations.\n */\nexport function diffAll(\n existingSpecs: Map<string, AnyOperationSpec>,\n importedSpecs: ImportedOperationSpec[],\n options: DiffOptions = {}\n): SpecDiff[] {\n const diffs: SpecDiff[] = [];\n\n // Track which existing specs have been matched\n const matchedExisting = new Set<string>();\n\n for (const imported of importedSpecs) {\n const operationId = imported.source.sourceId;\n\n // Try to find matching existing spec\n // Match by operationId in x-contractspec extension or by name\n let existing: AnyOperationSpec | undefined;\n\n for (const [key, spec] of existingSpecs) {\n // Check x-contractspec match or name match\n const specName = spec.meta.name;\n if (key === operationId || specName.includes(operationId)) {\n existing = spec;\n matchedExisting.add(key);\n break;\n }\n }\n\n diffs.push(createSpecDiff(operationId, existing, imported, options));\n }\n\n // Add diffs for existing specs that weren't matched (removed from OpenAPI)\n for (const [key, spec] of existingSpecs) {\n if (!matchedExisting.has(key)) {\n diffs.push({\n operationId: key,\n existing: spec,\n incoming: undefined as unknown as ImportedOperationSpec,\n changes: [\n {\n path: '',\n type: 'removed',\n oldValue: spec,\n description: 'Spec no longer exists in OpenAPI source',\n },\n ],\n isEquivalent: false,\n });\n }\n }\n\n return diffs;\n}\n\n/**\n * Format diff changes for display.\n */\nexport function formatDiffChanges(changes: DiffChange[]): string {\n if (changes.length === 0) {\n return 'No changes detected';\n }\n\n const lines: string[] = [];\n\n for (const change of changes) {\n const prefix = {\n added: '+',\n removed: '-',\n modified: '~',\n type_changed: '!',\n required_changed: '?',\n }[change.type];\n\n lines.push(`${prefix} ${change.path}: ${change.description}`);\n\n if (change.type === 'modified' || change.type === 'type_changed') {\n lines.push(` old: ${JSON.stringify(change.oldValue)}`);\n lines.push(` new: ${JSON.stringify(change.newValue)}`);\n } else if (change.type === 'added') {\n lines.push(` value: ${JSON.stringify(change.newValue)}`);\n } else if (change.type === 'removed') {\n lines.push(` was: ${JSON.stringify(change.oldValue)}`);\n }\n }\n\n return lines.join('\\n');\n}\n"],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { GeneratedRegistryCode } from "../types.js";
2
+ import { DataViewRegistry } from "@lssm/lib.contracts";
3
+
4
+ //#region src/openapi/exporter/data-views.d.ts
5
+
6
+ /**
7
+ * Exported data view structure for OpenAPI extensions.
8
+ */
9
+ interface ExportedDataView {
10
+ name: string;
11
+ version: number;
12
+ description?: string;
13
+ stability?: string;
14
+ entity: string;
15
+ kind: 'list' | 'detail' | 'table' | 'grid';
16
+ source: {
17
+ primary: {
18
+ name: string;
19
+ version: number;
20
+ };
21
+ item?: {
22
+ name: string;
23
+ version: number;
24
+ };
25
+ };
26
+ fields: unknown[];
27
+ }
28
+ /**
29
+ * Export data views to OpenAPI extension format.
30
+ */
31
+ declare function exportDataViews(registry: DataViewRegistry): ExportedDataView[];
32
+ /**
33
+ * Generate TypeScript code for data views registry.
34
+ */
35
+ declare function generateDataViewsRegistry(registry: DataViewRegistry): GeneratedRegistryCode;
36
+ //#endregion
37
+ export { ExportedDataView, exportDataViews, generateDataViewsRegistry };
38
+ //# sourceMappingURL=data-views.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-views.d.ts","names":[],"sources":["../../../src/openapi/exporter/data-views.ts"],"sourcesContent":[],"mappings":";;;;;AA0BA;AAkBA;;UAnCiB,gBAAA;;;;;;;;;;;;;;;;;;;;;;iBAiBD,eAAA,WACJ,mBACT;;;;iBAgBa,yBAAA,WACJ,mBACT"}
@@ -0,0 +1,47 @@
1
+ //#region src/openapi/exporter/data-views.ts
2
+ /**
3
+ * Export data views to OpenAPI extension format.
4
+ */
5
+ function exportDataViews(registry) {
6
+ return registry.list().map((dv) => ({
7
+ name: dv.meta.name,
8
+ version: dv.meta.version,
9
+ description: dv.meta.description,
10
+ stability: dv.meta.stability,
11
+ entity: dv.meta.entity,
12
+ kind: dv.view.kind,
13
+ source: dv.source,
14
+ fields: dv.view.fields
15
+ }));
16
+ }
17
+ /**
18
+ * Generate TypeScript code for data views registry.
19
+ */
20
+ function generateDataViewsRegistry(registry) {
21
+ const dataViews = registry.list();
22
+ const imports = /* @__PURE__ */ new Set();
23
+ const registrations = [];
24
+ for (const dv of dataViews) {
25
+ const dvVarName = dv.meta.name.replace(/\./g, "_") + `_v${dv.meta.version}`;
26
+ imports.add(`import { ${dvVarName} } from './${dv.meta.name.split(".")[0]}';`);
27
+ registrations.push(` .register(${dvVarName})`);
28
+ }
29
+ return {
30
+ code: `/**
31
+ * Auto-generated data views registry.
32
+ * DO NOT EDIT - This file is generated by ContractSpec exporter.
33
+ */
34
+ import { DataViewRegistry } from '@lssm/lib.contracts';
35
+
36
+ ${Array.from(imports).join("\n")}
37
+
38
+ export const dataViewsRegistry = new DataViewRegistry()
39
+ ${registrations.join("\n")};
40
+ `,
41
+ fileName: "dataviews-registry.ts"
42
+ };
43
+ }
44
+
45
+ //#endregion
46
+ export { exportDataViews, generateDataViewsRegistry };
47
+ //# sourceMappingURL=data-views.js.map
@@ -0,0 +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, DataViewSpec } from '@lssm/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: { name: string; version: number };\n item?: { name: 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.name,\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.name.replace(/\\./g, '_') + `_v${dv.meta.version}`;\n imports.add(\n `import { ${dvVarName} } from './${dv.meta.name.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 '@lssm/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,KAAK,QAAQ,OAAO,IAAI,GAAG,KAAK,GAAG,KAAK;AAClE,UAAQ,IACN,YAAY,UAAU,aAAa,GAAG,KAAK,KAAK,MAAM,IAAI,CAAC,GAAG,IAC/D;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"}
@@ -0,0 +1,28 @@
1
+ import { GeneratedRegistryCode } from "../types.js";
2
+ import { EventSpec } from "@lssm/lib.contracts";
3
+ import { AnySchemaModel } from "@lssm/lib.schema";
4
+
5
+ //#region src/openapi/exporter/events.d.ts
6
+
7
+ type OpenApiSchemaObject = Record<string, unknown>;
8
+ /**
9
+ * Exported event structure for OpenAPI extensions.
10
+ */
11
+ interface ExportedEvent {
12
+ name: string;
13
+ version: number;
14
+ description?: string;
15
+ payload: OpenApiSchemaObject | null;
16
+ pii?: string[];
17
+ }
18
+ /**
19
+ * Export events to OpenAPI extension format.
20
+ */
21
+ declare function exportEvents(events: EventSpec<AnySchemaModel>[]): ExportedEvent[];
22
+ /**
23
+ * Generate TypeScript code for events exports.
24
+ */
25
+ declare function generateEventsExports(events: EventSpec<AnySchemaModel>[]): GeneratedRegistryCode;
26
+ //#endregion
27
+ export { ExportedEvent, exportEvents, generateEventsExports };
28
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,39 @@
1
+ import { z } from "zod";
2
+
3
+ //#region src/openapi/exporter/events.ts
4
+ /**
5
+ * Export events to OpenAPI extension format.
6
+ */
7
+ function exportEvents(events) {
8
+ return events.map((event) => ({
9
+ name: event.name,
10
+ version: event.version,
11
+ description: event.description,
12
+ payload: event.payload ? z.toJSONSchema(event.payload.getZod()) : null,
13
+ pii: event.pii
14
+ }));
15
+ }
16
+ /**
17
+ * Generate TypeScript code for events exports.
18
+ */
19
+ function generateEventsExports(events) {
20
+ const eventExports = [];
21
+ for (const event of events) {
22
+ const eventVarName = event.name.replace(/\./g, "_") + `_v${event.version}`;
23
+ eventExports.push(`export { ${eventVarName} } from './${event.name.split(".")[0]}';`);
24
+ }
25
+ return {
26
+ code: `/**
27
+ * Auto-generated events exports.
28
+ * DO NOT EDIT - This file is generated by ContractSpec exporter.
29
+ */
30
+
31
+ ${eventExports.join("\n")}
32
+ `,
33
+ fileName: "events-exports.ts"
34
+ };
35
+ }
36
+
37
+ //#endregion
38
+ export { exportEvents, generateEventsExports };
39
+ //# sourceMappingURL=events.js.map
@@ -0,0 +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 '@lssm/lib.contracts';\nimport type { AnySchemaModel } from '@lssm/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.name,\n version: event.version,\n description: event.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 = event.name.replace(/\\./g, '_') + `_v${event.version}`;\n eventExports.push(`export { ${eventVarName} } from './${event.name.split('.')[0]}';`);\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;EACZ,SAAS,MAAM;EACf,aAAa,MAAM;EACnB,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,eAAe,MAAM,KAAK,QAAQ,OAAO,IAAI,GAAG,KAAK,MAAM;AACjE,eAAa,KAAK,YAAY,aAAa,aAAa,MAAM,KAAK,MAAM,IAAI,CAAC,GAAG,IAAI;;AAWvF,QAAO;EACL,MATW;;;;;EAKb,aAAa,KAAK,KAAK,CAAC;;EAKtB,UAAU;EACX"}
@@ -0,0 +1,37 @@
1
+ import { GeneratedRegistryCode } from "../types.js";
2
+ import { FeatureRegistry } from "@lssm/lib.contracts";
3
+
4
+ //#region src/openapi/exporter/features.d.ts
5
+
6
+ /**
7
+ * Exported feature structure for OpenAPI extensions.
8
+ */
9
+ interface ExportedFeature {
10
+ key: string;
11
+ description?: string;
12
+ owners?: string[];
13
+ stability?: string;
14
+ operations?: {
15
+ name: string;
16
+ version: number;
17
+ }[];
18
+ events?: {
19
+ name: string;
20
+ version: number;
21
+ }[];
22
+ presentations?: {
23
+ name: string;
24
+ version: number;
25
+ }[];
26
+ }
27
+ /**
28
+ * Export features to OpenAPI extension format.
29
+ */
30
+ declare function exportFeatures(registry: FeatureRegistry): ExportedFeature[];
31
+ /**
32
+ * Generate TypeScript code for features registry.
33
+ */
34
+ declare function generateFeaturesRegistry(registry: FeatureRegistry): GeneratedRegistryCode;
35
+ //#endregion
36
+ export { ExportedFeature, exportFeatures, generateFeaturesRegistry };
37
+ //# sourceMappingURL=features.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"features.d.ts","names":[],"sources":["../../../src/openapi/exporter/features.ts"],"sourcesContent":[],"mappings":";;;;;AAsBA;AAeA;;UA5BiB,eAAA;;;;;;;;;;;;;;;;;;;;;iBAaD,cAAA,WAAyB,kBAAkB;;;;iBAe3C,wBAAA,WACJ,kBACT"}
@@ -0,0 +1,46 @@
1
+ //#region src/openapi/exporter/features.ts
2
+ /**
3
+ * Export features to OpenAPI extension format.
4
+ */
5
+ function exportFeatures(registry) {
6
+ return registry.list().map((feature) => ({
7
+ key: feature.meta.key,
8
+ description: feature.meta.description,
9
+ owners: feature.meta.owners,
10
+ stability: feature.meta.stability,
11
+ operations: feature.operations,
12
+ events: feature.events,
13
+ presentations: feature.presentations
14
+ }));
15
+ }
16
+ /**
17
+ * Generate TypeScript code for features registry.
18
+ */
19
+ function generateFeaturesRegistry(registry) {
20
+ const features = registry.list();
21
+ const imports = /* @__PURE__ */ new Set();
22
+ const registrations = [];
23
+ for (const feature of features) {
24
+ const featureVarName = feature.meta.key.replace(/-/g, "_");
25
+ imports.add(`import { ${featureVarName} } from './${feature.meta.key}';`);
26
+ registrations.push(` .register(${featureVarName})`);
27
+ }
28
+ return {
29
+ code: `/**
30
+ * Auto-generated features registry.
31
+ * DO NOT EDIT - This file is generated by ContractSpec exporter.
32
+ */
33
+ import { FeatureRegistry } from '@lssm/lib.contracts';
34
+
35
+ ${Array.from(imports).join("\n")}
36
+
37
+ export const featuresRegistry = new FeatureRegistry()
38
+ ${registrations.join("\n")};
39
+ `,
40
+ fileName: "features-registry.ts"
41
+ };
42
+ }
43
+
44
+ //#endregion
45
+ export { exportFeatures, generateFeaturesRegistry };
46
+ //# sourceMappingURL=features.js.map
@@ -0,0 +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 { FeatureModuleSpec, FeatureRegistry } from '@lssm/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?: { name: string; version: number }[];\n events?: { name: string; version: number }[];\n presentations?: { name: 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(\n `import { ${featureVarName} } from './${feature.meta.key}';`\n );\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 '@lssm/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,IACN,YAAY,eAAe,aAAa,QAAQ,KAAK,IAAI,IAC1D;AACD,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"}
@@ -0,0 +1,30 @@
1
+ import { GeneratedRegistryCode } from "../types.js";
2
+ import { FormRegistry } from "@lssm/lib.contracts";
3
+
4
+ //#region src/openapi/exporter/forms.d.ts
5
+
6
+ type OpenApiSchemaObject = Record<string, unknown>;
7
+ /**
8
+ * Exported form structure for OpenAPI extensions.
9
+ */
10
+ interface ExportedForm {
11
+ key: string;
12
+ version: number;
13
+ description?: string;
14
+ stability?: string;
15
+ owners?: string[];
16
+ fields: unknown[];
17
+ model: OpenApiSchemaObject | null;
18
+ actions?: unknown[];
19
+ }
20
+ /**
21
+ * Export forms to OpenAPI extension format.
22
+ */
23
+ declare function exportForms(registry: FormRegistry): ExportedForm[];
24
+ /**
25
+ * Generate TypeScript code for forms registry.
26
+ */
27
+ declare function generateFormsRegistry(registry: FormRegistry): GeneratedRegistryCode;
28
+ //#endregion
29
+ export { ExportedForm, exportForms, generateFormsRegistry };
30
+ //# sourceMappingURL=forms.d.ts.map
@@ -0,0 +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"}