@objectstack/objectql 9.9.0 → 9.10.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/index.d.mts +49 -1
- package/dist/index.d.ts +49 -1
- package/dist/index.js +71 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +71 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -141,7 +141,10 @@ var init_seed_loader = __esm({
|
|
|
141
141
|
const seedIdentity = config.identity;
|
|
142
142
|
const baseEvalCtx = {
|
|
143
143
|
now: seedNow,
|
|
144
|
-
|
|
144
|
+
// `id: null` is a legitimate seed-time state (the owning admin does not
|
|
145
|
+
// exist yet) that the formula EvalContext's `user.id: string` type does
|
|
146
|
+
// not yet model — cast the fallback so `os.user.id` evaluates to null.
|
|
147
|
+
user: seedIdentity?.user ?? { id: null },
|
|
145
148
|
// Fall back to the per-tenant organizationId so `os.org.id` resolves
|
|
146
149
|
// during per-org replay even without an explicit identity.org.
|
|
147
150
|
org: seedIdentity?.org ?? (config.organizationId ? { id: config.organizationId } : void 0),
|
|
@@ -161,7 +164,7 @@ var init_seed_loader = __esm({
|
|
|
161
164
|
targetField: "(expression)",
|
|
162
165
|
attemptedValue: dataset.records[i],
|
|
163
166
|
recordIndex: i,
|
|
164
|
-
message: `Cannot resolve dynamic seed values for ${objectName} record #${i}: ${seedResult.error.message}.
|
|
167
|
+
message: `Cannot resolve dynamic seed values for ${objectName} record #${i}: ${seedResult.error.message}. \`os.user.id\` resolves to null at seed time (the owning admin does not exist yet) and owner-style fields are assigned by the first-admin handoff \u2014 so a required, non-owner field must not depend on it. Provide a literal value or make the field optional.`
|
|
165
168
|
};
|
|
166
169
|
errors.push(error);
|
|
167
170
|
allErrors.push(error);
|
|
@@ -840,6 +843,8 @@ function applySystemFields(schema, opts) {
|
|
|
840
843
|
const tenancyDisabled = schema.tenancy?.enabled === false;
|
|
841
844
|
const wantTenant = sf?.tenant !== false && !tenancyDisabled;
|
|
842
845
|
const wantAudit = sf?.audit !== false;
|
|
846
|
+
const ownership = schema.ownership;
|
|
847
|
+
const wantOwner = ownership !== "org" && ownership !== "none" && !schema.managedBy && !schema.name.startsWith("sys_");
|
|
843
848
|
const additions = {};
|
|
844
849
|
if (wantTenant && !schema.fields?.organization_id) {
|
|
845
850
|
additions.organization_id = {
|
|
@@ -898,6 +903,17 @@ function applySystemFields(schema, opts) {
|
|
|
898
903
|
};
|
|
899
904
|
}
|
|
900
905
|
}
|
|
906
|
+
if (wantOwner && !schema.fields?.owner_id) {
|
|
907
|
+
additions.owner_id = {
|
|
908
|
+
type: "lookup",
|
|
909
|
+
reference: "sys_user",
|
|
910
|
+
label: "Owner",
|
|
911
|
+
required: false,
|
|
912
|
+
readonly: false,
|
|
913
|
+
system: true,
|
|
914
|
+
description: "Record owner (auto-stamped to the creating user on insert; reassignable). Drives owner-scoped views, reports and notifications."
|
|
915
|
+
};
|
|
916
|
+
}
|
|
901
917
|
if (Object.keys(additions).length === 0) return schema;
|
|
902
918
|
return {
|
|
903
919
|
...schema,
|
|
@@ -7025,7 +7041,7 @@ function aggregateBucket(rows, aggregations) {
|
|
|
7025
7041
|
const alias = agg.alias;
|
|
7026
7042
|
const fn = agg.function;
|
|
7027
7043
|
if (fn === "count") {
|
|
7028
|
-
if (!agg.field) {
|
|
7044
|
+
if (!agg.field || agg.field === "*") {
|
|
7029
7045
|
out[alias] = rows.length;
|
|
7030
7046
|
} else {
|
|
7031
7047
|
out[alias] = rows.reduce(
|
|
@@ -9448,6 +9464,58 @@ var ScopedContext = class _ScopedContext {
|
|
|
9448
9464
|
throw error;
|
|
9449
9465
|
}
|
|
9450
9466
|
}
|
|
9467
|
+
/**
|
|
9468
|
+
* Resolve the default driver, if it exposes transaction primitives.
|
|
9469
|
+
* Shared by {@link transaction} and the discrete begin/commit/rollback trio.
|
|
9470
|
+
*/
|
|
9471
|
+
txDriver() {
|
|
9472
|
+
const engine = this.engine;
|
|
9473
|
+
const driver = engine.defaultDriver ? engine.drivers?.get(engine.defaultDriver) : void 0;
|
|
9474
|
+
return driver?.beginTransaction ? driver : void 0;
|
|
9475
|
+
}
|
|
9476
|
+
/**
|
|
9477
|
+
* Discrete transaction primitives — `begin` / `commit` / `rollback` as three
|
|
9478
|
+
* separate calls, in contrast to {@link transaction}'s single-callback form.
|
|
9479
|
+
*
|
|
9480
|
+
* This trio exists for callers that cannot keep a JS closure on the stack for
|
|
9481
|
+
* the lifetime of the transaction — chiefly the sandbox runner, where the
|
|
9482
|
+
* hook/action body's `ctx.api.transaction(fn)` is driven across many host
|
|
9483
|
+
* event-loop turns via deferred promises. Across those `setImmediate`
|
|
9484
|
+
* boundaries the engine's ambient `txStore` (AsyncLocalStorage) does NOT
|
|
9485
|
+
* survive, so the transaction handle is threaded **explicitly**: `begin`
|
|
9486
|
+
* returns a child ScopedContext carrying `transaction: trx` in its execution
|
|
9487
|
+
* context, and `resolveTx` honors that explicit handle ahead of the ambient
|
|
9488
|
+
* store. Every `object(...)` op on the returned context therefore reuses the
|
|
9489
|
+
* one connection without relying on ALS.
|
|
9490
|
+
*
|
|
9491
|
+
* Returns `null` when the driver has no transaction support — the caller then
|
|
9492
|
+
* runs non-transactionally against `this` (same graceful degrade as
|
|
9493
|
+
* {@link transaction}).
|
|
9494
|
+
*/
|
|
9495
|
+
async beginTransaction() {
|
|
9496
|
+
const driver = this.txDriver();
|
|
9497
|
+
if (!driver) return null;
|
|
9498
|
+
const trx = await driver.beginTransaction();
|
|
9499
|
+
const ctx = new _ScopedContext(
|
|
9500
|
+
{ ...this.executionContext, transaction: trx },
|
|
9501
|
+
this.engine
|
|
9502
|
+
);
|
|
9503
|
+
return { ctx, handle: trx };
|
|
9504
|
+
}
|
|
9505
|
+
/** Commit a handle obtained from {@link beginTransaction}. */
|
|
9506
|
+
async commitTransaction(handle) {
|
|
9507
|
+
const driver = this.txDriver();
|
|
9508
|
+
if (!driver) return;
|
|
9509
|
+
if (driver.commit) await driver.commit(handle);
|
|
9510
|
+
else if (driver.commitTransaction) await driver.commitTransaction(handle);
|
|
9511
|
+
}
|
|
9512
|
+
/** Roll back a handle obtained from {@link beginTransaction}. */
|
|
9513
|
+
async rollbackTransaction(handle) {
|
|
9514
|
+
const driver = this.txDriver();
|
|
9515
|
+
if (!driver) return;
|
|
9516
|
+
if (driver.rollback) await driver.rollback(handle);
|
|
9517
|
+
else if (driver.rollbackTransaction) await driver.rollbackTransaction(handle);
|
|
9518
|
+
}
|
|
9451
9519
|
get userId() {
|
|
9452
9520
|
return this.executionContext.userId;
|
|
9453
9521
|
}
|