@contractspec/lib.source-extractors 0.0.0-canary-20260119222405
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -0
- package/dist/_virtual/rolldown_runtime.js +18 -0
- package/dist/codegen/index.d.ts +12 -0
- package/dist/codegen/index.d.ts.map +1 -0
- package/dist/codegen/index.js +17 -0
- package/dist/codegen/index.js.map +1 -0
- package/dist/codegen/operation-gen.d.ts +16 -0
- package/dist/codegen/operation-gen.d.ts.map +1 -0
- package/dist/codegen/operation-gen.js +91 -0
- package/dist/codegen/operation-gen.js.map +1 -0
- package/dist/codegen/registry-gen.d.ts +11 -0
- package/dist/codegen/registry-gen.d.ts.map +1 -0
- package/dist/codegen/registry-gen.js +47 -0
- package/dist/codegen/registry-gen.js.map +1 -0
- package/dist/codegen/schema-gen.d.ts +16 -0
- package/dist/codegen/schema-gen.d.ts.map +1 -0
- package/dist/codegen/schema-gen.js +93 -0
- package/dist/codegen/schema-gen.js.map +1 -0
- package/dist/codegen/types.d.ts +48 -0
- package/dist/codegen/types.d.ts.map +1 -0
- package/dist/detect.d.ts +47 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/detect.js +177 -0
- package/dist/detect.js.map +1 -0
- package/dist/extract.d.ts +24 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +125 -0
- package/dist/extract.js.map +1 -0
- package/dist/extractors/base.d.ts +90 -0
- package/dist/extractors/base.d.ts.map +1 -0
- package/dist/extractors/base.js +152 -0
- package/dist/extractors/base.js.map +1 -0
- package/dist/extractors/elysia/extractor.d.ts +15 -0
- package/dist/extractors/elysia/extractor.d.ts.map +1 -0
- package/dist/extractors/elysia/extractor.js +58 -0
- package/dist/extractors/elysia/extractor.js.map +1 -0
- package/dist/extractors/express/extractor.d.ts +15 -0
- package/dist/extractors/express/extractor.d.ts.map +1 -0
- package/dist/extractors/express/extractor.js +61 -0
- package/dist/extractors/express/extractor.js.map +1 -0
- package/dist/extractors/fastify/extractor.d.ts +15 -0
- package/dist/extractors/fastify/extractor.d.ts.map +1 -0
- package/dist/extractors/fastify/extractor.js +61 -0
- package/dist/extractors/fastify/extractor.js.map +1 -0
- package/dist/extractors/hono/extractor.d.ts +15 -0
- package/dist/extractors/hono/extractor.d.ts.map +1 -0
- package/dist/extractors/hono/extractor.js +57 -0
- package/dist/extractors/hono/extractor.js.map +1 -0
- package/dist/extractors/index.d.ts +21 -0
- package/dist/extractors/index.d.ts.map +1 -0
- package/dist/extractors/index.js +42 -0
- package/dist/extractors/index.js.map +1 -0
- package/dist/extractors/nestjs/extractor.d.ts +29 -0
- package/dist/extractors/nestjs/extractor.d.ts.map +1 -0
- package/dist/extractors/nestjs/extractor.js +118 -0
- package/dist/extractors/nestjs/extractor.js.map +1 -0
- package/dist/extractors/next-api/extractor.d.ts +16 -0
- package/dist/extractors/next-api/extractor.d.ts.map +1 -0
- package/dist/extractors/next-api/extractor.js +80 -0
- package/dist/extractors/next-api/extractor.js.map +1 -0
- package/dist/extractors/trpc/extractor.d.ts +15 -0
- package/dist/extractors/trpc/extractor.d.ts.map +1 -0
- package/dist/extractors/trpc/extractor.js +71 -0
- package/dist/extractors/trpc/extractor.js.map +1 -0
- package/dist/extractors/zod/extractor.d.ts +16 -0
- package/dist/extractors/zod/extractor.d.ts.map +1 -0
- package/dist/extractors/zod/extractor.js +69 -0
- package/dist/extractors/zod/extractor.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/registry.d.ts +85 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +87 -0
- package/dist/registry.js.map +1 -0
- package/dist/types.d.ts +272 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +0 -0
- package/package.json +71 -0
package/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# @contractspec/lib.source-extractors
|
|
2
|
+
|
|
3
|
+
Extract contract candidates from TypeScript source code across multiple frameworks.
|
|
4
|
+
|
|
5
|
+
## Supported Frameworks
|
|
6
|
+
|
|
7
|
+
| Framework | Detection | Routes | Schemas | Status |
|
|
8
|
+
|-----------|-----------|--------|---------|--------|
|
|
9
|
+
| NestJS | ✅ | ✅ | ✅ | Ready |
|
|
10
|
+
| Express | ✅ | ✅ | ✅ | Ready |
|
|
11
|
+
| Fastify | ✅ | ✅ | ✅ | Ready |
|
|
12
|
+
| Hono | ✅ | ✅ | ✅ | Ready |
|
|
13
|
+
| Elysia | ✅ | ✅ | ✅ | Ready |
|
|
14
|
+
| tRPC | ✅ | ✅ | ✅ | Ready |
|
|
15
|
+
| Next.js API | ✅ | ✅ | ✅ | Ready |
|
|
16
|
+
| Zod Schemas | ✅ | N/A | ✅ | Ready |
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bun add @contractspec/lib.source-extractors
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { detectFramework, extractFromProject } from '@contractspec/lib.source-extractors';
|
|
28
|
+
import { registerAllExtractors } from '@contractspec/lib.source-extractors/extractors';
|
|
29
|
+
import { generateOperations } from '@contractspec/lib.source-extractors/codegen';
|
|
30
|
+
|
|
31
|
+
// Register all built-in extractors
|
|
32
|
+
registerAllExtractors();
|
|
33
|
+
|
|
34
|
+
// Detect frameworks in a project
|
|
35
|
+
const project = await detectFramework('./my-project', {
|
|
36
|
+
readFile: (path) => fs.readFile(path, 'utf-8'),
|
|
37
|
+
glob: (pattern) => glob(pattern),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Extract contract candidates
|
|
41
|
+
const result = await extractFromProject(project, {
|
|
42
|
+
scope: ['src/controllers'], // Optional: limit scope
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
if (result.success && result.ir) {
|
|
46
|
+
console.log(`Found ${result.ir.endpoints.length} endpoints`);
|
|
47
|
+
console.log(`Found ${result.ir.schemas.length} schemas`);
|
|
48
|
+
|
|
49
|
+
// Generate ContractSpec code
|
|
50
|
+
const files = generateOperations(result.ir, {
|
|
51
|
+
outputDir: './generated',
|
|
52
|
+
defaultAuth: 'user',
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## IR Schema
|
|
58
|
+
|
|
59
|
+
The Intermediate Representation (IR) provides a framework-agnostic view of extracted contracts:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
interface ImportIR {
|
|
63
|
+
version: '1.0';
|
|
64
|
+
extractedAt: string;
|
|
65
|
+
project: ProjectInfo;
|
|
66
|
+
endpoints: EndpointCandidate[];
|
|
67
|
+
schemas: SchemaCandidate[];
|
|
68
|
+
errors: ErrorCandidate[];
|
|
69
|
+
events: EventCandidate[];
|
|
70
|
+
ambiguities: Ambiguity[];
|
|
71
|
+
stats: { ... };
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Confidence Levels
|
|
76
|
+
|
|
77
|
+
Each extracted item has a confidence score:
|
|
78
|
+
|
|
79
|
+
- **high**: Explicit schema found (Zod, class-validator, JSON Schema)
|
|
80
|
+
- **medium**: TypeScript types or framework decorators present
|
|
81
|
+
- **low**: Inferred from naming conventions or partial information
|
|
82
|
+
- **ambiguous**: Requires manual review
|
|
83
|
+
|
|
84
|
+
## License
|
|
85
|
+
|
|
86
|
+
MIT
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) {
|
|
6
|
+
__defProp(target, name, {
|
|
7
|
+
get: all[name],
|
|
8
|
+
enumerable: true
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
if (symbols) {
|
|
12
|
+
__defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
13
|
+
}
|
|
14
|
+
return target;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { __exportAll };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { GeneratedFile, GenerationOptions, GenerationResult } from "./types.js";
|
|
2
|
+
import { generateOperation, generateOperations } from "./operation-gen.js";
|
|
3
|
+
import { generateSchema, generateSchemas } from "./schema-gen.js";
|
|
4
|
+
import { generateRegistry } from "./registry-gen.js";
|
|
5
|
+
|
|
6
|
+
//#region src/codegen/index.d.ts
|
|
7
|
+
declare namespace index_d_exports {
|
|
8
|
+
export { GeneratedFile, GenerationOptions, GenerationResult, generateOperation, generateOperations, generateRegistry, generateSchema, generateSchemas };
|
|
9
|
+
}
|
|
10
|
+
//#endregion
|
|
11
|
+
export { type GeneratedFile, type GenerationOptions, type GenerationResult, generateOperation, generateOperations, generateRegistry, generateSchema, generateSchemas, index_d_exports };
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/codegen/index.ts"],"sourcesContent":[],"mappings":""}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { __exportAll } from "../_virtual/rolldown_runtime.js";
|
|
2
|
+
import { generateOperation, generateOperations } from "./operation-gen.js";
|
|
3
|
+
import { generateSchema, generateSchemas } from "./schema-gen.js";
|
|
4
|
+
import { generateRegistry } from "./registry-gen.js";
|
|
5
|
+
|
|
6
|
+
//#region src/codegen/index.ts
|
|
7
|
+
var codegen_exports = /* @__PURE__ */ __exportAll({
|
|
8
|
+
generateOperation: () => generateOperation,
|
|
9
|
+
generateOperations: () => generateOperations,
|
|
10
|
+
generateRegistry: () => generateRegistry,
|
|
11
|
+
generateSchema: () => generateSchema,
|
|
12
|
+
generateSchemas: () => generateSchemas
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
//#endregion
|
|
16
|
+
export { codegen_exports, generateOperation, generateOperations, generateRegistry, generateSchema, generateSchemas };
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/codegen/index.ts"],"sourcesContent":["/**\n * Code generation module.\n *\n * Generates ContractSpec definitions from the Intermediate Representation.\n */\n\n// Operation generators\nexport { generateOperation, generateOperations } from './operation-gen';\n\n// Schema generators\nexport { generateSchema, generateSchemas } from './schema-gen';\n\n// Registry generators\nexport { generateRegistry } from './registry-gen';\n\n// Types\nexport type {\n GeneratedFile,\n GenerationOptions,\n GenerationResult,\n} from './types';\n"],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { EndpointCandidate, ImportIR } from "../types.js";
|
|
2
|
+
import { GeneratedFile, GenerationOptions } from "./types.js";
|
|
3
|
+
|
|
4
|
+
//#region src/codegen/operation-gen.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Generate a single operation spec file.
|
|
8
|
+
*/
|
|
9
|
+
declare function generateOperation(endpoint: EndpointCandidate, options: GenerationOptions): GeneratedFile;
|
|
10
|
+
/**
|
|
11
|
+
* Generate all operation spec files from IR.
|
|
12
|
+
*/
|
|
13
|
+
declare function generateOperations(ir: ImportIR, options: GenerationOptions): GeneratedFile[];
|
|
14
|
+
//#endregion
|
|
15
|
+
export { generateOperation, generateOperations };
|
|
16
|
+
//# sourceMappingURL=operation-gen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation-gen.d.ts","names":[],"sources":["../../src/codegen/operation-gen.ts"],"sourcesContent":[],"mappings":";;;;;;;AA+BA;AACM,iBApBU,iBAAA,CAoBV,QAAA,EAnBM,iBAmBN,EAAA,OAAA,EAlBK,iBAkBL,CAAA,EAjBH,aAiBG;;;;iBADU,kBAAA,KACV,mBACK,oBACR"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
//#region src/codegen/operation-gen.ts
|
|
2
|
+
/**
|
|
3
|
+
* Generate a single operation spec file.
|
|
4
|
+
*/
|
|
5
|
+
function generateOperation(endpoint, options) {
|
|
6
|
+
const specName = toSpecName(endpoint);
|
|
7
|
+
return {
|
|
8
|
+
path: `${toFileName(endpoint)}.ts`,
|
|
9
|
+
content: generateOperationCode(endpoint, specName, options),
|
|
10
|
+
type: "operation"
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Generate all operation spec files from IR.
|
|
15
|
+
*/
|
|
16
|
+
function generateOperations(ir, options) {
|
|
17
|
+
return ir.endpoints.map((endpoint) => generateOperation(endpoint, options));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Convert endpoint to spec name (PascalCase).
|
|
21
|
+
*/
|
|
22
|
+
function toSpecName(endpoint) {
|
|
23
|
+
const parts = endpoint.path.replace(/^\//, "").split("/").filter((p) => p && !p.startsWith(":") && !p.startsWith("{"));
|
|
24
|
+
return `${endpoint.method.toLowerCase()}${parts.map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join("")}Spec`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Convert endpoint to file name (kebab-case).
|
|
28
|
+
*/
|
|
29
|
+
function toFileName(endpoint) {
|
|
30
|
+
const parts = endpoint.path.replace(/^\//, "").split("/").filter((p) => p && !p.startsWith(":") && !p.startsWith("{"));
|
|
31
|
+
return `${endpoint.method.toLowerCase()}-${parts.join("-")}`.replace(/--+/g, "-");
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Generate the operation spec code.
|
|
35
|
+
*/
|
|
36
|
+
function generateOperationCode(endpoint, specName, options) {
|
|
37
|
+
const defineFunc = endpoint.kind === "command" ? "defineCommand" : "defineQuery";
|
|
38
|
+
const auth = options.defaultAuth ?? "user";
|
|
39
|
+
const owners = options.defaultOwners ?? ["team"];
|
|
40
|
+
return [
|
|
41
|
+
`/**`,
|
|
42
|
+
` * ${endpoint.method} ${endpoint.path}`,
|
|
43
|
+
` *`,
|
|
44
|
+
` * Generated from: ${endpoint.source.file}:${endpoint.source.startLine}`,
|
|
45
|
+
` * Confidence: ${endpoint.confidence.level}`,
|
|
46
|
+
` */`,
|
|
47
|
+
``,
|
|
48
|
+
`import { ${defineFunc} } from '@contractspec/lib.contracts';`,
|
|
49
|
+
`import { fromZod } from '@contractspec/lib.schema';`,
|
|
50
|
+
`import { z } from 'zod';`,
|
|
51
|
+
``,
|
|
52
|
+
`// TODO: Define input schema based on extracted information`,
|
|
53
|
+
`const inputSchema = fromZod(z.object({`,
|
|
54
|
+
` // Add fields here`,
|
|
55
|
+
`}));`,
|
|
56
|
+
``,
|
|
57
|
+
`// TODO: Define output schema`,
|
|
58
|
+
`const outputSchema = fromZod(z.object({`,
|
|
59
|
+
` // Add fields here`,
|
|
60
|
+
`}));`,
|
|
61
|
+
``,
|
|
62
|
+
`export const ${specName} = ${defineFunc}({`,
|
|
63
|
+
` meta: {`,
|
|
64
|
+
` name: '${endpoint.handlerName ?? endpoint.id}',`,
|
|
65
|
+
` version: 1,`,
|
|
66
|
+
` stability: 'experimental',`,
|
|
67
|
+
` owners: ${JSON.stringify(owners)},`,
|
|
68
|
+
` goal: 'TODO: Describe the business goal',`,
|
|
69
|
+
` context: 'Generated from ${endpoint.source.file}',`,
|
|
70
|
+
` },`,
|
|
71
|
+
` io: {`,
|
|
72
|
+
` input: inputSchema,`,
|
|
73
|
+
` output: outputSchema,`,
|
|
74
|
+
` },`,
|
|
75
|
+
` policy: {`,
|
|
76
|
+
` auth: '${auth}',`,
|
|
77
|
+
` },`,
|
|
78
|
+
` transport: {`,
|
|
79
|
+
` rest: {`,
|
|
80
|
+
` method: '${endpoint.method}',`,
|
|
81
|
+
` path: '${endpoint.path}',`,
|
|
82
|
+
` },`,
|
|
83
|
+
` },`,
|
|
84
|
+
`});`,
|
|
85
|
+
``
|
|
86
|
+
].join("\n");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
//#endregion
|
|
90
|
+
export { generateOperation, generateOperations };
|
|
91
|
+
//# sourceMappingURL=operation-gen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation-gen.js","names":[],"sources":["../../src/codegen/operation-gen.ts"],"sourcesContent":["/**\n * Operation code generator.\n *\n * Generates defineCommand/defineQuery specs from endpoint candidates.\n */\n\nimport type { EndpointCandidate, ImportIR } from '../types';\nimport type { GeneratedFile, GenerationOptions } from './types';\n\n/**\n * Generate a single operation spec file.\n */\nexport function generateOperation(\n endpoint: EndpointCandidate,\n options: GenerationOptions\n): GeneratedFile {\n const specName = toSpecName(endpoint);\n const fileName = `${toFileName(endpoint)}.ts`;\n\n const code = generateOperationCode(endpoint, specName, options);\n\n return {\n path: fileName,\n content: code,\n type: 'operation',\n };\n}\n\n/**\n * Generate all operation spec files from IR.\n */\nexport function generateOperations(\n ir: ImportIR,\n options: GenerationOptions\n): GeneratedFile[] {\n return ir.endpoints.map((endpoint) => generateOperation(endpoint, options));\n}\n\n/**\n * Convert endpoint to spec name (PascalCase).\n */\nfunction toSpecName(endpoint: EndpointCandidate): string {\n const parts = endpoint.path\n .replace(/^\\//, '')\n .split('/')\n .filter((p) => p && !p.startsWith(':') && !p.startsWith('{'));\n\n const methodPart = endpoint.method.toLowerCase();\n const pathPart = parts\n .map((p) => p.charAt(0).toUpperCase() + p.slice(1))\n .join('');\n\n return `${methodPart}${pathPart}Spec`;\n}\n\n/**\n * Convert endpoint to file name (kebab-case).\n */\nfunction toFileName(endpoint: EndpointCandidate): string {\n const parts = endpoint.path\n .replace(/^\\//, '')\n .split('/')\n .filter((p) => p && !p.startsWith(':') && !p.startsWith('{'));\n\n const methodPart = endpoint.method.toLowerCase();\n const pathPart = parts.join('-');\n\n return `${methodPart}-${pathPart}`.replace(/--+/g, '-');\n}\n\n/**\n * Generate the operation spec code.\n */\nfunction generateOperationCode(\n endpoint: EndpointCandidate,\n specName: string,\n options: GenerationOptions\n): string {\n const isCommand = endpoint.kind === 'command';\n const defineFunc = isCommand ? 'defineCommand' : 'defineQuery';\n const auth = options.defaultAuth ?? 'user';\n const owners = options.defaultOwners ?? ['team'];\n\n const lines = [\n `/**`,\n ` * ${endpoint.method} ${endpoint.path}`,\n ` *`,\n ` * Generated from: ${endpoint.source.file}:${endpoint.source.startLine}`,\n ` * Confidence: ${endpoint.confidence.level}`,\n ` */`,\n ``,\n `import { ${defineFunc} } from '@contractspec/lib.contracts';`,\n `import { fromZod } from '@contractspec/lib.schema';`,\n `import { z } from 'zod';`,\n ``,\n `// TODO: Define input schema based on extracted information`,\n `const inputSchema = fromZod(z.object({`,\n ` // Add fields here`,\n `}));`,\n ``,\n `// TODO: Define output schema`,\n `const outputSchema = fromZod(z.object({`,\n ` // Add fields here`,\n `}));`,\n ``,\n `export const ${specName} = ${defineFunc}({`,\n ` meta: {`,\n ` name: '${endpoint.handlerName ?? endpoint.id}',`,\n ` version: 1,`,\n ` stability: 'experimental',`,\n ` owners: ${JSON.stringify(owners)},`,\n ` goal: 'TODO: Describe the business goal',`,\n ` context: 'Generated from ${endpoint.source.file}',`,\n ` },`,\n ` io: {`,\n ` input: inputSchema,`,\n ` output: outputSchema,`,\n ` },`,\n ` policy: {`,\n ` auth: '${auth}',`,\n ` },`,\n ` transport: {`,\n ` rest: {`,\n ` method: '${endpoint.method}',`,\n ` path: '${endpoint.path}',`,\n ` },`,\n ` },`,\n `});`,\n ``,\n ];\n\n return lines.join('\\n');\n}\n"],"mappings":";;;;AAYA,SAAgB,kBACd,UACA,SACe;CACf,MAAM,WAAW,WAAW,SAAS;AAKrC,QAAO;EACL,MALe,GAAG,WAAW,SAAS,CAAC;EAMvC,SAJW,sBAAsB,UAAU,UAAU,QAAQ;EAK7D,MAAM;EACP;;;;;AAMH,SAAgB,mBACd,IACA,SACiB;AACjB,QAAO,GAAG,UAAU,KAAK,aAAa,kBAAkB,UAAU,QAAQ,CAAC;;;;;AAM7E,SAAS,WAAW,UAAqC;CACvD,MAAM,QAAQ,SAAS,KACpB,QAAQ,OAAO,GAAG,CAClB,MAAM,IAAI,CACV,QAAQ,MAAM,KAAK,CAAC,EAAE,WAAW,IAAI,IAAI,CAAC,EAAE,WAAW,IAAI,CAAC;AAO/D,QAAO,GALY,SAAS,OAAO,aAAa,GAC/B,MACd,KAAK,MAAM,EAAE,OAAO,EAAE,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE,CAAC,CAClD,KAAK,GAAG,CAEqB;;;;;AAMlC,SAAS,WAAW,UAAqC;CACvD,MAAM,QAAQ,SAAS,KACpB,QAAQ,OAAO,GAAG,CAClB,MAAM,IAAI,CACV,QAAQ,MAAM,KAAK,CAAC,EAAE,WAAW,IAAI,IAAI,CAAC,EAAE,WAAW,IAAI,CAAC;AAK/D,QAAO,GAHY,SAAS,OAAO,aAAa,CAG3B,GAFJ,MAAM,KAAK,IAAI,GAEG,QAAQ,QAAQ,IAAI;;;;;AAMzD,SAAS,sBACP,UACA,UACA,SACQ;CAER,MAAM,aADY,SAAS,SAAS,YACL,kBAAkB;CACjD,MAAM,OAAO,QAAQ,eAAe;CACpC,MAAM,SAAS,QAAQ,iBAAiB,CAAC,OAAO;AAkDhD,QAhDc;EACZ;EACA,MAAM,SAAS,OAAO,GAAG,SAAS;EAClC;EACA,sBAAsB,SAAS,OAAO,KAAK,GAAG,SAAS,OAAO;EAC9D,kBAAkB,SAAS,WAAW;EACtC;EACA;EACA,YAAY,WAAW;EACvB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,gBAAgB,SAAS,KAAK,WAAW;EACzC;EACA,cAAc,SAAS,eAAe,SAAS,GAAG;EAClD;EACA;EACA,eAAe,KAAK,UAAU,OAAO,CAAC;EACtC;EACA,gCAAgC,SAAS,OAAO,KAAK;EACrD;EACA;EACA;EACA;EACA;EACA;EACA,cAAc,KAAK;EACnB;EACA;EACA;EACA,kBAAkB,SAAS,OAAO;EAClC,gBAAgB,SAAS,KAAK;EAC9B;EACA;EACA;EACA;EACD,CAEY,KAAK,KAAK"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { GeneratedFile } from "./types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/codegen/registry-gen.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generate a registry file for the generated operations.
|
|
7
|
+
*/
|
|
8
|
+
declare function generateRegistry(operationFiles: GeneratedFile[]): GeneratedFile;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { generateRegistry };
|
|
11
|
+
//# sourceMappingURL=registry-gen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-gen.d.ts","names":[],"sources":["../../src/codegen/registry-gen.ts"],"sourcesContent":[],"mappings":";;;;;;;iBAWgB,gBAAA,iBACE,kBACf"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
//#region src/codegen/registry-gen.ts
|
|
2
|
+
/**
|
|
3
|
+
* Generate a registry file for the generated operations.
|
|
4
|
+
*/
|
|
5
|
+
function generateRegistry(operationFiles) {
|
|
6
|
+
const operationImports = operationFiles.filter((f) => f.type === "operation").map((f) => {
|
|
7
|
+
const name = f.path.replace(".ts", "").replace(/-/g, "_");
|
|
8
|
+
const specName = toPascalCase(name) + "Spec";
|
|
9
|
+
return {
|
|
10
|
+
path: f.path,
|
|
11
|
+
name,
|
|
12
|
+
specName
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
const lines = [
|
|
16
|
+
`/**`,
|
|
17
|
+
` * Generated operation registry.`,
|
|
18
|
+
` */`,
|
|
19
|
+
``,
|
|
20
|
+
`import { OperationSpecRegistry } from '@contractspec/lib.contracts';`,
|
|
21
|
+
``
|
|
22
|
+
];
|
|
23
|
+
for (const op of operationImports) {
|
|
24
|
+
const importPath = `./${op.path.replace(".ts", "")}`;
|
|
25
|
+
lines.push(`import { ${op.specName} } from '${importPath}';`);
|
|
26
|
+
}
|
|
27
|
+
lines.push(``);
|
|
28
|
+
lines.push(`export const operationRegistry = new OperationSpecRegistry();`);
|
|
29
|
+
lines.push(``);
|
|
30
|
+
for (const op of operationImports) lines.push(`operationRegistry.register(${op.specName});`);
|
|
31
|
+
lines.push(``);
|
|
32
|
+
return {
|
|
33
|
+
path: "registry.ts",
|
|
34
|
+
content: lines.join("\n"),
|
|
35
|
+
type: "registry"
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Convert kebab-case to PascalCase.
|
|
40
|
+
*/
|
|
41
|
+
function toPascalCase(str) {
|
|
42
|
+
return str.split(/[-_]/).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
//#endregion
|
|
46
|
+
export { generateRegistry };
|
|
47
|
+
//# sourceMappingURL=registry-gen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-gen.js","names":[],"sources":["../../src/codegen/registry-gen.ts"],"sourcesContent":["/**\n * Registry code generator.\n *\n * Generates OperationSpecRegistry from generated operations.\n */\n\nimport type { GeneratedFile } from './types';\n\n/**\n * Generate a registry file for the generated operations.\n */\nexport function generateRegistry(\n operationFiles: GeneratedFile[]\n): GeneratedFile {\n const operationImports = operationFiles\n .filter((f) => f.type === 'operation')\n .map((f) => {\n const name = f.path.replace('.ts', '').replace(/-/g, '_');\n const specName = toPascalCase(name) + 'Spec';\n return { path: f.path, name, specName };\n });\n\n const lines = [\n `/**`,\n ` * Generated operation registry.`,\n ` */`,\n ``,\n `import { OperationSpecRegistry } from '@contractspec/lib.contracts';`,\n ``,\n ];\n\n // Add imports\n for (const op of operationImports) {\n const importPath = `./${op.path.replace('.ts', '')}`;\n lines.push(`import { ${op.specName} } from '${importPath}';`);\n }\n\n lines.push(``);\n lines.push(`export const operationRegistry = new OperationSpecRegistry();`);\n lines.push(``);\n\n // Register operations\n for (const op of operationImports) {\n lines.push(`operationRegistry.register(${op.specName});`);\n }\n\n lines.push(``);\n\n return {\n path: 'registry.ts',\n content: lines.join('\\n'),\n type: 'registry',\n };\n}\n\n/**\n * Convert kebab-case to PascalCase.\n */\nfunction toPascalCase(str: string): string {\n return str\n .split(/[-_]/)\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n}\n"],"mappings":";;;;AAWA,SAAgB,iBACd,gBACe;CACf,MAAM,mBAAmB,eACtB,QAAQ,MAAM,EAAE,SAAS,YAAY,CACrC,KAAK,MAAM;EACV,MAAM,OAAO,EAAE,KAAK,QAAQ,OAAO,GAAG,CAAC,QAAQ,MAAM,IAAI;EACzD,MAAM,WAAW,aAAa,KAAK,GAAG;AACtC,SAAO;GAAE,MAAM,EAAE;GAAM;GAAM;GAAU;GACvC;CAEJ,MAAM,QAAQ;EACZ;EACA;EACA;EACA;EACA;EACA;EACD;AAGD,MAAK,MAAM,MAAM,kBAAkB;EACjC,MAAM,aAAa,KAAK,GAAG,KAAK,QAAQ,OAAO,GAAG;AAClD,QAAM,KAAK,YAAY,GAAG,SAAS,WAAW,WAAW,IAAI;;AAG/D,OAAM,KAAK,GAAG;AACd,OAAM,KAAK,gEAAgE;AAC3E,OAAM,KAAK,GAAG;AAGd,MAAK,MAAM,MAAM,iBACf,OAAM,KAAK,8BAA8B,GAAG,SAAS,IAAI;AAG3D,OAAM,KAAK,GAAG;AAEd,QAAO;EACL,MAAM;EACN,SAAS,MAAM,KAAK,KAAK;EACzB,MAAM;EACP;;;;;AAMH,SAAS,aAAa,KAAqB;AACzC,QAAO,IACJ,MAAM,OAAO,CACb,KAAK,SAAS,KAAK,OAAO,EAAE,CAAC,aAAa,GAAG,KAAK,MAAM,EAAE,CAAC,CAC3D,KAAK,GAAG"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ImportIR, SchemaCandidate } from "../types.js";
|
|
2
|
+
import { GeneratedFile, GenerationOptions } from "./types.js";
|
|
3
|
+
|
|
4
|
+
//#region src/codegen/schema-gen.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Generate a single schema file.
|
|
8
|
+
*/
|
|
9
|
+
declare function generateSchema(schema: SchemaCandidate, _options: GenerationOptions): GeneratedFile;
|
|
10
|
+
/**
|
|
11
|
+
* Generate all schema files from IR.
|
|
12
|
+
*/
|
|
13
|
+
declare function generateSchemas(ir: ImportIR, options: GenerationOptions): GeneratedFile[];
|
|
14
|
+
//#endregion
|
|
15
|
+
export { generateSchema, generateSchemas };
|
|
16
|
+
//# sourceMappingURL=schema-gen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-gen.d.ts","names":[],"sources":["../../src/codegen/schema-gen.ts"],"sourcesContent":[],"mappings":";;;;;;;AA6BA;AACM,iBAlBU,cAAA,CAkBV,MAAA,EAjBI,eAiBJ,EAAA,QAAA,EAhBM,iBAgBN,CAAA,EAfH,aAeG;;;;iBADU,eAAA,KACV,mBACK,oBACR"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
//#region src/codegen/schema-gen.ts
|
|
2
|
+
/**
|
|
3
|
+
* Generate a single schema file.
|
|
4
|
+
*/
|
|
5
|
+
function generateSchema(schema, _options) {
|
|
6
|
+
const fileName = `${toFileName(schema.name)}.ts`;
|
|
7
|
+
const code = generateSchemaCode(schema);
|
|
8
|
+
return {
|
|
9
|
+
path: `schemas/${fileName}`,
|
|
10
|
+
content: code,
|
|
11
|
+
type: "schema"
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Generate all schema files from IR.
|
|
16
|
+
*/
|
|
17
|
+
function generateSchemas(ir, options) {
|
|
18
|
+
return ir.schemas.map((schema) => generateSchema(schema, options));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Convert name to file name (kebab-case).
|
|
22
|
+
*/
|
|
23
|
+
function toFileName(name) {
|
|
24
|
+
return name.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/([A-Z])([A-Z][a-z])/g, "$1-$2").toLowerCase();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Generate schema code.
|
|
28
|
+
*/
|
|
29
|
+
function generateSchemaCode(schema) {
|
|
30
|
+
const lines = [
|
|
31
|
+
`/**`,
|
|
32
|
+
` * ${schema.name}`,
|
|
33
|
+
` *`,
|
|
34
|
+
` * Generated from: ${schema.source.file}:${schema.source.startLine}`,
|
|
35
|
+
` * Schema type: ${schema.schemaType}`,
|
|
36
|
+
` * Confidence: ${schema.confidence.level}`,
|
|
37
|
+
` */`,
|
|
38
|
+
``,
|
|
39
|
+
`import { fromZod } from '@contractspec/lib.schema';`,
|
|
40
|
+
`import { z } from 'zod';`,
|
|
41
|
+
``
|
|
42
|
+
];
|
|
43
|
+
if (schema.rawDefinition && schema.schemaType === "zod") {
|
|
44
|
+
lines.push(`// Original definition from source:`);
|
|
45
|
+
lines.push(`// ${schema.rawDefinition.split("\n")[0]}`);
|
|
46
|
+
lines.push(``);
|
|
47
|
+
}
|
|
48
|
+
lines.push(`export const ${schema.name}Schema = fromZod(z.object({`);
|
|
49
|
+
if (schema.fields && schema.fields.length > 0) for (const field of schema.fields) {
|
|
50
|
+
const zodType = mapToZodType(field.type, field.optional);
|
|
51
|
+
lines.push(` ${field.name}: ${zodType},`);
|
|
52
|
+
}
|
|
53
|
+
else lines.push(` // TODO: Define schema fields`);
|
|
54
|
+
lines.push(`}));`);
|
|
55
|
+
lines.push(``);
|
|
56
|
+
lines.push(`export type ${schema.name} = z.infer<typeof ${schema.name}Schema.zodSchema>;`);
|
|
57
|
+
lines.push(``);
|
|
58
|
+
return lines.join("\n");
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Map TypeScript type to Zod type.
|
|
62
|
+
*/
|
|
63
|
+
function mapToZodType(tsType, optional) {
|
|
64
|
+
let zodType;
|
|
65
|
+
switch (tsType.toLowerCase()) {
|
|
66
|
+
case "string":
|
|
67
|
+
zodType = "z.string()";
|
|
68
|
+
break;
|
|
69
|
+
case "number":
|
|
70
|
+
zodType = "z.number()";
|
|
71
|
+
break;
|
|
72
|
+
case "boolean":
|
|
73
|
+
zodType = "z.boolean()";
|
|
74
|
+
break;
|
|
75
|
+
case "date":
|
|
76
|
+
zodType = "z.date()";
|
|
77
|
+
break;
|
|
78
|
+
case "string[]":
|
|
79
|
+
case "array<string>":
|
|
80
|
+
zodType = "z.array(z.string())";
|
|
81
|
+
break;
|
|
82
|
+
case "number[]":
|
|
83
|
+
case "array<number>":
|
|
84
|
+
zodType = "z.array(z.number())";
|
|
85
|
+
break;
|
|
86
|
+
default: zodType = "z.unknown()";
|
|
87
|
+
}
|
|
88
|
+
return optional ? `${zodType}.optional()` : zodType;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
export { generateSchema, generateSchemas };
|
|
93
|
+
//# sourceMappingURL=schema-gen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-gen.js","names":[],"sources":["../../src/codegen/schema-gen.ts"],"sourcesContent":["/**\n * Schema code generator.\n *\n * Generates defineSchemaModel specs from schema candidates.\n */\n\nimport type { SchemaCandidate, ImportIR } from '../types';\nimport type { GeneratedFile, GenerationOptions } from './types';\n\n/**\n * Generate a single schema file.\n */\nexport function generateSchema(\n schema: SchemaCandidate,\n _options: GenerationOptions\n): GeneratedFile {\n const fileName = `${toFileName(schema.name)}.ts`;\n const code = generateSchemaCode(schema);\n\n return {\n path: `schemas/${fileName}`,\n content: code,\n type: 'schema',\n };\n}\n\n/**\n * Generate all schema files from IR.\n */\nexport function generateSchemas(\n ir: ImportIR,\n options: GenerationOptions\n): GeneratedFile[] {\n return ir.schemas.map((schema) => generateSchema(schema, options));\n}\n\n/**\n * Convert name to file name (kebab-case).\n */\nfunction toFileName(name: string): string {\n return name\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')\n .toLowerCase();\n}\n\n/**\n * Generate schema code.\n */\nfunction generateSchemaCode(schema: SchemaCandidate): string {\n const lines = [\n `/**`,\n ` * ${schema.name}`,\n ` *`,\n ` * Generated from: ${schema.source.file}:${schema.source.startLine}`,\n ` * Schema type: ${schema.schemaType}`,\n ` * Confidence: ${schema.confidence.level}`,\n ` */`,\n ``,\n `import { fromZod } from '@contractspec/lib.schema';`,\n `import { z } from 'zod';`,\n ``,\n ];\n\n if (schema.rawDefinition && schema.schemaType === 'zod') {\n // Use the raw Zod definition if available\n lines.push(`// Original definition from source:`);\n lines.push(`// ${schema.rawDefinition.split('\\n')[0]}`);\n lines.push(``);\n }\n\n lines.push(`export const ${schema.name}Schema = fromZod(z.object({`);\n\n if (schema.fields && schema.fields.length > 0) {\n for (const field of schema.fields) {\n const zodType = mapToZodType(field.type, field.optional);\n lines.push(` ${field.name}: ${zodType},`);\n }\n } else {\n lines.push(` // TODO: Define schema fields`);\n }\n\n lines.push(`}));`);\n lines.push(``);\n lines.push(\n `export type ${schema.name} = z.infer<typeof ${schema.name}Schema.zodSchema>;`\n );\n lines.push(``);\n\n return lines.join('\\n');\n}\n\n/**\n * Map TypeScript type to Zod type.\n */\nfunction mapToZodType(tsType: string, optional: boolean): string {\n let zodType: string;\n\n switch (tsType.toLowerCase()) {\n case 'string':\n zodType = 'z.string()';\n break;\n case 'number':\n zodType = 'z.number()';\n break;\n case 'boolean':\n zodType = 'z.boolean()';\n break;\n case 'date':\n zodType = 'z.date()';\n break;\n case 'string[]':\n case 'array<string>':\n zodType = 'z.array(z.string())';\n break;\n case 'number[]':\n case 'array<number>':\n zodType = 'z.array(z.number())';\n break;\n default:\n zodType = 'z.unknown()';\n }\n\n return optional ? `${zodType}.optional()` : zodType;\n}\n"],"mappings":";;;;AAYA,SAAgB,eACd,QACA,UACe;CACf,MAAM,WAAW,GAAG,WAAW,OAAO,KAAK,CAAC;CAC5C,MAAM,OAAO,mBAAmB,OAAO;AAEvC,QAAO;EACL,MAAM,WAAW;EACjB,SAAS;EACT,MAAM;EACP;;;;;AAMH,SAAgB,gBACd,IACA,SACiB;AACjB,QAAO,GAAG,QAAQ,KAAK,WAAW,eAAe,QAAQ,QAAQ,CAAC;;;;;AAMpE,SAAS,WAAW,MAAsB;AACxC,QAAO,KACJ,QAAQ,mBAAmB,QAAQ,CACnC,QAAQ,wBAAwB,QAAQ,CACxC,aAAa;;;;;AAMlB,SAAS,mBAAmB,QAAiC;CAC3D,MAAM,QAAQ;EACZ;EACA,MAAM,OAAO;EACb;EACA,sBAAsB,OAAO,OAAO,KAAK,GAAG,OAAO,OAAO;EAC1D,mBAAmB,OAAO;EAC1B,kBAAkB,OAAO,WAAW;EACpC;EACA;EACA;EACA;EACA;EACD;AAED,KAAI,OAAO,iBAAiB,OAAO,eAAe,OAAO;AAEvD,QAAM,KAAK,sCAAsC;AACjD,QAAM,KAAK,MAAM,OAAO,cAAc,MAAM,KAAK,CAAC,KAAK;AACvD,QAAM,KAAK,GAAG;;AAGhB,OAAM,KAAK,gBAAgB,OAAO,KAAK,6BAA6B;AAEpE,KAAI,OAAO,UAAU,OAAO,OAAO,SAAS,EAC1C,MAAK,MAAM,SAAS,OAAO,QAAQ;EACjC,MAAM,UAAU,aAAa,MAAM,MAAM,MAAM,SAAS;AACxD,QAAM,KAAK,KAAK,MAAM,KAAK,IAAI,QAAQ,GAAG;;KAG5C,OAAM,KAAK,kCAAkC;AAG/C,OAAM,KAAK,OAAO;AAClB,OAAM,KAAK,GAAG;AACd,OAAM,KACJ,eAAe,OAAO,KAAK,oBAAoB,OAAO,KAAK,oBAC5D;AACD,OAAM,KAAK,GAAG;AAEd,QAAO,MAAM,KAAK,KAAK;;;;;AAMzB,SAAS,aAAa,QAAgB,UAA2B;CAC/D,IAAI;AAEJ,SAAQ,OAAO,aAAa,EAA5B;EACE,KAAK;AACH,aAAU;AACV;EACF,KAAK;AACH,aAAU;AACV;EACF,KAAK;AACH,aAAU;AACV;EACF,KAAK;AACH,aAAU;AACV;EACF,KAAK;EACL,KAAK;AACH,aAAU;AACV;EACF,KAAK;EACL,KAAK;AACH,aAAU;AACV;EACF,QACE,WAAU;;AAGd,QAAO,WAAW,GAAG,QAAQ,eAAe"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//#region src/codegen/types.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Code generation types.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* A generated file.
|
|
7
|
+
*/
|
|
8
|
+
interface GeneratedFile {
|
|
9
|
+
/** Relative path from output directory */
|
|
10
|
+
path: string;
|
|
11
|
+
/** File content */
|
|
12
|
+
content: string;
|
|
13
|
+
/** Type of generated file */
|
|
14
|
+
type: 'operation' | 'schema' | 'registry' | 'index';
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Options for code generation.
|
|
18
|
+
*/
|
|
19
|
+
interface GenerationOptions {
|
|
20
|
+
/** Output directory */
|
|
21
|
+
outputDir: string;
|
|
22
|
+
/** Whether to overwrite existing files */
|
|
23
|
+
overwrite?: boolean;
|
|
24
|
+
/** Schema format to use */
|
|
25
|
+
schemaFormat?: 'zod' | 'typescript';
|
|
26
|
+
/** Default auth level */
|
|
27
|
+
defaultAuth?: 'anonymous' | 'user' | 'admin';
|
|
28
|
+
/** Default owners */
|
|
29
|
+
defaultOwners?: string[];
|
|
30
|
+
/** Prefix for generated names */
|
|
31
|
+
prefix?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Result of code generation.
|
|
35
|
+
*/
|
|
36
|
+
interface GenerationResult {
|
|
37
|
+
/** Generated files */
|
|
38
|
+
files: GeneratedFile[];
|
|
39
|
+
/** Number of operations generated */
|
|
40
|
+
operationsGenerated: number;
|
|
41
|
+
/** Number of schemas generated */
|
|
42
|
+
schemasGenerated: number;
|
|
43
|
+
/** Warnings during generation */
|
|
44
|
+
warnings: string[];
|
|
45
|
+
}
|
|
46
|
+
//#endregion
|
|
47
|
+
export { GeneratedFile, GenerationOptions, GenerationResult };
|
|
48
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../src/codegen/types.ts"],"sourcesContent":[],"mappings":";;AAOA;AAYA;AAkBA;;;UA9BiB,aAAA;;;;;;;;;;;UAYA,iBAAA;;;;;;;;;;;;;;;;;UAkBA,gBAAA;;SAER"}
|
package/dist/detect.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { FrameworkInfo, ProjectInfo } from "./types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/detect.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Dependencies from package.json.
|
|
7
|
+
*/
|
|
8
|
+
interface PackageDependencies {
|
|
9
|
+
dependencies?: Record<string, string>;
|
|
10
|
+
devDependencies?: Record<string, string>;
|
|
11
|
+
peerDependencies?: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Detect frameworks from package.json dependencies.
|
|
15
|
+
*/
|
|
16
|
+
declare function detectFrameworksFromPackageJson(packageJson: PackageDependencies): FrameworkInfo[];
|
|
17
|
+
/**
|
|
18
|
+
* Detect frameworks from source code imports.
|
|
19
|
+
*/
|
|
20
|
+
declare function detectFrameworksFromCode(sourceCode: string): FrameworkInfo[];
|
|
21
|
+
/**
|
|
22
|
+
* Detect frameworks from file paths.
|
|
23
|
+
*/
|
|
24
|
+
declare function detectFrameworksFromPaths(filePaths: string[]): FrameworkInfo[];
|
|
25
|
+
/**
|
|
26
|
+
* Merge framework detections, preferring higher confidence.
|
|
27
|
+
*/
|
|
28
|
+
declare function mergeFrameworkDetections(...detections: FrameworkInfo[][]): FrameworkInfo[];
|
|
29
|
+
/**
|
|
30
|
+
* Detect frameworks for a project.
|
|
31
|
+
* This is a convenience function that combines all detection methods.
|
|
32
|
+
*/
|
|
33
|
+
declare function detectFramework(rootPath: string, options?: {
|
|
34
|
+
readFile?: (path: string) => Promise<string>;
|
|
35
|
+
glob?: (pattern: string) => Promise<string[]>;
|
|
36
|
+
}): Promise<ProjectInfo>;
|
|
37
|
+
/**
|
|
38
|
+
* Get all supported framework IDs.
|
|
39
|
+
*/
|
|
40
|
+
declare function getSupportedFrameworks(): string[];
|
|
41
|
+
/**
|
|
42
|
+
* Check if a framework ID is supported.
|
|
43
|
+
*/
|
|
44
|
+
declare function isFrameworkSupported(id: string): boolean;
|
|
45
|
+
//#endregion
|
|
46
|
+
export { detectFramework, detectFrameworksFromCode, detectFrameworksFromPackageJson, detectFrameworksFromPaths, getSupportedFrameworks, isFrameworkSupported, mergeFrameworkDetections };
|
|
47
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","names":[],"sources":["../src/detect.ts"],"sourcesContent":[],"mappings":";;;;;;AA8FA;AA+BA,UAxCU,mBAAA,CAwCM;EA0BA,YAAA,CAAA,EAjEC,MAiED,CAAA,MAAyB,EAAA,MAAA,CAAA;EA8BzB,eAAA,CAAA,EA9FI,MA8FJ,CAAA,MAAwB,EAAA,MACvB,CAAA;EA8BK,gBAAA,CAAA,EA5HD,MA4HgB,CAAA,MAAA,EAAA,MAAA,CAAA;;;;;AAM3B,iBA5HM,+BAAA,CA4HN,WAAA,EA3HK,mBA2HL,CAAA,EA1HP,aA0HO,EAAA;AAoCV;AAOA;;iBAxIgB,wBAAA,sBAA8C;;;;iBA0B9C,yBAAA,uBAEb;;;;iBA4Ba,wBAAA,gBACC,oBACd;;;;;iBA6BmB,eAAA;+BAGW;8BACD;IAE7B,QAAQ;;;;iBAoCK,sBAAA,CAAA;;;;iBAOA,oBAAA"}
|