forge-sql-orm 1.0.15 → 1.0.16
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/package.json +3 -3
- package/scripts/actions/PatchPostinstall.ts +201 -0
- package/scripts/actions/generate-models.ts +65 -0
- package/scripts/actions/migrations-create.ts +193 -0
- package/scripts/actions/migrations-update.ts +200 -0
- package/scripts/cli.ts +221 -0
- package/{dist-cli → scripts}/forgeSqlCLI.js +1 -2
- package/dist-cli/cli.js +0 -571
- package/dist-cli/cli.js.map +0 -1
- package/dist-cli/cli.mjs +0 -570
- package/dist-cli/cli.mjs.map +0 -1
package/dist-cli/cli.js
DELETED
|
@@ -1,571 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
const commander = require("commander");
|
|
4
|
-
const dotenv = require("dotenv");
|
|
5
|
-
const inquirer = require("inquirer");
|
|
6
|
-
require("reflect-metadata");
|
|
7
|
-
const path = require("path");
|
|
8
|
-
const fs = require("fs");
|
|
9
|
-
const mysql = require("@mikro-orm/mysql");
|
|
10
|
-
const entityGenerator = require("@mikro-orm/entity-generator");
|
|
11
|
-
const regenerateIndexFile = (outputPath) => {
|
|
12
|
-
const entitiesDir = path.resolve(outputPath);
|
|
13
|
-
const indexPath = path.join(entitiesDir, "index.ts");
|
|
14
|
-
const entityFiles = fs.readdirSync(entitiesDir).filter((file) => file.endsWith(".ts") && file !== "index.ts");
|
|
15
|
-
const imports = entityFiles.map((file) => {
|
|
16
|
-
const entityName = path.basename(file, ".ts");
|
|
17
|
-
return `import { ${entityName} } from "./${entityName}";`;
|
|
18
|
-
});
|
|
19
|
-
const indexContent = `${imports.join("\n")}
|
|
20
|
-
|
|
21
|
-
export default [${entityFiles.map((file) => path.basename(file, ".ts")).join(", ")}];
|
|
22
|
-
`;
|
|
23
|
-
fs.writeFileSync(indexPath, indexContent, "utf8");
|
|
24
|
-
console.log(`✅ Updated index.ts with ${entityFiles.length} entities.`);
|
|
25
|
-
};
|
|
26
|
-
const generateModels = async (options) => {
|
|
27
|
-
try {
|
|
28
|
-
const ormConfig = mysql.defineConfig({
|
|
29
|
-
host: options.host,
|
|
30
|
-
port: options.port,
|
|
31
|
-
user: options.user,
|
|
32
|
-
password: options.password,
|
|
33
|
-
dbName: options.dbName,
|
|
34
|
-
namingStrategy: mysql.MongoNamingStrategy,
|
|
35
|
-
discovery: { warnWhenNoEntities: false },
|
|
36
|
-
extensions: [entityGenerator.EntityGenerator],
|
|
37
|
-
debug: true
|
|
38
|
-
});
|
|
39
|
-
const orm = mysql.MikroORM.initSync(ormConfig);
|
|
40
|
-
console.log(`✅ Connected to ${options.dbName} at ${options.host}:${options.port}`);
|
|
41
|
-
await orm.entityGenerator.generate({
|
|
42
|
-
entitySchema: true,
|
|
43
|
-
bidirectionalRelations: false,
|
|
44
|
-
identifiedReferences: false,
|
|
45
|
-
forceUndefined: true,
|
|
46
|
-
undefinedDefaults: true,
|
|
47
|
-
useCoreBaseEntity: false,
|
|
48
|
-
onlyPurePivotTables: false,
|
|
49
|
-
outputPurePivotTables: false,
|
|
50
|
-
scalarPropertiesForRelations: "always",
|
|
51
|
-
save: true,
|
|
52
|
-
path: options.output
|
|
53
|
-
});
|
|
54
|
-
regenerateIndexFile(options.output);
|
|
55
|
-
console.log(`✅ Entities generated at: ${options.output}`);
|
|
56
|
-
process.exit(0);
|
|
57
|
-
} catch (error) {
|
|
58
|
-
console.error(`❌ Error generating entities:`, error);
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
function cleanSQLStatement$1(sql) {
|
|
63
|
-
return sql.replace(/\s+default\s+character\s+set\s+utf8mb4\s+engine\s*=\s*InnoDB;?/gi, "").trim();
|
|
64
|
-
}
|
|
65
|
-
function generateMigrationFile$1(createStatements, version) {
|
|
66
|
-
const versionPrefix = `v${version}_MIGRATION`;
|
|
67
|
-
const migrationLines = createStatements.map(
|
|
68
|
-
(stmt, index) => ` .enqueue("${versionPrefix}${index}", "${cleanSQLStatement$1(stmt)}")`
|
|
69
|
-
// eslint-disable-line no-useless-escape
|
|
70
|
-
).join("\n");
|
|
71
|
-
return `import { MigrationRunner } from "@forge/sql/out/migration";
|
|
72
|
-
|
|
73
|
-
export default (migrationRunner: MigrationRunner): MigrationRunner => {
|
|
74
|
-
return migrationRunner
|
|
75
|
-
${migrationLines};
|
|
76
|
-
};`;
|
|
77
|
-
}
|
|
78
|
-
function saveMigrationFiles$1(migrationCode, version, outputDir) {
|
|
79
|
-
if (!fs.existsSync(outputDir)) {
|
|
80
|
-
fs.mkdirSync(outputDir, { recursive: true });
|
|
81
|
-
}
|
|
82
|
-
const migrationFilePath = path.join(outputDir, `migrationV${version}.ts`);
|
|
83
|
-
const migrationCountPath = path.join(outputDir, `migrationCount.ts`);
|
|
84
|
-
const indexFilePath = path.join(outputDir, `index.ts`);
|
|
85
|
-
fs.writeFileSync(migrationFilePath, migrationCode);
|
|
86
|
-
fs.writeFileSync(migrationCountPath, `export const MIGRATION_VERSION = ${version};`);
|
|
87
|
-
const indexFileContent = `import { MigrationRunner } from "@forge/sql/out/migration";
|
|
88
|
-
import { MIGRATION_VERSION } from "./migrationCount";
|
|
89
|
-
|
|
90
|
-
export type MigrationType = (
|
|
91
|
-
migrationRunner: MigrationRunner,
|
|
92
|
-
) => MigrationRunner;
|
|
93
|
-
|
|
94
|
-
export default async (
|
|
95
|
-
migrationRunner: MigrationRunner,
|
|
96
|
-
): Promise<MigrationRunner> => {
|
|
97
|
-
for (let i = 1; i <= MIGRATION_VERSION; i++) {
|
|
98
|
-
const migrations = (await import(\`./migrationV\${i}\`)) as {
|
|
99
|
-
default: MigrationType;
|
|
100
|
-
};
|
|
101
|
-
migrations.default(migrationRunner);
|
|
102
|
-
}
|
|
103
|
-
return migrationRunner;
|
|
104
|
-
};`;
|
|
105
|
-
fs.writeFileSync(indexFilePath, indexFileContent);
|
|
106
|
-
console.log(`✅ Migration file created: ${migrationFilePath}`);
|
|
107
|
-
console.log(`✅ Migration count file updated: ${migrationCountPath}`);
|
|
108
|
-
console.log(`✅ Migration index file created: ${indexFilePath}`);
|
|
109
|
-
}
|
|
110
|
-
const extractCreateStatements$1 = (schema) => {
|
|
111
|
-
const statements = schema.split(";").map((s) => s.trim());
|
|
112
|
-
return statements.filter(
|
|
113
|
-
(stmt) => stmt.startsWith("create table") || stmt.startsWith("alter table") && stmt.includes("add index") || stmt.startsWith("primary")
|
|
114
|
-
);
|
|
115
|
-
};
|
|
116
|
-
const loadEntities$1 = async (entitiesPath) => {
|
|
117
|
-
try {
|
|
118
|
-
const indexFilePath = path.resolve(path.join(entitiesPath, "index.ts"));
|
|
119
|
-
if (!fs.existsSync(indexFilePath)) {
|
|
120
|
-
console.error(`❌ Error: index.ts not found in ${entitiesPath}`);
|
|
121
|
-
process.exit(1);
|
|
122
|
-
}
|
|
123
|
-
const { default: entities } = await import(indexFilePath);
|
|
124
|
-
console.log(`✅ Loaded ${entities.length} entities from ${entitiesPath}`);
|
|
125
|
-
return entities;
|
|
126
|
-
} catch (error) {
|
|
127
|
-
console.error(`❌ Error loading index.ts from ${entitiesPath}:`, error);
|
|
128
|
-
process.exit(1);
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
const loadMigrationVersion$1 = async (migrationPath) => {
|
|
132
|
-
try {
|
|
133
|
-
const migrationCountFilePath = path.resolve(path.join(migrationPath, "migrationCount.ts"));
|
|
134
|
-
if (!fs.existsSync(migrationCountFilePath)) {
|
|
135
|
-
return 0;
|
|
136
|
-
}
|
|
137
|
-
const { MIGRATION_VERSION } = await import(migrationCountFilePath);
|
|
138
|
-
console.log(`✅ Current migration version: ${MIGRATION_VERSION}`);
|
|
139
|
-
return MIGRATION_VERSION;
|
|
140
|
-
} catch (error) {
|
|
141
|
-
console.error(`❌ Error loading migrationCount:`, error);
|
|
142
|
-
process.exit(1);
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
const createMigration = async (options) => {
|
|
146
|
-
try {
|
|
147
|
-
let version = await loadMigrationVersion$1(options.output);
|
|
148
|
-
if (version > 0) {
|
|
149
|
-
console.error(`❌ Error: Migration has already been created.`);
|
|
150
|
-
process.exit(1);
|
|
151
|
-
}
|
|
152
|
-
version = 1;
|
|
153
|
-
const entities = await loadEntities$1(options.entitiesPath);
|
|
154
|
-
const orm = mysql.MikroORM.initSync({
|
|
155
|
-
host: options.host,
|
|
156
|
-
port: options.port,
|
|
157
|
-
user: options.user,
|
|
158
|
-
password: options.password,
|
|
159
|
-
dbName: options.dbName,
|
|
160
|
-
entities
|
|
161
|
-
});
|
|
162
|
-
const createSchemaSQL = await orm.schema.getCreateSchemaSQL({ wrap: true });
|
|
163
|
-
const statements = extractCreateStatements$1(createSchemaSQL);
|
|
164
|
-
const migrationFile = generateMigrationFile$1(statements, version);
|
|
165
|
-
saveMigrationFiles$1(migrationFile, version, options.output);
|
|
166
|
-
console.log(`✅ Migration successfully created!`);
|
|
167
|
-
process.exit(0);
|
|
168
|
-
} catch (error) {
|
|
169
|
-
console.error(`❌ Error during migration creation:`, error);
|
|
170
|
-
process.exit(1);
|
|
171
|
-
}
|
|
172
|
-
};
|
|
173
|
-
function cleanSQLStatement(sql) {
|
|
174
|
-
return sql.replace(/\s+default\s+character\s+set\s+utf8mb4\s+engine\s*=\s*InnoDB;?/gi, "").trim();
|
|
175
|
-
}
|
|
176
|
-
function generateMigrationFile(createStatements, version) {
|
|
177
|
-
const versionPrefix = `v${version}_MIGRATION`;
|
|
178
|
-
const migrationLines = createStatements.map(
|
|
179
|
-
(stmt, index) => ` .enqueue("${versionPrefix}${index}", "${cleanSQLStatement(stmt)}")`
|
|
180
|
-
// eslint-disable-line no-useless-escape
|
|
181
|
-
).join("\n");
|
|
182
|
-
return `import { MigrationRunner } from "@forge/sql/out/migration";
|
|
183
|
-
|
|
184
|
-
export default (migrationRunner: MigrationRunner): MigrationRunner => {
|
|
185
|
-
return migrationRunner
|
|
186
|
-
${migrationLines};
|
|
187
|
-
};`;
|
|
188
|
-
}
|
|
189
|
-
function saveMigrationFiles(migrationCode, version, outputDir) {
|
|
190
|
-
if (!fs.existsSync(outputDir)) {
|
|
191
|
-
fs.mkdirSync(outputDir, { recursive: true });
|
|
192
|
-
}
|
|
193
|
-
const migrationFilePath = path.join(outputDir, `migrationV${version}.ts`);
|
|
194
|
-
const migrationCountPath = path.join(outputDir, `migrationCount.ts`);
|
|
195
|
-
const indexFilePath = path.join(outputDir, `index.ts`);
|
|
196
|
-
fs.writeFileSync(migrationFilePath, migrationCode);
|
|
197
|
-
fs.writeFileSync(migrationCountPath, `export const MIGRATION_VERSION = ${version};`);
|
|
198
|
-
const indexFileContent = `import { MigrationRunner } from "@forge/sql/out/migration";
|
|
199
|
-
import { MIGRATION_VERSION } from "./migrationCount";
|
|
200
|
-
|
|
201
|
-
export type MigrationType = (
|
|
202
|
-
migrationRunner: MigrationRunner,
|
|
203
|
-
) => MigrationRunner;
|
|
204
|
-
|
|
205
|
-
export default async (
|
|
206
|
-
migrationRunner: MigrationRunner,
|
|
207
|
-
): Promise<MigrationRunner> => {
|
|
208
|
-
for (let i = 1; i <= MIGRATION_VERSION; i++) {
|
|
209
|
-
const migrations = (await import(\`./migrationV\${i}\`)) as {
|
|
210
|
-
default: MigrationType;
|
|
211
|
-
};
|
|
212
|
-
migrations.default(migrationRunner);
|
|
213
|
-
}
|
|
214
|
-
return migrationRunner;
|
|
215
|
-
};`;
|
|
216
|
-
fs.writeFileSync(indexFilePath, indexFileContent);
|
|
217
|
-
console.log(`✅ Migration file created: ${migrationFilePath}`);
|
|
218
|
-
console.log(`✅ Migration count file updated: ${migrationCountPath}`);
|
|
219
|
-
console.log(`✅ Migration index file created: ${indexFilePath}`);
|
|
220
|
-
}
|
|
221
|
-
const extractCreateStatements = (schema) => {
|
|
222
|
-
const statements = schema.split(";").map((s) => s.trim());
|
|
223
|
-
return statements.filter(
|
|
224
|
-
(stmt) => stmt.startsWith("create table") || stmt.startsWith("alter table") && stmt.includes("add index") || stmt.startsWith("alter table") && stmt.includes("add") && !stmt.includes("foreign") || stmt.startsWith("alter table") && stmt.includes("modify") && !stmt.includes("foreign")
|
|
225
|
-
);
|
|
226
|
-
};
|
|
227
|
-
const loadEntities = async (entitiesPath) => {
|
|
228
|
-
try {
|
|
229
|
-
const indexFilePath = path.resolve(path.join(entitiesPath, "index.ts"));
|
|
230
|
-
if (!fs.existsSync(indexFilePath)) {
|
|
231
|
-
console.error(`❌ Error: index.ts not found in ${entitiesPath}`);
|
|
232
|
-
process.exit(1);
|
|
233
|
-
}
|
|
234
|
-
const { default: entities } = await import(indexFilePath);
|
|
235
|
-
console.log(`✅ Loaded ${entities.length} entities from ${entitiesPath}`);
|
|
236
|
-
return entities;
|
|
237
|
-
} catch (error) {
|
|
238
|
-
console.error(`❌ Error loading index.ts from ${entitiesPath}:`, error);
|
|
239
|
-
process.exit(1);
|
|
240
|
-
}
|
|
241
|
-
};
|
|
242
|
-
const loadMigrationVersion = async (migrationPath) => {
|
|
243
|
-
try {
|
|
244
|
-
const migrationCountFilePath = path.resolve(path.join(migrationPath, "migrationCount.ts"));
|
|
245
|
-
if (!fs.existsSync(migrationCountFilePath)) {
|
|
246
|
-
console.warn(
|
|
247
|
-
`⚠️ Warning: migrationCount.ts not found in ${migrationCountFilePath}, assuming no previous migrations.`
|
|
248
|
-
);
|
|
249
|
-
return 0;
|
|
250
|
-
}
|
|
251
|
-
const { MIGRATION_VERSION } = await import(migrationCountFilePath);
|
|
252
|
-
console.log(`✅ Current migration version: ${MIGRATION_VERSION}`);
|
|
253
|
-
return MIGRATION_VERSION;
|
|
254
|
-
} catch (error) {
|
|
255
|
-
console.error(`❌ Error loading migrationCount:`, error);
|
|
256
|
-
process.exit(1);
|
|
257
|
-
}
|
|
258
|
-
};
|
|
259
|
-
const updateMigration = async (options) => {
|
|
260
|
-
try {
|
|
261
|
-
let version = await loadMigrationVersion(options.output);
|
|
262
|
-
if (version < 1) {
|
|
263
|
-
console.log(
|
|
264
|
-
`⚠️ Initial migration not found. Run "npx forge-sql-orm migrations:create" first.`
|
|
265
|
-
);
|
|
266
|
-
process.exit(0);
|
|
267
|
-
}
|
|
268
|
-
version += 1;
|
|
269
|
-
const entities = await loadEntities(options.entitiesPath);
|
|
270
|
-
const orm = mysql.MikroORM.initSync({
|
|
271
|
-
host: options.host,
|
|
272
|
-
port: options.port,
|
|
273
|
-
user: options.user,
|
|
274
|
-
password: options.password,
|
|
275
|
-
dbName: options.dbName,
|
|
276
|
-
entities,
|
|
277
|
-
debug: true
|
|
278
|
-
});
|
|
279
|
-
const createSchemaSQL = await orm.schema.getUpdateSchemaMigrationSQL({ wrap: true });
|
|
280
|
-
const statements = extractCreateStatements(createSchemaSQL?.down || "");
|
|
281
|
-
if (statements.length) {
|
|
282
|
-
const migrationFile = generateMigrationFile(statements, version);
|
|
283
|
-
saveMigrationFiles(migrationFile, version, options.output);
|
|
284
|
-
console.log(`✅ Migration successfully updated!`);
|
|
285
|
-
process.exit(0);
|
|
286
|
-
} else {
|
|
287
|
-
console.log(`⚠️ No new migration changes detected.`);
|
|
288
|
-
process.exit(0);
|
|
289
|
-
}
|
|
290
|
-
} catch (error) {
|
|
291
|
-
console.error(`❌ Error during migration update:`, error);
|
|
292
|
-
process.exit(1);
|
|
293
|
-
}
|
|
294
|
-
};
|
|
295
|
-
const PATCHES = [
|
|
296
|
-
// 🗑️ Remove unused dialects (mssql, postgres, sqlite) in MikroORM
|
|
297
|
-
{
|
|
298
|
-
file: "node_modules/@mikro-orm/knex/MonkeyPatchable.d.ts",
|
|
299
|
-
deleteLines: [/^.*mssql.*$/gim, /^.*MsSql.*$/gim, /^\s*Postgres.*$/gm, /^.*Sqlite3.*$/gm, /^.*BetterSqlite3.*$/gim],
|
|
300
|
-
description: "Removing unused dialects from MonkeyPatchable.d.ts"
|
|
301
|
-
},
|
|
302
|
-
{
|
|
303
|
-
file: "node_modules/@mikro-orm/knex/MonkeyPatchable.js",
|
|
304
|
-
deleteLines: [/^.*mssql.*$/gim, /^.*MsSql.*$/gim, /^.*postgres.*$/gim, /^.*sqlite.*$/gim, /^.*Sqlite.*$/gim],
|
|
305
|
-
description: "Removing unused dialects from MonkeyPatchable.js"
|
|
306
|
-
},
|
|
307
|
-
{
|
|
308
|
-
file: "node_modules/@mikro-orm/knex/dialects/index.js",
|
|
309
|
-
deleteLines: [/^.*mssql.*$/gim, /^.*MsSql.*$/gim, /^.*postgresql.*$/gim, /^.*sqlite.*$/gim],
|
|
310
|
-
description: "Removing unused dialects from @mikro-orm/knex/dialects/index.js"
|
|
311
|
-
},
|
|
312
|
-
{
|
|
313
|
-
deleteFolder: "node_modules/@mikro-orm/knex/dialects/mssql",
|
|
314
|
-
description: "Removing mssql dialect from MikroORM"
|
|
315
|
-
},
|
|
316
|
-
{
|
|
317
|
-
deleteFolder: "node_modules/@mikro-orm/knex/dialects/postgresql",
|
|
318
|
-
description: "Removing postgresql dialect from MikroORM"
|
|
319
|
-
},
|
|
320
|
-
{
|
|
321
|
-
deleteFolder: "node_modules/@mikro-orm/knex/dialects/sqlite",
|
|
322
|
-
description: "Removing sqlite dialect from MikroORM"
|
|
323
|
-
},
|
|
324
|
-
// 🔄 Fix Webpack `Critical dependency: the request of a dependency is an expression`
|
|
325
|
-
{
|
|
326
|
-
file: "node_modules/@mikro-orm/core/utils/Configuration.js",
|
|
327
|
-
search: /dynamicImportProvider:\s*\/\* istanbul ignore next \*\/\s*\(id\) => import\(id\),/g,
|
|
328
|
-
replace: "dynamicImportProvider: /* istanbul ignore next */ () => Promise.resolve({}),",
|
|
329
|
-
description: "Fixing dynamic imports in MikroORM Configuration"
|
|
330
|
-
},
|
|
331
|
-
{
|
|
332
|
-
file: "node_modules/@mikro-orm/core/utils/Utils.js",
|
|
333
|
-
search: /static dynamicImportProvider = \(id\) => import\(id\);/g,
|
|
334
|
-
replace: "static dynamicImportProvider = () => Promise.resolve({});",
|
|
335
|
-
description: "Fixing dynamic imports in MikroORM Utils.js"
|
|
336
|
-
},
|
|
337
|
-
// 🛑 Remove deprecated `require.extensions` usage
|
|
338
|
-
{
|
|
339
|
-
file: "node_modules/@mikro-orm/core/utils/Utils.js",
|
|
340
|
-
search: /\s\|\|\s*\(require\.extensions\s*&&\s*!!require\.extensions\['\.ts'\]\);\s*/g,
|
|
341
|
-
replace: ";",
|
|
342
|
-
description: "Removing deprecated `require.extensions` check in MikroORM"
|
|
343
|
-
},
|
|
344
|
-
// 🛠️ Patch Knex to remove `Migrator` and `Seeder`
|
|
345
|
-
{
|
|
346
|
-
file: "node_modules/knex/lib/knex-builder/make-knex.js",
|
|
347
|
-
deleteLines: [/^const \{ Migrator \} = require\('\.\.\/migrations\/migrate\/Migrator'\);$/gm, /^const Seeder = require\('\.\.\/migrations\/seed\/Seeder'\);$/gm],
|
|
348
|
-
description: "Removing `Migrator` and `Seeder` requires from make-knex.js"
|
|
349
|
-
},
|
|
350
|
-
{
|
|
351
|
-
file: "node_modules/knex/lib/knex-builder/make-knex.js",
|
|
352
|
-
search: /\sreturn new Migrator\(this\);/g,
|
|
353
|
-
replace: "return null;",
|
|
354
|
-
description: "Replacing `return new Migrator(this);` with `return null;`"
|
|
355
|
-
},
|
|
356
|
-
{
|
|
357
|
-
file: "node_modules/knex/lib/knex-builder/make-knex.js",
|
|
358
|
-
search: /\sreturn new Seeder\(this\);/g,
|
|
359
|
-
replace: "return null;",
|
|
360
|
-
description: "Replacing `return new Seeder(this);` with `return null;`"
|
|
361
|
-
},
|
|
362
|
-
// 🔄 Patch for MikroORM Entity Generator to use 'forge-sql-orm'
|
|
363
|
-
// {
|
|
364
|
-
// file: "node_modules/@mikro-orm/entity-generator/SourceFile.js",
|
|
365
|
-
// search: /^.* from '@mikro-orm.*$/gim,
|
|
366
|
-
// replace: " }).join(', '))} } from 'forge-sql-orm';`);",
|
|
367
|
-
// description: "Replacing entity generator imports with 'forge-sql-orm'"
|
|
368
|
-
// },
|
|
369
|
-
{
|
|
370
|
-
file: "node_modules/knex/lib/dialects/index.js",
|
|
371
|
-
deleteLines: [/^.*mssql.*$/gim, /^.*MsSql.*$/gim, /^.*postgresql.*$/gim, /^.*sqlite.*$/gim, /^.*oracle.*$/gim, /^.*oracledb.*$/gim, /^.*pgnative.*$/gim, /^.*postgres.*$/gim, /^.*redshift.*$/gim, /^.*sqlite3.*$/gim, /^.*cockroachdb.*$/gim],
|
|
372
|
-
description: "Removing unused dialects from @mikro-orm/knex/dialects/index.js"
|
|
373
|
-
},
|
|
374
|
-
{
|
|
375
|
-
file: "node_modules/@mikro-orm/core/utils/Utils.js",
|
|
376
|
-
search: /\s\|\|\s*\(require\.extensions\s*&&\s*!!require\.extensions\['\.ts'\]\);\s*/g,
|
|
377
|
-
replace: ";",
|
|
378
|
-
// Replaces with semicolon to keep syntax valid
|
|
379
|
-
description: "Removing deprecated `require.extensions` check from MikroORM"
|
|
380
|
-
},
|
|
381
|
-
{
|
|
382
|
-
file: "node_modules/@mikro-orm/core/utils/Utils.js",
|
|
383
|
-
search: /^.*extensions.*$/gim,
|
|
384
|
-
replace: "{",
|
|
385
|
-
// Replaces with semicolon to keep syntax valid
|
|
386
|
-
description: "Removing deprecated `require.extensions` check from MikroORM"
|
|
387
|
-
},
|
|
388
|
-
{
|
|
389
|
-
file: "node_modules/@mikro-orm/core/utils/Utils.js",
|
|
390
|
-
search: /^.*package.json.*$/gim,
|
|
391
|
-
replace: "return 0;",
|
|
392
|
-
// Replaces with semicolon to keep syntax valid
|
|
393
|
-
description: "Removing deprecated `require.extensions` check from MikroORM"
|
|
394
|
-
},
|
|
395
|
-
{
|
|
396
|
-
file: "node_modules/@mikro-orm/knex/dialects/mysql/index.js",
|
|
397
|
-
deleteLines: [/^.*MariaDbKnexDialect.*$/gim],
|
|
398
|
-
description: "Removing MariaDbKnexDialect"
|
|
399
|
-
}
|
|
400
|
-
];
|
|
401
|
-
function runPostInstallPatch() {
|
|
402
|
-
console.log("🔧 Applying MikroORM & Knex patches...");
|
|
403
|
-
PATCHES.forEach(({ file, search, replace, deleteLines, deleteFile, deleteFolder, description }) => {
|
|
404
|
-
if (file) {
|
|
405
|
-
const filePath = path.resolve(file);
|
|
406
|
-
if (fs.existsSync(filePath)) {
|
|
407
|
-
let content = fs.readFileSync(filePath, "utf8");
|
|
408
|
-
let originalContent = content;
|
|
409
|
-
if (search && replace) {
|
|
410
|
-
if (typeof search === "string" ? content.includes(search) : search.test(content)) {
|
|
411
|
-
content = content.replace(search, replace);
|
|
412
|
-
console.log(`[PATCHED] ${description}`);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
if (deleteLines) {
|
|
416
|
-
deleteLines.forEach((pattern) => {
|
|
417
|
-
content = content.split("\n").filter((line) => !pattern.test(line)).join("\n");
|
|
418
|
-
});
|
|
419
|
-
if (content !== originalContent) {
|
|
420
|
-
console.log(`[CLEANED] Removed matching lines in ${file}`);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
if (content !== originalContent) {
|
|
424
|
-
fs.writeFileSync(filePath, content, "utf8");
|
|
425
|
-
}
|
|
426
|
-
if (content.trim() === "") {
|
|
427
|
-
fs.unlinkSync(filePath);
|
|
428
|
-
console.log(`[REMOVED] ${filePath} (file is now empty)`);
|
|
429
|
-
}
|
|
430
|
-
} else {
|
|
431
|
-
console.warn(`[WARNING] File not found: ${file}`);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
if (deleteFile) {
|
|
435
|
-
const deleteFilePath = path.resolve(__dirname, "../", deleteFile);
|
|
436
|
-
if (fs.existsSync(deleteFilePath)) {
|
|
437
|
-
fs.unlinkSync(deleteFilePath);
|
|
438
|
-
console.log(`[DELETED] ${description}`);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
if (deleteFolder) {
|
|
442
|
-
const deleteFolderPath = path.resolve(__dirname, "../", deleteFolder);
|
|
443
|
-
if (fs.existsSync(deleteFolderPath)) {
|
|
444
|
-
fs.rmSync(deleteFolderPath, { recursive: true, force: true });
|
|
445
|
-
console.log(`[DELETED] ${description}`);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
});
|
|
449
|
-
console.log("🎉 MikroORM & Knex patching completed!");
|
|
450
|
-
}
|
|
451
|
-
dotenv.config();
|
|
452
|
-
const askMissingParams = async (config, defaultOutput, customAskMissingParams) => {
|
|
453
|
-
const questions = [];
|
|
454
|
-
if (!config.host)
|
|
455
|
-
questions.push({
|
|
456
|
-
type: "input",
|
|
457
|
-
name: "host",
|
|
458
|
-
message: "Enter database host:",
|
|
459
|
-
default: "localhost"
|
|
460
|
-
});
|
|
461
|
-
if (!config.port)
|
|
462
|
-
questions.push({
|
|
463
|
-
type: "input",
|
|
464
|
-
name: "port",
|
|
465
|
-
message: "Enter database port:",
|
|
466
|
-
default: "3306",
|
|
467
|
-
validate: (input) => !isNaN(parseInt(input, 10))
|
|
468
|
-
});
|
|
469
|
-
if (!config.user)
|
|
470
|
-
questions.push({
|
|
471
|
-
type: "input",
|
|
472
|
-
name: "user",
|
|
473
|
-
message: "Enter database user:",
|
|
474
|
-
default: "root"
|
|
475
|
-
});
|
|
476
|
-
if (!config.password)
|
|
477
|
-
questions.push({
|
|
478
|
-
type: "password",
|
|
479
|
-
name: "password",
|
|
480
|
-
message: "Enter database password:",
|
|
481
|
-
mask: "*"
|
|
482
|
-
});
|
|
483
|
-
if (!config.dbName)
|
|
484
|
-
questions.push({
|
|
485
|
-
type: "input",
|
|
486
|
-
name: "dbName",
|
|
487
|
-
message: "Enter database name:"
|
|
488
|
-
});
|
|
489
|
-
if (!config.output)
|
|
490
|
-
questions.push({
|
|
491
|
-
type: "input",
|
|
492
|
-
name: "output",
|
|
493
|
-
message: "Enter output path:",
|
|
494
|
-
default: defaultOutput
|
|
495
|
-
});
|
|
496
|
-
if (customAskMissingParams) {
|
|
497
|
-
customAskMissingParams(config, questions);
|
|
498
|
-
}
|
|
499
|
-
if (questions.length > 0) {
|
|
500
|
-
const answers = await inquirer.prompt(questions);
|
|
501
|
-
return { ...config, ...answers, port: parseInt(answers.port, 10) };
|
|
502
|
-
}
|
|
503
|
-
return config;
|
|
504
|
-
};
|
|
505
|
-
const getConfig = async (cmd, defaultOutput, customConfig, customAskMissingParams) => {
|
|
506
|
-
let config = {
|
|
507
|
-
host: cmd.host || process.env.FORGE_SQL_ORM_HOST,
|
|
508
|
-
port: cmd.port ? parseInt(cmd.port, 10) : process.env.FORGE_SQL_ORM_PORT ? parseInt(process.env.FORGE_SQL_ORM_PORT, 10) : void 0,
|
|
509
|
-
user: cmd.user || process.env.FORGE_SQL_ORM_USER,
|
|
510
|
-
password: cmd.password || process.env.FORGE_SQL_ORM_PASSWORD,
|
|
511
|
-
dbName: cmd.dbName || process.env.FORGE_SQL_ORM_DBNAME,
|
|
512
|
-
output: cmd.output || process.env.FORGE_SQL_ORM_OUTPUT
|
|
513
|
-
};
|
|
514
|
-
if (customConfig) {
|
|
515
|
-
config = { ...config, ...customConfig() };
|
|
516
|
-
}
|
|
517
|
-
return await askMissingParams(config, defaultOutput, customAskMissingParams);
|
|
518
|
-
};
|
|
519
|
-
const program = new commander.Command();
|
|
520
|
-
program.version("1.0.0");
|
|
521
|
-
program.command("generate:model").description("Generate MikroORM models from the database.").option("--host <string>", "Database host").option("--port <number>", "Database port").option("--user <string>", "Database user").option("--password <string>", "Database password").option("--dbName <string>", "Database name").option("--output <string>", "Output path for entities").action(async (cmd) => {
|
|
522
|
-
const config = await getConfig(cmd, "./database/entities");
|
|
523
|
-
await generateModels(config);
|
|
524
|
-
});
|
|
525
|
-
program.command("migrations:create").description("Generate an initial migration for the entire database.").option("--host <string>", "Database host").option("--port <number>", "Database port").option("--user <string>", "Database user").option("--password <string>", "Database password").option("--dbName <string>", "Database name").option("--output <string>", "Output path for migrations").option("--entitiesPath <string>", "Path to the folder containing entities").action(async (cmd) => {
|
|
526
|
-
const config = await getConfig(
|
|
527
|
-
cmd,
|
|
528
|
-
"./database/migration",
|
|
529
|
-
() => ({
|
|
530
|
-
entitiesPath: cmd.entitiesPath || process.env.FORGE_SQL_ORM_ENTITIES_PATH
|
|
531
|
-
}),
|
|
532
|
-
(cfg, questions) => {
|
|
533
|
-
if (!cfg.entitiesPath)
|
|
534
|
-
questions.push({
|
|
535
|
-
type: "input",
|
|
536
|
-
name: "entitiesPath",
|
|
537
|
-
message: "Enter the path to entities:",
|
|
538
|
-
default: "./database/entities"
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
);
|
|
542
|
-
await createMigration(config);
|
|
543
|
-
});
|
|
544
|
-
program.command("migrations:update").description("Generate a migration to update the database schema.").option("--host <string>", "Database host").option("--port <number>", "Database port").option("--user <string>", "Database user").option("--password <string>", "Database password").option("--dbName <string>", "Database name").option("--output <string>", "Output path for migrations").option("--entitiesPath <string>", "Path to the folder containing entities").action(async (cmd) => {
|
|
545
|
-
const config = await getConfig(
|
|
546
|
-
cmd,
|
|
547
|
-
"./database/migration",
|
|
548
|
-
() => ({
|
|
549
|
-
entitiesPath: cmd.entitiesPath || process.env.FORGE_SQL_ORM_ENTITIES_PATH
|
|
550
|
-
}),
|
|
551
|
-
(cfg, questions) => {
|
|
552
|
-
if (!cfg.entitiesPath)
|
|
553
|
-
questions.push({
|
|
554
|
-
type: "input",
|
|
555
|
-
name: "entitiesPath",
|
|
556
|
-
message: "Enter the path to entities:",
|
|
557
|
-
default: "./database/entities"
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
);
|
|
561
|
-
await updateMigration(config);
|
|
562
|
-
});
|
|
563
|
-
program.command("patch:mikroorm").description("Patch MikroORM and Knex dependencies to work properly with Forge").action(async () => {
|
|
564
|
-
console.log("Running MikroORM patch...");
|
|
565
|
-
await runPostInstallPatch();
|
|
566
|
-
await runPostInstallPatch();
|
|
567
|
-
await runPostInstallPatch();
|
|
568
|
-
console.log("✅ MikroORM patch applied successfully!");
|
|
569
|
-
});
|
|
570
|
-
program.parse(process.argv);
|
|
571
|
-
//# sourceMappingURL=cli.js.map
|