@contractspec/module.workspace 0.0.0-canary-20260113162409
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/LICENSE +21 -0
- package/README.md +50 -0
- package/dist/ai/prompts/code-generation.d.ts +24 -0
- package/dist/ai/prompts/code-generation.d.ts.map +1 -0
- package/dist/ai/prompts/code-generation.js +134 -0
- package/dist/ai/prompts/code-generation.js.map +1 -0
- package/dist/ai/prompts/spec-creation.d.ts +28 -0
- package/dist/ai/prompts/spec-creation.d.ts.map +1 -0
- package/dist/ai/prompts/spec-creation.js +102 -0
- package/dist/ai/prompts/spec-creation.js.map +1 -0
- package/dist/analysis/deps/graph.d.ts +34 -0
- package/dist/analysis/deps/graph.d.ts.map +1 -0
- package/dist/analysis/deps/graph.js +85 -0
- package/dist/analysis/deps/graph.js.map +1 -0
- package/dist/analysis/deps/parse-imports.d.ts +17 -0
- package/dist/analysis/deps/parse-imports.d.ts.map +1 -0
- package/dist/analysis/deps/parse-imports.js +31 -0
- package/dist/analysis/deps/parse-imports.js.map +1 -0
- package/dist/analysis/diff/deep-diff.d.ts +33 -0
- package/dist/analysis/diff/deep-diff.d.ts.map +1 -0
- package/dist/analysis/diff/deep-diff.js +114 -0
- package/dist/analysis/diff/deep-diff.js.map +1 -0
- package/dist/analysis/diff/semantic.d.ts +11 -0
- package/dist/analysis/diff/semantic.d.ts.map +1 -0
- package/dist/analysis/diff/semantic.js +97 -0
- package/dist/analysis/diff/semantic.js.map +1 -0
- package/dist/analysis/example-scan.d.ts +15 -0
- package/dist/analysis/example-scan.d.ts.map +1 -0
- package/dist/analysis/example-scan.js +116 -0
- package/dist/analysis/example-scan.js.map +1 -0
- package/dist/analysis/feature-extractor.js +203 -0
- package/dist/analysis/feature-extractor.js.map +1 -0
- package/dist/analysis/feature-scan.d.ts +15 -0
- package/dist/analysis/feature-scan.d.ts.map +1 -0
- package/dist/analysis/feature-scan.js +56 -0
- package/dist/analysis/feature-scan.js.map +1 -0
- package/dist/analysis/grouping.d.ts +79 -0
- package/dist/analysis/grouping.d.ts.map +1 -0
- package/dist/analysis/grouping.js +115 -0
- package/dist/analysis/grouping.js.map +1 -0
- package/dist/analysis/impact/classifier.d.ts +19 -0
- package/dist/analysis/impact/classifier.d.ts.map +1 -0
- package/dist/analysis/impact/classifier.js +135 -0
- package/dist/analysis/impact/classifier.js.map +1 -0
- package/dist/analysis/impact/index.js +2 -0
- package/dist/analysis/impact/rules.d.ts +35 -0
- package/dist/analysis/impact/rules.d.ts.map +1 -0
- package/dist/analysis/impact/rules.js +154 -0
- package/dist/analysis/impact/rules.js.map +1 -0
- package/dist/analysis/impact/types.d.ts +95 -0
- package/dist/analysis/impact/types.d.ts.map +1 -0
- package/dist/analysis/index.js +18 -0
- package/dist/analysis/snapshot/index.js +2 -0
- package/dist/analysis/snapshot/normalizer.d.ts +36 -0
- package/dist/analysis/snapshot/normalizer.d.ts.map +1 -0
- package/dist/analysis/snapshot/normalizer.js +67 -0
- package/dist/analysis/snapshot/normalizer.js.map +1 -0
- package/dist/analysis/snapshot/snapshot.d.ts +18 -0
- package/dist/analysis/snapshot/snapshot.d.ts.map +1 -0
- package/dist/analysis/snapshot/snapshot.js +163 -0
- package/dist/analysis/snapshot/snapshot.js.map +1 -0
- package/dist/analysis/snapshot/types.d.ts +74 -0
- package/dist/analysis/snapshot/types.d.ts.map +1 -0
- package/dist/analysis/spec-parser.d.ts +11 -0
- package/dist/analysis/spec-parser.d.ts.map +1 -0
- package/dist/analysis/spec-parser.js +89 -0
- package/dist/analysis/spec-parser.js.map +1 -0
- package/dist/analysis/spec-parsing-utils.d.ts +26 -0
- package/dist/analysis/spec-parsing-utils.d.ts.map +1 -0
- package/dist/analysis/spec-parsing-utils.js +98 -0
- package/dist/analysis/spec-parsing-utils.js.map +1 -0
- package/dist/analysis/spec-scan.d.ts +20 -0
- package/dist/analysis/spec-scan.d.ts.map +1 -0
- package/dist/analysis/spec-scan.js +141 -0
- package/dist/analysis/spec-scan.js.map +1 -0
- package/dist/analysis/utils/matchers.js +77 -0
- package/dist/analysis/utils/matchers.js.map +1 -0
- package/dist/analysis/utils/variables.js +45 -0
- package/dist/analysis/utils/variables.js.map +1 -0
- package/dist/analysis/validate/index.js +1 -0
- package/dist/analysis/validate/spec-structure.d.ts +29 -0
- package/dist/analysis/validate/spec-structure.d.ts.map +1 -0
- package/dist/analysis/validate/spec-structure.js +455 -0
- package/dist/analysis/validate/spec-structure.js.map +1 -0
- package/dist/formatter.d.ts +42 -0
- package/dist/formatter.d.ts.map +1 -0
- package/dist/formatter.js +163 -0
- package/dist/formatter.js.map +1 -0
- package/dist/formatters/index.js +2 -0
- package/dist/formatters/spec-markdown.d.ts +31 -0
- package/dist/formatters/spec-markdown.d.ts.map +1 -0
- package/dist/formatters/spec-markdown.js +263 -0
- package/dist/formatters/spec-markdown.js.map +1 -0
- package/dist/formatters/spec-to-docblock.d.ts +14 -0
- package/dist/formatters/spec-to-docblock.d.ts.map +1 -0
- package/dist/formatters/spec-to-docblock.js +48 -0
- package/dist/formatters/spec-to-docblock.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +39 -0
- package/dist/templates/app-config.d.ts +7 -0
- package/dist/templates/app-config.d.ts.map +1 -0
- package/dist/templates/app-config.js +107 -0
- package/dist/templates/app-config.js.map +1 -0
- package/dist/templates/data-view.d.ts +7 -0
- package/dist/templates/data-view.d.ts.map +1 -0
- package/dist/templates/data-view.js +69 -0
- package/dist/templates/data-view.js.map +1 -0
- package/dist/templates/event.d.ts +11 -0
- package/dist/templates/event.d.ts.map +1 -0
- package/dist/templates/event.js +41 -0
- package/dist/templates/event.js.map +1 -0
- package/dist/templates/experiment.d.ts +7 -0
- package/dist/templates/experiment.d.ts.map +1 -0
- package/dist/templates/experiment.js +88 -0
- package/dist/templates/experiment.js.map +1 -0
- package/dist/templates/handler.d.ts +20 -0
- package/dist/templates/handler.d.ts.map +1 -0
- package/dist/templates/handler.js +96 -0
- package/dist/templates/handler.js.map +1 -0
- package/dist/templates/integration-utils.js +105 -0
- package/dist/templates/integration-utils.js.map +1 -0
- package/dist/templates/integration.d.ts +7 -0
- package/dist/templates/integration.d.ts.map +1 -0
- package/dist/templates/integration.js +62 -0
- package/dist/templates/integration.js.map +1 -0
- package/dist/templates/knowledge.d.ts +7 -0
- package/dist/templates/knowledge.d.ts.map +1 -0
- package/dist/templates/knowledge.js +69 -0
- package/dist/templates/knowledge.js.map +1 -0
- package/dist/templates/migration.d.ts +7 -0
- package/dist/templates/migration.d.ts.map +1 -0
- package/dist/templates/migration.js +61 -0
- package/dist/templates/migration.js.map +1 -0
- package/dist/templates/operation.d.ts +11 -0
- package/dist/templates/operation.d.ts.map +1 -0
- package/dist/templates/operation.js +101 -0
- package/dist/templates/operation.js.map +1 -0
- package/dist/templates/presentation.d.ts +11 -0
- package/dist/templates/presentation.d.ts.map +1 -0
- package/dist/templates/presentation.js +79 -0
- package/dist/templates/presentation.js.map +1 -0
- package/dist/templates/telemetry.d.ts +7 -0
- package/dist/templates/telemetry.d.ts.map +1 -0
- package/dist/templates/telemetry.js +90 -0
- package/dist/templates/telemetry.js.map +1 -0
- package/dist/templates/utils.d.ts +27 -0
- package/dist/templates/utils.d.ts.map +1 -0
- package/dist/templates/utils.js +39 -0
- package/dist/templates/utils.js.map +1 -0
- package/dist/templates/workflow-runner.d.ts +16 -0
- package/dist/templates/workflow-runner.d.ts.map +1 -0
- package/dist/templates/workflow-runner.js +49 -0
- package/dist/templates/workflow-runner.js.map +1 -0
- package/dist/templates/workflow.d.ts +11 -0
- package/dist/templates/workflow.d.ts.map +1 -0
- package/dist/templates/workflow.js +68 -0
- package/dist/templates/workflow.js.map +1 -0
- package/dist/types/analysis-types.d.ts +199 -0
- package/dist/types/analysis-types.d.ts.map +1 -0
- package/dist/types/generation-types.d.ts +87 -0
- package/dist/types/generation-types.d.ts.map +1 -0
- package/dist/types/generation-types.js +21 -0
- package/dist/types/generation-types.js.map +1 -0
- package/dist/types/llm-types.d.ts +138 -0
- package/dist/types/llm-types.d.ts.map +1 -0
- package/dist/types/rulesync-types.d.ts +24 -0
- package/dist/types/rulesync-types.d.ts.map +1 -0
- package/dist/types/spec-types.d.ts +343 -0
- package/dist/types/spec-types.d.ts.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { toCamelCase, toKebabCase, toPascalCase } from "./utils.js";
|
|
2
|
+
|
|
3
|
+
//#region src/templates/handler.ts
|
|
4
|
+
/**
|
|
5
|
+
* Handler and component template generation.
|
|
6
|
+
* Extracted from cli-contractspec/src/templates/handler.template.ts
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Generate handler implementation template.
|
|
10
|
+
*/
|
|
11
|
+
function generateHandlerTemplate(specName, kind) {
|
|
12
|
+
const handlerName = toCamelCase(specName.split(".").pop() ?? "unknown") + "Handler";
|
|
13
|
+
const specVarName = toPascalCase(specName.split(".").pop() ?? "Unknown") + "Spec";
|
|
14
|
+
return `import type { ContractHandler } from '@contractspec/lib.contracts';
|
|
15
|
+
import { ${specVarName} } from '../contracts/${toKebabCase(specName)}.contracts';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Handler for ${specName}
|
|
19
|
+
*/
|
|
20
|
+
export const ${handlerName}: ContractHandler<typeof ${specVarName}> = async (
|
|
21
|
+
input,
|
|
22
|
+
context
|
|
23
|
+
) => {
|
|
24
|
+
// TODO: Implement ${kind} logic
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
// 1. Validate prerequisites
|
|
28
|
+
// 2. Perform business logic
|
|
29
|
+
// 3. Emit events if needed
|
|
30
|
+
// 4. Return result
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
ok: true,
|
|
34
|
+
};
|
|
35
|
+
} catch (error) {
|
|
36
|
+
// Handle and map errors to spec.io.errors
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Generate React component template.
|
|
44
|
+
*/
|
|
45
|
+
function generateComponentTemplate(componentName, description) {
|
|
46
|
+
const pascalName = toPascalCase(componentName);
|
|
47
|
+
return `import React from 'react';
|
|
48
|
+
|
|
49
|
+
interface ${pascalName}Props {
|
|
50
|
+
// TODO: Define props based on presentation spec
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* ${description}
|
|
55
|
+
*/
|
|
56
|
+
export const ${pascalName}: React.FC<${pascalName}Props> = (props) => {
|
|
57
|
+
return (
|
|
58
|
+
<div>
|
|
59
|
+
{/* TODO: Implement component UI */}
|
|
60
|
+
<p>Component: ${pascalName}</p>
|
|
61
|
+
</div>
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
`;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Generate test template.
|
|
68
|
+
*/
|
|
69
|
+
function generateTestTemplate(targetName, type) {
|
|
70
|
+
const importPath = type === "handler" ? "../handlers" : "../components";
|
|
71
|
+
const testName = toPascalCase(targetName);
|
|
72
|
+
return `import { describe, it, expect } from 'bun:test';
|
|
73
|
+
import { ${testName} } from '${importPath}/${toKebabCase(targetName)}';
|
|
74
|
+
|
|
75
|
+
describe('${testName}', () => {
|
|
76
|
+
it('should ${type === "handler" ? "handle valid input" : "render correctly"}', async () => {
|
|
77
|
+
// TODO: Implement test
|
|
78
|
+
expect(true).toBe(true);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('should handle edge cases', async () => {
|
|
82
|
+
// TODO: Test edge cases
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
${type === "handler" ? `it('should handle errors appropriately', async () => {
|
|
86
|
+
// TODO: Test error scenarios
|
|
87
|
+
});` : `it('should be accessible', async () => {
|
|
88
|
+
// TODO: Test accessibility
|
|
89
|
+
});`}
|
|
90
|
+
});
|
|
91
|
+
`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
//#endregion
|
|
95
|
+
export { generateComponentTemplate, generateHandlerTemplate, generateTestTemplate };
|
|
96
|
+
//# sourceMappingURL=handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.js","names":[],"sources":["../../src/templates/handler.ts"],"sourcesContent":["/**\n * Handler and component template generation.\n * Extracted from cli-contractspec/src/templates/handler.template.ts\n */\n\nimport { toPascalCase, toCamelCase, toKebabCase } from './utils';\n\n/**\n * Generate handler implementation template.\n */\nexport function generateHandlerTemplate(\n specName: string,\n kind: 'command' | 'query'\n): string {\n const handlerName =\n toCamelCase(specName.split('.').pop() ?? 'unknown') + 'Handler';\n const specVarName =\n toPascalCase(specName.split('.').pop() ?? 'Unknown') + 'Spec';\n\n return `import type { ContractHandler } from '@contractspec/lib.contracts';\nimport { ${specVarName} } from '../contracts/${toKebabCase(specName)}.contracts';\n\n/**\n * Handler for ${specName}\n */\nexport const ${handlerName}: ContractHandler<typeof ${specVarName}> = async (\n input,\n context\n) => {\n // TODO: Implement ${kind} logic\n \n try {\n // 1. Validate prerequisites\n // 2. Perform business logic\n // 3. Emit events if needed\n // 4. Return result\n \n return {\n ok: true,\n };\n } catch (error) {\n // Handle and map errors to spec.io.errors\n throw error;\n }\n};\n`;\n}\n\n/**\n * Generate React component template.\n */\nexport function generateComponentTemplate(\n componentName: string,\n description: string\n): string {\n const pascalName = toPascalCase(componentName);\n\n return `import React from 'react';\n\ninterface ${pascalName}Props {\n // TODO: Define props based on presentation spec\n}\n\n/**\n * ${description}\n */\nexport const ${pascalName}: React.FC<${pascalName}Props> = (props) => {\n return (\n <div>\n {/* TODO: Implement component UI */}\n <p>Component: ${pascalName}</p>\n </div>\n );\n};\n`;\n}\n\n/**\n * Generate test template.\n */\nexport function generateTestTemplate(\n targetName: string,\n type: 'handler' | 'component'\n): string {\n const importPath = type === 'handler' ? '../handlers' : '../components';\n const testName = toPascalCase(targetName);\n\n return `import { describe, it, expect } from 'bun:test';\nimport { ${testName} } from '${importPath}/${toKebabCase(targetName)}';\n\ndescribe('${testName}', () => {\n it('should ${type === 'handler' ? 'handle valid input' : 'render correctly'}', async () => {\n // TODO: Implement test\n expect(true).toBe(true);\n });\n\n it('should handle edge cases', async () => {\n // TODO: Test edge cases\n });\n\n ${\n type === 'handler'\n ? `it('should handle errors appropriately', async () => {\n // TODO: Test error scenarios\n });`\n : `it('should be accessible', async () => {\n // TODO: Test accessibility\n });`\n }\n});\n`;\n}\n"],"mappings":";;;;;;;;;;AAUA,SAAgB,wBACd,UACA,MACQ;CACR,MAAM,cACJ,YAAY,SAAS,MAAM,IAAI,CAAC,KAAK,IAAI,UAAU,GAAG;CACxD,MAAM,cACJ,aAAa,SAAS,MAAM,IAAI,CAAC,KAAK,IAAI,UAAU,GAAG;AAEzD,QAAO;WACE,YAAY,wBAAwB,YAAY,SAAS,CAAC;;;iBAGpD,SAAS;;eAEX,YAAY,2BAA2B,YAAY;;;;uBAI3C,KAAK;;;;;;;;;;;;;;;;;;;;;AAsB5B,SAAgB,0BACd,eACA,aACQ;CACR,MAAM,aAAa,aAAa,cAAc;AAE9C,QAAO;;YAEG,WAAW;;;;;KAKlB,YAAY;;eAEF,WAAW,aAAa,WAAW;;;;sBAI5B,WAAW;;;;;;;;;AAUjC,SAAgB,qBACd,YACA,MACQ;CACR,MAAM,aAAa,SAAS,YAAY,gBAAgB;CACxD,MAAM,WAAW,aAAa,WAAW;AAEzC,QAAO;WACE,SAAS,WAAW,WAAW,GAAG,YAAY,WAAW,CAAC;;YAEzD,SAAS;eACN,SAAS,YAAY,uBAAuB,mBAAmB;;;;;;;;;IAU1E,SAAS,YACL;;SAGA;;OAGL"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
//#region src/templates/integration-utils.ts
|
|
2
|
+
function renderConfigSchema(fields) {
|
|
3
|
+
const requiredFields = fields.filter((field) => field.required);
|
|
4
|
+
return ` schema: {
|
|
5
|
+
type: 'object',
|
|
6
|
+
${requiredFields.length > 0 ? ` required: [${requiredFields.map((field) => `'${field.key}'`).join(", ")}],
|
|
7
|
+
` : ""} properties: {
|
|
8
|
+
${(fields.length ? fields.map((field) => {
|
|
9
|
+
const description = field.description ? `, description: '${escape(field.description)}'` : "";
|
|
10
|
+
return ` ${field.key}: { type: '${mapConfigType(field.type)}'${description} }`;
|
|
11
|
+
}).join(",\n") : "") || " "}
|
|
12
|
+
},
|
|
13
|
+
},\n`;
|
|
14
|
+
}
|
|
15
|
+
function renderSecretSchema(fields) {
|
|
16
|
+
const requiredFields = fields.filter((field) => field.required);
|
|
17
|
+
return ` schema: {
|
|
18
|
+
type: 'object',
|
|
19
|
+
${requiredFields.length > 0 ? ` required: [${requiredFields.map((field) => `'${field.key}'`).join(", ")}],
|
|
20
|
+
` : ""} properties: {
|
|
21
|
+
${(fields.length ? fields.map((field) => {
|
|
22
|
+
const description = field.description ? `, description: '${escape(field.description)}'` : "";
|
|
23
|
+
return ` ${field.key}: { type: 'string'${description} }`;
|
|
24
|
+
}).join(",\n") : "") || " "}
|
|
25
|
+
},
|
|
26
|
+
},\n`;
|
|
27
|
+
}
|
|
28
|
+
function renderConfigExample(fields) {
|
|
29
|
+
if (fields.length === 0) return `{}`;
|
|
30
|
+
return `{
|
|
31
|
+
${fields.map((field) => {
|
|
32
|
+
switch (field.type) {
|
|
33
|
+
case "number": return ` ${field.key}: 0`;
|
|
34
|
+
case "boolean": return ` ${field.key}: true`;
|
|
35
|
+
case "string":
|
|
36
|
+
default: return ` ${field.key}: '${field.key.toUpperCase()}_VALUE'`;
|
|
37
|
+
}
|
|
38
|
+
}).join(",\n")}
|
|
39
|
+
}`;
|
|
40
|
+
}
|
|
41
|
+
function renderSecretExample(fields) {
|
|
42
|
+
if (fields.length === 0) return `{}`;
|
|
43
|
+
return `{
|
|
44
|
+
${fields.map((field) => ` ${field.key}: '${field.key.toUpperCase()}_SECRET'`).join(",\n")}
|
|
45
|
+
}`;
|
|
46
|
+
}
|
|
47
|
+
function renderConstraints(rpm, rph) {
|
|
48
|
+
if (rpm == null && rph == null) return "";
|
|
49
|
+
const entries = [];
|
|
50
|
+
if (rpm != null) entries.push(` rpm: ${rpm}`);
|
|
51
|
+
if (rph != null) entries.push(` rph: ${rph}`);
|
|
52
|
+
return ` constraints: {
|
|
53
|
+
rateLimit: {
|
|
54
|
+
${entries.join(",\n")}
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
`;
|
|
58
|
+
}
|
|
59
|
+
function renderByokSetup(modes, instructions, scopes) {
|
|
60
|
+
if (!modes.includes("byok")) return "";
|
|
61
|
+
const instructionsLine = instructions ? ` setupInstructions: '${escape(instructions)}',\n` : "";
|
|
62
|
+
const scopesLine = scopes && scopes.length ? ` requiredScopes: [${scopes.map((scope) => `'${escape(scope)}'`).join(", ")}],\n` : "";
|
|
63
|
+
if (!instructionsLine && !scopesLine) return "";
|
|
64
|
+
return ` byokSetup: {
|
|
65
|
+
${instructionsLine}${scopesLine} },
|
|
66
|
+
`;
|
|
67
|
+
}
|
|
68
|
+
function mapConfigType(type) {
|
|
69
|
+
switch (type) {
|
|
70
|
+
case "number": return "number";
|
|
71
|
+
case "boolean": return "boolean";
|
|
72
|
+
case "string":
|
|
73
|
+
default: return "string";
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function stabilityToEnum(stability) {
|
|
77
|
+
switch (stability) {
|
|
78
|
+
case "beta": return "Beta";
|
|
79
|
+
case "stable": return "Stable";
|
|
80
|
+
case "deprecated": return "Deprecated";
|
|
81
|
+
case "experimental":
|
|
82
|
+
default: return "Experimental";
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function renderProvides(data) {
|
|
86
|
+
return data.capabilitiesProvided.map((cap) => ` { key: '${cap.key}', version: ${cap.version} }`).join(",\n");
|
|
87
|
+
}
|
|
88
|
+
function renderRequires(data) {
|
|
89
|
+
if (data.capabilitiesRequired.length === 0) return "";
|
|
90
|
+
return ` requires: [
|
|
91
|
+
${data.capabilitiesRequired.map((req) => {
|
|
92
|
+
const version = typeof req.version === "number" ? `, version: ${req.version}` : "";
|
|
93
|
+
const optional = req.optional ? ", optional: true" : "";
|
|
94
|
+
const reason = req.reason ? `, reason: '${escape(req.reason)}'` : "";
|
|
95
|
+
return ` { key: '${req.key}'${version}${optional}${reason} }`;
|
|
96
|
+
}).join(",\n")}
|
|
97
|
+
],`;
|
|
98
|
+
}
|
|
99
|
+
function escape(value) {
|
|
100
|
+
return value.replace(/`/g, "\\`").replace(/'/g, "\\'");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
//#endregion
|
|
104
|
+
export { escape, renderByokSetup, renderConfigExample, renderConfigSchema, renderConstraints, renderProvides, renderRequires, renderSecretExample, renderSecretSchema, stabilityToEnum };
|
|
105
|
+
//# sourceMappingURL=integration-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration-utils.js","names":[],"sources":["../../src/templates/integration-utils.ts"],"sourcesContent":["import type {\n IntegrationConfigFieldData,\n IntegrationSecretFieldData,\n IntegrationSpecData,\n Stability,\n} from '../types/spec-types';\n\nexport function renderConfigSchema(\n fields: IntegrationConfigFieldData[]\n): string {\n const requiredFields = fields.filter((field) => field.required);\n const requiredBlock =\n requiredFields.length > 0\n ? ` required: [${requiredFields\n .map((field) => `'${field.key}'`)\n .join(', ')}],\n`\n : '';\n\n const properties = fields.length\n ? fields\n .map((field) => {\n const description = field.description\n ? `, description: '${escape(field.description)}'`\n : '';\n return ` ${field.key}: { type: '${mapConfigType(\n field.type\n )}'${description} }`;\n })\n .join(',\\n')\n : '';\n\n return ` schema: {\n type: 'object',\n${requiredBlock} properties: {\n${properties || ' '}\n },\n },\\n`;\n}\n\nexport function renderSecretSchema(\n fields: IntegrationSecretFieldData[]\n): string {\n const requiredFields = fields.filter((field) => field.required);\n const requiredBlock =\n requiredFields.length > 0\n ? ` required: [${requiredFields\n .map((field) => `'${field.key}'`)\n .join(', ')}],\n`\n : '';\n\n const properties = fields.length\n ? fields\n .map((field) => {\n const description = field.description\n ? `, description: '${escape(field.description)}'`\n : '';\n return ` ${field.key}: { type: 'string'${description} }`;\n })\n .join(',\\n')\n : '';\n\n return ` schema: {\n type: 'object',\n${requiredBlock} properties: {\n${properties || ' '}\n },\n },\\n`;\n}\n\nexport function renderConfigExample(\n fields: IntegrationConfigFieldData[]\n): string {\n if (fields.length === 0) {\n return `{}`;\n }\n\n const exampleEntries = fields.map((field) => {\n switch (field.type) {\n case 'number':\n return ` ${field.key}: 0`;\n case 'boolean':\n return ` ${field.key}: true`;\n case 'string':\n default:\n return ` ${field.key}: '${field.key.toUpperCase()}_VALUE'`;\n }\n });\n\n return `{\n${exampleEntries.join(',\\n')}\n }`;\n}\n\nexport function renderSecretExample(\n fields: IntegrationSecretFieldData[]\n): string {\n if (fields.length === 0) {\n return `{}`;\n }\n\n const exampleEntries = fields.map(\n (field) => ` ${field.key}: '${field.key.toUpperCase()}_SECRET'`\n );\n\n return `{\n${exampleEntries.join(',\\n')}\n }`;\n}\n\nexport function renderConstraints(rpm?: number, rph?: number): string {\n if (rpm == null && rph == null) return '';\n const entries: string[] = [];\n if (rpm != null) entries.push(` rpm: ${rpm}`);\n if (rph != null) entries.push(` rph: ${rph}`);\n return ` constraints: {\n rateLimit: {\n${entries.join(',\\n')}\n },\n },\n`;\n}\n\nexport function renderByokSetup(\n modes: string[],\n instructions?: string,\n scopes?: string[]\n): string {\n if (!modes.includes('byok')) {\n return '';\n }\n\n const instructionsLine = instructions\n ? ` setupInstructions: '${escape(instructions)}',\\n`\n : '';\n const scopesLine =\n scopes && scopes.length\n ? ` requiredScopes: [${scopes\n .map((scope) => `'${escape(scope)}'`)\n .join(', ')}],\\n`\n : '';\n\n if (!instructionsLine && !scopesLine) {\n return '';\n }\n\n return ` byokSetup: {\n${instructionsLine}${scopesLine} },\n`;\n}\n\nexport function mapConfigType(\n type: IntegrationConfigFieldData['type']\n): string {\n switch (type) {\n case 'number':\n return 'number';\n case 'boolean':\n return 'boolean';\n case 'string':\n default:\n return 'string';\n }\n}\n\nexport function stabilityToEnum(stability: Stability): string {\n switch (stability) {\n case 'beta':\n return 'Beta';\n case 'stable':\n return 'Stable';\n case 'deprecated':\n return 'Deprecated';\n case 'experimental':\n default:\n return 'Experimental';\n }\n}\n\nexport function renderProvides(data: IntegrationSpecData): string {\n return data.capabilitiesProvided\n .map((cap) => ` { key: '${cap.key}', version: ${cap.version} }`)\n .join(',\\n');\n}\n\nexport function renderRequires(data: IntegrationSpecData): string {\n if (data.capabilitiesRequired.length === 0) return '';\n\n return ` requires: [\n${data.capabilitiesRequired\n .map((req) => {\n const version =\n typeof req.version === 'number' ? `, version: ${req.version}` : '';\n const optional = req.optional ? ', optional: true' : '';\n const reason = req.reason ? `, reason: '${escape(req.reason)}'` : '';\n return ` { key: '${req.key}'${version}${optional}${reason} }`;\n })\n .join(',\\n')}\n ],`;\n}\n\nexport function escape(value: string): string {\n return value.replace(/`/g, '\\\\`').replace(/'/g, \"\\\\'\");\n}\n"],"mappings":";AAOA,SAAgB,mBACd,QACQ;CACR,MAAM,iBAAiB,OAAO,QAAQ,UAAU,MAAM,SAAS;AAsB/D,QAAO;;EApBL,eAAe,SAAS,IACpB,oBAAoB,eACjB,KAAK,UAAU,IAAI,MAAM,IAAI,GAAG,CAChC,KAAK,KAAK,CAAC;IAEd,GAiBQ;GAfK,OAAO,SACtB,OACG,KAAK,UAAU;EACd,MAAM,cAAc,MAAM,cACtB,mBAAmB,OAAO,MAAM,YAAY,CAAC,KAC7C;AACJ,SAAO,WAAW,MAAM,IAAI,aAAa,cACvC,MAAM,KACP,CAAC,GAAG,YAAY;GACjB,CACD,KAAK,MAAM,GACd,OAKU,SAAS;;;;AAKzB,SAAgB,mBACd,QACQ;CACR,MAAM,iBAAiB,OAAO,QAAQ,UAAU,MAAM,SAAS;AAoB/D,QAAO;;EAlBL,eAAe,SAAS,IACpB,oBAAoB,eACjB,KAAK,UAAU,IAAI,MAAM,IAAI,GAAG,CAChC,KAAK,KAAK,CAAC;IAEd,GAeQ;GAbK,OAAO,SACtB,OACG,KAAK,UAAU;EACd,MAAM,cAAc,MAAM,cACtB,mBAAmB,OAAO,MAAM,YAAY,CAAC,KAC7C;AACJ,SAAO,WAAW,MAAM,IAAI,oBAAoB,YAAY;GAC5D,CACD,KAAK,MAAM,GACd,OAKU,SAAS;;;;AAKzB,SAAgB,oBACd,QACQ;AACR,KAAI,OAAO,WAAW,EACpB,QAAO;AAeT,QAAO;EAZgB,OAAO,KAAK,UAAU;AAC3C,UAAQ,MAAM,MAAd;GACE,KAAK,SACH,QAAO,OAAO,MAAM,IAAI;GAC1B,KAAK,UACH,QAAO,OAAO,MAAM,IAAI;GAC1B,KAAK;GACL,QACE,QAAO,OAAO,MAAM,IAAI,KAAK,MAAM,IAAI,aAAa,CAAC;;GAEzD,CAGa,KAAK,MAAM,CAAC;;;AAI7B,SAAgB,oBACd,QACQ;AACR,KAAI,OAAO,WAAW,EACpB,QAAO;AAOT,QAAO;EAJgB,OAAO,KAC3B,UAAU,OAAO,MAAM,IAAI,KAAK,MAAM,IAAI,aAAa,CAAC,UAC1D,CAGc,KAAK,MAAM,CAAC;;;AAI7B,SAAgB,kBAAkB,KAAc,KAAsB;AACpE,KAAI,OAAO,QAAQ,OAAO,KAAM,QAAO;CACvC,MAAM,UAAoB,EAAE;AAC5B,KAAI,OAAO,KAAM,SAAQ,KAAK,cAAc,MAAM;AAClD,KAAI,OAAO,KAAM,SAAQ,KAAK,cAAc,MAAM;AAClD,QAAO;;EAEP,QAAQ,KAAK,MAAM,CAAC;;;;;AAMtB,SAAgB,gBACd,OACA,cACA,QACQ;AACR,KAAI,CAAC,MAAM,SAAS,OAAO,CACzB,QAAO;CAGT,MAAM,mBAAmB,eACrB,2BAA2B,OAAO,aAAa,CAAC,QAChD;CACJ,MAAM,aACJ,UAAU,OAAO,SACb,wBAAwB,OACrB,KAAK,UAAU,IAAI,OAAO,MAAM,CAAC,GAAG,CACpC,KAAK,KAAK,CAAC,QACd;AAEN,KAAI,CAAC,oBAAoB,CAAC,WACxB,QAAO;AAGT,QAAO;EACP,mBAAmB,WAAW;;;AAIhC,SAAgB,cACd,MACQ;AACR,SAAQ,MAAR;EACE,KAAK,SACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK;EACL,QACE,QAAO;;;AAIb,SAAgB,gBAAgB,WAA8B;AAC5D,SAAQ,WAAR;EACE,KAAK,OACH,QAAO;EACT,KAAK,SACH,QAAO;EACT,KAAK,aACH,QAAO;EACT,KAAK;EACL,QACE,QAAO;;;AAIb,SAAgB,eAAe,MAAmC;AAChE,QAAO,KAAK,qBACT,KAAK,QAAQ,iBAAiB,IAAI,IAAI,cAAc,IAAI,QAAQ,IAAI,CACpE,KAAK,MAAM;;AAGhB,SAAgB,eAAe,MAAmC;AAChE,KAAI,KAAK,qBAAqB,WAAW,EAAG,QAAO;AAEnD,QAAO;EACP,KAAK,qBACJ,KAAK,QAAQ;EACZ,MAAM,UACJ,OAAO,IAAI,YAAY,WAAW,cAAc,IAAI,YAAY;EAClE,MAAM,WAAW,IAAI,WAAW,qBAAqB;EACrD,MAAM,SAAS,IAAI,SAAS,cAAc,OAAO,IAAI,OAAO,CAAC,KAAK;AAClE,SAAO,iBAAiB,IAAI,IAAI,GAAG,UAAU,WAAW,OAAO;GAC/D,CACD,KAAK,MAAM,CAAC;;;AAIf,SAAgB,OAAO,OAAuB;AAC5C,QAAO,MAAM,QAAQ,MAAM,MAAM,CAAC,QAAQ,MAAM,MAAM"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { IntegrationSpecData } from "../types/spec-types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/templates/integration.d.ts
|
|
4
|
+
declare function generateIntegrationSpec(data: IntegrationSpecData): string;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { generateIntegrationSpec };
|
|
7
|
+
//# sourceMappingURL=integration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.d.ts","names":[],"sources":["../../src/templates/integration.ts"],"sourcesContent":[],"mappings":";;;iBAegB,uBAAA,OAA8B"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { toPascalCase } from "./utils.js";
|
|
2
|
+
import { escape, renderByokSetup, renderConfigExample, renderConfigSchema, renderConstraints, renderProvides, renderRequires, renderSecretExample, renderSecretSchema, stabilityToEnum } from "./integration-utils.js";
|
|
3
|
+
|
|
4
|
+
//#region src/templates/integration.ts
|
|
5
|
+
function generateIntegrationSpec(data) {
|
|
6
|
+
const specName = toPascalCase(data.name.split(".").pop() ?? "Integration");
|
|
7
|
+
const varName = `${specName}IntegrationSpec`;
|
|
8
|
+
const registerFn = `register${specName}Integration`;
|
|
9
|
+
const supportedModes = data.supportedModes.length ? data.supportedModes : ["managed"];
|
|
10
|
+
const supportedModesLine = supportedModes.map((mode) => `'${mode}'`).join(", ");
|
|
11
|
+
const provides = renderProvides(data);
|
|
12
|
+
const requires = renderRequires(data);
|
|
13
|
+
const configSchema = renderConfigSchema(data.configFields);
|
|
14
|
+
const configExample = renderConfigExample(data.configFields);
|
|
15
|
+
const secretSchema = renderSecretSchema(data.secretFields);
|
|
16
|
+
const secretExample = renderSecretExample(data.secretFields);
|
|
17
|
+
const docsUrl = data.docsUrl ? ` docsUrl: '${escape(data.docsUrl)}',\n` : "";
|
|
18
|
+
const constraints = renderConstraints(data.rateLimitRpm, data.rateLimitRph);
|
|
19
|
+
const byokSetup = renderByokSetup(supportedModes, data.byokSetupInstructions, data.byokRequiredScopes);
|
|
20
|
+
return `import { StabilityEnum, defineIntegration } from '@contractspec/lib.contracts';
|
|
21
|
+
import type { IntegrationSpecRegistry } from '@contractspec/lib.contracts/integrations/spec';
|
|
22
|
+
|
|
23
|
+
export const ${varName} = defineIntegration({
|
|
24
|
+
meta: {
|
|
25
|
+
key: '${escape(data.name)}',
|
|
26
|
+
version: ${data.version},
|
|
27
|
+
category: '${data.category}',
|
|
28
|
+
displayName: '${escape(data.displayName)}',
|
|
29
|
+
title: '${escape(data.title)}',
|
|
30
|
+
description: '${escape(data.description)}',
|
|
31
|
+
domain: '${escape(data.domain)}',
|
|
32
|
+
owners: [${data.owners.map((owner) => `'${escape(owner)}'`).join(", ")}],
|
|
33
|
+
tags: [${data.tags.map((tag) => `'${escape(tag)}'`).join(", ")}],
|
|
34
|
+
stability: StabilityEnum.${stabilityToEnum(data.stability)},
|
|
35
|
+
},
|
|
36
|
+
supportedModes: [${supportedModesLine}],
|
|
37
|
+
capabilities: {
|
|
38
|
+
provides: [
|
|
39
|
+
${provides}
|
|
40
|
+
],
|
|
41
|
+
${requires.length > 0 ? `${requires}\n` : ""} },
|
|
42
|
+
configSchema: {
|
|
43
|
+
${configSchema} example: ${configExample},
|
|
44
|
+
},
|
|
45
|
+
secretSchema: {
|
|
46
|
+
${secretSchema} example: ${secretExample},
|
|
47
|
+
},
|
|
48
|
+
${docsUrl}${constraints}${byokSetup} healthCheck: {
|
|
49
|
+
method: '${data.healthCheckMethod}',
|
|
50
|
+
timeoutMs: ${data.healthCheckTimeoutMs ?? 5e3},
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export function ${registerFn}(registry: IntegrationSpecRegistry): IntegrationSpecRegistry {
|
|
55
|
+
return registry.register(${varName});
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
export { generateIntegrationSpec };
|
|
62
|
+
//# sourceMappingURL=integration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.js","names":[],"sources":["../../src/templates/integration.ts"],"sourcesContent":["import type { IntegrationSpecData } from '../types/spec-types';\nimport { toPascalCase } from './utils';\nimport {\n escape,\n renderByokSetup,\n renderConfigExample,\n renderConfigSchema,\n renderConstraints,\n renderProvides,\n renderRequires,\n renderSecretExample,\n renderSecretSchema,\n stabilityToEnum,\n} from './integration-utils';\n\nexport function generateIntegrationSpec(data: IntegrationSpecData): string {\n const specName = toPascalCase(data.name.split('.').pop() ?? 'Integration');\n const varName = `${specName}IntegrationSpec`;\n const registerFn = `register${specName}Integration`;\n\n const supportedModes = data.supportedModes.length\n ? data.supportedModes\n : ['managed'];\n const supportedModesLine = supportedModes\n .map((mode) => `'${mode}'`)\n .join(', ');\n\n const provides = renderProvides(data);\n const requires = renderRequires(data);\n\n const configSchema = renderConfigSchema(data.configFields);\n const configExample = renderConfigExample(data.configFields);\n const secretSchema = renderSecretSchema(data.secretFields);\n const secretExample = renderSecretExample(data.secretFields);\n const docsUrl = data.docsUrl ? ` docsUrl: '${escape(data.docsUrl)}',\\n` : '';\n const constraints = renderConstraints(data.rateLimitRpm, data.rateLimitRph);\n const byokSetup = renderByokSetup(\n supportedModes,\n data.byokSetupInstructions,\n data.byokRequiredScopes\n );\n\n return `import { StabilityEnum, defineIntegration } from '@contractspec/lib.contracts';\nimport type { IntegrationSpecRegistry } from '@contractspec/lib.contracts/integrations/spec';\n\nexport const ${varName} = defineIntegration({\n meta: {\n key: '${escape(data.name)}',\n version: ${data.version},\n category: '${data.category}',\n displayName: '${escape(data.displayName)}',\n title: '${escape(data.title)}',\n description: '${escape(data.description)}',\n domain: '${escape(data.domain)}',\n owners: [${data.owners.map((owner) => `'${escape(owner)}'`).join(', ')}],\n tags: [${data.tags.map((tag) => `'${escape(tag)}'`).join(', ')}],\n stability: StabilityEnum.${stabilityToEnum(data.stability)},\n },\n supportedModes: [${supportedModesLine}],\n capabilities: {\n provides: [\n${provides}\n ],\n${requires.length > 0 ? `${requires}\\n` : ''} },\n configSchema: {\n${configSchema} example: ${configExample},\n },\n secretSchema: {\n${secretSchema} example: ${secretExample},\n },\n${docsUrl}${constraints}${byokSetup} healthCheck: {\n method: '${data.healthCheckMethod}',\n timeoutMs: ${data.healthCheckTimeoutMs ?? 5000},\n },\n});\n\nexport function ${registerFn}(registry: IntegrationSpecRegistry): IntegrationSpecRegistry {\n return registry.register(${varName});\n}\n`;\n}\n"],"mappings":";;;;AAeA,SAAgB,wBAAwB,MAAmC;CACzE,MAAM,WAAW,aAAa,KAAK,KAAK,MAAM,IAAI,CAAC,KAAK,IAAI,cAAc;CAC1E,MAAM,UAAU,GAAG,SAAS;CAC5B,MAAM,aAAa,WAAW,SAAS;CAEvC,MAAM,iBAAiB,KAAK,eAAe,SACvC,KAAK,iBACL,CAAC,UAAU;CACf,MAAM,qBAAqB,eACxB,KAAK,SAAS,IAAI,KAAK,GAAG,CAC1B,KAAK,KAAK;CAEb,MAAM,WAAW,eAAe,KAAK;CACrC,MAAM,WAAW,eAAe,KAAK;CAErC,MAAM,eAAe,mBAAmB,KAAK,aAAa;CAC1D,MAAM,gBAAgB,oBAAoB,KAAK,aAAa;CAC5D,MAAM,eAAe,mBAAmB,KAAK,aAAa;CAC1D,MAAM,gBAAgB,oBAAoB,KAAK,aAAa;CAC5D,MAAM,UAAU,KAAK,UAAU,eAAe,OAAO,KAAK,QAAQ,CAAC,QAAQ;CAC3E,MAAM,cAAc,kBAAkB,KAAK,cAAc,KAAK,aAAa;CAC3E,MAAM,YAAY,gBAChB,gBACA,KAAK,uBACL,KAAK,mBACN;AAED,QAAO;;;eAGM,QAAQ;;YAEX,OAAO,KAAK,KAAK,CAAC;eACf,KAAK,QAAQ;iBACX,KAAK,SAAS;oBACX,OAAO,KAAK,YAAY,CAAC;cAC/B,OAAO,KAAK,MAAM,CAAC;oBACb,OAAO,KAAK,YAAY,CAAC;eAC9B,OAAO,KAAK,OAAO,CAAC;eACpB,KAAK,OAAO,KAAK,UAAU,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC;aAC9D,KAAK,KAAK,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC;+BACpC,gBAAgB,KAAK,UAAU,CAAC;;qBAE1C,mBAAmB;;;EAGtC,SAAS;;EAET,SAAS,SAAS,IAAI,GAAG,SAAS,MAAM,GAAG;;EAE3C,aAAa,eAAe,cAAc;;;EAG1C,aAAa,eAAe,cAAc;;EAE1C,UAAU,cAAc,UAAU;eACrB,KAAK,kBAAkB;iBACrB,KAAK,wBAAwB,IAAK;;;;kBAIjC,WAAW;6BACA,QAAQ"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { KnowledgeSpaceSpecData } from "../types/spec-types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/templates/knowledge.d.ts
|
|
4
|
+
declare function generateKnowledgeSpaceSpec(data: KnowledgeSpaceSpecData): string;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { generateKnowledgeSpaceSpec };
|
|
7
|
+
//# sourceMappingURL=knowledge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge.d.ts","names":[],"sources":["../../src/templates/knowledge.ts"],"sourcesContent":[],"mappings":";;;iBAGgB,0BAAA,OACR"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { escapeString, toPascalCase } from "./utils.js";
|
|
2
|
+
|
|
3
|
+
//#region src/templates/knowledge.ts
|
|
4
|
+
function generateKnowledgeSpaceSpec(data) {
|
|
5
|
+
const specName = toPascalCase(data.name.split(".").pop() ?? "KnowledgeSpace");
|
|
6
|
+
const varName = `${specName}KnowledgeSpace`;
|
|
7
|
+
const registerFn = `register${specName}KnowledgeSpace`;
|
|
8
|
+
const retention = renderRetention(data);
|
|
9
|
+
const access = renderAccess(data);
|
|
10
|
+
const indexing = renderIndexing(data);
|
|
11
|
+
const policyComment = data.policyName && !data.policyVersion ? ` // defaults to latest version` : "";
|
|
12
|
+
return `import { StabilityEnum } from '@contractspec/lib.contracts/ownership';
|
|
13
|
+
import type { KnowledgeSpaceSpec } from '@contractspec/lib.contracts/knowledge/spec';
|
|
14
|
+
import type { KnowledgeSpaceRegistry } from '@contractspec/lib.contracts/knowledge/spec';
|
|
15
|
+
|
|
16
|
+
export const ${varName}: KnowledgeSpaceSpec = {
|
|
17
|
+
meta: {
|
|
18
|
+
key: '${escapeString(data.name)}',
|
|
19
|
+
version: ${data.version},
|
|
20
|
+
category: '${data.category}',
|
|
21
|
+
displayName: '${escape(data.displayName)}',
|
|
22
|
+
title: '${escape(data.title)}',
|
|
23
|
+
description: '${escape(data.description)}',
|
|
24
|
+
domain: '${escape(data.domain)}',
|
|
25
|
+
owners: [${data.owners.map((owner) => `'${escapeString(owner)}'`).join(", ")}],
|
|
26
|
+
tags: [${data.tags.map((tag) => `'${escapeString(tag)}'`).join(", ")}],
|
|
27
|
+
stability: StabilityEnum.${stabilityToEnum(data.stability)},
|
|
28
|
+
},
|
|
29
|
+
retention: ${retention},
|
|
30
|
+
access: {
|
|
31
|
+
${access}${data.policyName ? ` policy: { name: '${escapeString(data.policyName)}',${data.policyVersion ? ` version: ${data.policyVersion}` : ""} },${policyComment}\n` : ""} },
|
|
32
|
+
${indexing} description: '${escape(data.description || data.displayName)}',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export function ${registerFn}(registry: KnowledgeSpaceRegistry): KnowledgeSpaceRegistry {
|
|
36
|
+
return registry.register(${varName});
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
39
|
+
}
|
|
40
|
+
function renderRetention(data) {
|
|
41
|
+
return `{ ttlDays: ${data.retention.ttlDays === null ? "null" : typeof data.retention.ttlDays === "number" ? String(data.retention.ttlDays) : "null"}${typeof data.retention.archiveAfterDays === "number" ? `, archiveAfterDays: ${data.retention.archiveAfterDays}` : ""} }`;
|
|
42
|
+
}
|
|
43
|
+
function renderAccess(data) {
|
|
44
|
+
return `${` trustLevel: '${data.trustLevel}',\n`}${` automationWritable: ${data.automationWritable},\n`}`;
|
|
45
|
+
}
|
|
46
|
+
function renderIndexing(data) {
|
|
47
|
+
const entries = [];
|
|
48
|
+
if (data.embeddingModel) entries.push(` embeddingModel: '${escape(data.embeddingModel)}'`);
|
|
49
|
+
if (typeof data.chunkSize === "number") entries.push(` chunkSize: ${data.chunkSize}`);
|
|
50
|
+
if (data.vectorDbIntegration) entries.push(` vectorDbIntegration: '${escape(data.vectorDbIntegration)}'`);
|
|
51
|
+
if (entries.length === 0) return "";
|
|
52
|
+
return ` indexing: {\n${entries.join(",\n")}\n },\n`;
|
|
53
|
+
}
|
|
54
|
+
function stabilityToEnum(stability) {
|
|
55
|
+
switch (stability) {
|
|
56
|
+
case "beta": return "Beta";
|
|
57
|
+
case "stable": return "Stable";
|
|
58
|
+
case "deprecated": return "Deprecated";
|
|
59
|
+
case "experimental":
|
|
60
|
+
default: return "Experimental";
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function escape(value) {
|
|
64
|
+
return value.replace(/`/g, "\\`").replace(/'/g, "\\'");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
//#endregion
|
|
68
|
+
export { generateKnowledgeSpaceSpec };
|
|
69
|
+
//# sourceMappingURL=knowledge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge.js","names":[],"sources":["../../src/templates/knowledge.ts"],"sourcesContent":["import type { KnowledgeSpaceSpecData, Stability } from '../types/spec-types';\nimport { toPascalCase, escapeString } from './utils';\n\nexport function generateKnowledgeSpaceSpec(\n data: KnowledgeSpaceSpecData\n): string {\n const specName = toPascalCase(data.name.split('.').pop() ?? 'KnowledgeSpace');\n const varName = `${specName}KnowledgeSpace`;\n const registerFn = `register${specName}KnowledgeSpace`;\n\n const retention = renderRetention(data);\n const access = renderAccess(data);\n const indexing = renderIndexing(data);\n const policyComment =\n data.policyName && !data.policyVersion\n ? ` // defaults to latest version`\n : '';\n\n return `import { StabilityEnum } from '@contractspec/lib.contracts/ownership';\nimport type { KnowledgeSpaceSpec } from '@contractspec/lib.contracts/knowledge/spec';\nimport type { KnowledgeSpaceRegistry } from '@contractspec/lib.contracts/knowledge/spec';\n\nexport const ${varName}: KnowledgeSpaceSpec = {\n meta: {\n key: '${escapeString(data.name)}',\n version: ${data.version},\n category: '${data.category}',\n displayName: '${escape(data.displayName)}',\n title: '${escape(data.title)}',\n description: '${escape(data.description)}',\n domain: '${escape(data.domain)}',\n owners: [${data.owners.map((owner) => `'${escapeString(owner)}'`).join(', ')}],\n tags: [${data.tags.map((tag) => `'${escapeString(tag)}'`).join(', ')}],\n stability: StabilityEnum.${stabilityToEnum(data.stability)},\n },\n retention: ${retention},\n access: {\n${access}${data.policyName ? ` policy: { name: '${escapeString(data.policyName)}',${data.policyVersion ? ` version: ${data.policyVersion}` : ''} },${policyComment}\\n` : ''} },\n${indexing} description: '${escape(data.description || data.displayName)}',\n};\n\nexport function ${registerFn}(registry: KnowledgeSpaceRegistry): KnowledgeSpaceRegistry {\n return registry.register(${varName});\n}\n`;\n}\n\nfunction renderRetention(data: KnowledgeSpaceSpecData): string {\n const ttl =\n data.retention.ttlDays === null\n ? 'null'\n : typeof data.retention.ttlDays === 'number'\n ? String(data.retention.ttlDays)\n : 'null';\n const archive =\n typeof data.retention.archiveAfterDays === 'number'\n ? `, archiveAfterDays: ${data.retention.archiveAfterDays}`\n : '';\n return `{ ttlDays: ${ttl}${archive} }`;\n}\n\nfunction renderAccess(data: KnowledgeSpaceSpecData): string {\n const trustLine = ` trustLevel: '${data.trustLevel}',\\n`;\n const automationLine = ` automationWritable: ${data.automationWritable},\\n`;\n return `${trustLine}${automationLine}`;\n}\n\nfunction renderIndexing(data: KnowledgeSpaceSpecData): string {\n const entries: string[] = [];\n if (data.embeddingModel) {\n entries.push(` embeddingModel: '${escape(data.embeddingModel)}'`);\n }\n if (typeof data.chunkSize === 'number') {\n entries.push(` chunkSize: ${data.chunkSize}`);\n }\n if (data.vectorDbIntegration) {\n entries.push(\n ` vectorDbIntegration: '${escape(data.vectorDbIntegration)}'`\n );\n }\n if (entries.length === 0) {\n return '';\n }\n return ` indexing: {\\n${entries.join(',\\n')}\\n },\\n`;\n}\n\nfunction stabilityToEnum(stability: Stability): string {\n switch (stability) {\n case 'beta':\n return 'Beta';\n case 'stable':\n return 'Stable';\n case 'deprecated':\n return 'Deprecated';\n case 'experimental':\n default:\n return 'Experimental';\n }\n}\n\nfunction escape(value: string): string {\n return value.replace(/`/g, '\\\\`').replace(/'/g, \"\\\\'\");\n}\n"],"mappings":";;;AAGA,SAAgB,2BACd,MACQ;CACR,MAAM,WAAW,aAAa,KAAK,KAAK,MAAM,IAAI,CAAC,KAAK,IAAI,iBAAiB;CAC7E,MAAM,UAAU,GAAG,SAAS;CAC5B,MAAM,aAAa,WAAW,SAAS;CAEvC,MAAM,YAAY,gBAAgB,KAAK;CACvC,MAAM,SAAS,aAAa,KAAK;CACjC,MAAM,WAAW,eAAe,KAAK;CACrC,MAAM,gBACJ,KAAK,cAAc,CAAC,KAAK,gBACrB,mCACA;AAEN,QAAO;;;;eAIM,QAAQ;;YAEX,aAAa,KAAK,KAAK,CAAC;eACrB,KAAK,QAAQ;iBACX,KAAK,SAAS;oBACX,OAAO,KAAK,YAAY,CAAC;cAC/B,OAAO,KAAK,MAAM,CAAC;oBACb,OAAO,KAAK,YAAY,CAAC;eAC9B,OAAO,KAAK,OAAO,CAAC;eACpB,KAAK,OAAO,KAAK,UAAU,IAAI,aAAa,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC;aACpE,KAAK,KAAK,KAAK,QAAQ,IAAI,aAAa,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC;+BAC1C,gBAAgB,KAAK,UAAU,CAAC;;eAEhD,UAAU;;EAEvB,SAAS,KAAK,aAAa,wBAAwB,aAAa,KAAK,WAAW,CAAC,IAAI,KAAK,gBAAgB,aAAa,KAAK,kBAAkB,GAAG,KAAK,cAAc,MAAM,GAAG;EAC7K,SAAS,kBAAkB,OAAO,KAAK,eAAe,KAAK,YAAY,CAAC;;;kBAGxD,WAAW;6BACA,QAAQ;;;;AAKrC,SAAS,gBAAgB,MAAsC;AAW7D,QAAO,cATL,KAAK,UAAU,YAAY,OACvB,SACA,OAAO,KAAK,UAAU,YAAY,WAChC,OAAO,KAAK,UAAU,QAAQ,GAC9B,SAEN,OAAO,KAAK,UAAU,qBAAqB,WACvC,uBAAuB,KAAK,UAAU,qBACtC,GAC6B;;AAGrC,SAAS,aAAa,MAAsC;AAG1D,QAAO,GAFW,oBAAoB,KAAK,WAAW,QAC/B,2BAA2B,KAAK,mBAAmB;;AAI5E,SAAS,eAAe,MAAsC;CAC5D,MAAM,UAAoB,EAAE;AAC5B,KAAI,KAAK,eACP,SAAQ,KAAK,wBAAwB,OAAO,KAAK,eAAe,CAAC,GAAG;AAEtE,KAAI,OAAO,KAAK,cAAc,SAC5B,SAAQ,KAAK,kBAAkB,KAAK,YAAY;AAElD,KAAI,KAAK,oBACP,SAAQ,KACN,6BAA6B,OAAO,KAAK,oBAAoB,CAAC,GAC/D;AAEH,KAAI,QAAQ,WAAW,EACrB,QAAO;AAET,QAAO,kBAAkB,QAAQ,KAAK,MAAM,CAAC;;AAG/C,SAAS,gBAAgB,WAA8B;AACrD,SAAQ,WAAR;EACE,KAAK,OACH,QAAO;EACT,KAAK,SACH,QAAO;EACT,KAAK,aACH,QAAO;EACT,KAAK;EACL,QACE,QAAO;;;AAIb,SAAS,OAAO,OAAuB;AACrC,QAAO,MAAM,QAAQ,MAAM,MAAM,CAAC,QAAQ,MAAM,MAAM"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { MigrationSpecData } from "../types/spec-types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/templates/migration.d.ts
|
|
4
|
+
declare function generateMigrationSpec(data: MigrationSpecData): string;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { generateMigrationSpec };
|
|
7
|
+
//# sourceMappingURL=migration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.d.ts","names":[],"sources":["../../src/templates/migration.ts"],"sourcesContent":[],"mappings":";;;iBAGgB,qBAAA,OAA4B"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { escapeString, toPascalCase } from "./utils.js";
|
|
2
|
+
|
|
3
|
+
//#region src/templates/migration.ts
|
|
4
|
+
function generateMigrationSpec(data) {
|
|
5
|
+
const migrationVar = `${toPascalCase(data.name.split(".").pop() ?? "Migration")}Migration`;
|
|
6
|
+
const dependencies = data.dependencies.length > 0 ? `dependencies: [${data.dependencies.map((dep) => `'${escapeString(dep)}'`).join(", ")}],` : "";
|
|
7
|
+
return `import type { MigrationSpec } from '@contractspec/lib.contracts/migrations';
|
|
8
|
+
|
|
9
|
+
export const ${migrationVar}: MigrationSpec = {
|
|
10
|
+
meta: {
|
|
11
|
+
key: '${escapeString(data.name)}',
|
|
12
|
+
version: ${data.version},
|
|
13
|
+
title: '${escape(data.title)}',
|
|
14
|
+
description: '${escape(data.description ?? "")}',
|
|
15
|
+
domain: '${escape(data.domain)}',
|
|
16
|
+
owners: [${data.owners.map((owner) => `'${escapeString(owner)}'`).join(", ")}],
|
|
17
|
+
tags: [${data.tags.map((tag) => `'${escapeString(tag)}'`).join(", ")}],
|
|
18
|
+
stability: '${data.stability}',
|
|
19
|
+
},
|
|
20
|
+
plan: {
|
|
21
|
+
up: [
|
|
22
|
+
${renderSteps(data.up)}
|
|
23
|
+
],${data.down && data.down.length ? `
|
|
24
|
+
down: [
|
|
25
|
+
${renderSteps(data.down)}
|
|
26
|
+
],` : ""}
|
|
27
|
+
},
|
|
28
|
+
${dependencies}
|
|
29
|
+
};
|
|
30
|
+
`;
|
|
31
|
+
}
|
|
32
|
+
function renderSteps(steps) {
|
|
33
|
+
return steps.map((step) => {
|
|
34
|
+
const description = step.description ? `description: '${escape(step.description)}',` : "";
|
|
35
|
+
switch (step.kind) {
|
|
36
|
+
case "schema": return ` {
|
|
37
|
+
kind: 'schema',
|
|
38
|
+
${description}
|
|
39
|
+
sql: \`${escape(step.sql ?? "")}\`,
|
|
40
|
+
}`;
|
|
41
|
+
case "data": return ` {
|
|
42
|
+
kind: 'data',
|
|
43
|
+
${description}
|
|
44
|
+
script: \`${escape(step.script ?? "")}\`,
|
|
45
|
+
}`;
|
|
46
|
+
case "validation":
|
|
47
|
+
default: return ` {
|
|
48
|
+
kind: 'validation',
|
|
49
|
+
${description}
|
|
50
|
+
assertion: \`${escape(step.assertion ?? "")}\`,
|
|
51
|
+
}`;
|
|
52
|
+
}
|
|
53
|
+
}).join(",\n");
|
|
54
|
+
}
|
|
55
|
+
function escape(value) {
|
|
56
|
+
return value.replace(/`/g, "\\`").replace(/'/g, "\\'");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
//#endregion
|
|
60
|
+
export { generateMigrationSpec };
|
|
61
|
+
//# sourceMappingURL=migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration.js","names":[],"sources":["../../src/templates/migration.ts"],"sourcesContent":["import type { MigrationSpecData } from '../types/spec-types';\nimport { toPascalCase, escapeString } from './utils';\n\nexport function generateMigrationSpec(data: MigrationSpecData): string {\n const specName = toPascalCase(data.name.split('.').pop() ?? 'Migration');\n const migrationVar = `${specName}Migration`;\n\n const dependencies =\n data.dependencies.length > 0\n ? `dependencies: [${data.dependencies\n .map((dep) => `'${escapeString(dep)}'`)\n .join(', ')}],`\n : '';\n\n return `import type { MigrationSpec } from '@contractspec/lib.contracts/migrations';\n\nexport const ${migrationVar}: MigrationSpec = {\n meta: {\n key: '${escapeString(data.name)}',\n version: ${data.version},\n title: '${escape(data.title)}',\n description: '${escape(data.description ?? '')}',\n domain: '${escape(data.domain)}',\n owners: [${data.owners.map((owner) => `'${escapeString(owner)}'`).join(', ')}],\n tags: [${data.tags.map((tag) => `'${escapeString(tag)}'`).join(', ')}],\n stability: '${data.stability}',\n },\n plan: {\n up: [\n${renderSteps(data.up)}\n ],${\n data.down && data.down.length\n ? `\n down: [\n${renderSteps(data.down)}\n ],`\n : ''\n }\n },\n ${dependencies}\n};\n`;\n}\n\nfunction renderSteps(steps: MigrationSpecData['up']) {\n return steps\n .map((step) => {\n const description = step.description\n ? `description: '${escape(step.description)}',`\n : '';\n switch (step.kind) {\n case 'schema':\n return ` {\n kind: 'schema',\n ${description}\n sql: \\`${escape(step.sql ?? '')}\\`,\n }`;\n case 'data':\n return ` {\n kind: 'data',\n ${description}\n script: \\`${escape(step.script ?? '')}\\`,\n }`;\n case 'validation':\n default:\n return ` {\n kind: 'validation',\n ${description}\n assertion: \\`${escape(step.assertion ?? '')}\\`,\n }`;\n }\n })\n .join(',\\n');\n}\n\nfunction escape(value: string): string {\n return value.replace(/`/g, '\\\\`').replace(/'/g, \"\\\\'\");\n}\n"],"mappings":";;;AAGA,SAAgB,sBAAsB,MAAiC;CAErE,MAAM,eAAe,GADJ,aAAa,KAAK,KAAK,MAAM,IAAI,CAAC,KAAK,IAAI,YAAY,CACvC;CAEjC,MAAM,eACJ,KAAK,aAAa,SAAS,IACvB,kBAAkB,KAAK,aACpB,KAAK,QAAQ,IAAI,aAAa,IAAI,CAAC,GAAG,CACtC,KAAK,KAAK,CAAC,MACd;AAEN,QAAO;;eAEM,aAAa;;YAEhB,aAAa,KAAK,KAAK,CAAC;eACrB,KAAK,QAAQ;cACd,OAAO,KAAK,MAAM,CAAC;oBACb,OAAO,KAAK,eAAe,GAAG,CAAC;eACpC,OAAO,KAAK,OAAO,CAAC;eACpB,KAAK,OAAO,KAAK,UAAU,IAAI,aAAa,MAAM,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC;aACpE,KAAK,KAAK,KAAK,QAAQ,IAAI,aAAa,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC;kBACvD,KAAK,UAAU;;;;EAI/B,YAAY,KAAK,GAAG,CAAC;QAEjB,KAAK,QAAQ,KAAK,KAAK,SACnB;;EAER,YAAY,KAAK,KAAK,CAAC;UAEf,GACL;;IAED,aAAa;;;;AAKjB,SAAS,YAAY,OAAgC;AACnD,QAAO,MACJ,KAAK,SAAS;EACb,MAAM,cAAc,KAAK,cACrB,iBAAiB,OAAO,KAAK,YAAY,CAAC,MAC1C;AACJ,UAAQ,KAAK,MAAb;GACE,KAAK,SACH,QAAO;;UAEP,YAAY;iBACL,OAAO,KAAK,OAAO,GAAG,CAAC;;GAEhC,KAAK,OACH,QAAO;;UAEP,YAAY;oBACF,OAAO,KAAK,UAAU,GAAG,CAAC;;GAEtC,KAAK;GACL,QACE,QAAO;;UAEP,YAAY;uBACC,OAAO,KAAK,aAAa,GAAG,CAAC;;;GAG9C,CACD,KAAK,MAAM;;AAGhB,SAAS,OAAO,OAAuB;AACrC,QAAO,MAAM,QAAQ,MAAM,MAAM,CAAC,QAAQ,MAAM,MAAM"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { OperationSpecData } from "../types/spec-types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/templates/operation.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generate operation spec TypeScript code.
|
|
7
|
+
*/
|
|
8
|
+
declare function generateOperationSpec(data: OperationSpecData): string;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { generateOperationSpec };
|
|
11
|
+
//# sourceMappingURL=operation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation.d.ts","names":[],"sources":["../../src/templates/operation.ts"],"sourcesContent":[],"mappings":";;;;;;;iBAWgB,qBAAA,OAA4B"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { capitalize, toPascalCase } from "./utils.js";
|
|
2
|
+
|
|
3
|
+
//#region src/templates/operation.ts
|
|
4
|
+
/**
|
|
5
|
+
* Generate operation spec TypeScript code.
|
|
6
|
+
*/
|
|
7
|
+
function generateOperationSpec(data) {
|
|
8
|
+
const { name, version, kind, description, goal, context, stability, owners, tags, auth, flags } = data;
|
|
9
|
+
const specVarName = toPascalCase(name.split(".").pop() ?? "Unknown") + "Spec";
|
|
10
|
+
const inputSchemaName = specVarName.replace("Spec", "Input");
|
|
11
|
+
const outputSchemaName = specVarName.replace("Spec", "Output");
|
|
12
|
+
return `import { define${capitalize(kind)} } from '@contractspec/lib.contracts';
|
|
13
|
+
import { ScalarTypeEnum, SchemaModel } from '@contractspec/lib.schema';
|
|
14
|
+
|
|
15
|
+
// TODO: Define input schema
|
|
16
|
+
export const ${inputSchemaName} = new SchemaModel({
|
|
17
|
+
name: '${inputSchemaName}',
|
|
18
|
+
description: 'Input for ${name}',
|
|
19
|
+
fields: {
|
|
20
|
+
// Add your fields here
|
|
21
|
+
// example: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// TODO: Define output schema
|
|
26
|
+
export const ${outputSchemaName} = new SchemaModel({
|
|
27
|
+
name: '${outputSchemaName}',
|
|
28
|
+
description: 'Output for ${name}',
|
|
29
|
+
fields: {
|
|
30
|
+
// Add your fields here
|
|
31
|
+
ok: { type: ScalarTypeEnum.Boolean(), isOptional: false },
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export const ${specVarName} = define${capitalize(kind)}({
|
|
36
|
+
meta: {
|
|
37
|
+
key: '${name}',
|
|
38
|
+
version: ${version},
|
|
39
|
+
stability: '${stability}',
|
|
40
|
+
owners: [${owners.map((o) => `'${o}'`).join(", ")}],
|
|
41
|
+
tags: [${tags.map((t) => `'${t}'`).join(", ")}],
|
|
42
|
+
description: '${description}',
|
|
43
|
+
goal: '${goal}',
|
|
44
|
+
context: '${context}',
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
io: {
|
|
48
|
+
input: ${inputSchemaName},
|
|
49
|
+
output: ${outputSchemaName},
|
|
50
|
+
errors: {
|
|
51
|
+
// Define possible errors
|
|
52
|
+
// EXAMPLE_ERROR: {
|
|
53
|
+
// description: 'Example error description',
|
|
54
|
+
// http: 400,
|
|
55
|
+
// when: 'When this error occurs',
|
|
56
|
+
// },
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
policy: {
|
|
61
|
+
auth: '${auth}',
|
|
62
|
+
${flags.length > 0 ? `flags: [${flags.map((f) => `'${f}'`).join(", ")}],` : "// flags: [],"}
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
sideEffects: {
|
|
66
|
+
${data.emitsEvents ? "emits: [\n // Define events to emit\n // { ref: SomeEventSpec, when: 'always' }\n ]," : "// emits: [],"}
|
|
67
|
+
analytics: [
|
|
68
|
+
// Define analytics events
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
transport: {
|
|
73
|
+
rest: { method: '${kind === "command" ? "POST" : "GET"}' },
|
|
74
|
+
gql: { field: '${name.replace(/\./g, "_")}' },
|
|
75
|
+
mcp: { toolName: '${name}.v${version}' },
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
acceptance: {
|
|
79
|
+
scenarios: [
|
|
80
|
+
{
|
|
81
|
+
name: 'Happy path',
|
|
82
|
+
given: ['preconditions'],
|
|
83
|
+
when: ['action taken'],
|
|
84
|
+
then: ['expected outcome'],
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
examples: [
|
|
88
|
+
{
|
|
89
|
+
name: 'Example usage',
|
|
90
|
+
input: { /* example input */ },
|
|
91
|
+
output: { ok: true },
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
//#endregion
|
|
100
|
+
export { generateOperationSpec };
|
|
101
|
+
//# sourceMappingURL=operation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation.js","names":[],"sources":["../../src/templates/operation.ts"],"sourcesContent":["/**\n * Operation spec template generation.\n * Extracted from cli-contractspec/src/templates/operation.template.ts\n */\n\nimport type { OperationSpecData } from '../types/spec-types';\nimport { toPascalCase, capitalize } from './utils';\n\n/**\n * Generate operation spec TypeScript code.\n */\nexport function generateOperationSpec(data: OperationSpecData): string {\n const {\n name,\n version,\n kind,\n description,\n goal,\n context,\n stability,\n owners,\n tags,\n auth,\n flags,\n } = data;\n\n const specVarName = toPascalCase(name.split('.').pop() ?? 'Unknown') + 'Spec';\n const inputSchemaName = specVarName.replace('Spec', 'Input');\n const outputSchemaName = specVarName.replace('Spec', 'Output');\n\n return `import { define${capitalize(kind)} } from '@contractspec/lib.contracts';\nimport { ScalarTypeEnum, SchemaModel } from '@contractspec/lib.schema';\n\n// TODO: Define input schema\nexport const ${inputSchemaName} = new SchemaModel({\n name: '${inputSchemaName}',\n description: 'Input for ${name}',\n fields: {\n // Add your fields here\n // example: { type: ScalarTypeEnum.String_unsecure(), isOptional: false },\n },\n});\n\n// TODO: Define output schema\nexport const ${outputSchemaName} = new SchemaModel({\n name: '${outputSchemaName}',\n description: 'Output for ${name}',\n fields: {\n // Add your fields here\n ok: { type: ScalarTypeEnum.Boolean(), isOptional: false },\n },\n});\n\nexport const ${specVarName} = define${capitalize(kind)}({\n meta: {\n key: '${name}',\n version: ${version},\n stability: '${stability}',\n owners: [${owners.map((o) => `'${o}'`).join(', ')}],\n tags: [${tags.map((t) => `'${t}'`).join(', ')}],\n description: '${description}',\n goal: '${goal}',\n context: '${context}',\n },\n\n io: {\n input: ${inputSchemaName},\n output: ${outputSchemaName},\n errors: {\n // Define possible errors\n // EXAMPLE_ERROR: {\n // description: 'Example error description',\n // http: 400,\n // when: 'When this error occurs',\n // },\n },\n },\n\n policy: {\n auth: '${auth}',\n ${flags.length > 0 ? `flags: [${flags.map((f) => `'${f}'`).join(', ')}],` : '// flags: [],'}\n },\n\n sideEffects: {\n ${data.emitsEvents ? \"emits: [\\n // Define events to emit\\n // { ref: SomeEventSpec, when: 'always' }\\n ],\" : '// emits: [],'}\n analytics: [\n // Define analytics events\n ],\n },\n\n transport: {\n rest: { method: '${kind === 'command' ? 'POST' : 'GET'}' },\n gql: { field: '${name.replace(/\\./g, '_')}' },\n mcp: { toolName: '${name}.v${version}' },\n },\n\n acceptance: {\n scenarios: [\n {\n name: 'Happy path',\n given: ['preconditions'],\n when: ['action taken'],\n then: ['expected outcome'],\n },\n ],\n examples: [\n {\n name: 'Example usage',\n input: { /* example input */ },\n output: { ok: true },\n },\n ],\n },\n});\n`;\n}\n"],"mappings":";;;;;;AAWA,SAAgB,sBAAsB,MAAiC;CACrE,MAAM,EACJ,MACA,SACA,MACA,aACA,MACA,SACA,WACA,QACA,MACA,MACA,UACE;CAEJ,MAAM,cAAc,aAAa,KAAK,MAAM,IAAI,CAAC,KAAK,IAAI,UAAU,GAAG;CACvE,MAAM,kBAAkB,YAAY,QAAQ,QAAQ,QAAQ;CAC5D,MAAM,mBAAmB,YAAY,QAAQ,QAAQ,SAAS;AAE9D,QAAO,kBAAkB,WAAW,KAAK,CAAC;;;;eAI7B,gBAAgB;WACpB,gBAAgB;4BACC,KAAK;;;;;;;;eAQlB,iBAAiB;WACrB,iBAAiB;6BACC,KAAK;;;;;;;eAOnB,YAAY,WAAW,WAAW,KAAK,CAAC;;YAE3C,KAAK;eACF,QAAQ;kBACL,UAAU;eACb,OAAO,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC;aACzC,KAAK,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC;oBAC9B,YAAY;aACnB,KAAK;gBACF,QAAQ;;;;aAIX,gBAAgB;cACf,iBAAiB;;;;;;;;;;;;aAYlB,KAAK;MACZ,MAAM,SAAS,IAAI,WAAW,MAAM,KAAK,MAAM,IAAI,EAAE,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,gBAAgB;;;;MAI1F,KAAK,cAAc,sGAAsG,gBAAgB;;;;;;;uBAOxH,SAAS,YAAY,SAAS,MAAM;qBACtC,KAAK,QAAQ,OAAO,IAAI,CAAC;wBACtB,KAAK,IAAI,QAAQ"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PresentationSpecData } from "../types/spec-types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/templates/presentation.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generate presentation spec TypeScript code.
|
|
7
|
+
*/
|
|
8
|
+
declare function generatePresentationSpec(data: PresentationSpecData): string;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { generatePresentationSpec };
|
|
11
|
+
//# sourceMappingURL=presentation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentation.d.ts","names":[],"sources":["../../src/templates/presentation.ts"],"sourcesContent":[],"mappings":";;;;;;;iBAWgB,wBAAA,OAA+B"}
|