@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,229 @@
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 path from 'path';
8
+ import fs from 'fs-extra';
9
+ import { createJiti } from 'jiti';
10
+ export class KeystoneIntrospector {
11
+ /**
12
+ * Introspect a KeystoneJS config file
13
+ */
14
+ async introspect(cwd, configPath = 'keystone.config.ts') {
15
+ const fullPath = path.isAbsolute(configPath) ? configPath : path.join(cwd, configPath);
16
+ // Try alternative paths
17
+ const paths = [fullPath, path.join(cwd, 'keystone.ts'), path.join(cwd, 'keystone.config.js')];
18
+ let foundPath;
19
+ for (const p of paths) {
20
+ if (await fs.pathExists(p)) {
21
+ foundPath = p;
22
+ break;
23
+ }
24
+ }
25
+ if (!foundPath) {
26
+ throw new Error(`KeystoneJS config not found. Tried: ${paths.join(', ')}`);
27
+ }
28
+ try {
29
+ // Use jiti to load TypeScript config
30
+ const jiti = createJiti(import.meta.url, {
31
+ interopDefault: true,
32
+ moduleCache: false,
33
+ });
34
+ const configModule = (await jiti.import(foundPath));
35
+ const config = typeof configModule === 'object' && configModule !== null && 'default' in configModule
36
+ ? configModule.default
37
+ : configModule;
38
+ const keystoneSchema = this.parseConfig(config);
39
+ // Convert KeystoneSchema to IntrospectedSchema
40
+ return this.convertToIntrospectedSchema(keystoneSchema);
41
+ }
42
+ catch (error) {
43
+ const message = error instanceof Error ? error.message : String(error);
44
+ throw new Error(`Failed to load KeystoneJS config: ${message}`);
45
+ }
46
+ }
47
+ /**
48
+ * Parse the loaded KeystoneJS config object
49
+ */
50
+ parseConfig(config) {
51
+ const result = {
52
+ lists: [],
53
+ };
54
+ if (typeof config !== 'object' || config === null) {
55
+ return result;
56
+ }
57
+ const configObj = config;
58
+ // Extract database config
59
+ if (configObj.db && typeof configObj.db === 'object' && configObj.db !== null) {
60
+ const db = configObj.db;
61
+ result.db = {
62
+ provider: typeof db.provider === 'string' ? db.provider : 'unknown',
63
+ url: typeof db.url === 'string' ? db.url : undefined,
64
+ };
65
+ }
66
+ // Extract lists
67
+ if (configObj.lists && typeof configObj.lists === 'object' && configObj.lists !== null) {
68
+ for (const [name, listDef] of Object.entries(configObj.lists)) {
69
+ const list = this.parseList(name, listDef);
70
+ result.lists.push(list);
71
+ }
72
+ }
73
+ return result;
74
+ }
75
+ /**
76
+ * Parse a single list definition
77
+ */
78
+ parseList(name, listDef) {
79
+ const list = {
80
+ name,
81
+ fields: [],
82
+ };
83
+ if (typeof listDef !== 'object' || listDef === null) {
84
+ return list;
85
+ }
86
+ const listDefObj = listDef;
87
+ // Extract fields
88
+ if (listDefObj.fields && typeof listDefObj.fields === 'object' && listDefObj.fields !== null) {
89
+ for (const [fieldName, fieldDef] of Object.entries(listDefObj.fields)) {
90
+ const field = this.parseField(fieldName, fieldDef);
91
+ list.fields.push(field);
92
+ }
93
+ }
94
+ // Store access and hooks for reference (not used in migration but useful)
95
+ if (listDefObj.access && typeof listDefObj.access === 'object') {
96
+ list.access = listDefObj.access;
97
+ }
98
+ if (listDefObj.hooks && typeof listDefObj.hooks === 'object') {
99
+ list.hooks = listDefObj.hooks;
100
+ }
101
+ return list;
102
+ }
103
+ /**
104
+ * Parse a single field definition
105
+ */
106
+ parseField(name, fieldDef) {
107
+ // KeystoneJS fields are objects with a type property or function results
108
+ let type = 'unknown';
109
+ let options = {};
110
+ if (typeof fieldDef === 'object' && fieldDef !== null) {
111
+ const fieldDefObj = fieldDef;
112
+ // Check for common field type patterns
113
+ if (typeof fieldDefObj.type === 'string') {
114
+ type = fieldDefObj.type;
115
+ }
116
+ else if (typeof fieldDefObj._type === 'string') {
117
+ type = fieldDefObj._type;
118
+ }
119
+ else if (fieldDefObj.constructor &&
120
+ typeof fieldDefObj.constructor === 'object' &&
121
+ fieldDefObj.constructor !== null) {
122
+ const constructor = fieldDefObj.constructor;
123
+ if (typeof constructor.name === 'string') {
124
+ type = constructor.name;
125
+ }
126
+ }
127
+ // Extract common options
128
+ if (fieldDefObj.validation !== undefined)
129
+ options.validation = fieldDefObj.validation;
130
+ if (fieldDefObj.defaultValue !== undefined)
131
+ options.defaultValue = fieldDefObj.defaultValue;
132
+ if (fieldDefObj.isRequired !== undefined)
133
+ options.isRequired = fieldDefObj.isRequired;
134
+ if (fieldDefObj.ref !== undefined)
135
+ options.ref = fieldDefObj.ref;
136
+ if (fieldDefObj.many !== undefined)
137
+ options.many = fieldDefObj.many;
138
+ }
139
+ return { name, type, options };
140
+ }
141
+ /**
142
+ * Convert KeystoneSchema to IntrospectedSchema format
143
+ */
144
+ convertToIntrospectedSchema(keystoneSchema) {
145
+ const models = keystoneSchema.lists.map((list) => {
146
+ const fields = list.fields.map((field) => {
147
+ const isRelationship = field.type.toLowerCase() === 'relationship';
148
+ const isRequired = field.options?.isRequired === true;
149
+ const introspectedField = {
150
+ name: field.name,
151
+ type: field.type,
152
+ isRequired,
153
+ isUnique: false, // KeystoneJS doesn't expose this easily
154
+ isId: field.name === 'id',
155
+ isList: field.options?.many === true,
156
+ };
157
+ if (field.options?.defaultValue !== undefined) {
158
+ introspectedField.defaultValue = String(field.options.defaultValue);
159
+ }
160
+ if (isRelationship && field.options?.ref) {
161
+ const ref = String(field.options.ref);
162
+ const [model, fieldName] = ref.split('.');
163
+ introspectedField.relation = {
164
+ name: '',
165
+ model,
166
+ fields: [],
167
+ references: fieldName ? [fieldName] : [],
168
+ };
169
+ }
170
+ return introspectedField;
171
+ });
172
+ return {
173
+ name: list.name,
174
+ fields,
175
+ hasRelations: fields.some((f) => f.relation !== undefined),
176
+ primaryKey: 'id',
177
+ };
178
+ });
179
+ return {
180
+ provider: keystoneSchema.db?.provider || 'unknown',
181
+ models,
182
+ enums: [], // KeystoneJS doesn't have enums in the same way
183
+ };
184
+ }
185
+ /**
186
+ * Map KeystoneJS field type to OpenSaaS equivalent
187
+ */
188
+ mapKeystoneTypeToOpenSaas(keystoneType) {
189
+ // KeystoneJS → OpenSaaS is mostly 1:1
190
+ const mappings = {
191
+ text: { type: 'text', import: 'text' },
192
+ integer: { type: 'integer', import: 'integer' },
193
+ float: { type: 'float', import: 'float' },
194
+ checkbox: { type: 'checkbox', import: 'checkbox' },
195
+ timestamp: { type: 'timestamp', import: 'timestamp' },
196
+ select: { type: 'select', import: 'select' },
197
+ relationship: { type: 'relationship', import: 'relationship' },
198
+ password: { type: 'password', import: 'password' },
199
+ json: { type: 'json', import: 'json' },
200
+ // Storage field types (from @opensaas/stack-storage)
201
+ image: { type: 'image', import: 'image' },
202
+ file: { type: 'file', import: 'file' },
203
+ // Virtual/computed fields
204
+ virtual: { type: 'virtual', import: 'virtual' },
205
+ // Other field types
206
+ calendarDay: { type: 'timestamp', import: 'timestamp' },
207
+ };
208
+ const lower = keystoneType.toLowerCase();
209
+ return mappings[lower] || { type: 'text', import: 'text' };
210
+ }
211
+ /**
212
+ * Get warnings for unsupported features
213
+ */
214
+ getWarnings(schema) {
215
+ const warnings = [];
216
+ const hasFileOrImageFields = schema.models.some((model) => model.fields.some((field) => ['image', 'file'].includes(field.type.toLowerCase())));
217
+ const hasVirtualFields = schema.models.some((model) => model.fields.some((field) => field.type.toLowerCase() === 'virtual'));
218
+ // Add storage configuration reminder if file/image fields are present
219
+ if (hasFileOrImageFields) {
220
+ warnings.push("Your schema uses file/image fields - you'll need to configure storage providers in your OpenSaaS config");
221
+ }
222
+ // Add virtual field migration reminder
223
+ if (hasVirtualFields) {
224
+ warnings.push("Your schema uses virtual fields - you'll need to manually migrate the resolveOutput hooks to compute field values");
225
+ }
226
+ return warnings;
227
+ }
228
+ }
229
+ //# sourceMappingURL=keystone-introspector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keystone-introspector.js","sourceRoot":"","sources":["../../../src/migration/introspectors/keystone-introspector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Next.js Project Introspector
3
+ *
4
+ * Detects Next.js version, auth libraries, database libraries,
5
+ * and other project characteristics.
6
+ */
7
+ export interface NextjsAnalysis {
8
+ version: string;
9
+ routerType: 'app' | 'pages' | 'both' | 'unknown';
10
+ typescript: boolean;
11
+ authLibrary?: string;
12
+ databaseLibrary?: string;
13
+ hasPrisma: boolean;
14
+ hasEnvFile: boolean;
15
+ existingDependencies: string[];
16
+ }
17
+ export declare class NextjsIntrospector {
18
+ /**
19
+ * Analyze a Next.js project
20
+ */
21
+ introspect(cwd: string): Promise<NextjsAnalysis>;
22
+ /**
23
+ * Get Next.js version from package.json
24
+ */
25
+ private getNextVersion;
26
+ /**
27
+ * Detect if project uses app router, pages router, or both
28
+ */
29
+ private detectRouterType;
30
+ /**
31
+ * Check if project uses TypeScript
32
+ */
33
+ private hasTypeScript;
34
+ /**
35
+ * Check if package.json has a dependency
36
+ */
37
+ private hasDependency;
38
+ /**
39
+ * Get all dependencies
40
+ */
41
+ private getAllDependencies;
42
+ /**
43
+ * Detect auth library being used
44
+ */
45
+ private detectAuthLibrary;
46
+ /**
47
+ * Detect database library being used
48
+ */
49
+ private detectDatabaseLibrary;
50
+ /**
51
+ * Get migration recommendations based on analysis
52
+ */
53
+ getRecommendations(analysis: NextjsAnalysis): string[];
54
+ /**
55
+ * Get warnings for potential issues
56
+ */
57
+ getWarnings(analysis: NextjsAnalysis): string[];
58
+ }
59
+ //# sourceMappingURL=nextjs-introspector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextjs-introspector.d.ts","sourceRoot":"","sources":["../../../src/migration/introspectors/nextjs-introspector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;IAChD,UAAU,EAAE,OAAO,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,OAAO,CAAA;IAClB,UAAU,EAAE,OAAO,CAAA;IACnB,oBAAoB,EAAE,MAAM,EAAE,CAAA;CAC/B;AAED,qBAAa,kBAAkB;IAC7B;;OAEG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IA+BtD;;OAEG;IACH,OAAO,CAAC,cAAc;IAQtB;;OAEG;YACW,gBAAgB;IAc9B;;OAEG;YACW,aAAa;IAI3B;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAM1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAoBzB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAoB7B;;OAEG;IACH,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,EAAE;IA8BtD;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,EAAE;CAiBhD"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Next.js Project Introspector
3
+ *
4
+ * Detects Next.js version, auth libraries, database libraries,
5
+ * and other project characteristics.
6
+ */
7
+ import path from 'path';
8
+ import fs from 'fs-extra';
9
+ export class NextjsIntrospector {
10
+ /**
11
+ * Analyze a Next.js project
12
+ */
13
+ async introspect(cwd) {
14
+ const packageJsonPath = path.join(cwd, 'package.json');
15
+ if (!(await fs.pathExists(packageJsonPath))) {
16
+ throw new Error('package.json not found');
17
+ }
18
+ const pkg = await fs.readJSON(packageJsonPath);
19
+ const analysis = {
20
+ version: this.getNextVersion(pkg),
21
+ routerType: await this.detectRouterType(cwd),
22
+ typescript: await this.hasTypeScript(cwd),
23
+ hasPrisma: this.hasDependency(pkg, '@prisma/client') ||
24
+ (await fs.pathExists(path.join(cwd, 'prisma'))),
25
+ hasEnvFile: (await fs.pathExists(path.join(cwd, '.env'))) ||
26
+ (await fs.pathExists(path.join(cwd, '.env.local'))),
27
+ existingDependencies: this.getAllDependencies(pkg),
28
+ };
29
+ // Detect auth library
30
+ analysis.authLibrary = this.detectAuthLibrary(pkg);
31
+ // Detect database library
32
+ analysis.databaseLibrary = this.detectDatabaseLibrary(pkg);
33
+ return analysis;
34
+ }
35
+ /**
36
+ * Get Next.js version from package.json
37
+ */
38
+ getNextVersion(pkg) {
39
+ const deps = pkg.dependencies;
40
+ const devDeps = pkg.devDependencies;
41
+ const version = deps?.next || devDeps?.next || 'unknown';
42
+ // Strip semver prefixes like ^ or ~
43
+ return version.replace(/^[\^~]/, '');
44
+ }
45
+ /**
46
+ * Detect if project uses app router, pages router, or both
47
+ */
48
+ async detectRouterType(cwd) {
49
+ const hasApp = (await fs.pathExists(path.join(cwd, 'app'))) ||
50
+ (await fs.pathExists(path.join(cwd, 'src', 'app')));
51
+ const hasPages = (await fs.pathExists(path.join(cwd, 'pages'))) ||
52
+ (await fs.pathExists(path.join(cwd, 'src', 'pages')));
53
+ if (hasApp && hasPages)
54
+ return 'both';
55
+ if (hasApp)
56
+ return 'app';
57
+ if (hasPages)
58
+ return 'pages';
59
+ return 'unknown';
60
+ }
61
+ /**
62
+ * Check if project uses TypeScript
63
+ */
64
+ async hasTypeScript(cwd) {
65
+ return await fs.pathExists(path.join(cwd, 'tsconfig.json'));
66
+ }
67
+ /**
68
+ * Check if package.json has a dependency
69
+ */
70
+ hasDependency(pkg, name) {
71
+ const deps = pkg.dependencies;
72
+ const devDeps = pkg.devDependencies;
73
+ return !!(deps?.[name] || devDeps?.[name]);
74
+ }
75
+ /**
76
+ * Get all dependencies
77
+ */
78
+ getAllDependencies(pkg) {
79
+ const deps = pkg.dependencies;
80
+ const devDeps = pkg.devDependencies;
81
+ return [...Object.keys(deps || {}), ...Object.keys(devDeps || {})];
82
+ }
83
+ /**
84
+ * Detect auth library being used
85
+ */
86
+ detectAuthLibrary(pkg) {
87
+ const authLibraries = [
88
+ { name: 'next-auth', dep: 'next-auth' },
89
+ { name: 'better-auth', dep: 'better-auth' },
90
+ { name: 'clerk', dep: '@clerk/nextjs' },
91
+ { name: 'auth0', dep: '@auth0/nextjs-auth0' },
92
+ { name: 'supabase', dep: '@supabase/auth-helpers-nextjs' },
93
+ { name: 'lucia', dep: 'lucia' },
94
+ { name: 'kinde', dep: '@kinde-oss/kinde-auth-nextjs' },
95
+ ];
96
+ for (const lib of authLibraries) {
97
+ if (this.hasDependency(pkg, lib.dep)) {
98
+ return lib.name;
99
+ }
100
+ }
101
+ return undefined;
102
+ }
103
+ /**
104
+ * Detect database library being used
105
+ */
106
+ detectDatabaseLibrary(pkg) {
107
+ const dbLibraries = [
108
+ { name: 'prisma', dep: '@prisma/client' },
109
+ { name: 'drizzle', dep: 'drizzle-orm' },
110
+ { name: 'typeorm', dep: 'typeorm' },
111
+ { name: 'mongoose', dep: 'mongoose' },
112
+ { name: 'knex', dep: 'knex' },
113
+ { name: 'sequelize', dep: 'sequelize' },
114
+ { name: 'kysely', dep: 'kysely' },
115
+ ];
116
+ for (const lib of dbLibraries) {
117
+ if (this.hasDependency(pkg, lib.dep)) {
118
+ return lib.name;
119
+ }
120
+ }
121
+ return undefined;
122
+ }
123
+ /**
124
+ * Get migration recommendations based on analysis
125
+ */
126
+ getRecommendations(analysis) {
127
+ const recommendations = [];
128
+ if (analysis.routerType === 'pages') {
129
+ recommendations.push('Consider migrating to App Router for best OpenSaaS Stack integration');
130
+ }
131
+ if (analysis.authLibrary && analysis.authLibrary !== 'better-auth') {
132
+ recommendations.push(`Consider migrating from ${analysis.authLibrary} to Better-auth (used by OpenSaaS Stack auth plugin)`);
133
+ }
134
+ if (!analysis.hasPrisma) {
135
+ recommendations.push("OpenSaaS Stack uses Prisma - you'll need to set up your data models");
136
+ }
137
+ if (analysis.databaseLibrary && analysis.databaseLibrary !== 'prisma') {
138
+ recommendations.push(`You're using ${analysis.databaseLibrary} - you may need to migrate to Prisma or run both`);
139
+ }
140
+ if (!analysis.hasEnvFile) {
141
+ recommendations.push('Create a .env file with DATABASE_URL for your database connection');
142
+ }
143
+ return recommendations;
144
+ }
145
+ /**
146
+ * Get warnings for potential issues
147
+ */
148
+ getWarnings(analysis) {
149
+ const warnings = [];
150
+ if (analysis.version.startsWith('12') || analysis.version.startsWith('11')) {
151
+ warnings.push(`Next.js ${analysis.version} is quite old - consider upgrading to 14+ for best results`);
152
+ }
153
+ if (analysis.databaseLibrary === 'mongoose') {
154
+ warnings.push('MongoDB/Mongoose is not fully supported by Prisma - migration may require database change');
155
+ }
156
+ return warnings;
157
+ }
158
+ }
159
+ //# sourceMappingURL=nextjs-introspector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextjs-introspector.js","sourceRoot":"","sources":["../../../src/migration/introspectors/nextjs-introspector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Prisma Schema Introspector
3
+ *
4
+ * Parses prisma/schema.prisma and extracts structured information
5
+ * about models, fields, relationships, and enums.
6
+ */
7
+ import type { IntrospectedSchema } from '../types.js';
8
+ export declare class PrismaIntrospector {
9
+ /**
10
+ * Introspect a Prisma schema file
11
+ */
12
+ introspect(cwd: string, schemaPath?: string): Promise<IntrospectedSchema>;
13
+ /**
14
+ * Extract database provider from datasource block
15
+ */
16
+ private extractProvider;
17
+ /**
18
+ * Extract all model definitions
19
+ */
20
+ private extractModels;
21
+ /**
22
+ * Extract fields from a model body
23
+ */
24
+ private extractFields;
25
+ /**
26
+ * Parse a single field line
27
+ */
28
+ private parseFieldLine;
29
+ /**
30
+ * Extract enum definitions
31
+ */
32
+ private extractEnums;
33
+ /**
34
+ * Map Prisma type to OpenSaaS field type
35
+ */
36
+ mapPrismaTypeToOpenSaas(prismaType: string): {
37
+ type: string;
38
+ import: string;
39
+ };
40
+ /**
41
+ * Get warnings for unsupported features
42
+ */
43
+ getWarnings(schema: IntrospectedSchema): string[];
44
+ }
45
+ //# sourceMappingURL=prisma-introspector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prisma-introspector.d.ts","sourceRoot":"","sources":["../../../src/migration/introspectors/prisma-introspector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAwC,MAAM,aAAa,CAAA;AAE3F,qBAAa,kBAAkB;IAC7B;;OAEG;IACG,UAAU,CACd,GAAG,EAAE,MAAM,EACX,UAAU,GAAE,MAA+B,GAC1C,OAAO,CAAC,kBAAkB,CAAC;IAgB9B;;OAEG;IACH,OAAO,CAAC,eAAe;IAKvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAyBrB;;OAEG;IACH,OAAO,CAAC,aAAa;IAqBrB;;OAEG;IACH,OAAO,CAAC,cAAc;IAqEtB;;OAEG;IACH,OAAO,CAAC,YAAY;IAsBpB;;OAEG;IACH,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAgB7E;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,MAAM,EAAE;CAmBlD"}