@claudetools/tools 0.9.1 → 0.9.2
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/cli.js +9 -1
- package/dist/codedna/__tests__/examples/mongoose-example.d.ts +6 -0
- package/dist/codedna/__tests__/examples/mongoose-example.js +163 -0
- package/dist/codedna/__tests__/fixtures/typeorm-production-test.d.ts +1 -0
- package/dist/codedna/__tests__/fixtures/typeorm-production-test.js +231 -0
- package/dist/codedna/__tests__/fixtures/typeorm-test.d.ts +1 -0
- package/dist/codedna/__tests__/fixtures/typeorm-test.js +124 -0
- package/dist/codedna/__tests__/laravel-output-review.d.ts +1 -0
- package/dist/codedna/__tests__/laravel-output-review.js +249 -0
- package/dist/codedna/__tests__/mongoose-output-test.d.ts +1 -0
- package/dist/codedna/__tests__/mongoose-output-test.js +178 -0
- package/dist/codedna/examples/radix-example.d.ts +2 -0
- package/dist/codedna/examples/radix-example.js +259 -0
- package/dist/codedna/index.d.ts +5 -3
- package/dist/codedna/index.js +6 -3
- package/dist/codedna/kappa-ast.d.ts +143 -5
- package/dist/codedna/kappa-drizzle-generator.js +8 -5
- package/dist/codedna/kappa-gofiber-generator.d.ts +65 -0
- package/dist/codedna/kappa-gofiber-generator.js +587 -0
- package/dist/codedna/kappa-laravel-generator.d.ts +68 -0
- package/dist/codedna/kappa-laravel-generator.js +741 -0
- package/dist/codedna/kappa-lexer.d.ts +44 -0
- package/dist/codedna/kappa-lexer.js +124 -0
- package/dist/codedna/kappa-mantine-generator.d.ts +65 -0
- package/dist/codedna/kappa-mantine-generator.js +518 -0
- package/dist/codedna/kappa-mongoose-generator.d.ts +44 -0
- package/dist/codedna/kappa-mongoose-generator.js +442 -0
- package/dist/codedna/kappa-parser.d.ts +43 -1
- package/dist/codedna/kappa-parser.js +601 -0
- package/dist/codedna/kappa-radix-generator.d.ts +61 -0
- package/dist/codedna/kappa-radix-generator.js +566 -0
- package/dist/codedna/kappa-typeorm-generator.d.ts +59 -0
- package/dist/codedna/kappa-typeorm-generator.js +723 -0
- package/dist/codedna/kappa-vitest-generator.d.ts +85 -0
- package/dist/codedna/kappa-vitest-generator.js +739 -0
- package/dist/codedna/parser.js +26 -1
- package/dist/codegen/cloud-client.d.ts +160 -0
- package/dist/codegen/cloud-client.js +195 -0
- package/dist/codegen/codegen-tool.d.ts +35 -0
- package/dist/codegen/codegen-tool.js +312 -0
- package/dist/codegen/field-inference.d.ts +24 -0
- package/dist/codegen/field-inference.js +101 -0
- package/dist/codegen/form-parser.d.ts +13 -0
- package/dist/codegen/form-parser.js +186 -0
- package/dist/codegen/index.d.ts +2 -0
- package/dist/codegen/index.js +4 -0
- package/dist/codegen/natural-parser.d.ts +50 -0
- package/dist/codegen/natural-parser.js +769 -0
- package/dist/handlers/codedna-handlers.d.ts +1 -1
- package/dist/handlers/codegen-handlers.d.ts +20 -0
- package/dist/handlers/codegen-handlers.js +60 -0
- package/dist/handlers/kappa-handlers.d.ts +97 -0
- package/dist/handlers/kappa-handlers.js +408 -0
- package/dist/handlers/tool-handlers.js +124 -221
- package/dist/helpers/api-client.js +48 -3
- package/dist/helpers/compact-formatter.d.ts +9 -2
- package/dist/helpers/compact-formatter.js +26 -2
- package/dist/helpers/config.d.ts +7 -2
- package/dist/helpers/config.js +25 -10
- package/dist/helpers/session-validation.d.ts +1 -1
- package/dist/helpers/session-validation.js +2 -4
- package/dist/helpers/tasks.d.ts +21 -0
- package/dist/helpers/tasks.js +52 -0
- package/dist/helpers/workers.d.ts +1 -1
- package/dist/helpers/workers.js +19 -19
- package/dist/setup.d.ts +1 -0
- package/dist/setup.js +49 -16
- package/dist/templates/claude-md.d.ts +1 -1
- package/dist/templates/claude-md.js +37 -152
- package/dist/templates/orchestrator-prompt.d.ts +2 -2
- package/dist/templates/orchestrator-prompt.js +31 -38
- package/dist/templates/self-critique.d.ts +50 -0
- package/dist/templates/self-critique.js +209 -0
- package/dist/templates/worker-prompt.d.ts +3 -3
- package/dist/templates/worker-prompt.js +18 -18
- package/dist/tools.js +77 -413
- package/docs/codedna/generator-testing-summary.md +205 -0
- package/docs/codedna/radix-ui-generator.md +478 -0
- package/docs/kappa-gofiber-generator.md +274 -0
- package/docs/kappa-laravel-fixes.md +172 -0
- package/docs/kappa-mongoose-generator.md +322 -0
- package/docs/kappa-vitest-generator.md +337 -0
- package/package.json +1 -1
- package/dist/context/deduplication.test.d.ts +0 -6
- package/dist/context/deduplication.test.js +0 -84
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import { parseArgs } from 'node:util';
|
|
|
7
7
|
import { readFileSync } from 'node:fs';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
9
|
import { dirname, join } from 'node:path';
|
|
10
|
-
import { runSetup, runUninstall, runInit, runCleanup } from './setup.js';
|
|
10
|
+
import { runSetup, runUninstall, runInit, runCleanup, runOnboard } from './setup.js';
|
|
11
11
|
import { startServer } from './index.js';
|
|
12
12
|
import { startWatcher, stopWatcher, watcherStatus } from './watcher.js';
|
|
13
13
|
import { generateCodebaseMap, generateCodebaseMapLocal } from './helpers/codebase-mapper.js';
|
|
@@ -52,6 +52,7 @@ Options:
|
|
|
52
52
|
|
|
53
53
|
Commands:
|
|
54
54
|
init Initialize current directory as a project
|
|
55
|
+
onboard Interactive project onboarding (teach Claude about your project)
|
|
55
56
|
cleanup Remove legacy config and broken hooks
|
|
56
57
|
watch Start the file watcher daemon
|
|
57
58
|
watch --stop Stop the watcher daemon
|
|
@@ -99,6 +100,13 @@ else if (positionals[0] === 'cleanup') {
|
|
|
99
100
|
process.exit(1);
|
|
100
101
|
});
|
|
101
102
|
}
|
|
103
|
+
else if (positionals[0] === 'onboard') {
|
|
104
|
+
// Handle onboard command
|
|
105
|
+
runOnboard().catch((error) => {
|
|
106
|
+
console.error('Onboard failed:', error);
|
|
107
|
+
process.exit(1);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
102
110
|
else if (positionals[0] === 'watch') {
|
|
103
111
|
// Handle watch command
|
|
104
112
|
const watchArgs = process.argv.slice(3); // Get args after 'watch'
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example usage of the Kappa Mongoose Generator
|
|
3
|
+
*
|
|
4
|
+
* This demonstrates how to generate MongoDB/Mongoose schemas from Kappa entity blocks.
|
|
5
|
+
*/
|
|
6
|
+
import { generateMongooseSchema } from '../../kappa-mongoose-generator.js';
|
|
7
|
+
// Sample entity blocks
|
|
8
|
+
const loc = {
|
|
9
|
+
startLine: 1,
|
|
10
|
+
startColumn: 1,
|
|
11
|
+
endLine: 1,
|
|
12
|
+
endColumn: 1,
|
|
13
|
+
startOffset: 0,
|
|
14
|
+
endOffset: 0,
|
|
15
|
+
};
|
|
16
|
+
const entities = [
|
|
17
|
+
{
|
|
18
|
+
kind: 'EntityBlock',
|
|
19
|
+
name: 'User',
|
|
20
|
+
loc,
|
|
21
|
+
fields: [
|
|
22
|
+
{
|
|
23
|
+
kind: 'EntityField',
|
|
24
|
+
name: 'id',
|
|
25
|
+
loc,
|
|
26
|
+
type: { kind: 'primitive', type: 'uuid' },
|
|
27
|
+
modifiers: ['primary', 'auto'],
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
kind: 'EntityField',
|
|
31
|
+
name: 'email',
|
|
32
|
+
loc,
|
|
33
|
+
type: { kind: 'primitive', type: 'email' },
|
|
34
|
+
modifiers: ['unique'],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
kind: 'EntityField',
|
|
38
|
+
name: 'username',
|
|
39
|
+
loc,
|
|
40
|
+
type: { kind: 'primitive', type: 'string', range: { min: 3, max: 20 } },
|
|
41
|
+
modifiers: [],
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
kind: 'EntityField',
|
|
45
|
+
name: 'bio',
|
|
46
|
+
loc,
|
|
47
|
+
type: { kind: 'primitive', type: 'markdown' },
|
|
48
|
+
modifiers: ['optional'],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
kind: 'EntityField',
|
|
52
|
+
name: 'role',
|
|
53
|
+
loc,
|
|
54
|
+
type: { kind: 'enum', values: ['admin', 'user', 'guest'] },
|
|
55
|
+
modifiers: [],
|
|
56
|
+
defaultValue: 'user',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
relationships: [
|
|
60
|
+
{
|
|
61
|
+
kind: 'EntityRelationship',
|
|
62
|
+
type: 'has_many',
|
|
63
|
+
entity: 'Post',
|
|
64
|
+
loc,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
capabilities: [],
|
|
68
|
+
lifecycleHooks: [],
|
|
69
|
+
indexes: [
|
|
70
|
+
{
|
|
71
|
+
kind: 'EntityIndex',
|
|
72
|
+
fields: ['email'],
|
|
73
|
+
unique: true,
|
|
74
|
+
loc,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
kind: 'EntityBlock',
|
|
80
|
+
name: 'Post',
|
|
81
|
+
loc,
|
|
82
|
+
fields: [
|
|
83
|
+
{
|
|
84
|
+
kind: 'EntityField',
|
|
85
|
+
name: 'id',
|
|
86
|
+
loc,
|
|
87
|
+
type: { kind: 'primitive', type: 'uuid' },
|
|
88
|
+
modifiers: ['primary', 'auto'],
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
kind: 'EntityField',
|
|
92
|
+
name: 'title',
|
|
93
|
+
loc,
|
|
94
|
+
type: { kind: 'primitive', type: 'string', range: { min: 1, max: 200 } },
|
|
95
|
+
modifiers: [],
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
kind: 'EntityField',
|
|
99
|
+
name: 'content',
|
|
100
|
+
loc,
|
|
101
|
+
type: { kind: 'primitive', type: 'markdown' },
|
|
102
|
+
modifiers: [],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
kind: 'EntityField',
|
|
106
|
+
name: 'published',
|
|
107
|
+
loc,
|
|
108
|
+
type: { kind: 'primitive', type: 'bool' },
|
|
109
|
+
modifiers: [],
|
|
110
|
+
defaultValue: 'false',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
kind: 'EntityField',
|
|
114
|
+
name: 'tags',
|
|
115
|
+
loc,
|
|
116
|
+
type: { kind: 'array', itemType: { kind: 'primitive', type: 'string' } },
|
|
117
|
+
modifiers: ['optional'],
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
relationships: [
|
|
121
|
+
{
|
|
122
|
+
kind: 'EntityRelationship',
|
|
123
|
+
type: 'belongs_to',
|
|
124
|
+
entity: 'User',
|
|
125
|
+
as: 'author',
|
|
126
|
+
loc,
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
capabilities: [],
|
|
130
|
+
lifecycleHooks: [],
|
|
131
|
+
indexes: [
|
|
132
|
+
{
|
|
133
|
+
kind: 'EntityIndex',
|
|
134
|
+
fields: ['userId', 'published'],
|
|
135
|
+
loc,
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
},
|
|
139
|
+
];
|
|
140
|
+
// Generate schemas with all options enabled
|
|
141
|
+
const result = generateMongooseSchema(entities, {
|
|
142
|
+
typescript: true,
|
|
143
|
+
provenance: true,
|
|
144
|
+
separateTypes: true,
|
|
145
|
+
});
|
|
146
|
+
console.log('=== Generated Schema File ===');
|
|
147
|
+
console.log(result.schema);
|
|
148
|
+
console.log('\n=== Generated Types File ===');
|
|
149
|
+
console.log(result.types);
|
|
150
|
+
// Example output structure:
|
|
151
|
+
//
|
|
152
|
+
// Schema file includes:
|
|
153
|
+
// - Mongoose imports
|
|
154
|
+
// - Schema definitions with validators
|
|
155
|
+
// - Virtual relationships
|
|
156
|
+
// - Indexes
|
|
157
|
+
// - Model exports
|
|
158
|
+
//
|
|
159
|
+
// Types file includes:
|
|
160
|
+
// - TypeScript interfaces extending Document
|
|
161
|
+
// - Proper typing for all fields
|
|
162
|
+
// - Relationship types
|
|
163
|
+
// - Timestamp fields (createdAt, updatedAt)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { generateTypeORMEntities } from '../../kappa-typeorm-generator.js';
|
|
2
|
+
const loc = {
|
|
3
|
+
startLine: 1,
|
|
4
|
+
startColumn: 1,
|
|
5
|
+
endLine: 1,
|
|
6
|
+
endColumn: 1,
|
|
7
|
+
startOffset: 0,
|
|
8
|
+
endOffset: 0,
|
|
9
|
+
};
|
|
10
|
+
function createEntity(name, overrides = {}) {
|
|
11
|
+
return {
|
|
12
|
+
kind: 'EntityBlock',
|
|
13
|
+
name,
|
|
14
|
+
loc,
|
|
15
|
+
fields: [],
|
|
16
|
+
relationships: [],
|
|
17
|
+
capabilities: [],
|
|
18
|
+
lifecycleHooks: [],
|
|
19
|
+
indexes: [],
|
|
20
|
+
...overrides,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
// Comprehensive production test covering all major TypeORM features
|
|
24
|
+
const entities = [
|
|
25
|
+
createEntity('User', {
|
|
26
|
+
fields: [
|
|
27
|
+
{
|
|
28
|
+
kind: 'EntityField',
|
|
29
|
+
name: 'id',
|
|
30
|
+
loc,
|
|
31
|
+
type: { kind: 'primitive', type: 'uuid' },
|
|
32
|
+
modifiers: ['primary', 'auto'],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
kind: 'EntityField',
|
|
36
|
+
name: 'email',
|
|
37
|
+
loc,
|
|
38
|
+
type: { kind: 'primitive', type: 'email' },
|
|
39
|
+
modifiers: ['unique'],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
kind: 'EntityField',
|
|
43
|
+
name: 'firstName',
|
|
44
|
+
loc,
|
|
45
|
+
type: { kind: 'primitive', type: 'string', range: { min: 1, max: 100 } },
|
|
46
|
+
modifiers: [],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
kind: 'EntityField',
|
|
50
|
+
name: 'lastName',
|
|
51
|
+
loc,
|
|
52
|
+
type: { kind: 'primitive', type: 'string', range: { min: 1, max: 100 } },
|
|
53
|
+
modifiers: ['optional'],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
kind: 'EntityField',
|
|
57
|
+
name: 'age',
|
|
58
|
+
loc,
|
|
59
|
+
type: { kind: 'primitive', type: 'int' },
|
|
60
|
+
modifiers: ['optional'],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
kind: 'EntityField',
|
|
64
|
+
name: 'role',
|
|
65
|
+
loc,
|
|
66
|
+
type: { kind: 'enum', values: ['admin', 'user', 'moderator'] },
|
|
67
|
+
modifiers: [],
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
kind: 'EntityField',
|
|
71
|
+
name: 'settings',
|
|
72
|
+
loc,
|
|
73
|
+
type: { kind: 'primitive', type: 'json' },
|
|
74
|
+
modifiers: [],
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
indexes: [
|
|
78
|
+
{
|
|
79
|
+
kind: 'EntityIndex',
|
|
80
|
+
fields: ['email'],
|
|
81
|
+
unique: true,
|
|
82
|
+
loc,
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
relationships: [
|
|
86
|
+
{
|
|
87
|
+
kind: 'EntityRelationship',
|
|
88
|
+
type: 'has_many',
|
|
89
|
+
entity: 'Post',
|
|
90
|
+
loc,
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
}),
|
|
94
|
+
createEntity('Post', {
|
|
95
|
+
fields: [
|
|
96
|
+
{
|
|
97
|
+
kind: 'EntityField',
|
|
98
|
+
name: 'id',
|
|
99
|
+
loc,
|
|
100
|
+
type: { kind: 'primitive', type: 'uuid' },
|
|
101
|
+
modifiers: ['primary', 'auto'],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
kind: 'EntityField',
|
|
105
|
+
name: 'title',
|
|
106
|
+
loc,
|
|
107
|
+
type: { kind: 'primitive', type: 'string', range: { min: 1, max: 200 } },
|
|
108
|
+
modifiers: [],
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
kind: 'EntityField',
|
|
112
|
+
name: 'content',
|
|
113
|
+
loc,
|
|
114
|
+
type: { kind: 'primitive', type: 'markdown' },
|
|
115
|
+
modifiers: [],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
kind: 'EntityField',
|
|
119
|
+
name: 'published',
|
|
120
|
+
loc,
|
|
121
|
+
type: { kind: 'primitive', type: 'bool' },
|
|
122
|
+
modifiers: [],
|
|
123
|
+
defaultValue: 'false',
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
kind: 'EntityField',
|
|
127
|
+
name: 'publishedAt',
|
|
128
|
+
loc,
|
|
129
|
+
type: { kind: 'primitive', type: 'timestamp' },
|
|
130
|
+
modifiers: ['optional'],
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
relationships: [
|
|
134
|
+
{
|
|
135
|
+
kind: 'EntityRelationship',
|
|
136
|
+
type: 'belongs_to',
|
|
137
|
+
entity: 'User',
|
|
138
|
+
as: 'author',
|
|
139
|
+
cascade: 'delete',
|
|
140
|
+
loc,
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
kind: 'EntityRelationship',
|
|
144
|
+
type: 'has_many',
|
|
145
|
+
entity: 'Tag',
|
|
146
|
+
through: 'PostTag',
|
|
147
|
+
loc,
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
}),
|
|
151
|
+
createEntity('Tag', {
|
|
152
|
+
fields: [
|
|
153
|
+
{
|
|
154
|
+
kind: 'EntityField',
|
|
155
|
+
name: 'id',
|
|
156
|
+
loc,
|
|
157
|
+
type: { kind: 'primitive', type: 'int' },
|
|
158
|
+
modifiers: ['primary', 'auto'],
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
kind: 'EntityField',
|
|
162
|
+
name: 'name',
|
|
163
|
+
loc,
|
|
164
|
+
type: { kind: 'primitive', type: 'string', range: { min: 1, max: 50 } },
|
|
165
|
+
modifiers: ['unique'],
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
kind: 'EntityField',
|
|
169
|
+
name: 'slug',
|
|
170
|
+
loc,
|
|
171
|
+
type: { kind: 'primitive', type: 'slug' },
|
|
172
|
+
modifiers: ['unique'],
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
}),
|
|
176
|
+
];
|
|
177
|
+
console.log('=== Testing PostgreSQL Dialect ===\n');
|
|
178
|
+
const pgResult = generateTypeORMEntities(entities, { dialect: 'postgres', migrations: true });
|
|
179
|
+
console.log('User Entity (PostgreSQL):');
|
|
180
|
+
console.log(pgResult.entities.User);
|
|
181
|
+
console.log('\n---\n');
|
|
182
|
+
console.log('Post Entity (PostgreSQL):');
|
|
183
|
+
console.log(pgResult.entities.Post);
|
|
184
|
+
console.log('\n---\n');
|
|
185
|
+
console.log('Tag Entity (PostgreSQL):');
|
|
186
|
+
console.log(pgResult.entities.Tag);
|
|
187
|
+
console.log('\n---\n');
|
|
188
|
+
console.log('Migration (PostgreSQL):');
|
|
189
|
+
console.log(pgResult.migration);
|
|
190
|
+
console.log('\n\n=== Testing MySQL Dialect ===\n');
|
|
191
|
+
const mysqlResult = generateTypeORMEntities(entities, { dialect: 'mysql', migrations: true });
|
|
192
|
+
console.log('User Entity (MySQL - excerpt):');
|
|
193
|
+
console.log(mysqlResult.entities.User.split('\n').slice(0, 25).join('\n'));
|
|
194
|
+
console.log('\n---\n');
|
|
195
|
+
console.log('Post FK Column (MySQL):');
|
|
196
|
+
const postLines = mysqlResult.entities.Post.split('\n');
|
|
197
|
+
const fkLineIndex = postLines.findIndex(line => line.includes('userId'));
|
|
198
|
+
console.log(postLines.slice(Math.max(0, fkLineIndex - 1), fkLineIndex + 2).join('\n'));
|
|
199
|
+
console.log('\n\n=== Production Readiness Checks ===\n');
|
|
200
|
+
// Verify key features
|
|
201
|
+
const checks = [
|
|
202
|
+
['PostgreSQL UUID FK type', pgResult.entities.Post.includes("type: 'uuid'")],
|
|
203
|
+
['MySQL varchar FK type', mysqlResult.entities.Post.includes("type: 'varchar', length: 36")],
|
|
204
|
+
['Enum with length', pgResult.entities.User.includes("type: 'varchar', length: 50")],
|
|
205
|
+
['Proper decorator syntax', pgResult.entities.User.includes('@PrimaryGeneratedColumn("uuid")')],
|
|
206
|
+
['Snake case table names', pgResult.entities.User.includes("@Entity('user')")],
|
|
207
|
+
['Snake case column names', pgResult.entities.User.includes("name: 'first_name'")],
|
|
208
|
+
['Nullable columns', pgResult.entities.User.includes('lastName?: string')],
|
|
209
|
+
['Unique indexes', pgResult.entities.User.includes('@Index(["email"], { unique: true })')],
|
|
210
|
+
['ManyToOne relationship', pgResult.entities.Post.includes('@ManyToOne(() => User')],
|
|
211
|
+
['ManyToMany relationship', pgResult.entities.Post.includes('@ManyToMany(() => Tag')],
|
|
212
|
+
['Cascade delete', pgResult.entities.Post.includes('onDelete: "CASCADE"')],
|
|
213
|
+
['Migration SQL', pgResult.migration?.includes('CREATE TABLE') ?? false],
|
|
214
|
+
['Data source config', pgResult.dataSource.includes('AppDataSource')],
|
|
215
|
+
];
|
|
216
|
+
let passed = 0;
|
|
217
|
+
let failed = 0;
|
|
218
|
+
checks.forEach(([check, result]) => {
|
|
219
|
+
if (result) {
|
|
220
|
+
console.log(`✓ ${check}`);
|
|
221
|
+
passed++;
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
console.log(`✗ ${check}`);
|
|
225
|
+
failed++;
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
console.log(`\n${passed} passed, ${failed} failed`);
|
|
229
|
+
if (failed > 0) {
|
|
230
|
+
process.exit(1);
|
|
231
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { generateTypeORMEntities } from '../../kappa-typeorm-generator.js';
|
|
2
|
+
const loc = {
|
|
3
|
+
startLine: 1,
|
|
4
|
+
startColumn: 1,
|
|
5
|
+
endLine: 1,
|
|
6
|
+
endColumn: 1,
|
|
7
|
+
startOffset: 0,
|
|
8
|
+
endOffset: 0,
|
|
9
|
+
};
|
|
10
|
+
function createEntity(name, overrides = {}) {
|
|
11
|
+
return {
|
|
12
|
+
kind: 'EntityBlock',
|
|
13
|
+
name,
|
|
14
|
+
loc,
|
|
15
|
+
fields: [],
|
|
16
|
+
relationships: [],
|
|
17
|
+
capabilities: [],
|
|
18
|
+
lifecycleHooks: [],
|
|
19
|
+
indexes: [],
|
|
20
|
+
...overrides,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const entities = [
|
|
24
|
+
createEntity('User', {
|
|
25
|
+
fields: [
|
|
26
|
+
{
|
|
27
|
+
kind: 'EntityField',
|
|
28
|
+
name: 'id',
|
|
29
|
+
loc,
|
|
30
|
+
type: { kind: 'primitive', type: 'uuid' },
|
|
31
|
+
modifiers: ['primary', 'auto'],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
kind: 'EntityField',
|
|
35
|
+
name: 'email',
|
|
36
|
+
loc,
|
|
37
|
+
type: { kind: 'primitive', type: 'email' },
|
|
38
|
+
modifiers: ['unique'],
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
kind: 'EntityField',
|
|
42
|
+
name: 'name',
|
|
43
|
+
loc,
|
|
44
|
+
type: { kind: 'primitive', type: 'string' },
|
|
45
|
+
modifiers: [],
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
kind: 'EntityField',
|
|
49
|
+
name: 'age',
|
|
50
|
+
loc,
|
|
51
|
+
type: { kind: 'primitive', type: 'int' },
|
|
52
|
+
modifiers: ['optional'],
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
kind: 'EntityField',
|
|
56
|
+
name: 'role',
|
|
57
|
+
loc,
|
|
58
|
+
type: { kind: 'enum', values: ['admin', 'user', 'moderator'] },
|
|
59
|
+
modifiers: [],
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
kind: 'EntityField',
|
|
63
|
+
name: 'status',
|
|
64
|
+
loc,
|
|
65
|
+
type: { kind: 'enum', values: ['active', 'inactive', 'suspended'] },
|
|
66
|
+
modifiers: ['optional'],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
kind: 'EntityField',
|
|
70
|
+
name: 'metadata',
|
|
71
|
+
loc,
|
|
72
|
+
type: { kind: 'primitive', type: 'json' },
|
|
73
|
+
modifiers: [],
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
}),
|
|
77
|
+
createEntity('Post', {
|
|
78
|
+
fields: [
|
|
79
|
+
{
|
|
80
|
+
kind: 'EntityField',
|
|
81
|
+
name: 'id',
|
|
82
|
+
loc,
|
|
83
|
+
type: { kind: 'primitive', type: 'uuid' },
|
|
84
|
+
modifiers: ['primary', 'auto'],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
kind: 'EntityField',
|
|
88
|
+
name: 'title',
|
|
89
|
+
loc,
|
|
90
|
+
type: { kind: 'primitive', type: 'string' },
|
|
91
|
+
modifiers: [],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
kind: 'EntityField',
|
|
95
|
+
name: 'published',
|
|
96
|
+
loc,
|
|
97
|
+
type: { kind: 'primitive', type: 'bool' },
|
|
98
|
+
modifiers: [],
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
relationships: [
|
|
102
|
+
{
|
|
103
|
+
kind: 'EntityRelationship',
|
|
104
|
+
type: 'belongs_to',
|
|
105
|
+
entity: 'User',
|
|
106
|
+
cascade: 'delete',
|
|
107
|
+
loc,
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
}),
|
|
111
|
+
];
|
|
112
|
+
const result = generateTypeORMEntities(entities);
|
|
113
|
+
console.log('=== User Entity ===');
|
|
114
|
+
console.log(result.entities.User);
|
|
115
|
+
console.log('\n=== Post Entity ===');
|
|
116
|
+
console.log(result.entities.Post);
|
|
117
|
+
console.log('\n=== Tag Entity ===');
|
|
118
|
+
console.log(result.entities.Tag);
|
|
119
|
+
console.log('\n=== Data Source ===');
|
|
120
|
+
console.log(result.dataSource);
|
|
121
|
+
if (result.migration) {
|
|
122
|
+
console.log('\n=== Migration ===');
|
|
123
|
+
console.log(result.migration);
|
|
124
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|