@opensaas/stack-cli 0.3.0 → 0.5.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.
Files changed (105) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +193 -0
  3. package/dist/commands/generate.d.ts.map +1 -1
  4. package/dist/commands/generate.js +4 -13
  5. package/dist/commands/generate.js.map +1 -1
  6. package/dist/commands/migrate.d.ts +9 -0
  7. package/dist/commands/migrate.d.ts.map +1 -0
  8. package/dist/commands/migrate.js +473 -0
  9. package/dist/commands/migrate.js.map +1 -0
  10. package/dist/generator/context.d.ts.map +1 -1
  11. package/dist/generator/context.js +20 -5
  12. package/dist/generator/context.js.map +1 -1
  13. package/dist/generator/index.d.ts +1 -1
  14. package/dist/generator/index.d.ts.map +1 -1
  15. package/dist/generator/index.js +1 -1
  16. package/dist/generator/index.js.map +1 -1
  17. package/dist/generator/lists.d.ts.map +1 -1
  18. package/dist/generator/lists.js +33 -1
  19. package/dist/generator/lists.js.map +1 -1
  20. package/dist/generator/prisma-extensions.d.ts +11 -0
  21. package/dist/generator/prisma-extensions.d.ts.map +1 -0
  22. package/dist/generator/prisma-extensions.js +134 -0
  23. package/dist/generator/prisma-extensions.js.map +1 -0
  24. package/dist/generator/prisma.d.ts.map +1 -1
  25. package/dist/generator/prisma.js +4 -0
  26. package/dist/generator/prisma.js.map +1 -1
  27. package/dist/generator/types.d.ts.map +1 -1
  28. package/dist/generator/types.js +151 -17
  29. package/dist/generator/types.js.map +1 -1
  30. package/dist/index.js +3 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/mcp/lib/documentation-provider.d.ts +23 -0
  33. package/dist/mcp/lib/documentation-provider.d.ts.map +1 -1
  34. package/dist/mcp/lib/documentation-provider.js +471 -0
  35. package/dist/mcp/lib/documentation-provider.js.map +1 -1
  36. package/dist/mcp/lib/wizards/migration-wizard.d.ts +80 -0
  37. package/dist/mcp/lib/wizards/migration-wizard.d.ts.map +1 -0
  38. package/dist/mcp/lib/wizards/migration-wizard.js +499 -0
  39. package/dist/mcp/lib/wizards/migration-wizard.js.map +1 -0
  40. package/dist/mcp/server/index.d.ts.map +1 -1
  41. package/dist/mcp/server/index.js +103 -0
  42. package/dist/mcp/server/index.js.map +1 -1
  43. package/dist/mcp/server/stack-mcp-server.d.ts +85 -0
  44. package/dist/mcp/server/stack-mcp-server.d.ts.map +1 -1
  45. package/dist/mcp/server/stack-mcp-server.js +219 -0
  46. package/dist/mcp/server/stack-mcp-server.js.map +1 -1
  47. package/dist/migration/generators/migration-generator.d.ts +60 -0
  48. package/dist/migration/generators/migration-generator.d.ts.map +1 -0
  49. package/dist/migration/generators/migration-generator.js +510 -0
  50. package/dist/migration/generators/migration-generator.js.map +1 -0
  51. package/dist/migration/introspectors/index.d.ts +12 -0
  52. package/dist/migration/introspectors/index.d.ts.map +1 -0
  53. package/dist/migration/introspectors/index.js +10 -0
  54. package/dist/migration/introspectors/index.js.map +1 -0
  55. package/dist/migration/introspectors/keystone-introspector.d.ts +59 -0
  56. package/dist/migration/introspectors/keystone-introspector.d.ts.map +1 -0
  57. package/dist/migration/introspectors/keystone-introspector.js +229 -0
  58. package/dist/migration/introspectors/keystone-introspector.js.map +1 -0
  59. package/dist/migration/introspectors/nextjs-introspector.d.ts +59 -0
  60. package/dist/migration/introspectors/nextjs-introspector.d.ts.map +1 -0
  61. package/dist/migration/introspectors/nextjs-introspector.js +159 -0
  62. package/dist/migration/introspectors/nextjs-introspector.js.map +1 -0
  63. package/dist/migration/introspectors/prisma-introspector.d.ts +45 -0
  64. package/dist/migration/introspectors/prisma-introspector.d.ts.map +1 -0
  65. package/dist/migration/introspectors/prisma-introspector.js +190 -0
  66. package/dist/migration/introspectors/prisma-introspector.js.map +1 -0
  67. package/dist/migration/types.d.ts +86 -0
  68. package/dist/migration/types.d.ts.map +1 -0
  69. package/dist/migration/types.js +5 -0
  70. package/dist/migration/types.js.map +1 -0
  71. package/package.json +12 -9
  72. package/src/commands/__snapshots__/generate.test.ts.snap +92 -21
  73. package/src/commands/generate.ts +8 -19
  74. package/src/commands/migrate.ts +534 -0
  75. package/src/generator/__snapshots__/context.test.ts.snap +60 -15
  76. package/src/generator/__snapshots__/types.test.ts.snap +689 -95
  77. package/src/generator/context.test.ts +3 -1
  78. package/src/generator/context.ts +20 -5
  79. package/src/generator/index.ts +1 -1
  80. package/src/generator/lists.ts +39 -1
  81. package/src/generator/prisma-extensions.ts +159 -0
  82. package/src/generator/prisma.ts +5 -0
  83. package/src/generator/types.ts +204 -17
  84. package/src/index.ts +4 -0
  85. package/src/mcp/lib/documentation-provider.ts +507 -0
  86. package/src/mcp/lib/wizards/migration-wizard.ts +584 -0
  87. package/src/mcp/server/index.ts +121 -0
  88. package/src/mcp/server/stack-mcp-server.ts +243 -0
  89. package/src/migration/generators/migration-generator.ts +675 -0
  90. package/src/migration/introspectors/index.ts +12 -0
  91. package/src/migration/introspectors/keystone-introspector.ts +296 -0
  92. package/src/migration/introspectors/nextjs-introspector.ts +209 -0
  93. package/src/migration/introspectors/prisma-introspector.ts +233 -0
  94. package/src/migration/types.ts +92 -0
  95. package/tests/introspectors/keystone-introspector.test.ts +255 -0
  96. package/tests/introspectors/nextjs-introspector.test.ts +302 -0
  97. package/tests/introspectors/prisma-introspector.test.ts +268 -0
  98. package/tests/migration-generator.test.ts +592 -0
  99. package/tests/migration-wizard.test.ts +442 -0
  100. package/tsconfig.tsbuildinfo +1 -1
  101. package/dist/generator/type-patcher.d.ts +0 -13
  102. package/dist/generator/type-patcher.d.ts.map +0 -1
  103. package/dist/generator/type-patcher.js +0 -68
  104. package/dist/generator/type-patcher.js.map +0 -1
  105. package/src/generator/type-patcher.ts +0 -93
