@contractspec/lib.source-extractors 0.10.1 → 0.12.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 (86) hide show
  1. package/dist/browser/codegen/index.js +225 -0
  2. package/dist/browser/extractors/index.js +835 -0
  3. package/dist/browser/index.js +1215 -0
  4. package/dist/browser/types.js +0 -0
  5. package/dist/codegen/index.d.ts +9 -11
  6. package/dist/codegen/index.d.ts.map +1 -1
  7. package/dist/codegen/index.js +223 -14
  8. package/dist/codegen/operation-gen.d.ts +9 -9
  9. package/dist/codegen/operation-gen.d.ts.map +1 -1
  10. package/dist/codegen/registry-gen.d.ts +7 -7
  11. package/dist/codegen/registry-gen.d.ts.map +1 -1
  12. package/dist/codegen/schema-gen.d.ts +9 -9
  13. package/dist/codegen/schema-gen.d.ts.map +1 -1
  14. package/dist/codegen/types.d.ts +29 -32
  15. package/dist/codegen/types.d.ts.map +1 -1
  16. package/dist/detect.d.ts +19 -18
  17. package/dist/detect.d.ts.map +1 -1
  18. package/dist/extract.d.ts +10 -9
  19. package/dist/extract.d.ts.map +1 -1
  20. package/dist/extractors/base.d.ts +76 -76
  21. package/dist/extractors/base.d.ts.map +1 -1
  22. package/dist/extractors/elysia/extractor.d.ts +15 -13
  23. package/dist/extractors/elysia/extractor.d.ts.map +1 -1
  24. package/dist/extractors/express/extractor.d.ts +16 -13
  25. package/dist/extractors/express/extractor.d.ts.map +1 -1
  26. package/dist/extractors/fastify/extractor.d.ts +16 -13
  27. package/dist/extractors/fastify/extractor.d.ts.map +1 -1
  28. package/dist/extractors/hono/extractor.d.ts +15 -13
  29. package/dist/extractors/hono/extractor.d.ts.map +1 -1
  30. package/dist/extractors/index.d.ts +16 -17
  31. package/dist/extractors/index.d.ts.map +1 -1
  32. package/dist/extractors/index.js +834 -40
  33. package/dist/extractors/nestjs/extractor.d.ts +28 -24
  34. package/dist/extractors/nestjs/extractor.d.ts.map +1 -1
  35. package/dist/extractors/next-api/extractor.d.ts +16 -14
  36. package/dist/extractors/next-api/extractor.d.ts.map +1 -1
  37. package/dist/extractors/trpc/extractor.d.ts +16 -13
  38. package/dist/extractors/trpc/extractor.d.ts.map +1 -1
  39. package/dist/extractors/zod/extractor.d.ts +15 -14
  40. package/dist/extractors/zod/extractor.d.ts.map +1 -1
  41. package/dist/index.d.ts +30 -7
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +1215 -6
  44. package/dist/node/codegen/index.js +225 -0
  45. package/dist/node/extractors/index.js +835 -0
  46. package/dist/node/index.js +1215 -0
  47. package/dist/node/types.js +0 -0
  48. package/dist/registry.d.ts +69 -69
  49. package/dist/registry.d.ts.map +1 -1
  50. package/dist/types.d.ts +182 -185
  51. package/dist/types.d.ts.map +1 -1
  52. package/dist/types.js +1 -0
  53. package/package.json +60 -21
  54. package/dist/_virtual/rolldown_runtime.js +0 -18
  55. package/dist/codegen/index.js.map +0 -1
  56. package/dist/codegen/operation-gen.js +0 -91
  57. package/dist/codegen/operation-gen.js.map +0 -1
  58. package/dist/codegen/registry-gen.js +0 -47
  59. package/dist/codegen/registry-gen.js.map +0 -1
  60. package/dist/codegen/schema-gen.js +0 -93
  61. package/dist/codegen/schema-gen.js.map +0 -1
  62. package/dist/detect.js +0 -177
  63. package/dist/detect.js.map +0 -1
  64. package/dist/extract.js +0 -125
  65. package/dist/extract.js.map +0 -1
  66. package/dist/extractors/base.js +0 -152
  67. package/dist/extractors/base.js.map +0 -1
  68. package/dist/extractors/elysia/extractor.js +0 -58
  69. package/dist/extractors/elysia/extractor.js.map +0 -1
  70. package/dist/extractors/express/extractor.js +0 -61
  71. package/dist/extractors/express/extractor.js.map +0 -1
  72. package/dist/extractors/fastify/extractor.js +0 -61
  73. package/dist/extractors/fastify/extractor.js.map +0 -1
  74. package/dist/extractors/hono/extractor.js +0 -57
  75. package/dist/extractors/hono/extractor.js.map +0 -1
  76. package/dist/extractors/index.js.map +0 -1
  77. package/dist/extractors/nestjs/extractor.js +0 -118
  78. package/dist/extractors/nestjs/extractor.js.map +0 -1
  79. package/dist/extractors/next-api/extractor.js +0 -80
  80. package/dist/extractors/next-api/extractor.js.map +0 -1
  81. package/dist/extractors/trpc/extractor.js +0 -71
  82. package/dist/extractors/trpc/extractor.js.map +0 -1
  83. package/dist/extractors/zod/extractor.js +0 -69
  84. package/dist/extractors/zod/extractor.js.map +0 -1
  85. package/dist/registry.js +0 -87
  86. package/dist/registry.js.map +0 -1
