@opensaas/stack-cli 0.4.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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +52 -0
- package/dist/commands/migrate.d.ts +9 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +473 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/lib/documentation-provider.d.ts +23 -0
- package/dist/mcp/lib/documentation-provider.d.ts.map +1 -1
- package/dist/mcp/lib/documentation-provider.js +471 -0
- package/dist/mcp/lib/documentation-provider.js.map +1 -1
- package/dist/mcp/lib/wizards/migration-wizard.d.ts +80 -0
- package/dist/mcp/lib/wizards/migration-wizard.d.ts.map +1 -0
- package/dist/mcp/lib/wizards/migration-wizard.js +499 -0
- package/dist/mcp/lib/wizards/migration-wizard.js.map +1 -0
- package/dist/mcp/server/index.d.ts.map +1 -1
- package/dist/mcp/server/index.js +103 -0
- package/dist/mcp/server/index.js.map +1 -1
- package/dist/mcp/server/stack-mcp-server.d.ts +85 -0
- package/dist/mcp/server/stack-mcp-server.d.ts.map +1 -1
- package/dist/mcp/server/stack-mcp-server.js +219 -0
- package/dist/mcp/server/stack-mcp-server.js.map +1 -1
- package/dist/migration/generators/migration-generator.d.ts +60 -0
- package/dist/migration/generators/migration-generator.d.ts.map +1 -0
- package/dist/migration/generators/migration-generator.js +510 -0
- package/dist/migration/generators/migration-generator.js.map +1 -0
- package/dist/migration/introspectors/index.d.ts +12 -0
- package/dist/migration/introspectors/index.d.ts.map +1 -0
- package/dist/migration/introspectors/index.js +10 -0
- package/dist/migration/introspectors/index.js.map +1 -0
- package/dist/migration/introspectors/keystone-introspector.d.ts +59 -0
- package/dist/migration/introspectors/keystone-introspector.d.ts.map +1 -0
- package/dist/migration/introspectors/keystone-introspector.js +229 -0
- package/dist/migration/introspectors/keystone-introspector.js.map +1 -0
- package/dist/migration/introspectors/nextjs-introspector.d.ts +59 -0
- package/dist/migration/introspectors/nextjs-introspector.d.ts.map +1 -0
- package/dist/migration/introspectors/nextjs-introspector.js +159 -0
- package/dist/migration/introspectors/nextjs-introspector.js.map +1 -0
- package/dist/migration/introspectors/prisma-introspector.d.ts +45 -0
- package/dist/migration/introspectors/prisma-introspector.d.ts.map +1 -0
- package/dist/migration/introspectors/prisma-introspector.js +190 -0
- package/dist/migration/introspectors/prisma-introspector.js.map +1 -0
- package/dist/migration/types.d.ts +86 -0
- package/dist/migration/types.d.ts.map +1 -0
- package/dist/migration/types.js +5 -0
- package/dist/migration/types.js.map +1 -0
- package/package.json +5 -2
- package/src/commands/migrate.ts +534 -0
- package/src/index.ts +4 -0
- package/src/mcp/lib/documentation-provider.ts +507 -0
- package/src/mcp/lib/wizards/migration-wizard.ts +584 -0
- package/src/mcp/server/index.ts +121 -0
- package/src/mcp/server/stack-mcp-server.ts +243 -0
- package/src/migration/generators/migration-generator.ts +675 -0
- package/src/migration/introspectors/index.ts +12 -0
- package/src/migration/introspectors/keystone-introspector.ts +296 -0
- package/src/migration/introspectors/nextjs-introspector.ts +209 -0
- package/src/migration/introspectors/prisma-introspector.ts +233 -0
- package/src/migration/types.ts +92 -0
- package/tests/introspectors/keystone-introspector.test.ts +255 -0
- package/tests/introspectors/nextjs-introspector.test.ts +302 -0
- package/tests/introspectors/prisma-introspector.test.ts +268 -0
- package/tests/migration-generator.test.ts +592 -0
- package/tests/migration-wizard.test.ts +442 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,190 @@
|
|
|
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 fs from 'fs-extra';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
export class PrismaIntrospector {
|
|
10
|
+
/**
|
|
11
|
+
* Introspect a Prisma schema file
|
|
12
|
+
*/
|
|
13
|
+
async introspect(cwd, schemaPath = 'prisma/schema.prisma') {
|
|
14
|
+
const fullPath = path.isAbsolute(schemaPath) ? schemaPath : path.join(cwd, schemaPath);
|
|
15
|
+
if (!(await fs.pathExists(fullPath))) {
|
|
16
|
+
throw new Error(`Schema file not found: ${fullPath}`);
|
|
17
|
+
}
|
|
18
|
+
const schema = await fs.readFile(fullPath, 'utf-8');
|
|
19
|
+
return {
|
|
20
|
+
provider: this.extractProvider(schema),
|
|
21
|
+
models: this.extractModels(schema),
|
|
22
|
+
enums: this.extractEnums(schema),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Extract database provider from datasource block
|
|
27
|
+
*/
|
|
28
|
+
extractProvider(schema) {
|
|
29
|
+
const match = schema.match(/datasource\s+\w+\s*\{[^}]*provider\s*=\s*"(\w+)"/);
|
|
30
|
+
return match ? match[1] : 'unknown';
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Extract all model definitions
|
|
34
|
+
*/
|
|
35
|
+
extractModels(schema) {
|
|
36
|
+
const models = [];
|
|
37
|
+
// Match model blocks
|
|
38
|
+
const modelRegex = /model\s+(\w+)\s*\{([^}]+)\}/g;
|
|
39
|
+
let match;
|
|
40
|
+
while ((match = modelRegex.exec(schema)) !== null) {
|
|
41
|
+
const name = match[1];
|
|
42
|
+
const body = match[2];
|
|
43
|
+
const fields = this.extractFields(body);
|
|
44
|
+
const primaryKey = fields.find((f) => f.isId)?.name || 'id';
|
|
45
|
+
models.push({
|
|
46
|
+
name,
|
|
47
|
+
fields,
|
|
48
|
+
hasRelations: fields.some((f) => f.relation !== undefined),
|
|
49
|
+
primaryKey,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return models;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Extract fields from a model body
|
|
56
|
+
*/
|
|
57
|
+
extractFields(body) {
|
|
58
|
+
const fields = [];
|
|
59
|
+
const lines = body.split('\n');
|
|
60
|
+
for (const line of lines) {
|
|
61
|
+
const trimmed = line.trim();
|
|
62
|
+
// Skip empty lines, comments, and model-level attributes
|
|
63
|
+
if (!trimmed || trimmed.startsWith('//') || trimmed.startsWith('@@')) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const field = this.parseFieldLine(trimmed);
|
|
67
|
+
if (field) {
|
|
68
|
+
fields.push(field);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return fields;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Parse a single field line
|
|
75
|
+
*/
|
|
76
|
+
parseFieldLine(line) {
|
|
77
|
+
// Basic field pattern: name Type modifiers attributes
|
|
78
|
+
// Examples:
|
|
79
|
+
// id String @id @default(cuid())
|
|
80
|
+
// title String
|
|
81
|
+
// isActive Boolean? @default(true)
|
|
82
|
+
// posts Post[]
|
|
83
|
+
// author User @relation(fields: [authorId], references: [id])
|
|
84
|
+
// Remove comments
|
|
85
|
+
const withoutComment = line.split('//')[0].trim();
|
|
86
|
+
// Match field name and type
|
|
87
|
+
const fieldMatch = withoutComment.match(/^(\w+)\s+(\w+)(\?)?(\[\])?(.*)$/);
|
|
88
|
+
if (!fieldMatch)
|
|
89
|
+
return null;
|
|
90
|
+
const [, name, rawType, optional, isList, rest] = fieldMatch;
|
|
91
|
+
// Skip if this looks like an index or other non-field line
|
|
92
|
+
if (['@@', 'index', 'unique'].some((kw) => name.startsWith(kw))) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
const field = {
|
|
96
|
+
name,
|
|
97
|
+
type: rawType,
|
|
98
|
+
isRequired: !optional,
|
|
99
|
+
isUnique: rest.includes('@unique'),
|
|
100
|
+
isId: rest.includes('@id'),
|
|
101
|
+
isList: !!isList,
|
|
102
|
+
};
|
|
103
|
+
// Extract default value (handle nested parentheses)
|
|
104
|
+
const defaultMatch = rest.match(/@default\(/);
|
|
105
|
+
if (defaultMatch) {
|
|
106
|
+
const startIdx = rest.indexOf('@default(') + '@default('.length;
|
|
107
|
+
let depth = 1;
|
|
108
|
+
let endIdx = startIdx;
|
|
109
|
+
while (depth > 0 && endIdx < rest.length) {
|
|
110
|
+
if (rest[endIdx] === '(')
|
|
111
|
+
depth++;
|
|
112
|
+
else if (rest[endIdx] === ')')
|
|
113
|
+
depth--;
|
|
114
|
+
if (depth > 0)
|
|
115
|
+
endIdx++;
|
|
116
|
+
}
|
|
117
|
+
field.defaultValue = rest.substring(startIdx, endIdx);
|
|
118
|
+
}
|
|
119
|
+
// Extract relation
|
|
120
|
+
const relationMatch = rest.match(/@relation\(([^)]+)\)/);
|
|
121
|
+
if (relationMatch) {
|
|
122
|
+
const relationBody = relationMatch[1];
|
|
123
|
+
// Parse relation parts
|
|
124
|
+
const fieldsMatch = relationBody.match(/fields:\s*\[([^\]]+)\]/);
|
|
125
|
+
const referencesMatch = relationBody.match(/references:\s*\[([^\]]+)\]/);
|
|
126
|
+
const nameMatch = relationBody.match(/name:\s*"([^"]+)"/) || relationBody.match(/"([^"]+)"/);
|
|
127
|
+
field.relation = {
|
|
128
|
+
name: nameMatch ? nameMatch[1] : '',
|
|
129
|
+
model: rawType,
|
|
130
|
+
fields: fieldsMatch ? fieldsMatch[1].split(',').map((f) => f.trim()) : [],
|
|
131
|
+
references: referencesMatch ? referencesMatch[1].split(',').map((r) => r.trim()) : [],
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return field;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Extract enum definitions
|
|
138
|
+
*/
|
|
139
|
+
extractEnums(schema) {
|
|
140
|
+
const enums = [];
|
|
141
|
+
// Match enum blocks
|
|
142
|
+
const enumRegex = /enum\s+(\w+)\s*\{([^}]+)\}/g;
|
|
143
|
+
let match;
|
|
144
|
+
while ((match = enumRegex.exec(schema)) !== null) {
|
|
145
|
+
const name = match[1];
|
|
146
|
+
const body = match[2];
|
|
147
|
+
const values = body
|
|
148
|
+
.split('\n')
|
|
149
|
+
.map((line) => line.trim())
|
|
150
|
+
.filter((line) => line && !line.startsWith('//'));
|
|
151
|
+
enums.push({ name, values });
|
|
152
|
+
}
|
|
153
|
+
return enums;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Map Prisma type to OpenSaaS field type
|
|
157
|
+
*/
|
|
158
|
+
mapPrismaTypeToOpenSaas(prismaType) {
|
|
159
|
+
const mappings = {
|
|
160
|
+
String: { type: 'text', import: 'text' },
|
|
161
|
+
Int: { type: 'integer', import: 'integer' },
|
|
162
|
+
Float: { type: 'float', import: 'float' },
|
|
163
|
+
Boolean: { type: 'checkbox', import: 'checkbox' },
|
|
164
|
+
DateTime: { type: 'timestamp', import: 'timestamp' },
|
|
165
|
+
Json: { type: 'json', import: 'json' },
|
|
166
|
+
BigInt: { type: 'text', import: 'text' }, // No native support
|
|
167
|
+
Decimal: { type: 'text', import: 'text' }, // No native support
|
|
168
|
+
Bytes: { type: 'text', import: 'text' }, // No native support
|
|
169
|
+
};
|
|
170
|
+
return mappings[prismaType] || { type: 'text', import: 'text' };
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Get warnings for unsupported features
|
|
174
|
+
*/
|
|
175
|
+
getWarnings(schema) {
|
|
176
|
+
const warnings = [];
|
|
177
|
+
// Check for unsupported types
|
|
178
|
+
for (const model of schema.models) {
|
|
179
|
+
for (const field of model.fields) {
|
|
180
|
+
if (['BigInt', 'Decimal', 'Bytes'].includes(field.type)) {
|
|
181
|
+
warnings.push(`Field "${model.name}.${field.name}" uses unsupported type "${field.type}" - will be mapped to text()`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// Check for composite IDs
|
|
186
|
+
// This would require checking for @@id in the original schema
|
|
187
|
+
return warnings;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=prisma-introspector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prisma-introspector.js","sourceRoot":"","sources":["../../../src/migration/introspectors/prisma-introspector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration types - Shared types for the migration system
|
|
3
|
+
*/
|
|
4
|
+
export type ProjectType = 'prisma' | 'nextjs' | 'keystone';
|
|
5
|
+
export interface ModelInfo {
|
|
6
|
+
name: string;
|
|
7
|
+
fieldCount: number;
|
|
8
|
+
}
|
|
9
|
+
export interface ProjectAnalysis {
|
|
10
|
+
projectTypes: ProjectType[];
|
|
11
|
+
cwd: string;
|
|
12
|
+
models?: ModelInfo[];
|
|
13
|
+
provider?: string;
|
|
14
|
+
hasAuth?: boolean;
|
|
15
|
+
authLibrary?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface FieldMapping {
|
|
18
|
+
prismaType: string;
|
|
19
|
+
opensaasType: string;
|
|
20
|
+
opensaasImport: string;
|
|
21
|
+
}
|
|
22
|
+
export interface MigrationQuestion {
|
|
23
|
+
id: string;
|
|
24
|
+
text: string;
|
|
25
|
+
type: 'text' | 'select' | 'boolean' | 'multiselect';
|
|
26
|
+
options?: string[];
|
|
27
|
+
defaultValue?: string | boolean | string[];
|
|
28
|
+
required?: boolean;
|
|
29
|
+
dependsOn?: {
|
|
30
|
+
questionId: string;
|
|
31
|
+
value: string | boolean;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export interface MigrationSession {
|
|
35
|
+
id: string;
|
|
36
|
+
projectType: ProjectType;
|
|
37
|
+
analysis: ProjectAnalysis;
|
|
38
|
+
currentQuestionIndex: number;
|
|
39
|
+
answers: Record<string, string | boolean | string[]>;
|
|
40
|
+
generatedConfig?: string;
|
|
41
|
+
isComplete: boolean;
|
|
42
|
+
createdAt: Date;
|
|
43
|
+
updatedAt: Date;
|
|
44
|
+
}
|
|
45
|
+
export interface MigrationOutput {
|
|
46
|
+
configContent: string;
|
|
47
|
+
dependencies: string[];
|
|
48
|
+
files: Array<{
|
|
49
|
+
path: string;
|
|
50
|
+
content: string;
|
|
51
|
+
language: string;
|
|
52
|
+
description: string;
|
|
53
|
+
}>;
|
|
54
|
+
steps: string[];
|
|
55
|
+
warnings: string[];
|
|
56
|
+
}
|
|
57
|
+
export interface IntrospectedModel {
|
|
58
|
+
name: string;
|
|
59
|
+
fields: IntrospectedField[];
|
|
60
|
+
hasRelations: boolean;
|
|
61
|
+
primaryKey: string;
|
|
62
|
+
}
|
|
63
|
+
export interface IntrospectedField {
|
|
64
|
+
name: string;
|
|
65
|
+
type: string;
|
|
66
|
+
isRequired: boolean;
|
|
67
|
+
isUnique: boolean;
|
|
68
|
+
isId: boolean;
|
|
69
|
+
isList: boolean;
|
|
70
|
+
defaultValue?: string;
|
|
71
|
+
relation?: {
|
|
72
|
+
name: string;
|
|
73
|
+
model: string;
|
|
74
|
+
fields: string[];
|
|
75
|
+
references: string[];
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export interface IntrospectedSchema {
|
|
79
|
+
provider: string;
|
|
80
|
+
models: IntrospectedModel[];
|
|
81
|
+
enums: Array<{
|
|
82
|
+
name: string;
|
|
83
|
+
values: string[];
|
|
84
|
+
}>;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/migration/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/migration/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opensaas/stack-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "CLI tools for OpenSaas Stack",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -40,13 +40,16 @@
|
|
|
40
40
|
"chalk": "^5.6.2",
|
|
41
41
|
"chokidar": "^5.0.0",
|
|
42
42
|
"commander": "^14.0.2",
|
|
43
|
+
"fs-extra": "^11.3.2",
|
|
44
|
+
"glob": "^13.0.0",
|
|
43
45
|
"jiti": "^2.6.1",
|
|
44
46
|
"ora": "^9.0.0",
|
|
45
47
|
"prompts": "^2.4.2",
|
|
46
48
|
"zod": "^4.1.13",
|
|
47
|
-
"@opensaas/stack-core": "0.
|
|
49
|
+
"@opensaas/stack-core": "0.5.0"
|
|
48
50
|
},
|
|
49
51
|
"devDependencies": {
|
|
52
|
+
"@types/fs-extra": "^11.0.4",
|
|
50
53
|
"@types/node": "^24.10.1",
|
|
51
54
|
"@types/prompts": "^2.4.9",
|
|
52
55
|
"@vitest/coverage-v8": "^4.0.15",
|