arkormx 2.10.1 → 2.11.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/dist/cli.mjs +541 -21
- package/dist/{index-GhBV8Kyw.d.cts → index-DggXDBiD.d.cts} +524 -13
- package/dist/{index-ufenXVzx.d.mts → index-DoqUdah-.d.mts} +524 -13
- package/dist/index.cjs +539 -62
- package/dist/index.d.cts +2 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +520 -63
- package/dist/relationship/index.cjs +1 -1
- package/dist/relationship/index.d.cts +1 -1
- package/dist/relationship/index.d.mts +1 -1
- package/dist/relationship/index.mjs +1 -1
- package/dist/{relationship-CmhzOlEo.mjs → relationship-CP1xbMOa.mjs} +507 -5
- package/dist/{relationship-DGOpcWA0.cjs → relationship-IC-TAFyG.cjs} +626 -4
- package/package.json +1 -1
|
@@ -1126,6 +1126,423 @@ var PrimaryKeyGenerationPlanner = class {
|
|
|
1126
1126
|
}
|
|
1127
1127
|
};
|
|
1128
1128
|
|
|
1129
|
+
//#endregion
|
|
1130
|
+
//#region src/Expression.ts
|
|
1131
|
+
/**
|
|
1132
|
+
* A composable SQL expression. Instances are immutable — every operator returns a
|
|
1133
|
+
* new expression — and are accepted by `select`, `where`, `groupBy`, `orderBy`,
|
|
1134
|
+
* `having`, and the aggregate helpers. Adapters compile the underlying node tree.
|
|
1135
|
+
*/
|
|
1136
|
+
var Expression = class Expression {
|
|
1137
|
+
/**
|
|
1138
|
+
* Type guard for values that came out of the expression builder.
|
|
1139
|
+
*/
|
|
1140
|
+
static isExpression(value) {
|
|
1141
|
+
return value instanceof Expression;
|
|
1142
|
+
}
|
|
1143
|
+
eq(value) {
|
|
1144
|
+
return binary("=", this, coerceValue(value));
|
|
1145
|
+
}
|
|
1146
|
+
ne(value) {
|
|
1147
|
+
return binary("!=", this, coerceValue(value));
|
|
1148
|
+
}
|
|
1149
|
+
gt(value) {
|
|
1150
|
+
return binary(">", this, coerceValue(value));
|
|
1151
|
+
}
|
|
1152
|
+
gte(value) {
|
|
1153
|
+
return binary(">=", this, coerceValue(value));
|
|
1154
|
+
}
|
|
1155
|
+
lt(value) {
|
|
1156
|
+
return binary("<", this, coerceValue(value));
|
|
1157
|
+
}
|
|
1158
|
+
lte(value) {
|
|
1159
|
+
return binary("<=", this, coerceValue(value));
|
|
1160
|
+
}
|
|
1161
|
+
like(value) {
|
|
1162
|
+
return binary("like", this, coerceValue(value));
|
|
1163
|
+
}
|
|
1164
|
+
ilike(value) {
|
|
1165
|
+
return binary("ilike", this, coerceValue(value));
|
|
1166
|
+
}
|
|
1167
|
+
notLike(value) {
|
|
1168
|
+
return binary("not-like", this, coerceValue(value));
|
|
1169
|
+
}
|
|
1170
|
+
notIlike(value) {
|
|
1171
|
+
return binary("not-ilike", this, coerceValue(value));
|
|
1172
|
+
}
|
|
1173
|
+
in(values) {
|
|
1174
|
+
return new NodeExpression({
|
|
1175
|
+
kind: "in",
|
|
1176
|
+
operand: this.toExpressionNode(),
|
|
1177
|
+
values: values.map((value) => coerceValue(value).toExpressionNode()),
|
|
1178
|
+
not: false
|
|
1179
|
+
});
|
|
1180
|
+
}
|
|
1181
|
+
notIn(values) {
|
|
1182
|
+
return new NodeExpression({
|
|
1183
|
+
kind: "in",
|
|
1184
|
+
operand: this.toExpressionNode(),
|
|
1185
|
+
values: values.map((value) => coerceValue(value).toExpressionNode()),
|
|
1186
|
+
not: true
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
isNull() {
|
|
1190
|
+
return new NodeExpression({
|
|
1191
|
+
kind: "null-check",
|
|
1192
|
+
operand: this.toExpressionNode(),
|
|
1193
|
+
not: false
|
|
1194
|
+
});
|
|
1195
|
+
}
|
|
1196
|
+
isNotNull() {
|
|
1197
|
+
return new NodeExpression({
|
|
1198
|
+
kind: "null-check",
|
|
1199
|
+
operand: this.toExpressionNode(),
|
|
1200
|
+
not: true
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
and(other) {
|
|
1204
|
+
return binary("and", this, other);
|
|
1205
|
+
}
|
|
1206
|
+
or(other) {
|
|
1207
|
+
return binary("or", this, other);
|
|
1208
|
+
}
|
|
1209
|
+
plus(value) {
|
|
1210
|
+
return binary("+", this, coerceValue(value));
|
|
1211
|
+
}
|
|
1212
|
+
minus(value) {
|
|
1213
|
+
return binary("-", this, coerceValue(value));
|
|
1214
|
+
}
|
|
1215
|
+
times(value) {
|
|
1216
|
+
return binary("*", this, coerceValue(value));
|
|
1217
|
+
}
|
|
1218
|
+
dividedBy(value) {
|
|
1219
|
+
return binary("/", this, coerceValue(value));
|
|
1220
|
+
}
|
|
1221
|
+
};
|
|
1222
|
+
/**
|
|
1223
|
+
* Concrete expression backed by a pre-built node.
|
|
1224
|
+
*/
|
|
1225
|
+
var NodeExpression = class extends Expression {
|
|
1226
|
+
constructor(node) {
|
|
1227
|
+
super();
|
|
1228
|
+
this.node = node;
|
|
1229
|
+
}
|
|
1230
|
+
toExpressionNode() {
|
|
1231
|
+
return this.node;
|
|
1232
|
+
}
|
|
1233
|
+
};
|
|
1234
|
+
/**
|
|
1235
|
+
* Fluent `CASE … WHEN … THEN … ELSE … END` builder. Immutable.
|
|
1236
|
+
*/
|
|
1237
|
+
var CaseExpression = class CaseExpression extends Expression {
|
|
1238
|
+
constructor(branches, elseExpr) {
|
|
1239
|
+
super();
|
|
1240
|
+
this.branches = branches;
|
|
1241
|
+
this.elseExpr = elseExpr;
|
|
1242
|
+
}
|
|
1243
|
+
when(condition, result) {
|
|
1244
|
+
return new CaseExpression([...this.branches, {
|
|
1245
|
+
when: condition,
|
|
1246
|
+
then: coerceValue(result)
|
|
1247
|
+
}], this.elseExpr);
|
|
1248
|
+
}
|
|
1249
|
+
else(result) {
|
|
1250
|
+
return new CaseExpression(this.branches, coerceValue(result));
|
|
1251
|
+
}
|
|
1252
|
+
toExpressionNode() {
|
|
1253
|
+
return {
|
|
1254
|
+
kind: "case",
|
|
1255
|
+
cases: this.branches.map((branch) => ({
|
|
1256
|
+
when: branch.when.toExpressionNode(),
|
|
1257
|
+
then: branch.then.toExpressionNode()
|
|
1258
|
+
})),
|
|
1259
|
+
else: this.elseExpr?.toExpressionNode()
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
};
|
|
1263
|
+
/**
|
|
1264
|
+
* JSON-path value extraction (`metadata ->> 'billType'`), with optional casts.
|
|
1265
|
+
*/
|
|
1266
|
+
var JsonExpression = class JsonExpression extends Expression {
|
|
1267
|
+
constructor(column, path, castTo) {
|
|
1268
|
+
super();
|
|
1269
|
+
this.column = column;
|
|
1270
|
+
this.path = path;
|
|
1271
|
+
this.castTo = castTo;
|
|
1272
|
+
}
|
|
1273
|
+
asText() {
|
|
1274
|
+
return new JsonExpression(this.column, this.path, "text");
|
|
1275
|
+
}
|
|
1276
|
+
asNumber() {
|
|
1277
|
+
return new JsonExpression(this.column, this.path, "number");
|
|
1278
|
+
}
|
|
1279
|
+
asBoolean() {
|
|
1280
|
+
return new JsonExpression(this.column, this.path, "boolean");
|
|
1281
|
+
}
|
|
1282
|
+
toExpressionNode() {
|
|
1283
|
+
return {
|
|
1284
|
+
kind: "json",
|
|
1285
|
+
column: this.column,
|
|
1286
|
+
path: this.path,
|
|
1287
|
+
cast: this.castTo
|
|
1288
|
+
};
|
|
1289
|
+
}
|
|
1290
|
+
};
|
|
1291
|
+
/**
|
|
1292
|
+
* Aggregate expression (`sum`, `count`, `avg`, `min`, `max`) with optional filter.
|
|
1293
|
+
*/
|
|
1294
|
+
var AggregateExpression = class AggregateExpression extends Expression {
|
|
1295
|
+
constructor(fn, arg, options = {}) {
|
|
1296
|
+
super();
|
|
1297
|
+
this.fn = fn;
|
|
1298
|
+
this.arg = arg;
|
|
1299
|
+
this.options = options;
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Restricts the aggregate to rows matching `predicate` (`FILTER (WHERE …)`).
|
|
1303
|
+
*/
|
|
1304
|
+
filter(predicate) {
|
|
1305
|
+
return new AggregateExpression(this.fn, this.arg, {
|
|
1306
|
+
...this.options,
|
|
1307
|
+
filterExpr: predicate
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
distinct() {
|
|
1311
|
+
return new AggregateExpression(this.fn, this.arg, {
|
|
1312
|
+
...this.options,
|
|
1313
|
+
distinct: true
|
|
1314
|
+
});
|
|
1315
|
+
}
|
|
1316
|
+
toExpressionNode() {
|
|
1317
|
+
return {
|
|
1318
|
+
kind: "aggregate",
|
|
1319
|
+
fn: this.fn,
|
|
1320
|
+
arg: this.arg?.toExpressionNode(),
|
|
1321
|
+
distinct: this.options.distinct,
|
|
1322
|
+
filter: this.options.filterExpr?.toExpressionNode()
|
|
1323
|
+
};
|
|
1324
|
+
}
|
|
1325
|
+
};
|
|
1326
|
+
const binary = (operator, left, right) => new NodeExpression({
|
|
1327
|
+
kind: "binary",
|
|
1328
|
+
operator,
|
|
1329
|
+
left: left.toExpressionNode(),
|
|
1330
|
+
right: right.toExpressionNode()
|
|
1331
|
+
});
|
|
1332
|
+
/**
|
|
1333
|
+
* Coerces a raw value into a bound-literal expression; passes expressions through.
|
|
1334
|
+
*/
|
|
1335
|
+
const coerceValue = (value) => {
|
|
1336
|
+
if (value instanceof Expression) return value;
|
|
1337
|
+
return new NodeExpression({
|
|
1338
|
+
kind: "value",
|
|
1339
|
+
value
|
|
1340
|
+
});
|
|
1341
|
+
};
|
|
1342
|
+
/**
|
|
1343
|
+
* Coerces a bare string into a column reference; passes expressions through.
|
|
1344
|
+
*/
|
|
1345
|
+
const coerceColumn = (value) => {
|
|
1346
|
+
if (value instanceof Expression) return value;
|
|
1347
|
+
if (typeof value === "string") return col(value);
|
|
1348
|
+
return coerceValue(value);
|
|
1349
|
+
};
|
|
1350
|
+
/**
|
|
1351
|
+
* Rebuilds an {@link Expression} around an already-serialized node.
|
|
1352
|
+
*/
|
|
1353
|
+
const fromExpressionNode = (node) => new NodeExpression(node);
|
|
1354
|
+
/**
|
|
1355
|
+
* A typed column reference. Supports joined `table.column` syntax.
|
|
1356
|
+
*/
|
|
1357
|
+
const col = (name) => new NodeExpression({
|
|
1358
|
+
kind: "column",
|
|
1359
|
+
name
|
|
1360
|
+
});
|
|
1361
|
+
/**
|
|
1362
|
+
* A bound literal value (parameterized, never interpolated).
|
|
1363
|
+
*/
|
|
1364
|
+
const val = (value) => new NodeExpression({
|
|
1365
|
+
kind: "value",
|
|
1366
|
+
value
|
|
1367
|
+
});
|
|
1368
|
+
/**
|
|
1369
|
+
* Raw SQL escape hatch with positional `?` bindings.
|
|
1370
|
+
*/
|
|
1371
|
+
const raw = (sql, bindings = []) => new NodeExpression({
|
|
1372
|
+
kind: "raw",
|
|
1373
|
+
sql,
|
|
1374
|
+
bindings
|
|
1375
|
+
});
|
|
1376
|
+
/**
|
|
1377
|
+
* Starts a `CASE WHEN condition THEN result` expression.
|
|
1378
|
+
*/
|
|
1379
|
+
const caseWhen = (condition, result) => new CaseExpression([{
|
|
1380
|
+
when: condition,
|
|
1381
|
+
then: coerceValue(result)
|
|
1382
|
+
}]);
|
|
1383
|
+
/**
|
|
1384
|
+
* `COALESCE(a, b, …)` — first non-null argument. Bare strings are columns.
|
|
1385
|
+
*/
|
|
1386
|
+
const coalesce = (...args) => new NodeExpression({
|
|
1387
|
+
kind: "function",
|
|
1388
|
+
name: "coalesce",
|
|
1389
|
+
args: args.map((arg) => coerceColumn(arg).toExpressionNode())
|
|
1390
|
+
});
|
|
1391
|
+
/**
|
|
1392
|
+
* An arbitrary SQL function call. Bare-string arguments are treated as columns.
|
|
1393
|
+
*/
|
|
1394
|
+
const fn = (name, ...args) => new NodeExpression({
|
|
1395
|
+
kind: "function",
|
|
1396
|
+
name,
|
|
1397
|
+
args: args.map((arg) => coerceColumn(arg).toExpressionNode())
|
|
1398
|
+
});
|
|
1399
|
+
/**
|
|
1400
|
+
* JSON value extraction: `json('metadata', 'billType')` => `metadata ->> 'billType'`.
|
|
1401
|
+
*/
|
|
1402
|
+
const json = (column, ...path) => new JsonExpression(column, path.map(String));
|
|
1403
|
+
/**
|
|
1404
|
+
* `SUM(expr)`; a bare-string argument is treated as a column.
|
|
1405
|
+
*/
|
|
1406
|
+
const sum = (arg) => new AggregateExpression("sum", coerceColumn(arg));
|
|
1407
|
+
/**
|
|
1408
|
+
* `AVG(expr)`; a bare-string argument is treated as a column.
|
|
1409
|
+
*/
|
|
1410
|
+
const avg = (arg) => new AggregateExpression("avg", coerceColumn(arg));
|
|
1411
|
+
/**
|
|
1412
|
+
* `MIN(expr)`; a bare-string argument is treated as a column.
|
|
1413
|
+
*/
|
|
1414
|
+
const min = (arg) => new AggregateExpression("min", coerceColumn(arg));
|
|
1415
|
+
/**
|
|
1416
|
+
* `MAX(expr)`; a bare-string argument is treated as a column.
|
|
1417
|
+
*/
|
|
1418
|
+
const max = (arg) => new AggregateExpression("max", coerceColumn(arg));
|
|
1419
|
+
/**
|
|
1420
|
+
* `COUNT(expr)` — or `COUNT(*)` when called without an argument.
|
|
1421
|
+
*/
|
|
1422
|
+
const count = (arg) => new AggregateExpression("count", arg === void 0 ? void 0 : coerceColumn(arg));
|
|
1423
|
+
const EXPRESSION_OPERATORS = {
|
|
1424
|
+
"=": "=",
|
|
1425
|
+
"==": "=",
|
|
1426
|
+
"!=": "!=",
|
|
1427
|
+
"<>": "!=",
|
|
1428
|
+
">": ">",
|
|
1429
|
+
">=": ">=",
|
|
1430
|
+
"<": "<",
|
|
1431
|
+
"<=": "<=",
|
|
1432
|
+
like: "like",
|
|
1433
|
+
ilike: "ilike",
|
|
1434
|
+
"not like": "not-like",
|
|
1435
|
+
"not ilike": "not-ilike"
|
|
1436
|
+
};
|
|
1437
|
+
/**
|
|
1438
|
+
* Builds a comparison predicate: `where('createdAt', '>=', boundary)`. Handy as an
|
|
1439
|
+
* inline predicate for `caseWhen`, `having`, and aggregate `.filter(…)`.
|
|
1440
|
+
*/
|
|
1441
|
+
const where = (column, operator, value) => {
|
|
1442
|
+
const normalized = EXPRESSION_OPERATORS[operator];
|
|
1443
|
+
if (!normalized) throw new Error(`Unsupported expression operator [${operator}].`);
|
|
1444
|
+
return binary(normalized, col(column), coerceValue(value));
|
|
1445
|
+
};
|
|
1446
|
+
/**
|
|
1447
|
+
* The expression-builder namespace passed to `static computed` factories, so a
|
|
1448
|
+
* model can declare a virtual attribute as `category: (e) => e.coalesce(…)`.
|
|
1449
|
+
*/
|
|
1450
|
+
const expressionBuilder = {
|
|
1451
|
+
col,
|
|
1452
|
+
val,
|
|
1453
|
+
raw,
|
|
1454
|
+
caseWhen,
|
|
1455
|
+
coalesce,
|
|
1456
|
+
fn,
|
|
1457
|
+
json,
|
|
1458
|
+
sum,
|
|
1459
|
+
avg,
|
|
1460
|
+
min,
|
|
1461
|
+
max,
|
|
1462
|
+
count,
|
|
1463
|
+
where
|
|
1464
|
+
};
|
|
1465
|
+
|
|
1466
|
+
//#endregion
|
|
1467
|
+
//#region src/helpers/generated-column.ts
|
|
1468
|
+
/**
|
|
1469
|
+
* Resolves a generated-column expression into raw Postgres SQL. Generated columns
|
|
1470
|
+
* cannot carry bind parameters (they must be immutable), so literal values are
|
|
1471
|
+
* inlined and aggregates are rejected.
|
|
1472
|
+
*/
|
|
1473
|
+
const resolveGeneratedExpression = (expression) => {
|
|
1474
|
+
if (typeof expression === "string") return expression;
|
|
1475
|
+
return expressionNodeToSql(expression(expressionBuilder).toExpressionNode());
|
|
1476
|
+
};
|
|
1477
|
+
const quoteIdentifier = (name) => name.split(".").map((part) => `"${part.replace(/"/g, "\"\"")}"`).join(".");
|
|
1478
|
+
const quoteLiteral = (value) => {
|
|
1479
|
+
if (value === null || value === void 0) return "null";
|
|
1480
|
+
if (typeof value === "number" || typeof value === "bigint") return String(value);
|
|
1481
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
1482
|
+
if (value instanceof Date) return `'${value.toISOString()}'`;
|
|
1483
|
+
return `'${String(value).replace(/'/g, "''")}'`;
|
|
1484
|
+
};
|
|
1485
|
+
const BINARY_OPERATORS = {
|
|
1486
|
+
"=": "=",
|
|
1487
|
+
"!=": "!=",
|
|
1488
|
+
">": ">",
|
|
1489
|
+
">=": ">=",
|
|
1490
|
+
"<": "<",
|
|
1491
|
+
"<=": "<=",
|
|
1492
|
+
like: "like",
|
|
1493
|
+
ilike: "ilike",
|
|
1494
|
+
"not-like": "not like",
|
|
1495
|
+
"not-ilike": "not ilike",
|
|
1496
|
+
and: "and",
|
|
1497
|
+
or: "or",
|
|
1498
|
+
"+": "+",
|
|
1499
|
+
"-": "-",
|
|
1500
|
+
"*": "*",
|
|
1501
|
+
"/": "/"
|
|
1502
|
+
};
|
|
1503
|
+
const FUNCTION_NAME = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
1504
|
+
const jsonAccessorSql = (node) => {
|
|
1505
|
+
const base = `${quoteIdentifier(node.column)}::jsonb`;
|
|
1506
|
+
let accessor;
|
|
1507
|
+
if (node.path.length === 0) accessor = base;
|
|
1508
|
+
else if (node.path.length === 1) accessor = `(${base} ->> ${quoteLiteral(node.path[0])})`;
|
|
1509
|
+
else accessor = `(${base} #>> '{${node.path.join(",")}}'::text[])`;
|
|
1510
|
+
if (node.cast === "number") return `(${accessor})::numeric`;
|
|
1511
|
+
if (node.cast === "boolean") return `(${accessor})::boolean`;
|
|
1512
|
+
return accessor;
|
|
1513
|
+
};
|
|
1514
|
+
const expressionNodeToSql = (node) => {
|
|
1515
|
+
switch (node.kind) {
|
|
1516
|
+
case "column": return quoteIdentifier(node.name);
|
|
1517
|
+
case "value": return quoteLiteral(node.value);
|
|
1518
|
+
case "raw": return inlineRawSql(node.sql, node.bindings);
|
|
1519
|
+
case "json": return jsonAccessorSql(node);
|
|
1520
|
+
case "function":
|
|
1521
|
+
if (!FUNCTION_NAME.test(node.name)) throw new ArkormException(`Unsupported SQL function name [${node.name}].`);
|
|
1522
|
+
return `${node.name}(${node.args.map(expressionNodeToSql).join(", ")})`;
|
|
1523
|
+
case "case": return `case ${node.cases.map((branch) => `when ${expressionNodeToSql(branch.when)} then ${expressionNodeToSql(branch.then)}`).join(" ")}${node.else ? ` else ${expressionNodeToSql(node.else)}` : ""} end`;
|
|
1524
|
+
case "binary": {
|
|
1525
|
+
const operator = BINARY_OPERATORS[node.operator];
|
|
1526
|
+
return `(${expressionNodeToSql(node.left)} ${operator} ${expressionNodeToSql(node.right)})`;
|
|
1527
|
+
}
|
|
1528
|
+
case "in": {
|
|
1529
|
+
const values = node.values.map(expressionNodeToSql).join(", ");
|
|
1530
|
+
return `(${expressionNodeToSql(node.operand)} ${node.not ? "not in" : "in"} (${values}))`;
|
|
1531
|
+
}
|
|
1532
|
+
case "null-check": return `(${expressionNodeToSql(node.operand)} is ${node.not ? "not null" : "null"})`;
|
|
1533
|
+
case "aggregate": throw new ArkormException("Aggregate expressions are not allowed in generated columns.");
|
|
1534
|
+
default: throw new ArkormException(`Unsupported expression node [${node.kind}].`);
|
|
1535
|
+
}
|
|
1536
|
+
};
|
|
1537
|
+
const inlineRawSql = (sql, bindings) => {
|
|
1538
|
+
const segments = sql.split("?");
|
|
1539
|
+
if (segments.length !== bindings.length + 1) throw new ArkormException("Raw expression bindings do not match the number of placeholders.");
|
|
1540
|
+
return segments.reduce((accumulator, segment, index) => {
|
|
1541
|
+
const binding = index < bindings.length ? quoteLiteral(bindings[index]) : "";
|
|
1542
|
+
return accumulator + segment + binding;
|
|
1543
|
+
}, "");
|
|
1544
|
+
};
|
|
1545
|
+
|
|
1129
1546
|
//#endregion
|
|
1130
1547
|
//#region src/database/TableBuilder.ts
|
|
1131
1548
|
const PRISMA_ENUM_MEMBER_REGEX$1 = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
@@ -1218,6 +1635,15 @@ var EnumBuilder = class {
|
|
|
1218
1635
|
this.tableBuilder.map(name, this.columnName);
|
|
1219
1636
|
return this;
|
|
1220
1637
|
}
|
|
1638
|
+
/**
|
|
1639
|
+
* Marks the enum column as an in-place change to an existing column.
|
|
1640
|
+
*
|
|
1641
|
+
* @returns
|
|
1642
|
+
*/
|
|
1643
|
+
change() {
|
|
1644
|
+
this.tableBuilder.change(this.columnName);
|
|
1645
|
+
return this;
|
|
1646
|
+
}
|
|
1221
1647
|
};
|
|
1222
1648
|
/**
|
|
1223
1649
|
* The TableBuilder class provides a fluent interface for defining
|
|
@@ -1230,6 +1656,7 @@ var TableBuilder = class {
|
|
|
1230
1656
|
constructor() {
|
|
1231
1657
|
this.columns = [];
|
|
1232
1658
|
this.dropColumnNames = [];
|
|
1659
|
+
this.changeColumnNames = /* @__PURE__ */ new Set();
|
|
1233
1660
|
this.indexes = [];
|
|
1234
1661
|
this.foreignKeys = [];
|
|
1235
1662
|
this.compositeUniqueConstraints = [];
|
|
@@ -1419,6 +1846,30 @@ var TableBuilder = class {
|
|
|
1419
1846
|
return this.column(name, "dateTime", options);
|
|
1420
1847
|
}
|
|
1421
1848
|
/**
|
|
1849
|
+
* Defines a database-computed column (`GENERATED ALWAYS AS (…) STORED`). The
|
|
1850
|
+
* expression may be a raw SQL string or an expression-builder factory, and must
|
|
1851
|
+
* be immutable and reference only the row's own columns. Combine with
|
|
1852
|
+
* {@link index} to index the generated value.
|
|
1853
|
+
*
|
|
1854
|
+
* @example
|
|
1855
|
+
* table.generated('category', "case when metadata->>'kind' = 'a' then 'x' else 'y' end", {
|
|
1856
|
+
* type: 'text',
|
|
1857
|
+
* })
|
|
1858
|
+
* table.generated('total', (e) => e.col('price').times(e.col('quantity')), { type: 'integer' })
|
|
1859
|
+
*
|
|
1860
|
+
* @param name The generated column name.
|
|
1861
|
+
* @param expression The SQL expression string, or a builder factory.
|
|
1862
|
+
* @param options Column type (default `text`), `stored` flag, and nullability.
|
|
1863
|
+
* @returns
|
|
1864
|
+
*/
|
|
1865
|
+
generated(name, expression, options = {}) {
|
|
1866
|
+
return this.column(name, options.type ?? "text", {
|
|
1867
|
+
generatedExpression: resolveGeneratedExpression(expression),
|
|
1868
|
+
generatedStored: options.stored ?? true,
|
|
1869
|
+
nullable: options.nullable
|
|
1870
|
+
});
|
|
1871
|
+
}
|
|
1872
|
+
/**
|
|
1422
1873
|
* Defines colonns for a polymorphic relationship in the table.
|
|
1423
1874
|
*
|
|
1424
1875
|
* @param name The base name for the polymorphic relationship columns.
|
|
@@ -1543,6 +1994,24 @@ var TableBuilder = class {
|
|
|
1543
1994
|
return this;
|
|
1544
1995
|
}
|
|
1545
1996
|
/**
|
|
1997
|
+
* Marks a (re)defined column as a change to an existing column rather than an
|
|
1998
|
+
* addition. Use it at the end of a normal column chain inside `alterTable` to
|
|
1999
|
+
* redefine the column's type, nullability, default, or enum values in place:
|
|
2000
|
+
*
|
|
2001
|
+
* ```ts
|
|
2002
|
+
* table.string('status').default('active').change()
|
|
2003
|
+
* table.enum('role', ['admin', 'user', 'guest']).change()
|
|
2004
|
+
* ```
|
|
2005
|
+
*
|
|
2006
|
+
* @param columnName Optional explicit column name. When omitted, applies to the latest defined column.
|
|
2007
|
+
* @returns The current TableBuilder instance for chaining.
|
|
2008
|
+
*/
|
|
2009
|
+
change(columnName) {
|
|
2010
|
+
const column = this.resolveColumn(columnName);
|
|
2011
|
+
this.changeColumnNames.add(column.name);
|
|
2012
|
+
return this;
|
|
2013
|
+
}
|
|
2014
|
+
/**
|
|
1546
2015
|
* Marks a column as nullable.
|
|
1547
2016
|
*
|
|
1548
2017
|
* @param columnName Optional explicit column name. When omitted, applies to the latest defined column.
|
|
@@ -1651,7 +2120,18 @@ var TableBuilder = class {
|
|
|
1651
2120
|
* @returns
|
|
1652
2121
|
*/
|
|
1653
2122
|
getColumns() {
|
|
1654
|
-
return this.columns.map((column) => ({
|
|
2123
|
+
return this.columns.filter((column) => !this.changeColumnNames.has(column.name)).map((column) => ({
|
|
2124
|
+
...column,
|
|
2125
|
+
enumValues: column.enumValues ? [...column.enumValues] : void 0
|
|
2126
|
+
}));
|
|
2127
|
+
}
|
|
2128
|
+
/**
|
|
2129
|
+
* Returns a deep copy of the columns flagged for in-place change via `change()`.
|
|
2130
|
+
*
|
|
2131
|
+
* @returns
|
|
2132
|
+
*/
|
|
2133
|
+
getChangeColumns() {
|
|
2134
|
+
return this.columns.filter((column) => this.changeColumnNames.has(column.name)).map((column) => ({
|
|
1655
2135
|
...column,
|
|
1656
2136
|
enumValues: column.enumValues ? [...column.enumValues] : void 0
|
|
1657
2137
|
}));
|
|
@@ -1725,6 +2205,8 @@ var TableBuilder = class {
|
|
|
1725
2205
|
updatedAt: options.updatedAt,
|
|
1726
2206
|
precision: options.precision,
|
|
1727
2207
|
scale: options.scale,
|
|
2208
|
+
generatedExpression: options.generatedExpression,
|
|
2209
|
+
generatedStored: options.generatedStored,
|
|
1728
2210
|
primaryKeyGeneration: options.primaryKeyGeneration
|
|
1729
2211
|
});
|
|
1730
2212
|
const column = this.columns[this.columns.length - 1];
|
|
@@ -1873,6 +2355,7 @@ var SchemaBuilder = class SchemaBuilder {
|
|
|
1873
2355
|
type: "alterTable",
|
|
1874
2356
|
table,
|
|
1875
2357
|
addColumns: builder.getColumns(),
|
|
2358
|
+
changeColumns: builder.getChangeColumns(),
|
|
1876
2359
|
dropColumns: builder.getDropColumns(),
|
|
1877
2360
|
addIndexes: builder.getIndexes(),
|
|
1878
2361
|
addForeignKeys: builder.getForeignKeys(),
|
|
@@ -1927,6 +2410,10 @@ var SchemaBuilder = class SchemaBuilder {
|
|
|
1927
2410
|
...column,
|
|
1928
2411
|
enumValues: column.enumValues ? [...column.enumValues] : void 0
|
|
1929
2412
|
})),
|
|
2413
|
+
changeColumns: operation.changeColumns?.map((column) => ({
|
|
2414
|
+
...column,
|
|
2415
|
+
enumValues: column.enumValues ? [...column.enumValues] : void 0
|
|
2416
|
+
})),
|
|
1930
2417
|
dropColumns: [...operation.dropColumns],
|
|
1931
2418
|
addIndexes: operation.addIndexes.map((index) => ({
|
|
1932
2419
|
...index,
|
|
@@ -2103,6 +2590,10 @@ const buildFieldLine = (column) => {
|
|
|
2103
2590
|
const mapped = typeof column.map === "string" && column.map.trim().length > 0 ? ` @map("${column.map.replace(/"/g, "\\\"")}")` : "";
|
|
2104
2591
|
const updatedAt = column.updatedAt ? " @updatedAt" : "";
|
|
2105
2592
|
const nativeType = column.type === "decimal" ? ` @db.Decimal(${column.precision ?? 8}, ${column.scale ?? 2})` : "";
|
|
2593
|
+
if (column.generatedExpression) {
|
|
2594
|
+
const escaped = column.generatedExpression.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
2595
|
+
return ` ${column.name} ${scalar}${nullable}${unique} @default(dbgenerated("${escaped}"))${mapped}${nativeType}`;
|
|
2596
|
+
}
|
|
2106
2597
|
const defaultValue = column.type === "enum" ? formatEnumDefaultValue(column.default) : column.primaryKeyGeneration?.prismaDefault ?? formatDefaultValue(column.default);
|
|
2107
2598
|
const defaultSuffix = defaultValue ? ` ${defaultValue}` : "";
|
|
2108
2599
|
return ` ${column.name} ${scalar}${nullable}${primary}${unique}${defaultSuffix}${updatedAt}${mapped}${nativeType}`;
|
|
@@ -2431,11 +2922,18 @@ const applyCreateTableOperation = (schema, operation) => {
|
|
|
2431
2922
|
const applyAlterTableOperation = (schema, operation) => {
|
|
2432
2923
|
const model = findModelBlock(schema, operation.table);
|
|
2433
2924
|
if (!model) throw new ArkormException(`Prisma model for table [${operation.table}] was not found.`);
|
|
2434
|
-
const schemaWithEnums = ensureEnumBlocks(schema, operation.addColumns);
|
|
2925
|
+
const schemaWithEnums = ensureEnumBlocks(schema, [...operation.addColumns, ...operation.changeColumns ?? []]);
|
|
2435
2926
|
const refreshedModel = findModelBlock(schemaWithEnums, operation.table);
|
|
2436
2927
|
if (!refreshedModel) throw new ArkormException(`Prisma model for table [${operation.table}] was not found.`);
|
|
2437
2928
|
let block = refreshedModel.block;
|
|
2438
2929
|
const bodyLines = block.split("\n");
|
|
2930
|
+
(operation.changeColumns ?? []).forEach((column) => {
|
|
2931
|
+
const fieldLine = buildFieldLine(column);
|
|
2932
|
+
const columnRegex = new RegExp(`^\\s*${escapeRegex(column.name)}\\s+`);
|
|
2933
|
+
const index = bodyLines.findIndex((line) => columnRegex.test(line));
|
|
2934
|
+
if (index >= 0) bodyLines.splice(index, 1, fieldLine);
|
|
2935
|
+
else bodyLines.splice(Math.max(1, bodyLines.length - 1), 0, fieldLine);
|
|
2936
|
+
});
|
|
2439
2937
|
operation.dropColumns.forEach((column) => {
|
|
2440
2938
|
const columnRegex = new RegExp(`^\\s*${escapeRegex(column)}\\s+`);
|
|
2441
2939
|
for (let index = 0; index < bodyLines.length; index += 1) if (columnRegex.test(bodyLines[index])) {
|
|
@@ -2660,14 +3158,18 @@ const stripPrismaSchemaModelsAndEnums = (schema) => {
|
|
|
2660
3158
|
};
|
|
2661
3159
|
const applyMigrationToDatabase = async (adapter, migration) => {
|
|
2662
3160
|
if (!supportsDatabaseMigrationExecution(adapter)) throw new ArkormException("The configured adapter does not support database-backed migration execution.");
|
|
2663
|
-
const
|
|
3161
|
+
const instance = typeof migration === "function" ? new migration() : migration;
|
|
3162
|
+
const operations = await getMigrationPlan(instance, "up");
|
|
2664
3163
|
await adapter.executeSchemaOperations(operations);
|
|
3164
|
+
await instance.done?.("up");
|
|
2665
3165
|
return { operations };
|
|
2666
3166
|
};
|
|
2667
3167
|
const applyMigrationRollbackToDatabase = async (adapter, migration) => {
|
|
2668
3168
|
if (!supportsDatabaseMigrationExecution(adapter)) throw new ArkormException("The configured adapter does not support database-backed migration execution.");
|
|
2669
|
-
const
|
|
3169
|
+
const instance = typeof migration === "function" ? new migration() : migration;
|
|
3170
|
+
const operations = await getMigrationPlan(instance, "down");
|
|
2670
3171
|
await adapter.executeSchemaOperations(operations);
|
|
3172
|
+
await instance.done?.("down");
|
|
2671
3173
|
return { operations };
|
|
2672
3174
|
};
|
|
2673
3175
|
/**
|
|
@@ -5970,6 +6472,12 @@ var MorphToRelation = class extends Relation {
|
|
|
5970
6472
|
};
|
|
5971
6473
|
|
|
5972
6474
|
//#endregion
|
|
6475
|
+
Object.defineProperty(exports, 'AggregateExpression', {
|
|
6476
|
+
enumerable: true,
|
|
6477
|
+
get: function () {
|
|
6478
|
+
return AggregateExpression;
|
|
6479
|
+
}
|
|
6480
|
+
});
|
|
5973
6481
|
Object.defineProperty(exports, 'ArkormCollection', {
|
|
5974
6482
|
enumerable: true,
|
|
5975
6483
|
get: function () {
|
|
@@ -5994,12 +6502,24 @@ Object.defineProperty(exports, 'BelongsToRelation', {
|
|
|
5994
6502
|
return BelongsToRelation;
|
|
5995
6503
|
}
|
|
5996
6504
|
});
|
|
6505
|
+
Object.defineProperty(exports, 'CaseExpression', {
|
|
6506
|
+
enumerable: true,
|
|
6507
|
+
get: function () {
|
|
6508
|
+
return CaseExpression;
|
|
6509
|
+
}
|
|
6510
|
+
});
|
|
5997
6511
|
Object.defineProperty(exports, 'EnumBuilder', {
|
|
5998
6512
|
enumerable: true,
|
|
5999
6513
|
get: function () {
|
|
6000
6514
|
return EnumBuilder;
|
|
6001
6515
|
}
|
|
6002
6516
|
});
|
|
6517
|
+
Object.defineProperty(exports, 'Expression', {
|
|
6518
|
+
enumerable: true,
|
|
6519
|
+
get: function () {
|
|
6520
|
+
return Expression;
|
|
6521
|
+
}
|
|
6522
|
+
});
|
|
6003
6523
|
Object.defineProperty(exports, 'ForeignKeyBuilder', {
|
|
6004
6524
|
enumerable: true,
|
|
6005
6525
|
get: function () {
|
|
@@ -6030,6 +6550,12 @@ Object.defineProperty(exports, 'HasOneThroughRelation', {
|
|
|
6030
6550
|
return HasOneThroughRelation;
|
|
6031
6551
|
}
|
|
6032
6552
|
});
|
|
6553
|
+
Object.defineProperty(exports, 'JsonExpression', {
|
|
6554
|
+
enumerable: true,
|
|
6555
|
+
get: function () {
|
|
6556
|
+
return JsonExpression;
|
|
6557
|
+
}
|
|
6558
|
+
});
|
|
6033
6559
|
Object.defineProperty(exports, 'LengthAwarePaginator', {
|
|
6034
6560
|
enumerable: true,
|
|
6035
6561
|
get: function () {
|
|
@@ -6210,6 +6736,12 @@ Object.defineProperty(exports, 'applyOperationsToPrismaSchema', {
|
|
|
6210
6736
|
return applyOperationsToPrismaSchema;
|
|
6211
6737
|
}
|
|
6212
6738
|
});
|
|
6739
|
+
Object.defineProperty(exports, 'avg', {
|
|
6740
|
+
enumerable: true,
|
|
6741
|
+
get: function () {
|
|
6742
|
+
return avg;
|
|
6743
|
+
}
|
|
6744
|
+
});
|
|
6213
6745
|
Object.defineProperty(exports, 'awaitConfiguredModelsRegistration', {
|
|
6214
6746
|
enumerable: true,
|
|
6215
6747
|
get: function () {
|
|
@@ -6288,6 +6820,24 @@ Object.defineProperty(exports, 'buildUniqueConstraintLine', {
|
|
|
6288
6820
|
return buildUniqueConstraintLine;
|
|
6289
6821
|
}
|
|
6290
6822
|
});
|
|
6823
|
+
Object.defineProperty(exports, 'caseWhen', {
|
|
6824
|
+
enumerable: true,
|
|
6825
|
+
get: function () {
|
|
6826
|
+
return caseWhen;
|
|
6827
|
+
}
|
|
6828
|
+
});
|
|
6829
|
+
Object.defineProperty(exports, 'coalesce', {
|
|
6830
|
+
enumerable: true,
|
|
6831
|
+
get: function () {
|
|
6832
|
+
return coalesce;
|
|
6833
|
+
}
|
|
6834
|
+
});
|
|
6835
|
+
Object.defineProperty(exports, 'col', {
|
|
6836
|
+
enumerable: true,
|
|
6837
|
+
get: function () {
|
|
6838
|
+
return col;
|
|
6839
|
+
}
|
|
6840
|
+
});
|
|
6291
6841
|
Object.defineProperty(exports, 'computeMigrationChecksum', {
|
|
6292
6842
|
enumerable: true,
|
|
6293
6843
|
get: function () {
|
|
@@ -6300,6 +6850,12 @@ Object.defineProperty(exports, 'configureArkormRuntime', {
|
|
|
6300
6850
|
return configureArkormRuntime;
|
|
6301
6851
|
}
|
|
6302
6852
|
});
|
|
6853
|
+
Object.defineProperty(exports, 'count', {
|
|
6854
|
+
enumerable: true,
|
|
6855
|
+
get: function () {
|
|
6856
|
+
return count;
|
|
6857
|
+
}
|
|
6858
|
+
});
|
|
6303
6859
|
Object.defineProperty(exports, 'createEmptyAppliedMigrationsState', {
|
|
6304
6860
|
enumerable: true,
|
|
6305
6861
|
get: function () {
|
|
@@ -6384,6 +6940,12 @@ Object.defineProperty(exports, 'escapeRegex', {
|
|
|
6384
6940
|
return escapeRegex;
|
|
6385
6941
|
}
|
|
6386
6942
|
});
|
|
6943
|
+
Object.defineProperty(exports, 'expressionBuilder', {
|
|
6944
|
+
enumerable: true,
|
|
6945
|
+
get: function () {
|
|
6946
|
+
return expressionBuilder;
|
|
6947
|
+
}
|
|
6948
|
+
});
|
|
6387
6949
|
Object.defineProperty(exports, 'findAppliedMigration', {
|
|
6388
6950
|
enumerable: true,
|
|
6389
6951
|
get: function () {
|
|
@@ -6402,6 +6964,12 @@ Object.defineProperty(exports, 'findModelBlock', {
|
|
|
6402
6964
|
return findModelBlock;
|
|
6403
6965
|
}
|
|
6404
6966
|
});
|
|
6967
|
+
Object.defineProperty(exports, 'fn', {
|
|
6968
|
+
enumerable: true,
|
|
6969
|
+
get: function () {
|
|
6970
|
+
return fn;
|
|
6971
|
+
}
|
|
6972
|
+
});
|
|
6405
6973
|
Object.defineProperty(exports, 'formatDefaultValue', {
|
|
6406
6974
|
enumerable: true,
|
|
6407
6975
|
get: function () {
|
|
@@ -6420,6 +6988,12 @@ Object.defineProperty(exports, 'formatRelationAction', {
|
|
|
6420
6988
|
return formatRelationAction;
|
|
6421
6989
|
}
|
|
6422
6990
|
});
|
|
6991
|
+
Object.defineProperty(exports, 'fromExpressionNode', {
|
|
6992
|
+
enumerable: true,
|
|
6993
|
+
get: function () {
|
|
6994
|
+
return fromExpressionNode;
|
|
6995
|
+
}
|
|
6996
|
+
});
|
|
6423
6997
|
Object.defineProperty(exports, 'generateMigrationFile', {
|
|
6424
6998
|
enumerable: true,
|
|
6425
6999
|
get: function () {
|
|
@@ -6594,6 +7168,12 @@ Object.defineProperty(exports, 'isTransactionCapableClient', {
|
|
|
6594
7168
|
return isTransactionCapableClient;
|
|
6595
7169
|
}
|
|
6596
7170
|
});
|
|
7171
|
+
Object.defineProperty(exports, 'json', {
|
|
7172
|
+
enumerable: true,
|
|
7173
|
+
get: function () {
|
|
7174
|
+
return json;
|
|
7175
|
+
}
|
|
7176
|
+
});
|
|
6597
7177
|
Object.defineProperty(exports, 'loadArkormConfig', {
|
|
6598
7178
|
enumerable: true,
|
|
6599
7179
|
get: function () {
|
|
@@ -6636,12 +7216,30 @@ Object.defineProperty(exports, 'markMigrationRun', {
|
|
|
6636
7216
|
return markMigrationRun;
|
|
6637
7217
|
}
|
|
6638
7218
|
});
|
|
7219
|
+
Object.defineProperty(exports, 'max', {
|
|
7220
|
+
enumerable: true,
|
|
7221
|
+
get: function () {
|
|
7222
|
+
return max;
|
|
7223
|
+
}
|
|
7224
|
+
});
|
|
7225
|
+
Object.defineProperty(exports, 'min', {
|
|
7226
|
+
enumerable: true,
|
|
7227
|
+
get: function () {
|
|
7228
|
+
return min;
|
|
7229
|
+
}
|
|
7230
|
+
});
|
|
6639
7231
|
Object.defineProperty(exports, 'pad', {
|
|
6640
7232
|
enumerable: true,
|
|
6641
7233
|
get: function () {
|
|
6642
7234
|
return pad;
|
|
6643
7235
|
}
|
|
6644
7236
|
});
|
|
7237
|
+
Object.defineProperty(exports, 'raw', {
|
|
7238
|
+
enumerable: true,
|
|
7239
|
+
get: function () {
|
|
7240
|
+
return raw;
|
|
7241
|
+
}
|
|
7242
|
+
});
|
|
6645
7243
|
Object.defineProperty(exports, 'readAppliedMigrationsState', {
|
|
6646
7244
|
enumerable: true,
|
|
6647
7245
|
get: function () {
|
|
@@ -6732,6 +7330,12 @@ Object.defineProperty(exports, 'resolveEnumName', {
|
|
|
6732
7330
|
return resolveEnumName;
|
|
6733
7331
|
}
|
|
6734
7332
|
});
|
|
7333
|
+
Object.defineProperty(exports, 'resolveGeneratedExpression', {
|
|
7334
|
+
enumerable: true,
|
|
7335
|
+
get: function () {
|
|
7336
|
+
return resolveGeneratedExpression;
|
|
7337
|
+
}
|
|
7338
|
+
});
|
|
6735
7339
|
Object.defineProperty(exports, 'resolveMigrationClassName', {
|
|
6736
7340
|
enumerable: true,
|
|
6737
7341
|
get: function () {
|
|
@@ -6780,6 +7384,12 @@ Object.defineProperty(exports, 'stripPrismaSchemaModelsAndEnums', {
|
|
|
6780
7384
|
return stripPrismaSchemaModelsAndEnums;
|
|
6781
7385
|
}
|
|
6782
7386
|
});
|
|
7387
|
+
Object.defineProperty(exports, 'sum', {
|
|
7388
|
+
enumerable: true,
|
|
7389
|
+
get: function () {
|
|
7390
|
+
return sum;
|
|
7391
|
+
}
|
|
7392
|
+
});
|
|
6783
7393
|
Object.defineProperty(exports, 'supportsDatabaseCreation', {
|
|
6784
7394
|
enumerable: true,
|
|
6785
7395
|
get: function () {
|
|
@@ -6822,12 +7432,24 @@ Object.defineProperty(exports, 'toModelName', {
|
|
|
6822
7432
|
return toModelName;
|
|
6823
7433
|
}
|
|
6824
7434
|
});
|
|
7435
|
+
Object.defineProperty(exports, 'val', {
|
|
7436
|
+
enumerable: true,
|
|
7437
|
+
get: function () {
|
|
7438
|
+
return val;
|
|
7439
|
+
}
|
|
7440
|
+
});
|
|
6825
7441
|
Object.defineProperty(exports, 'validatePersistedMetadataFeaturesForMigrations', {
|
|
6826
7442
|
enumerable: true,
|
|
6827
7443
|
get: function () {
|
|
6828
7444
|
return validatePersistedMetadataFeaturesForMigrations;
|
|
6829
7445
|
}
|
|
6830
7446
|
});
|
|
7447
|
+
Object.defineProperty(exports, 'where', {
|
|
7448
|
+
enumerable: true,
|
|
7449
|
+
get: function () {
|
|
7450
|
+
return where;
|
|
7451
|
+
}
|
|
7452
|
+
});
|
|
6831
7453
|
Object.defineProperty(exports, 'writeAppliedMigrationsState', {
|
|
6832
7454
|
enumerable: true,
|
|
6833
7455
|
get: function () {
|