@@ -0,0 +1,510 @@
1
+ /**
2
+ * Migration Config Generator
3
+ *
4
+ * Generates opensaas.config.ts from migration session data.
5
+ */
6
+ import { PrismaIntrospector } from '../introspectors/prisma-introspector.js';
7
+ import { KeystoneIntrospector } from '../introspectors/keystone-introspector.js';
8
+ export class MigrationGenerator {
9
+ prismaIntrospector;
10
+ keystoneIntrospector;
11
+ constructor() {
12
+ this.prismaIntrospector = new PrismaIntrospector();
13
+ this.keystoneIntrospector = new KeystoneIntrospector();
14
+ }
15
+ /**
16
+ * Generate migration output from session
17
+ */
18
+ async generate(session) {
19
+ const { projectType, analysis, answers } = session;
20
+ // Get full schema if available
21
+ let schema;
22
+ try {
23
+ if (projectType === 'prisma') {
24
+ schema = await this.prismaIntrospector.introspect(analysis.cwd);
25
+ }
26
+ else if (projectType === 'keystone') {
27
+ schema = await this.keystoneIntrospector.introspect(analysis.cwd);
28
+ }
29
+ }
30
+ catch {
31
+ // Continue without schema - will generate example config
32
+ }
33
+ // Collect used field types for imports
34
+ const usedFieldTypes = new Set(['text']); // Always need text
35
+ const warnings = [];
36
+ // Generate lists
37
+ const lists = this.generateLists(schema, answers, usedFieldTypes, warnings);
38
+ // Generate access control helpers
39
+ const accessHelpers = this.generateAccessHelpers(answers);
40
+ // Generate database config
41
+ const dbConfig = this.generateDatabaseConfig(answers.db_provider || analysis.provider || 'sqlite');
42
+ // Determine if using auth
43
+ const useAuth = answers.enable_auth === true;
44
+ // Generate imports
45
+ const imports = this.generateImports(usedFieldTypes, useAuth, dbConfig.provider);
46
+ // Generate the full config
47
+ const configContent = this.assembleConfig({
48
+ imports,
49
+ accessHelpers,
50
+ dbConfig,
51
+ lists,
52
+ useAuth,
53
+ authMethods: answers.auth_methods || ['email-password'],
54
+ adminBasePath: answers.admin_base_path || '/admin',
55
+ });
56
+ // Generate dependencies list
57
+ const dependencies = this.generateDependencies(dbConfig.provider, useAuth);
58
+ // Generate additional files
59
+ const files = this.generateAdditionalFiles(answers, dbConfig.provider);
60
+ // Generate next steps
61
+ const steps = this.generateSteps(useAuth, dbConfig.provider);
62
+ // Add warnings from introspection
63
+ if (schema) {
64
+ const introspectorWarnings = projectType === 'prisma'
65
+ ? this.prismaIntrospector.getWarnings(schema)
66
+ : this.keystoneIntrospector.getWarnings(schema);
67
+ warnings.push(...introspectorWarnings);
68
+ }
69
+ return {
70
+ configContent,
71
+ dependencies,
72
+ files,
73
+ steps,
74
+ warnings,
75
+ };
76
+ }
77
+ /**
78
+ * Generate list definitions from schema
79
+ */
80
+ generateLists(schema, answers, usedFieldTypes, warnings) {
81
+ if (!schema || schema.models.length === 0) {
82
+ // No schema, generate example lists
83
+ usedFieldTypes.add('timestamp');
84
+ return ` // Add your lists here
85
+ // Example:
86
+ // Post: list({
87
+ // fields: {
88
+ // title: text({ validation: { isRequired: true } }),
89
+ // content: text(),
90
+ // createdAt: timestamp({ defaultValue: { kind: 'now' } }),
91
+ // },
92
+ // }),`;
93
+ }
94
+ // Filter out auth models if using auth plugin
95
+ const skipAuthModels = answers.skip_auth_models === true;
96
+ const authModelNames = ['User', 'Account', 'Session', 'Verification'];
97
+ const modelsToGenerate = schema.models.filter((model) => {
98
+ if (skipAuthModels && authModelNames.includes(model.name)) {
99
+ return false;
100
+ }
101
+ return true;
102
+ });
103
+ // Get models that should have owner access
104
+ const ownerModels = new Set(answers.models_with_owner || []);
105
+ // Generate each list
106
+ const listDefinitions = modelsToGenerate.map((model) => {
107
+ return this.generateList(model, schema, ownerModels.has(model.name), answers, usedFieldTypes, warnings);
108
+ });
109
+ return listDefinitions.join('\n');
110
+ }
111
+ /**
112
+ * Generate a single list definition
113
+ */
114
+ generateList(model, schema, hasOwnerAccess, answers, usedFieldTypes, warnings) {
115
+ const fields = [];
116
+ // Skip system fields (id, createdAt, updatedAt) - OpenSaaS adds these automatically
117
+ const systemFields = ['id', 'createdAt', 'updatedAt'];
118
+ for (const field of model.fields) {
119
+ if (systemFields.includes(field.name))
120
+ continue;
121
+ if (field.isId)
122
+ continue; // Skip ID fields
123
+ const fieldDef = this.generateField(field, schema, usedFieldTypes, warnings);
124
+ if (fieldDef) {
125
+ fields.push(` ${field.name}: ${fieldDef},`);
126
+ }
127
+ }
128
+ // Generate access control
129
+ const access = this.generateListAccess(hasOwnerAccess, model, answers);
130
+ const fieldsBlock = fields.length > 0 ? `\n${fields.join('\n')}\n ` : '';
131
+ return ` ${model.name}: list({
132
+ fields: {${fieldsBlock}},${access}
133
+ }),`;
134
+ }
135
+ /**
136
+ * Generate a field definition
137
+ */
138
+ generateField(field, schema, usedFieldTypes, warnings) {
139
+ // Handle relationships
140
+ if (field.relation) {
141
+ usedFieldTypes.add('relationship');
142
+ // Find the related model and back-reference field
143
+ const relatedModel = schema.models.find((m) => m.name === field.relation.model);
144
+ const backRef = relatedModel?.fields.find((f) => f.relation && f.relation.model === field.type);
145
+ const ref = backRef ? `${field.relation.model}.${backRef.name}` : field.relation.model;
146
+ const many = field.isList ? ', many: true' : '';
147
+ return `relationship({ ref: '${ref}'${many} })`;
148
+ }
149
+ // Handle enums as select fields
150
+ const enumDef = schema.enums.find((e) => e.name === field.type);
151
+ if (enumDef) {
152
+ usedFieldTypes.add('select');
153
+ const enumOptions = enumDef.values.map((v) => `{ label: '${v}', value: '${v}' }`).join(', ');
154
+ let selectOptions = `options: [${enumOptions}]`;
155
+ if (field.defaultValue) {
156
+ const defaultVal = field.defaultValue.replace(/^["']|["']$/g, '');
157
+ selectOptions += `, defaultValue: '${defaultVal}'`;
158
+ }
159
+ return `select({ ${selectOptions} })`;
160
+ }
161
+ // Map Prisma/Keystone types to OpenSaaS
162
+ const mapping = this.prismaIntrospector.mapPrismaTypeToOpenSaas(field.type);
163
+ usedFieldTypes.add(mapping.import);
164
+ // Build options
165
+ const options = [];
166
+ if (field.isRequired && !field.defaultValue) {
167
+ options.push('validation: { isRequired: true }');
168
+ }
169
+ if (field.isUnique) {
170
+ options.push("isIndexed: 'unique'");
171
+ }
172
+ // Handle default values
173
+ if (field.defaultValue) {
174
+ if (field.type === 'DateTime' && field.defaultValue === 'now()') {
175
+ options.push("defaultValue: { kind: 'now' }");
176
+ }
177
+ else if (field.type === 'Boolean') {
178
+ options.push(`defaultValue: ${field.defaultValue}`);
179
+ }
180
+ // Other defaults are harder to map automatically
181
+ }
182
+ // Generate unsupported type warning
183
+ if (['BigInt', 'Decimal', 'Bytes'].includes(field.type)) {
184
+ warnings.push(`Field "${field.name}" uses unsupported type "${field.type}" - mapped to text()`);
185
+ }
186
+ const optionsStr = options.length > 0 ? `{ ${options.join(', ')} }` : '';
187
+ return `${mapping.type}(${optionsStr})`;
188
+ }
189
+ /**
190
+ * Generate list access control
191
+ */
192
+ generateListAccess(hasOwnerAccess, model, answers) {
193
+ const defaultAccess = answers.default_access || 'public-read-auth-write';
194
+ if (hasOwnerAccess) {
195
+ // Find the user relationship field
196
+ const userField = model.fields.find((f) => f.relation?.model === 'User' ||
197
+ f.name.toLowerCase().includes('author') ||
198
+ f.name.toLowerCase().includes('owner') ||
199
+ f.name.toLowerCase().includes('user'));
200
+ const ownerField = userField?.name || 'author';
201
+ const ownerIdField = ownerField.endsWith('Id') ? ownerField : `${ownerField}Id`;
202
+ return `
203
+ access: {
204
+ operation: {
205
+ query: () => true,
206
+ create: ({ session }) => !!session,
207
+ update: isOwner,
208
+ delete: isOwner,
209
+ },
210
+ filter: {
211
+ // Optionally filter queries to only show user's own items
212
+ // query: ({ session }) => session ? { ${ownerIdField}: { equals: session.userId } } : true,
213
+ },
214
+ },`;
215
+ }
216
+ // Generate based on default access pattern
217
+ switch (defaultAccess) {
218
+ case 'authenticated-only':
219
+ return `
220
+ access: {
221
+ operation: {
222
+ query: ({ session }) => !!session,
223
+ create: ({ session }) => !!session,
224
+ update: ({ session }) => !!session,
225
+ delete: ({ session }) => !!session,
226
+ },
227
+ },`;
228
+ case 'owner-only':
229
+ return `
230
+ access: {
231
+ operation: {
232
+ query: ({ session }) => !!session,
233
+ create: ({ session }) => !!session,
234
+ update: ({ session }) => !!session,
235
+ delete: ({ session }) => !!session,
236
+ },
237
+ // Add filter to scope to user's own items:
238
+ // filter: { query: ({ session }) => ({ userId: { equals: session?.userId } }) },
239
+ },`;
240
+ case 'admin-only':
241
+ return `
242
+ access: {
243
+ operation: {
244
+ query: ({ session }) => session?.role === 'admin',
245
+ create: ({ session }) => session?.role === 'admin',
246
+ update: ({ session }) => session?.role === 'admin',
247
+ delete: ({ session }) => session?.role === 'admin',
248
+ },
249
+ },`;
250
+ case 'public-read-auth-write':
251
+ default:
252
+ return `
253
+ access: {
254
+ operation: {
255
+ query: () => true,
256
+ create: ({ session }) => !!session,
257
+ update: ({ session }) => !!session,
258
+ delete: ({ session }) => !!session,
259
+ },
260
+ },`;
261
+ }
262
+ }
263
+ /**
264
+ * Generate access control helper functions
265
+ */
266
+ generateAccessHelpers(answers) {
267
+ const helpers = [];
268
+ const ownerModels = answers.models_with_owner || [];
269
+ if (ownerModels.length > 0) {
270
+ helpers.push(`/**
271
+ * Access control helpers
272
+ */
273
+
274
+ // Check if user owns the item (based on authorId or userId)
275
+ const isOwner: AccessControl = ({ session, item }) => {
276
+ if (!session) return false
277
+ // Try authorId first, then userId
278
+ const ownerId = (item as any)?.authorId || (item as any)?.userId
279
+ return ownerId === session.userId
280
+ }
281
+ `);
282
+ }
283
+ return helpers.join('\n');
284
+ }
285
+ /**
286
+ * Generate database configuration
287
+ */
288
+ generateDatabaseConfig(provider) {
289
+ switch (provider) {
290
+ case 'postgresql':
291
+ return {
292
+ provider: 'postgresql',
293
+ imports: ["import { PrismaPg } from '@prisma/adapter-pg'", "import pg from 'pg'"],
294
+ configCode: ` db: {
295
+ provider: 'postgresql',
296
+ prismaClientConstructor: (PrismaClient) => {
297
+ const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL })
298
+ const adapter = new PrismaPg(pool)
299
+ return new PrismaClient({ adapter })
300
+ },
301
+ },`,
302
+ };
303
+ case 'mysql':
304
+ return {
305
+ provider: 'mysql',
306
+ imports: ["import { PrismaPlanetScale } from '@prisma/adapter-planetscale'"],
307
+ configCode: ` db: {
308
+ provider: 'mysql',
309
+ prismaClientConstructor: (PrismaClient) => {
310
+ const adapter = new PrismaPlanetScale({
311
+ url: process.env.DATABASE_URL!,
312
+ })
313
+ return new PrismaClient({ adapter })
314
+ },
315
+ },`,
316
+ };
317
+ case 'sqlite':
318
+ default:
319
+ return {
320
+ provider: 'sqlite',
321
+ imports: ["import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3'"],
322
+ configCode: ` db: {
323
+ provider: 'sqlite',
324
+ prismaClientConstructor: (PrismaClient) => {
325
+ const adapter = new PrismaBetterSqlite3({
326
+ url: process.env.DATABASE_URL || 'file:./dev.db',
327
+ })
328
+ return new PrismaClient({ adapter })
329
+ },
330
+ },`,
331
+ };
332
+ }
333
+ }
334
+ /**
335
+ * Generate import statements
336
+ */
337
+ generateImports(usedFieldTypes, useAuth, dbProvider) {
338
+ const imports = [];
339
+ // Core imports
340
+ imports.push("import { config, list } from '@opensaas/stack-core'");
341
+ // Field imports
342
+ const fieldTypes = Array.from(usedFieldTypes).sort();
343
+ imports.push(`import { ${fieldTypes.join(', ')} } from '@opensaas/stack-core/fields'`);
344
+ // Auth imports
345
+ if (useAuth) {
346
+ imports.push("import { authPlugin } from '@opensaas/stack-auth'");
347
+ imports.push("import type { AccessControl } from '@opensaas/stack-core'");
348
+ }
349
+ // Database adapter imports
350
+ const dbConfig = this.generateDatabaseConfig(dbProvider);
351
+ imports.push(...dbConfig.imports);
352
+ return imports.join('\n');
353
+ }
354
+ /**
355
+ * Assemble the complete config file
356
+ */
357
+ assembleConfig(options) {
358
+ const { imports, accessHelpers, dbConfig, lists, useAuth, authMethods, adminBasePath } = options;
359
+ // Generate auth plugin config
360
+ let authPluginStr = '';
361
+ if (useAuth) {
362
+ const authOptions = [];
363
+ if (authMethods.includes('email-password')) {
364
+ authOptions.push(` emailAndPassword: {
365
+ enabled: true,
366
+ minPasswordLength: 8,
367
+ },`);
368
+ }
369
+ if (authMethods.includes('magic-link')) {
370
+ authOptions.push(` magicLink: {
371
+ enabled: true,
372
+ },`);
373
+ }
374
+ // OAuth providers would need additional setup
375
+ if (authMethods.includes('google')) {
376
+ authOptions.push(` // Uncomment and configure Google OAuth:
377
+ // google: {
378
+ // clientId: process.env.GOOGLE_CLIENT_ID!,
379
+ // clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
380
+ // },`);
381
+ }
382
+ if (authMethods.includes('github')) {
383
+ authOptions.push(` // Uncomment and configure GitHub OAuth:
384
+ // github: {
385
+ // clientId: process.env.GITHUB_CLIENT_ID!,
386
+ // clientSecret: process.env.GITHUB_CLIENT_SECRET!,
387
+ // },`);
388
+ }
389
+ authOptions.push(` sessionFields: ['userId', 'email', 'name'],`);
390
+ authPluginStr = ` authPlugin({
391
+ ${authOptions.join('\n')}
392
+ }),`;
393
+ }
394
+ // Build config body
395
+ const pluginsBlock = useAuth
396
+ ? ` plugins: [
397
+ ${authPluginStr}
398
+ ],
399
+
400
+ `
401
+ : '';
402
+ const configBody = `export default config({
403
+ ${pluginsBlock}${dbConfig.configCode}
404
+ lists: {
405
+ ${lists}
406
+ },
407
+ ui: {
408
+ basePath: '${adminBasePath}',
409
+ },
410
+ })`;
411
+ return `${imports}
412
+
413
+ ${accessHelpers}${configBody}
414
+ `;
415
+ }
416
+ /**
417
+ * Generate list of dependencies to install
418
+ */
419
+ generateDependencies(dbProvider, useAuth) {
420
+ const deps = [
421
+ '@opensaas/stack-core',
422
+ '@opensaas/stack-ui',
423
+ '@prisma/client',
424
+ 'prisma',
425
+ ];
426
+ // Database adapter deps
427
+ switch (dbProvider) {
428
+ case 'postgresql':
429
+ deps.push('@prisma/adapter-pg', 'pg', '@types/pg');
430
+ break;
431
+ case 'mysql':
432
+ deps.push('@prisma/adapter-planetscale');
433
+ break;
434
+ case 'sqlite':
435
+ default:
436
+ deps.push('@prisma/adapter-better-sqlite3');
437
+ break;
438
+ }
439
+ // Auth deps
440
+ if (useAuth) {
441
+ deps.push('@opensaas/stack-auth', 'better-auth');
442
+ }
443
+ return deps;
444
+ }
445
+ /**
446
+ * Generate additional files if needed
447
+ */
448
+ generateAdditionalFiles(answers, dbProvider) {
449
+ const files = [];
450
+ // Generate .env.example
451
+ const envVars = ['# Database'];
452
+ // Database URL based on provider
453
+ switch (dbProvider) {
454
+ case 'postgresql':
455
+ envVars.push('DATABASE_URL="postgresql://user:password@localhost:5432/mydb"');
456
+ break;
457
+ case 'mysql':
458
+ envVars.push('DATABASE_URL="mysql://user:password@localhost:3306/mydb"');
459
+ break;
460
+ case 'sqlite':
461
+ default:
462
+ envVars.push('DATABASE_URL="file:./dev.db"');
463
+ break;
464
+ }
465
+ envVars.push('');
466
+ if (answers.enable_auth) {
467
+ envVars.push('# Auth');
468
+ envVars.push('BETTER_AUTH_SECRET="generate-with-openssl-rand-base64-32"');
469
+ envVars.push('BETTER_AUTH_URL="http://localhost:3000"');
470
+ envVars.push('');
471
+ const authMethods = answers.auth_methods || [];
472
+ if (authMethods.includes('google')) {
473
+ envVars.push('# Google OAuth (optional)');
474
+ envVars.push('GOOGLE_CLIENT_ID=""');
475
+ envVars.push('GOOGLE_CLIENT_SECRET=""');
476
+ envVars.push('');
477
+ }
478
+ if (authMethods.includes('github')) {
479
+ envVars.push('# GitHub OAuth (optional)');
480
+ envVars.push('GITHUB_CLIENT_ID=""');
481
+ envVars.push('GITHUB_CLIENT_SECRET=""');
482
+ envVars.push('');
483
+ }
484
+ }
485
+ files.push({
486
+ path: '.env.example',
487
+ content: envVars.join('\n'),
488
+ language: 'bash',
489
+ description: 'Environment variables template',
490
+ });
491
+ return files;
492
+ }
493
+ /**
494
+ * Generate next steps
495
+ */
496
+ generateSteps(useAuth, dbProvider) {
497
+ const steps = [
498
+ 'Save the generated config to `opensaas.config.ts`',
499
+ 'Copy `.env.example` to `.env` and fill in values',
500
+ ];
501
+ if (useAuth) {
502
+ steps.push('Generate BETTER_AUTH_SECRET: `openssl rand -base64 32`');
503
+ }
504
+ steps.push('Install dependencies: `pnpm add <dependencies>`', 'Generate Prisma schema: `pnpm opensaas generate`', 'Generate Prisma client: `npx prisma generate`', 'Push schema to database: `npx prisma db push`', 'Start development server: `pnpm dev`');
505
+ const adminPath = useAuth ? '' : '/admin';
506
+ steps.push(`Visit admin UI at http://localhost:3000${adminPath}`);
507
+ return steps;
508
+ }
509
+ }
510
+ //# sourceMappingURL=migration-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-generator.js","sourceRoot":"","sources":["../../../src/migration/generators/migration-generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AASH,OAAO,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAA;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAEhF,MAAM,OAAO,kBAAkB;IACrB,kBAAkB,CAAoB;IACtC,oBAAoB,CAAsB;IAElD;QACE,IAAI,CAAC,kBAAkB,GAAG,IAAI,kBAAkB,EAAE,CAAA;QAClD,IAAI,CAAC,oBAAoB,GAAG,IAAI,oBAAoB,EAAE,CAAA;IACxD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,OAAyB;QACtC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAA;QAElD,+BAA+B;QAC/B,IAAI,MAAsC,CAAA;QAC1C,IAAI,CAAC;YACH,IAAI,WAAW,KAAK,QAAQ,EAAE,CAAC;gBAC7B,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;YACjE,CAAC;iBAAM,IAAI,WAAW,KAAK,UAAU,EAAE,CAAC;gBACtC,MAAM,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;YACnE,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,yDAAyD;QAC3D,CAAC;QAED,uCAAuC;QACvC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAS,CAAC,MAAM,CAAC,CAAC,CAAA,CAAC,mBAAmB;QACpE,MAAM,QAAQ,GAAa,EAAE,CAAA;QAE7B,iBAAiB;QACjB,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAA;QAE3E,kCAAkC;QAClC,MAAM,aAAa,GAAG,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAA;QAEzD,2BAA2B;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,sBAAsB,CACzC,OAAO,CAAC,WAAsB,IAAI,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CACjE,CAAA;QAED,0BAA0B;QAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,KAAK,IAAI,CAAA;QAE5C,mBAAmB;QACnB,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;QAEhF,2BAA2B;QAC3B,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC;YACxC,OAAO;YACP,aAAa;YACb,QAAQ;YACR,KAAK;YACL,OAAO;YACP,WAAW,EAAG,OAAO,CAAC,YAAyB,IAAI,CAAC,gBAAgB,CAAC;YACrE,aAAa,EAAG,OAAO,CAAC,eAA0B,IAAI,QAAQ;SAC/D,CAAC,CAAA;QAEF,6BAA6B;QAC7B,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAE1E,4BAA4B;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;QAEtE,sBAAsB;QACtB,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;QAE5D,kCAAkC;QAClC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,oBAAoB,GACxB,WAAW,KAAK,QAAQ;gBACtB,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,MAAM,CAAC;gBAC7C,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;YACnD,QAAQ,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,CAAA;QACxC,CAAC;QAED,OAAO;YACL,aAAa;YACb,YAAY;YACZ,KAAK;YACL,KAAK;YACL,QAAQ;SACT,CAAA;IACH,CAAC;IAED;;OAEG;IACK,aAAa,CACnB,MAAsC,EACtC,OAAgC,EAChC,cAA2B,EAC3B,QAAkB;QAElB,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1C,oCAAoC;YACpC,cAAc,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;YAC/B,OAAO;;;;;;;;WAQF,CAAA;QACP,CAAC;QAED,8CAA8C;QAC9C,MAAM,cAAc,GAAG,OAAO,CAAC,gBAAgB,KAAK,IAAI,CAAA;QACxD,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,CAAC,CAAA;QAErE,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACtD,IAAI,cAAc,IAAI,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1D,OAAO,KAAK,CAAA;YACd,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC,CAAC,CAAA;QAEF,2CAA2C;QAC3C,MAAM,WAAW,GAAG,IAAI,GAAG,CAAE,OAAO,CAAC,iBAA8B,IAAI,EAAE,CAAC,CAAA;QAE1E,qBAAqB;QACrB,MAAM,eAAe,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACrD,OAAO,IAAI,CAAC,YAAY,CACtB,KAAK,EACL,MAAM,EACN,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAC3B,OAAO,EACP,cAAc,EACd,QAAQ,CACT,CAAA;QACH,CAAC,CAAC,CAAA;QAEF,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACnC,CAAC;IAED;;OAEG;IACK,YAAY,CAClB,KAAwB,EACxB,MAA0B,EAC1B,cAAuB,EACvB,OAAgC,EAChC,cAA2B,EAC3B,QAAkB;QAElB,MAAM,MAAM,GAAa,EAAE,CAAA;QAE3B,oFAAoF;QACpF,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;QAErD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YACjC,IAAI,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAQ;YAC/C,IAAI,KAAK,CAAC,IAAI;gBAAE,SAAQ,CAAC,iBAAiB;YAE1C,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,CAAC,CAAA;YAC5E,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,IAAI,KAAK,QAAQ,GAAG,CAAC,CAAA;YACpD,CAAC;QACH,CAAC;QAED,0BAA0B;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,cAAc,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;QAEtE,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAA;QAE7E,OAAO,OAAO,KAAK,CAAC,IAAI;iBACX,WAAW,KAAK,MAAM;QAC/B,CAAA;IACN,CAAC;IAED;;OAEG;IACK,aAAa,CACnB,KAAwB,EACxB,MAA0B,EAC1B,cAA2B,EAC3B,QAAkB;QAElB,uBAAuB;QACvB,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnB,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;YAElC,kDAAkD;YAClD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,QAAS,CAAC,KAAK,CAAC,CAAA;YAChF,MAAM,OAAO,GAAG,YAAY,EAAE,MAAM,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,KAAK,KAAK,CAAC,IAAI,CACrD,CAAA;YAED,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAA;YAEtF,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAA;YAC/C,OAAO,wBAAwB,GAAG,IAAI,IAAI,KAAK,CAAA;QACjD,CAAC;QAED,gCAAgC;QAChC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAA;QAC/D,IAAI,OAAO,EAAE,CAAC;YACZ,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YAC5B,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAE5F,IAAI,aAAa,GAAG,aAAa,WAAW,GAAG,CAAA;YAC/C,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;gBACvB,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAA;gBACjE,aAAa,IAAI,oBAAoB,UAAU,GAAG,CAAA;YACpD,CAAC;YACD,OAAO,YAAY,aAAa,KAAK,CAAA;QACvC,CAAC;QAED,wCAAwC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,CAAC,uBAAuB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC3E,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAElC,gBAAgB;QAChB,MAAM,OAAO,GAAa,EAAE,CAAA;QAE5B,IAAI,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YAC5C,OAAO,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAA;QAClD,CAAC;QAED,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnB,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;QACrC,CAAC;QAED,wBAAwB;QACxB,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACvB,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,YAAY,KAAK,OAAO,EAAE,CAAC;gBAChE,OAAO,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAA;YAC/C,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACpC,OAAO,CAAC,IAAI,CAAC,iBAAiB,KAAK,CAAC,YAAY,EAAE,CAAC,CAAA;YACrD,CAAC;YACD,iDAAiD;QACnD,CAAC;QAED,oCAAoC;QACpC,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACxD,QAAQ,CAAC,IAAI,CACX,UAAU,KAAK,CAAC,IAAI,4BAA4B,KAAK,CAAC,IAAI,sBAAsB,CACjF,CAAA;QACH,CAAC;QAED,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;QACxE,OAAO,GAAG,OAAO,CAAC,IAAI,IAAI,UAAU,GAAG,CAAA;IACzC,CAAC;IAED;;OAEG;IACK,kBAAkB,CACxB,cAAuB,EACvB,KAAwB,EACxB,OAAgC;QAEhC,MAAM,aAAa,GAAI,OAAO,CAAC,cAAyB,IAAI,wBAAwB,CAAA;QAEpF,IAAI,cAAc,EAAE,CAAC;YACnB,mCAAmC;YACnC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CACjC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,QAAQ,EAAE,KAAK,KAAK,MAAM;gBAC5B,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBACvC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACtC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CACxC,CAAA;YAED,MAAM,UAAU,GAAG,SAAS,EAAE,IAAI,IAAI,QAAQ,CAAA;YAC9C,MAAM,YAAY,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,CAAA;YAE/E,OAAO;;;;;;;;;;mDAUsC,YAAY;;SAEtD,CAAA;QACL,CAAC;QAED,2CAA2C;QAC3C,QAAQ,aAAa,EAAE,CAAC;YACtB,KAAK,oBAAoB;gBACvB,OAAO;;;;;;;;SAQN,CAAA;YAEH,KAAK,YAAY;gBACf,OAAO;;;;;;;;;;SAUN,CAAA;YAEH,KAAK,YAAY;gBACf,OAAO;;;;;;;;SAQN,CAAA;YAEH,KAAK,wBAAwB,CAAC;YAC9B;gBACE,OAAO;;;;;;;;SAQN,CAAA;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACK,qBAAqB,CAAC,OAAgC;QAC5D,MAAM,OAAO,GAAa,EAAE,CAAA;QAC5B,MAAM,WAAW,GAAI,OAAO,CAAC,iBAA8B,IAAI,EAAE,CAAA;QAEjE,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC;;;;;;;;;;;CAWlB,CAAC,CAAA;QACE,CAAC;QAED,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC;IAED;;OAEG;IACK,sBAAsB,CAAC,QAAgB;QAK7C,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,YAAY;gBACf,OAAO;oBACL,QAAQ,EAAE,YAAY;oBACtB,OAAO,EAAE,CAAC,+CAA+C,EAAE,qBAAqB,CAAC;oBACjF,UAAU,EAAE;;;;;;;OAOf;iBACE,CAAA;YAEH,KAAK,OAAO;gBACV,OAAO;oBACL,QAAQ,EAAE,OAAO;oBACjB,OAAO,EAAE,CAAC,iEAAiE,CAAC;oBAC5E,UAAU,EAAE;;;;;;;;OAQf;iBACE,CAAA;YAEH,KAAK,QAAQ,CAAC;YACd;gBACE,OAAO;oBACL,QAAQ,EAAE,QAAQ;oBAClB,OAAO,EAAE,CAAC,sEAAsE,CAAC;oBACjF,UAAU,EAAE;;;;;;;;OAQf;iBACE,CAAA;QACL,CAAC;IACH,CAAC;IAED;;OAEG;IACK,eAAe,CACrB,cAA2B,EAC3B,OAAgB,EAChB,UAAkB;QAElB,MAAM,OAAO,GAAa,EAAE,CAAA;QAE5B,eAAe;QACf,OAAO,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAA;QAEnE,gBAAgB;QAChB,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,IAAI,EAAE,CAAA;QACpD,OAAO,CAAC,IAAI,CAAC,YAAY,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAA;QAEtF,eAAe;QACf,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAA;YACjE,OAAO,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAA;QAC3E,CAAC;QAED,2BAA2B;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAA;QACxD,OAAO,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAA;QAEjC,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,OAQtB;QACC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,OAAO,CAAA;QAEhG,8BAA8B;QAC9B,IAAI,aAAa,GAAG,EAAE,CAAA;QACtB,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,WAAW,GAAa,EAAE,CAAA;YAEhC,IAAI,WAAW,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBAC3C,WAAW,CAAC,IAAI,CAAC;;;SAGhB,CAAC,CAAA;YACJ,CAAC;YAED,IAAI,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBACvC,WAAW,CAAC,IAAI,CAAC;;SAEhB,CAAC,CAAA;YACJ,CAAC;YAED,8CAA8C;YAC9C,IAAI,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACnC,WAAW,CAAC,IAAI,CAAC;;;;YAIb,CAAC,CAAA;YACP,CAAC;YAED,IAAI,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACnC,WAAW,CAAC,IAAI,CAAC;;;;YAIb,CAAC,CAAA;YACP,CAAC;YAED,WAAW,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAA;YAErE,aAAa,GAAG;EACpB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;QAChB,CAAA;QACJ,CAAC;QAED,oBAAoB;QACpB,MAAM,YAAY,GAAG,OAAO;YAC1B,CAAC,CAAC;EACN,aAAa;;;CAGd;YACK,CAAC,CAAC,EAAE,CAAA;QAEN,MAAM,UAAU,GAAG;EACrB,YAAY,GAAG,QAAQ,CAAC,UAAU;;EAElC,KAAK;;;iBAGU,aAAa;;GAE3B,CAAA;QAEC,OAAO,GAAG,OAAO;;EAEnB,aAAa,GAAG,UAAU;CAC3B,CAAA;IACC,CAAC;IAED;;OAEG;IACK,oBAAoB,CAAC,UAAkB,EAAE,OAAgB;QAC/D,MAAM,IAAI,GAAa;YACrB,sBAAsB;YACtB,oBAAoB;YACpB,gBAAgB;YAChB,QAAQ;SACT,CAAA;QAED,wBAAwB;QACxB,QAAQ,UAAU,EAAE,CAAC;YACnB,KAAK,YAAY;gBACf,IAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,IAAI,EAAE,WAAW,CAAC,CAAA;gBAClD,MAAK;YACP,KAAK,OAAO;gBACV,IAAI,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAA;gBACxC,MAAK;YACP,KAAK,QAAQ,CAAC;YACd;gBACE,IAAI,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAA;gBAC3C,MAAK;QACT,CAAC;QAED,YAAY;QACZ,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,aAAa,CAAC,CAAA;QAClD,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;OAEG;IACK,uBAAuB,CAC7B,OAAgC,EAChC,UAAkB;QAOlB,MAAM,KAAK,GAKN,EAAE,CAAA;QAEP,wBAAwB;QACxB,MAAM,OAAO,GAAa,CAAC,YAAY,CAAC,CAAA;QAExC,iCAAiC;QACjC,QAAQ,UAAU,EAAE,CAAC;YACnB,KAAK,YAAY;gBACf,OAAO,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAA;gBAC7E,MAAK;YACP,KAAK,OAAO;gBACV,OAAO,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAA;gBACxE,MAAK;YACP,KAAK,QAAQ,CAAC;YACd;gBACE,OAAO,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;gBAC5C,MAAK;QACT,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAEhB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACtB,OAAO,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAA;YACzE,OAAO,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAA;YACvD,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAEhB,MAAM,WAAW,GAAI,OAAO,CAAC,YAAyB,IAAI,EAAE,CAAA;YAC5D,IAAI,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACnC,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAA;gBACzC,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;gBACnC,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAA;gBACvC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAClB,CAAC;YACD,IAAI,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACnC,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAA;gBACzC,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;gBACnC,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAA;gBACvC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAClB,CAAC;QACH,CAAC;QAED,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YAC3B,QAAQ,EAAE,MAAM;YAChB,WAAW,EAAE,gCAAgC;SAC9C,CAAC,CAAA;QAEF,OAAO,KAAK,CAAA;IACd,CAAC;IAED;;OAEG;IACK,aAAa,CAAC,OAAgB,EAAE,UAAkB;QACxD,MAAM,KAAK,GAAG;YACZ,mDAAmD;YACnD,kDAAkD;SACnD,CAAA;QAED,IAAI,OAAO,EAAE,CAAC;YACZ,KAAK,CAAC,IAAI,CAAC,wDAAwD,CAAC,CAAA;QACtE,CAAC;QAED,KAAK,CAAC,IAAI,CACR,iDAAiD,EACjD,kDAAkD,EAClD,+CAA+C,EAC/C,+CAA+C,EAC/C,sCAAsC,CACvC,CAAA;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAA;QACzC,KAAK,CAAC,IAAI,CAAC,0CAA0C,SAAS,EAAE,CAAC,CAAA;QAEjE,OAAO,KAAK,CAAA;IACd,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Schema introspectors for migration system
3
+ *
4
+ * These introspectors parse existing schemas and configs to extract
5
+ * model and field information for automated migration.
6
+ */
7
+ export { PrismaIntrospector } from './prisma-introspector.js';
8
+ export { KeystoneIntrospector } from './keystone-introspector.js';
9
+ export type { KeystoneList, KeystoneField, KeystoneSchema } from './keystone-introspector.js';
10
+ export { NextjsIntrospector } from './nextjs-introspector.js';
11
+ export type { NextjsAnalysis } from './nextjs-introspector.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/migration/introspectors/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AACjE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAC7F,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAC7D,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Schema introspectors for migration system
3
+ *
4
+ * These introspectors parse existing schemas and configs to extract
5
+ * model and field information for automated migration.
6
+ */
7
+ export { PrismaIntrospector } from './prisma-introspector.js';
8
+ export { KeystoneIntrospector } from './keystone-introspector.js';
9
+ export { NextjsIntrospector } from './nextjs-introspector.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/migration/introspectors/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AAEjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * KeystoneJS Config Introspector
3
+ *
4
+ * Loads keystone.config.ts using jiti and extracts list definitions.
5
+ * KeystoneJS → OpenSaaS migration is mostly 1:1.
6
+ */
7
+ import type { IntrospectedSchema } from '../types.js';
8
+ export interface KeystoneList {
9
+ name: string;
10
+ fields: KeystoneField[];
11
+ access?: Record<string, unknown>;
12
+ hooks?: Record<string, unknown>;
13
+ }
14
+ export interface KeystoneField {
15
+ name: string;
16
+ type: string;
17
+ options?: Record<string, unknown>;
18
+ }
19
+ export interface KeystoneSchema {
20
+ lists: KeystoneList[];
21
+ db?: {
22
+ provider: string;
23
+ url?: string;
24
+ };
25
+ }
26
+ export declare class KeystoneIntrospector {
27
+ /**
28
+ * Introspect a KeystoneJS config file
29
+ */
30
+ introspect(cwd: string, configPath?: string): Promise<IntrospectedSchema>;
31
+ /**
32
+ * Parse the loaded KeystoneJS config object
33
+ */
34
+ private parseConfig;
35
+ /**
36
+ * Parse a single list definition
37
+ */
38
+ private parseList;
39
+ /**
40
+ * Parse a single field definition
41
+ */
42
+ private parseField;
43
+ /**
44
+ * Convert KeystoneSchema to IntrospectedSchema format
45
+ */
46
+ private convertToIntrospectedSchema;
47
+ /**
48
+ * Map KeystoneJS field type to OpenSaaS equivalent
49
+ */
50
+ mapKeystoneTypeToOpenSaas(keystoneType: string): {
51
+ type: string;
52
+ import: string;
53
+ };
54
+ /**
55
+ * Get warnings for unsupported features
56
+ */
57
+ getWarnings(schema: IntrospectedSchema): string[];
58
+ }
59
+ //# sourceMappingURL=keystone-introspector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keystone-introspector.d.ts","sourceRoot":"","sources":["../../../src/migration/introspectors/keystone-introspector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAwC,MAAM,aAAa,CAAA;AAE3F,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,aAAa,EAAE,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,YAAY,EAAE,CAAA;IACrB,EAAE,CAAC,EAAE;QACH,QAAQ,EAAE,MAAM,CAAA;QAChB,GAAG,CAAC,EAAE,MAAM,CAAA;KACb,CAAA;CACF;AAED,qBAAa,oBAAoB;IAC/B;;OAEG;IACG,UAAU,CACd,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,MAA6B,GACxC,OAAO,CAAC,kBAAkB,CAAC;IAyC9B;;OAEG;IACH,OAAO,CAAC,WAAW;IA+BnB;;OAEG;IACH,OAAO,CAAC,SAAS;IA+BjB;;OAEG;IACH,OAAO,CAAC,UAAU;IAmClB;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAiDnC;;OAEG;IACH,yBAAyB,CAAC,YAAY,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAyBjF;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,EAAE;CAyBlD"}