@claudetools/tools 0.8.11 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/codedna/generators/astro.d.ts +18 -0
- package/dist/codedna/generators/astro.js +91 -0
- package/dist/codedna/generators/authjs.d.ts +18 -0
- package/dist/codedna/generators/authjs.js +68 -0
- package/dist/codedna/generators/better-auth.d.ts +18 -0
- package/dist/codedna/generators/better-auth.js +62 -0
- package/dist/codedna/generators/drizzle-orm.d.ts +18 -0
- package/dist/codedna/generators/drizzle-orm.js +65 -0
- package/dist/codedna/generators/elysia-api.d.ts +12 -0
- package/dist/codedna/generators/elysia-api.js +64 -0
- package/dist/codedna/generators/hono-api.d.ts +12 -0
- package/dist/codedna/generators/hono-api.js +64 -0
- package/dist/codedna/generators/lucia-auth.d.ts +18 -0
- package/dist/codedna/generators/lucia-auth.js +69 -0
- package/dist/codedna/generators/prisma.d.ts +18 -0
- package/dist/codedna/generators/prisma.js +64 -0
- package/dist/codedna/generators/react-router-v7.d.ts +18 -0
- package/dist/codedna/generators/react-router-v7.js +77 -0
- package/dist/codedna/generators/react19-shadcn.d.ts +21 -0
- package/dist/codedna/generators/react19-shadcn.js +367 -0
- package/dist/codedna/generators/sveltekit.d.ts +18 -0
- package/dist/codedna/generators/sveltekit.js +73 -0
- package/dist/codedna/generators/tanstack-start-drizzle.d.ts +92 -0
- package/dist/codedna/generators/tanstack-start-drizzle.js +824 -0
- package/dist/codedna/generators/trpc-api.d.ts +12 -0
- package/dist/codedna/generators/trpc-api.js +64 -0
- package/dist/codedna/index.d.ts +31 -0
- package/dist/codedna/index.js +39 -0
- package/dist/codedna/kappa-api-generator.d.ts +89 -0
- package/dist/codedna/kappa-api-generator.js +493 -0
- package/dist/codedna/kappa-ast.d.ts +552 -0
- package/dist/codedna/kappa-ast.js +141 -0
- package/dist/codedna/kappa-cli.d.ts +2 -0
- package/dist/codedna/kappa-cli.js +302 -0
- package/dist/codedna/kappa-component-generator.d.ts +47 -0
- package/dist/codedna/kappa-component-generator.js +295 -0
- package/dist/codedna/kappa-design-generator.d.ts +52 -0
- package/dist/codedna/kappa-design-generator.js +365 -0
- package/dist/codedna/kappa-drizzle-generator.d.ts +45 -0
- package/dist/codedna/kappa-drizzle-generator.js +355 -0
- package/dist/codedna/kappa-form-generator.d.ts +51 -0
- package/dist/codedna/kappa-form-generator.js +319 -0
- package/dist/codedna/kappa-lexer.d.ts +268 -0
- package/dist/codedna/kappa-lexer.js +757 -0
- package/dist/codedna/kappa-page-generator.d.ts +57 -0
- package/dist/codedna/kappa-page-generator.js +338 -0
- package/dist/codedna/kappa-parser.d.ts +261 -0
- package/dist/codedna/kappa-parser.js +2547 -0
- package/dist/codedna/kappa-provenance.d.ts +101 -0
- package/dist/codedna/kappa-provenance.js +199 -0
- package/dist/codedna/kappa-types-generator.d.ts +37 -0
- package/dist/codedna/kappa-types-generator.js +159 -0
- package/dist/codedna/kappa-validator.d.ts +86 -0
- package/dist/codedna/kappa-validator.js +638 -0
- package/dist/codedna/kappa-zod-generator.d.ts +32 -0
- package/dist/codedna/kappa-zod-generator.js +216 -0
- package/dist/handlers/kappa-handlers.d.ts +116 -0
- package/dist/handlers/kappa-handlers.js +465 -0
- package/dist/handlers/tool-handlers.js +121 -0
- package/dist/templates/claude-md.d.ts +1 -1
- package/dist/templates/claude-md.js +166 -9
- package/dist/tools.js +199 -0
- package/docs/research/2026-01-02-codedna-il-specification.md +639 -0
- package/docs/research/2026-01-02-codedna-v2-research.md +943 -0
- package/docs/research/2026-01-02-computation-foundations.md +564 -0
- package/docs/research/2026-01-02-hardware-description.md +814 -0
- package/docs/research/2026-01-02-kappa-specification.md +697 -0
- package/docs/research/2026-01-02-kappa-tanstack-example.md +527 -0
- package/docs/research/2026-01-02-kappa-v2-synthesis.md +406 -0
- package/docs/research/2026-01-02-kappa-v2.5-specification.md +1218 -0
- package/docs/research/2026-01-02-kappa-v3-specification.md +1864 -0
- package/docs/research/2026-01-02-kappa-whitepaper.md +662 -0
- package/docs/research/2026-01-02-logic-constraint.md +731 -0
- package/docs/research/2026-01-02-quantum-computation.md +635 -0
- package/package.json +4 -2
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { SourceLocation, EntityBlock, EntityField } from './kappa-ast.js';
|
|
2
|
+
export interface ProvenanceOptions {
|
|
3
|
+
/** Path to the Kappa spec file (optional) */
|
|
4
|
+
specFile?: string;
|
|
5
|
+
/** Include timestamp in header (default: true) */
|
|
6
|
+
timestamp?: boolean;
|
|
7
|
+
/** Include field-level provenance (default: false) */
|
|
8
|
+
fieldLevel?: boolean;
|
|
9
|
+
/** Comment style (default: 'line') */
|
|
10
|
+
style?: 'line' | 'block' | 'jsdoc';
|
|
11
|
+
}
|
|
12
|
+
export interface ProvenanceInfo {
|
|
13
|
+
/** Entity name */
|
|
14
|
+
entity: string;
|
|
15
|
+
/** Field name (if field-level) */
|
|
16
|
+
field?: string;
|
|
17
|
+
/** Source location in the spec */
|
|
18
|
+
location: SourceLocation;
|
|
19
|
+
/** Spec file path */
|
|
20
|
+
specFile?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare class ProvenanceGenerator {
|
|
23
|
+
private options;
|
|
24
|
+
constructor(options?: ProvenanceOptions);
|
|
25
|
+
/**
|
|
26
|
+
* Generate file header comment
|
|
27
|
+
*/
|
|
28
|
+
generateHeader(): string;
|
|
29
|
+
/**
|
|
30
|
+
* Generate provenance comment for an entity
|
|
31
|
+
*/
|
|
32
|
+
generateEntityProvenance(entity: EntityBlock): string;
|
|
33
|
+
/**
|
|
34
|
+
* Generate provenance comment for a field
|
|
35
|
+
*/
|
|
36
|
+
generateFieldProvenance(entity: EntityBlock, field: EntityField): string;
|
|
37
|
+
/**
|
|
38
|
+
* Generate inline provenance reference
|
|
39
|
+
*/
|
|
40
|
+
generateInlineRef(info: ProvenanceInfo): string;
|
|
41
|
+
/**
|
|
42
|
+
* Format a source location for display
|
|
43
|
+
*/
|
|
44
|
+
formatLocation(loc: SourceLocation): string;
|
|
45
|
+
/**
|
|
46
|
+
* Generate regeneration warning
|
|
47
|
+
*/
|
|
48
|
+
generateWarning(): string;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Generate a file header with provenance info
|
|
52
|
+
*/
|
|
53
|
+
export declare function generateProvenanceHeader(options?: ProvenanceOptions): string;
|
|
54
|
+
/**
|
|
55
|
+
* Generate provenance comment for an entity
|
|
56
|
+
*/
|
|
57
|
+
export declare function generateEntityProvenance(entity: EntityBlock, options?: ProvenanceOptions): string;
|
|
58
|
+
/**
|
|
59
|
+
* Generate provenance comment for a field
|
|
60
|
+
*/
|
|
61
|
+
export declare function generateFieldProvenance(entity: EntityBlock, field: EntityField, options?: ProvenanceOptions): string;
|
|
62
|
+
/**
|
|
63
|
+
* Wrap generated code with provenance header and footer
|
|
64
|
+
*/
|
|
65
|
+
export declare function wrapWithProvenance(code: string, options?: ProvenanceOptions): string;
|
|
66
|
+
export interface SourceMapEntry {
|
|
67
|
+
/** Generated line number */
|
|
68
|
+
generatedLine: number;
|
|
69
|
+
/** Generated column */
|
|
70
|
+
generatedColumn: number;
|
|
71
|
+
/** Original source location */
|
|
72
|
+
originalLocation: SourceLocation;
|
|
73
|
+
/** Entity name */
|
|
74
|
+
entity: string;
|
|
75
|
+
/** Field name (optional) */
|
|
76
|
+
field?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Create a source map for generated code
|
|
80
|
+
*/
|
|
81
|
+
export declare class ProvenanceSourceMap {
|
|
82
|
+
private entries;
|
|
83
|
+
private specFile?;
|
|
84
|
+
constructor(specFile?: string);
|
|
85
|
+
/**
|
|
86
|
+
* Add a mapping entry
|
|
87
|
+
*/
|
|
88
|
+
addMapping(generatedLine: number, generatedColumn: number, originalLocation: SourceLocation, entity: string, field?: string): void;
|
|
89
|
+
/**
|
|
90
|
+
* Find the original location for a generated position
|
|
91
|
+
*/
|
|
92
|
+
findOriginal(line: number, column: number): SourceMapEntry | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Export as JSON for tooling integration
|
|
95
|
+
*/
|
|
96
|
+
toJSON(): object;
|
|
97
|
+
/**
|
|
98
|
+
* Generate inline source map comment
|
|
99
|
+
*/
|
|
100
|
+
toInlineComment(): string;
|
|
101
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Kappa v2.5 Provenance Comments
|
|
3
|
+
// =============================================================================
|
|
4
|
+
//
|
|
5
|
+
// Utilities for adding provenance comments to generated code.
|
|
6
|
+
// Links generated code back to the original Kappa specification.
|
|
7
|
+
//
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// Comment Formatters
|
|
10
|
+
// =============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Format a single-line comment
|
|
13
|
+
*/
|
|
14
|
+
function lineComment(text) {
|
|
15
|
+
return `// ${text}`;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Format a block comment
|
|
19
|
+
*/
|
|
20
|
+
function blockComment(lines) {
|
|
21
|
+
if (lines.length === 1) {
|
|
22
|
+
return `/* ${lines[0]} */`;
|
|
23
|
+
}
|
|
24
|
+
return ['/*', ...lines.map(l => ` * ${l}`), ' */'].join('\n');
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Format a JSDoc comment
|
|
28
|
+
*/
|
|
29
|
+
function jsdocComment(lines) {
|
|
30
|
+
return ['/**', ...lines.map(l => ` * ${l}`), ' */'].join('\n');
|
|
31
|
+
}
|
|
32
|
+
// =============================================================================
|
|
33
|
+
// Provenance Generator
|
|
34
|
+
// =============================================================================
|
|
35
|
+
export class ProvenanceGenerator {
|
|
36
|
+
options;
|
|
37
|
+
constructor(options = {}) {
|
|
38
|
+
this.options = {
|
|
39
|
+
specFile: options.specFile ?? '',
|
|
40
|
+
timestamp: options.timestamp ?? true,
|
|
41
|
+
fieldLevel: options.fieldLevel ?? false,
|
|
42
|
+
style: options.style ?? 'line',
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Generate file header comment
|
|
47
|
+
*/
|
|
48
|
+
generateHeader() {
|
|
49
|
+
const lines = ['Generated by Kappa v2.5 CodeDNA'];
|
|
50
|
+
if (this.options.specFile) {
|
|
51
|
+
lines.push(`Source: ${this.options.specFile}`);
|
|
52
|
+
}
|
|
53
|
+
if (this.options.timestamp) {
|
|
54
|
+
lines.push(`Generated at: ${new Date().toISOString()}`);
|
|
55
|
+
}
|
|
56
|
+
lines.push('');
|
|
57
|
+
lines.push('DO NOT EDIT - Changes will be overwritten on regeneration.');
|
|
58
|
+
switch (this.options.style) {
|
|
59
|
+
case 'block':
|
|
60
|
+
return blockComment(lines);
|
|
61
|
+
case 'jsdoc':
|
|
62
|
+
return jsdocComment(lines);
|
|
63
|
+
default:
|
|
64
|
+
return lines.map(l => lineComment(l)).join('\n');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Generate provenance comment for an entity
|
|
69
|
+
*/
|
|
70
|
+
generateEntityProvenance(entity) {
|
|
71
|
+
const loc = entity.loc;
|
|
72
|
+
const locStr = this.formatLocation(loc);
|
|
73
|
+
const lines = [`Entity: ${entity.name}`, `Defined at: ${locStr}`];
|
|
74
|
+
switch (this.options.style) {
|
|
75
|
+
case 'block':
|
|
76
|
+
return blockComment(lines);
|
|
77
|
+
case 'jsdoc':
|
|
78
|
+
return jsdocComment(lines);
|
|
79
|
+
default:
|
|
80
|
+
return lines.map(l => lineComment(l)).join('\n');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Generate provenance comment for a field
|
|
85
|
+
*/
|
|
86
|
+
generateFieldProvenance(entity, field) {
|
|
87
|
+
if (!this.options.fieldLevel) {
|
|
88
|
+
return '';
|
|
89
|
+
}
|
|
90
|
+
const loc = field.loc;
|
|
91
|
+
const locStr = this.formatLocation(loc);
|
|
92
|
+
return lineComment(`${entity.name}.${field.name} @ ${locStr}`);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Generate inline provenance reference
|
|
96
|
+
*/
|
|
97
|
+
generateInlineRef(info) {
|
|
98
|
+
const locStr = this.formatLocation(info.location);
|
|
99
|
+
const ref = info.field
|
|
100
|
+
? `${info.entity}.${info.field}`
|
|
101
|
+
: info.entity;
|
|
102
|
+
return lineComment(`@kappa ${ref} @ ${locStr}`);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Format a source location for display
|
|
106
|
+
*/
|
|
107
|
+
formatLocation(loc) {
|
|
108
|
+
const file = this.options.specFile ? `${this.options.specFile}:` : '';
|
|
109
|
+
return `${file}${loc.startLine}:${loc.startColumn}`;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Generate regeneration warning
|
|
113
|
+
*/
|
|
114
|
+
generateWarning() {
|
|
115
|
+
return lineComment('WARNING: This file is auto-generated. Do not modify manually.');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// =============================================================================
|
|
119
|
+
// Convenience Functions
|
|
120
|
+
// =============================================================================
|
|
121
|
+
/**
|
|
122
|
+
* Generate a file header with provenance info
|
|
123
|
+
*/
|
|
124
|
+
export function generateProvenanceHeader(options = {}) {
|
|
125
|
+
const generator = new ProvenanceGenerator(options);
|
|
126
|
+
return generator.generateHeader();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Generate provenance comment for an entity
|
|
130
|
+
*/
|
|
131
|
+
export function generateEntityProvenance(entity, options = {}) {
|
|
132
|
+
const generator = new ProvenanceGenerator(options);
|
|
133
|
+
return generator.generateEntityProvenance(entity);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Generate provenance comment for a field
|
|
137
|
+
*/
|
|
138
|
+
export function generateFieldProvenance(entity, field, options = {}) {
|
|
139
|
+
const generator = new ProvenanceGenerator(options);
|
|
140
|
+
return generator.generateFieldProvenance(entity, field);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Wrap generated code with provenance header and footer
|
|
144
|
+
*/
|
|
145
|
+
export function wrapWithProvenance(code, options = {}) {
|
|
146
|
+
const generator = new ProvenanceGenerator(options);
|
|
147
|
+
const header = generator.generateHeader();
|
|
148
|
+
const warning = generator.generateWarning();
|
|
149
|
+
return `${header}\n\n${code}\n\n${warning}\n`;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Create a source map for generated code
|
|
153
|
+
*/
|
|
154
|
+
export class ProvenanceSourceMap {
|
|
155
|
+
entries = [];
|
|
156
|
+
specFile;
|
|
157
|
+
constructor(specFile) {
|
|
158
|
+
this.specFile = specFile;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Add a mapping entry
|
|
162
|
+
*/
|
|
163
|
+
addMapping(generatedLine, generatedColumn, originalLocation, entity, field) {
|
|
164
|
+
this.entries.push({
|
|
165
|
+
generatedLine,
|
|
166
|
+
generatedColumn,
|
|
167
|
+
originalLocation,
|
|
168
|
+
entity,
|
|
169
|
+
field,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Find the original location for a generated position
|
|
174
|
+
*/
|
|
175
|
+
findOriginal(line, column) {
|
|
176
|
+
// Find the closest entry at or before the given position
|
|
177
|
+
return this.entries
|
|
178
|
+
.filter(e => e.generatedLine <= line)
|
|
179
|
+
.sort((a, b) => b.generatedLine - a.generatedLine)[0];
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Export as JSON for tooling integration
|
|
183
|
+
*/
|
|
184
|
+
toJSON() {
|
|
185
|
+
return {
|
|
186
|
+
version: 1,
|
|
187
|
+
specFile: this.specFile,
|
|
188
|
+
mappings: this.entries,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Generate inline source map comment
|
|
193
|
+
*/
|
|
194
|
+
toInlineComment() {
|
|
195
|
+
const json = JSON.stringify(this.toJSON());
|
|
196
|
+
const base64 = Buffer.from(json).toString('base64');
|
|
197
|
+
return `//# kappaSourceMap=${base64}`;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { EntityBlock } from './kappa-ast.js';
|
|
2
|
+
export interface TypesGeneratorOptions {
|
|
3
|
+
/** Add provenance comments (default: true) */
|
|
4
|
+
provenance?: boolean;
|
|
5
|
+
/** Generate insert types (default: true) */
|
|
6
|
+
insertTypes?: boolean;
|
|
7
|
+
/** Generate update types (default: true) */
|
|
8
|
+
updateTypes?: boolean;
|
|
9
|
+
/** Export as interfaces vs type aliases (default: 'interface') */
|
|
10
|
+
style?: 'interface' | 'type';
|
|
11
|
+
/** Add JSDoc comments from field descriptions (default: true) */
|
|
12
|
+
jsdoc?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface GeneratedTypes {
|
|
15
|
+
/** Types file content */
|
|
16
|
+
types: string;
|
|
17
|
+
}
|
|
18
|
+
export declare class KappaTypesGenerator {
|
|
19
|
+
private provenance;
|
|
20
|
+
private insertTypes;
|
|
21
|
+
private updateTypes;
|
|
22
|
+
private style;
|
|
23
|
+
private jsdoc;
|
|
24
|
+
constructor(options?: TypesGeneratorOptions);
|
|
25
|
+
/**
|
|
26
|
+
* Generate TypeScript types from entity blocks
|
|
27
|
+
*/
|
|
28
|
+
generate(entities: EntityBlock[]): GeneratedTypes;
|
|
29
|
+
private generateTypesFile;
|
|
30
|
+
private generateEntityTypes;
|
|
31
|
+
private generateType;
|
|
32
|
+
private fieldTypeToTS;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Generate TypeScript types from Kappa entities
|
|
36
|
+
*/
|
|
37
|
+
export declare function generateTypeScriptTypes(entities: EntityBlock[], options?: TypesGeneratorOptions): GeneratedTypes;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Kappa v2.5 TypeScript Types Generator
|
|
3
|
+
// =============================================================================
|
|
4
|
+
//
|
|
5
|
+
// Generates pure TypeScript interfaces from Kappa entity blocks.
|
|
6
|
+
// No runtime dependencies - types only.
|
|
7
|
+
//
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// Type Mappings
|
|
10
|
+
// =============================================================================
|
|
11
|
+
const PRIMITIVE_TYPE_MAP = {
|
|
12
|
+
string: 'string',
|
|
13
|
+
int: 'number',
|
|
14
|
+
float: 'number',
|
|
15
|
+
bool: 'boolean',
|
|
16
|
+
email: 'string',
|
|
17
|
+
url: 'string',
|
|
18
|
+
uuid: 'string',
|
|
19
|
+
phone: 'string',
|
|
20
|
+
slug: 'string',
|
|
21
|
+
markdown: 'string',
|
|
22
|
+
json: 'Record<string, unknown>',
|
|
23
|
+
timestamp: 'Date',
|
|
24
|
+
date: 'string',
|
|
25
|
+
time: 'string',
|
|
26
|
+
duration: 'string',
|
|
27
|
+
};
|
|
28
|
+
// =============================================================================
|
|
29
|
+
// Generator Class
|
|
30
|
+
// =============================================================================
|
|
31
|
+
export class KappaTypesGenerator {
|
|
32
|
+
provenance;
|
|
33
|
+
insertTypes;
|
|
34
|
+
updateTypes;
|
|
35
|
+
style;
|
|
36
|
+
jsdoc;
|
|
37
|
+
constructor(options = {}) {
|
|
38
|
+
this.provenance = options.provenance ?? true;
|
|
39
|
+
this.insertTypes = options.insertTypes ?? true;
|
|
40
|
+
this.updateTypes = options.updateTypes ?? true;
|
|
41
|
+
this.style = options.style ?? 'interface';
|
|
42
|
+
this.jsdoc = options.jsdoc ?? true;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Generate TypeScript types from entity blocks
|
|
46
|
+
*/
|
|
47
|
+
generate(entities) {
|
|
48
|
+
const types = this.generateTypesFile(entities);
|
|
49
|
+
return { types };
|
|
50
|
+
}
|
|
51
|
+
// ===========================================================================
|
|
52
|
+
// Types File Generation
|
|
53
|
+
// ===========================================================================
|
|
54
|
+
generateTypesFile(entities) {
|
|
55
|
+
const lines = [];
|
|
56
|
+
// Header comment
|
|
57
|
+
if (this.provenance) {
|
|
58
|
+
lines.push('// Generated by Kappa v2.5 CodeDNA');
|
|
59
|
+
lines.push(`// Generated at: ${new Date().toISOString()}`);
|
|
60
|
+
lines.push('');
|
|
61
|
+
}
|
|
62
|
+
// Generate types for each entity
|
|
63
|
+
for (const entity of entities) {
|
|
64
|
+
lines.push(this.generateEntityTypes(entity));
|
|
65
|
+
lines.push('');
|
|
66
|
+
}
|
|
67
|
+
return lines.join('\n');
|
|
68
|
+
}
|
|
69
|
+
generateEntityTypes(entity) {
|
|
70
|
+
const lines = [];
|
|
71
|
+
// Main type (for select/read - all fields)
|
|
72
|
+
if (this.jsdoc) {
|
|
73
|
+
lines.push(`/** ${entity.name} entity */`);
|
|
74
|
+
}
|
|
75
|
+
lines.push(this.generateType(entity.name, entity.fields));
|
|
76
|
+
// Insert type (excludes auto-generated fields, makes optional fields optional)
|
|
77
|
+
if (this.insertTypes) {
|
|
78
|
+
lines.push('');
|
|
79
|
+
const insertFields = entity.fields.filter(f => !f.modifiers.includes('auto'));
|
|
80
|
+
if (this.jsdoc) {
|
|
81
|
+
lines.push(`/** Data required to create a new ${entity.name} */`);
|
|
82
|
+
}
|
|
83
|
+
lines.push(this.generateType(`New${entity.name}`, insertFields, { forInsert: true }));
|
|
84
|
+
}
|
|
85
|
+
// Update type (all fields optional, excludes auto fields)
|
|
86
|
+
if (this.updateTypes) {
|
|
87
|
+
lines.push('');
|
|
88
|
+
if (this.jsdoc) {
|
|
89
|
+
lines.push(`/** Data for updating an existing ${entity.name} */`);
|
|
90
|
+
}
|
|
91
|
+
// If insert types are enabled, reference NewEntity; otherwise reference main Entity
|
|
92
|
+
const baseType = this.insertTypes ? `New${entity.name}` : entity.name;
|
|
93
|
+
if (this.style === 'interface') {
|
|
94
|
+
lines.push(`export interface Update${entity.name} extends Partial<${baseType}> {}`);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
lines.push(`export type Update${entity.name} = Partial<${baseType}>;`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return lines.join('\n');
|
|
101
|
+
}
|
|
102
|
+
generateType(name, fields, options = {}) {
|
|
103
|
+
const lines = [];
|
|
104
|
+
if (this.style === 'interface') {
|
|
105
|
+
lines.push(`export interface ${name} {`);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
lines.push(`export type ${name} = {`);
|
|
109
|
+
}
|
|
110
|
+
for (const field of fields) {
|
|
111
|
+
const { name: fieldName, type, modifiers } = field;
|
|
112
|
+
const tsType = this.fieldTypeToTS(type);
|
|
113
|
+
const isOptional = modifiers.includes('optional');
|
|
114
|
+
const isPrimary = modifiers.includes('primary');
|
|
115
|
+
const isAuto = modifiers.includes('auto');
|
|
116
|
+
// Determine if field should be optional in output
|
|
117
|
+
let optional = isOptional;
|
|
118
|
+
if (options.forInsert && isPrimary && isAuto) {
|
|
119
|
+
optional = true; // Auto-generated primary keys are optional on insert
|
|
120
|
+
}
|
|
121
|
+
const optionalMark = optional ? '?' : '';
|
|
122
|
+
const nullableMark = isOptional ? ' | null' : '';
|
|
123
|
+
lines.push(` ${fieldName}${optionalMark}: ${tsType}${nullableMark};`);
|
|
124
|
+
}
|
|
125
|
+
if (this.style === 'interface') {
|
|
126
|
+
lines.push('}');
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
lines.push('};');
|
|
130
|
+
}
|
|
131
|
+
return lines.join('\n');
|
|
132
|
+
}
|
|
133
|
+
fieldTypeToTS(type) {
|
|
134
|
+
switch (type.kind) {
|
|
135
|
+
case 'primitive':
|
|
136
|
+
return PRIMITIVE_TYPE_MAP[type.type];
|
|
137
|
+
case 'enum':
|
|
138
|
+
return type.values.map(v => `'${v}'`).join(' | ');
|
|
139
|
+
case 'reference':
|
|
140
|
+
// Reference fields are strings (usually UUIDs)
|
|
141
|
+
return 'string';
|
|
142
|
+
case 'array':
|
|
143
|
+
const itemType = this.fieldTypeToTS(type.itemType);
|
|
144
|
+
return `${itemType}[]`;
|
|
145
|
+
default:
|
|
146
|
+
return 'unknown';
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// =============================================================================
|
|
151
|
+
// Convenience Function
|
|
152
|
+
// =============================================================================
|
|
153
|
+
/**
|
|
154
|
+
* Generate TypeScript types from Kappa entities
|
|
155
|
+
*/
|
|
156
|
+
export function generateTypeScriptTypes(entities, options = {}) {
|
|
157
|
+
const generator = new KappaTypesGenerator(options);
|
|
158
|
+
return generator.generate(entities);
|
|
159
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { KappaSpec, SourceLocation } from './kappa-ast.js';
|
|
2
|
+
export interface ValidationError {
|
|
3
|
+
/** Error code for programmatic handling */
|
|
4
|
+
code: ValidationErrorCode;
|
|
5
|
+
/** Human-readable message */
|
|
6
|
+
message: string;
|
|
7
|
+
/** Source location in the spec */
|
|
8
|
+
location: SourceLocation;
|
|
9
|
+
/** Related entity/field names for context */
|
|
10
|
+
context?: {
|
|
11
|
+
entityName?: string;
|
|
12
|
+
fieldName?: string;
|
|
13
|
+
referencedEntity?: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export type ValidationErrorCode = 'UNDEFINED_ENTITY_REFERENCE' | 'UNDEFINED_THROUGH_ENTITY' | 'SELF_REFERENCE_INVALID' | 'DUPLICATE_FIELD_NAME' | 'INVALID_MODIFIER_FOR_TYPE' | 'DUPLICATE_PRIMARY_KEY' | 'DUPLICATE_ENUM_VALUE' | 'INVALID_RANGE' | 'CONFLICTING_MODIFIERS' | 'EMPTY_ENUM' | 'DUPLICATE_RELATIONSHIP' | 'INVALID_CASCADE_ACTION' | 'UNDEFINED_CRUD_ENTITY' | 'UNDEFINED_RETURN_TYPE_ENTITY' | 'INVALID_EFFECT_TYPE' | 'UNDEFINED_JOINED_ENTITY' | 'DUPLICATE_PARAMETER_NAME' | 'UNDEFINED_CAPABILITY_TARGET' | 'UNDEFINED_PAGE_REFERENCE' | 'UNDEFINED_API_REFERENCE' | 'DUPLICATE_ENTITY_NAME' | 'DUPLICATE_API_NAME';
|
|
17
|
+
export interface ValidationResult {
|
|
18
|
+
valid: boolean;
|
|
19
|
+
errors: ValidationError[];
|
|
20
|
+
warnings: ValidationError[];
|
|
21
|
+
}
|
|
22
|
+
export declare class KappaValidator {
|
|
23
|
+
private errors;
|
|
24
|
+
private warnings;
|
|
25
|
+
/** Set of all defined entity names */
|
|
26
|
+
private entityNames;
|
|
27
|
+
/** Set of all defined API names */
|
|
28
|
+
private apiNames;
|
|
29
|
+
/** Set of all defined page names */
|
|
30
|
+
private pageNames;
|
|
31
|
+
/** Set of all defined form names */
|
|
32
|
+
private formNames;
|
|
33
|
+
/** Set of all defined journey names */
|
|
34
|
+
private journeyNames;
|
|
35
|
+
/**
|
|
36
|
+
* Validate a Kappa specification AST
|
|
37
|
+
*/
|
|
38
|
+
validate(spec: KappaSpec): ValidationResult;
|
|
39
|
+
private reset;
|
|
40
|
+
private collectDefinedNames;
|
|
41
|
+
private validateEntities;
|
|
42
|
+
private validateEntity;
|
|
43
|
+
private validateFieldType;
|
|
44
|
+
private validateModifiersForType;
|
|
45
|
+
private validateRelationship;
|
|
46
|
+
private validateCapability;
|
|
47
|
+
private validateAPIs;
|
|
48
|
+
private validateAPI;
|
|
49
|
+
private validateCRUD;
|
|
50
|
+
private validateAPIOperation;
|
|
51
|
+
private validateJourneys;
|
|
52
|
+
private validateJourney;
|
|
53
|
+
private validatePages;
|
|
54
|
+
private validatePage;
|
|
55
|
+
private validateForms;
|
|
56
|
+
private validateForm;
|
|
57
|
+
private addError;
|
|
58
|
+
private addWarning;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Validate a Kappa specification AST
|
|
62
|
+
*/
|
|
63
|
+
export declare function validateKappaSpec(spec: KappaSpec): ValidationResult;
|
|
64
|
+
/**
|
|
65
|
+
* Format a validation error for display (simple format)
|
|
66
|
+
*/
|
|
67
|
+
export declare function formatValidationError(error: ValidationError): string;
|
|
68
|
+
/**
|
|
69
|
+
* Options for rich error formatting
|
|
70
|
+
*/
|
|
71
|
+
export interface FormatOptions {
|
|
72
|
+
/** Original source code (required for code snippets) */
|
|
73
|
+
source?: string;
|
|
74
|
+
/** Use ANSI colors for terminal output */
|
|
75
|
+
colors?: boolean;
|
|
76
|
+
/** Number of context lines to show before/after error */
|
|
77
|
+
contextLines?: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Format a validation error with code snippet and visual indicators
|
|
81
|
+
*/
|
|
82
|
+
export declare function formatValidationErrorRich(error: ValidationError, options?: FormatOptions): string;
|
|
83
|
+
/**
|
|
84
|
+
* Format all validation results for display
|
|
85
|
+
*/
|
|
86
|
+
export declare function formatValidationResults(result: ValidationResult, options?: FormatOptions): string;
|