@@ -0,0 +1,225 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, {
5
+ get: all[name],
6
+ enumerable: true,
7
+ configurable: true,
8
+ set: (newValue) => all[name] = () => newValue
9
+ });
10
+ };
11
+
12
+ // src/codegen/index.ts
13
+ var exports_codegen = {};
14
+ __export(exports_codegen, {
15
+ generateSchemas: () => generateSchemas,
16
+ generateSchema: () => generateSchema,
17
+ generateRegistry: () => generateRegistry,
18
+ generateOperations: () => generateOperations,
19
+ generateOperation: () => generateOperation
20
+ });
21
+
22
+ // src/codegen/operation-gen.ts
23
+ function generateOperation(endpoint, options) {
24
+ const specName = toSpecName(endpoint);
25
+ const fileName = `${toFileName(endpoint)}.ts`;
26
+ const code = generateOperationCode(endpoint, specName, options);
27
+ return {
28
+ path: fileName,
29
+ content: code,
30
+ type: "operation"
31
+ };
32
+ }
33
+ function generateOperations(ir, options) {
34
+ return ir.endpoints.map((endpoint) => generateOperation(endpoint, options));
35
+ }
36
+ function toSpecName(endpoint) {
37
+ const parts = endpoint.path.replace(/^\//, "").split("/").filter((p) => p && !p.startsWith(":") && !p.startsWith("{"));
38
+ const methodPart = endpoint.method.toLowerCase();
39
+ const pathPart = parts.map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join("");
40
+ return `${methodPart}${pathPart}Spec`;
41
+ }
42
+ function toFileName(endpoint) {
43
+ const parts = endpoint.path.replace(/^\//, "").split("/").filter((p) => p && !p.startsWith(":") && !p.startsWith("{"));
44
+ const methodPart = endpoint.method.toLowerCase();
45
+ const pathPart = parts.join("-");
46
+ return `${methodPart}-${pathPart}`.replace(/--+/g, "-");
47
+ }
48
+ function generateOperationCode(endpoint, specName, options) {
49
+ const isCommand = endpoint.kind === "command";
50
+ const defineFunc = isCommand ? "defineCommand" : "defineQuery";
51
+ const auth = options.defaultAuth ?? "user";
52
+ const owners = options.defaultOwners ?? ["team"];
53
+ const lines = [
54
+ `/**`,
55
+ ` * ${endpoint.method} ${endpoint.path}`,
56
+ ` *`,
57
+ ` * Generated from: ${endpoint.source.file}:${endpoint.source.startLine}`,
58
+ ` * Confidence: ${endpoint.confidence.level}`,
59
+ ` */`,
60
+ ``,
61
+ `import { ${defineFunc} } from '@contractspec/lib.contracts';`,
62
+ `import { fromZod } from '@contractspec/lib.schema';`,
63
+ `import { z } from 'zod';`,
64
+ ``,
65
+ `// TODO: Define input schema based on extracted information`,
66
+ `const inputSchema = fromZod(z.object({`,
67
+ ` // Add fields here`,
68
+ `}));`,
69
+ ``,
70
+ `// TODO: Define output schema`,
71
+ `const outputSchema = fromZod(z.object({`,
72
+ ` // Add fields here`,
73
+ `}));`,
74
+ ``,
75
+ `export const ${specName} = ${defineFunc}({`,
76
+ ` meta: {`,
77
+ ` name: '${endpoint.handlerName ?? endpoint.id}',`,
78
+ ` version: 1,`,
79
+ ` stability: 'experimental',`,
80
+ ` owners: ${JSON.stringify(owners)},`,
81
+ ` goal: 'TODO: Describe the business goal',`,
82
+ ` context: 'Generated from ${endpoint.source.file}',`,
83
+ ` },`,
84
+ ` io: {`,
85
+ ` input: inputSchema,`,
86
+ ` output: outputSchema,`,
87
+ ` },`,
88
+ ` policy: {`,
89
+ ` auth: '${auth}',`,
90
+ ` },`,
91
+ ` transport: {`,
92
+ ` rest: {`,
93
+ ` method: '${endpoint.method}',`,
94
+ ` path: '${endpoint.path}',`,
95
+ ` },`,
96
+ ` },`,
97
+ `});`,
98
+ ``
99
+ ];
100
+ return lines.join(`
101
+ `);
102
+ }
103
+ // src/codegen/schema-gen.ts
104
+ function generateSchema(schema, _options) {
105
+ const fileName = `${toFileName2(schema.name)}.ts`;
106
+ const code = generateSchemaCode(schema);
107
+ return {
108
+ path: `schemas/${fileName}`,
109
+ content: code,
110
+ type: "schema"
111
+ };
112
+ }
113
+ function generateSchemas(ir, options) {
114
+ return ir.schemas.map((schema) => generateSchema(schema, options));
115
+ }
116
+ function toFileName2(name) {
117
+ return name.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
118
+ }
119
+ function generateSchemaCode(schema) {
120
+ const lines = [
121
+ `/**`,
122
+ ` * ${schema.name}`,
123
+ ` *`,
124
+ ` * Generated from: ${schema.source.file}:${schema.source.startLine}`,
125
+ ` * Schema type: ${schema.schemaType}`,
126
+ ` * Confidence: ${schema.confidence.level}`,
127
+ ` */`,
128
+ ``,
129
+ `import { fromZod } from '@contractspec/lib.schema';`,
130
+ `import { z } from 'zod';`,
131
+ ``
132
+ ];
133
+ if (schema.rawDefinition && schema.schemaType === "zod") {
134
+ lines.push(`// Original definition from source:`);
135
+ lines.push(`// ${schema.rawDefinition.split(`
136
+ `)[0]}`);
137
+ lines.push(``);
138
+ }
139
+ lines.push(`export const ${schema.name}Schema = fromZod(z.object({`);
140
+ if (schema.fields && schema.fields.length > 0) {
141
+ for (const field of schema.fields) {
142
+ const zodType = mapToZodType(field.type, field.optional);
143
+ lines.push(` ${field.name}: ${zodType},`);
144
+ }
145
+ } else {
146
+ lines.push(` // TODO: Define schema fields`);
147
+ }
148
+ lines.push(`}));`);
149
+ lines.push(``);
150
+ lines.push(`export type ${schema.name} = z.infer<typeof ${schema.name}Schema.zodSchema>;`);
151
+ lines.push(``);
152
+ return lines.join(`
153
+ `);
154
+ }
155
+ function mapToZodType(tsType, optional) {
156
+ let zodType;
157
+ switch (tsType.toLowerCase()) {
158
+ case "string":
159
+ zodType = "z.string()";
160
+ break;
161
+ case "number":
162
+ zodType = "z.number()";
163
+ break;
164
+ case "boolean":
165
+ zodType = "z.boolean()";
166
+ break;
167
+ case "date":
168
+ zodType = "z.date()";
169
+ break;
170
+ case "string[]":
171
+ case "array<string>":
172
+ zodType = "z.array(z.string())";
173
+ break;
174
+ case "number[]":
175
+ case "array<number>":
176
+ zodType = "z.array(z.number())";
177
+ break;
178
+ default:
179
+ zodType = "z.unknown()";
180
+ }
181
+ return optional ? `${zodType}.optional()` : zodType;
182
+ }
183
+ // src/codegen/registry-gen.ts
184
+ function generateRegistry(operationFiles) {
185
+ const operationImports = operationFiles.filter((f) => f.type === "operation").map((f) => {
186
+ const name = f.path.replace(".ts", "").replace(/-/g, "_");
187
+ const specName = toPascalCase(name) + "Spec";
188
+ return { path: f.path, name, specName };
189
+ });
190
+ const lines = [
191
+ `/**`,
192
+ ` * Generated operation registry.`,
193
+ ` */`,
194
+ ``,
195
+ `import { OperationSpecRegistry } from '@contractspec/lib.contracts';`,
196
+ ``
197
+ ];
198
+ for (const op of operationImports) {
199
+ const importPath = `./${op.path.replace(".ts", "")}`;
200
+ lines.push(`import { ${op.specName} } from '${importPath}';`);
201
+ }
202
+ lines.push(``);
203
+ lines.push(`export const operationRegistry = new OperationSpecRegistry();`);
204
+ lines.push(``);
205
+ for (const op of operationImports) {
206
+ lines.push(`operationRegistry.register(${op.specName});`);
207
+ }
208
+ lines.push(``);
209
+ return {
210
+ path: "registry.ts",
211
+ content: lines.join(`
212
+ `),
213
+ type: "registry"
214
+ };
215
+ }
216
+ function toPascalCase(str) {
217
+ return str.split(/[-_]/).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
218
+ }
219
+ export {
220
+ generateSchemas,
221
+ generateSchema,
222
+ generateRegistry,
223
+ generateOperations,
224
+ generateOperation
225
+ };