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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_relationship = require('../relationship-
|
|
2
|
+
const require_relationship = require('../relationship-IC-TAFyG.cjs');
|
|
3
3
|
|
|
4
4
|
exports.BelongsToManyRelation = require_relationship.BelongsToManyRelation;
|
|
5
5
|
exports.BelongsToRelation = require_relationship.BelongsToRelation;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $o as MorphToManyRelation, Qo as MorphToRelation, Zo as SetBasedEagerLoader, as as HasManyRelation, cs as BelongsToManyRelation, es as MorphOneRelation, is as HasManyThroughRelation, ls as Relation, ns as HasOneThroughRelation, os as BelongsToRelation, rs as HasOneRelation, ss as SingleResultRelation, ts as MorphManyRelation, us as RelationTableLoader } from "../index-DggXDBiD.cjs";
|
|
2
2
|
export { BelongsToManyRelation, BelongsToRelation, HasManyRelation, HasManyThroughRelation, HasOneRelation, HasOneThroughRelation, MorphManyRelation, MorphOneRelation, MorphToManyRelation, MorphToRelation, Relation, RelationTableLoader, SetBasedEagerLoader, SingleResultRelation };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $o as MorphToManyRelation, Qo as MorphToRelation, Zo as SetBasedEagerLoader, as as HasManyRelation, cs as BelongsToManyRelation, es as MorphOneRelation, is as HasManyThroughRelation, ls as Relation, ns as HasOneThroughRelation, os as BelongsToRelation, rs as HasOneRelation, ss as SingleResultRelation, ts as MorphManyRelation, us as RelationTableLoader } from "../index-DoqUdah-.mjs";
|
|
2
2
|
export { BelongsToManyRelation, BelongsToRelation, HasManyRelation, HasManyThroughRelation, HasOneRelation, HasOneThroughRelation, MorphManyRelation, MorphOneRelation, MorphToManyRelation, MorphToRelation, Relation, RelationTableLoader, SetBasedEagerLoader, SingleResultRelation };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $n as SetBasedEagerLoader, a as HasOneThroughRelation, c as HasManyRelation, d as BelongsToManyRelation, er as RelationTableLoader, f as Relation, i as MorphManyRelation, l as BelongsToRelation, n as MorphToManyRelation, o as HasOneRelation, r as MorphOneRelation, s as HasManyThroughRelation, t as MorphToRelation, u as SingleResultRelation } from "../relationship-CP1xbMOa.mjs";
|
|
2
2
|
|
|
3
3
|
export { BelongsToManyRelation, BelongsToRelation, HasManyRelation, HasManyThroughRelation, HasOneRelation, HasOneThroughRelation, MorphManyRelation, MorphOneRelation, MorphToManyRelation, MorphToRelation, Relation, RelationTableLoader, SetBasedEagerLoader, SingleResultRelation };
|
|
@@ -1098,6 +1098,423 @@ var PrimaryKeyGenerationPlanner = class {
|
|
|
1098
1098
|
}
|
|
1099
1099
|
};
|
|
1100
1100
|
|
|
1101
|
+
//#endregion
|
|
1102
|
+
//#region src/Expression.ts
|
|
1103
|
+
/**
|
|
1104
|
+
* A composable SQL expression. Instances are immutable — every operator returns a
|
|
1105
|
+
* new expression — and are accepted by `select`, `where`, `groupBy`, `orderBy`,
|
|
1106
|
+
* `having`, and the aggregate helpers. Adapters compile the underlying node tree.
|
|
1107
|
+
*/
|
|
1108
|
+
var Expression = class Expression {
|
|
1109
|
+
/**
|
|
1110
|
+
* Type guard for values that came out of the expression builder.
|
|
1111
|
+
*/
|
|
1112
|
+
static isExpression(value) {
|
|
1113
|
+
return value instanceof Expression;
|
|
1114
|
+
}
|
|
1115
|
+
eq(value) {
|
|
1116
|
+
return binary("=", this, coerceValue(value));
|
|
1117
|
+
}
|
|
1118
|
+
ne(value) {
|
|
1119
|
+
return binary("!=", this, coerceValue(value));
|
|
1120
|
+
}
|
|
1121
|
+
gt(value) {
|
|
1122
|
+
return binary(">", this, coerceValue(value));
|
|
1123
|
+
}
|
|
1124
|
+
gte(value) {
|
|
1125
|
+
return binary(">=", this, coerceValue(value));
|
|
1126
|
+
}
|
|
1127
|
+
lt(value) {
|
|
1128
|
+
return binary("<", this, coerceValue(value));
|
|
1129
|
+
}
|
|
1130
|
+
lte(value) {
|
|
1131
|
+
return binary("<=", this, coerceValue(value));
|
|
1132
|
+
}
|
|
1133
|
+
like(value) {
|
|
1134
|
+
return binary("like", this, coerceValue(value));
|
|
1135
|
+
}
|
|
1136
|
+
ilike(value) {
|
|
1137
|
+
return binary("ilike", this, coerceValue(value));
|
|
1138
|
+
}
|
|
1139
|
+
notLike(value) {
|
|
1140
|
+
return binary("not-like", this, coerceValue(value));
|
|
1141
|
+
}
|
|
1142
|
+
notIlike(value) {
|
|
1143
|
+
return binary("not-ilike", this, coerceValue(value));
|
|
1144
|
+
}
|
|
1145
|
+
in(values) {
|
|
1146
|
+
return new NodeExpression({
|
|
1147
|
+
kind: "in",
|
|
1148
|
+
operand: this.toExpressionNode(),
|
|
1149
|
+
values: values.map((value) => coerceValue(value).toExpressionNode()),
|
|
1150
|
+
not: false
|
|
1151
|
+
});
|
|
1152
|
+
}
|
|
1153
|
+
notIn(values) {
|
|
1154
|
+
return new NodeExpression({
|
|
1155
|
+
kind: "in",
|
|
1156
|
+
operand: this.toExpressionNode(),
|
|
1157
|
+
values: values.map((value) => coerceValue(value).toExpressionNode()),
|
|
1158
|
+
not: true
|
|
1159
|
+
});
|
|
1160
|
+
}
|
|
1161
|
+
isNull() {
|
|
1162
|
+
return new NodeExpression({
|
|
1163
|
+
kind: "null-check",
|
|
1164
|
+
operand: this.toExpressionNode(),
|
|
1165
|
+
not: false
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
isNotNull() {
|
|
1169
|
+
return new NodeExpression({
|
|
1170
|
+
kind: "null-check",
|
|
1171
|
+
operand: this.toExpressionNode(),
|
|
1172
|
+
not: true
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
and(other) {
|
|
1176
|
+
return binary("and", this, other);
|
|
1177
|
+
}
|
|
1178
|
+
or(other) {
|
|
1179
|
+
return binary("or", this, other);
|
|
1180
|
+
}
|
|
1181
|
+
plus(value) {
|
|
1182
|
+
return binary("+", this, coerceValue(value));
|
|
1183
|
+
}
|
|
1184
|
+
minus(value) {
|
|
1185
|
+
return binary("-", this, coerceValue(value));
|
|
1186
|
+
}
|
|
1187
|
+
times(value) {
|
|
1188
|
+
return binary("*", this, coerceValue(value));
|
|
1189
|
+
}
|
|
1190
|
+
dividedBy(value) {
|
|
1191
|
+
return binary("/", this, coerceValue(value));
|
|
1192
|
+
}
|
|
1193
|
+
};
|
|
1194
|
+
/**
|
|
1195
|
+
* Concrete expression backed by a pre-built node.
|
|
1196
|
+
*/
|
|
1197
|
+
var NodeExpression = class extends Expression {
|
|
1198
|
+
constructor(node) {
|
|
1199
|
+
super();
|
|
1200
|
+
this.node = node;
|
|
1201
|
+
}
|
|
1202
|
+
toExpressionNode() {
|
|
1203
|
+
return this.node;
|
|
1204
|
+
}
|
|
1205
|
+
};
|
|
1206
|
+
/**
|
|
1207
|
+
* Fluent `CASE … WHEN … THEN … ELSE … END` builder. Immutable.
|
|
1208
|
+
*/
|
|
1209
|
+
var CaseExpression = class CaseExpression extends Expression {
|
|
1210
|
+
constructor(branches, elseExpr) {
|
|
1211
|
+
super();
|
|
1212
|
+
this.branches = branches;
|
|
1213
|
+
this.elseExpr = elseExpr;
|
|
1214
|
+
}
|
|
1215
|
+
when(condition, result) {
|
|
1216
|
+
return new CaseExpression([...this.branches, {
|
|
1217
|
+
when: condition,
|
|
1218
|
+
then: coerceValue(result)
|
|
1219
|
+
}], this.elseExpr);
|
|
1220
|
+
}
|
|
1221
|
+
else(result) {
|
|
1222
|
+
return new CaseExpression(this.branches, coerceValue(result));
|
|
1223
|
+
}
|
|
1224
|
+
toExpressionNode() {
|
|
1225
|
+
return {
|
|
1226
|
+
kind: "case",
|
|
1227
|
+
cases: this.branches.map((branch) => ({
|
|
1228
|
+
when: branch.when.toExpressionNode(),
|
|
1229
|
+
then: branch.then.toExpressionNode()
|
|
1230
|
+
})),
|
|
1231
|
+
else: this.elseExpr?.toExpressionNode()
|
|
1232
|
+
};
|
|
1233
|
+
}
|
|
1234
|
+
};
|
|
1235
|
+
/**
|
|
1236
|
+
* JSON-path value extraction (`metadata ->> 'billType'`), with optional casts.
|
|
1237
|
+
*/
|
|
1238
|
+
var JsonExpression = class JsonExpression extends Expression {
|
|
1239
|
+
constructor(column, path, castTo) {
|
|
1240
|
+
super();
|
|
1241
|
+
this.column = column;
|
|
1242
|
+
this.path = path;
|
|
1243
|
+
this.castTo = castTo;
|
|
1244
|
+
}
|
|
1245
|
+
asText() {
|
|
1246
|
+
return new JsonExpression(this.column, this.path, "text");
|
|
1247
|
+
}
|
|
1248
|
+
asNumber() {
|
|
1249
|
+
return new JsonExpression(this.column, this.path, "number");
|
|
1250
|
+
}
|
|
1251
|
+
asBoolean() {
|
|
1252
|
+
return new JsonExpression(this.column, this.path, "boolean");
|
|
1253
|
+
}
|
|
1254
|
+
toExpressionNode() {
|
|
1255
|
+
return {
|
|
1256
|
+
kind: "json",
|
|
1257
|
+
column: this.column,
|
|
1258
|
+
path: this.path,
|
|
1259
|
+
cast: this.castTo
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
};
|
|
1263
|
+
/**
|
|
1264
|
+
* Aggregate expression (`sum`, `count`, `avg`, `min`, `max`) with optional filter.
|
|
1265
|
+
*/
|
|
1266
|
+
var AggregateExpression = class AggregateExpression extends Expression {
|
|
1267
|
+
constructor(fn, arg, options = {}) {
|
|
1268
|
+
super();
|
|
1269
|
+
this.fn = fn;
|
|
1270
|
+
this.arg = arg;
|
|
1271
|
+
this.options = options;
|
|
1272
|
+
}
|
|
1273
|
+
/**
|
|
1274
|
+
* Restricts the aggregate to rows matching `predicate` (`FILTER (WHERE …)`).
|
|
1275
|
+
*/
|
|
1276
|
+
filter(predicate) {
|
|
1277
|
+
return new AggregateExpression(this.fn, this.arg, {
|
|
1278
|
+
...this.options,
|
|
1279
|
+
filterExpr: predicate
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1282
|
+
distinct() {
|
|
1283
|
+
return new AggregateExpression(this.fn, this.arg, {
|
|
1284
|
+
...this.options,
|
|
1285
|
+
distinct: true
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
toExpressionNode() {
|
|
1289
|
+
return {
|
|
1290
|
+
kind: "aggregate",
|
|
1291
|
+
fn: this.fn,
|
|
1292
|
+
arg: this.arg?.toExpressionNode(),
|
|
1293
|
+
distinct: this.options.distinct,
|
|
1294
|
+
filter: this.options.filterExpr?.toExpressionNode()
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
};
|
|
1298
|
+
const binary = (operator, left, right) => new NodeExpression({
|
|
1299
|
+
kind: "binary",
|
|
1300
|
+
operator,
|
|
1301
|
+
left: left.toExpressionNode(),
|
|
1302
|
+
right: right.toExpressionNode()
|
|
1303
|
+
});
|
|
1304
|
+
/**
|
|
1305
|
+
* Coerces a raw value into a bound-literal expression; passes expressions through.
|
|
1306
|
+
*/
|
|
1307
|
+
const coerceValue = (value) => {
|
|
1308
|
+
if (value instanceof Expression) return value;
|
|
1309
|
+
return new NodeExpression({
|
|
1310
|
+
kind: "value",
|
|
1311
|
+
value
|
|
1312
|
+
});
|
|
1313
|
+
};
|
|
1314
|
+
/**
|
|
1315
|
+
* Coerces a bare string into a column reference; passes expressions through.
|
|
1316
|
+
*/
|
|
1317
|
+
const coerceColumn = (value) => {
|
|
1318
|
+
if (value instanceof Expression) return value;
|
|
1319
|
+
if (typeof value === "string") return col(value);
|
|
1320
|
+
return coerceValue(value);
|
|
1321
|
+
};
|
|
1322
|
+
/**
|
|
1323
|
+
* Rebuilds an {@link Expression} around an already-serialized node.
|
|
1324
|
+
*/
|
|
1325
|
+
const fromExpressionNode = (node) => new NodeExpression(node);
|
|
1326
|
+
/**
|
|
1327
|
+
* A typed column reference. Supports joined `table.column` syntax.
|
|
1328
|
+
*/
|
|
1329
|
+
const col = (name) => new NodeExpression({
|
|
1330
|
+
kind: "column",
|
|
1331
|
+
name
|
|
1332
|
+
});
|
|
1333
|
+
/**
|
|
1334
|
+
* A bound literal value (parameterized, never interpolated).
|
|
1335
|
+
*/
|
|
1336
|
+
const val = (value) => new NodeExpression({
|
|
1337
|
+
kind: "value",
|
|
1338
|
+
value
|
|
1339
|
+
});
|
|
1340
|
+
/**
|
|
1341
|
+
* Raw SQL escape hatch with positional `?` bindings.
|
|
1342
|
+
*/
|
|
1343
|
+
const raw = (sql, bindings = []) => new NodeExpression({
|
|
1344
|
+
kind: "raw",
|
|
1345
|
+
sql,
|
|
1346
|
+
bindings
|
|
1347
|
+
});
|
|
1348
|
+
/**
|
|
1349
|
+
* Starts a `CASE WHEN condition THEN result` expression.
|
|
1350
|
+
*/
|
|
1351
|
+
const caseWhen = (condition, result) => new CaseExpression([{
|
|
1352
|
+
when: condition,
|
|
1353
|
+
then: coerceValue(result)
|
|
1354
|
+
}]);
|
|
1355
|
+
/**
|
|
1356
|
+
* `COALESCE(a, b, …)` — first non-null argument. Bare strings are columns.
|
|
1357
|
+
*/
|
|
1358
|
+
const coalesce = (...args) => new NodeExpression({
|
|
1359
|
+
kind: "function",
|
|
1360
|
+
name: "coalesce",
|
|
1361
|
+
args: args.map((arg) => coerceColumn(arg).toExpressionNode())
|
|
1362
|
+
});
|
|
1363
|
+
/**
|
|
1364
|
+
* An arbitrary SQL function call. Bare-string arguments are treated as columns.
|
|
1365
|
+
*/
|
|
1366
|
+
const fn = (name, ...args) => new NodeExpression({
|
|
1367
|
+
kind: "function",
|
|
1368
|
+
name,
|
|
1369
|
+
args: args.map((arg) => coerceColumn(arg).toExpressionNode())
|
|
1370
|
+
});
|
|
1371
|
+
/**
|
|
1372
|
+
* JSON value extraction: `json('metadata', 'billType')` => `metadata ->> 'billType'`.
|
|
1373
|
+
*/
|
|
1374
|
+
const json = (column, ...path) => new JsonExpression(column, path.map(String));
|
|
1375
|
+
/**
|
|
1376
|
+
* `SUM(expr)`; a bare-string argument is treated as a column.
|
|
1377
|
+
*/
|
|
1378
|
+
const sum = (arg) => new AggregateExpression("sum", coerceColumn(arg));
|
|
1379
|
+
/**
|
|
1380
|
+
* `AVG(expr)`; a bare-string argument is treated as a column.
|
|
1381
|
+
*/
|
|
1382
|
+
const avg = (arg) => new AggregateExpression("avg", coerceColumn(arg));
|
|
1383
|
+
/**
|
|
1384
|
+
* `MIN(expr)`; a bare-string argument is treated as a column.
|
|
1385
|
+
*/
|
|
1386
|
+
const min = (arg) => new AggregateExpression("min", coerceColumn(arg));
|
|
1387
|
+
/**
|
|
1388
|
+
* `MAX(expr)`; a bare-string argument is treated as a column.
|
|
1389
|
+
*/
|
|
1390
|
+
const max = (arg) => new AggregateExpression("max", coerceColumn(arg));
|
|
1391
|
+
/**
|
|
1392
|
+
* `COUNT(expr)` — or `COUNT(*)` when called without an argument.
|
|
1393
|
+
*/
|
|
1394
|
+
const count = (arg) => new AggregateExpression("count", arg === void 0 ? void 0 : coerceColumn(arg));
|
|
1395
|
+
const EXPRESSION_OPERATORS = {
|
|
1396
|
+
"=": "=",
|
|
1397
|
+
"==": "=",
|
|
1398
|
+
"!=": "!=",
|
|
1399
|
+
"<>": "!=",
|
|
1400
|
+
">": ">",
|
|
1401
|
+
">=": ">=",
|
|
1402
|
+
"<": "<",
|
|
1403
|
+
"<=": "<=",
|
|
1404
|
+
like: "like",
|
|
1405
|
+
ilike: "ilike",
|
|
1406
|
+
"not like": "not-like",
|
|
1407
|
+
"not ilike": "not-ilike"
|
|
1408
|
+
};
|
|
1409
|
+
/**
|
|
1410
|
+
* Builds a comparison predicate: `where('createdAt', '>=', boundary)`. Handy as an
|
|
1411
|
+
* inline predicate for `caseWhen`, `having`, and aggregate `.filter(…)`.
|
|
1412
|
+
*/
|
|
1413
|
+
const where = (column, operator, value) => {
|
|
1414
|
+
const normalized = EXPRESSION_OPERATORS[operator];
|
|
1415
|
+
if (!normalized) throw new Error(`Unsupported expression operator [${operator}].`);
|
|
1416
|
+
return binary(normalized, col(column), coerceValue(value));
|
|
1417
|
+
};
|
|
1418
|
+
/**
|
|
1419
|
+
* The expression-builder namespace passed to `static computed` factories, so a
|
|
1420
|
+
* model can declare a virtual attribute as `category: (e) => e.coalesce(…)`.
|
|
1421
|
+
*/
|
|
1422
|
+
const expressionBuilder = {
|
|
1423
|
+
col,
|
|
1424
|
+
val,
|
|
1425
|
+
raw,
|
|
1426
|
+
caseWhen,
|
|
1427
|
+
coalesce,
|
|
1428
|
+
fn,
|
|
1429
|
+
json,
|
|
1430
|
+
sum,
|
|
1431
|
+
avg,
|
|
1432
|
+
min,
|
|
1433
|
+
max,
|
|
1434
|
+
count,
|
|
1435
|
+
where
|
|
1436
|
+
};
|
|
1437
|
+
|
|
1438
|
+
//#endregion
|
|
1439
|
+
//#region src/helpers/generated-column.ts
|
|
1440
|
+
/**
|
|
1441
|
+
* Resolves a generated-column expression into raw Postgres SQL. Generated columns
|
|
1442
|
+
* cannot carry bind parameters (they must be immutable), so literal values are
|
|
1443
|
+
* inlined and aggregates are rejected.
|
|
1444
|
+
*/
|
|
1445
|
+
const resolveGeneratedExpression = (expression) => {
|
|
1446
|
+
if (typeof expression === "string") return expression;
|
|
1447
|
+
return expressionNodeToSql(expression(expressionBuilder).toExpressionNode());
|
|
1448
|
+
};
|
|
1449
|
+
const quoteIdentifier = (name) => name.split(".").map((part) => `"${part.replace(/"/g, "\"\"")}"`).join(".");
|
|
1450
|
+
const quoteLiteral = (value) => {
|
|
1451
|
+
if (value === null || value === void 0) return "null";
|
|
1452
|
+
if (typeof value === "number" || typeof value === "bigint") return String(value);
|
|
1453
|
+
if (typeof value === "boolean") return value ? "true" : "false";
|
|
1454
|
+
if (value instanceof Date) return `'${value.toISOString()}'`;
|
|
1455
|
+
return `'${String(value).replace(/'/g, "''")}'`;
|
|
1456
|
+
};
|
|
1457
|
+
const BINARY_OPERATORS = {
|
|
1458
|
+
"=": "=",
|
|
1459
|
+
"!=": "!=",
|
|
1460
|
+
">": ">",
|
|
1461
|
+
">=": ">=",
|
|
1462
|
+
"<": "<",
|
|
1463
|
+
"<=": "<=",
|
|
1464
|
+
like: "like",
|
|
1465
|
+
ilike: "ilike",
|
|
1466
|
+
"not-like": "not like",
|
|
1467
|
+
"not-ilike": "not ilike",
|
|
1468
|
+
and: "and",
|
|
1469
|
+
or: "or",
|
|
1470
|
+
"+": "+",
|
|
1471
|
+
"-": "-",
|
|
1472
|
+
"*": "*",
|
|
1473
|
+
"/": "/"
|
|
1474
|
+
};
|
|
1475
|
+
const FUNCTION_NAME = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
1476
|
+
const jsonAccessorSql = (node) => {
|
|
1477
|
+
const base = `${quoteIdentifier(node.column)}::jsonb`;
|
|
1478
|
+
let accessor;
|
|
1479
|
+
if (node.path.length === 0) accessor = base;
|
|
1480
|
+
else if (node.path.length === 1) accessor = `(${base} ->> ${quoteLiteral(node.path[0])})`;
|
|
1481
|
+
else accessor = `(${base} #>> '{${node.path.join(",")}}'::text[])`;
|
|
1482
|
+
if (node.cast === "number") return `(${accessor})::numeric`;
|
|
1483
|
+
if (node.cast === "boolean") return `(${accessor})::boolean`;
|
|
1484
|
+
return accessor;
|
|
1485
|
+
};
|
|
1486
|
+
const expressionNodeToSql = (node) => {
|
|
1487
|
+
switch (node.kind) {
|
|
1488
|
+
case "column": return quoteIdentifier(node.name);
|
|
1489
|
+
case "value": return quoteLiteral(node.value);
|
|
1490
|
+
case "raw": return inlineRawSql(node.sql, node.bindings);
|
|
1491
|
+
case "json": return jsonAccessorSql(node);
|
|
1492
|
+
case "function":
|
|
1493
|
+
if (!FUNCTION_NAME.test(node.name)) throw new ArkormException(`Unsupported SQL function name [${node.name}].`);
|
|
1494
|
+
return `${node.name}(${node.args.map(expressionNodeToSql).join(", ")})`;
|
|
1495
|
+
case "case": return `case ${node.cases.map((branch) => `when ${expressionNodeToSql(branch.when)} then ${expressionNodeToSql(branch.then)}`).join(" ")}${node.else ? ` else ${expressionNodeToSql(node.else)}` : ""} end`;
|
|
1496
|
+
case "binary": {
|
|
1497
|
+
const operator = BINARY_OPERATORS[node.operator];
|
|
1498
|
+
return `(${expressionNodeToSql(node.left)} ${operator} ${expressionNodeToSql(node.right)})`;
|
|
1499
|
+
}
|
|
1500
|
+
case "in": {
|
|
1501
|
+
const values = node.values.map(expressionNodeToSql).join(", ");
|
|
1502
|
+
return `(${expressionNodeToSql(node.operand)} ${node.not ? "not in" : "in"} (${values}))`;
|
|
1503
|
+
}
|
|
1504
|
+
case "null-check": return `(${expressionNodeToSql(node.operand)} is ${node.not ? "not null" : "null"})`;
|
|
1505
|
+
case "aggregate": throw new ArkormException("Aggregate expressions are not allowed in generated columns.");
|
|
1506
|
+
default: throw new ArkormException(`Unsupported expression node [${node.kind}].`);
|
|
1507
|
+
}
|
|
1508
|
+
};
|
|
1509
|
+
const inlineRawSql = (sql, bindings) => {
|
|
1510
|
+
const segments = sql.split("?");
|
|
1511
|
+
if (segments.length !== bindings.length + 1) throw new ArkormException("Raw expression bindings do not match the number of placeholders.");
|
|
1512
|
+
return segments.reduce((accumulator, segment, index) => {
|
|
1513
|
+
const binding = index < bindings.length ? quoteLiteral(bindings[index]) : "";
|
|
1514
|
+
return accumulator + segment + binding;
|
|
1515
|
+
}, "");
|
|
1516
|
+
};
|
|
1517
|
+
|
|
1101
1518
|
//#endregion
|
|
1102
1519
|
//#region src/database/TableBuilder.ts
|
|
1103
1520
|
const PRISMA_ENUM_MEMBER_REGEX$1 = /^[A-Za-z][A-Za-z0-9_]*$/;
|
|
@@ -1190,6 +1607,15 @@ var EnumBuilder = class {
|
|
|
1190
1607
|
this.tableBuilder.map(name, this.columnName);
|
|
1191
1608
|
return this;
|
|
1192
1609
|
}
|
|
1610
|
+
/**
|
|
1611
|
+
* Marks the enum column as an in-place change to an existing column.
|
|
1612
|
+
*
|
|
1613
|
+
* @returns
|
|
1614
|
+
*/
|
|
1615
|
+
change() {
|
|
1616
|
+
this.tableBuilder.change(this.columnName);
|
|
1617
|
+
return this;
|
|
1618
|
+
}
|
|
1193
1619
|
};
|
|
1194
1620
|
/**
|
|
1195
1621
|
* The TableBuilder class provides a fluent interface for defining
|
|
@@ -1202,6 +1628,7 @@ var TableBuilder = class {
|
|
|
1202
1628
|
constructor() {
|
|
1203
1629
|
this.columns = [];
|
|
1204
1630
|
this.dropColumnNames = [];
|
|
1631
|
+
this.changeColumnNames = /* @__PURE__ */ new Set();
|
|
1205
1632
|
this.indexes = [];
|
|
1206
1633
|
this.foreignKeys = [];
|
|
1207
1634
|
this.compositeUniqueConstraints = [];
|
|
@@ -1391,6 +1818,30 @@ var TableBuilder = class {
|
|
|
1391
1818
|
return this.column(name, "dateTime", options);
|
|
1392
1819
|
}
|
|
1393
1820
|
/**
|
|
1821
|
+
* Defines a database-computed column (`GENERATED ALWAYS AS (…) STORED`). The
|
|
1822
|
+
* expression may be a raw SQL string or an expression-builder factory, and must
|
|
1823
|
+
* be immutable and reference only the row's own columns. Combine with
|
|
1824
|
+
* {@link index} to index the generated value.
|
|
1825
|
+
*
|
|
1826
|
+
* @example
|
|
1827
|
+
* table.generated('category', "case when metadata->>'kind' = 'a' then 'x' else 'y' end", {
|
|
1828
|
+
* type: 'text',
|
|
1829
|
+
* })
|
|
1830
|
+
* table.generated('total', (e) => e.col('price').times(e.col('quantity')), { type: 'integer' })
|
|
1831
|
+
*
|
|
1832
|
+
* @param name The generated column name.
|
|
1833
|
+
* @param expression The SQL expression string, or a builder factory.
|
|
1834
|
+
* @param options Column type (default `text`), `stored` flag, and nullability.
|
|
1835
|
+
* @returns
|
|
1836
|
+
*/
|
|
1837
|
+
generated(name, expression, options = {}) {
|
|
1838
|
+
return this.column(name, options.type ?? "text", {
|
|
1839
|
+
generatedExpression: resolveGeneratedExpression(expression),
|
|
1840
|
+
generatedStored: options.stored ?? true,
|
|
1841
|
+
nullable: options.nullable
|
|
1842
|
+
});
|
|
1843
|
+
}
|
|
1844
|
+
/**
|
|
1394
1845
|
* Defines colonns for a polymorphic relationship in the table.
|
|
1395
1846
|
*
|
|
1396
1847
|
* @param name The base name for the polymorphic relationship columns.
|
|
@@ -1515,6 +1966,24 @@ var TableBuilder = class {
|
|
|
1515
1966
|
return this;
|
|
1516
1967
|
}
|
|
1517
1968
|
/**
|
|
1969
|
+
* Marks a (re)defined column as a change to an existing column rather than an
|
|
1970
|
+
* addition. Use it at the end of a normal column chain inside `alterTable` to
|
|
1971
|
+
* redefine the column's type, nullability, default, or enum values in place:
|
|
1972
|
+
*
|
|
1973
|
+
* ```ts
|
|
1974
|
+
* table.string('status').default('active').change()
|
|
1975
|
+
* table.enum('role', ['admin', 'user', 'guest']).change()
|
|
1976
|
+
* ```
|
|
1977
|
+
*
|
|
1978
|
+
* @param columnName Optional explicit column name. When omitted, applies to the latest defined column.
|
|
1979
|
+
* @returns The current TableBuilder instance for chaining.
|
|
1980
|
+
*/
|
|
1981
|
+
change(columnName) {
|
|
1982
|
+
const column = this.resolveColumn(columnName);
|
|
1983
|
+
this.changeColumnNames.add(column.name);
|
|
1984
|
+
return this;
|
|
1985
|
+
}
|
|
1986
|
+
/**
|
|
1518
1987
|
* Marks a column as nullable.
|
|
1519
1988
|
*
|
|
1520
1989
|
* @param columnName Optional explicit column name. When omitted, applies to the latest defined column.
|
|
@@ -1623,7 +2092,18 @@ var TableBuilder = class {
|
|
|
1623
2092
|
* @returns
|
|
1624
2093
|
*/
|
|
1625
2094
|
getColumns() {
|
|
1626
|
-
return this.columns.map((column) => ({
|
|
2095
|
+
return this.columns.filter((column) => !this.changeColumnNames.has(column.name)).map((column) => ({
|
|
2096
|
+
...column,
|
|
2097
|
+
enumValues: column.enumValues ? [...column.enumValues] : void 0
|
|
2098
|
+
}));
|
|
2099
|
+
}
|
|
2100
|
+
/**
|
|
2101
|
+
* Returns a deep copy of the columns flagged for in-place change via `change()`.
|
|
2102
|
+
*
|
|
2103
|
+
* @returns
|
|
2104
|
+
*/
|
|
2105
|
+
getChangeColumns() {
|
|
2106
|
+
return this.columns.filter((column) => this.changeColumnNames.has(column.name)).map((column) => ({
|
|
1627
2107
|
...column,
|
|
1628
2108
|
enumValues: column.enumValues ? [...column.enumValues] : void 0
|
|
1629
2109
|
}));
|
|
@@ -1697,6 +2177,8 @@ var TableBuilder = class {
|
|
|
1697
2177
|
updatedAt: options.updatedAt,
|
|
1698
2178
|
precision: options.precision,
|
|
1699
2179
|
scale: options.scale,
|
|
2180
|
+
generatedExpression: options.generatedExpression,
|
|
2181
|
+
generatedStored: options.generatedStored,
|
|
1700
2182
|
primaryKeyGeneration: options.primaryKeyGeneration
|
|
1701
2183
|
});
|
|
1702
2184
|
const column = this.columns[this.columns.length - 1];
|
|
@@ -1845,6 +2327,7 @@ var SchemaBuilder = class SchemaBuilder {
|
|
|
1845
2327
|
type: "alterTable",
|
|
1846
2328
|
table,
|
|
1847
2329
|
addColumns: builder.getColumns(),
|
|
2330
|
+
changeColumns: builder.getChangeColumns(),
|
|
1848
2331
|
dropColumns: builder.getDropColumns(),
|
|
1849
2332
|
addIndexes: builder.getIndexes(),
|
|
1850
2333
|
addForeignKeys: builder.getForeignKeys(),
|
|
@@ -1899,6 +2382,10 @@ var SchemaBuilder = class SchemaBuilder {
|
|
|
1899
2382
|
...column,
|
|
1900
2383
|
enumValues: column.enumValues ? [...column.enumValues] : void 0
|
|
1901
2384
|
})),
|
|
2385
|
+
changeColumns: operation.changeColumns?.map((column) => ({
|
|
2386
|
+
...column,
|
|
2387
|
+
enumValues: column.enumValues ? [...column.enumValues] : void 0
|
|
2388
|
+
})),
|
|
1902
2389
|
dropColumns: [...operation.dropColumns],
|
|
1903
2390
|
addIndexes: operation.addIndexes.map((index) => ({
|
|
1904
2391
|
...index,
|
|
@@ -2075,6 +2562,10 @@ const buildFieldLine = (column) => {
|
|
|
2075
2562
|
const mapped = typeof column.map === "string" && column.map.trim().length > 0 ? ` @map("${column.map.replace(/"/g, "\\\"")}")` : "";
|
|
2076
2563
|
const updatedAt = column.updatedAt ? " @updatedAt" : "";
|
|
2077
2564
|
const nativeType = column.type === "decimal" ? ` @db.Decimal(${column.precision ?? 8}, ${column.scale ?? 2})` : "";
|
|
2565
|
+
if (column.generatedExpression) {
|
|
2566
|
+
const escaped = column.generatedExpression.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
|
|
2567
|
+
return ` ${column.name} ${scalar}${nullable}${unique} @default(dbgenerated("${escaped}"))${mapped}${nativeType}`;
|
|
2568
|
+
}
|
|
2078
2569
|
const defaultValue = column.type === "enum" ? formatEnumDefaultValue(column.default) : column.primaryKeyGeneration?.prismaDefault ?? formatDefaultValue(column.default);
|
|
2079
2570
|
const defaultSuffix = defaultValue ? ` ${defaultValue}` : "";
|
|
2080
2571
|
return ` ${column.name} ${scalar}${nullable}${primary}${unique}${defaultSuffix}${updatedAt}${mapped}${nativeType}`;
|
|
@@ -2403,11 +2894,18 @@ const applyCreateTableOperation = (schema, operation) => {
|
|
|
2403
2894
|
const applyAlterTableOperation = (schema, operation) => {
|
|
2404
2895
|
const model = findModelBlock(schema, operation.table);
|
|
2405
2896
|
if (!model) throw new ArkormException(`Prisma model for table [${operation.table}] was not found.`);
|
|
2406
|
-
const schemaWithEnums = ensureEnumBlocks(schema, operation.addColumns);
|
|
2897
|
+
const schemaWithEnums = ensureEnumBlocks(schema, [...operation.addColumns, ...operation.changeColumns ?? []]);
|
|
2407
2898
|
const refreshedModel = findModelBlock(schemaWithEnums, operation.table);
|
|
2408
2899
|
if (!refreshedModel) throw new ArkormException(`Prisma model for table [${operation.table}] was not found.`);
|
|
2409
2900
|
let block = refreshedModel.block;
|
|
2410
2901
|
const bodyLines = block.split("\n");
|
|
2902
|
+
(operation.changeColumns ?? []).forEach((column) => {
|
|
2903
|
+
const fieldLine = buildFieldLine(column);
|
|
2904
|
+
const columnRegex = new RegExp(`^\\s*${escapeRegex(column.name)}\\s+`);
|
|
2905
|
+
const index = bodyLines.findIndex((line) => columnRegex.test(line));
|
|
2906
|
+
if (index >= 0) bodyLines.splice(index, 1, fieldLine);
|
|
2907
|
+
else bodyLines.splice(Math.max(1, bodyLines.length - 1), 0, fieldLine);
|
|
2908
|
+
});
|
|
2411
2909
|
operation.dropColumns.forEach((column) => {
|
|
2412
2910
|
const columnRegex = new RegExp(`^\\s*${escapeRegex(column)}\\s+`);
|
|
2413
2911
|
for (let index = 0; index < bodyLines.length; index += 1) if (columnRegex.test(bodyLines[index])) {
|
|
@@ -2632,14 +3130,18 @@ const stripPrismaSchemaModelsAndEnums = (schema) => {
|
|
|
2632
3130
|
};
|
|
2633
3131
|
const applyMigrationToDatabase = async (adapter, migration) => {
|
|
2634
3132
|
if (!supportsDatabaseMigrationExecution(adapter)) throw new ArkormException("The configured adapter does not support database-backed migration execution.");
|
|
2635
|
-
const
|
|
3133
|
+
const instance = typeof migration === "function" ? new migration() : migration;
|
|
3134
|
+
const operations = await getMigrationPlan(instance, "up");
|
|
2636
3135
|
await adapter.executeSchemaOperations(operations);
|
|
3136
|
+
await instance.done?.("up");
|
|
2637
3137
|
return { operations };
|
|
2638
3138
|
};
|
|
2639
3139
|
const applyMigrationRollbackToDatabase = async (adapter, migration) => {
|
|
2640
3140
|
if (!supportsDatabaseMigrationExecution(adapter)) throw new ArkormException("The configured adapter does not support database-backed migration execution.");
|
|
2641
|
-
const
|
|
3141
|
+
const instance = typeof migration === "function" ? new migration() : migration;
|
|
3142
|
+
const operations = await getMigrationPlan(instance, "down");
|
|
2642
3143
|
await adapter.executeSchemaOperations(operations);
|
|
3144
|
+
await instance.done?.("down");
|
|
2643
3145
|
return { operations };
|
|
2644
3146
|
};
|
|
2645
3147
|
/**
|
|
@@ -5942,4 +6444,4 @@ var MorphToRelation = class extends Relation {
|
|
|
5942
6444
|
};
|
|
5943
6445
|
|
|
5944
6446
|
//#endregion
|
|
5945
|
-
export { applyOperationsToPersistedColumnMappingsState as $, resolvePrismaType as $t, getRuntimePrismaClient as A,
|
|
6447
|
+
export { applyOperationsToPersistedColumnMappingsState as $, SetBasedEagerLoader as $n, resolvePrismaType as $t, getRuntimePrismaClient as A, where as An, buildInverseRelationLine as At, getRegisteredModels as B, getLatestAppliedMigrations as Bn, deriveRelationFieldName as Bt, getActiveTransactionClient as C, fromExpressionNode as Cn, applyMigrationRollbackToPrismaSchema as Ct, getRuntimeDebugHandler as D, raw as Dn, buildEnumBlock as Dt, getRuntimeClient as E, min as En, applyOperationsToPrismaSchema as Et, loadArkormConfig as F, computeMigrationChecksum as Fn, buildUniqueConstraintLine as Ft, loadModelsFrom as G, readAppliedMigrationsStateFromStore as Gn, formatDefaultValue as Gt, getRegisteredSeeders as H, markMigrationApplied as Hn, escapeRegex as Ht, resetArkormRuntimeForTests as I, createEmptyAppliedMigrationsState as In, createMigrationTimestamp as It, registerMigrations as J, supportsDatabaseMigrationState as Jn, generateMigrationFile as Jt, loadSeedersFrom as K, removeAppliedMigration as Kn, formatEnumDefaultValue as Kt, runArkormTransaction as L, deleteAppliedMigrationsStateFromStore as Ln, deriveCollectionFieldName as Lt, isDelegateLike as M, ForeignKeyBuilder as Mn, buildModelBlock as Mt, isQuerySchemaLike as N, buildMigrationIdentity as Nn, buildPrimaryKeyLine as Nt, getRuntimePaginationCurrentPageResolver as O, sum as On, buildFieldLine as Ot, isTransactionCapableClient as P, buildMigrationRunId as Pn, buildRelationLine as Pt, resetRuntimeRegistryForTests as Q, UnsupportedAdapterFeatureException as Qn, resolveMigrationClassName as Qt, getRegisteredFactories as R, findAppliedMigration as Rn, deriveInverseRelationAlias as Rt, getActiveTransactionAdapter as S, fn as Sn, applyMigrationRollbackToDatabase as St, getRuntimeAdapter as T, max as Tn, applyMigrationToPrismaSchema as Tt, loadFactoriesFrom as U, markMigrationRun as Un, findEnumBlock as Ut, getRegisteredPaths as V, isMigrationApplied as Vn, deriveSingularFieldName as Vt, loadMigrationsFrom as W, readAppliedMigrationsState as Wn, findModelBlock as Wt, registerPaths as X, writeAppliedMigrationsStateToStore as Xn, pad as Xt, registerModels as Y, writeAppliedMigrationsState as Yn, getMigrationPlan as Yt, registerSeeders as Z, RuntimeModuleLoader as Zn, resolveEnumName as Zt, bindAdapterToModels as _, caseWhen as _n, PRISMA_ENUM_REGEX as _t, HasOneThroughRelation as a, supportsDatabaseReset as an, getPersistedPrimaryKeyGeneration as at, emitRuntimeDebugEvent as b, count as bn, applyCreateTableOperation as bt, HasManyRelation as c, SchemaBuilder as cn, readPersistedColumnMappingsState as ct, BelongsToManyRelation as d, resolveGeneratedExpression as dn, resolveColumnMappingsFilePath as dt, runMigrationWithPrisma as en, RelationTableLoader as er, createEmptyPersistedColumnMappingsState as et, Relation as f, AggregateExpression as fn, resolvePersistedMetadataFeatures as ft, awaitConfiguredModelsRegistration as g, avg as gn, PRISMA_ENUM_MEMBER_REGEX as gt, URLDriver as h, JsonExpression as hn, writePersistedColumnMappingsState as ht, MorphManyRelation as i, supportsDatabaseMigrationExecution as in, getPersistedEnumTsType as it, getUserConfig as j, PrimaryKeyGenerationPlanner as jn, buildMigrationSource as jt, getRuntimePaginationURLDriverFactory as k, val as kn, buildIndexLine as kt, BelongsToRelation as l, EnumBuilder as ln, rebuildPersistedColumnMappingsState as lt, Paginator as m, Expression as mn, validatePersistedMetadataFeaturesForMigrations as mt, MorphToManyRelation as n, stripPrismaSchemaModelsAndEnums as nn, ArkormCollection as nr, getPersistedColumnMap as nt, HasOneRelation as o, toMigrationFileSlug as on, getPersistedTableMetadata as ot, LengthAwarePaginator as p, CaseExpression as pn, syncPersistedColumnMappingsFromState as pt, registerFactories as q, resolveMigrationStateFilePath as qn, formatRelationAction as qt, MorphOneRelation as r, supportsDatabaseCreation as rn, ArkormException as rr, getPersistedEnumMap as rt, HasManyThroughRelation as s, toModelName as sn, getPersistedTimestampColumns as st, MorphToRelation as t, runPrismaCommand as tn, RelationResolutionException as tr, deletePersistedColumnMappingsState as tt, SingleResultRelation as u, TableBuilder as un, resetPersistedColumnMappingsCache as ut, configureArkormRuntime as v, coalesce as vn, PRISMA_MODEL_REGEX as vt, getDefaultStubsPath as w, json as wn, applyMigrationToDatabase as wt, ensureArkormConfigLoading as x, expressionBuilder as xn, applyDropTableOperation as xt, defineConfig as y, col as yn, applyAlterTableOperation as yt, getRegisteredMigrations as z, getLastMigrationRun as zn, deriveRelationAlias as zt };
|