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
package/dist/index.cjs
CHANGED
|
@@ -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
|
let pg = require("pg");
|
|
4
4
|
let node_path = require("node:path");
|
|
5
5
|
let module$1 = require("module");
|
|
@@ -65,7 +65,8 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
65
65
|
rawWhere: true,
|
|
66
66
|
distinct: true,
|
|
67
67
|
groupBy: true,
|
|
68
|
-
joins: true
|
|
68
|
+
joins: true,
|
|
69
|
+
expressions: true
|
|
69
70
|
};
|
|
70
71
|
}
|
|
71
72
|
resolveConfiguredDatabaseName(connectionString) {
|
|
@@ -386,6 +387,13 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
386
387
|
}
|
|
387
388
|
buildSchemaColumnDefinition(table, column) {
|
|
388
389
|
const parts = [this.quoteIdentifier(column.map ?? column.name), this.resolveSchemaColumnType(table, column)];
|
|
390
|
+
if (column.generatedExpression) {
|
|
391
|
+
const storage = column.generatedStored === false ? "" : " stored";
|
|
392
|
+
parts.push(`generated always as (${column.generatedExpression})${storage}`);
|
|
393
|
+
if (column.unique) parts.push("unique");
|
|
394
|
+
if (!column.nullable && !column.primary) parts.push("not null");
|
|
395
|
+
return parts.join(" ");
|
|
396
|
+
}
|
|
389
397
|
if (this.shouldUseIdentity(column)) parts.push("generated by default as identity");
|
|
390
398
|
const defaultValue = this.resolveSchemaColumnDefault(column);
|
|
391
399
|
if (defaultValue && !this.shouldUseIdentity(column)) parts.push(`default ${defaultValue}`);
|
|
@@ -451,12 +459,60 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
451
459
|
const table = this.resolveMappedTable(operation.table);
|
|
452
460
|
await this.ensureEnumTypes(table, operation.addColumns, executor);
|
|
453
461
|
for (const column of operation.addColumns) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} add column if not exists ${this.buildSchemaColumnDefinition(table, column)}`, executor);
|
|
462
|
+
for (const column of operation.changeColumns ?? []) await this.executeChangeColumn(table, column, executor);
|
|
454
463
|
for (const column of operation.dropColumns) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} drop column if exists ${this.quoteIdentifier(column)}`, executor);
|
|
455
464
|
for (const foreignKey of operation.addForeignKeys ?? []) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} add ${this.buildSchemaForeignKeyConstraint(table, foreignKey, operation.addColumns)}`, executor);
|
|
456
465
|
if (operation.addPrimaryKey) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} add ${this.buildSchemaPrimaryKeyConstraint(table, operation.addPrimaryKey, operation.addColumns)}`, executor);
|
|
457
466
|
for (const constraint of operation.addUniqueConstraints ?? []) await this.executeRawStatement(`alter table ${this.quoteIdentifier(table)} add ${this.buildSchemaUniqueConstraint(table, constraint, operation.addColumns)}`, executor);
|
|
458
467
|
for (const index of operation.addIndexes ?? []) await this.executeRawStatement(this.buildSchemaIndexStatement(table, index, operation.addColumns), executor);
|
|
459
468
|
}
|
|
469
|
+
async enumTypeExists(enumName, executor) {
|
|
470
|
+
const result = await kysely.sql`
|
|
471
|
+
select exists(select 1 from pg_type where typname = ${enumName}) as exists
|
|
472
|
+
`.execute(executor);
|
|
473
|
+
return Boolean(result.rows[0]?.exists);
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Redefine an existing column in place using ALTER COLUMN statements: the
|
|
477
|
+
* column type (recreating the enum type when enum values change), nullability,
|
|
478
|
+
* default, and a conventionally-named unique constraint.
|
|
479
|
+
*
|
|
480
|
+
* @param table
|
|
481
|
+
* @param column
|
|
482
|
+
* @param executor
|
|
483
|
+
*/
|
|
484
|
+
async executeChangeColumn(table, column, executor) {
|
|
485
|
+
const quotedTable = this.quoteIdentifier(table);
|
|
486
|
+
const physicalName = column.map ?? column.name;
|
|
487
|
+
const physical = this.quoteIdentifier(physicalName);
|
|
488
|
+
if (column.type === "enum") {
|
|
489
|
+
const enumName = this.resolveSchemaEnumName(table, column);
|
|
490
|
+
const values = column.enumValues ?? [];
|
|
491
|
+
if (values.length === 0) throw new require_relationship.ArkormException(`Enum column [${column.name}] requires enum values to change its definition.`);
|
|
492
|
+
const quotedEnum = this.quoteIdentifier(enumName);
|
|
493
|
+
const enumLiterals = values.map((value) => this.quoteLiteral(value)).join(", ");
|
|
494
|
+
if (await this.enumTypeExists(enumName, executor)) {
|
|
495
|
+
const tempEnum = this.quoteIdentifier(`${enumName}__arkorm_change`);
|
|
496
|
+
await this.executeRawStatement(`drop type if exists ${tempEnum}`, executor);
|
|
497
|
+
await this.executeRawStatement(`alter type ${quotedEnum} rename to ${tempEnum}`, executor);
|
|
498
|
+
await this.executeRawStatement(`create type ${quotedEnum} as enum (${enumLiterals})`, executor);
|
|
499
|
+
await this.executeRawStatement(`alter table ${quotedTable} alter column ${physical} type ${quotedEnum} using ${physical}::text::${quotedEnum}`, executor);
|
|
500
|
+
await this.executeRawStatement(`drop type ${tempEnum}`, executor);
|
|
501
|
+
} else {
|
|
502
|
+
await this.executeRawStatement(`create type ${quotedEnum} as enum (${enumLiterals})`, executor);
|
|
503
|
+
await this.executeRawStatement(`alter table ${quotedTable} alter column ${physical} type ${quotedEnum} using ${physical}::text::${quotedEnum}`, executor);
|
|
504
|
+
}
|
|
505
|
+
} else {
|
|
506
|
+
const targetType = this.resolveSchemaColumnType(table, column);
|
|
507
|
+
await this.executeRawStatement(`alter table ${quotedTable} alter column ${physical} type ${targetType} using ${physical}::${targetType}`, executor);
|
|
508
|
+
}
|
|
509
|
+
await this.executeRawStatement(column.nullable ? `alter table ${quotedTable} alter column ${physical} drop not null` : `alter table ${quotedTable} alter column ${physical} set not null`, executor);
|
|
510
|
+
const defaultValue = this.resolveSchemaColumnDefault(column);
|
|
511
|
+
await this.executeRawStatement(defaultValue ? `alter table ${quotedTable} alter column ${physical} set default ${defaultValue}` : `alter table ${quotedTable} alter column ${physical} drop default`, executor);
|
|
512
|
+
const constraint = this.quoteIdentifier(`${table}_${physicalName}_key`);
|
|
513
|
+
await this.executeRawStatement(`alter table ${quotedTable} drop constraint if exists ${constraint}`, executor);
|
|
514
|
+
if (column.unique) await this.executeRawStatement(`alter table ${quotedTable} add constraint ${constraint} unique (${physical})`, executor);
|
|
515
|
+
}
|
|
460
516
|
async executeDropTableOperation(operation, executor) {
|
|
461
517
|
const table = this.resolveMappedTable(operation.table);
|
|
462
518
|
await this.executeRawStatement(`drop table if exists ${this.quoteIdentifier(table)} cascade`, executor);
|
|
@@ -595,11 +651,16 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
595
651
|
}
|
|
596
652
|
buildSelectList(target, columns) {
|
|
597
653
|
if (!columns || columns.length === 0) return kysely.sql.raw("*");
|
|
598
|
-
return kysely.sql.join(columns.map(({ column, alias, raw, wildcard }) => {
|
|
654
|
+
return kysely.sql.join(columns.map(({ column, alias, raw, wildcard, expression }) => {
|
|
599
655
|
if (wildcard) return kysely.sql.raw("*");
|
|
656
|
+
if (expression) {
|
|
657
|
+
const compiled = this.buildExpression(target, expression);
|
|
658
|
+
const resultAlias = alias ?? column;
|
|
659
|
+
return resultAlias ? kysely.sql`${compiled} as ${kysely.sql.id(resultAlias)}` : compiled;
|
|
660
|
+
}
|
|
600
661
|
if (raw) {
|
|
601
|
-
const
|
|
602
|
-
return alias ? kysely.sql`${
|
|
662
|
+
const rawExpression = kysely.sql.raw(column);
|
|
663
|
+
return alias ? kysely.sql`${rawExpression} as ${kysely.sql.id(alias)}` : rawExpression;
|
|
603
664
|
}
|
|
604
665
|
const mappedColumn = this.mapColumn(target, column);
|
|
605
666
|
const resultAlias = alias ?? column;
|
|
@@ -609,13 +670,18 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
609
670
|
}
|
|
610
671
|
buildOrderBy(target, orderBy) {
|
|
611
672
|
if (!orderBy || orderBy.length === 0) return kysely.sql``;
|
|
612
|
-
return kysely.sql` order by ${kysely.sql.join(orderBy.map(({ column, direction }) => {
|
|
613
|
-
return kysely.sql`${kysely.sql.ref(this.mapColumn(target, column))} ${kysely.sql.raw(direction === "desc" ? "desc" : "asc")}`;
|
|
673
|
+
return kysely.sql` order by ${kysely.sql.join(orderBy.map(({ column, direction, expression }) => {
|
|
674
|
+
return kysely.sql`${expression ? this.buildExpression(target, expression) : kysely.sql.ref(this.mapColumn(target, column))} ${kysely.sql.raw(direction === "desc" ? "desc" : "asc")}`;
|
|
614
675
|
}), kysely.sql`, `)}`;
|
|
615
676
|
}
|
|
616
677
|
buildGroupBy(target, groupBy) {
|
|
617
678
|
if (!groupBy || groupBy.length === 0) return kysely.sql``;
|
|
618
|
-
return kysely.sql` group by ${kysely.sql.join(groupBy.map((
|
|
679
|
+
return kysely.sql` group by ${kysely.sql.join(groupBy.map((item) => {
|
|
680
|
+
if (typeof item === "string") return kysely.sql.ref(this.mapColumn(target, item));
|
|
681
|
+
if ("alias" in item) return kysely.sql.ref(item.alias);
|
|
682
|
+
if ("expression" in item) return this.buildExpression(target, item.expression);
|
|
683
|
+
return this.buildRawExpressionFragment(item.raw.sql, item.raw.bindings ?? []);
|
|
684
|
+
}), kysely.sql`, `)}`;
|
|
619
685
|
}
|
|
620
686
|
buildHavingClause(target, having) {
|
|
621
687
|
if (!having) return kysely.sql``;
|
|
@@ -764,6 +830,96 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
764
830
|
const contains = kysely.sql`${accessor} @> ${jsonValue}::jsonb`;
|
|
765
831
|
return condition.not ? kysely.sql`not (${contains})` : contains;
|
|
766
832
|
}
|
|
833
|
+
/**
|
|
834
|
+
* Compiles a serialized {@link ExpressionNode} into a parameterized SQL fragment.
|
|
835
|
+
* Shared by expression-backed select columns, `group by`, `order by`, and any
|
|
836
|
+
* boolean expression used as a `where`/`having` predicate.
|
|
837
|
+
*
|
|
838
|
+
* @param target
|
|
839
|
+
* @param node
|
|
840
|
+
* @returns
|
|
841
|
+
*/
|
|
842
|
+
buildExpression(target, node) {
|
|
843
|
+
switch (node.kind) {
|
|
844
|
+
case "column": return this.buildExpressionColumn(target, node.name);
|
|
845
|
+
case "value": return kysely.sql`${node.value}`;
|
|
846
|
+
case "raw": return this.buildRawExpressionFragment(node.sql, node.bindings);
|
|
847
|
+
case "json": return this.buildJsonValueExpression(target, node);
|
|
848
|
+
case "function": {
|
|
849
|
+
const args = node.args.map((arg) => this.buildExpression(target, arg));
|
|
850
|
+
return kysely.sql`${kysely.sql.raw(this.sanitizeFunctionName(node.name))}(${kysely.sql.join(args, kysely.sql`, `)})`;
|
|
851
|
+
}
|
|
852
|
+
case "case": {
|
|
853
|
+
const branches = node.cases.map((branch) => kysely.sql`when ${this.buildExpression(target, branch.when)} then ${this.buildExpression(target, branch.then)}`);
|
|
854
|
+
const elseClause = node.else ? kysely.sql` else ${this.buildExpression(target, node.else)}` : kysely.sql``;
|
|
855
|
+
return kysely.sql`case ${kysely.sql.join(branches, kysely.sql` `)}${elseClause} end`;
|
|
856
|
+
}
|
|
857
|
+
case "binary": return this.buildBinaryExpression(target, node);
|
|
858
|
+
case "in": {
|
|
859
|
+
const operand = this.buildExpression(target, node.operand);
|
|
860
|
+
const values = node.values.map((value) => this.buildExpression(target, value));
|
|
861
|
+
const list = values.length > 0 ? kysely.sql.join(values, kysely.sql`, `) : kysely.sql`null`;
|
|
862
|
+
return node.not ? kysely.sql`(${operand} not in (${list}))` : kysely.sql`(${operand} in (${list}))`;
|
|
863
|
+
}
|
|
864
|
+
case "null-check": {
|
|
865
|
+
const operand = this.buildExpression(target, node.operand);
|
|
866
|
+
return node.not ? kysely.sql`(${operand} is not null)` : kysely.sql`(${operand} is null)`;
|
|
867
|
+
}
|
|
868
|
+
case "aggregate": return this.buildAggregateExpression(target, node);
|
|
869
|
+
default: throw new require_relationship.ArkormException(`Unsupported expression node [${node.kind}].`);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
buildExpressionColumn(target, name) {
|
|
873
|
+
if (name.includes(".")) return kysely.sql.ref(name);
|
|
874
|
+
return kysely.sql.ref(this.mapColumn(target, name));
|
|
875
|
+
}
|
|
876
|
+
buildBinaryExpression(target, node) {
|
|
877
|
+
const left = this.buildExpression(target, node.left);
|
|
878
|
+
const right = this.buildExpression(target, node.right);
|
|
879
|
+
switch (node.operator) {
|
|
880
|
+
case "like": return kysely.sql`(${left} like ${right})`;
|
|
881
|
+
case "ilike": return kysely.sql`(${left} ilike ${right})`;
|
|
882
|
+
case "not-like": return kysely.sql`(${left} not like ${right})`;
|
|
883
|
+
case "not-ilike": return kysely.sql`(${left} not ilike ${right})`;
|
|
884
|
+
case "and": return kysely.sql`(${left} and ${right})`;
|
|
885
|
+
case "or": return kysely.sql`(${left} or ${right})`;
|
|
886
|
+
default: return kysely.sql`(${left} ${kysely.sql.raw(node.operator)} ${right})`;
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
buildAggregateExpression(target, node) {
|
|
890
|
+
const argument = node.arg ? this.buildExpression(target, node.arg) : kysely.sql.raw("*");
|
|
891
|
+
const distinctKeyword = node.distinct ? kysely.sql`distinct ` : kysely.sql``;
|
|
892
|
+
let call = kysely.sql`${kysely.sql.raw(node.fn)}(${distinctKeyword}${argument})`;
|
|
893
|
+
if (node.filter) call = kysely.sql`${call} filter (where ${this.buildExpression(target, node.filter)})`;
|
|
894
|
+
if (node.fn === "sum" || node.fn === "avg") return kysely.sql`(${call})::double precision`;
|
|
895
|
+
if (node.fn === "count") return kysely.sql`(${call})::bigint`;
|
|
896
|
+
return call;
|
|
897
|
+
}
|
|
898
|
+
buildJsonValueExpression(target, node) {
|
|
899
|
+
const base = kysely.sql`${kysely.sql.ref(this.mapColumn(target, node.column))}::jsonb`;
|
|
900
|
+
let accessor;
|
|
901
|
+
if (node.path.length === 0) accessor = base;
|
|
902
|
+
else if (node.path.length === 1) accessor = kysely.sql`(${base} ->> ${node.path[0]})`;
|
|
903
|
+
else accessor = kysely.sql`(${base} #>> ${`{${node.path.join(",")}}`}::text[])`;
|
|
904
|
+
if (node.cast === "number") return kysely.sql`(${accessor})::numeric`;
|
|
905
|
+
if (node.cast === "boolean") return kysely.sql`(${accessor})::boolean`;
|
|
906
|
+
return accessor;
|
|
907
|
+
}
|
|
908
|
+
buildRawExpressionFragment(rawSql, bindings) {
|
|
909
|
+
const segments = rawSql.split("?");
|
|
910
|
+
if (segments.length !== bindings.length + 1) throw new require_relationship.ArkormException("Raw expression bindings do not match the number of placeholders.");
|
|
911
|
+
const parts = [];
|
|
912
|
+
segments.forEach((segment, index) => {
|
|
913
|
+
if (segment.length > 0) parts.push(kysely.sql.raw(this.quoteCamelCaseIdentifiers(segment)));
|
|
914
|
+
if (index < bindings.length) parts.push(kysely.sql`${bindings[index]}`);
|
|
915
|
+
});
|
|
916
|
+
if (parts.length === 0) return kysely.sql``;
|
|
917
|
+
return kysely.sql`${kysely.sql.join(parts, kysely.sql``)}`;
|
|
918
|
+
}
|
|
919
|
+
sanitizeFunctionName(name) {
|
|
920
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_.]*$/.test(name)) throw new require_relationship.ArkormException(`Unsupported SQL function name [${name}].`);
|
|
921
|
+
return name;
|
|
922
|
+
}
|
|
767
923
|
buildWhereCondition(target, condition) {
|
|
768
924
|
if (!condition) return kysely.sql`1 = 1`;
|
|
769
925
|
if (condition.type === "comparison") return this.buildComparisonCondition(target, condition);
|
|
@@ -773,6 +929,7 @@ var KyselyDatabaseAdapter = class KyselyDatabaseAdapter {
|
|
|
773
929
|
if (condition.type === "exists") return this.buildExistsCondition(condition);
|
|
774
930
|
if (condition.type === "full-text") return this.buildFullTextCondition(target, condition);
|
|
775
931
|
if (condition.type === "json") return this.buildJsonCondition(target, condition);
|
|
932
|
+
if (condition.type === "expression") return kysely.sql`${this.buildExpression(target, condition.expression)}`;
|
|
776
933
|
if (condition.type === "group") {
|
|
777
934
|
const group = condition;
|
|
778
935
|
const conditions = group.conditions.map((entry) => {
|
|
@@ -1645,6 +1802,7 @@ var PrismaDatabaseAdapter = class PrismaDatabaseAdapter {
|
|
|
1645
1802
|
rawWhere: false,
|
|
1646
1803
|
distinct: false,
|
|
1647
1804
|
groupBy: false,
|
|
1805
|
+
expressions: false,
|
|
1648
1806
|
returning: false
|
|
1649
1807
|
};
|
|
1650
1808
|
}
|
|
@@ -1680,6 +1838,14 @@ var PrismaDatabaseAdapter = class PrismaDatabaseAdapter {
|
|
|
1680
1838
|
}
|
|
1681
1839
|
toQuerySelect(columns) {
|
|
1682
1840
|
if (!columns || columns.length === 0) return void 0;
|
|
1841
|
+
const expressionColumn = columns.find((column) => column.expression);
|
|
1842
|
+
if (expressionColumn) throw new require_relationship.UnsupportedAdapterFeatureException("Expression select columns are not supported by the Prisma compatibility adapter; use a SQL-backed adapter.", {
|
|
1843
|
+
operation: "adapter.select",
|
|
1844
|
+
meta: {
|
|
1845
|
+
feature: "expressions",
|
|
1846
|
+
alias: expressionColumn.alias
|
|
1847
|
+
}
|
|
1848
|
+
});
|
|
1683
1849
|
const rawColumn = columns.find((column) => column.raw);
|
|
1684
1850
|
if (rawColumn) throw new require_relationship.UnsupportedAdapterFeatureException("Raw select expressions are not supported by the Prisma compatibility adapter; use a SQL-backed adapter or DB.raw().", {
|
|
1685
1851
|
operation: "adapter.select",
|
|
@@ -1697,6 +1863,10 @@ var PrismaDatabaseAdapter = class PrismaDatabaseAdapter {
|
|
|
1697
1863
|
}
|
|
1698
1864
|
toQueryOrderBy(orderBy) {
|
|
1699
1865
|
if (!orderBy || orderBy.length === 0) return void 0;
|
|
1866
|
+
if (orderBy.some((entry) => entry.expression)) throw new require_relationship.UnsupportedAdapterFeatureException("Order-by expressions are not supported by the Prisma compatibility adapter; use a SQL-backed adapter.", {
|
|
1867
|
+
operation: "adapter.select",
|
|
1868
|
+
meta: { feature: "expressions" }
|
|
1869
|
+
});
|
|
1700
1870
|
return orderBy.map((entry) => ({ [entry.column]: entry.direction }));
|
|
1701
1871
|
}
|
|
1702
1872
|
toComparisonWhere(condition) {
|
|
@@ -3326,13 +3496,22 @@ var Migration = class {
|
|
|
3326
3496
|
static {
|
|
3327
3497
|
this[MIGRATION_BRAND] = true;
|
|
3328
3498
|
}
|
|
3499
|
+
/**
|
|
3500
|
+
* Optional lifecycle hook invoked after the migration's schema operations
|
|
3501
|
+
* have been applied to the database, for either direction. Override it to run
|
|
3502
|
+
* extra logic such as seeding or data backfills once the schema is in place.
|
|
3503
|
+
*
|
|
3504
|
+
* @param direction The direction that just ran (`'up'` or `'down'`).
|
|
3505
|
+
*/
|
|
3506
|
+
done(_direction) {}
|
|
3329
3507
|
};
|
|
3330
3508
|
|
|
3331
3509
|
//#endregion
|
|
3332
3510
|
//#region src/cli/commands/MigrateCommand.ts
|
|
3333
3511
|
/**
|
|
3334
3512
|
* The MigrateCommand class implements the CLI command for applying migration
|
|
3335
|
-
* classes to the Prisma schema and running the Prisma workflow
|
|
3513
|
+
* classes to the database or Prisma schema and running the Prisma workflow when
|
|
3514
|
+
* using the Prisma compatibility driver.
|
|
3336
3515
|
*
|
|
3337
3516
|
* @author Legacy (3m1n3nc3)
|
|
3338
3517
|
* @since 0.1.0
|
|
@@ -3343,22 +3522,22 @@ var MigrateCommand = class extends _h3ravel_musket.Command {
|
|
|
3343
3522
|
this.signature = `migrate
|
|
3344
3523
|
{name? : Migration class or file name}
|
|
3345
3524
|
{--all : Run all migrations from the configured migrations directory}
|
|
3346
|
-
{--deploy : Use prisma migrate deploy instead of migrate dev}
|
|
3347
|
-
{--skip-generate : Skip prisma generate}
|
|
3525
|
+
{--deploy : Use prisma migrate deploy instead of migrate dev (Prisma compatibility driver only)}
|
|
3526
|
+
{--skip-generate : Skip prisma generate (Prisma compatibility driver only)}
|
|
3348
3527
|
{--skip-migrate : Skip prisma migrate command}
|
|
3349
3528
|
{--state-file= : Path to applied migration state file}
|
|
3350
|
-
{--schema= : Explicit prisma schema path}
|
|
3351
|
-
{--migration-name= : Name for prisma migrate dev}
|
|
3529
|
+
{--schema= : Explicit prisma schema path (Prisma compatibility driver only)}
|
|
3530
|
+
{--migration-name= : Name for prisma migrate dev (Prisma compatibility driver only)}
|
|
3352
3531
|
{--create-database : Create the configured database without prompting}
|
|
3353
3532
|
`;
|
|
3354
|
-
this.description = "Apply migration classes to schema.prisma and run Prisma workflow";
|
|
3533
|
+
this.description = "Apply migration classes to the database or schema.prisma and run Prisma workflow when using the Prisma compatibility driver";
|
|
3355
3534
|
}
|
|
3356
3535
|
/**
|
|
3357
3536
|
* Command handler for the migrate command.
|
|
3358
3537
|
* This method is responsible for orchestrating the migration
|
|
3359
3538
|
* process, including loading migration classes, applying them to
|
|
3360
|
-
* the Prisma schema, and running the appropriate Prisma commands
|
|
3361
|
-
* based on the provided options.
|
|
3539
|
+
* the the database or Prisma schema, and running the appropriate Prisma commands
|
|
3540
|
+
* when using the Prisma compatibility driver based on the provided options.
|
|
3362
3541
|
*
|
|
3363
3542
|
* @returns
|
|
3364
3543
|
*/
|
|
@@ -3567,10 +3746,10 @@ var MigrateFreshCommand = class extends _h3ravel_musket.Command {
|
|
|
3567
3746
|
constructor(..._args) {
|
|
3568
3747
|
super(..._args);
|
|
3569
3748
|
this.signature = `migrate:fresh
|
|
3570
|
-
{--skip-generate : Skip prisma generate}
|
|
3571
|
-
{--skip-migrate : Skip prisma database sync}
|
|
3749
|
+
{--skip-generate : Skip prisma generate (Prisma compatibility driver only)}
|
|
3750
|
+
{--skip-migrate : Skip prisma database sync (Prisma compatibility driver only)}
|
|
3572
3751
|
{--state-file= : Path to applied migration state file}
|
|
3573
|
-
{--schema= : Explicit prisma schema path}
|
|
3752
|
+
{--schema= : Explicit prisma schema path (Prisma compatibility driver only)}
|
|
3574
3753
|
{--create-database : Create the configured database without prompting}
|
|
3575
3754
|
`;
|
|
3576
3755
|
this.description = "Reset the database and rerun all migration classes";
|
|
@@ -3725,12 +3904,12 @@ var MigrateRollbackCommand = class extends _h3ravel_musket.Command {
|
|
|
3725
3904
|
this.signature = `migrate:rollback
|
|
3726
3905
|
{--step= : Number of latest applied migration classes to rollback}
|
|
3727
3906
|
{--dry-run : Preview rollback targets without applying changes}
|
|
3728
|
-
{--deploy : Use prisma migrate deploy instead of migrate dev}
|
|
3729
|
-
{--skip-generate : Skip prisma generate}
|
|
3730
|
-
{--skip-migrate : Skip prisma migrate command}
|
|
3907
|
+
{--deploy : Use prisma migrate deploy instead of migrate dev (Prisma compatibility driver only)}
|
|
3908
|
+
{--skip-generate : Skip prisma generate (Prisma compatibility driver only)}
|
|
3909
|
+
{--skip-migrate : Skip prisma migrate command (Prisma compatibility driver only)}
|
|
3731
3910
|
{--state-file= : Path to applied migration state file}
|
|
3732
|
-
{--schema= : Explicit prisma schema path}
|
|
3733
|
-
{--migration-name= : Name for prisma migrate dev}
|
|
3911
|
+
{--schema= : Explicit prisma schema path (Prisma compatibility driver only)}
|
|
3912
|
+
{--migration-name= : Name for prisma migrate dev (Prisma compatibility driver only)}
|
|
3734
3913
|
`;
|
|
3735
3914
|
this.description = "Rollback migration classes from schema.prisma and run Prisma workflow";
|
|
3736
3915
|
}
|
|
@@ -3745,7 +3924,7 @@ var MigrateRollbackCommand = class extends _h3ravel_musket.Command {
|
|
|
3745
3924
|
const useDatabaseMigrations = require_relationship.supportsDatabaseMigrationExecution(adapter);
|
|
3746
3925
|
const persistedFeatures = require_relationship.resolvePersistedMetadataFeatures(this.app.getConfig("features"));
|
|
3747
3926
|
let appliedState = await require_relationship.readAppliedMigrationsStateFromStore(adapter, stateFilePath);
|
|
3748
|
-
const stepOption = this.option("step");
|
|
3927
|
+
const stepOption = this.option("step", 1);
|
|
3749
3928
|
const stepCount = stepOption == null ? void 0 : Number(stepOption);
|
|
3750
3929
|
if (stepCount != null && (!Number.isFinite(stepCount) || stepCount <= 0 || !Number.isInteger(stepCount))) return void this.error("Error: --step must be a positive integer.");
|
|
3751
3930
|
const targets = stepCount ? require_relationship.getLatestAppliedMigrations(appliedState, stepCount) : (() => {
|
|
@@ -4420,14 +4599,34 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4420
4599
|
return Math.max(1, resolvedPage);
|
|
4421
4600
|
}
|
|
4422
4601
|
where(whereOrCallback) {
|
|
4602
|
+
if (whereOrCallback instanceof require_relationship.Expression) return this.appendExpressionCondition("AND", whereOrCallback);
|
|
4423
4603
|
if (typeof whereOrCallback === "function") return this.appendNestedWhere("AND", whereOrCallback);
|
|
4424
4604
|
return this.addLogicalWhere("AND", whereOrCallback);
|
|
4425
4605
|
}
|
|
4426
4606
|
orWhere(whereOrCallback) {
|
|
4607
|
+
if (whereOrCallback instanceof require_relationship.Expression) return this.appendExpressionCondition("OR", whereOrCallback);
|
|
4427
4608
|
if (typeof whereOrCallback === "function") return this.appendNestedWhere("OR", whereOrCallback);
|
|
4428
4609
|
return this.addLogicalWhere("OR", whereOrCallback);
|
|
4429
4610
|
}
|
|
4430
4611
|
/**
|
|
4612
|
+
* Appends a boolean {@link Expression} as a where predicate. When the query is
|
|
4613
|
+
* using the Prisma-like legacy where representation, the expression is merged in
|
|
4614
|
+
* as a structured condition alongside it.
|
|
4615
|
+
*/
|
|
4616
|
+
appendExpressionCondition(boolean, expression) {
|
|
4617
|
+
const condition = {
|
|
4618
|
+
type: "expression",
|
|
4619
|
+
expression: expression.toExpressionNode()
|
|
4620
|
+
};
|
|
4621
|
+
if (this.legacyWhere) {
|
|
4622
|
+
const existing = this.tryBuildQueryCondition(this.legacyWhere);
|
|
4623
|
+
this.legacyWhere = void 0;
|
|
4624
|
+
if (existing) this.queryWhere = existing;
|
|
4625
|
+
}
|
|
4626
|
+
this.appendQueryCondition(boolean, condition);
|
|
4627
|
+
return this;
|
|
4628
|
+
}
|
|
4629
|
+
/**
|
|
4431
4630
|
* Resolve a callback into a parenthesized group condition and append it.
|
|
4432
4631
|
*/
|
|
4433
4632
|
appendNestedWhere(boolean, callback) {
|
|
@@ -5077,15 +5276,17 @@ var QueryBuilder = class QueryBuilder {
|
|
|
5077
5276
|
whereIn(key, values) {
|
|
5078
5277
|
return this.where({ [key]: { in: values } });
|
|
5079
5278
|
}
|
|
5080
|
-
|
|
5081
|
-
* Adds an orderBy clause to the query. This will overwrite any existing orderBy clause.
|
|
5082
|
-
*
|
|
5083
|
-
* @param orderBy
|
|
5084
|
-
* @returns
|
|
5085
|
-
*/
|
|
5086
|
-
orderBy(orderBy) {
|
|
5279
|
+
orderBy(orderByOrExpression, direction = "asc") {
|
|
5087
5280
|
this.randomOrderEnabled = false;
|
|
5088
|
-
|
|
5281
|
+
if (orderByOrExpression instanceof require_relationship.Expression) {
|
|
5282
|
+
this.queryOrderBy = [...this.queryOrderBy ?? [], {
|
|
5283
|
+
column: "",
|
|
5284
|
+
direction,
|
|
5285
|
+
expression: orderByOrExpression.toExpressionNode()
|
|
5286
|
+
}];
|
|
5287
|
+
return this;
|
|
5288
|
+
}
|
|
5289
|
+
const normalized = this.normalizeQueryOrderBy(orderByOrExpression);
|
|
5089
5290
|
if (!normalized) throw new require_relationship.UnsupportedAdapterFeatureException("Order clauses must use Arkorm-normalizable column directions.", {
|
|
5090
5291
|
operation: "orderBy",
|
|
5091
5292
|
model: this.model.name
|
|
@@ -5094,6 +5295,28 @@ var QueryBuilder = class QueryBuilder {
|
|
|
5094
5295
|
return this;
|
|
5095
5296
|
}
|
|
5096
5297
|
/**
|
|
5298
|
+
* Appends a raw SQL `order by` fragment (with positional `?` bindings), useful
|
|
5299
|
+
* for ordering by a computed expression the builder does not model directly.
|
|
5300
|
+
*
|
|
5301
|
+
* @param sql
|
|
5302
|
+
* @param bindings
|
|
5303
|
+
* @param direction
|
|
5304
|
+
* @returns
|
|
5305
|
+
*/
|
|
5306
|
+
orderByRaw(sql, bindings = [], direction = "asc") {
|
|
5307
|
+
this.randomOrderEnabled = false;
|
|
5308
|
+
this.queryOrderBy = [...this.queryOrderBy ?? [], {
|
|
5309
|
+
column: "",
|
|
5310
|
+
direction,
|
|
5311
|
+
expression: {
|
|
5312
|
+
kind: "raw",
|
|
5313
|
+
sql,
|
|
5314
|
+
bindings
|
|
5315
|
+
}
|
|
5316
|
+
}];
|
|
5317
|
+
return this;
|
|
5318
|
+
}
|
|
5319
|
+
/**
|
|
5097
5320
|
* Puts the query results in random order.
|
|
5098
5321
|
*
|
|
5099
5322
|
* @returns
|
|
@@ -5459,12 +5682,6 @@ var QueryBuilder = class QueryBuilder {
|
|
|
5459
5682
|
pipe(callback) {
|
|
5460
5683
|
return callback(this);
|
|
5461
5684
|
}
|
|
5462
|
-
/**
|
|
5463
|
-
* Adds a select clause to the query. This will overwrite any existing select clause.
|
|
5464
|
-
*
|
|
5465
|
-
* @param select
|
|
5466
|
-
* @returns
|
|
5467
|
-
*/
|
|
5468
5685
|
select(select) {
|
|
5469
5686
|
const normalized = this.normalizeQuerySelect(select);
|
|
5470
5687
|
if (normalized === null) throw new require_relationship.UnsupportedAdapterFeatureException("Select clauses must use Arkorm-normalizable column projections.", {
|
|
@@ -5474,12 +5691,6 @@ var QueryBuilder = class QueryBuilder {
|
|
|
5474
5691
|
this.querySelect = normalized;
|
|
5475
5692
|
return this;
|
|
5476
5693
|
}
|
|
5477
|
-
/**
|
|
5478
|
-
* Appends columns or expressions to the existing select clause.
|
|
5479
|
-
*
|
|
5480
|
-
* @param select
|
|
5481
|
-
* @returns
|
|
5482
|
-
*/
|
|
5483
5694
|
addSelect(select) {
|
|
5484
5695
|
const normalized = this.normalizeQuerySelect(select);
|
|
5485
5696
|
if (normalized === null) throw new require_relationship.UnsupportedAdapterFeatureException("Select clauses must use Arkorm-normalizable column projections.", {
|
|
@@ -5503,6 +5714,8 @@ var QueryBuilder = class QueryBuilder {
|
|
|
5503
5714
|
return this;
|
|
5504
5715
|
}
|
|
5505
5716
|
groupBy(...columns) {
|
|
5717
|
+
const first = columns[0];
|
|
5718
|
+
if (columns.length === 1 && this.isGroupByAggregateSpec(first)) return this.executeGroupByAggregate(first);
|
|
5506
5719
|
const normalized = Array.isArray(columns[0]) ? columns[0] : columns;
|
|
5507
5720
|
if (normalized.length === 0) throw new QueryConstraintException("groupBy requires at least one column.", {
|
|
5508
5721
|
operation: "groupBy",
|
|
@@ -5511,6 +5724,109 @@ var QueryBuilder = class QueryBuilder {
|
|
|
5511
5724
|
this.queryGroupBy = [...normalized];
|
|
5512
5725
|
return this;
|
|
5513
5726
|
}
|
|
5727
|
+
/**
|
|
5728
|
+
* Appends a raw SQL `group by` fragment (with positional `?` bindings), mirroring
|
|
5729
|
+
* `whereRaw`/`havingRaw`. Combines with any columns/expressions already grouped.
|
|
5730
|
+
*
|
|
5731
|
+
* @param sql
|
|
5732
|
+
* @param bindings
|
|
5733
|
+
* @returns
|
|
5734
|
+
*/
|
|
5735
|
+
groupByRaw(sql, bindings = []) {
|
|
5736
|
+
this.queryGroupBy = [...this.queryGroupBy ?? [], { raw: {
|
|
5737
|
+
sql,
|
|
5738
|
+
bindings
|
|
5739
|
+
} }];
|
|
5740
|
+
return this;
|
|
5741
|
+
}
|
|
5742
|
+
/**
|
|
5743
|
+
* Resolves the recorded group-by sources into adapter {@link QueryGroupByItem}s.
|
|
5744
|
+
* A bare string that matches a select-column alias is expanded to that column's
|
|
5745
|
+
* underlying expression (group-by-alias); otherwise it is treated as a column.
|
|
5746
|
+
*/
|
|
5747
|
+
buildGroupByItems(selectColumns) {
|
|
5748
|
+
if (!this.queryGroupBy || this.queryGroupBy.length === 0) return void 0;
|
|
5749
|
+
const expressionAliases = /* @__PURE__ */ new Map();
|
|
5750
|
+
selectColumns?.forEach((column) => {
|
|
5751
|
+
if (column.expression && column.alias) expressionAliases.set(JSON.stringify(column.expression), column.alias);
|
|
5752
|
+
});
|
|
5753
|
+
const aliasNames = new Set(expressionAliases.values());
|
|
5754
|
+
return this.queryGroupBy.map((source) => {
|
|
5755
|
+
if (source instanceof require_relationship.Expression) {
|
|
5756
|
+
const node = source.toExpressionNode();
|
|
5757
|
+
const alias = expressionAliases.get(JSON.stringify(node));
|
|
5758
|
+
return alias ? { alias } : { expression: node };
|
|
5759
|
+
}
|
|
5760
|
+
if (typeof source === "object") return { raw: source.raw };
|
|
5761
|
+
return aliasNames.has(source) ? { alias: source } : source;
|
|
5762
|
+
});
|
|
5763
|
+
}
|
|
5764
|
+
isGroupByAggregateSpec(value) {
|
|
5765
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof require_relationship.Expression) && Array.isArray(value.by);
|
|
5766
|
+
}
|
|
5767
|
+
/**
|
|
5768
|
+
* Executes the query and returns plain, un-hydrated rows keyed by their select
|
|
5769
|
+
* alias — the natural shape for `select` + `groupBy` aggregate reports. Pass a
|
|
5770
|
+
* row type to describe the projection.
|
|
5771
|
+
*
|
|
5772
|
+
* @returns
|
|
5773
|
+
*/
|
|
5774
|
+
async getRows() {
|
|
5775
|
+
return await this.executeReadRows();
|
|
5776
|
+
}
|
|
5777
|
+
/**
|
|
5778
|
+
* Runs a Prisma-style grouped aggregate and returns typed rows shaped as
|
|
5779
|
+
* `{ <by columns>, _sum, _avg, _min, _max, _count }`.
|
|
5780
|
+
*/
|
|
5781
|
+
async executeGroupByAggregate(spec) {
|
|
5782
|
+
const selectMap = {};
|
|
5783
|
+
spec.by.forEach((column) => {
|
|
5784
|
+
selectMap[column] = true;
|
|
5785
|
+
});
|
|
5786
|
+
const aggregates = [];
|
|
5787
|
+
const register = (group, factory, map, numeric) => {
|
|
5788
|
+
Object.keys(map).forEach((column) => {
|
|
5789
|
+
if (!map[column]) return;
|
|
5790
|
+
const alias = `${group}_${column}`;
|
|
5791
|
+
selectMap[alias] = factory(column);
|
|
5792
|
+
aggregates.push({
|
|
5793
|
+
group,
|
|
5794
|
+
column,
|
|
5795
|
+
alias,
|
|
5796
|
+
numeric
|
|
5797
|
+
});
|
|
5798
|
+
});
|
|
5799
|
+
};
|
|
5800
|
+
if (spec._sum) register("_sum", (column) => require_relationship.sum(column), spec._sum, true);
|
|
5801
|
+
if (spec._avg) register("_avg", (column) => require_relationship.avg(column), spec._avg, true);
|
|
5802
|
+
if (spec._min) register("_min", (column) => require_relationship.min(column), spec._min, false);
|
|
5803
|
+
if (spec._max) register("_max", (column) => require_relationship.max(column), spec._max, false);
|
|
5804
|
+
let countAllAlias;
|
|
5805
|
+
if (spec._count === true) {
|
|
5806
|
+
countAllAlias = "_count_all";
|
|
5807
|
+
selectMap[countAllAlias] = require_relationship.count();
|
|
5808
|
+
} else if (spec._count) register("_count", (column) => require_relationship.count(column), spec._count, true);
|
|
5809
|
+
this.select(selectMap);
|
|
5810
|
+
this.groupBy(spec.by);
|
|
5811
|
+
return (await this.getRows()).map((row) => {
|
|
5812
|
+
const result = {};
|
|
5813
|
+
spec.by.forEach((column) => {
|
|
5814
|
+
result[column] = row[column];
|
|
5815
|
+
});
|
|
5816
|
+
const grouped = {};
|
|
5817
|
+
aggregates.forEach(({ group, column, alias, numeric }) => {
|
|
5818
|
+
grouped[group] ??= {};
|
|
5819
|
+
grouped[group][column] = numeric ? this.coerceNumeric(row[alias]) : row[alias];
|
|
5820
|
+
});
|
|
5821
|
+
Object.assign(result, grouped);
|
|
5822
|
+
if (countAllAlias) result._count = this.coerceNumeric(row[countAllAlias]);
|
|
5823
|
+
return result;
|
|
5824
|
+
});
|
|
5825
|
+
}
|
|
5826
|
+
coerceNumeric(value) {
|
|
5827
|
+
if (value === null || value === void 0) return null;
|
|
5828
|
+
return Number(value);
|
|
5829
|
+
}
|
|
5514
5830
|
appendHavingCondition(boolean, condition) {
|
|
5515
5831
|
if (!this.queryHaving) {
|
|
5516
5832
|
this.queryHaving = condition;
|
|
@@ -5531,12 +5847,35 @@ var QueryBuilder = class QueryBuilder {
|
|
|
5531
5847
|
value: hasOperator ? maybeValue : operatorOrValue
|
|
5532
5848
|
};
|
|
5533
5849
|
}
|
|
5534
|
-
|
|
5535
|
-
|
|
5850
|
+
/**
|
|
5851
|
+
* Resolves the three `having` call shapes into a condition: `having(column, …)`,
|
|
5852
|
+
* `having(expression)` (a boolean expression predicate), and
|
|
5853
|
+
* `having(expression, operator, value)` (compare an aggregate to a value).
|
|
5854
|
+
*/
|
|
5855
|
+
buildHavingCondition(columnOrExpression, operatorOrValue, maybeValue) {
|
|
5856
|
+
if (columnOrExpression instanceof require_relationship.Expression) return {
|
|
5857
|
+
type: "expression",
|
|
5858
|
+
expression: (operatorOrValue === void 0 ? columnOrExpression : this.compareExpression(columnOrExpression, operatorOrValue, maybeValue)).toExpressionNode()
|
|
5859
|
+
};
|
|
5860
|
+
return this.buildHavingComparison(operatorOrValue, maybeValue, columnOrExpression);
|
|
5861
|
+
}
|
|
5862
|
+
compareExpression(expression, operator, value) {
|
|
5863
|
+
switch (operator) {
|
|
5864
|
+
case "=": return expression.eq(value);
|
|
5865
|
+
case "!=": return expression.ne(value);
|
|
5866
|
+
case ">": return expression.gt(value);
|
|
5867
|
+
case ">=": return expression.gte(value);
|
|
5868
|
+
case "<": return expression.lt(value);
|
|
5869
|
+
case "<=": return expression.lte(value);
|
|
5870
|
+
default: return expression.eq(value);
|
|
5871
|
+
}
|
|
5872
|
+
}
|
|
5873
|
+
having(columnOrExpression, operatorOrValue, maybeValue) {
|
|
5874
|
+
this.appendHavingCondition("AND", this.buildHavingCondition(columnOrExpression, operatorOrValue, maybeValue));
|
|
5536
5875
|
return this;
|
|
5537
5876
|
}
|
|
5538
|
-
orHaving(
|
|
5539
|
-
this.appendHavingCondition("OR", this.
|
|
5877
|
+
orHaving(columnOrExpression, operatorOrValue, maybeValue) {
|
|
5878
|
+
this.appendHavingCondition("OR", this.buildHavingCondition(columnOrExpression, operatorOrValue, maybeValue));
|
|
5540
5879
|
return this;
|
|
5541
5880
|
}
|
|
5542
5881
|
/**
|
|
@@ -6694,12 +7033,19 @@ var QueryBuilder = class QueryBuilder {
|
|
|
6694
7033
|
}
|
|
6695
7034
|
if (typeof select !== "object" || !select) return null;
|
|
6696
7035
|
const entries = Object.entries(select);
|
|
6697
|
-
if (entries.some(([, value]) => value !== true && value !== false && value !== void 0 && typeof value !== "string")) return null;
|
|
6698
|
-
const columns = entries.filter(([, value]) => value === true || typeof value === "string").map(([column, value]) =>
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
7036
|
+
if (entries.some(([, value]) => value !== true && value !== false && value !== void 0 && typeof value !== "string" && !(value instanceof require_relationship.Expression))) return null;
|
|
7037
|
+
const columns = entries.filter(([, value]) => value === true || typeof value === "string" || value instanceof require_relationship.Expression).map(([column, value]) => {
|
|
7038
|
+
if (value instanceof require_relationship.Expression) return {
|
|
7039
|
+
column,
|
|
7040
|
+
alias: column,
|
|
7041
|
+
expression: value.toExpressionNode()
|
|
7042
|
+
};
|
|
7043
|
+
return typeof value === "string" ? {
|
|
7044
|
+
column,
|
|
7045
|
+
alias: value,
|
|
7046
|
+
raw: true
|
|
7047
|
+
} : { column };
|
|
7048
|
+
});
|
|
6703
7049
|
return columns.length > 0 ? columns : [];
|
|
6704
7050
|
}
|
|
6705
7051
|
normalizeQueryOrderBy(orderBy) {
|
|
@@ -6857,7 +7203,7 @@ var QueryBuilder = class QueryBuilder {
|
|
|
6857
7203
|
offset: normalizedQuery.offsetValue,
|
|
6858
7204
|
columns: normalizedQuery.querySelect ? [...normalizedQuery.querySelect] : void 0,
|
|
6859
7205
|
distinct: normalizedQuery.queryDistinct || void 0,
|
|
6860
|
-
groupBy: normalizedQuery.queryGroupBy ?
|
|
7206
|
+
groupBy: normalizedQuery.queryGroupBy ? normalizedQuery.queryGroupBy.filter((source) => typeof source === "string") : void 0,
|
|
6861
7207
|
relationLoads: this.mergeRelationLoadPlans(normalizedQuery.queryRelationLoads ? this.cloneRelationLoads(normalizedQuery.queryRelationLoads) : void 0, this.mergeRelationLoadPlans(callbackRelationLoads, childRelationLoads))
|
|
6862
7208
|
});
|
|
6863
7209
|
}
|
|
@@ -7121,11 +7467,11 @@ var QueryBuilder = class QueryBuilder {
|
|
|
7121
7467
|
if (columns === null || orderBy === null || condition === null) return null;
|
|
7122
7468
|
if (this.hasRelationFilters() && this.canExecuteRelationFiltersInAdapter() && relationFilters === null) return null;
|
|
7123
7469
|
if (this.hasRelationAggregates() && this.canExecuteRelationAggregatesInAdapter() && relationAggregates === null) return null;
|
|
7124
|
-
return {
|
|
7470
|
+
return this.expandComputedAttributes({
|
|
7125
7471
|
target: this.buildQueryTarget(),
|
|
7126
7472
|
columns,
|
|
7127
7473
|
distinct: this.queryDistinct || void 0,
|
|
7128
|
-
groupBy: this.
|
|
7474
|
+
groupBy: this.buildGroupByItems(columns ?? void 0),
|
|
7129
7475
|
having: this.queryHaving,
|
|
7130
7476
|
joins: this.queryJoins ? [...this.queryJoins] : void 0,
|
|
7131
7477
|
where: condition,
|
|
@@ -7135,8 +7481,87 @@ var QueryBuilder = class QueryBuilder {
|
|
|
7135
7481
|
relationLoads: this.queryRelationLoads,
|
|
7136
7482
|
relationFilters: this.canExecuteRelationFiltersInAdapter() ? relationFilters ?? void 0 : void 0,
|
|
7137
7483
|
relationAggregates: this.canExecuteRelationAggregatesInAdapter() ? relationAggregates ?? void 0 : void 0
|
|
7484
|
+
});
|
|
7485
|
+
}
|
|
7486
|
+
/** Reads and caches the model's resolved `static computed` expression map. */
|
|
7487
|
+
computedAttributes() {
|
|
7488
|
+
const model = this.model;
|
|
7489
|
+
return typeof model.getComputed === "function" ? model.getComputed() : {};
|
|
7490
|
+
}
|
|
7491
|
+
/**
|
|
7492
|
+
* Expands references to `static computed` attribute names into their backing
|
|
7493
|
+
* expressions across a select spec's columns, group by, order by, where, and
|
|
7494
|
+
* having clauses. A no-op when the model declares no computed attributes.
|
|
7495
|
+
*/
|
|
7496
|
+
expandComputedAttributes(spec) {
|
|
7497
|
+
const computed = this.computedAttributes();
|
|
7498
|
+
if (Object.keys(computed).length === 0) return spec;
|
|
7499
|
+
const columns = spec.columns?.map((column) => {
|
|
7500
|
+
if (column.expression || column.raw || column.wildcard) return column;
|
|
7501
|
+
const expression = computed[column.column];
|
|
7502
|
+
return expression ? {
|
|
7503
|
+
...column,
|
|
7504
|
+
expression,
|
|
7505
|
+
alias: column.alias ?? column.column
|
|
7506
|
+
} : column;
|
|
7507
|
+
});
|
|
7508
|
+
const selectedComputedAliases = new Set(columns?.filter((column) => column.expression && column.alias).map((column) => column.alias));
|
|
7509
|
+
return {
|
|
7510
|
+
...spec,
|
|
7511
|
+
columns,
|
|
7512
|
+
groupBy: spec.groupBy?.map((item) => {
|
|
7513
|
+
if (typeof item !== "string") return item;
|
|
7514
|
+
const expression = computed[item];
|
|
7515
|
+
if (!expression) return item;
|
|
7516
|
+
return selectedComputedAliases.has(item) ? { alias: item } : { expression };
|
|
7517
|
+
}),
|
|
7518
|
+
orderBy: spec.orderBy?.map((clause) => {
|
|
7519
|
+
if (clause.expression) return clause;
|
|
7520
|
+
const expression = computed[clause.column];
|
|
7521
|
+
return expression ? {
|
|
7522
|
+
...clause,
|
|
7523
|
+
expression
|
|
7524
|
+
} : clause;
|
|
7525
|
+
}),
|
|
7526
|
+
where: spec.where ? this.expandComputedCondition(spec.where, computed) : spec.where,
|
|
7527
|
+
having: spec.having ? this.expandComputedCondition(spec.having, computed) : spec.having
|
|
7138
7528
|
};
|
|
7139
7529
|
}
|
|
7530
|
+
expandComputedCondition(condition, computed) {
|
|
7531
|
+
if (condition.type === "comparison" && computed[condition.column]) return {
|
|
7532
|
+
type: "expression",
|
|
7533
|
+
expression: this.computedComparison(computed[condition.column], condition.operator, condition.value)
|
|
7534
|
+
};
|
|
7535
|
+
if (condition.type === "group") return {
|
|
7536
|
+
...condition,
|
|
7537
|
+
conditions: condition.conditions.map((entry) => this.expandComputedCondition(entry, computed))
|
|
7538
|
+
};
|
|
7539
|
+
if (condition.type === "not") return {
|
|
7540
|
+
...condition,
|
|
7541
|
+
condition: this.expandComputedCondition(condition.condition, computed)
|
|
7542
|
+
};
|
|
7543
|
+
return condition;
|
|
7544
|
+
}
|
|
7545
|
+
/** Converts a where comparison against a computed attribute into an expression. */
|
|
7546
|
+
computedComparison(node, operator, value) {
|
|
7547
|
+
const expression = require_relationship.fromExpressionNode(node);
|
|
7548
|
+
const list = Array.isArray(value) ? value : [];
|
|
7549
|
+
switch (operator) {
|
|
7550
|
+
case "!=": return expression.ne(value).toExpressionNode();
|
|
7551
|
+
case ">": return expression.gt(value).toExpressionNode();
|
|
7552
|
+
case ">=": return expression.gte(value).toExpressionNode();
|
|
7553
|
+
case "<": return expression.lt(value).toExpressionNode();
|
|
7554
|
+
case "<=": return expression.lte(value).toExpressionNode();
|
|
7555
|
+
case "in": return expression.in(list).toExpressionNode();
|
|
7556
|
+
case "not-in": return expression.notIn(list).toExpressionNode();
|
|
7557
|
+
case "is-null": return expression.isNull().toExpressionNode();
|
|
7558
|
+
case "is-not-null": return expression.isNotNull().toExpressionNode();
|
|
7559
|
+
case "contains": return expression.like(`%${String(value)}%`).toExpressionNode();
|
|
7560
|
+
case "starts-with": return expression.like(`${String(value)}%`).toExpressionNode();
|
|
7561
|
+
case "ends-with": return expression.like(`%${String(value)}`).toExpressionNode();
|
|
7562
|
+
default: return expression.eq(value).toExpressionNode();
|
|
7563
|
+
}
|
|
7564
|
+
}
|
|
7140
7565
|
tryBuildAggregateSpec() {
|
|
7141
7566
|
const condition = this.buildQueryWhereCondition(false);
|
|
7142
7567
|
const relationFilters = this.tryBuildRelationFilterSpecs();
|
|
@@ -7635,6 +8060,9 @@ var Model = class Model {
|
|
|
7635
8060
|
static {
|
|
7636
8061
|
this.castMapCache = /* @__PURE__ */ new WeakMap();
|
|
7637
8062
|
}
|
|
8063
|
+
static {
|
|
8064
|
+
this.computedCache = /* @__PURE__ */ new WeakMap();
|
|
8065
|
+
}
|
|
7638
8066
|
static {
|
|
7639
8067
|
this.emittedDeprecationWarnings = /* @__PURE__ */ new Set();
|
|
7640
8068
|
}
|
|
@@ -7785,6 +8213,19 @@ var Model = class Model {
|
|
|
7785
8213
|
return casts;
|
|
7786
8214
|
}
|
|
7787
8215
|
/**
|
|
8216
|
+
* Resolves the model's `static computed` declarations into expression nodes,
|
|
8217
|
+
* cached per class. Returns an empty map when no computed attributes exist.
|
|
8218
|
+
*/
|
|
8219
|
+
static getComputed() {
|
|
8220
|
+
const cached = Model.computedCache.get(this);
|
|
8221
|
+
if (cached) return cached;
|
|
8222
|
+
const definitions = this.computed;
|
|
8223
|
+
const resolved = {};
|
|
8224
|
+
if (definitions) for (const [name, factory] of Object.entries(definitions)) resolved[name] = factory(require_relationship.expressionBuilder).toExpressionNode();
|
|
8225
|
+
Model.computedCache.set(this, resolved);
|
|
8226
|
+
return resolved;
|
|
8227
|
+
}
|
|
8228
|
+
/**
|
|
7788
8229
|
* Apply built-in persistence casts (currently `json` serialisation) to a raw
|
|
7789
8230
|
* attribute payload, without re-running arbitrary custom setters. Used by
|
|
7790
8231
|
* both instance `save()` and the query-builder insert/update paths so a JS
|
|
@@ -8191,6 +8632,22 @@ var Model = class Model {
|
|
|
8191
8632
|
});
|
|
8192
8633
|
return this;
|
|
8193
8634
|
}
|
|
8635
|
+
/**
|
|
8636
|
+
* Merge already-stored (database representation) attribute values into the
|
|
8637
|
+
* model without running set mutators or casts. Used to refresh the instance
|
|
8638
|
+
* from a row returned by a write, where the values are already in storage
|
|
8639
|
+
* form and must not be re-cast (re-applying a non-idempotent set-cast such as
|
|
8640
|
+
* a money or array cast would corrupt the value).
|
|
8641
|
+
*
|
|
8642
|
+
* @param attributes
|
|
8643
|
+
* @returns
|
|
8644
|
+
*/
|
|
8645
|
+
fillRawAttributes(attributes) {
|
|
8646
|
+
Object.entries(attributes).forEach(([key, value]) => {
|
|
8647
|
+
this.attributes[key] = Model.cloneAttributeValue(value);
|
|
8648
|
+
});
|
|
8649
|
+
return this;
|
|
8650
|
+
}
|
|
8194
8651
|
async update(attributes) {
|
|
8195
8652
|
try {
|
|
8196
8653
|
const primaryKey = this.constructor.getPrimaryKey();
|
|
@@ -8246,7 +8703,7 @@ var Model = class Model {
|
|
|
8246
8703
|
await Model.dispatchEvent(constructor, "creating", this);
|
|
8247
8704
|
const payload = this.normalizePersistenceAttributes(this.getRawAttributes());
|
|
8248
8705
|
const model = await constructor.query().create(payload);
|
|
8249
|
-
this.
|
|
8706
|
+
this.fillRawAttributes(model.getRawAttributes());
|
|
8250
8707
|
this.syncChanges(previousOriginal);
|
|
8251
8708
|
this.syncPrevious(previousOriginal);
|
|
8252
8709
|
this.syncOriginal();
|
|
@@ -8263,7 +8720,7 @@ var Model = class Model {
|
|
|
8263
8720
|
const payload = this.normalizePersistenceAttributes(this.getDirtyAttributes());
|
|
8264
8721
|
delete payload[primaryKey];
|
|
8265
8722
|
const model = await constructor.query().where({ [primaryKey]: identifier }).update(payload);
|
|
8266
|
-
this.
|
|
8723
|
+
this.fillRawAttributes(model.getRawAttributes());
|
|
8267
8724
|
this.syncChanges(previousOriginal);
|
|
8268
8725
|
this.syncPrevious(previousOriginal);
|
|
8269
8726
|
this.syncOriginal();
|
|
@@ -8306,7 +8763,7 @@ var Model = class Model {
|
|
|
8306
8763
|
const softDeleteConfig = constructor.getSoftDeleteConfig();
|
|
8307
8764
|
if (softDeleteConfig.enabled) {
|
|
8308
8765
|
const model = await constructor.query().where({ [primaryKey]: identifier }).update({ [softDeleteConfig.column]: /* @__PURE__ */ new Date() });
|
|
8309
|
-
this.
|
|
8766
|
+
this.fillRawAttributes(model.getRawAttributes());
|
|
8310
8767
|
this.syncChanges(previousOriginal);
|
|
8311
8768
|
this.syncOriginal();
|
|
8312
8769
|
await Model.dispatchEvent(constructor, "deleted", this);
|
|
@@ -8381,7 +8838,7 @@ var Model = class Model {
|
|
|
8381
8838
|
const previousOriginal = this.getOriginal();
|
|
8382
8839
|
await Model.dispatchEvent(constructor, "restoring", this);
|
|
8383
8840
|
const model = await constructor.query().withTrashed().where({ [primaryKey]: identifier }).update({ [softDeleteConfig.column]: null });
|
|
8384
|
-
this.
|
|
8841
|
+
this.fillRawAttributes(model.getRawAttributes());
|
|
8385
8842
|
this.syncChanges(previousOriginal);
|
|
8386
8843
|
this.syncOriginal();
|
|
8387
8844
|
await Model.dispatchEvent(constructor, "restored", this);
|
|
@@ -9625,18 +10082,22 @@ var PivotModel = class extends Model {
|
|
|
9625
10082
|
};
|
|
9626
10083
|
|
|
9627
10084
|
//#endregion
|
|
10085
|
+
exports.AggregateExpression = require_relationship.AggregateExpression;
|
|
9628
10086
|
exports.Arkorm = Arkorm;
|
|
9629
10087
|
exports.ArkormCollection = require_relationship.ArkormCollection;
|
|
9630
10088
|
exports.ArkormException = require_relationship.ArkormException;
|
|
9631
10089
|
exports.Arkormx = Arkormx;
|
|
9632
10090
|
exports.Attribute = Attribute;
|
|
10091
|
+
exports.CaseExpression = require_relationship.CaseExpression;
|
|
9633
10092
|
exports.CliApp = CliApp;
|
|
9634
10093
|
exports.DB = DB;
|
|
9635
10094
|
exports.EnumBuilder = require_relationship.EnumBuilder;
|
|
10095
|
+
exports.Expression = require_relationship.Expression;
|
|
9636
10096
|
exports.ForeignKeyBuilder = require_relationship.ForeignKeyBuilder;
|
|
9637
10097
|
exports.InitCommand = InitCommand;
|
|
9638
10098
|
exports.InlineFactory = InlineFactory;
|
|
9639
10099
|
exports.JoinClause = JoinClause;
|
|
10100
|
+
exports.JsonExpression = require_relationship.JsonExpression;
|
|
9640
10101
|
exports.KyselyDatabaseAdapter = KyselyDatabaseAdapter;
|
|
9641
10102
|
exports.LengthAwarePaginator = require_relationship.LengthAwarePaginator;
|
|
9642
10103
|
exports.MIGRATION_BRAND = MIGRATION_BRAND;
|
|
@@ -9684,6 +10145,7 @@ exports.applyMigrationToDatabase = require_relationship.applyMigrationToDatabase
|
|
|
9684
10145
|
exports.applyMigrationToPrismaSchema = require_relationship.applyMigrationToPrismaSchema;
|
|
9685
10146
|
exports.applyOperationsToPersistedColumnMappingsState = require_relationship.applyOperationsToPersistedColumnMappingsState;
|
|
9686
10147
|
exports.applyOperationsToPrismaSchema = require_relationship.applyOperationsToPrismaSchema;
|
|
10148
|
+
exports.avg = require_relationship.avg;
|
|
9687
10149
|
exports.awaitConfiguredModelsRegistration = require_relationship.awaitConfiguredModelsRegistration;
|
|
9688
10150
|
exports.bindAdapterToModels = require_relationship.bindAdapterToModels;
|
|
9689
10151
|
exports.buildEnumBlock = require_relationship.buildEnumBlock;
|
|
@@ -9697,8 +10159,12 @@ exports.buildModelBlock = require_relationship.buildModelBlock;
|
|
|
9697
10159
|
exports.buildPrimaryKeyLine = require_relationship.buildPrimaryKeyLine;
|
|
9698
10160
|
exports.buildRelationLine = require_relationship.buildRelationLine;
|
|
9699
10161
|
exports.buildUniqueConstraintLine = require_relationship.buildUniqueConstraintLine;
|
|
10162
|
+
exports.caseWhen = require_relationship.caseWhen;
|
|
10163
|
+
exports.coalesce = require_relationship.coalesce;
|
|
10164
|
+
exports.col = require_relationship.col;
|
|
9700
10165
|
exports.computeMigrationChecksum = require_relationship.computeMigrationChecksum;
|
|
9701
10166
|
exports.configureArkormRuntime = require_relationship.configureArkormRuntime;
|
|
10167
|
+
exports.count = require_relationship.count;
|
|
9702
10168
|
exports.createEmptyAppliedMigrationsState = require_relationship.createEmptyAppliedMigrationsState;
|
|
9703
10169
|
exports.createEmptyPersistedColumnMappingsState = require_relationship.createEmptyPersistedColumnMappingsState;
|
|
9704
10170
|
exports.createKyselyAdapter = createKyselyAdapter;
|
|
@@ -9719,12 +10185,15 @@ exports.deriveSingularFieldName = require_relationship.deriveSingularFieldName;
|
|
|
9719
10185
|
exports.emitRuntimeDebugEvent = require_relationship.emitRuntimeDebugEvent;
|
|
9720
10186
|
exports.ensureArkormConfigLoading = require_relationship.ensureArkormConfigLoading;
|
|
9721
10187
|
exports.escapeRegex = require_relationship.escapeRegex;
|
|
10188
|
+
exports.expressionBuilder = require_relationship.expressionBuilder;
|
|
9722
10189
|
exports.findAppliedMigration = require_relationship.findAppliedMigration;
|
|
9723
10190
|
exports.findEnumBlock = require_relationship.findEnumBlock;
|
|
9724
10191
|
exports.findModelBlock = require_relationship.findModelBlock;
|
|
10192
|
+
exports.fn = require_relationship.fn;
|
|
9725
10193
|
exports.formatDefaultValue = require_relationship.formatDefaultValue;
|
|
9726
10194
|
exports.formatEnumDefaultValue = require_relationship.formatEnumDefaultValue;
|
|
9727
10195
|
exports.formatRelationAction = require_relationship.formatRelationAction;
|
|
10196
|
+
exports.fromExpressionNode = require_relationship.fromExpressionNode;
|
|
9728
10197
|
exports.generateMigrationFile = require_relationship.generateMigrationFile;
|
|
9729
10198
|
exports.getActiveTransactionAdapter = require_relationship.getActiveTransactionAdapter;
|
|
9730
10199
|
exports.getActiveTransactionClient = require_relationship.getActiveTransactionClient;
|
|
@@ -9756,6 +10225,7 @@ exports.isDelegateLike = require_relationship.isDelegateLike;
|
|
|
9756
10225
|
exports.isMigrationApplied = require_relationship.isMigrationApplied;
|
|
9757
10226
|
exports.isQuerySchemaLike = require_relationship.isQuerySchemaLike;
|
|
9758
10227
|
exports.isTransactionCapableClient = require_relationship.isTransactionCapableClient;
|
|
10228
|
+
exports.json = require_relationship.json;
|
|
9759
10229
|
exports.loadArkormConfig = require_relationship.loadArkormConfig;
|
|
9760
10230
|
exports.loadFactoriesFrom = require_relationship.loadFactoriesFrom;
|
|
9761
10231
|
exports.loadMigrationsFrom = require_relationship.loadMigrationsFrom;
|
|
@@ -9763,7 +10233,10 @@ exports.loadModelsFrom = require_relationship.loadModelsFrom;
|
|
|
9763
10233
|
exports.loadSeedersFrom = require_relationship.loadSeedersFrom;
|
|
9764
10234
|
exports.markMigrationApplied = require_relationship.markMigrationApplied;
|
|
9765
10235
|
exports.markMigrationRun = require_relationship.markMigrationRun;
|
|
10236
|
+
exports.max = require_relationship.max;
|
|
10237
|
+
exports.min = require_relationship.min;
|
|
9766
10238
|
exports.pad = require_relationship.pad;
|
|
10239
|
+
exports.raw = require_relationship.raw;
|
|
9767
10240
|
exports.readAppliedMigrationsState = require_relationship.readAppliedMigrationsState;
|
|
9768
10241
|
exports.readAppliedMigrationsStateFromStore = require_relationship.readAppliedMigrationsStateFromStore;
|
|
9769
10242
|
exports.readPersistedColumnMappingsState = require_relationship.readPersistedColumnMappingsState;
|
|
@@ -9780,6 +10253,7 @@ exports.resetRuntimeRegistryForTests = require_relationship.resetRuntimeRegistry
|
|
|
9780
10253
|
exports.resolveCast = resolveCast;
|
|
9781
10254
|
exports.resolveColumnMappingsFilePath = require_relationship.resolveColumnMappingsFilePath;
|
|
9782
10255
|
exports.resolveEnumName = require_relationship.resolveEnumName;
|
|
10256
|
+
exports.resolveGeneratedExpression = require_relationship.resolveGeneratedExpression;
|
|
9783
10257
|
exports.resolveMigrationClassName = require_relationship.resolveMigrationClassName;
|
|
9784
10258
|
exports.resolveMigrationStateFilePath = require_relationship.resolveMigrationStateFilePath;
|
|
9785
10259
|
exports.resolvePersistedMetadataFeatures = require_relationship.resolvePersistedMetadataFeatures;
|
|
@@ -9790,6 +10264,7 @@ exports.runArkormTransaction = require_relationship.runArkormTransaction;
|
|
|
9790
10264
|
exports.runMigrationWithPrisma = require_relationship.runMigrationWithPrisma;
|
|
9791
10265
|
exports.runPrismaCommand = require_relationship.runPrismaCommand;
|
|
9792
10266
|
exports.stripPrismaSchemaModelsAndEnums = require_relationship.stripPrismaSchemaModelsAndEnums;
|
|
10267
|
+
exports.sum = require_relationship.sum;
|
|
9793
10268
|
exports.supportsDatabaseCreation = require_relationship.supportsDatabaseCreation;
|
|
9794
10269
|
exports.supportsDatabaseMigrationExecution = require_relationship.supportsDatabaseMigrationExecution;
|
|
9795
10270
|
exports.supportsDatabaseMigrationState = require_relationship.supportsDatabaseMigrationState;
|
|
@@ -9797,7 +10272,9 @@ exports.supportsDatabaseReset = require_relationship.supportsDatabaseReset;
|
|
|
9797
10272
|
exports.syncPersistedColumnMappingsFromState = require_relationship.syncPersistedColumnMappingsFromState;
|
|
9798
10273
|
exports.toMigrationFileSlug = require_relationship.toMigrationFileSlug;
|
|
9799
10274
|
exports.toModelName = require_relationship.toModelName;
|
|
10275
|
+
exports.val = require_relationship.val;
|
|
9800
10276
|
exports.validatePersistedMetadataFeaturesForMigrations = require_relationship.validatePersistedMetadataFeaturesForMigrations;
|
|
10277
|
+
exports.where = require_relationship.where;
|
|
9801
10278
|
exports.writeAppliedMigrationsState = require_relationship.writeAppliedMigrationsState;
|
|
9802
10279
|
exports.writeAppliedMigrationsStateToStore = require_relationship.writeAppliedMigrationsStateToStore;
|
|
9803
10280
|
exports.writePersistedColumnMappingsState = require_relationship.writePersistedColumnMappingsState;
|