@contractspec/lib.contracts-transformers 1.56.1 → 1.58.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.
Files changed (135) hide show
  1. package/dist/browser/common/index.js +86 -0
  2. package/dist/browser/index.js +2414 -0
  3. package/dist/browser/openapi/index.js +2404 -0
  4. package/dist/common/index.d.ts +6 -3
  5. package/dist/common/index.d.ts.map +1 -0
  6. package/dist/common/index.js +87 -3
  7. package/dist/common/types.d.ts +119 -121
  8. package/dist/common/types.d.ts.map +1 -1
  9. package/dist/common/utils.d.ts +11 -14
  10. package/dist/common/utils.d.ts.map +1 -1
  11. package/dist/index.d.ts +18 -18
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +2415 -18
  14. package/dist/node/common/index.js +86 -0
  15. package/dist/node/index.js +2414 -0
  16. package/dist/node/openapi/index.js +2404 -0
  17. package/dist/openapi/differ.d.ts +21 -22
  18. package/dist/openapi/differ.d.ts.map +1 -1
  19. package/dist/openapi/exporter/data-views.d.ts +24 -26
  20. package/dist/openapi/exporter/data-views.d.ts.map +1 -1
  21. package/dist/openapi/exporter/events.d.ts +15 -16
  22. package/dist/openapi/exporter/events.d.ts.map +1 -1
  23. package/dist/openapi/exporter/features.d.ts +23 -25
  24. package/dist/openapi/exporter/features.d.ts.map +1 -1
  25. package/dist/openapi/exporter/forms.d.ts +17 -18
  26. package/dist/openapi/exporter/forms.d.ts.map +1 -1
  27. package/dist/openapi/exporter/index.d.ts +12 -0
  28. package/dist/openapi/exporter/index.d.ts.map +1 -0
  29. package/dist/openapi/exporter/operations.d.ts +29 -30
  30. package/dist/openapi/exporter/operations.d.ts.map +1 -1
  31. package/dist/openapi/exporter/presentations.d.ts +16 -18
  32. package/dist/openapi/exporter/presentations.d.ts.map +1 -1
  33. package/dist/openapi/exporter/registries.d.ts +13 -15
  34. package/dist/openapi/exporter/registries.d.ts.map +1 -1
  35. package/dist/openapi/exporter/workflows.d.ts +23 -25
  36. package/dist/openapi/exporter/workflows.d.ts.map +1 -1
  37. package/dist/openapi/exporter.d.ts +24 -24
  38. package/dist/openapi/exporter.d.ts.map +1 -1
  39. package/dist/openapi/exporter.test.d.ts +2 -0
  40. package/dist/openapi/exporter.test.d.ts.map +1 -0
  41. package/dist/openapi/importer/analyzer.d.ts +14 -0
  42. package/dist/openapi/importer/analyzer.d.ts.map +1 -0
  43. package/dist/openapi/importer/events.d.ts +7 -0
  44. package/dist/openapi/importer/events.d.ts.map +1 -0
  45. package/dist/openapi/importer/generator.d.ts +8 -0
  46. package/dist/openapi/importer/generator.d.ts.map +1 -0
  47. package/dist/openapi/importer/grouping.d.ts +27 -0
  48. package/dist/openapi/importer/grouping.d.ts.map +1 -0
  49. package/dist/openapi/importer/index.d.ts +11 -10
  50. package/dist/openapi/importer/index.d.ts.map +1 -1
  51. package/dist/openapi/importer/models.d.ts +7 -0
  52. package/dist/openapi/importer/models.d.ts.map +1 -0
  53. package/dist/openapi/importer/schemas.d.ts +15 -0
  54. package/dist/openapi/importer/schemas.d.ts.map +1 -0
  55. package/dist/openapi/importer.d.ts +6 -0
  56. package/dist/openapi/importer.d.ts.map +1 -0
  57. package/dist/openapi/index.d.ts +12 -16
  58. package/dist/openapi/index.d.ts.map +1 -0
  59. package/dist/openapi/index.js +2405 -18
  60. package/dist/openapi/parser/document.d.ts +5 -10
  61. package/dist/openapi/parser/document.d.ts.map +1 -1
  62. package/dist/openapi/parser/index.d.ts +6 -0
  63. package/dist/openapi/parser/index.d.ts.map +1 -0
  64. package/dist/openapi/parser/operation.d.ts +7 -0
  65. package/dist/openapi/parser/operation.d.ts.map +1 -0
  66. package/dist/openapi/parser/parameters.d.ts +11 -0
  67. package/dist/openapi/parser/parameters.d.ts.map +1 -0
  68. package/dist/openapi/parser/resolvers.d.ts +21 -0
  69. package/dist/openapi/parser/resolvers.d.ts.map +1 -0
  70. package/dist/openapi/parser/utils.d.ts +9 -9
  71. package/dist/openapi/parser/utils.d.ts.map +1 -1
  72. package/dist/openapi/parser.d.ts +6 -0
  73. package/dist/openapi/parser.d.ts.map +1 -0
  74. package/dist/openapi/schema-converter.d.ts +45 -46
  75. package/dist/openapi/schema-converter.d.ts.map +1 -1
  76. package/dist/openapi/schema-generators/index.d.ts +115 -0
  77. package/dist/openapi/schema-generators/index.d.ts.map +1 -0
  78. package/dist/openapi/schema-generators.test.d.ts +2 -0
  79. package/dist/openapi/schema-generators.test.d.ts.map +1 -0
  80. package/dist/openapi/types.d.ts +198 -200
  81. package/dist/openapi/types.d.ts.map +1 -1
  82. package/package.json +53 -20
  83. package/dist/common/utils.js +0 -103
  84. package/dist/common/utils.js.map +0 -1
  85. package/dist/openapi/differ.js +0 -222
  86. package/dist/openapi/differ.js.map +0 -1
  87. package/dist/openapi/exporter/data-views.js +0 -47
  88. package/dist/openapi/exporter/data-views.js.map +0 -1
  89. package/dist/openapi/exporter/events.js +0 -39
  90. package/dist/openapi/exporter/events.js.map +0 -1
  91. package/dist/openapi/exporter/features.js +0 -46
  92. package/dist/openapi/exporter/features.js.map +0 -1
  93. package/dist/openapi/exporter/forms.js +0 -49
  94. package/dist/openapi/exporter/forms.js.map +0 -1
  95. package/dist/openapi/exporter/index.js +0 -8
  96. package/dist/openapi/exporter/operations.js +0 -143
  97. package/dist/openapi/exporter/operations.js.map +0 -1
  98. package/dist/openapi/exporter/presentations.js +0 -60
  99. package/dist/openapi/exporter/presentations.js.map +0 -1
  100. package/dist/openapi/exporter/registries.js +0 -29
  101. package/dist/openapi/exporter/registries.js.map +0 -1
  102. package/dist/openapi/exporter/workflows.js +0 -54
  103. package/dist/openapi/exporter/workflows.js.map +0 -1
  104. package/dist/openapi/exporter.js +0 -122
  105. package/dist/openapi/exporter.js.map +0 -1
  106. package/dist/openapi/importer/analyzer.js +0 -28
  107. package/dist/openapi/importer/analyzer.js.map +0 -1
  108. package/dist/openapi/importer/events.js +0 -40
  109. package/dist/openapi/importer/events.js.map +0 -1
  110. package/dist/openapi/importer/generator.js +0 -105
  111. package/dist/openapi/importer/generator.js.map +0 -1
  112. package/dist/openapi/importer/grouping.js +0 -73
  113. package/dist/openapi/importer/grouping.js.map +0 -1
  114. package/dist/openapi/importer/index.js +0 -175
  115. package/dist/openapi/importer/index.js.map +0 -1
  116. package/dist/openapi/importer/models.js +0 -22
  117. package/dist/openapi/importer/models.js.map +0 -1
  118. package/dist/openapi/importer/schemas.js +0 -60
  119. package/dist/openapi/importer/schemas.js.map +0 -1
  120. package/dist/openapi/parser/document.js +0 -95
  121. package/dist/openapi/parser/document.js.map +0 -1
  122. package/dist/openapi/parser/index.js +0 -5
  123. package/dist/openapi/parser/operation.js +0 -59
  124. package/dist/openapi/parser/operation.js.map +0 -1
  125. package/dist/openapi/parser/parameters.js +0 -37
  126. package/dist/openapi/parser/parameters.js.map +0 -1
  127. package/dist/openapi/parser/resolvers.js +0 -63
  128. package/dist/openapi/parser/resolvers.js.map +0 -1
  129. package/dist/openapi/parser/utils.js +0 -48
  130. package/dist/openapi/parser/utils.js.map +0 -1
  131. package/dist/openapi/parser.js +0 -6
  132. package/dist/openapi/schema-converter.js +0 -161
  133. package/dist/openapi/schema-converter.js.map +0 -1
  134. package/dist/openapi/schema-generators/index.js +0 -462
  135. package/dist/openapi/schema-generators/index.js.map +0 -1
