arkormx 0.2.10 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/cli.mjs +39 -9
- package/dist/index.cjs +553 -43
- package/dist/index.d.cts +246 -9
- package/dist/index.d.mts +246 -9
- package/dist/index.mjs +544 -44
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -34,6 +34,7 @@ let path = require("path");
|
|
|
34
34
|
path = __toESM(path);
|
|
35
35
|
let fs = require("fs");
|
|
36
36
|
let url = require("url");
|
|
37
|
+
let async_hooks = require("async_hooks");
|
|
37
38
|
let module$1 = require("module");
|
|
38
39
|
let _h3ravel_shared = require("@h3ravel/shared");
|
|
39
40
|
let _h3ravel_musket = require("@h3ravel/musket");
|
|
@@ -122,17 +123,43 @@ function resolveCast(definition) {
|
|
|
122
123
|
|
|
123
124
|
//#endregion
|
|
124
125
|
//#region src/Exceptions/ArkormException.ts
|
|
125
|
-
/**
|
|
126
|
-
* The ArkormException class is a custom error type for handling
|
|
127
|
-
* exceptions specific to the Arkormˣ.
|
|
128
|
-
*
|
|
129
|
-
* @author Legacy (3m1n3nc3)
|
|
130
|
-
* @since 0.1.0
|
|
131
|
-
*/
|
|
132
126
|
var ArkormException = class extends Error {
|
|
133
|
-
|
|
134
|
-
|
|
127
|
+
code;
|
|
128
|
+
operation;
|
|
129
|
+
model;
|
|
130
|
+
delegate;
|
|
131
|
+
relation;
|
|
132
|
+
scope;
|
|
133
|
+
meta;
|
|
134
|
+
constructor(message, context = {}) {
|
|
135
|
+
super(message, context.cause === void 0 ? void 0 : { cause: context.cause });
|
|
135
136
|
this.name = "ArkormException";
|
|
137
|
+
this.code = context.code;
|
|
138
|
+
this.operation = context.operation;
|
|
139
|
+
this.model = context.model;
|
|
140
|
+
this.delegate = context.delegate;
|
|
141
|
+
this.relation = context.relation;
|
|
142
|
+
this.scope = context.scope;
|
|
143
|
+
this.meta = context.meta;
|
|
144
|
+
}
|
|
145
|
+
getContext() {
|
|
146
|
+
return {
|
|
147
|
+
code: this.code,
|
|
148
|
+
operation: this.operation,
|
|
149
|
+
model: this.model,
|
|
150
|
+
delegate: this.delegate,
|
|
151
|
+
relation: this.relation,
|
|
152
|
+
scope: this.scope,
|
|
153
|
+
meta: this.meta,
|
|
154
|
+
cause: this.cause
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
toJSON() {
|
|
158
|
+
return {
|
|
159
|
+
name: this.name,
|
|
160
|
+
message: this.message,
|
|
161
|
+
...this.getContext()
|
|
162
|
+
};
|
|
136
163
|
}
|
|
137
164
|
};
|
|
138
165
|
|
|
@@ -1242,6 +1269,18 @@ const runMigrationWithPrisma = async (migration, options = {}) => {
|
|
|
1242
1269
|
};
|
|
1243
1270
|
};
|
|
1244
1271
|
|
|
1272
|
+
//#endregion
|
|
1273
|
+
//#region src/Exceptions/UnsupportedAdapterFeatureException.ts
|
|
1274
|
+
var UnsupportedAdapterFeatureException = class extends ArkormException {
|
|
1275
|
+
constructor(message, context = {}) {
|
|
1276
|
+
super(message, {
|
|
1277
|
+
code: "UNSUPPORTED_ADAPTER_FEATURE",
|
|
1278
|
+
...context
|
|
1279
|
+
});
|
|
1280
|
+
this.name = "UnsupportedAdapterFeatureException";
|
|
1281
|
+
}
|
|
1282
|
+
};
|
|
1283
|
+
|
|
1245
1284
|
//#endregion
|
|
1246
1285
|
//#region src/helpers/runtime-config.ts
|
|
1247
1286
|
const resolveDefaultStubsPath = () => {
|
|
@@ -1275,6 +1314,8 @@ let runtimeConfigLoaded = false;
|
|
|
1275
1314
|
let runtimeConfigLoadingPromise;
|
|
1276
1315
|
let runtimeClientResolver;
|
|
1277
1316
|
let runtimePaginationURLDriverFactory;
|
|
1317
|
+
let runtimePaginationCurrentPageResolver;
|
|
1318
|
+
const transactionClientStorage = new async_hooks.AsyncLocalStorage();
|
|
1278
1319
|
const mergePathConfig = (paths) => {
|
|
1279
1320
|
const defaults = baseConfig.paths ?? {};
|
|
1280
1321
|
const current = userConfig.paths ?? {};
|
|
@@ -1324,6 +1365,7 @@ const configureArkormRuntime = (prisma, options = {}) => {
|
|
|
1324
1365
|
Object.assign(userConfig, { ...nextConfig });
|
|
1325
1366
|
runtimeClientResolver = prisma;
|
|
1326
1367
|
runtimePaginationURLDriverFactory = nextConfig.pagination?.urlDriver;
|
|
1368
|
+
runtimePaginationCurrentPageResolver = nextConfig.pagination?.resolveCurrentPage;
|
|
1327
1369
|
};
|
|
1328
1370
|
/**
|
|
1329
1371
|
* Reset the ArkORM runtime configuration.
|
|
@@ -1338,6 +1380,7 @@ const resetArkormRuntimeForTests = () => {
|
|
|
1338
1380
|
runtimeConfigLoadingPromise = void 0;
|
|
1339
1381
|
runtimeClientResolver = void 0;
|
|
1340
1382
|
runtimePaginationURLDriverFactory = void 0;
|
|
1383
|
+
runtimePaginationCurrentPageResolver = void 0;
|
|
1341
1384
|
};
|
|
1342
1385
|
/**
|
|
1343
1386
|
* Resolve a Prisma client instance from the provided resolver, which can be either
|
|
@@ -1440,9 +1483,36 @@ const getDefaultStubsPath = () => {
|
|
|
1440
1483
|
* @returns
|
|
1441
1484
|
*/
|
|
1442
1485
|
const getRuntimePrismaClient = () => {
|
|
1486
|
+
const activeTransactionClient = transactionClientStorage.getStore();
|
|
1487
|
+
if (activeTransactionClient) return activeTransactionClient;
|
|
1443
1488
|
if (!runtimeConfigLoaded) loadRuntimeConfigSync();
|
|
1444
1489
|
return resolveClient(runtimeClientResolver);
|
|
1445
1490
|
};
|
|
1491
|
+
const getActiveTransactionClient = () => {
|
|
1492
|
+
return transactionClientStorage.getStore();
|
|
1493
|
+
};
|
|
1494
|
+
const isTransactionCapableClient = (value) => {
|
|
1495
|
+
if (!value || typeof value !== "object") return false;
|
|
1496
|
+
return typeof value.$transaction === "function";
|
|
1497
|
+
};
|
|
1498
|
+
const runArkormTransaction = async (callback, options = {}) => {
|
|
1499
|
+
const activeTransactionClient = transactionClientStorage.getStore();
|
|
1500
|
+
if (activeTransactionClient) return await callback(activeTransactionClient);
|
|
1501
|
+
const client = getRuntimePrismaClient();
|
|
1502
|
+
if (!client) throw new ArkormException("Cannot start a transaction without a configured Prisma client.", {
|
|
1503
|
+
code: "CLIENT_NOT_CONFIGURED",
|
|
1504
|
+
operation: "transaction"
|
|
1505
|
+
});
|
|
1506
|
+
if (!isTransactionCapableClient(client)) throw new UnsupportedAdapterFeatureException("Transactions are not supported by the current adapter.", {
|
|
1507
|
+
code: "TRANSACTION_NOT_SUPPORTED",
|
|
1508
|
+
operation: "transaction"
|
|
1509
|
+
});
|
|
1510
|
+
return await client.$transaction(async (transactionClient) => {
|
|
1511
|
+
return await transactionClientStorage.run(transactionClient, async () => {
|
|
1512
|
+
return await callback(transactionClient);
|
|
1513
|
+
});
|
|
1514
|
+
}, options);
|
|
1515
|
+
};
|
|
1446
1516
|
/**
|
|
1447
1517
|
* Get the configured pagination URL driver factory from runtime config.
|
|
1448
1518
|
*
|
|
@@ -1453,6 +1523,15 @@ const getRuntimePaginationURLDriverFactory = () => {
|
|
|
1453
1523
|
return runtimePaginationURLDriverFactory;
|
|
1454
1524
|
};
|
|
1455
1525
|
/**
|
|
1526
|
+
* Get the configured current-page resolver from runtime config.
|
|
1527
|
+
*
|
|
1528
|
+
* @returns
|
|
1529
|
+
*/
|
|
1530
|
+
const getRuntimePaginationCurrentPageResolver = () => {
|
|
1531
|
+
if (!runtimeConfigLoaded) loadRuntimeConfigSync();
|
|
1532
|
+
return runtimePaginationCurrentPageResolver;
|
|
1533
|
+
};
|
|
1534
|
+
/**
|
|
1456
1535
|
* Check if a given value is a Prisma delegate-like object
|
|
1457
1536
|
* by verifying the presence of common delegate methods.
|
|
1458
1537
|
*
|
|
@@ -2789,6 +2868,18 @@ const defineFactory = (model, definition) => {
|
|
|
2789
2868
|
return new InlineFactory(model, definition);
|
|
2790
2869
|
};
|
|
2791
2870
|
|
|
2871
|
+
//#endregion
|
|
2872
|
+
//#region src/Exceptions/MissingDelegateException.ts
|
|
2873
|
+
var MissingDelegateException = class extends ArkormException {
|
|
2874
|
+
constructor(message, context = {}) {
|
|
2875
|
+
super(message, {
|
|
2876
|
+
code: "MISSING_DELEGATE",
|
|
2877
|
+
...context
|
|
2878
|
+
});
|
|
2879
|
+
this.name = "MissingDelegateException";
|
|
2880
|
+
}
|
|
2881
|
+
};
|
|
2882
|
+
|
|
2792
2883
|
//#endregion
|
|
2793
2884
|
//#region src/Exceptions/ModelNotFoundException.ts
|
|
2794
2885
|
/**
|
|
@@ -2800,8 +2891,12 @@ const defineFactory = (model, definition) => {
|
|
|
2800
2891
|
*/
|
|
2801
2892
|
var ModelNotFoundException = class extends ArkormException {
|
|
2802
2893
|
modelName;
|
|
2803
|
-
constructor(modelName, message = "No query results for the given model.") {
|
|
2804
|
-
super(message
|
|
2894
|
+
constructor(modelName, message = "No query results for the given model.", context = {}) {
|
|
2895
|
+
super(message, {
|
|
2896
|
+
code: "MODEL_NOT_FOUND",
|
|
2897
|
+
model: modelName,
|
|
2898
|
+
...context
|
|
2899
|
+
});
|
|
2805
2900
|
this.name = "ModelNotFoundException";
|
|
2806
2901
|
this.modelName = modelName;
|
|
2807
2902
|
}
|
|
@@ -2810,6 +2905,54 @@ var ModelNotFoundException = class extends ArkormException {
|
|
|
2810
2905
|
}
|
|
2811
2906
|
};
|
|
2812
2907
|
|
|
2908
|
+
//#endregion
|
|
2909
|
+
//#region src/Exceptions/QueryConstraintException.ts
|
|
2910
|
+
var QueryConstraintException = class extends ArkormException {
|
|
2911
|
+
constructor(message, context = {}) {
|
|
2912
|
+
super(message, {
|
|
2913
|
+
code: "QUERY_CONSTRAINT",
|
|
2914
|
+
...context
|
|
2915
|
+
});
|
|
2916
|
+
this.name = "QueryConstraintException";
|
|
2917
|
+
}
|
|
2918
|
+
};
|
|
2919
|
+
|
|
2920
|
+
//#endregion
|
|
2921
|
+
//#region src/Exceptions/RelationResolutionException.ts
|
|
2922
|
+
var RelationResolutionException = class extends ArkormException {
|
|
2923
|
+
constructor(message, context = {}) {
|
|
2924
|
+
super(message, {
|
|
2925
|
+
code: "RELATION_RESOLUTION_FAILED",
|
|
2926
|
+
...context
|
|
2927
|
+
});
|
|
2928
|
+
this.name = "RelationResolutionException";
|
|
2929
|
+
}
|
|
2930
|
+
};
|
|
2931
|
+
|
|
2932
|
+
//#endregion
|
|
2933
|
+
//#region src/Exceptions/ScopeNotDefinedException.ts
|
|
2934
|
+
var ScopeNotDefinedException = class extends ArkormException {
|
|
2935
|
+
constructor(message, context = {}) {
|
|
2936
|
+
super(message, {
|
|
2937
|
+
code: "SCOPE_NOT_DEFINED",
|
|
2938
|
+
...context
|
|
2939
|
+
});
|
|
2940
|
+
this.name = "ScopeNotDefinedException";
|
|
2941
|
+
}
|
|
2942
|
+
};
|
|
2943
|
+
|
|
2944
|
+
//#endregion
|
|
2945
|
+
//#region src/Exceptions/UniqueConstraintResolutionException.ts
|
|
2946
|
+
var UniqueConstraintResolutionException = class extends ArkormException {
|
|
2947
|
+
constructor(message, context = {}) {
|
|
2948
|
+
super(message, {
|
|
2949
|
+
code: "UNIQUE_CONSTRAINT_RESOLUTION_FAILED",
|
|
2950
|
+
...context
|
|
2951
|
+
});
|
|
2952
|
+
this.name = "UniqueConstraintResolutionException";
|
|
2953
|
+
}
|
|
2954
|
+
};
|
|
2955
|
+
|
|
2813
2956
|
//#endregion
|
|
2814
2957
|
//#region src/helpers/prisma.ts
|
|
2815
2958
|
/**
|
|
@@ -3050,6 +3193,7 @@ var BelongsToManyRelation = class extends Relation {
|
|
|
3050
3193
|
async getResults() {
|
|
3051
3194
|
const parentValue = this.parent.getAttribute(this.parentKey);
|
|
3052
3195
|
const ids = (await this.related.getDelegate(this.throughDelegate).findMany({ where: { [this.foreignPivotKey]: parentValue } })).map((row) => row[this.relatedPivotKey]);
|
|
3196
|
+
if (ids.length === 0) return new ArkormCollection([]);
|
|
3053
3197
|
return this.applyConstraint(this.related.query().where({ [this.relatedKey]: { in: ids } })).get();
|
|
3054
3198
|
}
|
|
3055
3199
|
};
|
|
@@ -3136,6 +3280,7 @@ var HasManyThroughRelation = class extends Relation {
|
|
|
3136
3280
|
async getResults() {
|
|
3137
3281
|
const localValue = this.parent.getAttribute(this.localKey);
|
|
3138
3282
|
const keys = (await this.related.getDelegate(this.throughDelegate).findMany({ where: { [this.firstKey]: localValue } })).map((row) => row[this.secondLocalKey]);
|
|
3283
|
+
if (keys.length === 0) return new ArkormCollection([]);
|
|
3139
3284
|
return this.applyConstraint(this.related.query().where({ [this.secondKey]: { in: keys } })).get();
|
|
3140
3285
|
}
|
|
3141
3286
|
};
|
|
@@ -3293,6 +3438,7 @@ var MorphToManyRelation = class extends Relation {
|
|
|
3293
3438
|
[`${this.morphName}Id`]: parentValue,
|
|
3294
3439
|
[`${this.morphName}Type`]: morphType
|
|
3295
3440
|
} })).map((row) => row[this.relatedPivotKey]);
|
|
3441
|
+
if (ids.length === 0) return new ArkormCollection([]);
|
|
3296
3442
|
return this.applyConstraint(this.related.query().where({ [this.relatedKey]: { in: ids } })).get();
|
|
3297
3443
|
}
|
|
3298
3444
|
};
|
|
@@ -3505,6 +3651,13 @@ var QueryBuilder = class QueryBuilder {
|
|
|
3505
3651
|
this.delegate = delegate;
|
|
3506
3652
|
this.model = model;
|
|
3507
3653
|
}
|
|
3654
|
+
resolvePaginationPage(page, options) {
|
|
3655
|
+
if (typeof page !== "undefined") return Number.isFinite(page) ? Math.max(1, page) : 1;
|
|
3656
|
+
const pageName = options.pageName ?? "page";
|
|
3657
|
+
const resolvedPage = getRuntimePaginationCurrentPageResolver()?.(pageName, options);
|
|
3658
|
+
if (typeof resolvedPage !== "number" || !Number.isFinite(resolvedPage)) return 1;
|
|
3659
|
+
return Math.max(1, resolvedPage);
|
|
3660
|
+
}
|
|
3508
3661
|
/**
|
|
3509
3662
|
* Adds a where clause to the query. Multiple calls to where will combine
|
|
3510
3663
|
* the clauses with AND logic.
|
|
@@ -4037,7 +4190,11 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4037
4190
|
scope(name, ...args) {
|
|
4038
4191
|
const methodName = `scope${name.charAt(0).toUpperCase()}${name.slice(1)}`;
|
|
4039
4192
|
const scope = this.model.prototype?.[methodName];
|
|
4040
|
-
if (typeof scope !== "function") throw new
|
|
4193
|
+
if (typeof scope !== "function") throw new ScopeNotDefinedException(`Scope [${name}] is not defined.`, {
|
|
4194
|
+
operation: "scope",
|
|
4195
|
+
model: this.model.name,
|
|
4196
|
+
scope: name
|
|
4197
|
+
});
|
|
4041
4198
|
const scoped = scope.call(void 0, this, ...args);
|
|
4042
4199
|
if (scoped && scoped !== this) return scoped;
|
|
4043
4200
|
return this;
|
|
@@ -4159,7 +4316,7 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4159
4316
|
const relationCache = /* @__PURE__ */ new WeakMap();
|
|
4160
4317
|
const rows = await this.delegate.findMany(this.buildFindArgs());
|
|
4161
4318
|
const normalizedRows = this.randomOrderEnabled ? this.shuffleRows(rows) : rows;
|
|
4162
|
-
const models = this.model.
|
|
4319
|
+
const models = await this.model.hydrateManyRetrieved(normalizedRows);
|
|
4163
4320
|
let filteredModels = models;
|
|
4164
4321
|
if (this.hasRelationFilters()) if (this.hasOrRelationFilters() && this.args.where) {
|
|
4165
4322
|
const baseIds = new Set(models.map((model) => this.getModelId(model)).filter((id) => id != null));
|
|
@@ -4189,13 +4346,13 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4189
4346
|
if (rows.length === 0) return null;
|
|
4190
4347
|
const row = this.shuffleRows(rows)[0];
|
|
4191
4348
|
if (!row) return null;
|
|
4192
|
-
const model = this.model.
|
|
4349
|
+
const model = await this.model.hydrateRetrieved(row);
|
|
4193
4350
|
await model.load(this.eagerLoads);
|
|
4194
4351
|
return model;
|
|
4195
4352
|
}
|
|
4196
4353
|
const row = await this.delegate.findFirst(this.buildFindArgs());
|
|
4197
4354
|
if (!row) return null;
|
|
4198
|
-
const model = this.model.
|
|
4355
|
+
const model = await this.model.hydrateRetrieved(row);
|
|
4199
4356
|
await model.load(this.eagerLoads);
|
|
4200
4357
|
return model;
|
|
4201
4358
|
}
|
|
@@ -4215,7 +4372,10 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4215
4372
|
async findOr(value, keyOrCallback, maybeCallback) {
|
|
4216
4373
|
const key = typeof keyOrCallback === "string" ? keyOrCallback : "id";
|
|
4217
4374
|
const callback = typeof keyOrCallback === "function" ? keyOrCallback : maybeCallback;
|
|
4218
|
-
if (!callback) throw new
|
|
4375
|
+
if (!callback) throw new QueryConstraintException("findOr requires a fallback callback.", {
|
|
4376
|
+
operation: "findOr",
|
|
4377
|
+
model: this.model.name
|
|
4378
|
+
});
|
|
4219
4379
|
const found = await this.find(value, key);
|
|
4220
4380
|
if (found) return found;
|
|
4221
4381
|
return callback();
|
|
@@ -4329,7 +4489,11 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4329
4489
|
async insertGetId(values, sequence) {
|
|
4330
4490
|
const created = await this.delegate.create({ data: values });
|
|
4331
4491
|
const key = sequence ?? "id";
|
|
4332
|
-
if (!(key in created)) throw new
|
|
4492
|
+
if (!(key in created)) throw new UniqueConstraintResolutionException(`Inserted record does not contain key [${key}].`, {
|
|
4493
|
+
operation: "insertGetId",
|
|
4494
|
+
model: this.model.name,
|
|
4495
|
+
meta: { key }
|
|
4496
|
+
});
|
|
4333
4497
|
return created[key];
|
|
4334
4498
|
}
|
|
4335
4499
|
/**
|
|
@@ -4366,7 +4530,10 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4366
4530
|
*/
|
|
4367
4531
|
async update(data) {
|
|
4368
4532
|
const where = this.buildWhere();
|
|
4369
|
-
if (!where) throw new
|
|
4533
|
+
if (!where) throw new QueryConstraintException("Update requires a where clause.", {
|
|
4534
|
+
operation: "update",
|
|
4535
|
+
model: this.model.name
|
|
4536
|
+
});
|
|
4370
4537
|
const uniqueWhere = await this.resolveUniqueWhere(where);
|
|
4371
4538
|
const updated = await this.delegate.update({
|
|
4372
4539
|
where: uniqueWhere,
|
|
@@ -4382,7 +4549,10 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4382
4549
|
*/
|
|
4383
4550
|
async updateFrom(data) {
|
|
4384
4551
|
const where = this.buildWhere();
|
|
4385
|
-
if (!where) throw new
|
|
4552
|
+
if (!where) throw new QueryConstraintException("Update requires a where clause.", {
|
|
4553
|
+
operation: "updateFrom",
|
|
4554
|
+
model: this.model.name
|
|
4555
|
+
});
|
|
4386
4556
|
const delegate = this.delegate;
|
|
4387
4557
|
if (typeof delegate.updateMany === "function") {
|
|
4388
4558
|
const result = await delegate.updateMany({
|
|
@@ -4447,7 +4617,10 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4447
4617
|
*/
|
|
4448
4618
|
async delete() {
|
|
4449
4619
|
const where = this.buildWhere();
|
|
4450
|
-
if (!where) throw new
|
|
4620
|
+
if (!where) throw new QueryConstraintException("Delete requires a where clause.", {
|
|
4621
|
+
operation: "delete",
|
|
4622
|
+
model: this.model.name
|
|
4623
|
+
});
|
|
4451
4624
|
const uniqueWhere = await this.resolveUniqueWhere(where);
|
|
4452
4625
|
const deleted = await this.delegate.delete({ where: uniqueWhere });
|
|
4453
4626
|
return this.model.hydrate(deleted);
|
|
@@ -4513,7 +4686,10 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4513
4686
|
if (Array.isArray(source)) return source;
|
|
4514
4687
|
}
|
|
4515
4688
|
if (Array.isArray(source)) return source;
|
|
4516
|
-
throw new
|
|
4689
|
+
throw new QueryConstraintException("insertUsing expects a query builder, array of records, or async resolver.", {
|
|
4690
|
+
operation: "insertUsing",
|
|
4691
|
+
model: this.model.name
|
|
4692
|
+
});
|
|
4517
4693
|
}
|
|
4518
4694
|
/**
|
|
4519
4695
|
* Execute callback when no records exist.
|
|
@@ -4597,7 +4773,11 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4597
4773
|
*/
|
|
4598
4774
|
whereRaw(sql, bindings = []) {
|
|
4599
4775
|
const delegate = this.delegate;
|
|
4600
|
-
if (typeof delegate.applyRawWhere !== "function") throw new
|
|
4776
|
+
if (typeof delegate.applyRawWhere !== "function") throw new UnsupportedAdapterFeatureException("Raw where clauses are not supported by the current adapter.", {
|
|
4777
|
+
operation: "whereRaw",
|
|
4778
|
+
model: this.model.name,
|
|
4779
|
+
meta: { feature: "rawWhere" }
|
|
4780
|
+
});
|
|
4601
4781
|
this.args.where = delegate.applyRawWhere(this.buildWhere(), sql, bindings);
|
|
4602
4782
|
return this;
|
|
4603
4783
|
}
|
|
@@ -4610,7 +4790,11 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4610
4790
|
*/
|
|
4611
4791
|
orWhereRaw(sql, bindings = []) {
|
|
4612
4792
|
const delegate = this.delegate;
|
|
4613
|
-
if (typeof delegate.applyRawWhere !== "function") throw new
|
|
4793
|
+
if (typeof delegate.applyRawWhere !== "function") throw new UnsupportedAdapterFeatureException("Raw where clauses are not supported by the current adapter.", {
|
|
4794
|
+
operation: "orWhereRaw",
|
|
4795
|
+
model: this.model.name,
|
|
4796
|
+
meta: { feature: "rawWhere" }
|
|
4797
|
+
});
|
|
4614
4798
|
const rawWhere = delegate.applyRawWhere(void 0, sql, bindings);
|
|
4615
4799
|
return this.orWhere(rawWhere);
|
|
4616
4800
|
}
|
|
@@ -4623,15 +4807,14 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4623
4807
|
* @param options
|
|
4624
4808
|
* @returns
|
|
4625
4809
|
*/
|
|
4626
|
-
async paginate(
|
|
4810
|
+
async paginate(perPage = 15, page = void 0, options = {}) {
|
|
4811
|
+
const currentPage = this.resolvePaginationPage(page, options);
|
|
4627
4812
|
if (this.hasRelationFilters() || this.hasRelationAggregates()) {
|
|
4628
|
-
const currentPage = Math.max(1, page);
|
|
4629
4813
|
const pageSize = Math.max(1, perPage);
|
|
4630
4814
|
const rows = (await this.get()).all();
|
|
4631
4815
|
const start = (currentPage - 1) * pageSize;
|
|
4632
4816
|
return new LengthAwarePaginator(new ArkormCollection(rows.slice(start, start + pageSize)), rows.length, pageSize, currentPage, options);
|
|
4633
4817
|
}
|
|
4634
|
-
const currentPage = Math.max(1, page);
|
|
4635
4818
|
const pageSize = Math.max(1, perPage);
|
|
4636
4819
|
const total = await this.count();
|
|
4637
4820
|
return new LengthAwarePaginator(await this.clone().skip((currentPage - 1) * pageSize).take(pageSize).get(), total, pageSize, currentPage, options);
|
|
@@ -4643,9 +4826,9 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4643
4826
|
* @param page
|
|
4644
4827
|
* @returns
|
|
4645
4828
|
*/
|
|
4646
|
-
async simplePaginate(perPage = 15, page =
|
|
4829
|
+
async simplePaginate(perPage = 15, page = void 0, options = {}) {
|
|
4830
|
+
const currentPage = this.resolvePaginationPage(page, options);
|
|
4647
4831
|
if (this.hasRelationFilters() || this.hasRelationAggregates()) {
|
|
4648
|
-
const currentPage = Math.max(1, page);
|
|
4649
4832
|
const pageSize = Math.max(1, perPage);
|
|
4650
4833
|
const rows = (await this.get()).all();
|
|
4651
4834
|
const start = (currentPage - 1) * pageSize;
|
|
@@ -4653,7 +4836,6 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4653
4836
|
const hasMorePages = start + pageSize < rows.length;
|
|
4654
4837
|
return new Paginator(new ArkormCollection(pageRows), pageSize, currentPage, hasMorePages, options);
|
|
4655
4838
|
}
|
|
4656
|
-
const currentPage = Math.max(1, page);
|
|
4657
4839
|
const pageSize = Math.max(1, perPage);
|
|
4658
4840
|
const items = await this.clone().skip((currentPage - 1) * pageSize).take(pageSize + 1).get();
|
|
4659
4841
|
const hasMorePages = items.all().length > pageSize;
|
|
@@ -4734,9 +4916,16 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4734
4916
|
async resolveUniqueWhere(where) {
|
|
4735
4917
|
if (this.isUniqueWhere(where)) return where;
|
|
4736
4918
|
const row = await this.delegate.findFirst({ where });
|
|
4737
|
-
if (!row) throw new
|
|
4919
|
+
if (!row) throw new ModelNotFoundException(this.model.name, "Record not found for update/delete operation.", {
|
|
4920
|
+
operation: "resolveUniqueWhere",
|
|
4921
|
+
meta: { where }
|
|
4922
|
+
});
|
|
4738
4923
|
const record = row;
|
|
4739
|
-
if (!Object.prototype.hasOwnProperty.call(record, "id")) throw new
|
|
4924
|
+
if (!Object.prototype.hasOwnProperty.call(record, "id")) throw new UniqueConstraintResolutionException("Unable to resolve a unique identifier for update/delete operation. Include an id in the query constraints.", {
|
|
4925
|
+
operation: "resolveUniqueWhere",
|
|
4926
|
+
model: this.model.name,
|
|
4927
|
+
meta: { where }
|
|
4928
|
+
});
|
|
4740
4929
|
return { id: record.id };
|
|
4741
4930
|
}
|
|
4742
4931
|
/**
|
|
@@ -4859,7 +5048,11 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4859
5048
|
if (cached) return await cached;
|
|
4860
5049
|
const resolver = (async () => {
|
|
4861
5050
|
const relationMethod = model[relation];
|
|
4862
|
-
if (typeof relationMethod !== "function") throw new
|
|
5051
|
+
if (typeof relationMethod !== "function") throw new RelationResolutionException(`Relation [${relation}] is not defined on the model.`, {
|
|
5052
|
+
operation: "resolveRelatedResults",
|
|
5053
|
+
model: this.model.name,
|
|
5054
|
+
relation
|
|
5055
|
+
});
|
|
4863
5056
|
const relationInstance = relationMethod.call(model);
|
|
4864
5057
|
if (callback && typeof relationInstance.constrain === "function") relationInstance.constrain((query) => {
|
|
4865
5058
|
return callback(query) ?? query;
|
|
@@ -4874,7 +5067,11 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4874
5067
|
if (results instanceof ArkormCollection) return results.all();
|
|
4875
5068
|
return results;
|
|
4876
5069
|
}
|
|
4877
|
-
throw new
|
|
5070
|
+
throw new RelationResolutionException(`Relation [${relation}] does not support result resolution.`, {
|
|
5071
|
+
operation: "resolveRelatedResults",
|
|
5072
|
+
model: this.model.name,
|
|
5073
|
+
relation
|
|
5074
|
+
});
|
|
4878
5075
|
})();
|
|
4879
5076
|
callbackMap.set(callbackCacheKey, resolver);
|
|
4880
5077
|
return await resolver;
|
|
@@ -4915,6 +5112,8 @@ var QueryBuilder = class QueryBuilder {
|
|
|
4915
5112
|
* @since 0.1.0
|
|
4916
5113
|
*/
|
|
4917
5114
|
var Model = class Model {
|
|
5115
|
+
static lifecycleStates = /* @__PURE__ */ new WeakMap();
|
|
5116
|
+
static eventsSuppressed = 0;
|
|
4918
5117
|
static factoryClass;
|
|
4919
5118
|
static client;
|
|
4920
5119
|
static delegate;
|
|
@@ -4922,6 +5121,7 @@ var Model = class Model {
|
|
|
4922
5121
|
static deletedAtColumn = "deletedAt";
|
|
4923
5122
|
static globalScopes = {};
|
|
4924
5123
|
static eventListeners = {};
|
|
5124
|
+
static dispatchesEvents = {};
|
|
4925
5125
|
casts = {};
|
|
4926
5126
|
hidden = [];
|
|
4927
5127
|
visible = [];
|
|
@@ -4959,7 +5159,11 @@ var Model = class Model {
|
|
|
4959
5159
|
}
|
|
4960
5160
|
static factory(count) {
|
|
4961
5161
|
const factoryClass = this.factoryClass;
|
|
4962
|
-
if (!factoryClass) throw new ArkormException(`Factory is not configured for model [${this.name}]
|
|
5162
|
+
if (!factoryClass) throw new ArkormException(`Factory is not configured for model [${this.name}].`, {
|
|
5163
|
+
code: "FACTORY_NOT_CONFIGURED",
|
|
5164
|
+
operation: "factory",
|
|
5165
|
+
model: this.name
|
|
5166
|
+
});
|
|
4963
5167
|
const factory = new factoryClass();
|
|
4964
5168
|
if (typeof count === "number") factory.count(count);
|
|
4965
5169
|
return factory;
|
|
@@ -4975,6 +5179,21 @@ var Model = class Model {
|
|
|
4975
5179
|
this.globalScopes[name] = scope;
|
|
4976
5180
|
}
|
|
4977
5181
|
/**
|
|
5182
|
+
* Execute a callback without applying global scopes for the current model class.
|
|
5183
|
+
*
|
|
5184
|
+
* @param callback
|
|
5185
|
+
* @returns
|
|
5186
|
+
*/
|
|
5187
|
+
static async withoutGlobalScopes(callback) {
|
|
5188
|
+
const state = Model.getLifecycleState(this);
|
|
5189
|
+
state.globalScopesSuppressed += 1;
|
|
5190
|
+
try {
|
|
5191
|
+
return await callback();
|
|
5192
|
+
} finally {
|
|
5193
|
+
state.globalScopesSuppressed = Math.max(0, state.globalScopesSuppressed - 1);
|
|
5194
|
+
}
|
|
5195
|
+
}
|
|
5196
|
+
/**
|
|
4978
5197
|
* Remove a global scope by name.
|
|
4979
5198
|
*
|
|
4980
5199
|
* @param name
|
|
@@ -4996,11 +5215,60 @@ var Model = class Model {
|
|
|
4996
5215
|
* @param listener
|
|
4997
5216
|
*/
|
|
4998
5217
|
static on(event, listener) {
|
|
5218
|
+
Model.ensureModelBooted(this);
|
|
4999
5219
|
this.ensureOwnEventListeners();
|
|
5000
5220
|
if (!this.eventListeners[event]) this.eventListeners[event] = [];
|
|
5001
5221
|
this.eventListeners[event]?.push(listener);
|
|
5002
5222
|
}
|
|
5003
5223
|
/**
|
|
5224
|
+
* Register a model lifecycle callback listener.
|
|
5225
|
+
*
|
|
5226
|
+
* @param event
|
|
5227
|
+
* @param listener
|
|
5228
|
+
*/
|
|
5229
|
+
static event(event, listener) {
|
|
5230
|
+
this.on(event, listener);
|
|
5231
|
+
}
|
|
5232
|
+
static retrieved(listener) {
|
|
5233
|
+
this.event("retrieved", listener);
|
|
5234
|
+
}
|
|
5235
|
+
static saving(listener) {
|
|
5236
|
+
this.event("saving", listener);
|
|
5237
|
+
}
|
|
5238
|
+
static saved(listener) {
|
|
5239
|
+
this.event("saved", listener);
|
|
5240
|
+
}
|
|
5241
|
+
static creating(listener) {
|
|
5242
|
+
this.event("creating", listener);
|
|
5243
|
+
}
|
|
5244
|
+
static created(listener) {
|
|
5245
|
+
this.event("created", listener);
|
|
5246
|
+
}
|
|
5247
|
+
static updating(listener) {
|
|
5248
|
+
this.event("updating", listener);
|
|
5249
|
+
}
|
|
5250
|
+
static updated(listener) {
|
|
5251
|
+
this.event("updated", listener);
|
|
5252
|
+
}
|
|
5253
|
+
static deleting(listener) {
|
|
5254
|
+
this.event("deleting", listener);
|
|
5255
|
+
}
|
|
5256
|
+
static deleted(listener) {
|
|
5257
|
+
this.event("deleted", listener);
|
|
5258
|
+
}
|
|
5259
|
+
static restoring(listener) {
|
|
5260
|
+
this.event("restoring", listener);
|
|
5261
|
+
}
|
|
5262
|
+
static restored(listener) {
|
|
5263
|
+
this.event("restored", listener);
|
|
5264
|
+
}
|
|
5265
|
+
static forceDeleting(listener) {
|
|
5266
|
+
this.event("forceDeleting", listener);
|
|
5267
|
+
}
|
|
5268
|
+
static forceDeleted(listener) {
|
|
5269
|
+
this.event("forceDeleted", listener);
|
|
5270
|
+
}
|
|
5271
|
+
/**
|
|
5004
5272
|
* Remove listeners for an event. If listener is omitted, all listeners for that event are removed.
|
|
5005
5273
|
*
|
|
5006
5274
|
* @param event
|
|
@@ -5021,6 +5289,34 @@ var Model = class Model {
|
|
|
5021
5289
|
this.eventListeners = {};
|
|
5022
5290
|
}
|
|
5023
5291
|
/**
|
|
5292
|
+
* Execute a callback while suppressing lifecycle events for all models.
|
|
5293
|
+
*
|
|
5294
|
+
* @param callback
|
|
5295
|
+
* @returns
|
|
5296
|
+
*/
|
|
5297
|
+
static async withoutEvents(callback) {
|
|
5298
|
+
Model.eventsSuppressed += 1;
|
|
5299
|
+
try {
|
|
5300
|
+
return await callback();
|
|
5301
|
+
} finally {
|
|
5302
|
+
Model.eventsSuppressed = Math.max(0, Model.eventsSuppressed - 1);
|
|
5303
|
+
}
|
|
5304
|
+
}
|
|
5305
|
+
/**
|
|
5306
|
+
* Execute a callback within a transaction scope.
|
|
5307
|
+
* Nested calls reuse the active transaction client.
|
|
5308
|
+
*
|
|
5309
|
+
* @param callback
|
|
5310
|
+
* @param options
|
|
5311
|
+
* @returns
|
|
5312
|
+
*/
|
|
5313
|
+
static async transaction(callback, options = {}) {
|
|
5314
|
+
ensureArkormConfigLoading();
|
|
5315
|
+
return await runArkormTransaction(async (client) => {
|
|
5316
|
+
return await callback(client);
|
|
5317
|
+
}, options);
|
|
5318
|
+
}
|
|
5319
|
+
/**
|
|
5024
5320
|
* Get the Prisma delegate for the model.
|
|
5025
5321
|
* If a delegate name is provided, it will attempt to resolve that delegate.
|
|
5026
5322
|
* Otherwise, it will attempt to resolve a delegate based on the model's name or
|
|
@@ -5038,9 +5334,20 @@ var Model = class Model {
|
|
|
5038
5334
|
`${(0, _h3ravel_support.str)(key).singular()}`,
|
|
5039
5335
|
`${(0, _h3ravel_support.str)(key).camel().singular()}`
|
|
5040
5336
|
];
|
|
5337
|
+
const activeTransactionClient = getActiveTransactionClient();
|
|
5041
5338
|
const runtimeClient = getRuntimePrismaClient();
|
|
5042
|
-
const
|
|
5043
|
-
|
|
5339
|
+
const sources = activeTransactionClient ? [
|
|
5340
|
+
activeTransactionClient,
|
|
5341
|
+
this.client,
|
|
5342
|
+
runtimeClient
|
|
5343
|
+
] : [this.client, runtimeClient];
|
|
5344
|
+
const resolved = candidates.flatMap((name) => sources.map((source) => source?.[name])).find((candidate) => isDelegateLike(candidate));
|
|
5345
|
+
if (!resolved) throw new MissingDelegateException(`Database delegate [${key}] is not configured.`, {
|
|
5346
|
+
operation: "getDelegate",
|
|
5347
|
+
model: this.name,
|
|
5348
|
+
delegate: key,
|
|
5349
|
+
meta: { candidates }
|
|
5350
|
+
});
|
|
5044
5351
|
return resolved;
|
|
5045
5352
|
}
|
|
5046
5353
|
/**
|
|
@@ -5050,16 +5357,27 @@ var Model = class Model {
|
|
|
5050
5357
|
* @returns
|
|
5051
5358
|
*/
|
|
5052
5359
|
static query() {
|
|
5360
|
+
Model.ensureModelBooted(this);
|
|
5053
5361
|
let builder = new QueryBuilder(this.getDelegate(), this);
|
|
5054
5362
|
const modelClass = this;
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5363
|
+
if (!Model.areGlobalScopesSuppressed(modelClass)) {
|
|
5364
|
+
modelClass.ensureOwnGlobalScopes();
|
|
5365
|
+
Object.values(modelClass.globalScopes).forEach((scope) => {
|
|
5366
|
+
const scoped = scope(builder);
|
|
5367
|
+
if (scoped && scoped !== builder) builder = scoped;
|
|
5368
|
+
});
|
|
5369
|
+
}
|
|
5060
5370
|
return builder;
|
|
5061
5371
|
}
|
|
5062
5372
|
/**
|
|
5373
|
+
* Boot hook for subclasses to register scopes or perform one-time setup.
|
|
5374
|
+
*/
|
|
5375
|
+
static boot() {}
|
|
5376
|
+
/**
|
|
5377
|
+
* Booted hook for subclasses to register callbacks after boot logic runs.
|
|
5378
|
+
*/
|
|
5379
|
+
static booted() {}
|
|
5380
|
+
/**
|
|
5063
5381
|
* Get a query builder instance that includes soft-deleted records.
|
|
5064
5382
|
*
|
|
5065
5383
|
* @param this
|
|
@@ -5122,6 +5440,36 @@ var Model = class Model {
|
|
|
5122
5440
|
static hydrateMany(attributes) {
|
|
5123
5441
|
return attributes.map((attribute) => new this(attribute));
|
|
5124
5442
|
}
|
|
5443
|
+
/**
|
|
5444
|
+
* Hydrate a model instance and dispatch the retrieved lifecycle event.
|
|
5445
|
+
*
|
|
5446
|
+
* @param this
|
|
5447
|
+
* @param attributes
|
|
5448
|
+
* @returns
|
|
5449
|
+
*/
|
|
5450
|
+
static async hydrateRetrieved(attributes) {
|
|
5451
|
+
Model.ensureModelBooted(this);
|
|
5452
|
+
if (!Model.hasEventListeners(this, "retrieved")) return this.hydrate(attributes);
|
|
5453
|
+
const model = this.hydrate(attributes);
|
|
5454
|
+
await Model.dispatchEvent(this, "retrieved", model);
|
|
5455
|
+
return model;
|
|
5456
|
+
}
|
|
5457
|
+
/**
|
|
5458
|
+
* Hydrate multiple model instances and dispatch the retrieved lifecycle event for each.
|
|
5459
|
+
*
|
|
5460
|
+
* @param this
|
|
5461
|
+
* @param attributes
|
|
5462
|
+
* @returns
|
|
5463
|
+
*/
|
|
5464
|
+
static async hydrateManyRetrieved(attributes) {
|
|
5465
|
+
Model.ensureModelBooted(this);
|
|
5466
|
+
if (!Model.hasEventListeners(this, "retrieved")) return this.hydrateMany(attributes);
|
|
5467
|
+
const models = this.hydrateMany(attributes);
|
|
5468
|
+
await Promise.all(models.map(async (model) => {
|
|
5469
|
+
await Model.dispatchEvent(this, "retrieved", model);
|
|
5470
|
+
}));
|
|
5471
|
+
return models;
|
|
5472
|
+
}
|
|
5125
5473
|
fill(attributes) {
|
|
5126
5474
|
Object.entries(attributes).forEach(([key, value]) => {
|
|
5127
5475
|
this.setAttribute(key, value);
|
|
@@ -5178,6 +5526,14 @@ var Model = class Model {
|
|
|
5178
5526
|
return this;
|
|
5179
5527
|
}
|
|
5180
5528
|
/**
|
|
5529
|
+
* Save the model without dispatching lifecycle events.
|
|
5530
|
+
*
|
|
5531
|
+
* @returns
|
|
5532
|
+
*/
|
|
5533
|
+
async saveQuietly() {
|
|
5534
|
+
return await Model.withoutEvents(() => this.save());
|
|
5535
|
+
}
|
|
5536
|
+
/**
|
|
5181
5537
|
* Delete the model from the database.
|
|
5182
5538
|
* If soft deletes are enabled, it will perform a soft delete by
|
|
5183
5539
|
* setting the deleted at column to the current date.
|
|
@@ -5203,6 +5559,14 @@ var Model = class Model {
|
|
|
5203
5559
|
return this;
|
|
5204
5560
|
}
|
|
5205
5561
|
/**
|
|
5562
|
+
* Delete the model without dispatching lifecycle events.
|
|
5563
|
+
*
|
|
5564
|
+
* @returns
|
|
5565
|
+
*/
|
|
5566
|
+
async deleteQuietly() {
|
|
5567
|
+
return await Model.withoutEvents(() => this.delete());
|
|
5568
|
+
}
|
|
5569
|
+
/**
|
|
5206
5570
|
* Permanently delete the model from the database, regardless of whether soft
|
|
5207
5571
|
* deletes are enabled.
|
|
5208
5572
|
*
|
|
@@ -5221,6 +5585,14 @@ var Model = class Model {
|
|
|
5221
5585
|
return this;
|
|
5222
5586
|
}
|
|
5223
5587
|
/**
|
|
5588
|
+
* Force delete the model without dispatching lifecycle events.
|
|
5589
|
+
*
|
|
5590
|
+
* @returns
|
|
5591
|
+
*/
|
|
5592
|
+
async forceDeleteQuietly() {
|
|
5593
|
+
return await Model.withoutEvents(() => this.forceDelete());
|
|
5594
|
+
}
|
|
5595
|
+
/**
|
|
5224
5596
|
* Restore a soft-deleted model by setting the deleted at column to null.
|
|
5225
5597
|
*
|
|
5226
5598
|
* @returns
|
|
@@ -5238,6 +5610,14 @@ var Model = class Model {
|
|
|
5238
5610
|
return this;
|
|
5239
5611
|
}
|
|
5240
5612
|
/**
|
|
5613
|
+
* Restore the model without dispatching lifecycle events.
|
|
5614
|
+
*
|
|
5615
|
+
* @returns
|
|
5616
|
+
*/
|
|
5617
|
+
async restoreQuietly() {
|
|
5618
|
+
return await Model.withoutEvents(() => this.restore());
|
|
5619
|
+
}
|
|
5620
|
+
/**
|
|
5241
5621
|
* Load related models onto the current model instance.
|
|
5242
5622
|
*
|
|
5243
5623
|
* @param relations
|
|
@@ -5290,6 +5670,47 @@ var Model = class Model {
|
|
|
5290
5670
|
return this.toObject();
|
|
5291
5671
|
}
|
|
5292
5672
|
/**
|
|
5673
|
+
* Determine if another model represents the same persisted record.
|
|
5674
|
+
*
|
|
5675
|
+
* @param model
|
|
5676
|
+
* @returns
|
|
5677
|
+
*/
|
|
5678
|
+
is(model) {
|
|
5679
|
+
if (!(model instanceof Model)) return false;
|
|
5680
|
+
if (this.constructor !== model.constructor) return false;
|
|
5681
|
+
const identifier = this.getAttribute("id");
|
|
5682
|
+
const otherIdentifier = model.getAttribute("id");
|
|
5683
|
+
if (identifier == null || otherIdentifier == null) return false;
|
|
5684
|
+
return identifier === otherIdentifier;
|
|
5685
|
+
}
|
|
5686
|
+
/**
|
|
5687
|
+
* Determine if another model does not represent the same persisted record.
|
|
5688
|
+
*
|
|
5689
|
+
* @param model
|
|
5690
|
+
* @returns
|
|
5691
|
+
*/
|
|
5692
|
+
isNot(model) {
|
|
5693
|
+
return !this.is(model);
|
|
5694
|
+
}
|
|
5695
|
+
/**
|
|
5696
|
+
* Determine if another model is the same in-memory instance.
|
|
5697
|
+
*
|
|
5698
|
+
* @param model
|
|
5699
|
+
* @returns
|
|
5700
|
+
*/
|
|
5701
|
+
isSame(model) {
|
|
5702
|
+
return this === model;
|
|
5703
|
+
}
|
|
5704
|
+
/**
|
|
5705
|
+
* Determine if another model is not the same in-memory instance.
|
|
5706
|
+
*
|
|
5707
|
+
* @param model
|
|
5708
|
+
* @returns
|
|
5709
|
+
*/
|
|
5710
|
+
isNotSame(model) {
|
|
5711
|
+
return !this.isSame(model);
|
|
5712
|
+
}
|
|
5713
|
+
/**
|
|
5293
5714
|
* Define a has one relationship.
|
|
5294
5715
|
*
|
|
5295
5716
|
* @param related
|
|
@@ -5453,6 +5874,84 @@ var Model = class Model {
|
|
|
5453
5874
|
if (!Object.prototype.hasOwnProperty.call(this, "eventListeners")) this.eventListeners = { ...this.eventListeners || {} };
|
|
5454
5875
|
}
|
|
5455
5876
|
/**
|
|
5877
|
+
* Resolve lifecycle state for the provided model class.
|
|
5878
|
+
*
|
|
5879
|
+
* @param modelClass
|
|
5880
|
+
* @returns
|
|
5881
|
+
*/
|
|
5882
|
+
static getLifecycleState(modelClass) {
|
|
5883
|
+
const existing = Model.lifecycleStates.get(modelClass);
|
|
5884
|
+
if (existing) return existing;
|
|
5885
|
+
const state = {
|
|
5886
|
+
booted: false,
|
|
5887
|
+
booting: false,
|
|
5888
|
+
globalScopesSuppressed: 0
|
|
5889
|
+
};
|
|
5890
|
+
Model.lifecycleStates.set(modelClass, state);
|
|
5891
|
+
return state;
|
|
5892
|
+
}
|
|
5893
|
+
/**
|
|
5894
|
+
* Ensure the target model class has executed its boot lifecycle.
|
|
5895
|
+
*
|
|
5896
|
+
* @param modelClass
|
|
5897
|
+
*/
|
|
5898
|
+
static ensureModelBooted(modelClass) {
|
|
5899
|
+
const state = Model.getLifecycleState(modelClass);
|
|
5900
|
+
if (state.booted || state.booting) return;
|
|
5901
|
+
state.booting = true;
|
|
5902
|
+
try {
|
|
5903
|
+
const boot = modelClass.boot;
|
|
5904
|
+
if (boot !== Model.boot) boot.call(modelClass);
|
|
5905
|
+
const booted = modelClass.booted;
|
|
5906
|
+
if (booted !== Model.booted) booted.call(modelClass);
|
|
5907
|
+
state.booted = true;
|
|
5908
|
+
} finally {
|
|
5909
|
+
state.booting = false;
|
|
5910
|
+
}
|
|
5911
|
+
}
|
|
5912
|
+
/**
|
|
5913
|
+
* Determine if global scopes are currently suppressed for the model class.
|
|
5914
|
+
*
|
|
5915
|
+
* @param modelClass
|
|
5916
|
+
* @returns
|
|
5917
|
+
*/
|
|
5918
|
+
static areGlobalScopesSuppressed(modelClass) {
|
|
5919
|
+
return Model.getLifecycleState(modelClass).globalScopesSuppressed > 0;
|
|
5920
|
+
}
|
|
5921
|
+
/**
|
|
5922
|
+
* Resolve configured class-based event handlers for a lifecycle event.
|
|
5923
|
+
*
|
|
5924
|
+
* @param modelClass
|
|
5925
|
+
* @param event
|
|
5926
|
+
* @returns
|
|
5927
|
+
*/
|
|
5928
|
+
static resolveDispatchedEventListeners(modelClass, event) {
|
|
5929
|
+
const configured = modelClass.dispatchesEvents[event];
|
|
5930
|
+
if (!configured) return [];
|
|
5931
|
+
return (Array.isArray(configured) ? configured : [configured]).map((entry) => {
|
|
5932
|
+
const handler = typeof entry === "function" ? new entry() : entry;
|
|
5933
|
+
if (!handler || typeof handler.handle !== "function") throw new ArkormException(`Invalid event handler configured for [${modelClass.name}.${event}].`);
|
|
5934
|
+
return async (model) => {
|
|
5935
|
+
await handler.handle(model);
|
|
5936
|
+
};
|
|
5937
|
+
});
|
|
5938
|
+
}
|
|
5939
|
+
/**
|
|
5940
|
+
* Determine whether a lifecycle event has any registered listeners.
|
|
5941
|
+
*
|
|
5942
|
+
* @param modelClass
|
|
5943
|
+
* @param event
|
|
5944
|
+
* @returns
|
|
5945
|
+
*/
|
|
5946
|
+
static hasEventListeners(modelClass, event) {
|
|
5947
|
+
if (Model.eventsSuppressed > 0) return false;
|
|
5948
|
+
modelClass.ensureOwnEventListeners();
|
|
5949
|
+
if ((modelClass.eventListeners[event] || []).length > 0) return true;
|
|
5950
|
+
const configuredDispatchers = modelClass.dispatchesEvents[event];
|
|
5951
|
+
if (!configuredDispatchers) return false;
|
|
5952
|
+
return Array.isArray(configuredDispatchers) ? configuredDispatchers.length > 0 : true;
|
|
5953
|
+
}
|
|
5954
|
+
/**
|
|
5456
5955
|
* Dispatches lifecycle events to registered listeners.
|
|
5457
5956
|
*
|
|
5458
5957
|
* @param modelClass
|
|
@@ -5460,8 +5959,9 @@ var Model = class Model {
|
|
|
5460
5959
|
* @param model
|
|
5461
5960
|
*/
|
|
5462
5961
|
static async dispatchEvent(modelClass, event, model) {
|
|
5463
|
-
|
|
5464
|
-
|
|
5962
|
+
Model.ensureModelBooted(modelClass);
|
|
5963
|
+
if (!Model.hasEventListeners(modelClass, event)) return;
|
|
5964
|
+
const listeners = [...Model.resolveDispatchedEventListeners(modelClass, event), ...modelClass.eventListeners[event] || []];
|
|
5465
5965
|
for (const listener of listeners) await listener(model);
|
|
5466
5966
|
}
|
|
5467
5967
|
/**
|
|
@@ -5498,6 +5998,7 @@ exports.MigrateCommand = MigrateCommand;
|
|
|
5498
5998
|
exports.MigrateRollbackCommand = MigrateRollbackCommand;
|
|
5499
5999
|
exports.Migration = Migration;
|
|
5500
6000
|
exports.MigrationHistoryCommand = MigrationHistoryCommand;
|
|
6001
|
+
exports.MissingDelegateException = MissingDelegateException;
|
|
5501
6002
|
exports.Model = Model;
|
|
5502
6003
|
exports.ModelFactory = ModelFactory;
|
|
5503
6004
|
exports.ModelNotFoundException = ModelNotFoundException;
|
|
@@ -5505,12 +6006,17 @@ exports.ModelsSyncCommand = ModelsSyncCommand;
|
|
|
5505
6006
|
exports.PRISMA_MODEL_REGEX = PRISMA_MODEL_REGEX;
|
|
5506
6007
|
exports.Paginator = Paginator;
|
|
5507
6008
|
exports.QueryBuilder = QueryBuilder;
|
|
6009
|
+
exports.QueryConstraintException = QueryConstraintException;
|
|
6010
|
+
exports.RelationResolutionException = RelationResolutionException;
|
|
5508
6011
|
exports.SEEDER_BRAND = SEEDER_BRAND;
|
|
5509
6012
|
exports.SchemaBuilder = SchemaBuilder;
|
|
6013
|
+
exports.ScopeNotDefinedException = ScopeNotDefinedException;
|
|
5510
6014
|
exports.SeedCommand = SeedCommand;
|
|
5511
6015
|
exports.Seeder = Seeder;
|
|
5512
6016
|
exports.TableBuilder = TableBuilder;
|
|
5513
6017
|
exports.URLDriver = URLDriver;
|
|
6018
|
+
exports.UniqueConstraintResolutionException = UniqueConstraintResolutionException;
|
|
6019
|
+
exports.UnsupportedAdapterFeatureException = UnsupportedAdapterFeatureException;
|
|
5514
6020
|
exports.applyAlterTableOperation = applyAlterTableOperation;
|
|
5515
6021
|
exports.applyCreateTableOperation = applyCreateTableOperation;
|
|
5516
6022
|
exports.applyDropTableOperation = applyDropTableOperation;
|
|
@@ -5542,16 +6048,19 @@ exports.findModelBlock = findModelBlock;
|
|
|
5542
6048
|
exports.formatDefaultValue = formatDefaultValue;
|
|
5543
6049
|
exports.formatRelationAction = formatRelationAction;
|
|
5544
6050
|
exports.generateMigrationFile = generateMigrationFile;
|
|
6051
|
+
exports.getActiveTransactionClient = getActiveTransactionClient;
|
|
5545
6052
|
exports.getDefaultStubsPath = getDefaultStubsPath;
|
|
5546
6053
|
exports.getLastMigrationRun = getLastMigrationRun;
|
|
5547
6054
|
exports.getLatestAppliedMigrations = getLatestAppliedMigrations;
|
|
5548
6055
|
exports.getMigrationPlan = getMigrationPlan;
|
|
6056
|
+
exports.getRuntimePaginationCurrentPageResolver = getRuntimePaginationCurrentPageResolver;
|
|
5549
6057
|
exports.getRuntimePaginationURLDriverFactory = getRuntimePaginationURLDriverFactory;
|
|
5550
6058
|
exports.getRuntimePrismaClient = getRuntimePrismaClient;
|
|
5551
6059
|
exports.getUserConfig = getUserConfig;
|
|
5552
6060
|
exports.inferDelegateName = inferDelegateName;
|
|
5553
6061
|
exports.isDelegateLike = isDelegateLike;
|
|
5554
6062
|
exports.isMigrationApplied = isMigrationApplied;
|
|
6063
|
+
exports.isTransactionCapableClient = isTransactionCapableClient;
|
|
5555
6064
|
exports.loadArkormConfig = loadArkormConfig;
|
|
5556
6065
|
exports.markMigrationApplied = markMigrationApplied;
|
|
5557
6066
|
exports.markMigrationRun = markMigrationRun;
|
|
@@ -5563,6 +6072,7 @@ exports.resolveCast = resolveCast;
|
|
|
5563
6072
|
exports.resolveMigrationClassName = resolveMigrationClassName;
|
|
5564
6073
|
exports.resolveMigrationStateFilePath = resolveMigrationStateFilePath;
|
|
5565
6074
|
exports.resolvePrismaType = resolvePrismaType;
|
|
6075
|
+
exports.runArkormTransaction = runArkormTransaction;
|
|
5566
6076
|
exports.runMigrationWithPrisma = runMigrationWithPrisma;
|
|
5567
6077
|
exports.runPrismaCommand = runPrismaCommand;
|
|
5568
6078
|
exports.toMigrationFileSlug = toMigrationFileSlug;
|