@zenstackhq/runtime 3.0.0-alpha.20 → 3.0.0-alpha.22
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/{contract-XFKcwhq7.d.cts → contract-D8U59Syb.d.cts} +1 -0
- package/dist/{contract-XFKcwhq7.d.ts → contract-D8U59Syb.d.ts} +1 -0
- package/dist/index.cjs +77 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +105 -64
- package/dist/index.js.map +1 -1
- package/dist/plugins/policy/index.cjs +14 -10
- package/dist/plugins/policy/index.cjs.map +1 -1
- package/dist/plugins/policy/index.d.cts +1 -1
- package/dist/plugins/policy/index.d.ts +1 -1
- package/dist/plugins/policy/index.js +17 -13
- package/dist/plugins/policy/index.js.map +1 -1
- package/package.json +10 -8
|
@@ -562,6 +562,7 @@ declare abstract class BaseCrudDialect<Schema extends SchemaDef> {
|
|
|
562
562
|
protected and(eb: ExpressionBuilder<any, any>, ...args: Expression<SqlBool>[]): Expression<SqlBool>;
|
|
563
563
|
protected or(eb: ExpressionBuilder<any, any>, ...args: Expression<SqlBool>[]): Expression<SqlBool>;
|
|
564
564
|
protected not(eb: ExpressionBuilder<any, any>, ...args: Expression<SqlBool>[]): ExpressionWrapper<any, any, SqlBool>;
|
|
565
|
+
fieldRef(model: string, field: string, eb: ExpressionBuilder<any, any>, modelAlias?: string): ExpressionWrapper<any, any, unknown>;
|
|
565
566
|
abstract get provider(): DataSourceProviderType;
|
|
566
567
|
/**
|
|
567
568
|
* Builds selection for a relation field.
|
|
@@ -562,6 +562,7 @@ declare abstract class BaseCrudDialect<Schema extends SchemaDef> {
|
|
|
562
562
|
protected and(eb: ExpressionBuilder<any, any>, ...args: Expression<SqlBool>[]): Expression<SqlBool>;
|
|
563
563
|
protected or(eb: ExpressionBuilder<any, any>, ...args: Expression<SqlBool>[]): Expression<SqlBool>;
|
|
564
564
|
protected not(eb: ExpressionBuilder<any, any>, ...args: Expression<SqlBool>[]): ExpressionWrapper<any, any, SqlBool>;
|
|
565
|
+
fieldRef(model: string, field: string, eb: ExpressionBuilder<any, any>, modelAlias?: string): ExpressionWrapper<any, any, unknown>;
|
|
565
566
|
abstract get provider(): DataSourceProviderType;
|
|
566
567
|
/**
|
|
567
568
|
* Builds selection for a relation field.
|
package/dist/index.cjs
CHANGED
|
@@ -582,7 +582,7 @@ var BaseCrudDialect = class {
|
|
|
582
582
|
if (fieldDef.relation) {
|
|
583
583
|
result = this.and(eb, result, this.buildRelationFilter(eb, model, modelAlias, key, fieldDef, payload));
|
|
584
584
|
} else {
|
|
585
|
-
const fieldRef =
|
|
585
|
+
const fieldRef = this.fieldRef(fieldDef.originModel ?? model, key, eb, fieldDef.originModel ?? modelAlias);
|
|
586
586
|
if (fieldDef.array) {
|
|
587
587
|
result = this.and(eb, result, this.buildArrayFilter(eb, fieldRef, fieldDef, payload));
|
|
588
588
|
} else {
|
|
@@ -905,7 +905,7 @@ var BaseCrudDialect = class {
|
|
|
905
905
|
(0, import_common_helpers.invariant)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
|
|
906
906
|
for (const [k, v] of Object.entries(value)) {
|
|
907
907
|
(0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
|
|
908
|
-
result = result.orderBy((eb) => aggregate(eb,
|
|
908
|
+
result = result.orderBy((eb) => aggregate(eb, this.fieldRef(model, k, eb, modelAlias), field), import_kysely.sql.raw(this.negateSort(v, negated)));
|
|
909
909
|
}
|
|
910
910
|
continue;
|
|
911
911
|
}
|
|
@@ -914,7 +914,7 @@ var BaseCrudDialect = class {
|
|
|
914
914
|
(0, import_common_helpers.invariant)(value && typeof value === "object", 'invalid orderBy value for field "_count"');
|
|
915
915
|
for (const [k, v] of Object.entries(value)) {
|
|
916
916
|
(0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
|
|
917
|
-
result = result.orderBy((eb) => eb.fn.count(
|
|
917
|
+
result = result.orderBy((eb) => eb.fn.count(this.fieldRef(model, k, eb, modelAlias)), import_kysely.sql.raw(this.negateSort(v, negated)));
|
|
918
918
|
}
|
|
919
919
|
continue;
|
|
920
920
|
}
|
|
@@ -923,10 +923,11 @@ var BaseCrudDialect = class {
|
|
|
923
923
|
}
|
|
924
924
|
const fieldDef = requireField(this.schema, model, field);
|
|
925
925
|
if (!fieldDef.relation) {
|
|
926
|
+
const fieldRef = this.fieldRef(model, field, (0, import_kysely.expressionBuilder)(), modelAlias);
|
|
926
927
|
if (value === "asc" || value === "desc") {
|
|
927
|
-
result = result.orderBy(
|
|
928
|
+
result = result.orderBy(fieldRef, this.negateSort(value, negated));
|
|
928
929
|
} else if (value && typeof value === "object" && "nulls" in value && "sort" in value && (value.sort === "asc" || value.sort === "desc") && (value.nulls === "first" || value.nulls === "last")) {
|
|
929
|
-
result = result.orderBy(
|
|
930
|
+
result = result.orderBy(fieldRef, import_kysely.sql.raw(`${this.negateSort(value.sort, negated)} nulls ${value.nulls}`));
|
|
930
931
|
}
|
|
931
932
|
} else {
|
|
932
933
|
const relationModel = fieldDef.type;
|
|
@@ -988,7 +989,7 @@ var BaseCrudDialect = class {
|
|
|
988
989
|
buildSelectField(query, model, modelAlias, field) {
|
|
989
990
|
const fieldDef = requireField(this.schema, model, field);
|
|
990
991
|
if (fieldDef.computed) {
|
|
991
|
-
return query.select((eb) =>
|
|
992
|
+
return query.select((eb) => this.fieldRef(model, field, eb, modelAlias).as(field));
|
|
992
993
|
} else if (!fieldDef.originModel) {
|
|
993
994
|
return query.select(import_kysely.sql.ref(`${modelAlias}.${field}`).as(field));
|
|
994
995
|
} else {
|
|
@@ -1079,6 +1080,9 @@ var BaseCrudDialect = class {
|
|
|
1079
1080
|
not(eb, ...args) {
|
|
1080
1081
|
return eb.not(this.and(eb, ...args));
|
|
1081
1082
|
}
|
|
1083
|
+
fieldRef(model, field, eb, modelAlias) {
|
|
1084
|
+
return buildFieldRef(this.schema, model, field, this.options, eb, modelAlias);
|
|
1085
|
+
}
|
|
1082
1086
|
};
|
|
1083
1087
|
|
|
1084
1088
|
// src/client/crud/dialects/postgresql.ts
|
|
@@ -1172,7 +1176,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
1172
1176
|
if (payload === true || !payload.select) {
|
|
1173
1177
|
objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
|
|
1174
1178
|
import_kysely2.sql.lit(field),
|
|
1175
|
-
|
|
1179
|
+
this.fieldRef(relationModel, field, eb)
|
|
1176
1180
|
]).flatMap((v) => v));
|
|
1177
1181
|
} else if (payload.select) {
|
|
1178
1182
|
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
|
|
@@ -1184,7 +1188,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
1184
1188
|
];
|
|
1185
1189
|
} else {
|
|
1186
1190
|
const fieldDef = requireField(this.schema, relationModel, field);
|
|
1187
|
-
const fieldValue = fieldDef.relation ? eb.ref(`${parentAlias}$${relationField}$${field}.$j`) :
|
|
1191
|
+
const fieldValue = fieldDef.relation ? eb.ref(`${parentAlias}$${relationField}$${field}.$j`) : this.fieldRef(relationModel, field, eb);
|
|
1188
1192
|
return [
|
|
1189
1193
|
import_kysely2.sql.lit(field),
|
|
1190
1194
|
fieldValue
|
|
@@ -1335,7 +1339,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1335
1339
|
if (payload === true || !payload.select) {
|
|
1336
1340
|
objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
|
|
1337
1341
|
import_kysely3.sql.lit(field),
|
|
1338
|
-
|
|
1342
|
+
this.fieldRef(relationModel, field, eb)
|
|
1339
1343
|
]).flatMap((v) => v));
|
|
1340
1344
|
} else if (payload.select) {
|
|
1341
1345
|
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
|
|
@@ -1356,7 +1360,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1356
1360
|
} else {
|
|
1357
1361
|
return [
|
|
1358
1362
|
import_kysely3.sql.lit(field),
|
|
1359
|
-
|
|
1363
|
+
this.fieldRef(relationModel, field, eb)
|
|
1360
1364
|
];
|
|
1361
1365
|
}
|
|
1362
1366
|
}
|
|
@@ -2763,7 +2767,7 @@ var BaseOperationHandler = class {
|
|
|
2763
2767
|
query = query.distinctOn(distinct.map((f) => import_kysely8.sql.ref(`${model}.${f}`)));
|
|
2764
2768
|
} else {
|
|
2765
2769
|
inMemoryDistinct = distinct;
|
|
2766
|
-
query = distinct.reduce((acc, field) => acc.select((eb) =>
|
|
2770
|
+
query = distinct.reduce((acc, field) => acc.select((eb) => this.dialect.fieldRef(model, field, eb).as(`$distinct$${field}`)), query);
|
|
2767
2771
|
}
|
|
2768
2772
|
}
|
|
2769
2773
|
if (args && "select" in args && args.select) {
|
|
@@ -3436,7 +3440,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
|
|
|
3436
3440
|
const key = Object.keys(payload)[0];
|
|
3437
3441
|
const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, false);
|
|
3438
3442
|
const eb = (0, import_kysely8.expressionBuilder)();
|
|
3439
|
-
const fieldRef =
|
|
3443
|
+
const fieldRef = this.dialect.fieldRef(model, field, eb);
|
|
3440
3444
|
return (0, import_ts_pattern9.match)(key).with("set", () => value).with("increment", () => eb(fieldRef, "+", value)).with("decrement", () => eb(fieldRef, "-", value)).with("multiply", () => eb(fieldRef, "*", value)).with("divide", () => eb(fieldRef, "/", value)).otherwise(() => {
|
|
3441
3445
|
throw new InternalError(`Invalid incremental update operation: ${key}`);
|
|
3442
3446
|
});
|
|
@@ -3446,7 +3450,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
|
|
|
3446
3450
|
const key = Object.keys(payload)[0];
|
|
3447
3451
|
const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, true);
|
|
3448
3452
|
const eb = (0, import_kysely8.expressionBuilder)();
|
|
3449
|
-
const fieldRef =
|
|
3453
|
+
const fieldRef = this.dialect.fieldRef(model, field, eb);
|
|
3450
3454
|
return (0, import_ts_pattern9.match)(key).with("set", () => value).with("push", () => {
|
|
3451
3455
|
return eb(fieldRef, "||", eb.val(ensureArray(value)));
|
|
3452
3456
|
}).otherwise(() => {
|
|
@@ -4320,10 +4324,11 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
|
|
|
4320
4324
|
subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model, void 0, skip !== void 0 || take !== void 0, negateOrderBy);
|
|
4321
4325
|
return subQuery.as("$sub");
|
|
4322
4326
|
});
|
|
4327
|
+
const fieldRef = /* @__PURE__ */ __name((field) => this.dialect.fieldRef(this.model, field, (0, import_kysely11.expressionBuilder)(), "$sub"), "fieldRef");
|
|
4323
4328
|
const bys = typeof parsedArgs.by === "string" ? [
|
|
4324
4329
|
parsedArgs.by
|
|
4325
4330
|
] : parsedArgs.by;
|
|
4326
|
-
query = query.groupBy(bys.map((by) =>
|
|
4331
|
+
query = query.groupBy(bys.map((by) => fieldRef(by)));
|
|
4327
4332
|
if (parsedArgs.orderBy) {
|
|
4328
4333
|
query = this.dialect.buildOrderBy(query, this.model, "$sub", parsedArgs.orderBy, false, false);
|
|
4329
4334
|
}
|
|
@@ -4331,7 +4336,7 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
|
|
|
4331
4336
|
query = query.having((eb) => this.dialect.buildFilter(eb, this.model, "$sub", parsedArgs.having));
|
|
4332
4337
|
}
|
|
4333
4338
|
for (const by of bys) {
|
|
4334
|
-
query = query.select(() =>
|
|
4339
|
+
query = query.select(() => fieldRef(by).as(by));
|
|
4335
4340
|
}
|
|
4336
4341
|
for (const [key, value] of Object.entries(parsedArgs)) {
|
|
4337
4342
|
switch (key) {
|
|
@@ -4344,7 +4349,7 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
|
|
|
4344
4349
|
if (field === "_all") {
|
|
4345
4350
|
query = query.select((eb) => eb.cast(eb.fn.countAll(), "integer").as(`_count._all`));
|
|
4346
4351
|
} else {
|
|
4347
|
-
query = query.select((eb) => eb.cast(eb.fn.count(
|
|
4352
|
+
query = query.select((eb) => eb.cast(eb.fn.count(fieldRef(field)), "integer").as(`${key}.${field}`));
|
|
4348
4353
|
}
|
|
4349
4354
|
}
|
|
4350
4355
|
});
|
|
@@ -4357,10 +4362,7 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
|
|
|
4357
4362
|
case "_min": {
|
|
4358
4363
|
Object.entries(value).forEach(([field, val]) => {
|
|
4359
4364
|
if (val === true) {
|
|
4360
|
-
query = query.select((eb) => {
|
|
4361
|
-
const fn = (0, import_ts_pattern13.match)(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
|
|
4362
|
-
return fn(import_kysely11.sql.ref(`$sub.${field}`)).as(`${key}.${field}`);
|
|
4363
|
-
});
|
|
4365
|
+
query = query.select((eb) => aggregate(eb, fieldRef(field), key).as(`${key}.${field}`));
|
|
4364
4366
|
}
|
|
4365
4367
|
});
|
|
4366
4368
|
break;
|
|
@@ -6288,6 +6290,7 @@ __name(processCasing, "processCasing");
|
|
|
6288
6290
|
// src/client/helpers/schema-db-pusher.ts
|
|
6289
6291
|
var import_common_helpers11 = require("@zenstackhq/common-helpers");
|
|
6290
6292
|
var import_kysely15 = require("kysely");
|
|
6293
|
+
var import_toposort = __toESM(require("toposort"), 1);
|
|
6291
6294
|
var import_ts_pattern18 = require("ts-pattern");
|
|
6292
6295
|
var SchemaDbPusher = class {
|
|
6293
6296
|
static {
|
|
@@ -6307,41 +6310,79 @@ var SchemaDbPusher = class {
|
|
|
6307
6310
|
await createEnum.execute();
|
|
6308
6311
|
}
|
|
6309
6312
|
}
|
|
6310
|
-
|
|
6311
|
-
|
|
6313
|
+
const sortedModels = this.sortModels(this.schema.models);
|
|
6314
|
+
for (const modelDef of sortedModels) {
|
|
6315
|
+
const createTable = this.createModelTable(tx, modelDef);
|
|
6312
6316
|
await createTable.execute();
|
|
6313
6317
|
}
|
|
6314
6318
|
});
|
|
6315
6319
|
}
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
const
|
|
6320
|
+
sortModels(models) {
|
|
6321
|
+
const graph = [];
|
|
6322
|
+
for (const model of Object.values(models)) {
|
|
6323
|
+
let added = false;
|
|
6324
|
+
if (model.baseModel) {
|
|
6325
|
+
const baseDef = requireModel(this.schema, model.baseModel);
|
|
6326
|
+
graph.push([
|
|
6327
|
+
model,
|
|
6328
|
+
baseDef
|
|
6329
|
+
]);
|
|
6330
|
+
added = true;
|
|
6331
|
+
}
|
|
6332
|
+
for (const field of Object.values(model.fields)) {
|
|
6333
|
+
if (field.relation && field.relation.fields && field.relation.references) {
|
|
6334
|
+
const targetModel = requireModel(this.schema, field.type);
|
|
6335
|
+
graph.push([
|
|
6336
|
+
model,
|
|
6337
|
+
targetModel
|
|
6338
|
+
]);
|
|
6339
|
+
added = true;
|
|
6340
|
+
}
|
|
6341
|
+
}
|
|
6342
|
+
if (!added) {
|
|
6343
|
+
graph.push([
|
|
6344
|
+
model,
|
|
6345
|
+
void 0
|
|
6346
|
+
]);
|
|
6347
|
+
}
|
|
6348
|
+
}
|
|
6349
|
+
return (0, import_toposort.default)(graph).reverse().filter((m) => !!m);
|
|
6350
|
+
}
|
|
6351
|
+
createModelTable(kysely, modelDef) {
|
|
6352
|
+
let table = kysely.schema.createTable(modelDef.name).ifNotExists();
|
|
6319
6353
|
for (const [fieldName, fieldDef] of Object.entries(modelDef.fields)) {
|
|
6354
|
+
if (fieldDef.originModel && !fieldDef.id) {
|
|
6355
|
+
continue;
|
|
6356
|
+
}
|
|
6320
6357
|
if (fieldDef.relation) {
|
|
6321
|
-
table = this.addForeignKeyConstraint(table,
|
|
6358
|
+
table = this.addForeignKeyConstraint(table, modelDef.name, fieldName, fieldDef);
|
|
6322
6359
|
} else if (!this.isComputedField(fieldDef)) {
|
|
6323
|
-
table = this.createModelField(table,
|
|
6360
|
+
table = this.createModelField(table, fieldDef, modelDef);
|
|
6324
6361
|
}
|
|
6325
6362
|
}
|
|
6326
|
-
|
|
6327
|
-
|
|
6363
|
+
if (modelDef.baseModel) {
|
|
6364
|
+
const baseModelDef = requireModel(this.schema, modelDef.baseModel);
|
|
6365
|
+
table = table.addForeignKeyConstraint(`fk_${modelDef.baseModel}_delegate`, baseModelDef.idFields, modelDef.baseModel, baseModelDef.idFields, (cb) => cb.onDelete("cascade").onUpdate("cascade"));
|
|
6366
|
+
}
|
|
6367
|
+
table = this.addPrimaryKeyConstraint(table, modelDef);
|
|
6368
|
+
table = this.addUniqueConstraint(table, modelDef);
|
|
6328
6369
|
return table;
|
|
6329
6370
|
}
|
|
6330
6371
|
isComputedField(fieldDef) {
|
|
6331
6372
|
return fieldDef.attributes?.some((a) => a.name === "@computed");
|
|
6332
6373
|
}
|
|
6333
|
-
addPrimaryKeyConstraint(table,
|
|
6374
|
+
addPrimaryKeyConstraint(table, modelDef) {
|
|
6334
6375
|
if (modelDef.idFields.length === 1) {
|
|
6335
6376
|
if (Object.values(modelDef.fields).some((f) => f.id)) {
|
|
6336
6377
|
return table;
|
|
6337
6378
|
}
|
|
6338
6379
|
}
|
|
6339
6380
|
if (modelDef.idFields.length > 0) {
|
|
6340
|
-
table = table.addPrimaryKeyConstraint(`pk_${
|
|
6381
|
+
table = table.addPrimaryKeyConstraint(`pk_${modelDef.name}`, modelDef.idFields);
|
|
6341
6382
|
}
|
|
6342
6383
|
return table;
|
|
6343
6384
|
}
|
|
6344
|
-
addUniqueConstraint(table,
|
|
6385
|
+
addUniqueConstraint(table, modelDef) {
|
|
6345
6386
|
for (const [key, value] of Object.entries(modelDef.uniqueFields)) {
|
|
6346
6387
|
(0, import_common_helpers11.invariant)(typeof value === "object", "expecting an object");
|
|
6347
6388
|
if ("type" in value) {
|
|
@@ -6349,17 +6390,17 @@ var SchemaDbPusher = class {
|
|
|
6349
6390
|
if (fieldDef.unique) {
|
|
6350
6391
|
continue;
|
|
6351
6392
|
}
|
|
6352
|
-
table = table.addUniqueConstraint(`unique_${
|
|
6393
|
+
table = table.addUniqueConstraint(`unique_${modelDef.name}_${key}`, [
|
|
6353
6394
|
key
|
|
6354
6395
|
]);
|
|
6355
6396
|
} else {
|
|
6356
|
-
table = table.addUniqueConstraint(`unique_${
|
|
6397
|
+
table = table.addUniqueConstraint(`unique_${modelDef.name}_${key}`, Object.keys(value));
|
|
6357
6398
|
}
|
|
6358
6399
|
}
|
|
6359
6400
|
return table;
|
|
6360
6401
|
}
|
|
6361
|
-
createModelField(table,
|
|
6362
|
-
return table.addColumn(
|
|
6402
|
+
createModelField(table, fieldDef, modelDef) {
|
|
6403
|
+
return table.addColumn(fieldDef.name, this.mapFieldType(fieldDef), (col) => {
|
|
6363
6404
|
if (fieldDef.id && modelDef.idFields.length === 1) {
|
|
6364
6405
|
col = col.primaryKey();
|
|
6365
6406
|
}
|