arkormx 2.0.0-next.9 → 2.0.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/README.md +2 -2
- package/dist/cli.mjs +946 -227
- package/dist/index.cjs +5275 -3989
- package/dist/index.d.cts +640 -110
- package/dist/index.d.mts +641 -111
- package/dist/index.mjs +5266 -3990
- package/package.json +2 -2
- package/stubs/model.js.stub +1 -1
- package/stubs/model.stub +2 -2
- package/stubs/pivot-model.stub +4 -0
package/dist/cli.mjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
4
|
-
import { dirname, extname, join, resolve } from "node:path";
|
|
5
|
-
import { spawnSync } from "node:child_process";
|
|
6
|
-
import { str } from "@h3ravel/support";
|
|
7
|
-
import path, { dirname as dirname$1, extname as extname$1, join as join$1, relative } from "path";
|
|
8
|
-
import { copyFileSync, existsSync as existsSync$1, mkdirSync as mkdirSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, rmSync as rmSync$1, writeFileSync as writeFileSync$1 } from "fs";
|
|
9
2
|
import { AsyncLocalStorage } from "async_hooks";
|
|
10
3
|
import { createJiti } from "@rexxars/jiti";
|
|
11
4
|
import { pathToFileURL } from "node:url";
|
|
5
|
+
import { dirname, extname, join, resolve } from "node:path";
|
|
6
|
+
import { createRequire } from "module";
|
|
7
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "fs";
|
|
12
8
|
import { fileURLToPath } from "url";
|
|
9
|
+
import path, { dirname as dirname$1, extname as extname$1, join as join$1, relative } from "path";
|
|
10
|
+
import { existsSync as existsSync$1, mkdirSync as mkdirSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, rmSync as rmSync$1, writeFileSync as writeFileSync$1 } from "node:fs";
|
|
11
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
12
|
+
import { spawnSync } from "node:child_process";
|
|
13
|
+
import { str } from "@h3ravel/support";
|
|
13
14
|
import { Logger } from "@h3ravel/shared";
|
|
14
|
-
import { createRequire } from "module";
|
|
15
15
|
import { Command, Kernel } from "@h3ravel/musket";
|
|
16
16
|
|
|
17
17
|
//#region src/Exceptions/ArkormException.ts
|
|
@@ -55,6 +55,183 @@ var ArkormException = class extends Error {
|
|
|
55
55
|
}
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/Exceptions/MissingDelegateException.ts
|
|
60
|
+
var MissingDelegateException = class extends ArkormException {
|
|
61
|
+
constructor(message, context = {}) {
|
|
62
|
+
super(message, {
|
|
63
|
+
code: "MISSING_DELEGATE",
|
|
64
|
+
...context
|
|
65
|
+
});
|
|
66
|
+
this.name = "MissingDelegateException";
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/Exceptions/QueryExecutionException.ts
|
|
72
|
+
var QueryExecutionException = class extends ArkormException {
|
|
73
|
+
inspection;
|
|
74
|
+
constructor(message = "Database query execution failed.", context = {}) {
|
|
75
|
+
super(message, {
|
|
76
|
+
code: "QUERY_EXECUTION_FAILED",
|
|
77
|
+
...context,
|
|
78
|
+
meta: {
|
|
79
|
+
...context.meta ?? {},
|
|
80
|
+
...context.inspection ? { inspection: context.inspection } : {}
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
this.name = "QueryExecutionException";
|
|
84
|
+
this.inspection = context.inspection;
|
|
85
|
+
}
|
|
86
|
+
getInspection() {
|
|
87
|
+
return this.inspection;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region src/Exceptions/UnsupportedAdapterFeatureException.ts
|
|
93
|
+
var UnsupportedAdapterFeatureException = class extends ArkormException {
|
|
94
|
+
constructor(message, context = {}) {
|
|
95
|
+
super(message, {
|
|
96
|
+
code: "UNSUPPORTED_ADAPTER_FEATURE",
|
|
97
|
+
...context
|
|
98
|
+
});
|
|
99
|
+
this.name = "UnsupportedAdapterFeatureException";
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/helpers/runtime-module-loader.ts
|
|
105
|
+
var RuntimeModuleLoader = class {
|
|
106
|
+
static async load(filePath) {
|
|
107
|
+
const resolvedPath = resolve(filePath);
|
|
108
|
+
return await createJiti(pathToFileURL(resolvedPath).href, {
|
|
109
|
+
interopDefault: false,
|
|
110
|
+
tsconfigPaths: true
|
|
111
|
+
}).import(resolvedPath);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
//#endregion
|
|
116
|
+
//#region src/helpers/migration-history.ts
|
|
117
|
+
const createEmptyAppliedMigrationsState = () => ({
|
|
118
|
+
version: 1,
|
|
119
|
+
migrations: [],
|
|
120
|
+
runs: []
|
|
121
|
+
});
|
|
122
|
+
const supportsDatabaseMigrationState = (adapter) => {
|
|
123
|
+
return typeof adapter?.readAppliedMigrationsState === "function" && typeof adapter?.writeAppliedMigrationsState === "function";
|
|
124
|
+
};
|
|
125
|
+
const resolveMigrationStateFilePath = (cwd, configuredPath) => {
|
|
126
|
+
if (configuredPath && configuredPath.trim().length > 0) return resolve(configuredPath);
|
|
127
|
+
return join(cwd, ".arkormx", "migrations.applied.json");
|
|
128
|
+
};
|
|
129
|
+
const buildMigrationIdentity = (filePath, className) => {
|
|
130
|
+
const fileName = filePath.split("/").pop()?.split("\\").pop() ?? filePath;
|
|
131
|
+
return `${fileName.slice(0, fileName.length - extname(fileName).length)}:${className}`;
|
|
132
|
+
};
|
|
133
|
+
const computeMigrationChecksum = (filePath) => {
|
|
134
|
+
const source = readFileSync$1(filePath, "utf-8");
|
|
135
|
+
return createHash("sha256").update(source).digest("hex");
|
|
136
|
+
};
|
|
137
|
+
const readAppliedMigrationsState = (stateFilePath) => {
|
|
138
|
+
if (!existsSync$1(stateFilePath)) return createEmptyAppliedMigrationsState();
|
|
139
|
+
try {
|
|
140
|
+
const parsed = JSON.parse(readFileSync$1(stateFilePath, "utf-8"));
|
|
141
|
+
if (!Array.isArray(parsed.migrations)) return createEmptyAppliedMigrationsState();
|
|
142
|
+
return {
|
|
143
|
+
version: 1,
|
|
144
|
+
migrations: parsed.migrations.filter((migration) => {
|
|
145
|
+
return typeof migration?.id === "string" && typeof migration?.file === "string" && typeof migration?.className === "string" && typeof migration?.appliedAt === "string" && (migration?.checksum === void 0 || typeof migration?.checksum === "string");
|
|
146
|
+
}),
|
|
147
|
+
runs: Array.isArray(parsed.runs) ? parsed.runs.filter((run) => {
|
|
148
|
+
return typeof run?.id === "string" && typeof run?.appliedAt === "string" && Array.isArray(run?.migrationIds) && run.migrationIds.every((item) => typeof item === "string");
|
|
149
|
+
}) : []
|
|
150
|
+
};
|
|
151
|
+
} catch {
|
|
152
|
+
return createEmptyAppliedMigrationsState();
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
const readAppliedMigrationsStateFromStore = async (adapter, stateFilePath) => {
|
|
156
|
+
if (supportsDatabaseMigrationState(adapter)) return await adapter.readAppliedMigrationsState();
|
|
157
|
+
return readAppliedMigrationsState(stateFilePath);
|
|
158
|
+
};
|
|
159
|
+
const writeAppliedMigrationsState = (stateFilePath, state) => {
|
|
160
|
+
const directory = dirname(stateFilePath);
|
|
161
|
+
if (!existsSync$1(directory)) mkdirSync$1(directory, { recursive: true });
|
|
162
|
+
writeFileSync$1(stateFilePath, JSON.stringify(state, null, 2));
|
|
163
|
+
};
|
|
164
|
+
const writeAppliedMigrationsStateToStore = async (adapter, stateFilePath, state) => {
|
|
165
|
+
if (supportsDatabaseMigrationState(adapter)) {
|
|
166
|
+
await adapter.writeAppliedMigrationsState(state);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
writeAppliedMigrationsState(stateFilePath, state);
|
|
170
|
+
};
|
|
171
|
+
const isMigrationApplied = (state, identity, checksum) => {
|
|
172
|
+
const matched = state.migrations.find((migration) => migration.id === identity);
|
|
173
|
+
if (!matched) return false;
|
|
174
|
+
if (checksum && matched.checksum) return matched.checksum === checksum;
|
|
175
|
+
if (checksum && !matched.checksum) return false;
|
|
176
|
+
return true;
|
|
177
|
+
};
|
|
178
|
+
const findAppliedMigration = (state, identity) => {
|
|
179
|
+
return state.migrations.find((migration) => migration.id === identity);
|
|
180
|
+
};
|
|
181
|
+
const markMigrationApplied = (state, entry) => {
|
|
182
|
+
const next = state.migrations.filter((migration) => migration.id !== entry.id);
|
|
183
|
+
next.push(entry);
|
|
184
|
+
return {
|
|
185
|
+
version: 1,
|
|
186
|
+
migrations: next,
|
|
187
|
+
runs: state.runs ?? []
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
const removeAppliedMigration = (state, identity) => {
|
|
191
|
+
return {
|
|
192
|
+
version: 1,
|
|
193
|
+
migrations: state.migrations.filter((migration) => migration.id !== identity),
|
|
194
|
+
runs: (state.runs ?? []).map((run) => ({
|
|
195
|
+
...run,
|
|
196
|
+
migrationIds: run.migrationIds.filter((id) => id !== identity)
|
|
197
|
+
})).filter((run) => run.migrationIds.length > 0)
|
|
198
|
+
};
|
|
199
|
+
};
|
|
200
|
+
const buildMigrationRunId = () => {
|
|
201
|
+
return `run_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
202
|
+
};
|
|
203
|
+
const markMigrationRun = (state, run) => {
|
|
204
|
+
const nextRuns = (state.runs ?? []).filter((existing) => existing.id !== run.id);
|
|
205
|
+
nextRuns.push(run);
|
|
206
|
+
return {
|
|
207
|
+
version: 1,
|
|
208
|
+
migrations: state.migrations,
|
|
209
|
+
runs: nextRuns
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
const getLastMigrationRun = (state) => {
|
|
213
|
+
const runs = state.runs ?? [];
|
|
214
|
+
if (runs.length === 0) return void 0;
|
|
215
|
+
return runs.map((run, index) => ({
|
|
216
|
+
run,
|
|
217
|
+
index
|
|
218
|
+
})).sort((left, right) => {
|
|
219
|
+
const appliedAtOrder = right.run.appliedAt.localeCompare(left.run.appliedAt);
|
|
220
|
+
if (appliedAtOrder !== 0) return appliedAtOrder;
|
|
221
|
+
return right.index - left.index;
|
|
222
|
+
})[0]?.run;
|
|
223
|
+
};
|
|
224
|
+
const getLatestAppliedMigrations = (state, steps) => {
|
|
225
|
+
return state.migrations.map((migration, index) => ({
|
|
226
|
+
migration,
|
|
227
|
+
index
|
|
228
|
+
})).sort((left, right) => {
|
|
229
|
+
const appliedAtOrder = right.migration.appliedAt.localeCompare(left.migration.appliedAt);
|
|
230
|
+
if (appliedAtOrder !== 0) return appliedAtOrder;
|
|
231
|
+
return right.index - left.index;
|
|
232
|
+
}).slice(0, Math.max(0, steps)).map((entry) => entry.migration);
|
|
233
|
+
};
|
|
234
|
+
|
|
58
235
|
//#endregion
|
|
59
236
|
//#region src/helpers/PrimaryKeyGenerationPlanner.ts
|
|
60
237
|
var PrimaryKeyGenerationPlanner = class {
|
|
@@ -1367,9 +1544,9 @@ const generateMigrationFile = (name, options = {}) => {
|
|
|
1367
1544
|
const filePath = join(directory, fileName);
|
|
1368
1545
|
const content = buildMigrationSource(className, extension);
|
|
1369
1546
|
if (options.write ?? true) {
|
|
1370
|
-
if (!existsSync(directory)) mkdirSync(directory, { recursive: true });
|
|
1371
|
-
if (existsSync(filePath)) throw new ArkormException(`Migration file already exists: ${filePath}`);
|
|
1372
|
-
writeFileSync(filePath, content);
|
|
1547
|
+
if (!existsSync$1(directory)) mkdirSync$1(directory, { recursive: true });
|
|
1548
|
+
if (existsSync$1(filePath)) throw new ArkormException(`Migration file already exists: ${filePath}`);
|
|
1549
|
+
writeFileSync$1(filePath, content);
|
|
1373
1550
|
}
|
|
1374
1551
|
return {
|
|
1375
1552
|
fileName,
|
|
@@ -1425,11 +1602,11 @@ const applyMigrationRollbackToDatabase = async (adapter, migration) => {
|
|
|
1425
1602
|
*/
|
|
1426
1603
|
const applyMigrationToPrismaSchema = async (migration, options = {}) => {
|
|
1427
1604
|
const schemaPath = options.schemaPath ?? join(process.cwd(), "prisma", "schema.prisma");
|
|
1428
|
-
if (!existsSync(schemaPath)) throw new ArkormException(`Prisma schema file not found: ${schemaPath}`);
|
|
1429
|
-
const source = readFileSync(schemaPath, "utf-8");
|
|
1605
|
+
if (!existsSync$1(schemaPath)) throw new ArkormException(`Prisma schema file not found: ${schemaPath}`);
|
|
1606
|
+
const source = readFileSync$1(schemaPath, "utf-8");
|
|
1430
1607
|
const operations = await getMigrationPlan(migration, "up");
|
|
1431
1608
|
const schema = applyOperationsToPrismaSchema(source, operations);
|
|
1432
|
-
if (options.write ?? true) writeFileSync(schemaPath, schema);
|
|
1609
|
+
if (options.write ?? true) writeFileSync$1(schemaPath, schema);
|
|
1433
1610
|
return {
|
|
1434
1611
|
schema,
|
|
1435
1612
|
schemaPath,
|
|
@@ -1445,11 +1622,11 @@ const applyMigrationToPrismaSchema = async (migration, options = {}) => {
|
|
|
1445
1622
|
*/
|
|
1446
1623
|
const applyMigrationRollbackToPrismaSchema = async (migration, options = {}) => {
|
|
1447
1624
|
const schemaPath = options.schemaPath ?? join(process.cwd(), "prisma", "schema.prisma");
|
|
1448
|
-
if (!existsSync(schemaPath)) throw new ArkormException(`Prisma schema file not found: ${schemaPath}`);
|
|
1449
|
-
const source = readFileSync(schemaPath, "utf-8");
|
|
1625
|
+
if (!existsSync$1(schemaPath)) throw new ArkormException(`Prisma schema file not found: ${schemaPath}`);
|
|
1626
|
+
const source = readFileSync$1(schemaPath, "utf-8");
|
|
1450
1627
|
const operations = await getMigrationPlan(migration, "down");
|
|
1451
1628
|
const schema = applyOperationsToPrismaSchema(source, operations);
|
|
1452
|
-
if (options.write ?? true) writeFileSync(schemaPath, schema);
|
|
1629
|
+
if (options.write ?? true) writeFileSync$1(schemaPath, schema);
|
|
1453
1630
|
return {
|
|
1454
1631
|
schema,
|
|
1455
1632
|
schemaPath,
|
|
@@ -1457,149 +1634,6 @@ const applyMigrationRollbackToPrismaSchema = async (migration, options = {}) =>
|
|
|
1457
1634
|
};
|
|
1458
1635
|
};
|
|
1459
1636
|
|
|
1460
|
-
//#endregion
|
|
1461
|
-
//#region src/helpers/runtime-module-loader.ts
|
|
1462
|
-
var RuntimeModuleLoader = class {
|
|
1463
|
-
static async load(filePath) {
|
|
1464
|
-
const resolvedPath = resolve(filePath);
|
|
1465
|
-
return await createJiti(pathToFileURL(resolvedPath).href, {
|
|
1466
|
-
fsCache: false,
|
|
1467
|
-
interopDefault: false,
|
|
1468
|
-
moduleCache: false,
|
|
1469
|
-
tsconfigPaths: true
|
|
1470
|
-
}).import(resolvedPath);
|
|
1471
|
-
}
|
|
1472
|
-
static loadSync(filePath) {
|
|
1473
|
-
const resolvedPath = resolve(filePath);
|
|
1474
|
-
return createJiti(pathToFileURL(resolvedPath).href, {
|
|
1475
|
-
fsCache: false,
|
|
1476
|
-
interopDefault: false,
|
|
1477
|
-
moduleCache: false,
|
|
1478
|
-
tsconfigPaths: true
|
|
1479
|
-
})(resolvedPath);
|
|
1480
|
-
}
|
|
1481
|
-
};
|
|
1482
|
-
|
|
1483
|
-
//#endregion
|
|
1484
|
-
//#region src/helpers/migration-history.ts
|
|
1485
|
-
const createEmptyAppliedMigrationsState = () => ({
|
|
1486
|
-
version: 1,
|
|
1487
|
-
migrations: [],
|
|
1488
|
-
runs: []
|
|
1489
|
-
});
|
|
1490
|
-
const supportsDatabaseMigrationState = (adapter) => {
|
|
1491
|
-
return typeof adapter?.readAppliedMigrationsState === "function" && typeof adapter?.writeAppliedMigrationsState === "function";
|
|
1492
|
-
};
|
|
1493
|
-
const resolveMigrationStateFilePath = (cwd, configuredPath) => {
|
|
1494
|
-
if (configuredPath && configuredPath.trim().length > 0) return resolve(configuredPath);
|
|
1495
|
-
return join(cwd, ".arkormx", "migrations.applied.json");
|
|
1496
|
-
};
|
|
1497
|
-
const buildMigrationIdentity = (filePath, className) => {
|
|
1498
|
-
const fileName = filePath.split("/").pop()?.split("\\").pop() ?? filePath;
|
|
1499
|
-
return `${fileName.slice(0, fileName.length - extname(fileName).length)}:${className}`;
|
|
1500
|
-
};
|
|
1501
|
-
const computeMigrationChecksum = (filePath) => {
|
|
1502
|
-
const source = readFileSync(filePath, "utf-8");
|
|
1503
|
-
return createHash("sha256").update(source).digest("hex");
|
|
1504
|
-
};
|
|
1505
|
-
const readAppliedMigrationsState = (stateFilePath) => {
|
|
1506
|
-
if (!existsSync(stateFilePath)) return createEmptyAppliedMigrationsState();
|
|
1507
|
-
try {
|
|
1508
|
-
const parsed = JSON.parse(readFileSync(stateFilePath, "utf-8"));
|
|
1509
|
-
if (!Array.isArray(parsed.migrations)) return createEmptyAppliedMigrationsState();
|
|
1510
|
-
return {
|
|
1511
|
-
version: 1,
|
|
1512
|
-
migrations: parsed.migrations.filter((migration) => {
|
|
1513
|
-
return typeof migration?.id === "string" && typeof migration?.file === "string" && typeof migration?.className === "string" && typeof migration?.appliedAt === "string" && (migration?.checksum === void 0 || typeof migration?.checksum === "string");
|
|
1514
|
-
}),
|
|
1515
|
-
runs: Array.isArray(parsed.runs) ? parsed.runs.filter((run) => {
|
|
1516
|
-
return typeof run?.id === "string" && typeof run?.appliedAt === "string" && Array.isArray(run?.migrationIds) && run.migrationIds.every((item) => typeof item === "string");
|
|
1517
|
-
}) : []
|
|
1518
|
-
};
|
|
1519
|
-
} catch {
|
|
1520
|
-
return createEmptyAppliedMigrationsState();
|
|
1521
|
-
}
|
|
1522
|
-
};
|
|
1523
|
-
const readAppliedMigrationsStateFromStore = async (adapter, stateFilePath) => {
|
|
1524
|
-
if (supportsDatabaseMigrationState(adapter)) return await adapter.readAppliedMigrationsState();
|
|
1525
|
-
return readAppliedMigrationsState(stateFilePath);
|
|
1526
|
-
};
|
|
1527
|
-
const writeAppliedMigrationsState = (stateFilePath, state) => {
|
|
1528
|
-
const directory = dirname(stateFilePath);
|
|
1529
|
-
if (!existsSync(directory)) mkdirSync(directory, { recursive: true });
|
|
1530
|
-
writeFileSync(stateFilePath, JSON.stringify(state, null, 2));
|
|
1531
|
-
};
|
|
1532
|
-
const writeAppliedMigrationsStateToStore = async (adapter, stateFilePath, state) => {
|
|
1533
|
-
if (supportsDatabaseMigrationState(adapter)) {
|
|
1534
|
-
await adapter.writeAppliedMigrationsState(state);
|
|
1535
|
-
return;
|
|
1536
|
-
}
|
|
1537
|
-
writeAppliedMigrationsState(stateFilePath, state);
|
|
1538
|
-
};
|
|
1539
|
-
const isMigrationApplied = (state, identity, checksum) => {
|
|
1540
|
-
const matched = state.migrations.find((migration) => migration.id === identity);
|
|
1541
|
-
if (!matched) return false;
|
|
1542
|
-
if (checksum && matched.checksum) return matched.checksum === checksum;
|
|
1543
|
-
if (checksum && !matched.checksum) return false;
|
|
1544
|
-
return true;
|
|
1545
|
-
};
|
|
1546
|
-
const findAppliedMigration = (state, identity) => {
|
|
1547
|
-
return state.migrations.find((migration) => migration.id === identity);
|
|
1548
|
-
};
|
|
1549
|
-
const markMigrationApplied = (state, entry) => {
|
|
1550
|
-
const next = state.migrations.filter((migration) => migration.id !== entry.id);
|
|
1551
|
-
next.push(entry);
|
|
1552
|
-
return {
|
|
1553
|
-
version: 1,
|
|
1554
|
-
migrations: next,
|
|
1555
|
-
runs: state.runs ?? []
|
|
1556
|
-
};
|
|
1557
|
-
};
|
|
1558
|
-
const removeAppliedMigration = (state, identity) => {
|
|
1559
|
-
return {
|
|
1560
|
-
version: 1,
|
|
1561
|
-
migrations: state.migrations.filter((migration) => migration.id !== identity),
|
|
1562
|
-
runs: (state.runs ?? []).map((run) => ({
|
|
1563
|
-
...run,
|
|
1564
|
-
migrationIds: run.migrationIds.filter((id) => id !== identity)
|
|
1565
|
-
})).filter((run) => run.migrationIds.length > 0)
|
|
1566
|
-
};
|
|
1567
|
-
};
|
|
1568
|
-
const buildMigrationRunId = () => {
|
|
1569
|
-
return `run_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
|
1570
|
-
};
|
|
1571
|
-
const markMigrationRun = (state, run) => {
|
|
1572
|
-
const nextRuns = (state.runs ?? []).filter((existing) => existing.id !== run.id);
|
|
1573
|
-
nextRuns.push(run);
|
|
1574
|
-
return {
|
|
1575
|
-
version: 1,
|
|
1576
|
-
migrations: state.migrations,
|
|
1577
|
-
runs: nextRuns
|
|
1578
|
-
};
|
|
1579
|
-
};
|
|
1580
|
-
const getLastMigrationRun = (state) => {
|
|
1581
|
-
const runs = state.runs ?? [];
|
|
1582
|
-
if (runs.length === 0) return void 0;
|
|
1583
|
-
return runs.map((run, index) => ({
|
|
1584
|
-
run,
|
|
1585
|
-
index
|
|
1586
|
-
})).sort((left, right) => {
|
|
1587
|
-
const appliedAtOrder = right.run.appliedAt.localeCompare(left.run.appliedAt);
|
|
1588
|
-
if (appliedAtOrder !== 0) return appliedAtOrder;
|
|
1589
|
-
return right.index - left.index;
|
|
1590
|
-
})[0]?.run;
|
|
1591
|
-
};
|
|
1592
|
-
const getLatestAppliedMigrations = (state, steps) => {
|
|
1593
|
-
return state.migrations.map((migration, index) => ({
|
|
1594
|
-
migration,
|
|
1595
|
-
index
|
|
1596
|
-
})).sort((left, right) => {
|
|
1597
|
-
const appliedAtOrder = right.migration.appliedAt.localeCompare(left.migration.appliedAt);
|
|
1598
|
-
if (appliedAtOrder !== 0) return appliedAtOrder;
|
|
1599
|
-
return right.index - left.index;
|
|
1600
|
-
}).slice(0, Math.max(0, steps)).map((entry) => entry.migration);
|
|
1601
|
-
};
|
|
1602
|
-
|
|
1603
1637
|
//#endregion
|
|
1604
1638
|
//#region src/helpers/column-mappings.ts
|
|
1605
1639
|
let cachedColumnMappingsPath;
|
|
@@ -1715,14 +1749,14 @@ const resetPersistedColumnMappingsCache = () => {
|
|
|
1715
1749
|
};
|
|
1716
1750
|
const readPersistedColumnMappingsState = (filePath) => {
|
|
1717
1751
|
if (cachedColumnMappingsPath === filePath && cachedColumnMappingsState) return cachedColumnMappingsState;
|
|
1718
|
-
if (!existsSync(filePath)) {
|
|
1752
|
+
if (!existsSync$1(filePath)) {
|
|
1719
1753
|
const empty = createEmptyPersistedColumnMappingsState();
|
|
1720
1754
|
cachedColumnMappingsPath = filePath;
|
|
1721
1755
|
cachedColumnMappingsState = empty;
|
|
1722
1756
|
return empty;
|
|
1723
1757
|
}
|
|
1724
1758
|
try {
|
|
1725
|
-
const normalized = normalizePersistedColumnMappingsState(JSON.parse(readFileSync(filePath, "utf-8")));
|
|
1759
|
+
const normalized = normalizePersistedColumnMappingsState(JSON.parse(readFileSync$1(filePath, "utf-8")));
|
|
1726
1760
|
cachedColumnMappingsPath = filePath;
|
|
1727
1761
|
cachedColumnMappingsState = normalized;
|
|
1728
1762
|
return normalized;
|
|
@@ -1736,13 +1770,13 @@ const readPersistedColumnMappingsState = (filePath) => {
|
|
|
1736
1770
|
const writePersistedColumnMappingsState = (filePath, state) => {
|
|
1737
1771
|
const normalized = normalizePersistedColumnMappingsState(state);
|
|
1738
1772
|
const directory = dirname(filePath);
|
|
1739
|
-
if (!existsSync(directory)) mkdirSync(directory, { recursive: true });
|
|
1740
|
-
writeFileSync(filePath, JSON.stringify(normalized, null, 2));
|
|
1773
|
+
if (!existsSync$1(directory)) mkdirSync$1(directory, { recursive: true });
|
|
1774
|
+
writeFileSync$1(filePath, JSON.stringify(normalized, null, 2));
|
|
1741
1775
|
cachedColumnMappingsPath = filePath;
|
|
1742
1776
|
cachedColumnMappingsState = normalized;
|
|
1743
1777
|
};
|
|
1744
1778
|
const deletePersistedColumnMappingsState = (filePath) => {
|
|
1745
|
-
if (existsSync(filePath)) rmSync(filePath, { force: true });
|
|
1779
|
+
if (existsSync$1(filePath)) rmSync$1(filePath, { force: true });
|
|
1746
1780
|
resetPersistedColumnMappingsCache();
|
|
1747
1781
|
};
|
|
1748
1782
|
const getPersistedTableMetadata = (table, options = {}) => {
|
|
@@ -1922,7 +1956,7 @@ const resolveDefaultStubsPath = () => {
|
|
|
1922
1956
|
while (true) {
|
|
1923
1957
|
const packageJsonPath = path.join(current, "package.json");
|
|
1924
1958
|
const stubsPath = path.join(current, "stubs");
|
|
1925
|
-
if (existsSync
|
|
1959
|
+
if (existsSync(packageJsonPath) && existsSync(stubsPath)) return stubsPath;
|
|
1926
1960
|
const parent = path.dirname(current);
|
|
1927
1961
|
if (parent === current) break;
|
|
1928
1962
|
current = parent;
|
|
@@ -1949,19 +1983,702 @@ const userConfig = {
|
|
|
1949
1983
|
features: { ...baseConfig.features ?? {} },
|
|
1950
1984
|
paths: { ...baseConfig.paths ?? {} }
|
|
1951
1985
|
};
|
|
1986
|
+
let runtimeConfigLoaded = false;
|
|
1987
|
+
let runtimeConfigLoadingPromise;
|
|
1988
|
+
let runtimeClientResolver;
|
|
1989
|
+
let runtimeAdapter;
|
|
1990
|
+
let runtimePaginationURLDriverFactory;
|
|
1991
|
+
let runtimePaginationCurrentPageResolver;
|
|
1992
|
+
let runtimeDebugHandler;
|
|
1952
1993
|
const transactionClientStorage = new AsyncLocalStorage();
|
|
1994
|
+
const transactionAdapterStorage = new AsyncLocalStorage();
|
|
1995
|
+
const defaultDebugHandler = (event) => {
|
|
1996
|
+
const prefix = `[arkorm:${event.adapter}] ${event.operation}${event.target ? ` [${event.target}]` : ""}`;
|
|
1997
|
+
const payload = {
|
|
1998
|
+
phase: event.phase,
|
|
1999
|
+
durationMs: event.durationMs,
|
|
2000
|
+
inspection: event.inspection ?? void 0,
|
|
2001
|
+
meta: event.meta,
|
|
2002
|
+
error: event.error
|
|
2003
|
+
};
|
|
2004
|
+
if (event.phase === "error") {
|
|
2005
|
+
console.error(prefix, payload);
|
|
2006
|
+
return;
|
|
2007
|
+
}
|
|
2008
|
+
console.debug(prefix, payload);
|
|
2009
|
+
};
|
|
2010
|
+
const resolveDebugHandler = (debug) => {
|
|
2011
|
+
if (debug === true) return defaultDebugHandler;
|
|
2012
|
+
return typeof debug === "function" ? debug : void 0;
|
|
2013
|
+
};
|
|
2014
|
+
const mergePathConfig = (paths) => {
|
|
2015
|
+
const defaults = baseConfig.paths ?? {};
|
|
2016
|
+
const current = userConfig.paths ?? {};
|
|
2017
|
+
const incoming = Object.entries(paths ?? {}).reduce((all, [key, value]) => {
|
|
2018
|
+
if (typeof value === "string" && value.trim().length > 0) all[key] = path.isAbsolute(value) ? value : path.resolve(process.cwd(), value);
|
|
2019
|
+
return all;
|
|
2020
|
+
}, {});
|
|
2021
|
+
return {
|
|
2022
|
+
...defaults,
|
|
2023
|
+
...current,
|
|
2024
|
+
...incoming
|
|
2025
|
+
};
|
|
2026
|
+
};
|
|
2027
|
+
/**
|
|
2028
|
+
* Merge the feature configuration from the base defaults, user configuration, and provided options.
|
|
2029
|
+
*
|
|
2030
|
+
* @param features
|
|
2031
|
+
* @returns
|
|
2032
|
+
*/
|
|
2033
|
+
const mergeFeatureConfig = (features) => {
|
|
2034
|
+
const defaults = baseConfig.features ?? {};
|
|
2035
|
+
const current = userConfig.features ?? {};
|
|
2036
|
+
return {
|
|
2037
|
+
...defaults,
|
|
2038
|
+
...current,
|
|
2039
|
+
...features ?? {}
|
|
2040
|
+
};
|
|
2041
|
+
};
|
|
2042
|
+
/**
|
|
2043
|
+
* Bind a database adapter instance to an array of models that support adapter binding.
|
|
2044
|
+
*
|
|
2045
|
+
* @param adapter
|
|
2046
|
+
* @param models
|
|
2047
|
+
* @returns
|
|
2048
|
+
*/
|
|
2049
|
+
const bindAdapterToModels = (adapter, models) => {
|
|
2050
|
+
models.forEach((model) => {
|
|
2051
|
+
model.setAdapter(adapter);
|
|
2052
|
+
});
|
|
2053
|
+
return adapter;
|
|
2054
|
+
};
|
|
1953
2055
|
/**
|
|
1954
2056
|
* Get the user-provided ArkORM configuration.
|
|
1955
2057
|
*
|
|
2058
|
+
* @param key Optional specific configuration key to retrieve. If omitted, the entire configuration object is returned.
|
|
1956
2059
|
* @returns The user-provided ArkORM configuration object.
|
|
1957
2060
|
*/
|
|
1958
2061
|
const getUserConfig = (key) => {
|
|
1959
2062
|
if (key) return userConfig[key];
|
|
1960
2063
|
return userConfig;
|
|
1961
2064
|
};
|
|
2065
|
+
/**
|
|
2066
|
+
* Configure the ArkORM runtime with the provided runtime client resolver and
|
|
2067
|
+
* adapter-first options.
|
|
2068
|
+
*
|
|
2069
|
+
* @param client
|
|
2070
|
+
* @param options
|
|
2071
|
+
*/
|
|
2072
|
+
const configureArkormRuntime = (client, options = {}) => {
|
|
2073
|
+
const resolvedClient = client ?? options.client;
|
|
2074
|
+
const nextConfig = {
|
|
2075
|
+
...userConfig,
|
|
2076
|
+
features: mergeFeatureConfig(options.features),
|
|
2077
|
+
paths: mergePathConfig(options.paths)
|
|
2078
|
+
};
|
|
2079
|
+
nextConfig.client = resolvedClient;
|
|
2080
|
+
nextConfig.prisma = resolvedClient;
|
|
2081
|
+
if (options.pagination !== void 0) nextConfig.pagination = options.pagination;
|
|
2082
|
+
if (options.adapter !== void 0) nextConfig.adapter = options.adapter;
|
|
2083
|
+
if (options.boot !== void 0) nextConfig.boot = options.boot;
|
|
2084
|
+
if (options.debug !== void 0) nextConfig.debug = options.debug;
|
|
2085
|
+
if (options.outputExt !== void 0) nextConfig.outputExt = options.outputExt;
|
|
2086
|
+
Object.assign(userConfig, { ...nextConfig });
|
|
2087
|
+
runtimeClientResolver = resolvedClient;
|
|
2088
|
+
runtimeAdapter = options.adapter;
|
|
2089
|
+
runtimePaginationURLDriverFactory = nextConfig.pagination?.urlDriver;
|
|
2090
|
+
runtimePaginationCurrentPageResolver = nextConfig.pagination?.resolveCurrentPage;
|
|
2091
|
+
runtimeDebugHandler = resolveDebugHandler(nextConfig.debug);
|
|
2092
|
+
const bootClient = resolveClient(resolvedClient);
|
|
2093
|
+
options.boot?.({
|
|
2094
|
+
client: bootClient,
|
|
2095
|
+
prisma: bootClient,
|
|
2096
|
+
bindAdapter: bindAdapterToModels
|
|
2097
|
+
});
|
|
2098
|
+
};
|
|
2099
|
+
/**
|
|
2100
|
+
* Resolve a runtime client instance from the provided resolver, which can be either
|
|
2101
|
+
* a direct client instance or a function that returns a client instance.
|
|
2102
|
+
*
|
|
2103
|
+
* @param resolver
|
|
2104
|
+
* @returns
|
|
2105
|
+
*/
|
|
2106
|
+
const resolveClient = (resolver) => {
|
|
2107
|
+
if (!resolver) return void 0;
|
|
2108
|
+
const client = typeof resolver === "function" ? resolver() : resolver;
|
|
2109
|
+
if (!client || typeof client !== "object") return void 0;
|
|
2110
|
+
return client;
|
|
2111
|
+
};
|
|
2112
|
+
/**
|
|
2113
|
+
* Resolve and apply the ArkORM configuration from an imported module.
|
|
2114
|
+
* This function checks for a default export and falls back to the module itself, then validates
|
|
2115
|
+
* the configuration object and applies it to the runtime if valid.
|
|
2116
|
+
*
|
|
2117
|
+
* @param imported
|
|
2118
|
+
* @returns
|
|
2119
|
+
*/
|
|
2120
|
+
const resolveAndApplyConfig = (imported) => {
|
|
2121
|
+
const config = imported?.default ?? imported;
|
|
2122
|
+
if (!config || typeof config !== "object") return;
|
|
2123
|
+
const runtimeClient = config.client ?? config.prisma;
|
|
2124
|
+
configureArkormRuntime(runtimeClient, {
|
|
2125
|
+
client: runtimeClient,
|
|
2126
|
+
adapter: config.adapter,
|
|
2127
|
+
boot: config.boot,
|
|
2128
|
+
debug: config.debug,
|
|
2129
|
+
features: config.features,
|
|
2130
|
+
pagination: config.pagination,
|
|
2131
|
+
paths: config.paths,
|
|
2132
|
+
outputExt: config.outputExt
|
|
2133
|
+
});
|
|
2134
|
+
runtimeConfigLoaded = true;
|
|
2135
|
+
};
|
|
2136
|
+
/**
|
|
2137
|
+
* Dynamically import a configuration file.
|
|
2138
|
+
* A cache-busting query parameter is appended to ensure the latest version is loaded.
|
|
2139
|
+
*
|
|
2140
|
+
* @param configPath
|
|
2141
|
+
* @returns A promise that resolves to the imported configuration module.
|
|
2142
|
+
*/
|
|
2143
|
+
const importConfigFile = (configPath) => {
|
|
2144
|
+
return RuntimeModuleLoader.load(configPath);
|
|
2145
|
+
};
|
|
2146
|
+
const loadRuntimeConfigSync = () => {
|
|
2147
|
+
const require = createRequire(import.meta.url);
|
|
2148
|
+
const syncConfigPaths = [path.join(process.cwd(), "arkormx.config.cjs")];
|
|
2149
|
+
for (const configPath of syncConfigPaths) {
|
|
2150
|
+
if (!existsSync(configPath)) continue;
|
|
2151
|
+
try {
|
|
2152
|
+
resolveAndApplyConfig(require(configPath));
|
|
2153
|
+
return true;
|
|
2154
|
+
} catch {
|
|
2155
|
+
continue;
|
|
2156
|
+
}
|
|
2157
|
+
}
|
|
2158
|
+
return false;
|
|
2159
|
+
};
|
|
2160
|
+
/**
|
|
2161
|
+
* Load the ArkORM configuration by searching for configuration files in the
|
|
2162
|
+
* current working directory.
|
|
2163
|
+
* @returns
|
|
2164
|
+
*/
|
|
2165
|
+
const loadArkormConfig = async () => {
|
|
2166
|
+
if (runtimeConfigLoaded) return;
|
|
2167
|
+
if (runtimeConfigLoadingPromise) return await runtimeConfigLoadingPromise;
|
|
2168
|
+
if (loadRuntimeConfigSync()) return;
|
|
2169
|
+
runtimeConfigLoadingPromise = (async () => {
|
|
2170
|
+
const configPaths = [path.join(process.cwd(), "arkormx.config.js"), path.join(process.cwd(), "arkormx.config.ts")];
|
|
2171
|
+
for (const configPath of configPaths) {
|
|
2172
|
+
if (!existsSync(configPath)) continue;
|
|
2173
|
+
try {
|
|
2174
|
+
resolveAndApplyConfig(await importConfigFile(configPath));
|
|
2175
|
+
return;
|
|
2176
|
+
} catch {
|
|
2177
|
+
continue;
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
runtimeConfigLoaded = true;
|
|
2181
|
+
})();
|
|
2182
|
+
await runtimeConfigLoadingPromise;
|
|
2183
|
+
};
|
|
1962
2184
|
const getDefaultStubsPath = () => {
|
|
1963
2185
|
return resolveDefaultStubsPath();
|
|
1964
2186
|
};
|
|
2187
|
+
const getRuntimeDebugHandler = () => {
|
|
2188
|
+
if (!runtimeConfigLoaded) loadRuntimeConfigSync();
|
|
2189
|
+
return runtimeDebugHandler;
|
|
2190
|
+
};
|
|
2191
|
+
const emitRuntimeDebugEvent = (event) => {
|
|
2192
|
+
getRuntimeDebugHandler()?.(event);
|
|
2193
|
+
};
|
|
2194
|
+
/**
|
|
2195
|
+
* Check if a given value matches Arkorm's query-schema contract
|
|
2196
|
+
* by verifying the presence of common delegate methods.
|
|
2197
|
+
*
|
|
2198
|
+
* @param value The value to check.
|
|
2199
|
+
* @returns True if the value matches the query-schema contract, false otherwise.
|
|
2200
|
+
*/
|
|
2201
|
+
const isQuerySchemaLike = (value) => {
|
|
2202
|
+
if (!value || typeof value !== "object") return false;
|
|
2203
|
+
const candidate = value;
|
|
2204
|
+
return [
|
|
2205
|
+
"findMany",
|
|
2206
|
+
"findFirst",
|
|
2207
|
+
"create",
|
|
2208
|
+
"update",
|
|
2209
|
+
"delete",
|
|
2210
|
+
"count"
|
|
2211
|
+
].every((method) => typeof candidate[method] === "function");
|
|
2212
|
+
};
|
|
2213
|
+
/**
|
|
2214
|
+
* @deprecated Use isQuerySchemaLike instead.
|
|
2215
|
+
*/
|
|
2216
|
+
const isDelegateLike = isQuerySchemaLike;
|
|
2217
|
+
loadArkormConfig();
|
|
2218
|
+
|
|
2219
|
+
//#endregion
|
|
2220
|
+
//#region src/helpers/prisma.ts
|
|
2221
|
+
/**
|
|
2222
|
+
* Infer the Prisma delegate name for a given model name using a simple convention.
|
|
2223
|
+
*
|
|
2224
|
+
* @param modelName The name of the model to infer the delegate name for.
|
|
2225
|
+
* @returns The inferred Prisma delegate name.
|
|
2226
|
+
*/
|
|
2227
|
+
function inferDelegateName(modelName) {
|
|
2228
|
+
return `${modelName.charAt(0).toLowerCase()}${modelName.slice(1)}s`;
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
//#endregion
|
|
2232
|
+
//#region src/adapters/PrismaDatabaseAdapter.ts
|
|
2233
|
+
/**
|
|
2234
|
+
* Database adapter implementation for Prisma, allowing Arkorm to execute queries using Prisma
|
|
2235
|
+
* as the underlying query builder and executor.
|
|
2236
|
+
*
|
|
2237
|
+
* @author Legacy (3m1n3nc3)
|
|
2238
|
+
* @since 2.0.0-next.0
|
|
2239
|
+
*/
|
|
2240
|
+
var PrismaDatabaseAdapter = class PrismaDatabaseAdapter {
|
|
2241
|
+
capabilities;
|
|
2242
|
+
delegates;
|
|
2243
|
+
constructor(prisma, mapping = {}) {
|
|
2244
|
+
this.prisma = prisma;
|
|
2245
|
+
this.mapping = mapping;
|
|
2246
|
+
this.delegates = Object.entries(prisma).reduce((accumulator, [key, value]) => {
|
|
2247
|
+
if (!isDelegateLike(value)) return accumulator;
|
|
2248
|
+
accumulator[key] = value;
|
|
2249
|
+
return accumulator;
|
|
2250
|
+
}, {});
|
|
2251
|
+
this.capabilities = {
|
|
2252
|
+
transactions: this.hasTransactionSupport(prisma),
|
|
2253
|
+
insertMany: Object.values(this.delegates).some((delegate) => typeof delegate.createMany === "function"),
|
|
2254
|
+
upsert: false,
|
|
2255
|
+
updateMany: Object.values(this.delegates).some((delegate) => typeof delegate.updateMany === "function"),
|
|
2256
|
+
deleteMany: false,
|
|
2257
|
+
exists: true,
|
|
2258
|
+
relationLoads: false,
|
|
2259
|
+
relationAggregates: false,
|
|
2260
|
+
relationFilters: false,
|
|
2261
|
+
rawWhere: false,
|
|
2262
|
+
returning: false
|
|
2263
|
+
};
|
|
2264
|
+
}
|
|
2265
|
+
hasTransactionSupport(client) {
|
|
2266
|
+
return Boolean(client) && typeof client.$transaction === "function";
|
|
2267
|
+
}
|
|
2268
|
+
normalizeCandidate(value) {
|
|
2269
|
+
return value.trim();
|
|
2270
|
+
}
|
|
2271
|
+
unique(values) {
|
|
2272
|
+
return [...new Set(values.filter(Boolean))];
|
|
2273
|
+
}
|
|
2274
|
+
runtimeModelTypeToTs(typeName, kind, enumValues) {
|
|
2275
|
+
if (kind === "enum" && enumValues && enumValues.length > 0) return enumValues.map((value) => `'${value.replace(/'/g, "\\'")}'`).join(" | ");
|
|
2276
|
+
switch (typeName) {
|
|
2277
|
+
case "Int":
|
|
2278
|
+
case "Float":
|
|
2279
|
+
case "Decimal":
|
|
2280
|
+
case "BigInt": return "number";
|
|
2281
|
+
case "Boolean": return "boolean";
|
|
2282
|
+
case "DateTime": return "Date";
|
|
2283
|
+
case "Json": return "Record<string, unknown> | unknown[]";
|
|
2284
|
+
case "Bytes": return "Uint8Array";
|
|
2285
|
+
case "String":
|
|
2286
|
+
case "UUID": return "string";
|
|
2287
|
+
default: return "string";
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2290
|
+
getRuntimeDataModel() {
|
|
2291
|
+
const runtimeDataModel = this.prisma._runtimeDataModel;
|
|
2292
|
+
if (runtimeDataModel && typeof runtimeDataModel === "object") return runtimeDataModel;
|
|
2293
|
+
return null;
|
|
2294
|
+
}
|
|
2295
|
+
toQuerySelect(columns) {
|
|
2296
|
+
if (!columns || columns.length === 0) return void 0;
|
|
2297
|
+
return columns.reduce((select, column) => {
|
|
2298
|
+
select[column.column] = true;
|
|
2299
|
+
return select;
|
|
2300
|
+
}, {});
|
|
2301
|
+
}
|
|
2302
|
+
toQueryOrderBy(orderBy) {
|
|
2303
|
+
if (!orderBy || orderBy.length === 0) return void 0;
|
|
2304
|
+
return orderBy.map((entry) => ({ [entry.column]: entry.direction }));
|
|
2305
|
+
}
|
|
2306
|
+
toComparisonWhere(condition) {
|
|
2307
|
+
if (condition.operator === "is-null") return { [condition.column]: null };
|
|
2308
|
+
if (condition.operator === "is-not-null") return { [condition.column]: { not: null } };
|
|
2309
|
+
if (condition.operator === "=") return { [condition.column]: condition.value };
|
|
2310
|
+
if (condition.operator === "!=") return { [condition.column]: { not: condition.value } };
|
|
2311
|
+
if (condition.operator === ">") return { [condition.column]: { gt: condition.value } };
|
|
2312
|
+
if (condition.operator === ">=") return { [condition.column]: { gte: condition.value } };
|
|
2313
|
+
if (condition.operator === "<") return { [condition.column]: { lt: condition.value } };
|
|
2314
|
+
if (condition.operator === "<=") return { [condition.column]: { lte: condition.value } };
|
|
2315
|
+
if (condition.operator === "in") return { [condition.column]: { in: Array.isArray(condition.value) ? condition.value : [condition.value] } };
|
|
2316
|
+
if (condition.operator === "not-in") return { [condition.column]: { notIn: Array.isArray(condition.value) ? condition.value : [condition.value] } };
|
|
2317
|
+
if (condition.operator === "contains") return { [condition.column]: { contains: condition.value } };
|
|
2318
|
+
if (condition.operator === "starts-with") return { [condition.column]: { startsWith: condition.value } };
|
|
2319
|
+
return { [condition.column]: { endsWith: condition.value } };
|
|
2320
|
+
}
|
|
2321
|
+
toQueryWhere(condition) {
|
|
2322
|
+
if (!condition) return void 0;
|
|
2323
|
+
if (condition.type === "comparison") return this.toComparisonWhere(condition);
|
|
2324
|
+
if (condition.type === "group") {
|
|
2325
|
+
const group = condition;
|
|
2326
|
+
const grouped = group.conditions.map((entry) => this.toQueryWhere(entry)).filter((entry) => Boolean(entry));
|
|
2327
|
+
if (grouped.length === 0) return void 0;
|
|
2328
|
+
return group.operator === "and" ? { AND: grouped } : { OR: grouped };
|
|
2329
|
+
}
|
|
2330
|
+
if (condition.type === "not") {
|
|
2331
|
+
const notCondition = condition;
|
|
2332
|
+
const nested = this.toQueryWhere(notCondition.condition);
|
|
2333
|
+
if (!nested) return void 0;
|
|
2334
|
+
return { NOT: nested };
|
|
2335
|
+
}
|
|
2336
|
+
throw new UnsupportedAdapterFeatureException("Raw where clauses are not supported by the Prisma compatibility adapter; use a SQL-backed adapter for raw SQL predicates.", {
|
|
2337
|
+
operation: "adapter.where",
|
|
2338
|
+
meta: {
|
|
2339
|
+
feature: "rawWhere",
|
|
2340
|
+
sql: condition.sql
|
|
2341
|
+
}
|
|
2342
|
+
});
|
|
2343
|
+
}
|
|
2344
|
+
buildFindArgs(spec) {
|
|
2345
|
+
return {
|
|
2346
|
+
include: this.toQueryInclude(spec.relationLoads),
|
|
2347
|
+
where: this.toQueryWhere(spec.where),
|
|
2348
|
+
orderBy: this.toQueryOrderBy(spec.orderBy),
|
|
2349
|
+
select: this.toQuerySelect(spec.columns),
|
|
2350
|
+
skip: spec.offset,
|
|
2351
|
+
take: spec.limit
|
|
2352
|
+
};
|
|
2353
|
+
}
|
|
2354
|
+
emitDebugQuery(phase, operation, target, meta, durationMs, error, inspection = null) {
|
|
2355
|
+
emitRuntimeDebugEvent({
|
|
2356
|
+
type: "query",
|
|
2357
|
+
phase,
|
|
2358
|
+
adapter: "prisma",
|
|
2359
|
+
operation,
|
|
2360
|
+
target: target.table,
|
|
2361
|
+
inspection,
|
|
2362
|
+
meta,
|
|
2363
|
+
durationMs,
|
|
2364
|
+
error
|
|
2365
|
+
});
|
|
2366
|
+
}
|
|
2367
|
+
wrapExecutionError(error, operation, target, meta) {
|
|
2368
|
+
if (error instanceof ArkormException) return error;
|
|
2369
|
+
return new QueryExecutionException(`Failed to execute ${operation} query.`, {
|
|
2370
|
+
operation: `adapter.${operation}`,
|
|
2371
|
+
model: target.modelName,
|
|
2372
|
+
delegate: target.table,
|
|
2373
|
+
meta,
|
|
2374
|
+
cause: error
|
|
2375
|
+
});
|
|
2376
|
+
}
|
|
2377
|
+
async runWithDebug(operation, target, executor, meta) {
|
|
2378
|
+
const startedAt = Date.now();
|
|
2379
|
+
this.emitDebugQuery("before", operation, target, meta);
|
|
2380
|
+
try {
|
|
2381
|
+
const result = await executor();
|
|
2382
|
+
this.emitDebugQuery("after", operation, target, meta, Date.now() - startedAt);
|
|
2383
|
+
return result;
|
|
2384
|
+
} catch (error) {
|
|
2385
|
+
const wrapped = this.wrapExecutionError(error, operation, target, meta);
|
|
2386
|
+
this.emitDebugQuery("error", operation, target, meta, Date.now() - startedAt, wrapped);
|
|
2387
|
+
throw wrapped;
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
inspectQuery(_request) {
|
|
2391
|
+
return null;
|
|
2392
|
+
}
|
|
2393
|
+
toQueryInclude(relationLoads) {
|
|
2394
|
+
if (!relationLoads || relationLoads.length === 0) return void 0;
|
|
2395
|
+
return relationLoads.reduce((include, plan) => {
|
|
2396
|
+
const nestedInclude = this.toQueryInclude(plan.relationLoads);
|
|
2397
|
+
const nestedSelect = this.toQuerySelect(plan.columns);
|
|
2398
|
+
const nestedWhere = this.toQueryWhere(plan.constraint);
|
|
2399
|
+
const nestedOrderBy = this.toQueryOrderBy(plan.orderBy);
|
|
2400
|
+
if (!nestedInclude && !nestedSelect && !nestedWhere && !nestedOrderBy && plan.offset === void 0 && plan.limit === void 0) {
|
|
2401
|
+
include[plan.relation] = true;
|
|
2402
|
+
return include;
|
|
2403
|
+
}
|
|
2404
|
+
include[plan.relation] = {
|
|
2405
|
+
where: nestedWhere,
|
|
2406
|
+
orderBy: nestedOrderBy,
|
|
2407
|
+
select: nestedSelect,
|
|
2408
|
+
include: nestedInclude,
|
|
2409
|
+
skip: plan.offset,
|
|
2410
|
+
take: plan.limit
|
|
2411
|
+
};
|
|
2412
|
+
return include;
|
|
2413
|
+
}, {});
|
|
2414
|
+
}
|
|
2415
|
+
async introspectModels(options = {}) {
|
|
2416
|
+
const runtimeDataModel = this.getRuntimeDataModel();
|
|
2417
|
+
if (!runtimeDataModel?.models) return [];
|
|
2418
|
+
const requestedTables = new Set(options.tables?.filter(Boolean) ?? []);
|
|
2419
|
+
const enums = runtimeDataModel.enums ?? {};
|
|
2420
|
+
return Object.entries(runtimeDataModel.models).flatMap(([name, model]) => {
|
|
2421
|
+
const table = model.dbName ?? `${str(name).camel().plural()}`;
|
|
2422
|
+
if (requestedTables.size > 0 && !requestedTables.has(table)) return [];
|
|
2423
|
+
return [{
|
|
2424
|
+
name,
|
|
2425
|
+
table,
|
|
2426
|
+
fields: (model.fields ?? []).filter((field) => field.kind !== "object").map((field) => {
|
|
2427
|
+
const enumValues = field.kind === "enum" ? (enums[field.type]?.values ?? []).map((value) => typeof value === "string" ? value : value.name ?? "").filter(Boolean) : null;
|
|
2428
|
+
const baseType = this.runtimeModelTypeToTs(field.type, field.kind, enumValues);
|
|
2429
|
+
return {
|
|
2430
|
+
name: field.name,
|
|
2431
|
+
type: field.isList ? `Array<${baseType}>` : baseType,
|
|
2432
|
+
nullable: field.isRequired === false
|
|
2433
|
+
};
|
|
2434
|
+
})
|
|
2435
|
+
}];
|
|
2436
|
+
});
|
|
2437
|
+
}
|
|
2438
|
+
resolveDelegate(target) {
|
|
2439
|
+
const tableName = target.table ? this.normalizeCandidate(target.table) : "";
|
|
2440
|
+
const singularTableName = tableName ? `${str(tableName).singular()}` : "";
|
|
2441
|
+
const camelTableName = tableName ? `${str(tableName).camel()}` : "";
|
|
2442
|
+
const camelSingularTableName = tableName ? `${str(tableName).camel().singular()}` : "";
|
|
2443
|
+
const candidates = this.unique([
|
|
2444
|
+
target.table ? this.mapping[target.table] : "",
|
|
2445
|
+
tableName,
|
|
2446
|
+
singularTableName ? this.mapping[singularTableName] : "",
|
|
2447
|
+
singularTableName,
|
|
2448
|
+
camelTableName ? this.mapping[camelTableName] : "",
|
|
2449
|
+
camelTableName,
|
|
2450
|
+
camelSingularTableName ? this.mapping[camelSingularTableName] : "",
|
|
2451
|
+
camelSingularTableName,
|
|
2452
|
+
target.modelName ? this.mapping[target.modelName] : "",
|
|
2453
|
+
target.modelName ? this.normalizeCandidate(target.modelName) : "",
|
|
2454
|
+
target.modelName ? inferDelegateName(target.modelName) : "",
|
|
2455
|
+
target.modelName ? this.mapping[inferDelegateName(target.modelName)] : ""
|
|
2456
|
+
]);
|
|
2457
|
+
const resolved = candidates.map((candidate) => this.delegates[candidate]).find(Boolean);
|
|
2458
|
+
if (resolved) return resolved;
|
|
2459
|
+
throw new MissingDelegateException("Prisma delegate could not be resolved for adapter target.", {
|
|
2460
|
+
operation: "getDelegate",
|
|
2461
|
+
model: target.modelName,
|
|
2462
|
+
delegate: target.table,
|
|
2463
|
+
meta: {
|
|
2464
|
+
target,
|
|
2465
|
+
candidates
|
|
2466
|
+
}
|
|
2467
|
+
});
|
|
2468
|
+
}
|
|
2469
|
+
/**
|
|
2470
|
+
* Prisma can translate relation load plans on direct select/selectOne calls into
|
|
2471
|
+
* Prisma include/select arguments, but the adapter does not advertise the
|
|
2472
|
+
* adapter-owned batch relation load seam. QueryBuilder eager loads therefore stay
|
|
2473
|
+
* on Arkorm's generic relation loader on the Prisma compatibility path.
|
|
2474
|
+
*
|
|
2475
|
+
* @param spec
|
|
2476
|
+
* @returns
|
|
2477
|
+
*/
|
|
2478
|
+
async select(spec) {
|
|
2479
|
+
const delegate = this.resolveDelegate(spec.target);
|
|
2480
|
+
const args = this.buildFindArgs(spec);
|
|
2481
|
+
return await this.runWithDebug("select", spec.target, async () => {
|
|
2482
|
+
return await delegate.findMany(args);
|
|
2483
|
+
}, { args });
|
|
2484
|
+
}
|
|
2485
|
+
/**
|
|
2486
|
+
* Selects a single record matching the specified criteria.
|
|
2487
|
+
*
|
|
2488
|
+
* @param spec
|
|
2489
|
+
* @returns
|
|
2490
|
+
*/
|
|
2491
|
+
async selectOne(spec) {
|
|
2492
|
+
const delegate = this.resolveDelegate(spec.target);
|
|
2493
|
+
const args = this.buildFindArgs(spec);
|
|
2494
|
+
return await this.runWithDebug("selectOne", spec.target, async () => {
|
|
2495
|
+
return await delegate.findFirst(args);
|
|
2496
|
+
}, { args });
|
|
2497
|
+
}
|
|
2498
|
+
/**
|
|
2499
|
+
* Inserts a single record into the database and returns the created record.
|
|
2500
|
+
*
|
|
2501
|
+
* @param spec
|
|
2502
|
+
* @returns
|
|
2503
|
+
*/
|
|
2504
|
+
async insert(spec) {
|
|
2505
|
+
const delegate = this.resolveDelegate(spec.target);
|
|
2506
|
+
return await this.runWithDebug("insert", spec.target, async () => {
|
|
2507
|
+
return await delegate.create({ data: spec.values });
|
|
2508
|
+
}, { values: spec.values });
|
|
2509
|
+
}
|
|
2510
|
+
/**
|
|
2511
|
+
* Inserts multiple records into the database.
|
|
2512
|
+
*
|
|
2513
|
+
* @param spec
|
|
2514
|
+
* @returns
|
|
2515
|
+
*/
|
|
2516
|
+
async insertMany(spec) {
|
|
2517
|
+
const delegate = this.resolveDelegate(spec.target);
|
|
2518
|
+
const meta = {
|
|
2519
|
+
values: spec.values,
|
|
2520
|
+
ignoreDuplicates: spec.ignoreDuplicates
|
|
2521
|
+
};
|
|
2522
|
+
if (typeof delegate.createMany === "function") {
|
|
2523
|
+
const result = await this.runWithDebug("insertMany", spec.target, async () => {
|
|
2524
|
+
return await delegate.createMany?.({
|
|
2525
|
+
data: spec.values,
|
|
2526
|
+
skipDuplicates: spec.ignoreDuplicates
|
|
2527
|
+
});
|
|
2528
|
+
}, meta);
|
|
2529
|
+
if (typeof result === "number") return result;
|
|
2530
|
+
return typeof result?.count === "number" ? result.count : spec.values.length;
|
|
2531
|
+
}
|
|
2532
|
+
let inserted = 0;
|
|
2533
|
+
for (const values of spec.values) try {
|
|
2534
|
+
await delegate.create({ data: values });
|
|
2535
|
+
inserted += 1;
|
|
2536
|
+
} catch (error) {
|
|
2537
|
+
if (!spec.ignoreDuplicates) throw error;
|
|
2538
|
+
}
|
|
2539
|
+
return spec.ignoreDuplicates ? inserted : spec.values.length;
|
|
2540
|
+
}
|
|
2541
|
+
/**
|
|
2542
|
+
* Updates a single record matching the specified criteria and returns the updated record.
|
|
2543
|
+
*
|
|
2544
|
+
* @param spec
|
|
2545
|
+
* @returns
|
|
2546
|
+
*/
|
|
2547
|
+
async update(spec) {
|
|
2548
|
+
const delegate = this.resolveDelegate(spec.target);
|
|
2549
|
+
const where = this.toQueryWhere(spec.where);
|
|
2550
|
+
if (!where) return null;
|
|
2551
|
+
return await this.runWithDebug("update", spec.target, async () => {
|
|
2552
|
+
return await delegate.update({
|
|
2553
|
+
where,
|
|
2554
|
+
data: spec.values
|
|
2555
|
+
});
|
|
2556
|
+
}, {
|
|
2557
|
+
where,
|
|
2558
|
+
values: spec.values
|
|
2559
|
+
});
|
|
2560
|
+
}
|
|
2561
|
+
/**
|
|
2562
|
+
* Updates multiple records matching the specified criteria.
|
|
2563
|
+
*
|
|
2564
|
+
* @param spec
|
|
2565
|
+
* @returns
|
|
2566
|
+
*/
|
|
2567
|
+
async updateMany(spec) {
|
|
2568
|
+
const delegate = this.resolveDelegate(spec.target);
|
|
2569
|
+
const where = this.toQueryWhere(spec.where);
|
|
2570
|
+
const meta = {
|
|
2571
|
+
where,
|
|
2572
|
+
values: spec.values
|
|
2573
|
+
};
|
|
2574
|
+
if (typeof delegate.updateMany === "function") {
|
|
2575
|
+
const result = await this.runWithDebug("updateMany", spec.target, async () => {
|
|
2576
|
+
return await delegate.updateMany?.({
|
|
2577
|
+
where,
|
|
2578
|
+
data: spec.values
|
|
2579
|
+
});
|
|
2580
|
+
}, meta);
|
|
2581
|
+
if (typeof result === "number") return result;
|
|
2582
|
+
return typeof result?.count === "number" ? result.count : 0;
|
|
2583
|
+
}
|
|
2584
|
+
const rows = await delegate.findMany({ where });
|
|
2585
|
+
await Promise.all(rows.map(async (row) => {
|
|
2586
|
+
await delegate.update({
|
|
2587
|
+
where: row,
|
|
2588
|
+
data: spec.values
|
|
2589
|
+
});
|
|
2590
|
+
}));
|
|
2591
|
+
return rows.length;
|
|
2592
|
+
}
|
|
2593
|
+
/**
|
|
2594
|
+
* Deletes a single record matching the specified criteria and returns the deleted record.
|
|
2595
|
+
*
|
|
2596
|
+
* @param spec
|
|
2597
|
+
* @returns
|
|
2598
|
+
*/
|
|
2599
|
+
async delete(spec) {
|
|
2600
|
+
const delegate = this.resolveDelegate(spec.target);
|
|
2601
|
+
const where = this.toQueryWhere(spec.where);
|
|
2602
|
+
if (!where) return null;
|
|
2603
|
+
return await this.runWithDebug("delete", spec.target, async () => {
|
|
2604
|
+
return await delegate.delete({ where });
|
|
2605
|
+
}, { where });
|
|
2606
|
+
}
|
|
2607
|
+
/**
|
|
2608
|
+
* Deletes multiple records matching the specified criteria.
|
|
2609
|
+
*
|
|
2610
|
+
* @param spec
|
|
2611
|
+
* @returns
|
|
2612
|
+
*/
|
|
2613
|
+
async deleteMany(spec) {
|
|
2614
|
+
const delegate = this.resolveDelegate(spec.target);
|
|
2615
|
+
const where = this.toQueryWhere(spec.where);
|
|
2616
|
+
const rows = await this.runWithDebug("deleteMany", spec.target, async () => {
|
|
2617
|
+
return await delegate.findMany({ where });
|
|
2618
|
+
}, { where });
|
|
2619
|
+
await Promise.all(rows.map(async (row) => {
|
|
2620
|
+
await delegate.delete({ where: row });
|
|
2621
|
+
}));
|
|
2622
|
+
return rows.length;
|
|
2623
|
+
}
|
|
2624
|
+
/**
|
|
2625
|
+
* Counts the number of records matching the specified criteria.
|
|
2626
|
+
*
|
|
2627
|
+
* @param spec
|
|
2628
|
+
* @returns
|
|
2629
|
+
*/
|
|
2630
|
+
async count(spec) {
|
|
2631
|
+
const delegate = this.resolveDelegate(spec.target);
|
|
2632
|
+
const where = this.toQueryWhere(spec.where);
|
|
2633
|
+
return await this.runWithDebug("count", spec.target, async () => {
|
|
2634
|
+
return await delegate.count({ where });
|
|
2635
|
+
}, { where });
|
|
2636
|
+
}
|
|
2637
|
+
/**
|
|
2638
|
+
* Checks for the existence of records matching the specified criteria.
|
|
2639
|
+
*
|
|
2640
|
+
* @param spec
|
|
2641
|
+
* @returns
|
|
2642
|
+
*/
|
|
2643
|
+
async exists(spec) {
|
|
2644
|
+
return await this.selectOne({
|
|
2645
|
+
...spec,
|
|
2646
|
+
limit: 1
|
|
2647
|
+
}) != null;
|
|
2648
|
+
}
|
|
2649
|
+
/**
|
|
2650
|
+
* Loads related models for a batch of parent records based on the specified relation load plans.
|
|
2651
|
+
*
|
|
2652
|
+
* @param _spec
|
|
2653
|
+
*/
|
|
2654
|
+
async loadRelations(_spec) {
|
|
2655
|
+
throw new UnsupportedAdapterFeatureException("Adapter-owned relation batch loading is intentionally unavailable on the Prisma compatibility adapter; eager loading stays on Arkorm's generic loader for this path.", {
|
|
2656
|
+
operation: "adapter.loadRelations",
|
|
2657
|
+
meta: { feature: "relationLoads" }
|
|
2658
|
+
});
|
|
2659
|
+
}
|
|
2660
|
+
/**
|
|
2661
|
+
* Executes a series of database operations within a transaction.
|
|
2662
|
+
* If the underlying Prisma client does not support transactions, an exception is thrown.
|
|
2663
|
+
*
|
|
2664
|
+
* @param callback
|
|
2665
|
+
* @param context
|
|
2666
|
+
* @returns
|
|
2667
|
+
*/
|
|
2668
|
+
async transaction(callback, context = {}) {
|
|
2669
|
+
if (!this.hasTransactionSupport(this.prisma)) throw new UnsupportedAdapterFeatureException("Transactions are not supported by the Prisma compatibility adapter.", {
|
|
2670
|
+
operation: "adapter.transaction",
|
|
2671
|
+
meta: { feature: "transactions" }
|
|
2672
|
+
});
|
|
2673
|
+
return await this.prisma.$transaction(async (transactionClient) => {
|
|
2674
|
+
return await callback(new PrismaDatabaseAdapter(transactionClient, this.mapping));
|
|
2675
|
+
}, {
|
|
2676
|
+
isolationLevel: context.isolationLevel,
|
|
2677
|
+
maxWait: context.maxWait,
|
|
2678
|
+
timeout: context.timeout
|
|
2679
|
+
});
|
|
2680
|
+
}
|
|
2681
|
+
};
|
|
1965
2682
|
|
|
1966
2683
|
//#endregion
|
|
1967
2684
|
//#region src/cli/CliApp.ts
|
|
@@ -1984,6 +2701,9 @@ var CliApp = class {
|
|
|
1984
2701
|
* @returns The entire configuration object or the value of the specified key
|
|
1985
2702
|
*/
|
|
1986
2703
|
getConfig = getUserConfig;
|
|
2704
|
+
isUsingPrismaAdapter() {
|
|
2705
|
+
return this.getConfig("adapter") instanceof PrismaDatabaseAdapter;
|
|
2706
|
+
}
|
|
1987
2707
|
/**
|
|
1988
2708
|
* Utility to ensure directory exists
|
|
1989
2709
|
*
|
|
@@ -1991,7 +2711,7 @@ var CliApp = class {
|
|
|
1991
2711
|
*/
|
|
1992
2712
|
ensureDirectory(filePath) {
|
|
1993
2713
|
const dir = dirname$1(filePath);
|
|
1994
|
-
if (!existsSync
|
|
2714
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
1995
2715
|
}
|
|
1996
2716
|
/**
|
|
1997
2717
|
* Convert absolute paths under current working directory into relative display paths.
|
|
@@ -2040,13 +2760,13 @@ var CliApp = class {
|
|
|
2040
2760
|
* @returns
|
|
2041
2761
|
*/
|
|
2042
2762
|
resolveRuntimeDirectoryPath(directoryPath) {
|
|
2043
|
-
if (existsSync
|
|
2763
|
+
if (existsSync(directoryPath)) return directoryPath;
|
|
2044
2764
|
const { buildOutput } = this.getConfig("paths") || {};
|
|
2045
2765
|
if (typeof buildOutput !== "string" || buildOutput.trim().length === 0) return directoryPath;
|
|
2046
2766
|
const relativeSource = relative(process.cwd(), directoryPath);
|
|
2047
2767
|
if (!relativeSource || relativeSource.startsWith("..")) return directoryPath;
|
|
2048
2768
|
const mappedDirectory = join$1(buildOutput, relativeSource);
|
|
2049
|
-
return existsSync
|
|
2769
|
+
return existsSync(mappedDirectory) ? mappedDirectory : directoryPath;
|
|
2050
2770
|
}
|
|
2051
2771
|
/**
|
|
2052
2772
|
* Resolve a script file path for runtime execution.
|
|
@@ -2076,7 +2796,7 @@ var CliApp = class {
|
|
|
2076
2796
|
} else candidates.push(mappedFile);
|
|
2077
2797
|
}
|
|
2078
2798
|
}
|
|
2079
|
-
const runtimeMatch = candidates.find((path) => existsSync
|
|
2799
|
+
const runtimeMatch = candidates.find((path) => existsSync(path));
|
|
2080
2800
|
if (runtimeMatch) return runtimeMatch;
|
|
2081
2801
|
return filePath;
|
|
2082
2802
|
}
|
|
@@ -2088,14 +2808,14 @@ var CliApp = class {
|
|
|
2088
2808
|
* @param replacements
|
|
2089
2809
|
*/
|
|
2090
2810
|
generateFile(stubPath, outputPath, replacements, options) {
|
|
2091
|
-
if (existsSync
|
|
2811
|
+
if (existsSync(outputPath) && !options?.force) {
|
|
2092
2812
|
this.command.error(`Error: ${this.formatPathForLog(outputPath)} already exists.`);
|
|
2093
2813
|
process.exit(1);
|
|
2094
|
-
} else if (existsSync
|
|
2095
|
-
let content = readFileSync
|
|
2814
|
+
} else if (existsSync(outputPath) && options?.force) rmSync(outputPath);
|
|
2815
|
+
let content = readFileSync(stubPath, "utf-8");
|
|
2096
2816
|
for (const [key, value] of Object.entries(replacements)) content = content.replace(new RegExp(`{{${key}}}`, "g"), value);
|
|
2097
2817
|
this.ensureDirectory(outputPath);
|
|
2098
|
-
writeFileSync
|
|
2818
|
+
writeFileSync(outputPath, content);
|
|
2099
2819
|
return outputPath;
|
|
2100
2820
|
}
|
|
2101
2821
|
/**
|
|
@@ -2187,7 +2907,7 @@ var CliApp = class {
|
|
|
2187
2907
|
makeModel(name, options = {}) {
|
|
2188
2908
|
const baseName = str(name.replace(/Model$/, "")).pascal().toString();
|
|
2189
2909
|
const modelName = `${baseName}`;
|
|
2190
|
-
const
|
|
2910
|
+
const tableName = str(baseName).camel().plural().toString();
|
|
2191
2911
|
const outputExt = this.resolveOutputExt();
|
|
2192
2912
|
const outputPath = join$1(this.resolveConfigPath("models", join$1(process.cwd(), "src", "models")), `${modelName}.${outputExt}`);
|
|
2193
2913
|
const shouldBuildFactory = options.all || options.factory;
|
|
@@ -2196,14 +2916,16 @@ var CliApp = class {
|
|
|
2196
2916
|
const factoryName = `${baseName}Factory`;
|
|
2197
2917
|
const factoryPath = join$1(this.resolveConfigPath("factories", join$1(process.cwd(), "database", "factories")), `${factoryName}.${outputExt}`);
|
|
2198
2918
|
const factoryImportPath = `./${relative(dirname$1(outputPath), factoryPath).replace(/\\/g, "/").replace(/\.(ts|tsx|mts|cts|js|mjs|cjs)$/i, "")}${outputExt === "js" ? ".js" : ""}`;
|
|
2199
|
-
|
|
2919
|
+
let stubPath;
|
|
2920
|
+
if (options.pivot) stubPath = this.resolveStubPath("pivot-model.stub");
|
|
2921
|
+
else stubPath = this.resolveStubPath(outputExt === "js" ? "model.js.stub" : "model.stub");
|
|
2200
2922
|
const modelPath = this.generateFile(stubPath, outputPath, {
|
|
2201
2923
|
ModelName: modelName,
|
|
2202
|
-
|
|
2924
|
+
TableName: tableName,
|
|
2203
2925
|
FactoryImport: shouldBuildFactory ? `import { ${factoryName} } from '${factoryImportPath}'\n` : "",
|
|
2204
2926
|
FactoryLink: shouldBuildFactory ? outputExt === "js" ? `\n static factoryClass = ${factoryName}` : `\n protected static override factoryClass = ${factoryName}` : ""
|
|
2205
2927
|
}, options);
|
|
2206
|
-
const prisma = this.ensurePrismaModelEntry(modelName,
|
|
2928
|
+
const prisma = this.isUsingPrismaAdapter() ? this.ensurePrismaModelEntry(modelName, tableName) : void 0;
|
|
2207
2929
|
const created = {
|
|
2208
2930
|
model: {
|
|
2209
2931
|
name: modelName,
|
|
@@ -2220,33 +2942,30 @@ var CliApp = class {
|
|
|
2220
2942
|
modelImportPath: `./${relative(dirname$1(factoryPath), outputPath).replace(/\\/g, "/").replace(/\.(ts|tsx|mts|cts|js|mjs|cjs)$/i, "")}${outputExt === "js" ? ".js" : ""}`
|
|
2221
2943
|
});
|
|
2222
2944
|
if (shouldBuildSeeder) created.seeder = this.makeSeeder(baseName, { force: options.force });
|
|
2223
|
-
if (shouldBuildMigration) created.migration = this.makeMigration(`create ${
|
|
2945
|
+
if (shouldBuildMigration) created.migration = this.makeMigration(`create ${tableName} table`);
|
|
2224
2946
|
return created;
|
|
2225
2947
|
}
|
|
2226
2948
|
/**
|
|
2227
2949
|
* Ensure that the Prisma schema has a model entry for the given model
|
|
2228
|
-
* and
|
|
2950
|
+
* and table names.
|
|
2229
2951
|
* If the entry does not exist, it will be created with a default `id` field.
|
|
2230
2952
|
*
|
|
2231
2953
|
* @param modelName The name of the model to ensure in the Prisma schema.
|
|
2232
|
-
* @param
|
|
2954
|
+
* @param tableName The table name to ensure in the Prisma schema.
|
|
2233
2955
|
*/
|
|
2234
|
-
ensurePrismaModelEntry(modelName,
|
|
2956
|
+
ensurePrismaModelEntry(modelName, tableName) {
|
|
2235
2957
|
const schemaPath = join$1(process.cwd(), "prisma", "schema.prisma");
|
|
2236
|
-
if (!existsSync
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
};
|
|
2240
|
-
const source = readFileSync$1(schemaPath, "utf-8");
|
|
2241
|
-
const existingByTable = findModelBlock(source, delegateName);
|
|
2958
|
+
if (!existsSync(schemaPath)) return void 0;
|
|
2959
|
+
const source = readFileSync(schemaPath, "utf-8");
|
|
2960
|
+
const existingByTable = findModelBlock(source, tableName);
|
|
2242
2961
|
const existingByName = new RegExp(`model\\s+${modelName}\\s*\\{`, "m").test(source);
|
|
2243
2962
|
if (existingByTable || existingByName) return {
|
|
2244
2963
|
path: schemaPath,
|
|
2245
2964
|
updated: false
|
|
2246
2965
|
};
|
|
2247
|
-
writeFileSync
|
|
2966
|
+
writeFileSync(schemaPath, applyCreateTableOperation(source, {
|
|
2248
2967
|
type: "createTable",
|
|
2249
|
-
table:
|
|
2968
|
+
table: tableName,
|
|
2250
2969
|
columns: [{
|
|
2251
2970
|
name: "id",
|
|
2252
2971
|
type: "id",
|
|
@@ -2466,17 +3185,17 @@ var CliApp = class {
|
|
|
2466
3185
|
if (!classMatch) return null;
|
|
2467
3186
|
const className = classMatch[1];
|
|
2468
3187
|
const tableMatch = modelSource.match(/protected\s+static\s+override\s+table\s*=\s*['"]([^'"]+)['"]/) ?? modelSource.match(/static\s+table\s*=\s*['"]([^'"]+)['"]/);
|
|
2469
|
-
const
|
|
3188
|
+
const compatibilityDelegateMatch = modelSource.match(/protected\s+static\s+override\s+delegate\s*=\s*['"]([^'"]+)['"]/) ?? modelSource.match(/static\s+delegate\s*=\s*['"]([^'"]+)['"]/);
|
|
2470
3189
|
return {
|
|
2471
3190
|
className,
|
|
2472
|
-
table: tableMatch?.[1] ??
|
|
3191
|
+
table: tableMatch?.[1] ?? compatibilityDelegateMatch?.[1] ?? str(className).camel().plural().toString()
|
|
2473
3192
|
};
|
|
2474
3193
|
}
|
|
2475
3194
|
syncModelFiles(modelFiles, resolveStructure, enums) {
|
|
2476
3195
|
const updated = [];
|
|
2477
3196
|
const skipped = [];
|
|
2478
3197
|
modelFiles.forEach((filePath) => {
|
|
2479
|
-
const source = readFileSync
|
|
3198
|
+
const source = readFileSync(filePath, "utf-8");
|
|
2480
3199
|
const structure = resolveStructure(filePath, source);
|
|
2481
3200
|
if (!structure || structure.fields.length === 0) {
|
|
2482
3201
|
skipped.push(filePath);
|
|
@@ -2487,7 +3206,7 @@ var CliApp = class {
|
|
|
2487
3206
|
skipped.push(filePath);
|
|
2488
3207
|
return;
|
|
2489
3208
|
}
|
|
2490
|
-
writeFileSync
|
|
3209
|
+
writeFileSync(filePath, synced.content);
|
|
2491
3210
|
updated.push(filePath);
|
|
2492
3211
|
});
|
|
2493
3212
|
return {
|
|
@@ -2672,12 +3391,12 @@ var CliApp = class {
|
|
|
2672
3391
|
}
|
|
2673
3392
|
async syncModels(options = {}) {
|
|
2674
3393
|
const modelsDir = options.modelsDir ?? this.resolveConfigPath("models", join$1(process.cwd(), "src", "models"));
|
|
2675
|
-
if (!existsSync
|
|
2676
|
-
const modelFiles = readdirSync
|
|
3394
|
+
if (!existsSync(modelsDir)) throw new Error(`Models directory not found: ${modelsDir}`);
|
|
3395
|
+
const modelFiles = readdirSync(modelsDir).filter((file) => file.endsWith(".ts")).map((file) => join$1(modelsDir, file));
|
|
2677
3396
|
const adapter = this.getConfig("adapter");
|
|
2678
3397
|
if (adapter && typeof adapter.introspectModels === "function") {
|
|
2679
3398
|
const sources = modelFiles.reduce((all, filePath) => {
|
|
2680
|
-
const parsed = this.parseModelSyncSource(readFileSync
|
|
3399
|
+
const parsed = this.parseModelSyncSource(readFileSync(filePath, "utf-8"));
|
|
2681
3400
|
if (parsed) all.set(filePath, parsed);
|
|
2682
3401
|
return all;
|
|
2683
3402
|
}, /* @__PURE__ */ new Map());
|
|
@@ -2717,12 +3436,12 @@ var CliApp = class {
|
|
|
2717
3436
|
syncModelsFromPrisma(options = {}) {
|
|
2718
3437
|
const schemaPath = options.schemaPath ?? join$1(process.cwd(), "prisma", "schema.prisma");
|
|
2719
3438
|
const modelsDir = options.modelsDir ?? this.resolveConfigPath("models", join$1(process.cwd(), "src", "models"));
|
|
2720
|
-
if (!existsSync
|
|
2721
|
-
if (!existsSync
|
|
2722
|
-
const schema = readFileSync
|
|
3439
|
+
if (!existsSync(schemaPath)) throw new Error(`Prisma schema file not found: ${schemaPath}`);
|
|
3440
|
+
if (!existsSync(modelsDir)) throw new Error(`Models directory not found: ${modelsDir}`);
|
|
3441
|
+
const schema = readFileSync(schemaPath, "utf-8");
|
|
2723
3442
|
const prismaEnums = this.parsePrismaEnums(schema);
|
|
2724
3443
|
const prismaModels = this.parsePrismaModels(schema);
|
|
2725
|
-
const modelFiles = readdirSync
|
|
3444
|
+
const modelFiles = readdirSync(modelsDir).filter((file) => file.endsWith(".ts")).map((file) => join$1(modelsDir, file));
|
|
2726
3445
|
const result = this.syncModelFiles(modelFiles, (filePath, source) => {
|
|
2727
3446
|
const parsed = this.parseModelSyncSource(source);
|
|
2728
3447
|
if (!parsed) return void 0;
|
|
@@ -2762,18 +3481,18 @@ var InitCommand = class extends Command {
|
|
|
2762
3481
|
const stubsDir = typeof stubs === "string" && stubs.trim().length > 0 ? stubs : getDefaultStubsPath();
|
|
2763
3482
|
const preferredStubPath = join(stubsDir, "arkormx.config.stub");
|
|
2764
3483
|
const legacyStubPath = join(stubsDir, "arkorm.config.stub");
|
|
2765
|
-
const stubPath = existsSync
|
|
2766
|
-
if (existsSync
|
|
3484
|
+
const stubPath = existsSync(preferredStubPath) ? preferredStubPath : legacyStubPath;
|
|
3485
|
+
if (existsSync(outputDir) && !this.option("force")) {
|
|
2767
3486
|
this.error("Error: Arkormˣ has already been initialized. Use --force to reinitialize.");
|
|
2768
3487
|
process.exit(1);
|
|
2769
3488
|
}
|
|
2770
3489
|
this.app.ensureDirectory(outputDir);
|
|
2771
|
-
if (existsSync
|
|
2772
|
-
if (!existsSync
|
|
3490
|
+
if (existsSync(outputDir) && this.option("force")) copyFileSync(outputDir, outputDir.replace(/\.js$/, `.backup.${Date.now()}.js`));
|
|
3491
|
+
if (!existsSync(stubPath)) {
|
|
2773
3492
|
this.error(`Error: Missing config stub at ${preferredStubPath} (or ${legacyStubPath})`);
|
|
2774
3493
|
process.exit(1);
|
|
2775
3494
|
}
|
|
2776
|
-
writeFileSync
|
|
3495
|
+
writeFileSync(outputDir, readFileSync(stubPath, "utf-8"));
|
|
2777
3496
|
this.success("Arkormˣ initialized successfully!");
|
|
2778
3497
|
}
|
|
2779
3498
|
};
|
|
@@ -2849,6 +3568,7 @@ var MakeModelCommand = class extends Command {
|
|
|
2849
3568
|
{--factory : Create and link a factory}
|
|
2850
3569
|
{--seeder : Create a seeder}
|
|
2851
3570
|
{--migration : Create a migration}
|
|
3571
|
+
{--p|pivot : Indicate the required model is an intermediate pivot model}
|
|
2852
3572
|
{--all : Create and link factory, seeder, and migration}
|
|
2853
3573
|
`;
|
|
2854
3574
|
description = "Create a new model and optional linked resources";
|
|
@@ -2862,14 +3582,13 @@ var MakeModelCommand = class extends Command {
|
|
|
2862
3582
|
const name = this.argument("name");
|
|
2863
3583
|
if (!name) return void this.error("Error: Name argument is required.");
|
|
2864
3584
|
const created = this.app.makeModel(name, this.options());
|
|
3585
|
+
const createdFiles = [["Model", created.model.path]];
|
|
3586
|
+
if (created.prisma) createdFiles.push([`Prisma schema ${created.prisma.updated ? "(updated)" : "(already up to date)"}`, created.prisma.path]);
|
|
3587
|
+
if (created.factory) createdFiles.push(["Factory", created.factory.path]);
|
|
3588
|
+
if (created.seeder) createdFiles.push(["Seeder", created.seeder.path]);
|
|
3589
|
+
if (created.migration) createdFiles.push(["Migration", created.migration.path]);
|
|
2865
3590
|
this.success("Created files:");
|
|
2866
|
-
[
|
|
2867
|
-
["Model", created.model.path],
|
|
2868
|
-
[`Prisma schema ${created.prisma.updated ? "(updated)" : "(already up to date)"}`, created.prisma.path],
|
|
2869
|
-
created.factory ? ["Factory", created.factory.path] : "",
|
|
2870
|
-
created.seeder ? ["Seeder", created.seeder.path] : "",
|
|
2871
|
-
created.migration ? ["Migration", created.migration.path] : ""
|
|
2872
|
-
].filter(Boolean).map(([name, path]) => this.success(this.app.splitLogger(name, path)));
|
|
3591
|
+
createdFiles.map(([fileType, path]) => this.success(this.app.splitLogger(fileType, path)));
|
|
2873
3592
|
}
|
|
2874
3593
|
};
|
|
2875
3594
|
|
|
@@ -2948,7 +3667,7 @@ var MigrateCommand = class extends Command {
|
|
|
2948
3667
|
this.app.command = this;
|
|
2949
3668
|
const configuredMigrationsDir = this.app.getConfig("paths")?.migrations ?? join(process.cwd(), "database", "migrations");
|
|
2950
3669
|
const migrationsDir = this.app.resolveRuntimeDirectoryPath(configuredMigrationsDir);
|
|
2951
|
-
if (!existsSync(migrationsDir)) return void this.error(`Error: Migrations directory not found: ${this.app.formatPathForLog(configuredMigrationsDir)}`);
|
|
3670
|
+
if (!existsSync$1(migrationsDir)) return void this.error(`Error: Migrations directory not found: ${this.app.formatPathForLog(configuredMigrationsDir)}`);
|
|
2952
3671
|
const schemaPath = this.option("schema") ? resolve(String(this.option("schema"))) : join(process.cwd(), "prisma", "schema.prisma");
|
|
2953
3672
|
const classes = this.option("all") || !this.argument("name") ? await this.loadAllMigrations(migrationsDir) : (await this.loadNamedMigration(migrationsDir, this.argument("name"))).filter(([cls]) => cls !== void 0);
|
|
2954
3673
|
if (classes.length === 0) return void this.error("Error: No migration classes found to run.");
|
|
@@ -3043,7 +3762,7 @@ var MigrateCommand = class extends Command {
|
|
|
3043
3762
|
* @param migrationsDir The directory to load migration classes from.
|
|
3044
3763
|
*/
|
|
3045
3764
|
async loadAllMigrations(migrationsDir) {
|
|
3046
|
-
const files = readdirSync(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join(migrationsDir, file)));
|
|
3765
|
+
const files = readdirSync$1(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join(migrationsDir, file)));
|
|
3047
3766
|
return (await Promise.all(files.map(async (file) => (await this.loadMigrationClassesFromFile(file)).map((cls) => [cls, file])))).flat();
|
|
3048
3767
|
}
|
|
3049
3768
|
/**
|
|
@@ -3065,7 +3784,7 @@ var MigrateCommand = class extends Command {
|
|
|
3065
3784
|
`${base}Migration.js`,
|
|
3066
3785
|
`${base}Migration.mjs`,
|
|
3067
3786
|
`${base}Migration.cjs`
|
|
3068
|
-
].map((file) => join(migrationsDir, file)).find((file) => existsSync(file));
|
|
3787
|
+
].map((file) => join(migrationsDir, file)).find((file) => existsSync$1(file));
|
|
3069
3788
|
if (!target) return [[void 0, name]];
|
|
3070
3789
|
const runtimeTarget = this.app.resolveRuntimeScriptPath(target);
|
|
3071
3790
|
return (await this.loadMigrationClassesFromFile(runtimeTarget)).map((cls) => [cls, runtimeTarget]);
|
|
@@ -3101,7 +3820,7 @@ var MigrateFreshCommand = class extends Command {
|
|
|
3101
3820
|
this.app.command = this;
|
|
3102
3821
|
const configuredMigrationsDir = this.app.getConfig("paths")?.migrations ?? join(process.cwd(), "database", "migrations");
|
|
3103
3822
|
const migrationsDir = this.app.resolveRuntimeDirectoryPath(configuredMigrationsDir);
|
|
3104
|
-
if (!existsSync(migrationsDir)) return void this.error(`Error: Migrations directory not found: ${this.app.formatPathForLog(configuredMigrationsDir)}`);
|
|
3823
|
+
if (!existsSync$1(migrationsDir)) return void this.error(`Error: Migrations directory not found: ${this.app.formatPathForLog(configuredMigrationsDir)}`);
|
|
3105
3824
|
const adapter = this.app.getConfig("adapter");
|
|
3106
3825
|
const useDatabaseMigrations = supportsDatabaseMigrationExecution(adapter);
|
|
3107
3826
|
const persistedFeatures = resolvePersistedMetadataFeatures(this.app.getConfig("features"));
|
|
@@ -3122,8 +3841,8 @@ var MigrateFreshCommand = class extends Command {
|
|
|
3122
3841
|
}
|
|
3123
3842
|
await adapter.resetDatabase();
|
|
3124
3843
|
} else {
|
|
3125
|
-
if (!existsSync(schemaPath)) return void this.error(`Error: Prisma schema file not found: ${this.app.formatPathForLog(schemaPath)}`);
|
|
3126
|
-
writeFileSync(schemaPath, stripPrismaSchemaModelsAndEnums(readFileSync(schemaPath, "utf-8")));
|
|
3844
|
+
if (!existsSync$1(schemaPath)) return void this.error(`Error: Prisma schema file not found: ${this.app.formatPathForLog(schemaPath)}`);
|
|
3845
|
+
writeFileSync$1(schemaPath, stripPrismaSchemaModelsAndEnums(readFileSync$1(schemaPath, "utf-8")));
|
|
3127
3846
|
}
|
|
3128
3847
|
let appliedState = createEmptyAppliedMigrationsState();
|
|
3129
3848
|
await writeAppliedMigrationsStateToStore(adapter, stateFilePath, appliedState);
|
|
@@ -3170,7 +3889,7 @@ var MigrateFreshCommand = class extends Command {
|
|
|
3170
3889
|
migrations.forEach(([_, file]) => this.success(this.app.splitLogger("Migrated", file)));
|
|
3171
3890
|
}
|
|
3172
3891
|
async loadAllMigrations(migrationsDir) {
|
|
3173
|
-
const files = readdirSync(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join(migrationsDir, file)));
|
|
3892
|
+
const files = readdirSync$1(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join(migrationsDir, file)));
|
|
3174
3893
|
return (await Promise.all(files.map(async (file) => (await this.loadMigrationClassesFromFile(file)).map((cls) => [cls, file])))).flat();
|
|
3175
3894
|
}
|
|
3176
3895
|
async loadMigrationClassesFromFile(filePath) {
|
|
@@ -3209,7 +3928,7 @@ var MigrateRollbackCommand = class extends Command {
|
|
|
3209
3928
|
this.app.command = this;
|
|
3210
3929
|
const configuredMigrationsDir = this.app.getConfig("paths")?.migrations ?? join(process.cwd(), "database", "migrations");
|
|
3211
3930
|
const migrationsDir = this.app.resolveRuntimeDirectoryPath(configuredMigrationsDir);
|
|
3212
|
-
if (!existsSync(migrationsDir)) return void this.error(`Error: Migrations directory not found: ${this.app.formatPathForLog(configuredMigrationsDir)}`);
|
|
3931
|
+
if (!existsSync$1(migrationsDir)) return void this.error(`Error: Migrations directory not found: ${this.app.formatPathForLog(configuredMigrationsDir)}`);
|
|
3213
3932
|
const schemaPath = this.option("schema") ? resolve(String(this.option("schema"))) : join(process.cwd(), "prisma", "schema.prisma");
|
|
3214
3933
|
const stateFilePath = resolveMigrationStateFilePath(process.cwd(), this.option("state-file") ? String(this.option("state-file")) : void 0);
|
|
3215
3934
|
const adapter = this.app.getConfig("adapter");
|
|
@@ -3270,7 +3989,7 @@ var MigrateRollbackCommand = class extends Command {
|
|
|
3270
3989
|
rollbackClasses.forEach(([_, file]) => this.success(this.app.splitLogger("RolledBack", file)));
|
|
3271
3990
|
}
|
|
3272
3991
|
async loadAllMigrations(migrationsDir) {
|
|
3273
|
-
const files = readdirSync(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join(migrationsDir, file)));
|
|
3992
|
+
const files = readdirSync$1(migrationsDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).sort((left, right) => left.localeCompare(right)).map((file) => this.app.resolveRuntimeScriptPath(join(migrationsDir, file)));
|
|
3274
3993
|
return (await Promise.all(files.map(async (file) => (await this.loadMigrationClassesFromFile(file)).map((cls) => [cls, file])))).flat();
|
|
3275
3994
|
}
|
|
3276
3995
|
async loadMigrationClassesFromFile(filePath) {
|
|
@@ -3312,11 +4031,11 @@ var MigrationHistoryCommand = class extends Command {
|
|
|
3312
4031
|
this.success("Deleted tracked migration state from database.");
|
|
3313
4032
|
return;
|
|
3314
4033
|
}
|
|
3315
|
-
if (!existsSync(stateFilePath)) {
|
|
4034
|
+
if (!existsSync$1(stateFilePath)) {
|
|
3316
4035
|
this.success(`No migration state file found at ${this.app.formatPathForLog(stateFilePath)}`);
|
|
3317
4036
|
return;
|
|
3318
4037
|
}
|
|
3319
|
-
rmSync(stateFilePath);
|
|
4038
|
+
rmSync$1(stateFilePath);
|
|
3320
4039
|
deletePersistedColumnMappingsState(resolveColumnMappingsFilePath(process.cwd()));
|
|
3321
4040
|
this.success(`Deleted migration state file: ${this.app.formatPathForLog(stateFilePath)}`);
|
|
3322
4041
|
return;
|
|
@@ -3451,7 +4170,7 @@ var SeedCommand = class extends Command {
|
|
|
3451
4170
|
this.app.command = this;
|
|
3452
4171
|
const configuredSeedersDir = this.app.getConfig("paths")?.seeders ?? join(process.cwd(), "database", "seeders");
|
|
3453
4172
|
const seedersDir = this.app.resolveRuntimeDirectoryPath(configuredSeedersDir);
|
|
3454
|
-
if (!existsSync(seedersDir)) return void this.error(`ERROR: Seeders directory not found: ${this.app.formatPathForLog(configuredSeedersDir)}`);
|
|
4173
|
+
if (!existsSync$1(seedersDir)) return void this.error(`ERROR: Seeders directory not found: ${this.app.formatPathForLog(configuredSeedersDir)}`);
|
|
3455
4174
|
const classes = this.option("all") ? await this.loadAllSeeders(seedersDir) : await this.loadNamedSeeder(seedersDir, this.argument("name") ?? "DatabaseSeeder");
|
|
3456
4175
|
if (classes.length === 0) return void this.error("ERROR: No seeder classes found to run.");
|
|
3457
4176
|
for (const SeederClassItem of classes) await new SeederClassItem().run();
|
|
@@ -3465,7 +4184,7 @@ var SeedCommand = class extends Command {
|
|
|
3465
4184
|
* @returns
|
|
3466
4185
|
*/
|
|
3467
4186
|
async loadAllSeeders(seedersDir) {
|
|
3468
|
-
const files = readdirSync(seedersDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).map((file) => this.app.resolveRuntimeScriptPath(join(seedersDir, file)));
|
|
4187
|
+
const files = readdirSync$1(seedersDir).filter((file) => /\.(ts|js|mjs|cjs)$/i.test(file)).map((file) => this.app.resolveRuntimeScriptPath(join(seedersDir, file)));
|
|
3469
4188
|
return (await Promise.all(files.map(async (file) => await this.loadSeederClassesFromFile(file)))).flat();
|
|
3470
4189
|
}
|
|
3471
4190
|
/**
|
|
@@ -3486,7 +4205,7 @@ var SeedCommand = class extends Command {
|
|
|
3486
4205
|
`${base}Seeder.js`,
|
|
3487
4206
|
`${base}Seeder.mjs`,
|
|
3488
4207
|
`${base}Seeder.cjs`
|
|
3489
|
-
].map((file) => join(seedersDir, file)).find((file) => existsSync(file));
|
|
4208
|
+
].map((file) => join(seedersDir, file)).find((file) => existsSync$1(file));
|
|
3490
4209
|
if (!target) return [];
|
|
3491
4210
|
const runtimeTarget = this.app.resolveRuntimeScriptPath(target);
|
|
3492
4211
|
return await this.loadSeederClassesFromFile(runtimeTarget);
|