@@ -1,143 +0,0 @@
1
- import { z } from "zod";
2
- import { compareVersions } from "compare-versions";
3
-
4
- //#region src/openapi/exporter/operations.ts
5
- /**
6
- * Convert a spec name and version to an operationId.
7
- */
8
- function toOperationId(name, version) {
9
- return `${name.replace(/\./g, "_")}_v${version.replace(/\./g, "_")}`;
10
- }
11
- /**
12
- * Convert a spec name and version to a schema name.
13
- */
14
- function toSchemaName(prefix, name, version) {
15
- return `${prefix}_${toOperationId(name, version)}`;
16
- }
17
- /**
18
- * Determine HTTP method from spec kind and override.
19
- */
20
- function toHttpMethod(kind, override) {
21
- return (override ?? (kind === "query" ? "GET" : "POST")).toLowerCase();
22
- }
23
- /**
24
- * Generate default REST path from spec name and version.
25
- */
26
- function defaultRestPath(name, version) {
27
- return `/${name.replace(/\./g, "/")}/v${version}`;
28
- }
29
- /**
30
- * Get REST path from spec, using transport override or default.
31
- */
32
- function toRestPath(spec) {
33
- const path = spec.transport?.rest?.path ?? defaultRestPath(spec.meta.key, spec.meta.version);
34
- return path.startsWith("/") ? path : `/${path}`;
35
- }
36
- /**
37
- * Convert a SchemaModel to JSON Schema using Zod.
38
- */
39
- function schemaModelToJsonSchema(schema) {
40
- if (!schema) return null;
41
- return z.toJSONSchema(schema.getZod());
42
- }
43
- /**
44
- * Extract JSON Schema for a spec's input and output.
45
- */
46
- function jsonSchemaForSpec(spec) {
47
- return {
48
- input: schemaModelToJsonSchema(spec.io.input),
49
- output: schemaModelToJsonSchema(spec.io.output),
50
- meta: {
51
- key: spec.meta.key,
52
- version: spec.meta.version,
53
- kind: spec.meta.kind,
54
- description: spec.meta.description,
55
- tags: spec.meta.tags ?? [],
56
- stability: spec.meta.stability ?? "stable"
57
- }
58
- };
59
- }
60
- /**
61
- * Export operations from a registry to OpenAPI paths and schemas.
62
- */
63
- function exportOperations(registry) {
64
- const specs = Array.from(registry.list().values()).filter((s) => s.meta.kind === "command" || s.meta.kind === "query").sort((a, b) => {
65
- const byName = a.meta.key.localeCompare(b.meta.key);
66
- return byName !== 0 ? byName : compareVersions(a.meta.version, b.meta.version);
67
- });
68
- const paths = {};
69
- const schemas = {};
70
- for (const spec of specs) {
71
- const schema = jsonSchemaForSpec(spec);
72
- const method = toHttpMethod(spec.meta.kind, spec.transport?.rest?.method);
73
- const path = toRestPath(spec);
74
- const operationId = toOperationId(spec.meta.key, spec.meta.version);
75
- const pathItem = paths[path] ??= {};
76
- const op = {
77
- operationId,
78
- summary: spec.meta.description ?? spec.meta.key,
79
- description: spec.meta.description,
80
- tags: spec.meta.tags ?? [],
81
- "x-contractspec": {
82
- name: spec.meta.key,
83
- version: spec.meta.version,
84
- kind: spec.meta.kind
85
- },
86
- responses: {}
87
- };
88
- if (schema.input) {
89
- const inputName = toSchemaName("Input", spec.meta.key, spec.meta.version);
90
- schemas[inputName] = schema.input;
91
- op["requestBody"] = {
92
- required: true,
93
- content: { "application/json": { schema: { $ref: `#/components/schemas/${inputName}` } } }
94
- };
95
- }
96
- const responses = {};
97
- if (schema.output) {
98
- const outputName = toSchemaName("Output", spec.meta.key, spec.meta.version);
99
- schemas[outputName] = schema.output;
100
- responses["200"] = {
101
- description: "OK",
102
- content: { "application/json": { schema: { $ref: `#/components/schemas/${outputName}` } } }
103
- };
104
- } else responses["200"] = { description: "OK" };
105
- op["responses"] = responses;
106
- pathItem[method] = op;
107
- }
108
- return {
109
- paths,
110
- schemas
111
- };
112
- }
113
- /**
114
- * Generate TypeScript code for operations registry.
115
- */
116
- function generateOperationsRegistry(registry) {
117
- const specs = Array.from(registry.list().values());
118
- const imports = /* @__PURE__ */ new Set();
119
- const registrations = [];
120
- for (const spec of specs) {
121
- const specVarName = spec.meta.key.replace(/\./g, "_") + `_v${spec.meta.version.replace(/\./g, "_")}`;
122
- imports.add(`import { ${specVarName} } from './${spec.meta.key.split(".")[0]}';`);
123
- registrations.push(` .register(${specVarName})`);
124
- }
125
- return {
126
- code: `/**
127
- * Auto-generated operations registry.
128
- * DO NOT EDIT - This file is generated by ContractSpec exporter.
129
- */
130
- import { OperationSpecRegistry } from '@contractspec/lib.contracts';
131
-
132
- ${Array.from(imports).join("\n")}
133
-
134
- export const operationsRegistry = new OperationSpecRegistry()
135
- ${registrations.join("\n")};
136
- `,
137
- fileName: "operations-registry.ts"
138
- };
139
- }
140
-
141
- //#endregion
142
- export { defaultRestPath, exportOperations, generateOperationsRegistry, jsonSchemaForSpec, schemaModelToJsonSchema, toHttpMethod, toOperationId, toRestPath, toSchemaName };
143
- //# sourceMappingURL=operations.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"operations.js","names":[],"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":";;;;;;;AAkBA,SAAgB,cAAc,MAAc,SAAyB;AACnE,QAAO,GAAG,KAAK,QAAQ,OAAO,IAAI,CAAC,IAAI,QAAQ,QAAQ,OAAO,IAAI;;;;;AAMpE,SAAgB,aACd,QACA,MACA,SACQ;AACR,QAAO,GAAG,OAAO,GAAG,cAAc,MAAM,QAAQ;;;;;AAMlD,SAAgB,aACd,MACA,UACQ;AAER,SADe,aAAa,SAAS,UAAU,QAAQ,SACzC,aAAa;;;;;AAM7B,SAAgB,gBAAgB,MAAc,SAAyB;AACrE,QAAO,IAAI,KAAK,QAAQ,OAAO,IAAI,CAAC,IAAI;;;;;AAM1C,SAAgB,WAAW,MAAgC;CACzD,MAAM,OACJ,KAAK,WAAW,MAAM,QACtB,gBAAgB,KAAK,KAAK,KAAK,KAAK,KAAK,QAAQ;AACnD,QAAO,KAAK,WAAW,IAAI,GAAG,OAAO,IAAI;;;;;AAM3C,SAAgB,wBACd,QAC4B;AAC5B,KAAI,CAAC,OAAQ,QAAO;AACpB,QAAO,EAAE,aAAa,OAAO,QAAQ,CAAC;;;;;AAmBxC,SAAgB,kBACd,MACgB;AAChB,QAAO;EACL,OAAO,wBAAwB,KAAK,GAAG,MAAM;EAC7C,QAAQ,wBAAwB,KAAK,GAAG,OAAgC;EACxE,MAAM;GACJ,KAAK,KAAK,KAAK;GACf,SAAS,KAAK,KAAK;GACnB,MAAM,KAAK,KAAK;GAChB,aAAa,KAAK,KAAK;GACvB,MAAM,KAAK,KAAK,QAAQ,EAAE;GAC1B,WAAW,KAAK,KAAK,aAAa;GACnC;EACF;;;;;AAcH,SAAgB,iBACd,UACwB;CACxB,MAAM,QAAQ,MAAM,KAAK,SAAS,MAAM,CAAC,QAAQ,CAAC,CAC/C,QACE,MACC,EAAE,KAAK,SAAS,aAAa,EAAE,KAAK,SAAS,QAChD,CACA,MAAM,GAAG,MAAM;EACd,MAAM,SAAS,EAAE,KAAK,IAAI,cAAc,EAAE,KAAK,IAAI;AACnD,SAAO,WAAW,IACd,SACA,gBAAgB,EAAE,KAAK,SAAS,EAAE,KAAK,QAAQ;GACnD;CAEJ,MAAM,QAAiD,EAAE;CACzD,MAAM,UAA+C,EAAE;AAEvD,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,SAAS,kBACb,KACD;EACD,MAAM,SAAS,aAAa,KAAK,KAAK,MAAM,KAAK,WAAW,MAAM,OAAO;EACzE,MAAM,OAAO,WAAW,KAAK;EAE7B,MAAM,cAAc,cAAc,KAAK,KAAK,KAAK,KAAK,KAAK,QAAQ;EAEnE,MAAM,WAAY,MAAM,UAAU,EAAE;EACpC,MAAM,KAA8B;GAClC;GACA,SAAS,KAAK,KAAK,eAAe,KAAK,KAAK;GAC5C,aAAa,KAAK,KAAK;GACvB,MAAM,KAAK,KAAK,QAAQ,EAAE;GAC1B,kBAAkB;IAChB,MAAM,KAAK,KAAK;IAChB,SAAS,KAAK,KAAK;IACnB,MAAM,KAAK,KAAK;IACjB;GACD,WAAW,EAAE;GACd;AAED,MAAI,OAAO,OAAO;GAChB,MAAM,YAAY,aAAa,SAAS,KAAK,KAAK,KAAK,KAAK,KAAK,QAAQ;AACzE,WAAQ,aAAa,OAAO;AAC5B,MAAG,iBAAiB;IAClB,UAAU;IACV,SAAS,EACP,oBAAoB,EAClB,QAAQ,EAAE,MAAM,wBAAwB,aAAa,EACtD,EACF;IACF;;EAGH,MAAM,YAAqC,EAAE;AAC7C,MAAI,OAAO,QAAQ;GACjB,MAAM,aAAa,aACjB,UACA,KAAK,KAAK,KACV,KAAK,KAAK,QACX;AACD,WAAQ,cAAc,OAAO;AAC7B,aAAU,SAAS;IACjB,aAAa;IACb,SAAS,EACP,oBAAoB,EAClB,QAAQ,EAAE,MAAM,wBAAwB,cAAc,EACvD,EACF;IACF;QAED,WAAU,SAAS,EAAE,aAAa,MAAM;AAE1C,KAAG,eAAe;AAElB,WAAS,UAAU;;AAGrB,QAAO;EAAE;EAAO;EAAS;;;;;AAM3B,SAAgB,2BACd,UACuB;CACvB,MAAM,QAAQ,MAAM,KAAK,SAAS,MAAM,CAAC,QAAQ,CAAC;CAElD,MAAM,0BAAU,IAAI,KAAa;CACjC,MAAM,gBAA0B,EAAE;AAElC,MAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,cACJ,KAAK,KAAK,IAAI,QAAQ,OAAO,IAAI,GACjC,KAAK,KAAK,KAAK,QAAQ,QAAQ,OAAO,IAAI;AAC5C,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,60 +0,0 @@
1
- //#region src/openapi/exporter/presentations.ts
2
- /**
3
- * Export presentations to OpenAPI extension format.
4
- */
5
- function exportPresentations(registry) {
6
- return registry.list().map((pres) => ({
7
- name: pres.meta.key,
8
- version: pres.meta.version,
9
- description: pres.meta.description,
10
- stability: pres.meta.stability,
11
- sourceType: pres.source.type,
12
- targets: pres.targets,
13
- tags: pres.meta.tags
14
- }));
15
- }
16
- /**
17
- * Export presentations from an array.
18
- */
19
- function exportPresentationsFromArray(descriptors) {
20
- return descriptors.map((desc) => ({
21
- name: desc.meta.key,
22
- version: desc.meta.version,
23
- description: desc.meta.description,
24
- stability: desc.meta.stability,
25
- sourceType: desc.source.type,
26
- targets: desc.targets,
27
- tags: desc.meta.tags
28
- }));
29
- }
30
- /**
31
- * Generate TypeScript code for presentations registry.
32
- */
33
- function generatePresentationsRegistry(registry) {
34
- const presentations = registry.list();
35
- const imports = /* @__PURE__ */ new Set();
36
- const registrations = [];
37
- for (const pres of presentations) {
38
- const presVarName = pres.meta.key.replace(/\./g, "_") + `_v${pres.meta.version}`;
39
- imports.add(`import { ${presVarName} } from './${pres.meta.key.split(".")[0]}';`);
40
- registrations.push(` .register(${presVarName})`);
41
- }
42
- return {
43
- code: `/**
44
- * Auto-generated presentations registry.
45
- * DO NOT EDIT - This file is generated by ContractSpec exporter.
46
- */
47
- import { PresentationRegistry } from '@contractspec/lib.contracts';
48
-
49
- ${Array.from(imports).join("\n")}
50
-
51
- export const presentationsRegistry = new PresentationRegistry()
52
- ${registrations.join("\n")};
53
- `,
54
- fileName: "presentations-registry.ts"
55
- };
56
- }
57
-
58
- //#endregion
59
- export { exportPresentations, exportPresentationsFromArray, generatePresentationsRegistry };
60
- //# sourceMappingURL=presentations.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"presentations.js","names":[],"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,MAAM,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,29 +0,0 @@
1
- //#region src/openapi/exporter/registries.ts
2
- /**
3
- * Generate unified index file that exports all registries.
4
- */
5
- function generateRegistryIndex(options = {}) {
6
- const { operations = true, events = true, features = true, presentations = true, forms = true, dataViews = true, workflows = true } = options;
7
- const exports = [];
8
- if (operations) exports.push("export * from './operations-registry';");
9
- if (events) exports.push("export * from './events-exports';");
10
- if (features) exports.push("export * from './features-registry';");
11
- if (presentations) exports.push("export * from './presentations-registry';");
12
- if (forms) exports.push("export * from './forms-registry';");
13
- if (dataViews) exports.push("export * from './dataviews-registry';");
14
- if (workflows) exports.push("export * from './workflows-registry';");
15
- return {
16
- code: `/**
17
- * Auto-generated registry index.
18
- * DO NOT EDIT - This file is generated by ContractSpec exporter.
19
- */
20
-
21
- ${exports.join("\n")}
22
- `,
23
- fileName: "index.ts"
24
- };
25
- }
26
-
27
- //#endregion
28
- export { generateRegistryIndex };
29
- //# sourceMappingURL=registries.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"registries.js","names":[],"sources":["../../../src/openapi/exporter/registries.ts"],"sourcesContent":["/**\n * Unified registries generator - combines all surface registries.\n */\nimport type { GeneratedRegistryCode } from '../types';\n\n/**\n * Registry generation options.\n */\nexport interface RegistryGenerationOptions {\n operations?: boolean;\n events?: boolean;\n features?: boolean;\n presentations?: boolean;\n forms?: boolean;\n dataViews?: boolean;\n workflows?: boolean;\n}\n\n/**\n * Generate unified index file that exports all registries.\n */\nexport function generateRegistryIndex(\n options: RegistryGenerationOptions = {}\n): GeneratedRegistryCode {\n const {\n operations = true,\n events = true,\n features = true,\n presentations = true,\n forms = true,\n dataViews = true,\n workflows = true,\n } = options;\n\n const exports: string[] = [];\n\n if (operations) {\n exports.push(\"export * from './operations-registry';\");\n }\n if (events) {\n exports.push(\"export * from './events-exports';\");\n }\n if (features) {\n exports.push(\"export * from './features-registry';\");\n }\n if (presentations) {\n exports.push(\"export * from './presentations-registry';\");\n }\n if (forms) {\n exports.push(\"export * from './forms-registry';\");\n }\n if (dataViews) {\n exports.push(\"export * from './dataviews-registry';\");\n }\n if (workflows) {\n exports.push(\"export * from './workflows-registry';\");\n }\n\n const code = `/**\n * Auto-generated registry index.\n * DO NOT EDIT - This file is generated by ContractSpec exporter.\n */\n\n${exports.join('\\n')}\n`;\n\n return {\n code,\n fileName: 'index.ts',\n };\n}\n"],"mappings":";;;;AAqBA,SAAgB,sBACd,UAAqC,EAAE,EAChB;CACvB,MAAM,EACJ,aAAa,MACb,SAAS,MACT,WAAW,MACX,gBAAgB,MAChB,QAAQ,MACR,YAAY,MACZ,YAAY,SACV;CAEJ,MAAM,UAAoB,EAAE;AAE5B,KAAI,WACF,SAAQ,KAAK,yCAAyC;AAExD,KAAI,OACF,SAAQ,KAAK,oCAAoC;AAEnD,KAAI,SACF,SAAQ,KAAK,uCAAuC;AAEtD,KAAI,cACF,SAAQ,KAAK,4CAA4C;AAE3D,KAAI,MACF,SAAQ,KAAK,oCAAoC;AAEnD,KAAI,UACF,SAAQ,KAAK,wCAAwC;AAEvD,KAAI,UACF,SAAQ,KAAK,wCAAwC;AAWvD,QAAO;EACL,MATW;;;;;EAKb,QAAQ,KAAK,KAAK,CAAC;;EAKjB,UAAU;EACX"}
@@ -1,54 +0,0 @@
1
- //#region src/openapi/exporter/workflows.ts
2
- /**
3
- * Export workflows to OpenAPI extension format.
4
- */
5
- function exportWorkflows(registry) {
6
- return registry.list().map((wf) => ({
7
- name: wf.meta.key,
8
- version: wf.meta.version,
9
- description: wf.meta.description,
10
- stability: wf.meta.stability,
11
- owners: wf.meta.owners,
12
- steps: wf.definition.steps.map((s) => ({
13
- id: s.id,
14
- type: s.type,
15
- label: s.label
16
- })),
17
- transitions: wf.definition.transitions.map((t) => ({
18
- from: t.from,
19
- to: t.to,
20
- label: t.label
21
- }))
22
- }));
23
- }
24
- /**
25
- * Generate TypeScript code for workflows registry.
26
- */
27
- function generateWorkflowsRegistry(registry) {
28
- const workflows = registry.list();
29
- const imports = /* @__PURE__ */ new Set();
30
- const registrations = [];
31
- for (const wf of workflows) {
32
- const wfVarName = wf.meta.key.replace(/\./g, "_") + `_v${wf.meta.version}`;
33
- imports.add(`import { ${wfVarName} } from './${wf.meta.key.split(".")[0]}';`);
34
- registrations.push(` .register(${wfVarName})`);
35
- }
36
- return {
37
- code: `/**
38
- * Auto-generated workflows registry.
39
- * DO NOT EDIT - This file is generated by ContractSpec exporter.
40
- */
41
- import { WorkflowRegistry } from '@contractspec/lib.contracts';
42
-
43
- ${Array.from(imports).join("\n")}
44
-
45
- export const workflowsRegistry = new WorkflowRegistry()
46
- ${registrations.join("\n")};
47
- `,
48
- fileName: "workflows-registry.ts"
49
- };
50
- }
51
-
52
- //#endregion
53
- export { exportWorkflows, generateWorkflowsRegistry };
54
- //# sourceMappingURL=workflows.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"workflows.js","names":[],"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,MAAM,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,122 +0,0 @@
1
- import { defaultRestPath, exportOperations, generateOperationsRegistry } from "./exporter/operations.js";
2
- import { exportEvents, generateEventsExports } from "./exporter/events.js";
3
- import { exportFeatures, generateFeaturesRegistry } from "./exporter/features.js";
4
- import { exportPresentations, generatePresentationsRegistry } from "./exporter/presentations.js";
5
- import { exportForms, generateFormsRegistry } from "./exporter/forms.js";
6
- import { exportDataViews, generateDataViewsRegistry } from "./exporter/data-views.js";
7
- import { exportWorkflows, generateWorkflowsRegistry } from "./exporter/workflows.js";
8
- import { generateRegistryIndex } from "./exporter/registries.js";
9
-
10
- //#region src/openapi/exporter.ts
11
- /**
12
- * Export a OperationSpecRegistry to an OpenAPI 3.1 document.
13
- * @deprecated Use exportContractSpec for full surface support.
14
- */
15
- function openApiForRegistry(registry, options = {}) {
16
- const { paths, schemas } = exportOperations(registry);
17
- return {
18
- openapi: "3.1.0",
19
- info: {
20
- title: options.title ?? "ContractSpec API",
21
- version: options.version ?? "0.0.0",
22
- ...options.description ? { description: options.description } : {}
23
- },
24
- ...options.servers ? { servers: options.servers } : {},
25
- paths,
26
- components: { schemas }
27
- };
28
- }
29
- /**
30
- * Export all ContractSpec surfaces to OpenAPI document with extensions.
31
- */
32
- function exportContractSpec(registries, options = {}) {
33
- const { operations: includeOps = true, events: includeEvents = true, features: includeFeatures = true, presentations: includePresentations = true, forms: includeForms = true, dataViews: includeDataViews = true, workflows: includeWorkflows = true, generateRegistries = true } = options;
34
- let paths = {};
35
- let schemas = {};
36
- if (includeOps && registries.operations) {
37
- const opResult = exportOperations(registries.operations);
38
- paths = opResult.paths;
39
- schemas = opResult.schemas;
40
- }
41
- const doc = {
42
- openapi: "3.1.0",
43
- info: {
44
- title: options.title ?? "ContractSpec API",
45
- version: options.version ?? "0.0.0",
46
- ...options.description ? { description: options.description } : {}
47
- },
48
- ...options.servers ? { servers: options.servers } : {},
49
- paths,
50
- components: { schemas }
51
- };
52
- if (includeEvents && registries.events?.length) doc["x-contractspec-events"] = exportEvents(registries.events);
53
- if (includeFeatures && registries.features) doc["x-contractspec-features"] = exportFeatures(registries.features);
54
- if (includePresentations && registries.presentations) doc["x-contractspec-presentations"] = exportPresentations(registries.presentations);
55
- if (includeForms && registries.forms) doc["x-contractspec-forms"] = exportForms(registries.forms);
56
- if (includeDataViews && registries.dataViews) doc["x-contractspec-dataviews"] = exportDataViews(registries.dataViews);
57
- if (includeWorkflows && registries.workflows) doc["x-contractspec-workflows"] = exportWorkflows(registries.workflows);
58
- const result = { openApi: doc };
59
- if (generateRegistries) {
60
- result.registries = {};
61
- if (includeOps && registries.operations) result.registries.operations = generateOperationsRegistry(registries.operations);
62
- if (includeEvents && registries.events?.length) result.registries.events = generateEventsExports(registries.events);
63
- if (includeFeatures && registries.features) result.registries.features = generateFeaturesRegistry(registries.features);
64
- if (includePresentations && registries.presentations) result.registries.presentations = generatePresentationsRegistry(registries.presentations);
65
- if (includeForms && registries.forms) result.registries.forms = generateFormsRegistry(registries.forms);
66
- if (includeDataViews && registries.dataViews) result.registries.dataViews = generateDataViewsRegistry(registries.dataViews);
67
- if (includeWorkflows && registries.workflows) result.registries.workflows = generateWorkflowsRegistry(registries.workflows);
68
- result.registries.index = generateRegistryIndex({
69
- operations: includeOps && !!registries.operations,
70
- events: includeEvents && !!registries.events?.length,
71
- features: includeFeatures && !!registries.features,
72
- presentations: includePresentations && !!registries.presentations,
73
- forms: includeForms && !!registries.forms,
74
- dataViews: includeDataViews && !!registries.dataViews,
75
- workflows: includeWorkflows && !!registries.workflows
76
- });
77
- }
78
- return result;
79
- }
80
- /**
81
- * Export a OperationSpecRegistry to OpenAPI JSON string.
82
- */
83
- function openApiToJson(registry, options = {}) {
84
- const doc = openApiForRegistry(registry, options);
85
- return JSON.stringify(doc, null, 2);
86
- }
87
- /**
88
- * Export a OperationSpecRegistry to OpenAPI YAML string.
89
- */
90
- function openApiToYaml(registry, options = {}) {
91
- return jsonToYaml(openApiForRegistry(registry, options));
92
- }
93
- /**
94
- * Export ContractSpec to JSON string (all surfaces).
95
- */
96
- function contractSpecToJson(registries, options = {}) {
97
- const result = exportContractSpec(registries, options);
98
- return JSON.stringify(result.openApi, null, 2);
99
- }
100
- /**
101
- * Export ContractSpec to YAML string (all surfaces).
102
- */
103
- function contractSpecToYaml(registries, options = {}) {
104
- return jsonToYaml(exportContractSpec(registries, options).openApi);
105
- }
106
- /**
107
- * Simple JSON to YAML conversion.
108
- */
109
- function jsonToYaml(obj, indent = 0) {
110
- const spaces = " ".repeat(indent);
111
- let yaml = "";
112
- if (Array.isArray(obj)) for (const item of obj) if (typeof item === "object" && item !== null) yaml += `${spaces}-\n${jsonToYaml(item, indent + 1)}`;
113
- else yaml += `${spaces}- ${JSON.stringify(item)}\n`;
114
- else if (typeof obj === "object" && obj !== null) for (const [key, value] of Object.entries(obj)) if (Array.isArray(value)) yaml += `${spaces}${key}:\n${jsonToYaml(value, indent + 1)}`;
115
- else if (typeof value === "object" && value !== null) yaml += `${spaces}${key}:\n${jsonToYaml(value, indent + 1)}`;
116
- else yaml += `${spaces}${key}: ${JSON.stringify(value)}\n`;
117
- return yaml;
118
- }
119
-
120
- //#endregion
121
- export { contractSpecToJson, contractSpecToYaml, exportContractSpec, openApiForRegistry, openApiToJson, openApiToYaml };
122
- //# sourceMappingURL=exporter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"exporter.js","names":[],"sources":["../../src/openapi/exporter.ts"],"sourcesContent":["/**\n * Export ContractSpec specs to OpenAPI 3.1 format.\n * Refactored to use modular exporters for all surfaces.\n */\nimport type {\n OperationSpecRegistry,\n FeatureRegistry,\n PresentationRegistry,\n FormRegistry,\n DataViewRegistry,\n WorkflowRegistry,\n EventSpec,\n PresentationSpec,\n} from '@contractspec/lib.contracts';\nimport type { AnySchemaModel } from '@contractspec/lib.schema';\nimport type {\n ContractSpecOpenApiDocument,\n OpenApiExportOptions,\n ContractSpecExportOptions,\n ContractSpecExportResult,\n} from './types';\nimport {\n exportOperations,\n generateOperationsRegistry,\n defaultRestPath as defaultRestPathFn,\n} from './exporter/operations';\nimport { exportEvents, generateEventsExports } from './exporter/events';\nimport { exportFeatures, generateFeaturesRegistry } from './exporter/features';\nimport {\n exportPresentations,\n generatePresentationsRegistry,\n} from './exporter/presentations';\nimport { exportForms, generateFormsRegistry } from './exporter/forms';\nimport {\n exportDataViews,\n generateDataViewsRegistry,\n} from './exporter/data-views';\nimport {\n exportWorkflows,\n generateWorkflowsRegistry,\n} from './exporter/workflows';\nimport { generateRegistryIndex } from './exporter/registries';\n\n/**\n * Input registries for unified export.\n */\nexport interface ContractSpecRegistries {\n operations?: OperationSpecRegistry;\n events?: EventSpec<AnySchemaModel>[];\n features?: FeatureRegistry;\n presentations?: PresentationRegistry;\n presentationsArray?: PresentationSpec[];\n forms?: FormRegistry;\n dataViews?: DataViewRegistry;\n workflows?: WorkflowRegistry;\n}\n\n// Re-export for backwards compatibility\nexport { defaultRestPathFn as defaultRestPath };\n\n/**\n * Export a OperationSpecRegistry to an OpenAPI 3.1 document.\n * @deprecated Use exportContractSpec for full surface support.\n */\nexport function openApiForRegistry(\n registry: OperationSpecRegistry,\n options: OpenApiExportOptions = {}\n): ContractSpecOpenApiDocument {\n const { paths, schemas } = exportOperations(registry);\n\n return {\n openapi: '3.1.0',\n info: {\n title: options.title ?? 'ContractSpec API',\n version: options.version ?? '0.0.0',\n ...(options.description ? { description: options.description } : {}),\n },\n ...(options.servers ? { servers: options.servers } : {}),\n paths,\n components: { schemas },\n };\n}\n\n/**\n * Export all ContractSpec surfaces to OpenAPI document with extensions.\n */\nexport function exportContractSpec(\n registries: ContractSpecRegistries,\n options: ContractSpecExportOptions = {}\n): ContractSpecExportResult {\n const {\n operations: includeOps = true,\n events: includeEvents = true,\n features: includeFeatures = true,\n presentations: includePresentations = true,\n forms: includeForms = true,\n dataViews: includeDataViews = true,\n workflows: includeWorkflows = true,\n generateRegistries = true,\n } = options;\n\n // Build OpenAPI document\n let paths: Record<string, Record<string, unknown>> = {};\n let schemas: Record<string, Record<string, unknown>> = {};\n\n // Export operations\n if (includeOps && registries.operations) {\n const opResult = exportOperations(registries.operations);\n paths = opResult.paths;\n schemas = opResult.schemas;\n }\n\n const doc: ContractSpecOpenApiDocument = {\n openapi: '3.1.0',\n info: {\n title: options.title ?? 'ContractSpec API',\n version: options.version ?? '0.0.0',\n ...(options.description ? { description: options.description } : {}),\n },\n ...(options.servers ? { servers: options.servers } : {}),\n paths,\n components: { schemas },\n };\n\n // Add extensions for other surfaces\n if (includeEvents && registries.events?.length) {\n doc['x-contractspec-events'] = exportEvents(registries.events);\n }\n\n if (includeFeatures && registries.features) {\n doc['x-contractspec-features'] = exportFeatures(registries.features);\n }\n\n if (includePresentations && registries.presentations) {\n doc['x-contractspec-presentations'] = exportPresentations(\n registries.presentations\n );\n }\n\n if (includeForms && registries.forms) {\n doc['x-contractspec-forms'] = exportForms(registries.forms);\n }\n\n if (includeDataViews && registries.dataViews) {\n doc['x-contractspec-dataviews'] = exportDataViews(registries.dataViews);\n }\n\n if (includeWorkflows && registries.workflows) {\n doc['x-contractspec-workflows'] = exportWorkflows(registries.workflows);\n }\n\n const result: ContractSpecExportResult = {\n openApi: doc,\n };\n\n // Generate registry code if requested\n if (generateRegistries) {\n result.registries = {};\n\n if (includeOps && registries.operations) {\n result.registries.operations = generateOperationsRegistry(\n registries.operations\n );\n }\n\n if (includeEvents && registries.events?.length) {\n result.registries.events = generateEventsExports(registries.events);\n }\n\n if (includeFeatures && registries.features) {\n result.registries.features = generateFeaturesRegistry(\n registries.features\n );\n }\n\n if (includePresentations && registries.presentations) {\n result.registries.presentations = generatePresentationsRegistry(\n registries.presentations\n );\n }\n\n if (includeForms && registries.forms) {\n result.registries.forms = generateFormsRegistry(registries.forms);\n }\n\n if (includeDataViews && registries.dataViews) {\n result.registries.dataViews = generateDataViewsRegistry(\n registries.dataViews\n );\n }\n\n if (includeWorkflows && registries.workflows) {\n result.registries.workflows = generateWorkflowsRegistry(\n registries.workflows\n );\n }\n\n // Generate index file\n result.registries.index = generateRegistryIndex({\n operations: includeOps && !!registries.operations,\n events: includeEvents && !!registries.events?.length,\n features: includeFeatures && !!registries.features,\n presentations: includePresentations && !!registries.presentations,\n forms: includeForms && !!registries.forms,\n dataViews: includeDataViews && !!registries.dataViews,\n workflows: includeWorkflows && !!registries.workflows,\n });\n }\n\n return result;\n}\n\n/**\n * Export a OperationSpecRegistry to OpenAPI JSON string.\n */\nexport function openApiToJson(\n registry: OperationSpecRegistry,\n options: OpenApiExportOptions = {}\n): string {\n const doc = openApiForRegistry(registry, options);\n return JSON.stringify(doc, null, 2);\n}\n\n/**\n * Export a OperationSpecRegistry to OpenAPI YAML string.\n */\nexport function openApiToYaml(\n registry: OperationSpecRegistry,\n options: OpenApiExportOptions = {}\n): string {\n const doc = openApiForRegistry(registry, options);\n return jsonToYaml(doc);\n}\n\n/**\n * Export ContractSpec to JSON string (all surfaces).\n */\nexport function contractSpecToJson(\n registries: ContractSpecRegistries,\n options: ContractSpecExportOptions = {}\n): string {\n const result = exportContractSpec(registries, options);\n return JSON.stringify(result.openApi, null, 2);\n}\n\n/**\n * Export ContractSpec to YAML string (all surfaces).\n */\nexport function contractSpecToYaml(\n registries: ContractSpecRegistries,\n options: ContractSpecExportOptions = {}\n): string {\n const result = exportContractSpec(registries, options);\n return jsonToYaml(result.openApi);\n}\n\n/**\n * Simple JSON to YAML conversion.\n */\nfunction jsonToYaml(obj: unknown, indent = 0): string {\n const spaces = ' '.repeat(indent);\n let yaml = '';\n\n if (Array.isArray(obj)) {\n for (const item of obj) {\n if (typeof item === 'object' && item !== null) {\n yaml += `${spaces}-\\n${jsonToYaml(item, indent + 1)}`;\n } else {\n yaml += `${spaces}- ${JSON.stringify(item)}\\n`;\n }\n }\n } else if (typeof obj === 'object' && obj !== null) {\n for (const [key, value] of Object.entries(obj)) {\n if (Array.isArray(value)) {\n yaml += `${spaces}${key}:\\n${jsonToYaml(value, indent + 1)}`;\n } else if (typeof value === 'object' && value !== null) {\n yaml += `${spaces}${key}:\\n${jsonToYaml(value, indent + 1)}`;\n } else {\n yaml += `${spaces}${key}: ${JSON.stringify(value)}\\n`;\n }\n }\n }\n\n return yaml;\n}\n"],"mappings":"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"}
@@ -1,28 +0,0 @@
1
- //#region src/openapi/importer/analyzer.ts
2
- /**
3
- * HTTP methods that typically indicate a command (state-changing).
4
- */
5
- const COMMAND_METHODS = [
6
- "post",
7
- "put",
8
- "delete",
9
- "patch"
10
- ];
11
- /**
12
- * Determine if an operation is a command or query based on HTTP method.
13
- */
14
- function inferOpKind(method) {
15
- return COMMAND_METHODS.includes(method.toLowerCase()) ? "command" : "query";
16
- }
17
- /**
18
- * Determine auth level based on security requirements.
19
- */
20
- function inferAuthLevel(operation, defaultAuth) {
21
- if (!operation.security || operation.security.length === 0) return defaultAuth;
22
- for (const sec of operation.security) if (Object.keys(sec).length === 0) return "anonymous";
23
- return "user";
24
- }
25
-
26
- //#endregion
27
- export { COMMAND_METHODS, inferAuthLevel, inferOpKind };
28
- //# sourceMappingURL=analyzer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"analyzer.js","names":[],"sources":["../../../src/openapi/importer/analyzer.ts"],"sourcesContent":["import type { ParsedOperation } from '../types';\n\n/**\n * HTTP methods that typically indicate a command (state-changing).\n */\nexport const COMMAND_METHODS = ['post', 'put', 'delete', 'patch'];\n\n/**\n * Determine if an operation is a command or query based on HTTP method.\n */\nexport function inferOpKind(method: string): 'command' | 'query' {\n return COMMAND_METHODS.includes(method.toLowerCase()) ? 'command' : 'query';\n}\n\n/**\n * Determine auth level based on security requirements.\n */\nexport function inferAuthLevel(\n operation: ParsedOperation,\n defaultAuth: 'anonymous' | 'user' | 'admin'\n): 'anonymous' | 'user' | 'admin' {\n if (!operation.security || operation.security.length === 0) {\n // Check if any security scheme is present\n return defaultAuth;\n }\n\n // If there's an empty security requirement, it's anonymous\n for (const sec of operation.security) {\n if (Object.keys(sec).length === 0) {\n return 'anonymous';\n }\n }\n\n return 'user';\n}\n"],"mappings":";;;;AAKA,MAAa,kBAAkB;CAAC;CAAQ;CAAO;CAAU;CAAQ;;;;AAKjE,SAAgB,YAAY,QAAqC;AAC/D,QAAO,gBAAgB,SAAS,OAAO,aAAa,CAAC,GAAG,YAAY;;;;;AAMtE,SAAgB,eACd,WACA,aACgC;AAChC,KAAI,CAAC,UAAU,YAAY,UAAU,SAAS,WAAW,EAEvD,QAAO;AAIT,MAAK,MAAM,OAAO,UAAU,SAC1B,KAAI,OAAO,KAAK,IAAI,CAAC,WAAW,EAC9B,QAAO;AAIX,QAAO"}
@@ -1,40 +0,0 @@
1
- import { toPascalCase, toValidIdentifier } from "../../common/utils.js";
2
- import { generateImports, generateSchemaModelCode } from "../schema-converter.js";
3
-
4
- //#region src/openapi/importer/events.ts
5
- /**
6
- * Generate code for an event.
7
- */
8
- function generateEventCode(event, options) {
9
- const eventName = toValidIdentifier(event.name);
10
- const modelName = toPascalCase(eventName) + "Payload";
11
- const schemaFormat = options.schemaFormat || "contractspec";
12
- const payloadModel = generateSchemaModelCode(event.payload, modelName, schemaFormat, options);
13
- const imports = /* @__PURE__ */ new Set();
14
- imports.add("import { defineEvent, type EventSpec } from '@contractspec/lib.contracts';");
15
- if (payloadModel.imports && payloadModel.imports.length > 0) payloadModel.imports.forEach((i) => imports.add(i));
16
- else if (payloadModel.fields && payloadModel.fields.length > 0) generateImports(payloadModel.fields, options).split("\n").filter(Boolean).forEach((i) => imports.add(i));
17
- if (payloadModel.name !== modelName) {
18
- const modelsDir = `../${options.conventions.models}`;
19
- const kebabName = payloadModel.name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
20
- imports.add(`import { ${payloadModel.name} } from '${modelsDir}/${kebabName}';`);
21
- }
22
- return `
23
- ${Array.from(imports).join("\n")}
24
-
25
- ${payloadModel.code}
26
-
27
- export const ${eventName} = defineEvent({
28
- meta: {
29
- key: '${event.name}',
30
- version: '1.0.0',
31
- description: ${JSON.stringify(event.description ?? "")},
32
- },
33
- payload: ${payloadModel.name},
34
- });
35
- `.trim();
36
- }
37
-
38
- //#endregion
39
- export { generateEventCode };
40
- //# sourceMappingURL=events.js.map
@@ -1 +0,0 @@
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 { ResolvedContractsrcConfig } from '@contractspec/lib.contracts';\n\n/**\n * Generate code for an event.\n */\nexport function generateEventCode(\n event: ParsedEvent,\n options: ResolvedContractsrcConfig\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"}