fragment-ts 1.0.43 ā 1.0.44
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/commands/diagnostics.command.d.ts.map +1 -1
- package/dist/cli/commands/diagnostics.command.js +17 -73
- package/dist/cli/commands/diagnostics.command.js.map +1 -1
- package/dist/cli/commands/env.command.d.ts +10 -0
- package/dist/cli/commands/env.command.d.ts.map +1 -0
- package/dist/cli/commands/env.command.js +222 -0
- package/dist/cli/commands/env.command.js.map +1 -0
- package/dist/cli/commands/generate.command.js +9 -9
- package/dist/cli/commands/init.command.d.ts.map +1 -1
- package/dist/cli/commands/init.command.js +65 -35
- package/dist/cli/commands/init.command.js.map +1 -1
- package/dist/cli/commands/migrate.command.d.ts +14 -41
- package/dist/cli/commands/migrate.command.d.ts.map +1 -1
- package/dist/cli/commands/migrate.command.js +182 -424
- package/dist/cli/commands/migrate.command.js.map +1 -1
- package/dist/cli/commands/test.command.d.ts.map +1 -1
- package/dist/cli/commands/test.command.js +5 -51
- package/dist/cli/commands/test.command.js.map +1 -1
- package/dist/cli/index.js +48 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/scanner/component-scanner.d.ts +0 -4
- package/dist/core/scanner/component-scanner.d.ts.map +1 -1
- package/dist/core/scanner/component-scanner.js +0 -15
- package/dist/core/scanner/component-scanner.js.map +1 -1
- package/dist/shared/config.utils.d.ts +0 -27
- package/dist/shared/config.utils.d.ts.map +1 -1
- package/dist/shared/config.utils.js +7 -38
- package/dist/shared/config.utils.js.map +1 -1
- package/dist/shared/env.utils.d.ts +6 -18
- package/dist/shared/env.utils.d.ts.map +1 -1
- package/dist/shared/env.utils.js +84 -39
- package/dist/shared/env.utils.js.map +1 -1
- package/dist/testing/runner.d.ts.map +1 -1
- package/dist/testing/runner.js +2 -12
- package/dist/testing/runner.js.map +1 -1
- package/dist/typeorm/typeorm-module.d.ts.map +1 -1
- package/dist/typeorm/typeorm-module.js +4 -16
- package/dist/typeorm/typeorm-module.js.map +1 -1
- package/dist/web/application.d.ts.map +1 -1
- package/dist/web/application.js +1 -20
- package/dist/web/application.js.map +1 -1
- package/package.json +2 -1
- package/src/cli/commands/diagnostics.command.ts +16 -87
- package/src/cli/commands/env.command.ts +224 -0
- package/src/cli/commands/generate.command.ts +9 -9
- package/src/cli/commands/init.command.ts +68 -37
- package/src/cli/commands/migrate.command.ts +244 -528
- package/src/cli/commands/test.command.ts +5 -61
- package/src/cli/index.ts +19 -0
- package/src/core/scanner/component-scanner.ts +0 -15
- package/src/shared/config.utils.ts +10 -54
- package/src/shared/env.utils.ts +50 -44
- package/src/testing/runner.ts +2 -11
- package/src/typeorm/typeorm-module.ts +5 -14
- package/src/web/application.ts +1 -21
|
@@ -43,12 +43,13 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
43
43
|
const ora_1 = __importDefault(require("ora"));
|
|
44
44
|
const typeorm_module_1 = require("../../typeorm/typeorm-module");
|
|
45
45
|
const config_utils_1 = require("../../shared/config.utils");
|
|
46
|
-
const
|
|
46
|
+
const tsconfig_utils_1 = require("../../shared/tsconfig.utils");
|
|
47
|
+
const glob_1 = require("glob");
|
|
47
48
|
class MigrateCommand {
|
|
48
49
|
static register(program) {
|
|
49
50
|
program
|
|
50
51
|
.command("migrate")
|
|
51
|
-
.description("Run all pending migrations
|
|
52
|
+
.description("Run all pending migrations")
|
|
52
53
|
.action(async () => {
|
|
53
54
|
await this.runMigrations();
|
|
54
55
|
});
|
|
@@ -114,255 +115,169 @@ class MigrateCommand {
|
|
|
114
115
|
await this.createSeed(name);
|
|
115
116
|
});
|
|
116
117
|
}
|
|
117
|
-
// -----------------------------------------
|
|
118
|
-
// DETECTION METHODS
|
|
119
|
-
// -----------------------------------------
|
|
120
118
|
/**
|
|
121
|
-
*
|
|
119
|
+
* Detect if we should use TypeScript or JavaScript
|
|
122
120
|
*/
|
|
123
|
-
static
|
|
124
|
-
|
|
125
|
-
return this.tsNodeAvailable;
|
|
126
|
-
try {
|
|
127
|
-
// Check if ts-node is installed in the user's project
|
|
128
|
-
require.resolve("ts-node");
|
|
129
|
-
this.tsNodeAvailable = true;
|
|
130
|
-
}
|
|
131
|
-
catch {
|
|
132
|
-
try {
|
|
133
|
-
// Check if ts-node is installed globally or in parent modules
|
|
134
|
-
require("ts-node");
|
|
135
|
-
this.tsNodeAvailable = true;
|
|
136
|
-
}
|
|
137
|
-
catch {
|
|
138
|
-
this.tsNodeAvailable = false;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return this.tsNodeAvailable;
|
|
121
|
+
static setupEnvironment() {
|
|
122
|
+
return this.shouldUseTypeScript();
|
|
142
123
|
}
|
|
143
124
|
/**
|
|
144
|
-
*
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
return this.tsConfigExists;
|
|
149
|
-
this.tsConfigExists = fs.existsSync(path.join(process.cwd(), "tsconfig.json"));
|
|
150
|
-
return this.tsConfigExists;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Detect if TypeScript files exist in the project
|
|
154
|
-
*/
|
|
155
|
-
static detectProjectType() {
|
|
156
|
-
const srcDir = path.join(process.cwd(), "src");
|
|
157
|
-
const hasSrcDir = fs.existsSync(srcDir);
|
|
158
|
-
const hasTsFiles = hasSrcDir && fs.readdirSync(srcDir).some((file) => file.endsWith(".ts"));
|
|
159
|
-
const distDir = path.join(process.cwd(), "dist");
|
|
160
|
-
const hasDistDir = fs.existsSync(distDir);
|
|
161
|
-
const hasJsFiles = hasDistDir &&
|
|
162
|
-
fs.readdirSync(distDir).some((file) => file.endsWith(".js"));
|
|
163
|
-
if (hasTsFiles && !hasJsFiles)
|
|
164
|
-
return "typescript";
|
|
165
|
-
if (!hasTsFiles && hasJsFiles)
|
|
166
|
-
return "javascript";
|
|
167
|
-
if (hasTsFiles && hasJsFiles)
|
|
168
|
-
return "mixed";
|
|
169
|
-
// Default to checking for tsconfig
|
|
170
|
-
return this.hasTsConfig() ? "typescript" : "javascript";
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Determine whether to use TypeScript or JavaScript for migrations
|
|
125
|
+
* Detect if we should use TypeScript or JavaScript
|
|
126
|
+
* - Check if tsconfig.json exists AND has decorator support
|
|
127
|
+
* - Check if TypeScript files exist in include patterns
|
|
128
|
+
* - Check if ts-node is available
|
|
174
129
|
*/
|
|
175
130
|
static shouldUseTypeScript() {
|
|
176
|
-
|
|
177
|
-
const tsNodeAvailable = this.isTsNodeAvailable();
|
|
178
|
-
// Use the same logic as EnvUtils for consistency
|
|
179
|
-
const isDevMode = env_utils_1.EnvUtils.isDevelopmentMode();
|
|
180
|
-
// In development mode with ts-node available, use TypeScript
|
|
181
|
-
if (isDevMode && tsNodeAvailable) {
|
|
182
|
-
return true;
|
|
183
|
-
}
|
|
184
|
-
// In production mode, always use JavaScript
|
|
185
|
-
if (!isDevMode) {
|
|
131
|
+
if (!tsconfig_utils_1.TsConfigUtils.exists()) {
|
|
186
132
|
return false;
|
|
187
133
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
try {
|
|
198
|
-
// Register ts-node for TypeScript support
|
|
199
|
-
require("ts-node/register");
|
|
200
|
-
// If tsconfig-paths is available, register it too
|
|
134
|
+
if (!tsconfig_utils_1.TsConfigUtils.hasDecoratorSupport()) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
if (!this.isTsNodeAvailable()) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
const includePatterns = tsconfig_utils_1.TsConfigUtils.getIncludePatterns();
|
|
141
|
+
const cwd = process.cwd();
|
|
142
|
+
for (const pattern of includePatterns) {
|
|
201
143
|
try {
|
|
202
|
-
|
|
144
|
+
const files = (0, glob_1.globSync)(pattern, { cwd });
|
|
145
|
+
if (files.some((file) => file.endsWith(".ts") && !file.endsWith(".d.ts"))) {
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
203
148
|
}
|
|
204
149
|
catch {
|
|
205
|
-
//
|
|
150
|
+
// Ignore glob errors
|
|
206
151
|
}
|
|
207
|
-
console.log(chalk_1.default.gray("š Using ts-node for TypeScript migrations"));
|
|
208
152
|
}
|
|
209
|
-
|
|
210
|
-
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
static isTsNodeAvailable() {
|
|
156
|
+
if (this.tsNodeAvailable !== null) {
|
|
157
|
+
return this.tsNodeAvailable;
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
require.resolve("ts-node");
|
|
161
|
+
this.tsNodeAvailable = true;
|
|
211
162
|
}
|
|
163
|
+
catch {
|
|
164
|
+
this.tsNodeAvailable = false;
|
|
165
|
+
}
|
|
166
|
+
return this.tsNodeAvailable;
|
|
212
167
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
168
|
+
static registerTsNodeIfNeeded(useTypeScript) {
|
|
169
|
+
if (useTypeScript && this.isTsNodeAvailable()) {
|
|
170
|
+
require("ts-node").register({
|
|
171
|
+
transpileOnly: true,
|
|
172
|
+
compilerOptions: {
|
|
173
|
+
module: "commonjs",
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
}
|
|
219
177
|
}
|
|
220
178
|
/**
|
|
221
|
-
* Get migration paths
|
|
179
|
+
* Get entity and migration paths based on current mode
|
|
180
|
+
* Uses fragment.json config when available, otherwise infers from tsconfig
|
|
222
181
|
*/
|
|
223
|
-
static
|
|
182
|
+
static getPaths(useTypeScript) {
|
|
224
183
|
const dbConfig = config_utils_1.ConfigUtils.getDatabaseConfig();
|
|
225
|
-
|
|
184
|
+
const resolveExtension = (pattern) => {
|
|
185
|
+
return useTypeScript
|
|
186
|
+
? pattern.replace(/\.js$/, ".ts")
|
|
187
|
+
: pattern.replace(/\.ts$/, ".js");
|
|
188
|
+
};
|
|
189
|
+
if (dbConfig.entities || dbConfig.migrations) {
|
|
190
|
+
const entities = dbConfig.entities
|
|
191
|
+
? dbConfig.entities.map(resolveExtension)
|
|
192
|
+
: [useTypeScript ? "src/**/*.entity.ts" : "dist/**/*.entity.js"];
|
|
193
|
+
const migrations = dbConfig.migrations
|
|
194
|
+
? dbConfig.migrations.map(resolveExtension)
|
|
195
|
+
: [
|
|
196
|
+
useTypeScript
|
|
197
|
+
? "src/migrations/**/*.ts"
|
|
198
|
+
: "dist/migrations/**/*.js",
|
|
199
|
+
];
|
|
200
|
+
const migrationDir = this.extractMigrationDirectory(migrations[0], useTypeScript);
|
|
201
|
+
const seedsDir = path.join(migrationDir, "..", "seeds");
|
|
202
|
+
return { entities, migrations, seeds: seedsDir };
|
|
203
|
+
}
|
|
204
|
+
const rootDir = tsconfig_utils_1.TsConfigUtils.getRootDir();
|
|
205
|
+
const outDir = tsconfig_utils_1.TsConfigUtils.getOutDir();
|
|
206
|
+
const entities = [
|
|
207
|
+
useTypeScript ? `${rootDir}/**/*.entity.ts` : `${outDir}/**/*.entity.js`,
|
|
208
|
+
];
|
|
209
|
+
const migrations = [
|
|
210
|
+
useTypeScript
|
|
211
|
+
? `${rootDir}/migrations/**/*.ts`
|
|
212
|
+
: `${outDir}/migrations/**/*.js`,
|
|
213
|
+
];
|
|
214
|
+
const seeds = useTypeScript ? `${rootDir}/seeds` : `${outDir}/seeds`;
|
|
215
|
+
return { entities, migrations, seeds };
|
|
226
216
|
}
|
|
227
217
|
/**
|
|
228
|
-
*
|
|
218
|
+
* Extract the actual directory path from a glob pattern for file creation
|
|
229
219
|
*/
|
|
230
|
-
static
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
// Use configured paths but resolve based on current mode
|
|
234
|
-
return configPaths.map((pattern) => {
|
|
235
|
-
if (useTypeScript) {
|
|
236
|
-
return pattern.replace(/\.js$/, ".ts");
|
|
237
|
-
}
|
|
238
|
-
else {
|
|
239
|
-
return pattern.replace(/\.ts$/, ".js");
|
|
240
|
-
}
|
|
241
|
-
});
|
|
220
|
+
static extractMigrationDirectory(pattern, useTypeScript) {
|
|
221
|
+
if (pattern.includes("/**/*")) {
|
|
222
|
+
return pattern.split("/**/*")[0];
|
|
242
223
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* Get resolved migration paths based on current mode
|
|
248
|
-
*/
|
|
249
|
-
static getResolvedMigrationPaths(useTypeScript) {
|
|
250
|
-
const configPaths = this.getMigrationPathsFromConfig();
|
|
251
|
-
if (configPaths.length > 0) {
|
|
252
|
-
// Use configured paths but resolve based on current mode
|
|
253
|
-
return configPaths.map((pattern) => {
|
|
254
|
-
if (useTypeScript) {
|
|
255
|
-
return pattern.replace(/\.js$/, ".ts");
|
|
256
|
-
}
|
|
257
|
-
else {
|
|
258
|
-
return pattern.replace(/\.ts$/, ".js");
|
|
259
|
-
}
|
|
260
|
-
});
|
|
224
|
+
if (pattern.includes("/*.")) {
|
|
225
|
+
return pattern.split("/*")[0];
|
|
261
226
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
227
|
+
if (pattern.endsWith(".ts") || pattern.endsWith(".js")) {
|
|
228
|
+
return path.dirname(pattern);
|
|
229
|
+
}
|
|
230
|
+
return useTypeScript ? "src/migrations" : "dist/migrations";
|
|
266
231
|
}
|
|
267
|
-
// -----------------------------------------
|
|
268
|
-
// MIGRATION GENERATE
|
|
269
|
-
// -----------------------------------------
|
|
270
232
|
static async generateMigration(nameOrPath, options) {
|
|
271
|
-
const useTypeScript = this.
|
|
272
|
-
const spinner = (0, ora_1.default)(
|
|
233
|
+
const useTypeScript = this.setupEnvironment();
|
|
234
|
+
const spinner = (0, ora_1.default)(`Generating ${useTypeScript ? "TypeScript" : "JavaScript"} migration...`).start();
|
|
273
235
|
let dataSource = null;
|
|
274
236
|
try {
|
|
275
|
-
// Register ts-node if using TypeScript
|
|
276
237
|
this.registerTsNodeIfNeeded(useTypeScript);
|
|
277
|
-
|
|
278
|
-
const configOverride = {
|
|
279
|
-
entities: this.getResolvedEntityPaths(useTypeScript),
|
|
280
|
-
migrations: this.getResolvedMigrationPaths(useTypeScript),
|
|
281
|
-
};
|
|
238
|
+
const { entities, migrations } = this.getPaths(useTypeScript);
|
|
239
|
+
const configOverride = { entities, migrations };
|
|
282
240
|
dataSource = await typeorm_module_1.TypeORMModule.initialize(configOverride);
|
|
283
241
|
if (!dataSource?.isInitialized) {
|
|
284
242
|
throw new Error("Failed to initialize DataSource");
|
|
285
243
|
}
|
|
286
|
-
// Verify entities are loaded
|
|
287
244
|
this.verifyEntities(dataSource);
|
|
288
|
-
|
|
289
|
-
const
|
|
290
|
-
const migrationsDir = path.dirname(migrationPaths[0].replace("/**/*", ""));
|
|
245
|
+
const migrationsPattern = migrations[0];
|
|
246
|
+
const migrationsDir = this.extractMigrationDirectory(migrationsPattern, useTypeScript);
|
|
291
247
|
await fs.ensureDir(migrationsDir);
|
|
292
248
|
const existingMigrations = fs.existsSync(migrationsDir)
|
|
293
249
|
? fs
|
|
294
250
|
.readdirSync(migrationsDir)
|
|
295
|
-
.filter((f) => f.endsWith(useTypeScript ? ".ts" : ".js")
|
|
251
|
+
.filter((f) => f.endsWith(useTypeScript ? ".ts" : ".js") &&
|
|
252
|
+
!f.endsWith(".d.ts"))
|
|
296
253
|
: [];
|
|
297
254
|
const isFirstMigration = existingMigrations.length === 0;
|
|
298
|
-
// Generate schema SQL by comparing entities with database
|
|
299
255
|
spinner.text = "Analyzing schema changes...";
|
|
300
256
|
const sqlInMemory = await dataSource.driver.createSchemaBuilder().log();
|
|
301
257
|
const upQueries = sqlInMemory.upQueries || [];
|
|
302
258
|
const downQueries = sqlInMemory.downQueries || [];
|
|
303
259
|
const hasChanges = upQueries.length > 0;
|
|
304
|
-
// Handle no changes scenario
|
|
305
260
|
if (!hasChanges && !isFirstMigration) {
|
|
306
261
|
spinner.info("No schema changes detected. Migration not generated.");
|
|
307
262
|
return;
|
|
308
263
|
}
|
|
309
|
-
if (!hasChanges && isFirstMigration) {
|
|
310
|
-
const helpMessage = useTypeScript
|
|
311
|
-
? " - Your entities are in the correct location\n" +
|
|
312
|
-
" - Entity paths in fragment.json are correct\n" +
|
|
313
|
-
" - Entities are decorated with @Entity()"
|
|
314
|
-
: " - Your entities are compiled (run 'npm run build')\n" +
|
|
315
|
-
" - Entity paths in fragment.json point to dist/**/*.entity.js\n" +
|
|
316
|
-
" - Entities are decorated with @Entity()";
|
|
317
|
-
spinner.warn("No schema changes detected on first migration. Check that:\n" +
|
|
318
|
-
helpMessage);
|
|
319
|
-
return;
|
|
320
|
-
}
|
|
321
|
-
// Determine migration name
|
|
322
264
|
const migrationName = options.name ||
|
|
323
265
|
(nameOrPath ? path.basename(nameOrPath).replace(/\.ts$/, "") : null) ||
|
|
324
266
|
(isFirstMigration ? "InitialMigration" : "Migration");
|
|
325
267
|
const timestamp = Date.now();
|
|
326
268
|
const className = `${migrationName}${timestamp}`;
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
const upStatements = upQueries.map((query) => {
|
|
330
|
-
return this.buildQueryStatement(query);
|
|
331
|
-
});
|
|
332
|
-
const downStatements = downQueries.map((query) => {
|
|
333
|
-
return this.buildQueryStatement(query);
|
|
334
|
-
});
|
|
335
|
-
// Generate migration file content
|
|
269
|
+
const upStatements = upQueries.map((q) => this.buildQueryStatement(q));
|
|
270
|
+
const downStatements = downQueries.map((q) => this.buildQueryStatement(q));
|
|
336
271
|
const migrationContent = this.buildMigrationTemplate(className, upStatements, downStatements, isFirstMigration);
|
|
337
|
-
// Write migration file using config directory
|
|
338
272
|
const fileExt = useTypeScript ? ".ts" : ".js";
|
|
339
273
|
const fileName = `${timestamp}-${migrationName}${fileExt}`;
|
|
340
274
|
const filePath = path.join(migrationsDir, fileName);
|
|
341
275
|
await fs.writeFile(filePath, migrationContent, "utf-8");
|
|
342
|
-
|
|
343
|
-
spinner.succeed(`${fileType} migration generated: ${chalk_1.default.cyan(fileName)}\n` +
|
|
344
|
-
` ${chalk_1.default.gray("Location:")} ${filePath}\n` +
|
|
345
|
-
` ${chalk_1.default.gray("Queries:")} ${upQueries.length} up, ${downQueries.length} down\n` +
|
|
346
|
-
` ${chalk_1.default.gray("Mode:")} ${useTypeScript ? "TypeScript (ts-node)" : "JavaScript"}`);
|
|
276
|
+
spinner.succeed(`${useTypeScript ? "TypeScript" : "JavaScript"} migration generated: ${chalk_1.default.cyan(fileName)}`);
|
|
347
277
|
}
|
|
348
278
|
catch (error) {
|
|
349
279
|
spinner.fail("Migration generation failed");
|
|
350
|
-
|
|
351
|
-
console.error(chalk_1.default.red("\nā Error: " + error.message));
|
|
352
|
-
if (error.message.includes("Cannot find module") && useTypeScript) {
|
|
353
|
-
console.error(chalk_1.default.yellow("\nš” Tip: Try one of these solutions:\n" +
|
|
354
|
-
" 1. Install ts-node: npm install -D ts-node\n" +
|
|
355
|
-
" 2. Compile your project first: npm run build\n" +
|
|
356
|
-
" 3. Ensure your entities are in src/**/*.entity.ts"));
|
|
357
|
-
}
|
|
358
|
-
if (error.stack) {
|
|
359
|
-
console.error(chalk_1.default.gray("\nStack trace:"));
|
|
360
|
-
console.error(chalk_1.default.gray(error.stack));
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
else {
|
|
364
|
-
console.error(chalk_1.default.red(String(error)));
|
|
365
|
-
}
|
|
280
|
+
console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
|
|
366
281
|
process.exit(1);
|
|
367
282
|
}
|
|
368
283
|
finally {
|
|
@@ -370,111 +285,25 @@ class MigrateCommand {
|
|
|
370
285
|
try {
|
|
371
286
|
await dataSource.destroy();
|
|
372
287
|
}
|
|
373
|
-
catch
|
|
374
|
-
// Ignore cleanup errors
|
|
375
|
-
}
|
|
288
|
+
catch { }
|
|
376
289
|
}
|
|
377
290
|
}
|
|
378
291
|
}
|
|
379
|
-
/**
|
|
380
|
-
* Verify entities are loaded and provide helpful debugging
|
|
381
|
-
*/
|
|
382
|
-
static verifyEntities(dataSource) {
|
|
383
|
-
const entities = dataSource.entityMetadatas;
|
|
384
|
-
if (entities.length === 0) {
|
|
385
|
-
throw new Error("No entities found! Make sure:\n" +
|
|
386
|
-
" 1. Your entities are decorated with @Entity()\n" +
|
|
387
|
-
" 2. Entity paths in fragment.json are correct\n" +
|
|
388
|
-
" 3. For JavaScript mode: run 'npm run build' to compile\n" +
|
|
389
|
-
" 4. For TypeScript mode: entities should be in src/**/*.entity.ts");
|
|
390
|
-
}
|
|
391
|
-
console.log(chalk_1.default.gray(`\nš¦ Loaded ${entities.length} entity/entities:`));
|
|
392
|
-
entities.forEach((entity) => {
|
|
393
|
-
console.log(chalk_1.default.gray(` - ${entity.name} (${entity.tableName})`));
|
|
394
|
-
});
|
|
395
|
-
console.log();
|
|
396
|
-
}
|
|
397
|
-
/**
|
|
398
|
-
* Build a single query statement with proper escaping
|
|
399
|
-
*/
|
|
400
|
-
static buildQueryStatement(query) {
|
|
401
|
-
// Escape backslashes, backticks, and dollar signs for template literals
|
|
402
|
-
let sql = query.query
|
|
403
|
-
.replace(/\\/g, "\\\\") // Escape backslashes first
|
|
404
|
-
.replace(/`/g, "\\`") // Escape backticks
|
|
405
|
-
.replace(/\$/g, "\\$") // Escape dollar signs
|
|
406
|
-
.replace(/\r\n/g, " ") // Remove Windows line breaks
|
|
407
|
-
.replace(/\n/g, " ") // Remove Unix line breaks
|
|
408
|
-
.replace(/\s+/g, " ") // Collapse multiple spaces
|
|
409
|
-
.trim();
|
|
410
|
-
// Handle parameters if present
|
|
411
|
-
if (query.parameters && query.parameters.length > 0) {
|
|
412
|
-
const params = JSON.stringify(query.parameters);
|
|
413
|
-
return `await queryRunner.query(\`${sql}\`, ${params});`;
|
|
414
|
-
}
|
|
415
|
-
return `await queryRunner.query(\`${sql}\`);`;
|
|
416
|
-
}
|
|
417
|
-
// -----------------------------------------
|
|
418
|
-
// MIGRATION EXECUTION METHODS
|
|
419
|
-
// -----------------------------------------
|
|
420
292
|
static async runMigrations() {
|
|
421
|
-
const useTypeScript = this.
|
|
422
|
-
const spinner = (0, ora_1.default)(
|
|
293
|
+
const useTypeScript = this.setupEnvironment();
|
|
294
|
+
const spinner = (0, ora_1.default)(`Running ${useTypeScript ? "TypeScript" : "JavaScript"} migrations...`).start();
|
|
423
295
|
let dataSource = null;
|
|
424
296
|
try {
|
|
425
|
-
// Register ts-node if using TypeScript
|
|
426
297
|
this.registerTsNodeIfNeeded(useTypeScript);
|
|
427
|
-
|
|
428
|
-
const configOverride = {
|
|
429
|
-
entities: this.getResolvedEntityPaths(useTypeScript),
|
|
430
|
-
migrations: this.getResolvedMigrationPaths(useTypeScript),
|
|
431
|
-
};
|
|
298
|
+
const { entities, migrations } = this.getPaths(useTypeScript);
|
|
299
|
+
const configOverride = { entities, migrations };
|
|
432
300
|
dataSource = await typeorm_module_1.TypeORMModule.initialize(configOverride);
|
|
433
|
-
// Check if migrations exist using config paths
|
|
434
|
-
const migrationPaths = this.getResolvedMigrationPaths(useTypeScript);
|
|
435
|
-
const migrationsDir = path.dirname(migrationPaths[0].replace("/**/*", ""));
|
|
436
|
-
const fileExt = useTypeScript ? ".ts" : ".js";
|
|
437
|
-
const hasMigrations = fs.existsSync(migrationsDir) &&
|
|
438
|
-
fs.readdirSync(migrationsDir).filter((f) => f.endsWith(fileExt))
|
|
439
|
-
.length > 0;
|
|
440
|
-
if (!hasMigrations) {
|
|
441
|
-
const mode = useTypeScript ? "TypeScript" : "JavaScript";
|
|
442
|
-
spinner.info(`No ${mode.toLowerCase()} migrations found in ${migrationsDir}.`);
|
|
443
|
-
if (useTypeScript && this.hasJavaScriptMigrations()) {
|
|
444
|
-
console.log(chalk_1.default.yellow(`\nš” JavaScript migrations found. Try:\n` +
|
|
445
|
-
` 1. fragment migrate:run (in JavaScript mode)\n` +
|
|
446
|
-
` 2. Or compile your TypeScript: npm run build`));
|
|
447
|
-
}
|
|
448
|
-
else if (!useTypeScript && this.hasTypeScriptMigrations()) {
|
|
449
|
-
console.log(chalk_1.default.yellow(`\nš” TypeScript migrations found. Try:\n` +
|
|
450
|
-
` 1. Install ts-node: npm install -D ts-node\n` +
|
|
451
|
-
` 2. Then run: fragment migrate:run\n` +
|
|
452
|
-
` 3. Or compile first: npm run build`));
|
|
453
|
-
}
|
|
454
|
-
return;
|
|
455
|
-
}
|
|
456
|
-
const mode = useTypeScript ? "TypeScript" : "JavaScript";
|
|
457
|
-
spinner.text = `Running ${mode} migrations...`;
|
|
458
301
|
await typeorm_module_1.TypeORMModule.runMigrations();
|
|
459
|
-
spinner.succeed(`${
|
|
302
|
+
spinner.succeed(`${useTypeScript ? "TypeScript" : "JavaScript"} migrations completed successfully`);
|
|
460
303
|
}
|
|
461
304
|
catch (error) {
|
|
462
305
|
spinner.fail("Migration failed");
|
|
463
|
-
|
|
464
|
-
if (error.message.includes("Cannot find module") && useTypeScript) {
|
|
465
|
-
console.error(chalk_1.default.red("\nā TypeScript module not found."));
|
|
466
|
-
console.error(chalk_1.default.yellow("\nš” Try one of these solutions:\n" +
|
|
467
|
-
" 1. Install ts-node: npm install -D ts-node\n" +
|
|
468
|
-
" 2. Compile your TypeScript: npm run build\n" +
|
|
469
|
-
" 3. Check that your migration files are in src/migrations/*.ts"));
|
|
470
|
-
}
|
|
471
|
-
else {
|
|
472
|
-
console.error(chalk_1.default.red(error.message));
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
else {
|
|
476
|
-
console.error(chalk_1.default.red(String(error)));
|
|
477
|
-
}
|
|
306
|
+
console.error(chalk_1.default.red(error instanceof Error ? error.message : String(error)));
|
|
478
307
|
process.exit(1);
|
|
479
308
|
}
|
|
480
309
|
finally {
|
|
@@ -484,16 +313,13 @@ class MigrateCommand {
|
|
|
484
313
|
}
|
|
485
314
|
}
|
|
486
315
|
static async createMigration(name) {
|
|
487
|
-
|
|
488
|
-
const useTypeScript = true;
|
|
316
|
+
const useTypeScript = this.setupEnvironment();
|
|
489
317
|
const spinner = (0, ora_1.default)("Creating TypeScript migration...").start();
|
|
490
318
|
try {
|
|
319
|
+
const { migrations } = this.getPaths(true);
|
|
320
|
+
const migrationsDir = this.extractMigrationDirectory(migrations[0], true);
|
|
491
321
|
const timestamp = Date.now();
|
|
492
|
-
const
|
|
493
|
-
// Get migration directory from config
|
|
494
|
-
const migrationPaths = this.getResolvedMigrationPaths(useTypeScript);
|
|
495
|
-
const migrationsDir = path.dirname(migrationPaths[0].replace("/**/*", ""));
|
|
496
|
-
const fileName = `${timestamp}-${name}${fileExt}`;
|
|
322
|
+
const fileName = `${timestamp}-${name}.ts`;
|
|
497
323
|
const filePath = path.join(migrationsDir, fileName);
|
|
498
324
|
const content = `import { MigrationInterface, QueryRunner } from 'typeorm';
|
|
499
325
|
|
|
@@ -506,10 +332,6 @@ export class ${name}${timestamp} implements MigrationInterface {
|
|
|
506
332
|
await fs.ensureDir(path.dirname(filePath));
|
|
507
333
|
await fs.writeFile(filePath, content);
|
|
508
334
|
spinner.succeed(`TypeScript migration created: ${fileName}`);
|
|
509
|
-
console.log(chalk_1.default.gray(`\nš” Note: Migration created as TypeScript file.\n` +
|
|
510
|
-
` To use it, either:\n` +
|
|
511
|
-
` 1. Install ts-node: npm install -D ts-node\n` +
|
|
512
|
-
` 2. Or compile to JavaScript: npm run build`));
|
|
513
335
|
}
|
|
514
336
|
catch (error) {
|
|
515
337
|
spinner.fail("Failed to create migration");
|
|
@@ -518,21 +340,16 @@ export class ${name}${timestamp} implements MigrationInterface {
|
|
|
518
340
|
}
|
|
519
341
|
}
|
|
520
342
|
static async revertMigration() {
|
|
521
|
-
const useTypeScript = this.
|
|
522
|
-
const spinner = (0, ora_1.default)(
|
|
343
|
+
const useTypeScript = this.setupEnvironment();
|
|
344
|
+
const spinner = (0, ora_1.default)(`Reverting ${useTypeScript ? "TypeScript" : "JavaScript"} migration...`).start();
|
|
523
345
|
let dataSource = null;
|
|
524
346
|
try {
|
|
525
|
-
// Register ts-node if using TypeScript
|
|
526
347
|
this.registerTsNodeIfNeeded(useTypeScript);
|
|
527
|
-
|
|
528
|
-
const configOverride = {
|
|
529
|
-
entities: this.getResolvedEntityPaths(useTypeScript),
|
|
530
|
-
migrations: this.getResolvedMigrationPaths(useTypeScript),
|
|
531
|
-
};
|
|
348
|
+
const { entities, migrations } = this.getPaths(useTypeScript);
|
|
349
|
+
const configOverride = { entities, migrations };
|
|
532
350
|
dataSource = await typeorm_module_1.TypeORMModule.initialize(configOverride);
|
|
533
351
|
await typeorm_module_1.TypeORMModule.revertMigration();
|
|
534
|
-
|
|
535
|
-
spinner.succeed(`${mode} migration reverted successfully`);
|
|
352
|
+
spinner.succeed(`${useTypeScript ? "TypeScript" : "JavaScript"} migration reverted successfully`);
|
|
536
353
|
}
|
|
537
354
|
catch (error) {
|
|
538
355
|
spinner.fail("Revert failed");
|
|
@@ -546,22 +363,17 @@ export class ${name}${timestamp} implements MigrationInterface {
|
|
|
546
363
|
}
|
|
547
364
|
}
|
|
548
365
|
static async refreshMigrations() {
|
|
549
|
-
const useTypeScript = this.
|
|
550
|
-
const spinner = (0, ora_1.default)(
|
|
366
|
+
const useTypeScript = this.setupEnvironment();
|
|
367
|
+
const spinner = (0, ora_1.default)(`Refreshing ${useTypeScript ? "TypeScript" : "JavaScript"} migrations...`).start();
|
|
551
368
|
let dataSource = null;
|
|
552
369
|
try {
|
|
553
|
-
// Register ts-node if using TypeScript
|
|
554
370
|
this.registerTsNodeIfNeeded(useTypeScript);
|
|
555
|
-
|
|
556
|
-
const configOverride = {
|
|
557
|
-
entities: this.getResolvedEntityPaths(useTypeScript),
|
|
558
|
-
migrations: this.getResolvedMigrationPaths(useTypeScript),
|
|
559
|
-
};
|
|
371
|
+
const { entities, migrations } = this.getPaths(useTypeScript);
|
|
372
|
+
const configOverride = { entities, migrations };
|
|
560
373
|
dataSource = await typeorm_module_1.TypeORMModule.initialize(configOverride);
|
|
561
374
|
await typeorm_module_1.TypeORMModule.dropSchema();
|
|
562
375
|
await typeorm_module_1.TypeORMModule.runMigrations();
|
|
563
|
-
|
|
564
|
-
spinner.succeed(`${mode} migrations refreshed successfully`);
|
|
376
|
+
spinner.succeed(`${useTypeScript ? "TypeScript" : "JavaScript"} migrations refreshed successfully`);
|
|
565
377
|
}
|
|
566
378
|
catch (error) {
|
|
567
379
|
spinner.fail("Refresh failed");
|
|
@@ -575,16 +387,12 @@ export class ${name}${timestamp} implements MigrationInterface {
|
|
|
575
387
|
}
|
|
576
388
|
}
|
|
577
389
|
static async showStatus() {
|
|
578
|
-
const useTypeScript = this.
|
|
390
|
+
const useTypeScript = this.setupEnvironment();
|
|
579
391
|
let dataSource = null;
|
|
580
392
|
try {
|
|
581
|
-
// Register ts-node if using TypeScript
|
|
582
393
|
this.registerTsNodeIfNeeded(useTypeScript);
|
|
583
|
-
|
|
584
|
-
const configOverride = {
|
|
585
|
-
entities: this.getResolvedEntityPaths(useTypeScript),
|
|
586
|
-
migrations: this.getResolvedMigrationPaths(useTypeScript),
|
|
587
|
-
};
|
|
394
|
+
const { entities, migrations } = this.getPaths(useTypeScript);
|
|
395
|
+
const configOverride = { entities, migrations };
|
|
588
396
|
dataSource = await typeorm_module_1.TypeORMModule.initialize(configOverride);
|
|
589
397
|
const executedMigrations = await dataSource.query(`SELECT * FROM migrations ORDER BY timestamp DESC`);
|
|
590
398
|
const mode = useTypeScript ? "TypeScript" : "JavaScript";
|
|
@@ -598,9 +406,8 @@ export class ${name}${timestamp} implements MigrationInterface {
|
|
|
598
406
|
console.log(` ${chalk_1.default.cyan(m.name)} - ${new Date(m.timestamp).toLocaleString()}`);
|
|
599
407
|
});
|
|
600
408
|
}
|
|
601
|
-
|
|
602
|
-
const
|
|
603
|
-
const migrationsDir = path.dirname(migrationPaths[0].replace("/**/*", ""));
|
|
409
|
+
const migrationsPattern = migrations[0];
|
|
410
|
+
const migrationsDir = this.extractMigrationDirectory(migrationsPattern, useTypeScript);
|
|
604
411
|
const fileExt = useTypeScript ? ".ts" : ".js";
|
|
605
412
|
if (fs.existsSync(migrationsDir)) {
|
|
606
413
|
const files = fs
|
|
@@ -608,9 +415,7 @@ export class ${name}${timestamp} implements MigrationInterface {
|
|
|
608
415
|
.filter((f) => f.endsWith(fileExt));
|
|
609
416
|
console.log(chalk_1.default.blue(`\n Available ${mode.toLowerCase()} migration files: ${files.length}`));
|
|
610
417
|
}
|
|
611
|
-
|
|
612
|
-
console.log(chalk_1.default.gray(`\n Mode detection:`));
|
|
613
|
-
console.log(chalk_1.default.gray(` - Environment mode: ${env_utils_1.EnvUtils.getEnvironmentMode()}`));
|
|
418
|
+
console.log(chalk_1.default.gray(`\n Configuration:`));
|
|
614
419
|
console.log(chalk_1.default.gray(` - ts-node available: ${this.isTsNodeAvailable()}`));
|
|
615
420
|
console.log(chalk_1.default.gray(` - Using: ${useTypeScript ? "TypeScript" : "JavaScript"}`));
|
|
616
421
|
}
|
|
@@ -625,16 +430,13 @@ export class ${name}${timestamp} implements MigrationInterface {
|
|
|
625
430
|
}
|
|
626
431
|
}
|
|
627
432
|
static async syncSchema() {
|
|
628
|
-
const useTypeScript = this.
|
|
629
|
-
const spinner = (0, ora_1.default)(
|
|
433
|
+
const useTypeScript = this.setupEnvironment();
|
|
434
|
+
const spinner = (0, ora_1.default)(`Synchronizing ${useTypeScript ? "TypeScript" : "JavaScript"} schema...`).start();
|
|
630
435
|
let dataSource = null;
|
|
631
436
|
try {
|
|
632
|
-
// Register ts-node if using TypeScript
|
|
633
437
|
this.registerTsNodeIfNeeded(useTypeScript);
|
|
634
|
-
|
|
635
|
-
const configOverride = {
|
|
636
|
-
entities: this.getResolvedEntityPaths(useTypeScript),
|
|
637
|
-
};
|
|
438
|
+
const { entities } = this.getPaths(useTypeScript);
|
|
439
|
+
const configOverride = { entities };
|
|
638
440
|
dataSource = await typeorm_module_1.TypeORMModule.initialize(configOverride);
|
|
639
441
|
await typeorm_module_1.TypeORMModule.syncSchema();
|
|
640
442
|
spinner.succeed("Schema synchronized");
|
|
@@ -651,16 +453,13 @@ export class ${name}${timestamp} implements MigrationInterface {
|
|
|
651
453
|
}
|
|
652
454
|
}
|
|
653
455
|
static async dropSchema() {
|
|
654
|
-
const useTypeScript = this.
|
|
655
|
-
const spinner = (0, ora_1.default)(
|
|
456
|
+
const useTypeScript = this.setupEnvironment();
|
|
457
|
+
const spinner = (0, ora_1.default)(`Dropping ${useTypeScript ? "TypeScript" : "JavaScript"} schema...`).start();
|
|
656
458
|
let dataSource = null;
|
|
657
459
|
try {
|
|
658
|
-
// Register ts-node if using TypeScript
|
|
659
460
|
this.registerTsNodeIfNeeded(useTypeScript);
|
|
660
|
-
|
|
661
|
-
const configOverride = {
|
|
662
|
-
entities: this.getResolvedEntityPaths(useTypeScript),
|
|
663
|
-
};
|
|
461
|
+
const { entities } = this.getPaths(useTypeScript);
|
|
462
|
+
const configOverride = { entities };
|
|
664
463
|
dataSource = await typeorm_module_1.TypeORMModule.initialize(configOverride);
|
|
665
464
|
await typeorm_module_1.TypeORMModule.dropSchema();
|
|
666
465
|
spinner.succeed("Schema dropped");
|
|
@@ -677,40 +476,25 @@ export class ${name}${timestamp} implements MigrationInterface {
|
|
|
677
476
|
}
|
|
678
477
|
}
|
|
679
478
|
static async runSeeds() {
|
|
680
|
-
const
|
|
479
|
+
const useTypeScript = this.setupEnvironment();
|
|
480
|
+
const spinner = (0, ora_1.default)(`Running ${useTypeScript ? "TypeScript" : "JavaScript"} seeds...`).start();
|
|
681
481
|
try {
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
let seedsDir = "";
|
|
687
|
-
if (dbConfig.subscribers && dbConfig.subscribers.length > 0) {
|
|
688
|
-
// Infer seeds directory from subscribers or migrations
|
|
689
|
-
const migrationPaths = this.getResolvedMigrationPaths(useTypeScript);
|
|
690
|
-
seedsDir = path.join(path.dirname(migrationPaths[0]), "..", "seeds");
|
|
691
|
-
}
|
|
692
|
-
else {
|
|
693
|
-
// seedsDir = useTypeScript
|
|
694
|
-
// ? path.join(process.cwd(), "src", "seeds")
|
|
695
|
-
// : path.join(process.cwd(), "dist", "seeds");
|
|
696
|
-
throw new Error("No seeds directory found");
|
|
482
|
+
const { seeds: seedsDir } = this.getPaths(useTypeScript);
|
|
483
|
+
if (!fs.existsSync(seedsDir)) {
|
|
484
|
+
spinner.info(`No seeds directory found at ${seedsDir}`);
|
|
485
|
+
return;
|
|
697
486
|
}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
487
|
+
const files = fs.readdirSync(seedsDir);
|
|
488
|
+
for (const file of files) {
|
|
489
|
+
const isTsFile = file.endsWith(".ts") && !file.endsWith(".d.ts");
|
|
490
|
+
const isJsFile = file.endsWith(".js");
|
|
491
|
+
if ((useTypeScript && isTsFile) || (!useTypeScript && isJsFile)) {
|
|
492
|
+
if (useTypeScript) {
|
|
703
493
|
this.registerTsNodeIfNeeded(true);
|
|
704
|
-
const seedModule = require(path.join(seedsDir, file));
|
|
705
|
-
if (seedModule.default?.run) {
|
|
706
|
-
await seedModule.default.run();
|
|
707
|
-
}
|
|
708
494
|
}
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
await seedModule.default.run();
|
|
713
|
-
}
|
|
495
|
+
const seedModule = require(path.join(seedsDir, file));
|
|
496
|
+
if (seedModule.default?.run) {
|
|
497
|
+
await seedModule.default.run();
|
|
714
498
|
}
|
|
715
499
|
}
|
|
716
500
|
}
|
|
@@ -723,27 +507,17 @@ export class ${name}${timestamp} implements MigrationInterface {
|
|
|
723
507
|
}
|
|
724
508
|
}
|
|
725
509
|
static async createSeed(name) {
|
|
726
|
-
|
|
510
|
+
const useTypeScript = this.setupEnvironment();
|
|
727
511
|
const spinner = (0, ora_1.default)("Creating TypeScript seed...").start();
|
|
728
512
|
try {
|
|
729
|
-
|
|
730
|
-
const dbConfig = config_utils_1.ConfigUtils.getDatabaseConfig();
|
|
731
|
-
let seedsDir = "";
|
|
732
|
-
if (dbConfig.subscribers && dbConfig.subscribers.length > 0) {
|
|
733
|
-
const migrationPaths = this.getResolvedMigrationPaths(true);
|
|
734
|
-
seedsDir = path.join(path.dirname(migrationPaths[0]), "..", "seeds");
|
|
735
|
-
}
|
|
736
|
-
else {
|
|
737
|
-
seedsDir = path.join(process.cwd(), "src", "seeds");
|
|
738
|
-
}
|
|
513
|
+
const { seeds: seedsDir } = this.getPaths(true);
|
|
739
514
|
const fileName = `${name}.seed.ts`;
|
|
740
515
|
const filePath = path.join(seedsDir, fileName);
|
|
741
516
|
const content = `export default class ${name}Seed {
|
|
742
517
|
static async run() {
|
|
743
518
|
console.log('Running ${name} seed...');
|
|
744
519
|
}
|
|
745
|
-
}
|
|
746
|
-
`;
|
|
520
|
+
}`;
|
|
747
521
|
await fs.ensureDir(path.dirname(filePath));
|
|
748
522
|
await fs.writeFile(filePath, content);
|
|
749
523
|
spinner.succeed(`TypeScript seed created: ${fileName}`);
|
|
@@ -754,42 +528,32 @@ export class ${name}${timestamp} implements MigrationInterface {
|
|
|
754
528
|
process.exit(1);
|
|
755
529
|
}
|
|
756
530
|
}
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
.
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
static hasJavaScriptMigrations() {
|
|
768
|
-
const distMigrationsDir = path.join(process.cwd(), "dist", "migrations");
|
|
769
|
-
if (!fs.existsSync(distMigrationsDir))
|
|
770
|
-
return false;
|
|
771
|
-
const jsFiles = fs
|
|
772
|
-
.readdirSync(distMigrationsDir)
|
|
773
|
-
.filter((file) => file.endsWith(".js"));
|
|
774
|
-
return jsFiles.length > 0;
|
|
531
|
+
static verifyEntities(dataSource) {
|
|
532
|
+
const entities = dataSource.entityMetadatas;
|
|
533
|
+
if (entities.length === 0) {
|
|
534
|
+
throw new Error("No entities found!");
|
|
535
|
+
}
|
|
536
|
+
console.log(chalk_1.default.gray(`\nš¦ Loaded ${entities.length} entity/entities:`));
|
|
537
|
+
entities.forEach((entity) => {
|
|
538
|
+
console.log(chalk_1.default.gray(` - ${entity.name} (${entity.tableName})`));
|
|
539
|
+
});
|
|
540
|
+
console.log();
|
|
775
541
|
}
|
|
776
|
-
static
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
542
|
+
static buildQueryStatement(query) {
|
|
543
|
+
let sql = query.query
|
|
544
|
+
.replace(/\\/g, "\\\\")
|
|
545
|
+
.replace(/`/g, "\\`")
|
|
546
|
+
.replace(/\$/g, "\\$")
|
|
547
|
+
.replace(/\r\n/g, " ")
|
|
548
|
+
.replace(/\n/g, " ")
|
|
549
|
+
.replace(/\s+/g, " ")
|
|
550
|
+
.trim();
|
|
551
|
+
if (query.parameters && query.parameters.length > 0) {
|
|
552
|
+
const params = JSON.stringify(query.parameters);
|
|
553
|
+
return `await queryRunner.query(\`${sql}\`, ${params});`;
|
|
787
554
|
}
|
|
788
|
-
return
|
|
555
|
+
return `await queryRunner.query(\`${sql}\`);`;
|
|
789
556
|
}
|
|
790
|
-
/**
|
|
791
|
-
* Build the complete migration file template
|
|
792
|
-
*/
|
|
793
557
|
static buildMigrationTemplate(className, upStatements, downStatements, isFirstMigration) {
|
|
794
558
|
const upBody = upStatements.length > 0
|
|
795
559
|
? upStatements.map((s) => ` ${s}`).join("\n")
|
|
@@ -797,13 +561,9 @@ export class ${name}${timestamp} implements MigrationInterface {
|
|
|
797
561
|
const downBody = downStatements.length > 0
|
|
798
562
|
? downStatements.map((s) => ` ${s}`).join("\n")
|
|
799
563
|
: " // No changes";
|
|
800
|
-
|
|
801
|
-
? " // Initial migration - creates all tables\n"
|
|
802
|
-
: "";
|
|
803
|
-
return `import { MigrationInterface, QueryRunner } from "typeorm";
|
|
564
|
+
return `import { MigrationInterface, QueryRunner } from "fragment-ts";
|
|
804
565
|
|
|
805
566
|
export class ${className} implements MigrationInterface {
|
|
806
|
-
${comment}
|
|
807
567
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
808
568
|
${upBody}
|
|
809
569
|
}
|
|
@@ -811,11 +571,9 @@ ${upBody}
|
|
|
811
571
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
812
572
|
${downBody}
|
|
813
573
|
}
|
|
814
|
-
}
|
|
815
|
-
`;
|
|
574
|
+
}`;
|
|
816
575
|
}
|
|
817
576
|
}
|
|
818
577
|
exports.MigrateCommand = MigrateCommand;
|
|
819
578
|
MigrateCommand.tsNodeAvailable = null;
|
|
820
|
-
MigrateCommand.tsConfigExists = null;
|
|
821
579
|
//# sourceMappingURL=migrate.command.js.map
|