@edgebasejs/cli 0.1.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/cli/src/cli.d.ts +3 -0
- package/dist/cli/src/cli.d.ts.map +1 -0
- package/dist/cli/src/cli.js +58 -0
- package/dist/cli/src/cli.js.map +1 -0
- package/dist/cli/src/commands/generate.d.ts +5 -0
- package/dist/cli/src/commands/generate.d.ts.map +1 -0
- package/dist/cli/src/commands/generate.js +89 -0
- package/dist/cli/src/commands/generate.js.map +1 -0
- package/dist/cli/src/commands/index.d.ts +4 -0
- package/dist/cli/src/commands/index.d.ts.map +1 -0
- package/dist/cli/src/commands/index.js +4 -0
- package/dist/cli/src/commands/index.js.map +1 -0
- package/dist/cli/src/commands/init.d.ts +5 -0
- package/dist/cli/src/commands/init.d.ts.map +1 -0
- package/dist/cli/src/commands/init.js +96 -0
- package/dist/cli/src/commands/init.js.map +1 -0
- package/dist/cli/src/commands/migrate.d.ts +5 -0
- package/dist/cli/src/commands/migrate.d.ts.map +1 -0
- package/dist/cli/src/commands/migrate.js +114 -0
- package/dist/cli/src/commands/migrate.js.map +1 -0
- package/dist/cli/src/generators/index.d.ts +4 -0
- package/dist/cli/src/generators/index.d.ts.map +1 -0
- package/dist/cli/src/generators/index.js +4 -0
- package/dist/cli/src/generators/index.js.map +1 -0
- package/dist/cli/src/generators/migration-generator.d.ts +16 -0
- package/dist/cli/src/generators/migration-generator.d.ts.map +1 -0
- package/dist/cli/src/generators/migration-generator.js +118 -0
- package/dist/cli/src/generators/migration-generator.js.map +1 -0
- package/dist/cli/src/generators/migration-sql-generator.d.ts +26 -0
- package/dist/cli/src/generators/migration-sql-generator.d.ts.map +1 -0
- package/dist/cli/src/generators/migration-sql-generator.js +253 -0
- package/dist/cli/src/generators/migration-sql-generator.js.map +1 -0
- package/dist/cli/src/generators/schema-loader.d.ts +22 -0
- package/dist/cli/src/generators/schema-loader.d.ts.map +1 -0
- package/dist/cli/src/generators/schema-loader.js +72 -0
- package/dist/cli/src/generators/schema-loader.js.map +1 -0
- package/dist/cli/src/generators/sdk-generator.d.ts +10 -0
- package/dist/cli/src/generators/sdk-generator.d.ts.map +1 -0
- package/dist/cli/src/generators/sdk-generator.js +185 -0
- package/dist/cli/src/generators/sdk-generator.js.map +1 -0
- package/dist/cli/src/generators/sdk-ts-generator.d.ts +6 -0
- package/dist/cli/src/generators/sdk-ts-generator.d.ts.map +1 -0
- package/dist/cli/src/generators/sdk-ts-generator.js +105 -0
- package/dist/cli/src/generators/sdk-ts-generator.js.map +1 -0
- package/dist/cli/src/index.d.ts +3 -0
- package/dist/cli/src/index.d.ts.map +1 -0
- package/dist/cli/src/index.js +3 -0
- package/dist/cli/src/index.js.map +1 -0
- package/dist/schema/src/builder/index.d.ts +3 -0
- package/dist/schema/src/builder/index.d.ts.map +1 -0
- package/dist/schema/src/builder/index.js +3 -0
- package/dist/schema/src/builder/index.js.map +1 -0
- package/dist/schema/src/builder/schema-builder.d.ts +54 -0
- package/dist/schema/src/builder/schema-builder.d.ts.map +1 -0
- package/dist/schema/src/builder/schema-builder.js +144 -0
- package/dist/schema/src/builder/schema-builder.js.map +1 -0
- package/dist/schema/src/index.d.ts +3 -0
- package/dist/schema/src/index.d.ts.map +1 -0
- package/dist/schema/src/index.js +3 -0
- package/dist/schema/src/index.js.map +1 -0
- package/dist/shared-types/src/admin.d.ts +101 -0
- package/dist/shared-types/src/admin.d.ts.map +1 -0
- package/dist/shared-types/src/admin.js +3 -0
- package/dist/shared-types/src/admin.js.map +1 -0
- package/dist/shared-types/src/auth.d.ts +27 -0
- package/dist/shared-types/src/auth.d.ts.map +1 -0
- package/dist/shared-types/src/auth.js +2 -0
- package/dist/shared-types/src/auth.js.map +1 -0
- package/dist/shared-types/src/index.d.ts +5 -0
- package/dist/shared-types/src/index.d.ts.map +1 -0
- package/dist/shared-types/src/index.js +5 -0
- package/dist/shared-types/src/index.js.map +1 -0
- package/dist/shared-types/src/schema.d.ts +34 -0
- package/dist/shared-types/src/schema.d.ts.map +1 -0
- package/dist/shared-types/src/schema.js +2 -0
- package/dist/shared-types/src/schema.js.map +1 -0
- package/dist/shared-types/src/sync.d.ts +37 -0
- package/dist/shared-types/src/sync.d.ts.map +1 -0
- package/dist/shared-types/src/sync.js +2 -0
- package/dist/shared-types/src/sync.js.map +1 -0
- package/package.json +31 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
// Generate SQL migrations from schema changes
|
|
2
|
+
/**
|
|
3
|
+
* Compare two schemas and generate diff
|
|
4
|
+
*/
|
|
5
|
+
export function diffSchemas(oldSchema, newSchema) {
|
|
6
|
+
const diff = {
|
|
7
|
+
newEntities: {},
|
|
8
|
+
modifiedEntities: {},
|
|
9
|
+
deletedEntities: {},
|
|
10
|
+
};
|
|
11
|
+
// Find new and modified entities
|
|
12
|
+
for (const [entityName, newEntity] of Object.entries(newSchema.entities)) {
|
|
13
|
+
const oldEntity = oldSchema.entities[entityName];
|
|
14
|
+
if (!oldEntity) {
|
|
15
|
+
diff.newEntities[entityName] = newEntity;
|
|
16
|
+
}
|
|
17
|
+
else if (JSON.stringify(oldEntity) !== JSON.stringify(newEntity)) {
|
|
18
|
+
diff.modifiedEntities[entityName] = {
|
|
19
|
+
oldSchema: oldEntity,
|
|
20
|
+
newSchema: newEntity,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// Find deleted entities
|
|
25
|
+
for (const [entityName, oldEntity] of Object.entries(oldSchema.entities)) {
|
|
26
|
+
if (!newSchema.entities[entityName]) {
|
|
27
|
+
diff.deletedEntities[entityName] = oldEntity;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return diff;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Convert FieldType to SQLite column definition
|
|
34
|
+
*/
|
|
35
|
+
function fieldTypeToSQL(fieldName, field, entityName) {
|
|
36
|
+
let sql = `${fieldName} `;
|
|
37
|
+
switch (field.type) {
|
|
38
|
+
case 'string':
|
|
39
|
+
sql += 'TEXT';
|
|
40
|
+
break;
|
|
41
|
+
case 'integer':
|
|
42
|
+
sql += 'INTEGER';
|
|
43
|
+
break;
|
|
44
|
+
case 'number':
|
|
45
|
+
sql += 'REAL';
|
|
46
|
+
break;
|
|
47
|
+
case 'boolean':
|
|
48
|
+
sql += 'INTEGER'; // SQLite doesn't have boolean
|
|
49
|
+
break;
|
|
50
|
+
case 'timestamp':
|
|
51
|
+
sql += 'INTEGER'; // Unix timestamp
|
|
52
|
+
break;
|
|
53
|
+
case 'text':
|
|
54
|
+
sql += 'TEXT';
|
|
55
|
+
break;
|
|
56
|
+
case 'json':
|
|
57
|
+
sql += 'TEXT'; // JSON as TEXT
|
|
58
|
+
break;
|
|
59
|
+
case 'reference':
|
|
60
|
+
sql += 'TEXT';
|
|
61
|
+
break;
|
|
62
|
+
default:
|
|
63
|
+
sql += 'TEXT';
|
|
64
|
+
}
|
|
65
|
+
if (field.primary) {
|
|
66
|
+
sql += ' PRIMARY KEY';
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
if (field.required) {
|
|
70
|
+
sql += ' NOT NULL';
|
|
71
|
+
}
|
|
72
|
+
if (field.default !== undefined) {
|
|
73
|
+
let defaultValue = field.default;
|
|
74
|
+
if (typeof field.default === 'string') {
|
|
75
|
+
defaultValue = `'${field.default}'`;
|
|
76
|
+
}
|
|
77
|
+
else if (field.type === 'boolean') {
|
|
78
|
+
defaultValue = field.default ? 1 : 0;
|
|
79
|
+
}
|
|
80
|
+
sql += ` DEFAULT ${defaultValue}`;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Add foreign key constraint
|
|
84
|
+
if (field.reference) {
|
|
85
|
+
sql += ` REFERENCES ${field.reference}(id)`;
|
|
86
|
+
}
|
|
87
|
+
return sql;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Generate CREATE TABLE statement
|
|
91
|
+
*/
|
|
92
|
+
function generateCreateTable(entityName, entity) {
|
|
93
|
+
const columns = Object.entries(entity.fields).map(([fieldName, field]) => fieldTypeToSQL(fieldName, field, entityName));
|
|
94
|
+
let sql = `CREATE TABLE ${entityName} (\n`;
|
|
95
|
+
sql += columns.map((col) => ` ${col}`).join(',\n');
|
|
96
|
+
sql += '\n);\n';
|
|
97
|
+
// Add indexes
|
|
98
|
+
if (entity.indexes && entity.indexes.length > 0) {
|
|
99
|
+
for (const index of entity.indexes) {
|
|
100
|
+
const indexName = `idx_${entityName}_${index.fields.join('_')}`;
|
|
101
|
+
const unique = index.unique ? 'UNIQUE' : '';
|
|
102
|
+
sql += `\nCREATE ${unique} INDEX ${indexName} ON ${entityName}(${index.fields.join(', ')});\n`;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return sql;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Generate DROP TABLE statement
|
|
109
|
+
*/
|
|
110
|
+
function generateDropTable(entityName) {
|
|
111
|
+
return `DROP TABLE IF EXISTS ${entityName};\n`;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Detect field-level changes between old and new entity schemas
|
|
115
|
+
*/
|
|
116
|
+
function detectFieldChanges(oldEntity, newEntity) {
|
|
117
|
+
const changes = {
|
|
118
|
+
added: {},
|
|
119
|
+
removed: {},
|
|
120
|
+
modified: {},
|
|
121
|
+
};
|
|
122
|
+
const oldFields = oldEntity.fields || {};
|
|
123
|
+
const newFields = newEntity.fields || {};
|
|
124
|
+
// Find added and modified fields
|
|
125
|
+
for (const [fieldName, newField] of Object.entries(newFields)) {
|
|
126
|
+
const oldField = oldFields[fieldName];
|
|
127
|
+
if (!oldField) {
|
|
128
|
+
changes.added[fieldName] = newField;
|
|
129
|
+
}
|
|
130
|
+
else if (JSON.stringify(oldField) !== JSON.stringify(newField)) {
|
|
131
|
+
changes.modified[fieldName] = { old: oldField, new: newField };
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Find removed fields
|
|
135
|
+
for (const [fieldName, oldField] of Object.entries(oldFields)) {
|
|
136
|
+
if (!newFields[fieldName]) {
|
|
137
|
+
changes.removed[fieldName] = oldField;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return changes;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Generate ALTER TABLE statements for added fields
|
|
144
|
+
*/
|
|
145
|
+
function generateAddColumnStatements(entityName, addedFields) {
|
|
146
|
+
const statements = [];
|
|
147
|
+
for (const [fieldName, field] of Object.entries(addedFields)) {
|
|
148
|
+
const columnDef = fieldTypeToSQL(fieldName, field, entityName);
|
|
149
|
+
statements.push(`ALTER TABLE ${entityName} ADD COLUMN ${columnDef};`);
|
|
150
|
+
}
|
|
151
|
+
return statements;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Generate ALTER TABLE statements for removed fields
|
|
155
|
+
* Note: SQLite 3.35.0+ supports DROP COLUMN, but older versions require table recreation
|
|
156
|
+
*/
|
|
157
|
+
function generateRemoveColumnStatements(entityName, removedFields) {
|
|
158
|
+
const statements = [];
|
|
159
|
+
for (const [fieldName] of Object.entries(removedFields)) {
|
|
160
|
+
statements.push(`ALTER TABLE ${entityName} DROP COLUMN ${fieldName};`);
|
|
161
|
+
}
|
|
162
|
+
return statements;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Generate ALTER TABLE statements for modified columns (using SQLite table recreation pattern)
|
|
166
|
+
*/
|
|
167
|
+
function generateModifyColumnStatements(entityName, oldSchema, newSchema) {
|
|
168
|
+
const statements = [];
|
|
169
|
+
const changes = detectFieldChanges(oldSchema, newSchema);
|
|
170
|
+
// If there are constraint or default changes, we need to recreate the table
|
|
171
|
+
const hasConstraintChanges = Object.keys(changes.modified).some((fieldName) => {
|
|
172
|
+
const { old, new: newFieldType } = changes.modified[fieldName];
|
|
173
|
+
return old.required !== newFieldType.required || old.default !== newFieldType.default;
|
|
174
|
+
});
|
|
175
|
+
if (hasConstraintChanges || Object.keys(changes.removed).length > 0) {
|
|
176
|
+
// SQLite table recreation pattern:
|
|
177
|
+
// 1. Rename old table
|
|
178
|
+
// 2. Create new table with new schema
|
|
179
|
+
// 3. Copy data from old table
|
|
180
|
+
// 4. Drop old table
|
|
181
|
+
const tempTableName = `${entityName}_old`;
|
|
182
|
+
statements.push(`-- Rename old table`);
|
|
183
|
+
statements.push(`ALTER TABLE ${entityName} RENAME TO ${tempTableName};`);
|
|
184
|
+
statements.push('');
|
|
185
|
+
statements.push(`-- Create new table with updated schema`);
|
|
186
|
+
statements.push(generateCreateTable(entityName, newSchema));
|
|
187
|
+
statements.push('');
|
|
188
|
+
statements.push(`-- Copy data from old table`);
|
|
189
|
+
const oldFields = Object.keys(oldSchema.fields);
|
|
190
|
+
const newFields = Object.keys(newSchema.fields);
|
|
191
|
+
const commonFields = oldFields.filter((f) => newFields.includes(f));
|
|
192
|
+
if (commonFields.length > 0) {
|
|
193
|
+
statements.push(`INSERT INTO ${entityName} (${commonFields.join(', ')}) ` +
|
|
194
|
+
`SELECT ${commonFields.join(', ')} FROM ${tempTableName};`);
|
|
195
|
+
statements.push('');
|
|
196
|
+
}
|
|
197
|
+
statements.push(`-- Drop old table`);
|
|
198
|
+
statements.push(`DROP TABLE ${tempTableName};`);
|
|
199
|
+
}
|
|
200
|
+
return statements;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Generate migration SQL
|
|
204
|
+
*/
|
|
205
|
+
export function generateMigrationSQL(diff) {
|
|
206
|
+
const up = [];
|
|
207
|
+
const down = [];
|
|
208
|
+
// Create new entities
|
|
209
|
+
for (const [entityName, entity] of Object.entries(diff.newEntities)) {
|
|
210
|
+
up.push(generateCreateTable(entityName, entity));
|
|
211
|
+
down.push(generateDropTable(entityName));
|
|
212
|
+
}
|
|
213
|
+
// Handle modified entities
|
|
214
|
+
for (const [entityName, { oldSchema, newSchema }] of Object.entries(diff.modifiedEntities)) {
|
|
215
|
+
const changes = detectFieldChanges(oldSchema, newSchema);
|
|
216
|
+
// Check if we need table recreation (constraint changes or removals)
|
|
217
|
+
const hasConstraintChanges = Object.keys(changes.modified).some((fieldName) => {
|
|
218
|
+
const { old, new: newFieldType } = changes.modified[fieldName];
|
|
219
|
+
return old.required !== newFieldType.required || old.default !== newFieldType.default;
|
|
220
|
+
});
|
|
221
|
+
const needsTableRecreation = hasConstraintChanges || Object.keys(changes.removed).length > 0;
|
|
222
|
+
if (needsTableRecreation) {
|
|
223
|
+
// Use table recreation pattern for constraint changes
|
|
224
|
+
up.push(...generateModifyColumnStatements(entityName, oldSchema, newSchema));
|
|
225
|
+
}
|
|
226
|
+
else if (Object.keys(changes.added).length > 0) {
|
|
227
|
+
// Simple case: only adding columns
|
|
228
|
+
up.push(...generateAddColumnStatements(entityName, changes.added));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// Delete removed entities
|
|
232
|
+
for (const [entityName] of Object.entries(diff.deletedEntities)) {
|
|
233
|
+
up.push(generateDropTable(entityName));
|
|
234
|
+
down.push('-- TODO: Recreate dropped table\n');
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
up: up.join('\n'),
|
|
238
|
+
down: down.join('\n'),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Generate migration filename
|
|
243
|
+
*/
|
|
244
|
+
export function generateMigrationFilename(description, version) {
|
|
245
|
+
const timestamp = String(version).padStart(4, '0');
|
|
246
|
+
const slug = description
|
|
247
|
+
.toLowerCase()
|
|
248
|
+
.replace(/\s+/g, '_')
|
|
249
|
+
.replace(/[^a-z0-9_]/g, '')
|
|
250
|
+
.substring(0, 50);
|
|
251
|
+
return `${timestamp}_${slug}.sql`;
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=migration-sql-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-sql-generator.js","sourceRoot":"","sources":["../../../../src/generators/migration-sql-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { DatabaseSchema } from '@edgebasejs/types';
|
|
2
|
+
/**
|
|
3
|
+
* Load schema from edgebase.schema.ts
|
|
4
|
+
*/
|
|
5
|
+
export declare function loadSchema(projectDir: string): Promise<DatabaseSchema>;
|
|
6
|
+
/**
|
|
7
|
+
* Load schema history
|
|
8
|
+
*/
|
|
9
|
+
export declare function loadSchemaHistory(projectDir: string): {
|
|
10
|
+
version: number;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
schema: DatabaseSchema;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Save schema history
|
|
16
|
+
*/
|
|
17
|
+
export declare function saveSchemaHistory(projectDir: string, history: {
|
|
18
|
+
version: number;
|
|
19
|
+
timestamp: number;
|
|
20
|
+
schema: DatabaseSchema;
|
|
21
|
+
}): void;
|
|
22
|
+
//# sourceMappingURL=schema-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-loader.d.ts","sourceRoot":"","sources":["../../../../src/generators/schema-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;GAEG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAqD5E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,cAAc,CAAC;CACxB,CAaA;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,GACtE,IAAI,CAGN"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Load and parse edgebase.schema.ts file
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
/**
|
|
5
|
+
* Load schema from edgebase.schema.ts
|
|
6
|
+
*/
|
|
7
|
+
export async function loadSchema(projectDir) {
|
|
8
|
+
const schemaPath = path.join(projectDir, 'edgebase.schema.ts');
|
|
9
|
+
if (!fs.existsSync(schemaPath)) {
|
|
10
|
+
throw new Error('edgebase.schema.ts not found');
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
// Read the TypeScript file content
|
|
14
|
+
const content = fs.readFileSync(schemaPath, 'utf-8');
|
|
15
|
+
// Extract the schema object using regex
|
|
16
|
+
// Look for: const schema: DatabaseSchema = { ... }
|
|
17
|
+
// or: export default { entities: { ... } }
|
|
18
|
+
const schemaMatch = content.match(/(?:const\s+\w+|export\s+default)\s*:\s*DatabaseSchema\s*=\s*(\{[\s\S]*?\n\})/);
|
|
19
|
+
if (!schemaMatch) {
|
|
20
|
+
// Try alternate format: export default { ... }
|
|
21
|
+
const defaultMatch = content.match(/export\s+default\s+(\{[\s\S]*?\n\})/);
|
|
22
|
+
if (defaultMatch) {
|
|
23
|
+
try {
|
|
24
|
+
// Use Function constructor to safely evaluate the object literal
|
|
25
|
+
// This is safer than eval() and allows JSON-like object syntax
|
|
26
|
+
const schema = new Function(`return ${defaultMatch[1]}`)();
|
|
27
|
+
if (!schema || !schema.entities) {
|
|
28
|
+
throw new Error('Invalid schema: must have entities property');
|
|
29
|
+
}
|
|
30
|
+
return schema;
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
throw new Error(`Failed to parse schema object: ${e instanceof Error ? e.message : String(e)}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
throw new Error('Could not find schema definition in edgebase.schema.ts');
|
|
37
|
+
}
|
|
38
|
+
// Parse the extracted schema object
|
|
39
|
+
const schemaStr = schemaMatch[1];
|
|
40
|
+
const schema = new Function(`return ${schemaStr}`)();
|
|
41
|
+
if (!schema || !schema.entities) {
|
|
42
|
+
throw new Error('Invalid schema: must have entities property');
|
|
43
|
+
}
|
|
44
|
+
return schema;
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
throw new Error(`Failed to load schema: ${error instanceof Error ? error.message : String(error)}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Load schema history
|
|
52
|
+
*/
|
|
53
|
+
export function loadSchemaHistory(projectDir) {
|
|
54
|
+
const historyPath = path.join(projectDir, '.edgebase', 'schema-history.json');
|
|
55
|
+
if (!fs.existsSync(historyPath)) {
|
|
56
|
+
return {
|
|
57
|
+
version: 0,
|
|
58
|
+
timestamp: Date.now(),
|
|
59
|
+
schema: { entities: {} },
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const content = fs.readFileSync(historyPath, 'utf-8');
|
|
63
|
+
return JSON.parse(content);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Save schema history
|
|
67
|
+
*/
|
|
68
|
+
export function saveSchemaHistory(projectDir, history) {
|
|
69
|
+
const historyPath = path.join(projectDir, '.edgebase', 'schema-history.json');
|
|
70
|
+
fs.writeFileSync(historyPath, JSON.stringify(history, null, 2));
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=schema-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-loader.js","sourceRoot":"","sources":["../../../../src/generators/schema-loader.ts"],"names":[],"mappings":"AAAA,yCAAyC;AAEzC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAI7B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAkB;IACjD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;IAE/D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IAED,IAAI,CAAC;QACH,mCAAmC;QACnC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAErD,wCAAwC;QACxC,mDAAmD;QACnD,2CAA2C;QAC3C,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAC/B,8EAA8E,CAC/E,CAAC;QAEF,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,+CAA+C;YAC/C,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;YAC1E,IAAI,YAAY,EAAE,CAAC;gBACjB,IAAI,CAAC;oBACH,iEAAiE;oBACjE,+DAA+D;oBAC/D,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,UAAU,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC3D,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;wBAChC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;oBACjE,CAAC;oBACD,OAAO,MAAM,CAAC;gBAChB,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,IAAI,KAAK,CACb,kCAAkC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAC/E,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;QAC5E,CAAC;QAED,oCAAoC;QACpC,MAAM,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,UAAU,SAAS,EAAE,CAAC,EAAE,CAAC;QAErD,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,0BAA0B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CACnF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,UAAkB;IAKlD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,qBAAqB,CAAC,CAAC;IAE9E,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,OAAO;YACL,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;SACzB,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACtD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,UAAkB,EAClB,OAAuE;IAEvE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,qBAAqB,CAAC,CAAC;IAC9E,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DatabaseSchema } from '@edgebasejs/types';
|
|
2
|
+
/**
|
|
3
|
+
* Generate SDK file
|
|
4
|
+
*/
|
|
5
|
+
export declare function generateSDK(schema: DatabaseSchema): string;
|
|
6
|
+
/**
|
|
7
|
+
* Format SDK for file output
|
|
8
|
+
*/
|
|
9
|
+
export declare function formatSDKFile(sdk: string): string;
|
|
10
|
+
//# sourceMappingURL=sdk-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-generator.d.ts","sourceRoot":"","sources":["../../../../src/generators/sdk-generator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAA6B,MAAM,mBAAmB,CAAC;AAoKnF;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAoC1D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEjD"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// TypeScript SDK generator from schema definitions
|
|
2
|
+
/**
|
|
3
|
+
* Convert field type to TypeScript type
|
|
4
|
+
*/
|
|
5
|
+
function getTSType(fieldType) {
|
|
6
|
+
switch (fieldType) {
|
|
7
|
+
case 'string':
|
|
8
|
+
case 'text':
|
|
9
|
+
return 'string';
|
|
10
|
+
case 'integer':
|
|
11
|
+
case 'number':
|
|
12
|
+
case 'timestamp':
|
|
13
|
+
return 'number';
|
|
14
|
+
case 'boolean':
|
|
15
|
+
return 'boolean';
|
|
16
|
+
case 'json':
|
|
17
|
+
return 'Record<string, any>';
|
|
18
|
+
case 'reference':
|
|
19
|
+
return 'string';
|
|
20
|
+
default:
|
|
21
|
+
return 'any';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Generate entity types
|
|
26
|
+
*/
|
|
27
|
+
function generateEntityTypes(entityName, schema) {
|
|
28
|
+
const lines = [];
|
|
29
|
+
// Entity interface
|
|
30
|
+
lines.push(`export interface ${pascalCase(entityName)} {`);
|
|
31
|
+
for (const [fieldName, field] of Object.entries(schema.fields)) {
|
|
32
|
+
const tsType = getTSType(field.type);
|
|
33
|
+
const optional = !field.required ? '?' : '';
|
|
34
|
+
lines.push(` ${camelCase(fieldName)}${optional}: ${tsType};`);
|
|
35
|
+
}
|
|
36
|
+
lines.push('}');
|
|
37
|
+
// Create input (without id and timestamps)
|
|
38
|
+
lines.push('');
|
|
39
|
+
lines.push(`export interface Create${pascalCase(entityName)}Input {`);
|
|
40
|
+
for (const [fieldName, field] of Object.entries(schema.fields)) {
|
|
41
|
+
if (!field.primary &&
|
|
42
|
+
!['createdAt', 'updatedAt', 'created_at', 'updated_at'].includes(fieldName)) {
|
|
43
|
+
const tsType = getTSType(field.type);
|
|
44
|
+
const optional = !field.required ? '?' : '';
|
|
45
|
+
lines.push(` ${camelCase(fieldName)}${optional}: ${tsType};`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
lines.push('}');
|
|
49
|
+
// Update input
|
|
50
|
+
lines.push('');
|
|
51
|
+
lines.push(`export interface Update${pascalCase(entityName)}Input {`);
|
|
52
|
+
for (const [fieldName, field] of Object.entries(schema.fields)) {
|
|
53
|
+
if (!field.primary &&
|
|
54
|
+
!['createdAt', 'updatedAt', 'created_at', 'updated_at'].includes(fieldName)) {
|
|
55
|
+
const tsType = getTSType(field.type);
|
|
56
|
+
lines.push(` ${camelCase(fieldName)}?: ${tsType};`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
lines.push('}');
|
|
60
|
+
return lines.join('\n');
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Generate query hooks
|
|
64
|
+
*/
|
|
65
|
+
function generateQueryHooks(entityName) {
|
|
66
|
+
const pascalName = pascalCase(entityName);
|
|
67
|
+
const camelName = camelCase(entityName);
|
|
68
|
+
return `
|
|
69
|
+
/**
|
|
70
|
+
* Hook to query ${entityName}
|
|
71
|
+
*/
|
|
72
|
+
export function use${pascalName}(
|
|
73
|
+
filters?: Record<string, any>,
|
|
74
|
+
options?: { autoSync?: boolean }
|
|
75
|
+
) {
|
|
76
|
+
// This will be bound to the EdgeBase client at runtime
|
|
77
|
+
// Returns: { data: ${pascalName}[], loading: boolean, error: Error | null, refetch: () => void }
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Hook to get a single ${entityName} by ID
|
|
82
|
+
*/
|
|
83
|
+
export function use${pascalName}ById(id: string, options?: { autoSync?: boolean }) {
|
|
84
|
+
// Returns: { data: ${pascalName} | null, loading: boolean, error: Error | null }
|
|
85
|
+
}
|
|
86
|
+
`;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Generate mutation hooks
|
|
90
|
+
*/
|
|
91
|
+
function generateMutationHooks(entityName) {
|
|
92
|
+
const pascalName = pascalCase(entityName);
|
|
93
|
+
const camelName = camelCase(entityName);
|
|
94
|
+
return `
|
|
95
|
+
/**
|
|
96
|
+
* Hook to create a new ${entityName}
|
|
97
|
+
*/
|
|
98
|
+
export function useCreate${pascalName}() {
|
|
99
|
+
// Returns: { create: (input: Create${pascalName}Input) => Promise<${pascalName}>, loading: boolean, error: Error | null }
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Hook to update a ${entityName}
|
|
104
|
+
*/
|
|
105
|
+
export function useUpdate${pascalName}() {
|
|
106
|
+
// Returns: { update: (id: string, input: Update${pascalName}Input) => Promise<${pascalName}>, loading: boolean, error: Error | null }
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Hook to delete a ${entityName}
|
|
111
|
+
*/
|
|
112
|
+
export function useDelete${pascalName}() {
|
|
113
|
+
// Returns: { delete: (id: string) => Promise<void>, loading: boolean, error: Error | null }
|
|
114
|
+
}
|
|
115
|
+
`;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Generate access rules validation
|
|
119
|
+
*/
|
|
120
|
+
function generateAccessRulesValidator(entityName, accessRules) {
|
|
121
|
+
if (!accessRules) {
|
|
122
|
+
return `export const ${entityName}AccessRules = { canCreate: true, canRead: true, canUpdate: true, canDelete: true };`;
|
|
123
|
+
}
|
|
124
|
+
return `
|
|
125
|
+
/**
|
|
126
|
+
* Access rules for ${entityName}
|
|
127
|
+
* These are mirrored from the server for client-side UX optimization
|
|
128
|
+
*/
|
|
129
|
+
export const ${entityName}AccessRules = {
|
|
130
|
+
canCreate: ${!!accessRules.create},
|
|
131
|
+
canRead: ${!!accessRules.read},
|
|
132
|
+
canUpdate: ${!!accessRules.update},
|
|
133
|
+
canDelete: ${!!accessRules.delete},
|
|
134
|
+
};
|
|
135
|
+
`;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Case conversion helpers
|
|
139
|
+
*/
|
|
140
|
+
function camelCase(str) {
|
|
141
|
+
return str.replace(/_([a-z])/g, (g) => g[1].toUpperCase());
|
|
142
|
+
}
|
|
143
|
+
function pascalCase(str) {
|
|
144
|
+
return str.charAt(0).toUpperCase() + camelCase(str).slice(1);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Generate SDK file
|
|
148
|
+
*/
|
|
149
|
+
export function generateSDK(schema) {
|
|
150
|
+
const lines = [];
|
|
151
|
+
lines.push('// Auto-generated SDK - Do not edit manually');
|
|
152
|
+
lines.push('// Generated from schema definition');
|
|
153
|
+
lines.push('');
|
|
154
|
+
lines.push('import type { EdgeBaseClient } from "@edgebasejs/client-core";');
|
|
155
|
+
lines.push('');
|
|
156
|
+
// Generate types for each entity
|
|
157
|
+
for (const [entityName, entitySchema] of Object.entries(schema.entities)) {
|
|
158
|
+
lines.push(`// ${pascalCase(entityName)} entity`);
|
|
159
|
+
lines.push(generateEntityTypes(entityName, entitySchema));
|
|
160
|
+
lines.push('');
|
|
161
|
+
}
|
|
162
|
+
// Generate hooks for each entity
|
|
163
|
+
lines.push('// Hooks and utilities');
|
|
164
|
+
lines.push('');
|
|
165
|
+
for (const [entityName] of Object.entries(schema.entities)) {
|
|
166
|
+
lines.push(`// ${entityName} queries`);
|
|
167
|
+
lines.push(generateQueryHooks(entityName));
|
|
168
|
+
lines.push('');
|
|
169
|
+
lines.push(`// ${entityName} mutations`);
|
|
170
|
+
lines.push(generateMutationHooks(entityName));
|
|
171
|
+
lines.push('');
|
|
172
|
+
const entitySchema = schema.entities[entityName];
|
|
173
|
+
lines.push(`// ${entityName} access rules`);
|
|
174
|
+
lines.push(generateAccessRulesValidator(entityName, entitySchema.accessRules));
|
|
175
|
+
lines.push('');
|
|
176
|
+
}
|
|
177
|
+
return lines.join('\n');
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Format SDK for file output
|
|
181
|
+
*/
|
|
182
|
+
export function formatSDKFile(sdk) {
|
|
183
|
+
return `${sdk}\n`;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=sdk-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-generator.js","sourceRoot":"","sources":["../../../../src/generators/sdk-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-ts-generator.d.ts","sourceRoot":"","sources":["../../../../src/generators/sdk-ts-generator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAA2B,MAAM,mBAAmB,CAAC;AAiFjF;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAoC1D"}
|