@murumets-ee/entity 0.10.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 +472 -136
- 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 +129 -3
- 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 +98 -13
- 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.d.mts +17 -0
- package/dist/refs/index.d.mts.map +1 -1
- package/dist/refs/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -74,6 +74,23 @@ interface BaseFieldConfig {
|
|
|
74
74
|
translatable?: boolean;
|
|
75
75
|
indexed?: boolean;
|
|
76
76
|
unique?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Marks the field as **system-managed**: stored as a real column, populated
|
|
79
|
+
* by behavior hooks or trusted server-side transitions, but NOT writable
|
|
80
|
+
* through the public `AdminClient.create/update` surface.
|
|
81
|
+
*
|
|
82
|
+
* - Caller-supplied values for internal fields are silently stripped before
|
|
83
|
+
* hooks run (so an HTTP PATCH cannot poison a workflow state).
|
|
84
|
+
* - `beforeCreate` / `beforeUpdate` hooks may still set them (they run after
|
|
85
|
+
* the strip), and the values are preserved through validation.
|
|
86
|
+
* - Trusted server code that needs to write internals directly — e.g.
|
|
87
|
+
* workflow transitions invoked from an authorized admin route — must use
|
|
88
|
+
* `AdminClient.updateInternal()`, which bypasses the strip.
|
|
89
|
+
*
|
|
90
|
+
* Use this flag on any field added by a behavior whose value represents a
|
|
91
|
+
* controlled state machine (e.g. `_workflowStatus`), not user input.
|
|
92
|
+
*/
|
|
93
|
+
internal?: boolean;
|
|
77
94
|
access?: {
|
|
78
95
|
view?: string;
|
|
79
96
|
edit?: string;
|
|
@@ -182,6 +199,17 @@ type FieldToTS<F extends FieldConfig> = F extends IdField ? string : F extends T
|
|
|
182
199
|
type InferEntityDTO<Fields extends Record<string, FieldConfig>> = {
|
|
183
200
|
id: string;
|
|
184
201
|
} & { [K in keyof Fields as K extends 'id' ? never : Fields[K]['required'] extends true ? K : never]: FieldToTS<Fields[K]> } & { [K in keyof Fields as Fields[K]['required'] extends true ? never : K]?: FieldToTS<Fields[K]> | null };
|
|
202
|
+
/** Fields that are auto-generated and should not appear in create input. */
|
|
203
|
+
type AutoGeneratedFields = 'id' | 'createdAt' | 'updatedAt' | 'createdBy' | 'updatedBy' | '_version';
|
|
204
|
+
/**
|
|
205
|
+
* The input type for creating an entity.
|
|
206
|
+
* - Omits auto-generated fields (id, timestamps, version)
|
|
207
|
+
* - Required fields stay required; optional fields stay optional
|
|
208
|
+
*/
|
|
209
|
+
type InferCreateInput<Fields extends Record<string, FieldConfig>> = Omit<{ [K in keyof Fields as K extends 'id' ? never : Fields[K]['required'] extends true ? K : never]: FieldToTS<Fields[K]> } & { [K in keyof Fields as Fields[K]['required'] extends true ? never : K]?: FieldToTS<Fields[K]> | null }, AutoGeneratedFields>;
|
|
210
|
+
/** Fields that cannot be changed after creation. */
|
|
211
|
+
type ImmutableFields = 'id' | 'createdAt' | 'createdBy';
|
|
212
|
+
type InferUpdateInput<Fields extends Record<string, FieldConfig>> = { [K in keyof Fields as K extends ImmutableFields ? never : K]?: FieldToTS<Fields[K]> | null };
|
|
185
213
|
/**
|
|
186
214
|
* Behavior field types use `type` (not `interface`) because interfaces
|
|
187
215
|
* lack implicit index signatures needed for Record<string, FieldConfig>.
|
|
@@ -232,11 +260,97 @@ type InferEntity<E> = E extends {
|
|
|
232
260
|
} ? InferEntityDTO<F> : never;
|
|
233
261
|
//#endregion
|
|
234
262
|
//#region src/behaviors/types.d.ts
|
|
263
|
+
/**
|
|
264
|
+
* Structural shape of a queue `JobDefinition` as seen by behaviors.
|
|
265
|
+
*
|
|
266
|
+
* The entity package CANNOT import `@murumets-ee/queue` (would form a
|
|
267
|
+
* cycle through `@murumets-ee/core`'s registry — see CLAUDE.md
|
|
268
|
+
* "Package boundaries"). Instead, behaviors receive an `EnqueueOnCommit`
|
|
269
|
+
* function via `BehaviorContext`, and the queue's `JobDefinition<T>`
|
|
270
|
+
* is structurally compatible with this minimal shape. The actual
|
|
271
|
+
* payload validation runs inside the queue when the wrapped resolver
|
|
272
|
+
* forwards the call.
|
|
273
|
+
*/
|
|
274
|
+
interface JobLike {
|
|
275
|
+
readonly name: string;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Resolver shape for `BehaviorContext.enqueueOnCommit`. Synchronous,
|
|
279
|
+
* fire-and-forget — the resolver writes the row in the background and
|
|
280
|
+
* logs failures; behaviors do NOT await.
|
|
281
|
+
*
|
|
282
|
+
* Intended semantics (PLAN-OUTBOX §4.2): the row INSERT participates
|
|
283
|
+
* in the AdminClient operation's transaction — commit makes the job
|
|
284
|
+
* visible to the worker, rollback removes it. As of PR D this is the
|
|
285
|
+
* actual semantics: AdminClient threads its tx into the
|
|
286
|
+
* `EnqueueOnCommitFactory` once per call and passes the result through
|
|
287
|
+
* to behaviors. When the queue plugin is not loaded the field is
|
|
288
|
+
* `undefined` and behaviors no-op (per §6 Q6).
|
|
289
|
+
*/
|
|
290
|
+
type EnqueueOnCommit = (job: JobLike, payload: unknown) => void;
|
|
291
|
+
/**
|
|
292
|
+
* Factory that returns an {@link EnqueueOnCommit} resolver bound to an
|
|
293
|
+
* optional Drizzle transaction handle. AdminClient invokes this once
|
|
294
|
+
* per CRUD operation, passing the active tx so behaviors firing inside
|
|
295
|
+
* the operation enqueue rows that commit (or roll back) atomically
|
|
296
|
+
* with the entity write.
|
|
297
|
+
*
|
|
298
|
+
* The `tx` parameter is intentionally typed as `unknown` here — the
|
|
299
|
+
* entity package CANNOT import `drizzle-orm/postgres-js` types without
|
|
300
|
+
* pulling in the database stack and breaking its leaf-package contract.
|
|
301
|
+
* The queue plugin (which writes the slot) and AdminClient (which
|
|
302
|
+
* supplies the tx) both work with the precise `PostgresJsDatabase`
|
|
303
|
+
* shape; the interior of the factory casts as needed.
|
|
304
|
+
*
|
|
305
|
+
* **Mirror definition** lives in
|
|
306
|
+
* `packages/queue/src/enqueue-on-commit-slot.ts` with `tx?:
|
|
307
|
+
* PostgresJsDatabase`. The two are structurally compatible by design;
|
|
308
|
+
* if you rename or change one, change both. The runtime contract is
|
|
309
|
+
* the same — only the type-time visibility of the parameter differs.
|
|
310
|
+
*/
|
|
311
|
+
type EnqueueOnCommitFactory = (tx?: unknown) => EnqueueOnCommit;
|
|
235
312
|
/**
|
|
236
313
|
* Context passed to behavior hooks. Resolved once per request by AdminClient
|
|
237
314
|
* from its `contextResolver` and forwarded into every hook so behaviors never
|
|
238
315
|
* have to reach into AsyncLocalStorage themselves — that pattern breaks under
|
|
239
316
|
* bundlers (e.g. Turbopack) that duplicate module instances across boundaries.
|
|
317
|
+
*
|
|
318
|
+
* `loadCurrent` returns the *pre-update* entity row. It is eagerly loaded
|
|
319
|
+
* by AdminClient before any hooks fire on the **update** codepath and
|
|
320
|
+
* cached for the rest of that call — so calling it from `beforeUpdate`
|
|
321
|
+
* or `afterUpdate` returns the SAME snapshot regardless of whether a
|
|
322
|
+
* sibling hook touched it. Returns `null` when no entity matches the id
|
|
323
|
+
* (rare — usually means the row was deleted concurrently). On `create`
|
|
324
|
+
* AND `delete` codepaths, `loadCurrent` is undefined: create has no
|
|
325
|
+
* pre-state, and delete hooks receive the entity id directly via their
|
|
326
|
+
* first argument so a separate snapshot is unnecessary.
|
|
327
|
+
*
|
|
328
|
+
* `afterUpdate` always receives the post-update row as its first argument,
|
|
329
|
+
* so the (`row`, `loadCurrent()`) pair gives hooks a complete (after, before)
|
|
330
|
+
* view without per-call Map state. The eager load costs one extra
|
|
331
|
+
* `findById` per update; updates are not a hot path in this codebase, and
|
|
332
|
+
* the consistency win — no foot-gun for hook authors — is worth it.
|
|
333
|
+
*
|
|
334
|
+
* `viaInternal` is `true` when the hook is running on an `AdminClient.updateInternal`
|
|
335
|
+
* call (the trusted server-side path; public PATCH always sets it false).
|
|
336
|
+
* Hooks SHOULD treat this as informational only — the route layer has
|
|
337
|
+
* authorized the *capability*, but the hook is still responsible for
|
|
338
|
+
* enforcing structural invariants. Workflowable, for example, validates
|
|
339
|
+
* the `_workflowStatus` transition table on every update regardless of
|
|
340
|
+
* `viaInternal` so that even a route-layer bug cannot push the workflow
|
|
341
|
+
* row into an illegal state. Use `viaInternal` when a hook genuinely
|
|
342
|
+
* needs to differentiate (e.g. side effects that should only fire when
|
|
343
|
+
* a real user — not the seed loader — initiates the change).
|
|
344
|
+
*
|
|
345
|
+
* `enqueueOnCommit` is the outbox entry point for projection-style hooks
|
|
346
|
+
* (PR C of PLAN-OUTBOX). When wired (the queue plugin is available in
|
|
347
|
+
* the running app), behaviors can enqueue side-effect jobs without
|
|
348
|
+
* importing the queue package directly, keeping entity-as-leaf invariant
|
|
349
|
+
* intact. Synchronous + fire-and-forget — no await needed in hooks.
|
|
350
|
+
* Undefined when the AdminClient was constructed without an
|
|
351
|
+
* `enqueueOnCommit` resolver (e.g. CLI scripts that don't load the
|
|
352
|
+
* queue plugin); behaviors that depend on it must guard with `if
|
|
353
|
+
* (ctx.enqueueOnCommit) { ... }` or document the dependency loudly.
|
|
240
354
|
*/
|
|
241
355
|
interface BehaviorContext {
|
|
242
356
|
user?: {
|
|
@@ -244,6 +358,9 @@ interface BehaviorContext {
|
|
|
244
358
|
name?: string;
|
|
245
359
|
email?: string;
|
|
246
360
|
};
|
|
361
|
+
loadCurrent?: () => Promise<Record<string, unknown> | null>;
|
|
362
|
+
viaInternal?: boolean;
|
|
363
|
+
enqueueOnCommit?: EnqueueOnCommit;
|
|
247
364
|
}
|
|
248
365
|
interface Behavior<F extends Record<string, FieldConfig> = {}> {
|
|
249
366
|
name: string;
|
|
@@ -486,14 +603,14 @@ interface CursorInput {
|
|
|
486
603
|
/** Sort direction — must match the ORDER BY direction. */
|
|
487
604
|
direction: 'asc' | 'desc';
|
|
488
605
|
/** Tie-breaker: last seen entity ID. Required for non-unique sort fields. */
|
|
489
|
-
id?: string;
|
|
606
|
+
id?: string | undefined;
|
|
490
607
|
}
|
|
491
608
|
/** Decoded cursor (internal, after validation). */
|
|
492
609
|
interface DecodedCursor {
|
|
493
610
|
field: string;
|
|
494
611
|
value: string | number;
|
|
495
612
|
direction: 'asc' | 'desc';
|
|
496
|
-
id?: string;
|
|
613
|
+
id?: string | undefined;
|
|
497
614
|
}
|
|
498
615
|
/**
|
|
499
616
|
* Encode a cursor for API transport (base64url).
|
|
@@ -832,6 +949,15 @@ declare function generateLayoutSchema(entity: Entity, parent?: PgTable): _$drizz
|
|
|
832
949
|
};
|
|
833
950
|
dialect: "pg";
|
|
834
951
|
}> | null;
|
|
952
|
+
/**
|
|
953
|
+
* Check whether an entity has a behavior with the given name.
|
|
954
|
+
*
|
|
955
|
+
* Single source of truth replacing per-behavior predicates that used to
|
|
956
|
+
* inline the `entity.behaviors?.some(b => b.name === 'X') ?? false`
|
|
957
|
+
* pattern across the codebase. Use this whenever you need to branch on a
|
|
958
|
+
* behavior's presence — admin UI, schema generation, route dispatch, etc.
|
|
959
|
+
*/
|
|
960
|
+
declare function hasBehavior(entity: Entity, name: string): boolean;
|
|
835
961
|
/**
|
|
836
962
|
* Check if an entity has the versionable behavior
|
|
837
963
|
*/
|
|
@@ -985,5 +1111,5 @@ declare class ForbiddenError extends Error {
|
|
|
985
1111
|
constructor(message: string);
|
|
986
1112
|
}
|
|
987
1113
|
//#endregion
|
|
988
|
-
export { type AuditableFields, type Behavior, type BehaviorContext, type BlockDefinitionRef, type BlocksField, type BooleanField, type ContextResolver, CountCache, type CountCacheLike, type CursorInput, type DateField, type Entity, type EntityAdminConfig, type EntityDefinition, type EntityInput, type EntityUsage, type FieldConfig, type FieldToTS, ForbiddenError, type IdField, type InferEntity, type InferEntityDTO, type JsonField, type JsonValue, type MediaField, type NumberField, type PublishableFields, type ReferenceField, ReferencedEntityError, type RichTextField, type SecurityContext, type SelectField, type SlugField, type TextField, auditable, behavior, buildCursorCondition, buildEntitySchemaMap, decodeCursor, defineEntity, encodeCursor, estimateRowCount, field, generateLayoutSchema, generateLayoutTranslationSchema, generateSchema, generateTranslationSchema, hasBlocksFields, hasTranslatableBlocks, hierarchical, isPublishable, isVersionable, needsLocaleStatus, publishable, revisionable, sluggable, slugify, timestamped };
|
|
1114
|
+
export { type AuditableFields, type Behavior, type BehaviorContext, type BlockDefinitionRef, type BlocksField, type BooleanField, type ContextResolver, CountCache, type CountCacheLike, type CursorInput, type DateField, type EnqueueOnCommit, type EnqueueOnCommitFactory, type Entity, type EntityAdminConfig, type EntityDefinition, type EntityInput, type EntityUsage, type FieldConfig, type FieldToTS, ForbiddenError, type IdField, type InferCreateInput, type InferEntity, type InferEntityDTO, type InferUpdateInput, type JobLike, type JsonField, type JsonValue, type MediaField, type NumberField, type PublishableFields, type ReferenceField, ReferencedEntityError, type RichTextField, type SecurityContext, type SelectField, type SlugField, type TextField, auditable, behavior, buildCursorCondition, buildEntitySchemaMap, decodeCursor, defineEntity, encodeCursor, estimateRowCount, field, generateLayoutSchema, generateLayoutTranslationSchema, generateSchema, generateTranslationSchema, hasBehavior, hasBlocksFields, hasTranslatableBlocks, hierarchical, isPublishable, isVersionable, needsLocaleStatus, publishable, revisionable, sluggable, slugify, timestamped };
|
|
989
1115
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/admin-config.ts","../src/fields/base.ts","../src/types/infer.ts","../src/behaviors/types.ts","../src/behaviors/auditable.ts","../src/behaviors/hierarchical.ts","../src/behaviors/publishable.ts","../src/behaviors/revisionable.ts","../src/behaviors/sluggable.ts","../src/fields/builders.ts","../src/behaviors/timestamped.ts","../src/behaviors/index.ts","../src/count-cache.ts","../src/count-estimate.ts","../src/cursor.ts","../src/define-entity.ts","../src/refs/find-usages.ts","../src/refs/errors.ts","../src/schema-generator.ts","../src/shared/entity-data-ops.ts"],"mappings":";;;;;;;;;;;UAIiB,iBAAA;;EAEf,KAAA;EAFe;EAIf,KAAA;;EAEA,aAAA;EAJA;EAMA,IAAA;EAFA;EAIA,WAAA;EAAA;EAEA,MAAA;EAEA;EAAA,YAAA;EAIA;EAFA,aAAA;EAEkC;EAAlC,cAAA,GAAiB,MAAA;IAAiB,KAAA;IAAgB,WAAA;IAAsB,WAAA;EAAA;EAQxE;EANA,WAAA;EAUA;EARA,oBAAA;EAoBA;EAlBA,QAAA;EAuBiB;EArBjB,UAAA;;EAEA,aAAA;;EAEA,SAAA;EC7B8B;;;;;EDmC9B,MAAA;EC/BA;;;;;EDqCA,YAAA;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/admin-config.ts","../src/fields/base.ts","../src/types/infer.ts","../src/behaviors/types.ts","../src/behaviors/auditable.ts","../src/behaviors/hierarchical.ts","../src/behaviors/publishable.ts","../src/behaviors/revisionable.ts","../src/behaviors/sluggable.ts","../src/fields/builders.ts","../src/behaviors/timestamped.ts","../src/behaviors/index.ts","../src/count-cache.ts","../src/count-estimate.ts","../src/cursor.ts","../src/define-entity.ts","../src/refs/find-usages.ts","../src/refs/errors.ts","../src/schema-generator.ts","../src/shared/entity-data-ops.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{and as e,eq as t,getTableColumns as n,gt as r,lt as i,or as a,sql as o}from"drizzle-orm";import{boolean as s,doublePrecision as c,index as l,integer as u,jsonb as d,pgTable as f,text as p,timestamp as m,unique as h,uuid as g,varchar as _}from"drizzle-orm/pg-core";import"@murumets-ee/db";const v={id:e=>({type:`id`,required:!0,indexed:!0,...e}),text:e=>({type:`text`,...e}),number:e=>({type:`number`,...e}),boolean:e=>({type:`boolean`,default:!1,...e}),date:e=>({type:`date`,...e}),select:e=>({type:`select`,...e}),reference:e=>({type:`reference`,cardinality:`one`,onDelete:`set-null`,...e}),media:e=>({type:`media`,...e}),richtext:e=>({type:`richtext`,...e}),slug:e=>({type:`slug`,unique:!0,indexed:!0,...e}),json:e=>({type:`json`,...e}),blocks:e=>({type:`blocks`,...e})};function y(){return{name:`auditable`,fields:{createdBy:v.text(),updatedBy:v.text(),createdAt:v.date({indexed:!0}),updatedAt:v.date({indexed:!0})},hooks:{beforeCreate:async(e,t)=>{e.createdAt=new Date,e.updatedAt=new Date;let n=t?.user?.id;return n&&(e.createdBy=n,e.updatedBy=n),e},beforeUpdate:async(e,t,n)=>{t.updatedAt=new Date;let r=n?.user?.id;return r&&(t.updatedBy=r),t}}}}function b(e){return{name:`hierarchical`,fields:{parentId:v.reference({entity:`_self`,required:!1}),path:v.text({indexed:!0,maxLength:2048}),depth:v.number({integer:!0,default:0,indexed:!0})},hooks:{beforeCreate:async e=>(e.parentId||(e.depth=0),e)}}}function x(){return{name:`publishable`,fields:{status:v.select({options:[`draft`,`published`],default:`draft`,indexed:!0}),publishedAt:v.date({indexed:!0})},hooks:{beforeUpdate:async(e,t)=>(t.status===`published`&&!t.publishedAt&&(t.publishedAt=new Date),t)}}}function S(){return{name:`revisionable`,fields:{_version:v.number({required:!0,default:1,integer:!0})},hooks:{beforeCreate:async e=>(e._version=1,e),beforeUpdate:async(e,t)=>(t._version=(Number(t._version)||0)+1,t)}}}function C(e){return e.toLowerCase().trim().replace(/[^\w\s-]/g,``).replace(/[\s_-]+/g,`-`).replace(/^-+|-+$/g,``)}function w(e,t){return{name:`sluggable`,fields:{slug:v.slug({from:e,...t?.translatable?{translatable:!0}:{}})},hooks:{beforeCreate:async t=>(!t.slug&&t[e]&&(t.slug=C(String(t[e]))),t),beforeUpdate:async(t,n)=>(n[e]&&!n.slug&&(n.slug=C(String(n[e]))),n)}}}function T(){return{name:`timestamped`,fields:{createdAt:v.date({indexed:!0}),updatedAt:v.date({indexed:!0})},hooks:{beforeCreate:async e=>(e.createdAt=new Date,e.updatedAt=new Date,e),beforeUpdate:async(e,t)=>(t.updatedAt=new Date,t)}}}const E={publishable:x,auditable:y,sluggable:w,revisionable:S,hierarchical:b,timestamped:T};var D=class{cache=new Map;inflight=new Map;ttlMs;constructor(e=5e3){this.ttlMs=e}get(e){let t=this.cache.get(e);if(!t||Date.now()>t.expiresAt){t&&this.cache.delete(e);return}return t.count}set(e,t){this.cache.set(e,{count:t,expiresAt:Date.now()+this.ttlMs})}getOrCompute(e,t){let n=this.get(e);if(n!==void 0)return n;let r=this.inflight.get(e);if(r)return r;let i=t().then(t=>(this.set(e,t),t)).finally(()=>{this.inflight.delete(e)});return this.inflight.set(e,i),i}invalidate(e){for(let t of this.cache.keys()){let n=t.startsWith(`query:`)?t.slice(6):t;(n===e||n.startsWith(`${e}:`)||n.startsWith(`${e}@`))&&this.cache.delete(t)}}prune(){let e=Date.now();for(let[t,n]of this.cache.entries())e>n.expiresAt&&this.cache.delete(t)}clear(){this.cache.clear()}get size(){return this.cache.size}};async function O(e,t){let n=await e.execute(o`SELECT reltuples::bigint AS estimate FROM pg_class WHERE relname = ${t}`),r=(Array.isArray(n)?n:n.rows??[])[0],i=Number(r?.estimate??0);return i>0?i:0}const k=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function A(e,t,n){let r={field:t,value:e[t],direction:n,id:e.id};return btoa(JSON.stringify(r))}function j(e){try{let t=atob(e),n=JSON.parse(t);if(typeof n!=`object`||!n)return null;let r=n;return typeof r.field!=`string`||!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(r.field)||typeof r.value!=`string`&&typeof r.value!=`number`||r.direction!==`asc`&&r.direction!==`desc`||r.id!==void 0&&(typeof r.id!=`string`||!k.test(r.id))?null:{field:r.field,value:r.value,direction:r.direction,id:r.id}}catch{return null}}function M(o,s){let c=n(o),l=c[s.field];if(!l)return null;let u=s.direction===`desc`?i:r,d=u(l,s.value);if(!s.id)return d;let f=c.id;if(!f)return d;let p=u(f,s.id);return a(d,e(t(l,s.value),p))??d}function N(e){let t={};for(let n of e.behaviors||[])if(n.fields)for(let[e,r]of Object.entries(n.fields)){if(t[e]){console.warn(`Field '${e}' from behavior '${n.name}' conflicts with existing field. Skipping.`);continue}t[e]=r}let n={id:v.id(),...t,...e.fields};for(let[,e]of Object.entries(n))e.type===`slug`&&!e.translatable&&n[e.from]?.translatable&&(e.translatable=!0);return{...e,allFields:n}}var P=class extends Error{entityName;entityId;usages;constructor(e,t,n){let r=n.length;super(`Cannot delete ${e} '${t}': referenced by ${r} other entit${r===1?`y`:`ies`}`),this.name=`ReferencedEntityError`,this.entityName=e,this.entityId=t,this.usages=n}};const F=f(`entity_refs`,{sourceEntity:_(`source_entity`,{length:100}).notNull(),sourceId:g(`source_id`).notNull(),sourceField:_(`source_field`,{length:100}).notNull(),targetEntity:_(`target_entity`,{length:100}).notNull(),targetId:g(`target_id`).notNull()},e=>[h(`uq_entity_refs`).on(e.sourceEntity,e.sourceId,e.sourceField,e.targetEntity,e.targetId),l(`idx_entity_refs_target`).on(e.targetEntity,e.targetId),l(`idx_entity_refs_source`).on(e.sourceEntity,e.sourceId)]);function I(e,t,n){let r=n?.nullable??!1;switch(t.type){case`id`:return g(e).primaryKey().defaultRandom();case`text`:if(t.maxLength&&t.maxLength<=255){let n=_(e,{length:t.maxLength});return t.unique&&(n=n.unique()),!r&&t.required&&(n=n.notNull()),!r&&t.default!==void 0&&(n=n.default(t.default)),n}else{let n=p(e);return t.unique&&(n=n.unique()),!r&&t.required&&(n=n.notNull()),!r&&t.default!==void 0&&(n=n.default(t.default)),n}case`number`:{let n=t.integer?u(e):c(e);return!r&&t.required&&(n=n.notNull()),!r&&t.default!==void 0&&(n=n.default(t.default)),n}case`boolean`:{let n=s(e);if(!r&&t.required&&(n=n.notNull()),!r){let e=t.default===void 0?!1:t.default;n=n.default(e)}return n}case`date`:{let n=m(e,{withTimezone:!0});return!r&&t.required&&(n=n.notNull()),!r&&t.default!==void 0&&(n=n.default(t.default)),n}case`select`:{let n=_(e,{length:100});return!r&&t.required&&(n=n.notNull()),!r&&t.default!==void 0&&(n=n.default(t.default)),n}case`reference`:{if(t.cardinality===`many`)return g(e).array();let n=g(e);return!r&&t.required&&(n=n.notNull()),n}case`media`:{let n=g(e);return!r&&t.required&&(n=n.notNull()),n}case`slug`:{let n=_(e,{length:255});return t.unique&&!r&&(n=n.unique()),!r&&t.required&&(n=n.notNull()),n}case`richtext`:{let n=p(e);return!r&&t.required&&(n=n.notNull()),n}case`json`:return d(e);default:return p(e)}}function L(e){let t=e.name,n={};for(let[t,r]of Object.entries(e.allFields))r.type!==`blocks`&&(n[t]=I(t,r));(e.scope===`team`||e.scope===`user`)&&(n._scopeId=g(`_scope_id`));let r=Object.entries(e.allFields).filter(([e,t])=>t.type!==`blocks`&&t.type!==`id`&&t.indexed&&!t.unique),i=e.behaviors?.some(e=>e.name===`publishable`)??!1;return r.length===0&&!i?f(t,n):f(t,n,e=>{let n={};for(let[i]of r)n[`idx_${t}_${i}`]=l(`idx_${t}_${i}`).on(e[i]);return i&&e.status&&e.createdAt&&(n[`idx_${t}_status_created`]=l(`idx_${t}_status_created`).on(e.status,e.createdAt)),n})}function R(e,t){let r=Object.entries(e.allFields).filter(([e,t])=>t.translatable);if(r.length===0)return null;let i=`${e.name}_translations`,a=t?g(`entity_id`).notNull().references(()=>n(t).id,{onDelete:`cascade`}):g(`entity_id`).notNull(),o={id:g(`id`).primaryKey().defaultRandom(),entityId:a,locale:_(`locale`,{length:10}).notNull()},s=r.some(([e,t])=>t.type===`slug`);for(let[e,t]of r)o[e]=I(e,t,{nullable:!0});return f(i,o,e=>({uniqueEntityLocale:h().on(e.entityId,e.locale),...s&&e.slug?{uniqueSlugLocale:h().on(e.slug,e.locale)}:{}}))}function z(e){return Object.values(e.allFields).some(e=>e.type===`blocks`)}function B(e,t){if(!z(e))return null;let r=`${e.name}_layout`,i=t?g(`entity_id`).notNull().references(()=>n(t).id,{onDelete:`cascade`}):g(`entity_id`).notNull();return f(r,{id:g(`id`).primaryKey().defaultRandom(),entityId:i,fieldName:_(`field_name`,{length:100}).notNull(),blockType:_(`block_type`,{length:100}).notNull(),sortOrder:u(`sort_order`).notNull().default(0),data:d(`data`),locale:_(`locale`,{length:10})},e=>({idx_entity_locale_sort:l(`idx_${r}_entity_locale_sort`).on(e.entityId,e.locale,e.sortOrder)}))}function V(e){return e.behaviors?.some(e=>e.name===`versionable`)??!1}function H(e){if(!(e.behaviors?.some(e=>e.name===`publishable`)??!1))return!1;let t=e.allFields;return Object.values(t).some(e=>e.translatable)}function U(e){return e.behaviors?.some(e=>e.name===`publishable`)??!1}function W(e,t){return f(`${e.name}_locale_status`,{id:g(`id`).primaryKey().defaultRandom(),entityId:g(`entity_id`).notNull().references(()=>n(t).id,{onDelete:`cascade`}),locale:_(`locale`,{length:10}).notNull(),status:_(`status`,{length:20}).notNull().default(`draft`),publishedAt:m(`published_at`,{withTimezone:!0})},e=>({uniqueEntityLocale:h().on(e.entityId,e.locale)}))}function G(e,t){return f(`${e.name}_drafts`,{id:g(`id`).primaryKey().defaultRandom(),entityId:g(`entity_id`).notNull().references(()=>n(t).id,{onDelete:`cascade`}),locale:_(`locale`,{length:10}).notNull().default(`_`),data:d(`data`).notNull(),createdBy:_(`created_by`,{length:255}).notNull(),createdByName:_(`created_by_name`,{length:255}),createdAt:m(`created_at`,{withTimezone:!0}).notNull().defaultNow(),updatedAt:m(`updated_at`,{withTimezone:!0}).notNull().defaultNow()},e=>({uniqueEntityLocale:h().on(e.entityId,e.locale)}))}function K(e,t){return f(`${e.name}_versions`,{id:g(`id`).primaryKey().defaultRandom(),entityId:g(`entity_id`).notNull().references(()=>n(t).id,{onDelete:`cascade`}),version:u(`version`).notNull(),locale:_(`locale`,{length:10}).notNull().default(`_`),data:d(`data`).notNull(),delta:d(`delta`),status:_(`status`,{length:20}),createdBy:_(`created_by`,{length:255}),createdByName:_(`created_by_name`,{length:255}),createdAt:m(`created_at`,{withTimezone:!0}).notNull().defaultNow(),isAutosave:s(`is_autosave`).notNull().default(!1)},e=>({uniqueEntityVersionLocale:h().on(e.entityId,e.version,e.locale)}))}function q(){return f(`toolkit_content_locks`,{id:g(`id`).primaryKey().defaultRandom(),entityType:_(`entity_type`,{length:100}).notNull(),entityId:_(`entity_id`,{length:255}).notNull(),locale:_(`locale`,{length:10}).notNull().default(`_`),lockedBy:_(`locked_by`,{length:255}).notNull(),lockedByName:_(`locked_by_name`,{length:255}),lockedAt:m(`locked_at`,{withTimezone:!0}).notNull().defaultNow(),expiresAt:m(`expires_at`,{withTimezone:!0}).notNull()},e=>({uniqueEntityLock:h().on(e.entityType,e.entityId,e.locale)}))}function J(e){let t=e.allFields;return Object.values(t).some(e=>e.type!==`blocks`||e.localized?!1:e.blocks?.some(e=>Object.values(e.fields).some(e=>e.translatable)))}function Y(e,t){let r=Object.values(e.allFields).filter(e=>e.type===`blocks`&&!(`localized`in e&&e.localized));if(r.length===0||!r.some(e=>e.type===`blocks`?e.blocks.some(e=>Object.values(e.fields).some(e=>e.translatable)):!1))return null;let i=`${e.name}_layout_translations`,a=t?g(`layout_id`).notNull().references(()=>n(t).id,{onDelete:`cascade`}):g(`layout_id`).notNull();return f(i,{id:g(`id`).primaryKey().defaultRandom(),layoutId:a,locale:_(`locale`,{length:10}).notNull(),fields:d(`fields`).notNull()},e=>({uniqueLayoutLocale:h().on(e.layoutId,e.locale)}))}function X(e){let t={},n=!1;for(let r of e){let e=L(r);t[r.name]=e;let i=R(r,e);if(i&&(t[`${r.name}_translations`]=i),z(r)){let n=B(r,e);if(n){t[`${r.name}_layout`]=n;let e=Y(r,n);e&&(t[`${r.name}_layout_translations`]=e)}}V(r)&&(t[`${r.name}_versions`]=K(r,e)),H(r)&&(t[`${r.name}_locale_status`]=W(r,e)),U(r)&&(t[`${r.name}_drafts`]=G(r,e),n=!0)}return n&&(t.toolkit_content_locks=q()),t.entity_refs=F,t}var Z=class extends Error{constructor(e){super(e),this.name=`ForbiddenError`}};export{D as CountCache,Z as ForbiddenError,P as ReferencedEntityError,y as auditable,E as behavior,M as buildCursorCondition,X as buildEntitySchemaMap,j as decodeCursor,N as defineEntity,A as encodeCursor,O as estimateRowCount,v as field,B as generateLayoutSchema,Y as generateLayoutTranslationSchema,L as generateSchema,R as generateTranslationSchema,z as hasBlocksFields,J as hasTranslatableBlocks,b as hierarchical,U as isPublishable,V as isVersionable,H as needsLocaleStatus,x as publishable,S as revisionable,w as sluggable,C as slugify,T as timestamped};
|
|
1
|
+
import{and as e,eq as t,getTableColumns as n,gt as r,lt as i,or as a,sql as o}from"drizzle-orm";import{boolean as s,doublePrecision as c,index as l,integer as u,jsonb as d,pgTable as f,text as p,timestamp as m,unique as h,uuid as g,varchar as _}from"drizzle-orm/pg-core";import"@murumets-ee/db";const v={id:e=>({type:`id`,required:!0,indexed:!0,...e}),text:e=>({type:`text`,...e}),number:e=>({type:`number`,...e}),boolean:e=>({type:`boolean`,default:!1,...e}),date:e=>({type:`date`,...e}),select:e=>({type:`select`,...e}),reference:e=>({type:`reference`,cardinality:`one`,onDelete:`set-null`,...e}),media:e=>({type:`media`,...e}),richtext:e=>({type:`richtext`,...e}),slug:e=>({type:`slug`,unique:!0,indexed:!0,...e}),json:e=>({type:`json`,...e}),blocks:e=>({type:`blocks`,...e})};function y(){return{name:`auditable`,fields:{createdBy:v.text(),updatedBy:v.text(),createdAt:v.date({indexed:!0}),updatedAt:v.date({indexed:!0})},hooks:{beforeCreate:async(e,t)=>{e.createdAt=new Date,e.updatedAt=new Date;let n=t?.user?.id;return n&&(e.createdBy=n,e.updatedBy=n),e},beforeUpdate:async(e,t,n)=>{t.updatedAt=new Date;let r=n?.user?.id;return r&&(t.updatedBy=r),t}}}}function b(e){return{name:`hierarchical`,fields:{parentId:v.reference({entity:`_self`,required:!1}),path:v.text({indexed:!0,maxLength:2048}),depth:v.number({integer:!0,default:0,indexed:!0})},hooks:{beforeCreate:async e=>(e.parentId||(e.depth=0),e)}}}function x(){return{name:`publishable`,fields:{status:v.select({options:[`draft`,`published`],default:`draft`,indexed:!0}),publishedAt:v.date({indexed:!0})},hooks:{beforeUpdate:async(e,t)=>(t.status===`published`&&!t.publishedAt&&(t.publishedAt=new Date),t)}}}function S(){return{name:`revisionable`,fields:{_version:v.number({required:!0,default:1,integer:!0,internal:!0})},hooks:{beforeCreate:async e=>(e._version=1,e),beforeUpdate:async(e,t)=>(t._version=(Number(t._version)||0)+1,t)}}}function C(e){return e.toLowerCase().trim().replace(/[^\w\s-]/g,``).replace(/[\s_-]+/g,`-`).replace(/^-+|-+$/g,``)}function w(e,t){return{name:`sluggable`,fields:{slug:v.slug({from:e,...t?.translatable?{translatable:!0}:{}})},hooks:{beforeCreate:async t=>(!t.slug&&t[e]&&(t.slug=C(String(t[e]))),t),beforeUpdate:async(t,n)=>(n[e]&&!n.slug&&(n.slug=C(String(n[e]))),n)}}}function T(){return{name:`timestamped`,fields:{createdAt:v.date({indexed:!0}),updatedAt:v.date({indexed:!0})},hooks:{beforeCreate:async e=>(e.createdAt=new Date,e.updatedAt=new Date,e),beforeUpdate:async(e,t)=>(t.updatedAt=new Date,t)}}}const E={publishable:x,auditable:y,sluggable:w,revisionable:S,hierarchical:b,timestamped:T};var D=class{cache=new Map;inflight=new Map;ttlMs;constructor(e=5e3){this.ttlMs=e}get(e){let t=this.cache.get(e);if(!t||Date.now()>t.expiresAt){t&&this.cache.delete(e);return}return t.count}set(e,t){this.cache.set(e,{count:t,expiresAt:Date.now()+this.ttlMs})}getOrCompute(e,t){let n=this.get(e);if(n!==void 0)return n;let r=this.inflight.get(e);if(r)return r;let i=t().then(t=>(this.set(e,t),t)).finally(()=>{this.inflight.delete(e)});return this.inflight.set(e,i),i}invalidate(e){for(let t of this.cache.keys()){let n=t.startsWith(`query:`)?t.slice(6):t;(n===e||n.startsWith(`${e}:`)||n.startsWith(`${e}@`))&&this.cache.delete(t)}}prune(){let e=Date.now();for(let[t,n]of this.cache.entries())e>n.expiresAt&&this.cache.delete(t)}clear(){this.cache.clear()}get size(){return this.cache.size}};async function O(e,t){let n=await e.execute(o`SELECT reltuples::bigint AS estimate FROM pg_class WHERE relname = ${t}`),r=(Array.isArray(n)?n:n.rows??[])[0],i=Number(r?.estimate??0);return i>0?i:0}const k=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function A(e,t,n){let r={field:t,value:e[t],direction:n,id:e.id};return btoa(JSON.stringify(r))}function j(e){try{let t=atob(e),n=JSON.parse(t);if(typeof n!=`object`||!n)return null;let r=n;return typeof r.field!=`string`||!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(r.field)||typeof r.value!=`string`&&typeof r.value!=`number`||r.field===`id`&&(typeof r.value!=`string`||!k.test(r.value))||r.direction!==`asc`&&r.direction!==`desc`||r.id!==void 0&&(typeof r.id!=`string`||!k.test(r.id))?null:{field:r.field,value:r.value,direction:r.direction,id:r.id}}catch{return null}}function M(o,s){let c=n(o),l=c[s.field];if(!l)return null;let u=s.direction===`desc`?i:r,d=u(l,s.value);if(!s.id)return d;let f=c.id;if(!f)return d;let p=u(f,s.id);return a(d,e(t(l,s.value),p))??d}function N(e){let t={};for(let n of e.behaviors||[])if(n.fields)for(let[e,r]of Object.entries(n.fields)){if(t[e]){console.warn(`Field '${e}' from behavior '${n.name}' conflicts with existing field. Skipping.`);continue}t[e]=r}let n={id:v.id(),...t,...e.fields};for(let[,e]of Object.entries(n))e.type===`slug`&&!e.translatable&&n[e.from]?.translatable&&(e.translatable=!0);return{...e,allFields:n}}var P=class extends Error{entityName;entityId;usages;constructor(e,t,n){let r=n.length;super(`Cannot delete ${e} '${t}': referenced by ${r} other entit${r===1?`y`:`ies`}`),this.name=`ReferencedEntityError`,this.entityName=e,this.entityId=t,this.usages=n}};const F=f(`entity_refs`,{sourceEntity:_(`source_entity`,{length:100}).notNull(),sourceId:g(`source_id`).notNull(),sourceField:_(`source_field`,{length:100}).notNull(),targetEntity:_(`target_entity`,{length:100}).notNull(),targetId:g(`target_id`).notNull()},e=>[h(`uq_entity_refs`).on(e.sourceEntity,e.sourceId,e.sourceField,e.targetEntity,e.targetId),l(`idx_entity_refs_target`).on(e.targetEntity,e.targetId),l(`idx_entity_refs_source`).on(e.sourceEntity,e.sourceId)]);function I(e,t){let r=n(e).id;if(!r)throw Error(`Parent table for "${t}" has no "id" column`);return r}function L(e,t,n){let r=n?.nullable??!1;switch(t.type){case`id`:return g(e).primaryKey().defaultRandom();case`text`:if(t.maxLength&&t.maxLength<=255){let n=_(e,{length:t.maxLength});return t.unique&&(n=n.unique()),!r&&t.required&&(n=n.notNull()),!r&&t.default!==void 0&&(n=n.default(t.default)),n}else{let n=p(e);return t.unique&&(n=n.unique()),!r&&t.required&&(n=n.notNull()),!r&&t.default!==void 0&&(n=n.default(t.default)),n}case`number`:{let n=t.integer?u(e):c(e);return!r&&t.required&&(n=n.notNull()),!r&&t.default!==void 0&&(n=n.default(t.default)),n}case`boolean`:{let n=s(e);if(!r&&t.required&&(n=n.notNull()),!r){let e=t.default===void 0?!1:t.default;n=n.default(e)}return n}case`date`:{let n=m(e,{withTimezone:!0});return!r&&t.required&&(n=n.notNull()),!r&&t.default!==void 0&&(n=n.default(t.default)),n}case`select`:{let n=_(e,{length:100});return!r&&t.required&&(n=n.notNull()),!r&&t.default!==void 0&&(n=n.default(t.default)),n}case`reference`:{if(t.cardinality===`many`)return g(e).array();let n=g(e);return!r&&t.required&&(n=n.notNull()),n}case`media`:{let n=g(e);return!r&&t.required&&(n=n.notNull()),n}case`slug`:{let n=_(e,{length:255});return t.unique&&!r&&(n=n.unique()),!r&&t.required&&(n=n.notNull()),n}case`richtext`:{let n=p(e);return!r&&t.required&&(n=n.notNull()),n}case`json`:return d(e);default:return p(e)}}function R(e){let t=e.name,n={};for(let[t,r]of Object.entries(e.allFields))r.type!==`blocks`&&(n[t]=L(t,r));(e.scope===`team`||e.scope===`user`)&&(n._scopeId=g(`_scope_id`));let r=Object.entries(e.allFields).filter(([e,t])=>t.type!==`blocks`&&t.type!==`id`&&t.indexed&&!t.unique),i=e.behaviors?.some(e=>e.name===`publishable`)??!1;return r.length===0&&!i?f(t,n):f(t,n,e=>{let n={};for(let[i]of r){let r=e[i];if(!r)throw Error(`generateSchema: indexed field "${i}" missing from "${t}" pgTable`);n[`idx_${t}_${i}`]=l(`idx_${t}_${i}`).on(r)}let a=e.status,o=e.createdAt;return i&&a&&o&&(n[`idx_${t}_status_created`]=l(`idx_${t}_status_created`).on(a,o)),n})}function z(e,t){let n=Object.entries(e.allFields).filter(([e,t])=>t.translatable);if(n.length===0)return null;let r=`${e.name}_translations`,i=t?g(`entity_id`).notNull().references(()=>I(t,e.name),{onDelete:`cascade`}):g(`entity_id`).notNull(),a={id:g(`id`).primaryKey().defaultRandom(),entityId:i,locale:_(`locale`,{length:10}).notNull()},o=n.some(([e,t])=>t.type===`slug`);for(let[e,t]of n)a[e]=L(e,t,{nullable:!0});return f(r,a,t=>{let n=t.entityId,r=t.locale;if(!n||!r)throw Error(`Translation table for "${e.name}" missing entityId/locale columns`);let i=t.slug;return{uniqueEntityLocale:h().on(n,r),...o&&i?{uniqueSlugLocale:h().on(i,r)}:{}}})}function B(e){return Object.values(e.allFields).some(e=>e.type===`blocks`)}function V(e,t){if(!B(e))return null;let n=`${e.name}_layout`,r=t?g(`entity_id`).notNull().references(()=>I(t,e.name),{onDelete:`cascade`}):g(`entity_id`).notNull();return f(n,{id:g(`id`).primaryKey().defaultRandom(),entityId:r,fieldName:_(`field_name`,{length:100}).notNull(),blockType:_(`block_type`,{length:100}).notNull(),sortOrder:u(`sort_order`).notNull().default(0),data:d(`data`),locale:_(`locale`,{length:10})},e=>({idx_entity_locale_sort:l(`idx_${n}_entity_locale_sort`).on(e.entityId,e.locale,e.sortOrder)}))}function H(e,t){return e.behaviors?.some(e=>e.name===t)??!1}function U(e){return H(e,`versionable`)}function W(e){if(!H(e,`publishable`))return!1;let t=e.allFields;return Object.values(t).some(e=>e.translatable)}function G(e){return H(e,`publishable`)}function K(e,t){return f(`${e.name}_locale_status`,{id:g(`id`).primaryKey().defaultRandom(),entityId:g(`entity_id`).notNull().references(()=>I(t,e.name),{onDelete:`cascade`}),locale:_(`locale`,{length:10}).notNull(),status:_(`status`,{length:20}).notNull().default(`draft`),publishedAt:m(`published_at`,{withTimezone:!0})},e=>({uniqueEntityLocale:h().on(e.entityId,e.locale)}))}function q(e,t){return f(`${e.name}_drafts`,{id:g(`id`).primaryKey().defaultRandom(),entityId:g(`entity_id`).notNull().references(()=>I(t,e.name),{onDelete:`cascade`}),locale:_(`locale`,{length:10}).notNull().default(`_`),data:d(`data`).notNull(),createdBy:_(`created_by`,{length:255}).notNull(),createdByName:_(`created_by_name`,{length:255}),createdAt:m(`created_at`,{withTimezone:!0}).notNull().defaultNow(),updatedAt:m(`updated_at`,{withTimezone:!0}).notNull().defaultNow()},e=>({uniqueEntityLocale:h().on(e.entityId,e.locale)}))}function J(e,t){return f(`${e.name}_versions`,{id:g(`id`).primaryKey().defaultRandom(),entityId:g(`entity_id`).notNull().references(()=>I(t,e.name),{onDelete:`cascade`}),version:u(`version`).notNull(),locale:_(`locale`,{length:10}).notNull().default(`_`),data:d(`data`).notNull(),delta:d(`delta`),status:_(`status`,{length:20}),createdBy:_(`created_by`,{length:255}),createdByName:_(`created_by_name`,{length:255}),createdAt:m(`created_at`,{withTimezone:!0}).notNull().defaultNow(),isAutosave:s(`is_autosave`).notNull().default(!1)},e=>({uniqueEntityVersionLocale:h().on(e.entityId,e.version,e.locale)}))}function Y(){return f(`toolkit_content_locks`,{id:g(`id`).primaryKey().defaultRandom(),entityType:_(`entity_type`,{length:100}).notNull(),entityId:_(`entity_id`,{length:255}).notNull(),locale:_(`locale`,{length:10}).notNull().default(`_`),lockedBy:_(`locked_by`,{length:255}).notNull(),lockedByName:_(`locked_by_name`,{length:255}),lockedAt:m(`locked_at`,{withTimezone:!0}).notNull().defaultNow(),expiresAt:m(`expires_at`,{withTimezone:!0}).notNull()},e=>({uniqueEntityLock:h().on(e.entityType,e.entityId,e.locale)}))}function X(e){let t=e.allFields;return Object.values(t).some(e=>e.type!==`blocks`||e.localized?!1:e.blocks?.some(e=>Object.values(e.fields).some(e=>e.translatable)))}function Z(e,t){let n=Object.values(e.allFields).filter(e=>e.type===`blocks`&&!(`localized`in e&&e.localized));if(n.length===0||!n.some(e=>e.type===`blocks`?e.blocks.some(e=>Object.values(e.fields).some(e=>e.translatable)):!1))return null;let r=`${e.name}_layout_translations`,i=t?g(`layout_id`).notNull().references(()=>I(t,`${e.name} layout`),{onDelete:`cascade`}):g(`layout_id`).notNull();return f(r,{id:g(`id`).primaryKey().defaultRandom(),layoutId:i,locale:_(`locale`,{length:10}).notNull(),fields:d(`fields`).notNull()},e=>({uniqueLayoutLocale:h().on(e.layoutId,e.locale)}))}function Q(e){let t={},n=!1;for(let r of e){let e=R(r);t[r.name]=e;let i=z(r,e);if(i&&(t[`${r.name}_translations`]=i),B(r)){let n=V(r,e);if(n){t[`${r.name}_layout`]=n;let e=Z(r,n);e&&(t[`${r.name}_layout_translations`]=e)}}U(r)&&(t[`${r.name}_versions`]=J(r,e)),W(r)&&(t[`${r.name}_locale_status`]=K(r,e)),G(r)&&(t[`${r.name}_drafts`]=q(r,e),n=!0)}return n&&(t.toolkit_content_locks=Y()),t.entity_refs=F,t}var $=class extends Error{constructor(e){super(e),this.name=`ForbiddenError`}};export{D as CountCache,$ as ForbiddenError,P as ReferencedEntityError,y as auditable,E as behavior,M as buildCursorCondition,Q as buildEntitySchemaMap,j as decodeCursor,N as defineEntity,A as encodeCursor,O as estimateRowCount,v as field,V as generateLayoutSchema,Z as generateLayoutTranslationSchema,R as generateSchema,z as generateTranslationSchema,H as hasBehavior,B as hasBlocksFields,X as hasTranslatableBlocks,b as hierarchical,G as isPublishable,U as isVersionable,W as needsLocaleStatus,x as publishable,S as revisionable,w as sluggable,C as slugify,T as timestamped};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|