@murumets-ee/entity 0.11.0 → 0.12.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/admin/index.d.mts +318 -71
- package/dist/admin/index.d.mts.map +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/index.mjs.map +1 -1
- package/dist/index.d.mts +78 -9
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/query/index.d.mts +67 -19
- package/dist/query/index.d.mts.map +1 -1
- package/dist/query/index.mjs +1 -1
- package/dist/query/index.mjs.map +1 -1
- package/dist/refs/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/admin/index.d.mts
CHANGED
|
@@ -184,6 +184,122 @@ type InferCreateInput<Fields extends Record<string, FieldConfig>> = Omit<{ [K in
|
|
|
184
184
|
type ImmutableFields = 'id' | 'createdAt' | 'createdBy';
|
|
185
185
|
type InferUpdateInput<Fields extends Record<string, FieldConfig>> = { [K in keyof Fields as K extends ImmutableFields ? never : K]?: FieldToTS<Fields[K]> | null };
|
|
186
186
|
//#endregion
|
|
187
|
+
//#region src/behaviors/types.d.ts
|
|
188
|
+
/**
|
|
189
|
+
* Structural shape of a queue `JobDefinition` as seen by behaviors.
|
|
190
|
+
*
|
|
191
|
+
* The entity package CANNOT import `@murumets-ee/queue` (would form a
|
|
192
|
+
* cycle through `@murumets-ee/core`'s registry — see CLAUDE.md
|
|
193
|
+
* "Package boundaries"). Instead, behaviors receive an `EnqueueOnCommit`
|
|
194
|
+
* function via `BehaviorContext`, and the queue's `JobDefinition<T>`
|
|
195
|
+
* is structurally compatible with this minimal shape. The actual
|
|
196
|
+
* payload validation runs inside the queue when the wrapped resolver
|
|
197
|
+
* forwards the call.
|
|
198
|
+
*/
|
|
199
|
+
interface JobLike {
|
|
200
|
+
readonly name: string;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Resolver shape for `BehaviorContext.enqueueOnCommit`. Synchronous,
|
|
204
|
+
* fire-and-forget — the resolver writes the row in the background and
|
|
205
|
+
* logs failures; behaviors do NOT await.
|
|
206
|
+
*
|
|
207
|
+
* Intended semantics (PLAN-OUTBOX §4.2): the row INSERT participates
|
|
208
|
+
* in the AdminClient operation's transaction — commit makes the job
|
|
209
|
+
* visible to the worker, rollback removes it. As of PR D this is the
|
|
210
|
+
* actual semantics: AdminClient threads its tx into the
|
|
211
|
+
* `EnqueueOnCommitFactory` once per call and passes the result through
|
|
212
|
+
* to behaviors. When the queue plugin is not loaded the field is
|
|
213
|
+
* `undefined` and behaviors no-op (per §6 Q6).
|
|
214
|
+
*/
|
|
215
|
+
type EnqueueOnCommit = (job: JobLike, payload: unknown) => void;
|
|
216
|
+
/**
|
|
217
|
+
* Factory that returns an {@link EnqueueOnCommit} resolver bound to an
|
|
218
|
+
* optional Drizzle transaction handle. AdminClient invokes this once
|
|
219
|
+
* per CRUD operation, passing the active tx so behaviors firing inside
|
|
220
|
+
* the operation enqueue rows that commit (or roll back) atomically
|
|
221
|
+
* with the entity write.
|
|
222
|
+
*
|
|
223
|
+
* The `tx` parameter is intentionally typed as `unknown` here — the
|
|
224
|
+
* entity package CANNOT import `drizzle-orm/postgres-js` types without
|
|
225
|
+
* pulling in the database stack and breaking its leaf-package contract.
|
|
226
|
+
* The queue plugin (which writes the slot) and AdminClient (which
|
|
227
|
+
* supplies the tx) both work with the precise `PostgresJsDatabase`
|
|
228
|
+
* shape; the interior of the factory casts as needed.
|
|
229
|
+
*
|
|
230
|
+
* **Mirror definition** lives in
|
|
231
|
+
* `packages/queue/src/enqueue-on-commit-slot.ts` with `tx?:
|
|
232
|
+
* PostgresJsDatabase`. The two are structurally compatible by design;
|
|
233
|
+
* if you rename or change one, change both. The runtime contract is
|
|
234
|
+
* the same — only the type-time visibility of the parameter differs.
|
|
235
|
+
*/
|
|
236
|
+
type EnqueueOnCommitFactory = (tx?: unknown) => EnqueueOnCommit;
|
|
237
|
+
/**
|
|
238
|
+
* Context passed to behavior hooks. Resolved once per request by AdminClient
|
|
239
|
+
* from its `contextResolver` and forwarded into every hook so behaviors never
|
|
240
|
+
* have to reach into AsyncLocalStorage themselves — that pattern breaks under
|
|
241
|
+
* bundlers (e.g. Turbopack) that duplicate module instances across boundaries.
|
|
242
|
+
*
|
|
243
|
+
* `loadCurrent` returns the *pre-update* entity row. It is eagerly loaded
|
|
244
|
+
* by AdminClient before any hooks fire on the **update** codepath and
|
|
245
|
+
* cached for the rest of that call — so calling it from `beforeUpdate`
|
|
246
|
+
* or `afterUpdate` returns the SAME snapshot regardless of whether a
|
|
247
|
+
* sibling hook touched it. Returns `null` when no entity matches the id
|
|
248
|
+
* (rare — usually means the row was deleted concurrently). On `create`
|
|
249
|
+
* AND `delete` codepaths, `loadCurrent` is undefined: create has no
|
|
250
|
+
* pre-state, and delete hooks receive the entity id directly via their
|
|
251
|
+
* first argument so a separate snapshot is unnecessary.
|
|
252
|
+
*
|
|
253
|
+
* `afterUpdate` always receives the post-update row as its first argument,
|
|
254
|
+
* so the (`row`, `loadCurrent()`) pair gives hooks a complete (after, before)
|
|
255
|
+
* view without per-call Map state. The eager load costs one extra
|
|
256
|
+
* `findById` per update; updates are not a hot path in this codebase, and
|
|
257
|
+
* the consistency win — no foot-gun for hook authors — is worth it.
|
|
258
|
+
*
|
|
259
|
+
* `viaInternal` is `true` when the hook is running on an `AdminClient.updateInternal`
|
|
260
|
+
* call (the trusted server-side path; public PATCH always sets it false).
|
|
261
|
+
* Hooks SHOULD treat this as informational only — the route layer has
|
|
262
|
+
* authorized the *capability*, but the hook is still responsible for
|
|
263
|
+
* enforcing structural invariants. Workflowable, for example, validates
|
|
264
|
+
* the `_workflowStatus` transition table on every update regardless of
|
|
265
|
+
* `viaInternal` so that even a route-layer bug cannot push the workflow
|
|
266
|
+
* row into an illegal state. Use `viaInternal` when a hook genuinely
|
|
267
|
+
* needs to differentiate (e.g. side effects that should only fire when
|
|
268
|
+
* a real user — not the seed loader — initiates the change).
|
|
269
|
+
*
|
|
270
|
+
* `enqueueOnCommit` is the outbox entry point for projection-style hooks
|
|
271
|
+
* (PR C of PLAN-OUTBOX). When wired (the queue plugin is available in
|
|
272
|
+
* the running app), behaviors can enqueue side-effect jobs without
|
|
273
|
+
* importing the queue package directly, keeping entity-as-leaf invariant
|
|
274
|
+
* intact. Synchronous + fire-and-forget — no await needed in hooks.
|
|
275
|
+
* Undefined when the AdminClient was constructed without an
|
|
276
|
+
* `enqueueOnCommit` resolver (e.g. CLI scripts that don't load the
|
|
277
|
+
* queue plugin); behaviors that depend on it must guard with `if
|
|
278
|
+
* (ctx.enqueueOnCommit) { ... }` or document the dependency loudly.
|
|
279
|
+
*/
|
|
280
|
+
interface BehaviorContext {
|
|
281
|
+
user?: {
|
|
282
|
+
id: string;
|
|
283
|
+
name?: string;
|
|
284
|
+
email?: string;
|
|
285
|
+
};
|
|
286
|
+
loadCurrent?: () => Promise<Record<string, unknown> | null>;
|
|
287
|
+
viaInternal?: boolean;
|
|
288
|
+
enqueueOnCommit?: EnqueueOnCommit;
|
|
289
|
+
}
|
|
290
|
+
interface Behavior<F extends Record<string, FieldConfig> = {}> {
|
|
291
|
+
name: string;
|
|
292
|
+
fields?: F;
|
|
293
|
+
hooks?: {
|
|
294
|
+
beforeCreate?: (data: Record<string, unknown>, ctx?: BehaviorContext) => Promise<Record<string, unknown>>;
|
|
295
|
+
afterCreate?: (entity: Record<string, unknown>, ctx?: BehaviorContext) => Promise<void>;
|
|
296
|
+
beforeUpdate?: (id: string, data: Record<string, unknown>, ctx?: BehaviorContext) => Promise<Record<string, unknown>>;
|
|
297
|
+
afterUpdate?: (entity: Record<string, unknown>, ctx?: BehaviorContext) => Promise<void>;
|
|
298
|
+
beforeDelete?: (id: string, ctx?: BehaviorContext) => Promise<void>;
|
|
299
|
+
afterDelete?: (id: string, ctx?: BehaviorContext) => Promise<void>;
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
//#endregion
|
|
187
303
|
//#region src/cursor.d.ts
|
|
188
304
|
/** Cursor input for keyset pagination. */
|
|
189
305
|
interface CursorInput {
|
|
@@ -194,7 +310,7 @@ interface CursorInput {
|
|
|
194
310
|
/** Sort direction — must match the ORDER BY direction. */
|
|
195
311
|
direction: 'asc' | 'desc';
|
|
196
312
|
/** Tie-breaker: last seen entity ID. Required for non-unique sort fields. */
|
|
197
|
-
id?: string;
|
|
313
|
+
id?: string | undefined;
|
|
198
314
|
}
|
|
199
315
|
//#endregion
|
|
200
316
|
//#region src/admin-config.d.ts
|
|
@@ -256,53 +372,6 @@ interface EntityAdminConfig {
|
|
|
256
372
|
hideFromDashboard?: boolean;
|
|
257
373
|
}
|
|
258
374
|
//#endregion
|
|
259
|
-
//#region src/behaviors/types.d.ts
|
|
260
|
-
/**
|
|
261
|
-
* Context passed to behavior hooks. Resolved once per request by AdminClient
|
|
262
|
-
* from its `contextResolver` and forwarded into every hook so behaviors never
|
|
263
|
-
* have to reach into AsyncLocalStorage themselves — that pattern breaks under
|
|
264
|
-
* bundlers (e.g. Turbopack) that duplicate module instances across boundaries.
|
|
265
|
-
*
|
|
266
|
-
* `loadCurrent` is a lazy, memoized loader for the *current* entity row,
|
|
267
|
-
* provided by AdminClient on update/delete codepaths. Hooks that need to
|
|
268
|
-
* validate against the existing state (e.g. workflowable's transition
|
|
269
|
-
* checker) call it; behaviors that don't, don't pay for the round trip.
|
|
270
|
-
* Returns `null` when no entity matches the id (rare — usually means the
|
|
271
|
-
* row was deleted concurrently). On create, `loadCurrent` is undefined.
|
|
272
|
-
*
|
|
273
|
-
* `viaInternal` is `true` when the hook is running on an `AdminClient.updateInternal`
|
|
274
|
-
* call (the trusted server-side path; public PATCH always sets it false).
|
|
275
|
-
* Hooks SHOULD treat this as informational only — the route layer has
|
|
276
|
-
* authorized the *capability*, but the hook is still responsible for
|
|
277
|
-
* enforcing structural invariants. Workflowable, for example, validates
|
|
278
|
-
* the `_workflowStatus` transition table on every update regardless of
|
|
279
|
-
* `viaInternal` so that even a route-layer bug cannot push the workflow
|
|
280
|
-
* row into an illegal state. Use `viaInternal` when a hook genuinely
|
|
281
|
-
* needs to differentiate (e.g. side effects that should only fire when
|
|
282
|
-
* a real user — not the seed loader — initiates the change).
|
|
283
|
-
*/
|
|
284
|
-
interface BehaviorContext {
|
|
285
|
-
user?: {
|
|
286
|
-
id: string;
|
|
287
|
-
name?: string;
|
|
288
|
-
email?: string;
|
|
289
|
-
};
|
|
290
|
-
loadCurrent?: () => Promise<Record<string, unknown> | null>;
|
|
291
|
-
viaInternal?: boolean;
|
|
292
|
-
}
|
|
293
|
-
interface Behavior<F extends Record<string, FieldConfig> = {}> {
|
|
294
|
-
name: string;
|
|
295
|
-
fields?: F;
|
|
296
|
-
hooks?: {
|
|
297
|
-
beforeCreate?: (data: Record<string, unknown>, ctx?: BehaviorContext) => Promise<Record<string, unknown>>;
|
|
298
|
-
afterCreate?: (entity: Record<string, unknown>, ctx?: BehaviorContext) => Promise<void>;
|
|
299
|
-
beforeUpdate?: (id: string, data: Record<string, unknown>, ctx?: BehaviorContext) => Promise<Record<string, unknown>>;
|
|
300
|
-
afterUpdate?: (entity: Record<string, unknown>, ctx?: BehaviorContext) => Promise<void>;
|
|
301
|
-
beforeDelete?: (id: string, ctx?: BehaviorContext) => Promise<void>;
|
|
302
|
-
afterDelete?: (id: string, ctx?: BehaviorContext) => Promise<void>;
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
//#endregion
|
|
306
375
|
//#region src/define-entity.d.ts
|
|
307
376
|
/**
|
|
308
377
|
* A fully resolved entity with merged behavior fields.
|
|
@@ -380,32 +449,64 @@ type EntityResolver = () => Map<string, Entity> | undefined;
|
|
|
380
449
|
interface AdminClientConfig<AllFields extends Record<string, FieldConfig> = Record<string, FieldConfig>> {
|
|
381
450
|
entity: Entity<AllFields>;
|
|
382
451
|
db: PostgresJsDatabase;
|
|
383
|
-
logger?: Logger;
|
|
452
|
+
logger?: Logger | undefined;
|
|
384
453
|
/** Optional count cache for COUNT(*) query optimization. */
|
|
385
|
-
countCache?: CountCacheLike;
|
|
454
|
+
countCache?: CountCacheLike | undefined;
|
|
386
455
|
/**
|
|
387
456
|
* Resolves the current request's security context (user, role checker, scope).
|
|
388
457
|
* Provided automatically by `createAdminClient()` from @murumets-ee/core/clients.
|
|
389
458
|
* For direct `new AdminClient()` usage, pass your own resolver or use `runAsCli()`.
|
|
390
459
|
*/
|
|
391
|
-
contextResolver?: ContextResolver;
|
|
460
|
+
contextResolver?: ContextResolver | undefined;
|
|
392
461
|
/**
|
|
393
462
|
* Resolves the running app's entity registry. Used by cascade delete to
|
|
394
463
|
* read each referencing field's `onDelete` strategy. When omitted, all
|
|
395
464
|
* incoming references are treated as `restrict` — a safe default that
|
|
396
465
|
* blocks deletes rather than guessing.
|
|
397
466
|
*/
|
|
398
|
-
entityResolver?: EntityResolver;
|
|
467
|
+
entityResolver?: EntityResolver | undefined;
|
|
468
|
+
/**
|
|
469
|
+
* Outbox entry point exposed on `BehaviorContext.enqueueOnCommit`
|
|
470
|
+
* (PR C of PLAN-OUTBOX). When provided, projection-style behaviors can
|
|
471
|
+
* fire side-effect jobs from their hooks without importing the queue
|
|
472
|
+
* package — the entity package stays a leaf in the dependency graph.
|
|
473
|
+
*
|
|
474
|
+
* Used as a fallback when `enqueueOnCommitFactory` is not supplied:
|
|
475
|
+
* AdminClient passes this resolver verbatim into hook contexts, and
|
|
476
|
+
* the row INSERT is NOT bound to the operation's transaction. Tests
|
|
477
|
+
* that need to capture call-site behavior without wiring queue can
|
|
478
|
+
* pass this directly.
|
|
479
|
+
*
|
|
480
|
+
* In production wiring (`createAdminClient` in
|
|
481
|
+
* `@murumets-ee/core/clients`), prefer `enqueueOnCommitFactory` —
|
|
482
|
+
* that's the form that delivers PLAN-OUTBOX §4.2's "rollback removes
|
|
483
|
+
* the job" guarantee.
|
|
484
|
+
*/
|
|
485
|
+
enqueueOnCommit?: BehaviorContext['enqueueOnCommit'] | undefined;
|
|
486
|
+
/**
|
|
487
|
+
* Outbox factory exposed on `BehaviorContext.enqueueOnCommit` (PR D
|
|
488
|
+
* of PLAN-OUTBOX). When provided, AdminClient invokes the factory
|
|
489
|
+
* once per CRUD operation with the active Drizzle transaction so the
|
|
490
|
+
* resulting fire-and-forget resolver routes its INSERT through that
|
|
491
|
+
* tx. Hook-fired enqueues commit (or roll back) atomically with the
|
|
492
|
+
* entity write — the canonical PLAN-OUTBOX §4.2 semantics.
|
|
493
|
+
*
|
|
494
|
+
* Wired by `createAdminClient()` in `@murumets-ee/core/clients`
|
|
495
|
+
* against the running app's queue plugin. Takes precedence over the
|
|
496
|
+
* older `enqueueOnCommit` field when both are set; CLI scripts that
|
|
497
|
+
* don't load the queue plugin omit both.
|
|
498
|
+
*/
|
|
499
|
+
enqueueOnCommitFactory?: EnqueueOnCommitFactory | undefined;
|
|
399
500
|
}
|
|
400
501
|
interface FindManyOptions {
|
|
401
502
|
where?: SQL | undefined;
|
|
402
|
-
limit?: number;
|
|
403
|
-
offset?: number;
|
|
404
|
-
orderBy?: SQL | SQL[];
|
|
405
|
-
locale?: string;
|
|
503
|
+
limit?: number | undefined;
|
|
504
|
+
offset?: number | undefined;
|
|
505
|
+
orderBy?: SQL | SQL[] | undefined;
|
|
506
|
+
locale?: string | undefined;
|
|
406
507
|
/** Default content locale. For localized blocks, NULL rows (from initial create)
|
|
407
508
|
* are only returned as fallback when locale matches defaultLocale. */
|
|
408
|
-
defaultLocale?: string;
|
|
509
|
+
defaultLocale?: string | undefined;
|
|
409
510
|
/**
|
|
410
511
|
* Cursor-based (keyset) pagination. When provided, replaces OFFSET with a
|
|
411
512
|
* WHERE condition for O(1) page access at any depth. The `offset` option
|
|
@@ -413,13 +514,13 @@ interface FindManyOptions {
|
|
|
413
514
|
*
|
|
414
515
|
* The cursor `field` must be a real column on the entity table.
|
|
415
516
|
*/
|
|
416
|
-
cursor?: CursorInput;
|
|
517
|
+
cursor?: CursorInput | undefined;
|
|
417
518
|
/**
|
|
418
519
|
* Include fields marked `internal: true` (and legacy `_`-prefixed
|
|
419
520
|
* infrastructure columns) in the returned DTOs. Use only on trusted
|
|
420
521
|
* server-side reads that need to inspect state-machine fields.
|
|
421
522
|
*/
|
|
422
|
-
includeInternal?: boolean;
|
|
523
|
+
includeInternal?: boolean | undefined;
|
|
423
524
|
}
|
|
424
525
|
interface CountOptions {
|
|
425
526
|
where?: SQL | undefined;
|
|
@@ -461,8 +562,56 @@ declare class AdminClient<AllFields extends Record<string, FieldConfig> = Record
|
|
|
461
562
|
private countCache?;
|
|
462
563
|
private contextResolver?;
|
|
463
564
|
private entityResolver?;
|
|
464
|
-
|
|
565
|
+
private enqueueOnCommit?;
|
|
566
|
+
private enqueueOnCommitFactory?;
|
|
567
|
+
/** Shared context for entity-data-ops functions, bound to the default db. */
|
|
465
568
|
private get ctx();
|
|
569
|
+
/**
|
|
570
|
+
* Build an {@link EntityContext} bound to a specific Drizzle executor.
|
|
571
|
+
*
|
|
572
|
+
* Used by the public CRUD methods so that when the caller threads in
|
|
573
|
+
* `{ tx }` (PR D of PLAN-OUTBOX) every block-load / translation
|
|
574
|
+
* merge / scope-condition lookup hits the SAME tx as the entity write.
|
|
575
|
+
* Without this, a `loadBlocks(this.ctx, ...)` call inside an active tx
|
|
576
|
+
* would query `this.db` (the AdminClient's owned connection) and miss
|
|
577
|
+
* the in-flight INSERT — `entity_refs` / blocks rows wouldn't be
|
|
578
|
+
* visible until commit.
|
|
579
|
+
*
|
|
580
|
+
* For callers that don't pass a tx, `exec === this.db` and the ctx
|
|
581
|
+
* matches today's behaviour exactly.
|
|
582
|
+
*/
|
|
583
|
+
private ctxFor;
|
|
584
|
+
/**
|
|
585
|
+
* Build the `enqueueOnCommit` slot of a {@link BehaviorContext} for
|
|
586
|
+
* the active tx, ready to spread into `resolveAuthContext`'s options
|
|
587
|
+
* (PR D of PLAN-OUTBOX).
|
|
588
|
+
*
|
|
589
|
+
* - When the queue plugin's factory is wired, invoke it with `tx` so
|
|
590
|
+
* the resulting fire-and-forget resolver routes its INSERT through
|
|
591
|
+
* the caller's transaction (atomic with the entity write).
|
|
592
|
+
* - When only the legacy static `enqueueOnCommit` option is set, pass
|
|
593
|
+
* it through verbatim — used by tests and callers that wired their
|
|
594
|
+
* own resolver directly.
|
|
595
|
+
* - When neither is configured (CLI scripts, no queue plugin), return
|
|
596
|
+
* `{}` so the BehaviorContext's `enqueueOnCommit` field stays
|
|
597
|
+
* undefined and behaviors guard accordingly.
|
|
598
|
+
*/
|
|
599
|
+
private buildAuthOptions;
|
|
600
|
+
/**
|
|
601
|
+
* Re-bind `behaviorCtx.enqueueOnCommit` to the supplied executor.
|
|
602
|
+
*
|
|
603
|
+
* Used by `delete` / `deleteMany` when they open an internal tx
|
|
604
|
+
* because no caller tx was supplied: the auth context was resolved
|
|
605
|
+
* BEFORE the tx existed, so its `enqueueOnCommit` (if a factory is
|
|
606
|
+
* wired) was bound to `undefined` and would commit the queue row
|
|
607
|
+
* outside the internal tx. Rebinding here ensures the queue write
|
|
608
|
+
* rolls back with the cascade if anything in `runDelete` throws.
|
|
609
|
+
*
|
|
610
|
+
* Spreads conditionally to satisfy `exactOptionalPropertyTypes` —
|
|
611
|
+
* never assigns `enqueueOnCommit: undefined` (which would clear an
|
|
612
|
+
* existing static resolver if the factory wasn't configured).
|
|
613
|
+
*/
|
|
614
|
+
private rebindEnqueueOnCommit;
|
|
466
615
|
constructor(config: AdminClientConfig<AllFields>);
|
|
467
616
|
/**
|
|
468
617
|
* Strip caller-provided values for internal fields from the input.
|
|
@@ -478,7 +627,7 @@ declare class AdminClient<AllFields extends Record<string, FieldConfig> = Record
|
|
|
478
627
|
*/
|
|
479
628
|
private pickInternalFields;
|
|
480
629
|
/**
|
|
481
|
-
* Create a new entity
|
|
630
|
+
* Create a new entity.
|
|
482
631
|
*
|
|
483
632
|
* Flow:
|
|
484
633
|
* 1. Validate input with Zod
|
|
@@ -487,8 +636,26 @@ declare class AdminClient<AllFields extends Record<string, FieldConfig> = Record
|
|
|
487
636
|
* 4. Insert into database
|
|
488
637
|
* 5. Execute afterCreate hooks
|
|
489
638
|
* 6. Shape DTO and return
|
|
639
|
+
*
|
|
640
|
+
* **Caller transaction (`options.tx`)** — PR D of PLAN-OUTBOX. When
|
|
641
|
+
* supplied, the row INSERT, blocks save, refs sync, and any hook-fired
|
|
642
|
+
* `enqueueOnCommit` participate in the caller's transaction:
|
|
643
|
+
*
|
|
644
|
+
* ```ts
|
|
645
|
+
* await db.transaction(async (tx) => {
|
|
646
|
+
* const order = await orders.create({ ... }, { tx })
|
|
647
|
+
* // afterCreate hooks fired with this tx — enqueueOnCommit's INSERT
|
|
648
|
+
* // routes through it. Outer rollback removes both atomically.
|
|
649
|
+
* })
|
|
650
|
+
* ```
|
|
651
|
+
*
|
|
652
|
+
* When omitted, behaviour matches pre-PR-D exactly: each statement
|
|
653
|
+
* auto-commits, hooks run after commit, and the static
|
|
654
|
+
* `enqueueOnCommit` resolver (if any) writes outside the entity tx.
|
|
490
655
|
*/
|
|
491
|
-
create(data: InferCreateInput<AllFields
|
|
656
|
+
create(data: InferCreateInput<AllFields>, options?: {
|
|
657
|
+
tx?: PostgresJsDatabase;
|
|
658
|
+
}): Promise<InferEntityDTO<AllFields>>;
|
|
492
659
|
/**
|
|
493
660
|
* Find entity by ID.
|
|
494
661
|
*
|
|
@@ -522,6 +689,7 @@ declare class AdminClient<AllFields extends Record<string, FieldConfig> = Record
|
|
|
522
689
|
*/
|
|
523
690
|
update(id: string, data: InferUpdateInput<AllFields>, options?: {
|
|
524
691
|
locale?: string;
|
|
692
|
+
tx?: PostgresJsDatabase;
|
|
525
693
|
}): Promise<InferEntityDTO<AllFields>>;
|
|
526
694
|
/**
|
|
527
695
|
* Update entity by ID, allowing writes to fields marked `internal: true`.
|
|
@@ -542,18 +710,44 @@ declare class AdminClient<AllFields extends Record<string, FieldConfig> = Record
|
|
|
542
710
|
*/
|
|
543
711
|
updateInternal(id: string, data: Record<string, unknown>, options?: {
|
|
544
712
|
locale?: string;
|
|
713
|
+
tx?: PostgresJsDatabase;
|
|
545
714
|
}): Promise<InferEntityDTO<AllFields>>;
|
|
546
715
|
private updateImpl;
|
|
716
|
+
/**
|
|
717
|
+
* Internal `findById` variant that issues its SELECT through the
|
|
718
|
+
* caller-supplied executor. Used by `updateImpl` so the pre-update
|
|
719
|
+
* snapshot reflects any earlier writes the caller already made
|
|
720
|
+
* inside the same transaction.
|
|
721
|
+
*
|
|
722
|
+
* **Scope is NOT optional** — it must be the same `scopeId` that
|
|
723
|
+
* `resolveAuthContext` produced for the surrounding `update` call.
|
|
724
|
+
* The eventual UPDATE is scope-gated via its WHERE clause; if this
|
|
725
|
+
* pre-load skipped scope, hooks with side effects (audit logs,
|
|
726
|
+
* system-message creation, outbox enqueues) would observe and
|
|
727
|
+
* dispatch on cross-tenant rows even when the gated UPDATE matches
|
|
728
|
+
* nothing. See HIGH finding in pr-review for #247.
|
|
729
|
+
*
|
|
730
|
+
* Permission check is skipped because `resolveAuthContext` ran first
|
|
731
|
+
* in the surrounding `update` call.
|
|
732
|
+
*/
|
|
733
|
+
private findByIdInternal;
|
|
547
734
|
/**
|
|
548
735
|
* Delete entity by ID.
|
|
549
736
|
*
|
|
550
737
|
* Wraps cascade + delete in a transaction so cascaded deletes are rolled
|
|
551
|
-
* back if the final entity delete fails (no partial data loss).
|
|
738
|
+
* back if the final entity delete fails (no partial data loss). When
|
|
739
|
+
* the caller threads in `{ tx }` (PR D of PLAN-OUTBOX), the same tx
|
|
740
|
+
* is reused — the inner `db.transaction(...)` call is replaced with a
|
|
741
|
+
* direct invocation of the body, and any hook-fired `enqueueOnCommit`
|
|
742
|
+
* INSERT routes through the caller's tx so an outer rollback removes
|
|
743
|
+
* everything atomically.
|
|
552
744
|
*
|
|
553
745
|
* Checks entity_refs for incoming references first — throws
|
|
554
746
|
* ReferencedEntityError if this entity is still used somewhere.
|
|
555
747
|
*/
|
|
556
|
-
delete(id: string
|
|
748
|
+
delete(id: string, options?: {
|
|
749
|
+
tx?: PostgresJsDatabase;
|
|
750
|
+
}): Promise<void>;
|
|
557
751
|
/**
|
|
558
752
|
* Delete multiple entities matching a WHERE condition.
|
|
559
753
|
*
|
|
@@ -569,7 +763,9 @@ declare class AdminClient<AllFields extends Record<string, FieldConfig> = Record
|
|
|
569
763
|
*
|
|
570
764
|
* @returns Number of rows deleted
|
|
571
765
|
*/
|
|
572
|
-
deleteMany(where: SQL
|
|
766
|
+
deleteMany(where: SQL, options?: {
|
|
767
|
+
tx?: PostgresJsDatabase;
|
|
768
|
+
}): Promise<number>;
|
|
573
769
|
/** Maximum cascade depth to prevent infinite recursion from circular references. */
|
|
574
770
|
private static readonly MAX_CASCADE_DEPTH;
|
|
575
771
|
/**
|
|
@@ -634,6 +830,7 @@ declare class AdminClient<AllFields extends Record<string, FieldConfig> = Record
|
|
|
634
830
|
updateMany(where: SQL, data: Partial<InferUpdateInput<AllFields>>, options?: {
|
|
635
831
|
expressions?: Record<string, SQL>;
|
|
636
832
|
allowInternal?: boolean;
|
|
833
|
+
tx?: PostgresJsDatabase;
|
|
637
834
|
}): Promise<number>;
|
|
638
835
|
/**
|
|
639
836
|
* Run an aggregate query on this entity's table.
|
|
@@ -707,30 +904,66 @@ declare class AdminClient<AllFields extends Record<string, FieldConfig> = Record
|
|
|
707
904
|
/**
|
|
708
905
|
* Save translation for an entity.
|
|
709
906
|
* Each translatable field is a real column on the translation table.
|
|
907
|
+
*
|
|
908
|
+
* **Caller transaction (`options.tx`)** — Phase 4b of PLAN-OUTBOX. When
|
|
909
|
+
* supplied, the upsert participates in the caller's transaction so a
|
|
910
|
+
* caller wrapping `entity.create + saveTranslation` in a `db.transaction`
|
|
911
|
+
* gets atomic visibility — outer rollback removes BOTH the entity row
|
|
912
|
+
* and the translation row, never leaves an orphan translation pointing
|
|
913
|
+
* at a now-deleted entity. Without it, the translation would auto-commit
|
|
914
|
+
* regardless of the outer rollback. No hooks fire on this method, so no
|
|
915
|
+
* factory plumbing is needed — just routing the SQL through `exec`.
|
|
710
916
|
*/
|
|
711
|
-
saveTranslation(entityId: string, locale: string, translations: Record<string, unknown
|
|
917
|
+
saveTranslation(entityId: string, locale: string, translations: Record<string, unknown>, options?: {
|
|
918
|
+
tx?: PostgresJsDatabase;
|
|
919
|
+
}): Promise<void>;
|
|
712
920
|
/**
|
|
713
|
-
*
|
|
714
|
-
*
|
|
921
|
+
* Delete translation(s) for an entity. If `locale` is provided, deletes
|
|
922
|
+
* the specific locale row; otherwise deletes every translation row for
|
|
923
|
+
* the entity.
|
|
924
|
+
*
|
|
925
|
+
* **Caller transaction (`options.tx`)** — Phase 4b of PLAN-OUTBOX. Same
|
|
926
|
+
* shape as `saveTranslation` — when supplied, the DELETE participates
|
|
927
|
+
* in the caller's tx.
|
|
715
928
|
*/
|
|
716
|
-
deleteTranslation(entityId: string, locale?: string
|
|
929
|
+
deleteTranslation(entityId: string, locale?: string, options?: {
|
|
930
|
+
tx?: PostgresJsDatabase;
|
|
931
|
+
}): Promise<void>;
|
|
717
932
|
/**
|
|
718
933
|
* Save block-level translations for an entity.
|
|
719
934
|
* For each block in each blocks field, extracts translatable field values
|
|
720
935
|
* and upserts them into {entity}_layout_translations.
|
|
721
936
|
*
|
|
722
937
|
* Block _id must match an existing layout row ID.
|
|
938
|
+
*
|
|
939
|
+
* **Caller transaction (`options.tx`)** — Phase 4b of PLAN-OUTBOX.
|
|
940
|
+
* Routes the layout-row lookup AND every layout-translation upsert
|
|
941
|
+
* through the supplied tx, so a caller doing
|
|
942
|
+
* `entity.update + saveBlockTranslations` in one tx gets atomic
|
|
943
|
+
* visibility on rollback.
|
|
723
944
|
*/
|
|
724
|
-
saveBlockTranslations(entityId: string, locale: string, data: Record<string, unknown
|
|
945
|
+
saveBlockTranslations(entityId: string, locale: string, data: Record<string, unknown>, options?: {
|
|
946
|
+
tx?: PostgresJsDatabase;
|
|
947
|
+
}): Promise<void>;
|
|
725
948
|
/**
|
|
726
949
|
* Save per-locale blocks for an entity.
|
|
727
950
|
* Used for entities with `localized: true` on their blocks field — each locale gets
|
|
728
951
|
* its own independent block layout rows in the layout table.
|
|
952
|
+
*
|
|
953
|
+
* **Caller transaction (`options.tx`)** — Phase 4b of PLAN-OUTBOX. Threaded
|
|
954
|
+
* through to `saveBlocks`, which already accepts an executor.
|
|
729
955
|
*/
|
|
730
|
-
saveLocalizedBlocks(entityId: string, locale: string, data: Record<string, unknown
|
|
956
|
+
saveLocalizedBlocks(entityId: string, locale: string, data: Record<string, unknown>, options?: {
|
|
957
|
+
tx?: PostgresJsDatabase;
|
|
958
|
+
}): Promise<void>;
|
|
731
959
|
/**
|
|
732
960
|
* Save blocks for an entity after create/update.
|
|
733
961
|
* For each blocks field, writes rows to {entity}_layout table.
|
|
962
|
+
*
|
|
963
|
+
* `exec` is the active Drizzle executor — either a caller-supplied tx
|
|
964
|
+
* (PR D of PLAN-OUTBOX) or `this.db`. Routing through it keeps the
|
|
965
|
+
* blocks INSERTs/DELETEs in the same transaction as the parent
|
|
966
|
+
* entity write.
|
|
734
967
|
*/
|
|
735
968
|
private saveBlocks;
|
|
736
969
|
/**
|
|
@@ -740,10 +973,24 @@ declare class AdminClient<AllFields extends Record<string, FieldConfig> = Record
|
|
|
740
973
|
* - 'update': deletes refs for changed ref-bearing fields, then inserts new ones
|
|
741
974
|
*
|
|
742
975
|
* Gracefully skips if entity_refs table is not registered (e.g. before migration).
|
|
976
|
+
*
|
|
977
|
+
* `exec` is the active Drizzle executor — caller-supplied tx (PR D of
|
|
978
|
+
* PLAN-OUTBOX) or `this.db`. Routes the entity_refs UPDATE/INSERT
|
|
979
|
+
* through the same transaction as the parent entity write.
|
|
743
980
|
*/
|
|
744
981
|
private syncRefs;
|
|
745
982
|
/**
|
|
746
983
|
* Invalidate all count cache entries for this entity.
|
|
984
|
+
*
|
|
985
|
+
* **Tx-aware** (PR D of PLAN-OUTBOX). When `inCallerTx === true`, we
|
|
986
|
+
* skip the invalidation: the caller's tx hasn't committed yet, and
|
|
987
|
+
* eagerly invalidating would have other connections re-compute the
|
|
988
|
+
* count from the still-pre-tx state and cache that stale value.
|
|
989
|
+
* The caller is responsible for invalidating after their own commit
|
|
990
|
+
* (or accepting the cache TTL self-heal). For internally-managed
|
|
991
|
+
* txs (no-caller-tx path) and no-tx CRUD calls, the invalidation
|
|
992
|
+
* runs after the inner `db.transaction(...)` resolves — which only
|
|
993
|
+
* happens post-commit — so the cache reflects the committed state.
|
|
747
994
|
*/
|
|
748
995
|
private invalidateCountCache;
|
|
749
996
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/count-cache.ts","../../src/fields/base.ts","../../src/types/infer.ts","../../src/
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/count-cache.ts","../../src/fields/base.ts","../../src/types/infer.ts","../../src/behaviors/types.ts","../../src/cursor.ts","../../src/admin-config.ts","../../src/define-entity.ts","../../src/shared/entity-data-ops.ts","../../src/types/logger.ts","../../src/admin/client.ts"],"mappings":"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"}
|