@murumets-ee/entity 0.15.4 → 0.16.1

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.
@@ -1,5 +1,5 @@
1
1
  import { SQL, eq } from "drizzle-orm";
2
- import { PgTableWithColumns } from "drizzle-orm/pg-core";
2
+ import { PgColumn, PgColumnBuilderBase, PgTableWithColumns } from "drizzle-orm/pg-core";
3
3
  import { PostgresJsDatabase } from "drizzle-orm/postgres-js";
4
4
 
5
5
  //#region src/count-cache.d.ts
@@ -184,6 +184,35 @@ 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/schema-fragment.d.ts
188
+ /** Which table a behavior fragment targets. */
189
+ type SchemaTarget = 'main' | 'translations';
190
+ /**
191
+ * A constraint contributed by a behavior. The union is intentionally
192
+ * closed — there is NO `kind: 'raw'` escape hatch. If a future behavior
193
+ * needs a new constraint shape, add a typed variant to this union rather
194
+ * than reaching for raw SQL.
195
+ */
196
+ type SchemaFragment = {
197
+ kind: 'index';
198
+ name: string;
199
+ on: PgColumn[]; /** Defaults to btree. Pass `'gin'`/`'gist'` for FTS / vector indexes. */
200
+ using?: 'btree' | 'gin' | 'gist' | 'hash' | 'brin';
201
+ } | {
202
+ kind: 'uniqueConstraint';
203
+ /**
204
+ * Required even though Drizzle's `unique()` accepts an unnamed
205
+ * constraint — the schema generator uses `name` as the
206
+ * collision-detection key across behaviors.
207
+ */
208
+ name: string;
209
+ on: PgColumn[];
210
+ } | {
211
+ kind: 'checkConstraint';
212
+ name: string;
213
+ expression: SQL;
214
+ };
215
+ //#endregion
187
216
  //#region src/behaviors/types.d.ts
188
217
  /**
189
218
  * Structural shape of a queue `JobDefinition` as seen by behaviors.
@@ -298,6 +327,40 @@ interface Behavior<F extends Record<string, FieldConfig> = {}> {
298
327
  beforeDelete?: (id: string, ctx?: BehaviorContext) => Promise<void>;
299
328
  afterDelete?: (id: string, ctx?: BehaviorContext) => Promise<void>;
300
329
  };
330
+ /**
331
+ * Contribute extra columns to the entity's main table or `<entity>_translations` table.
332
+ * Runs BEFORE the Drizzle `pgTable()` call so contributions (including GENERATED
333
+ * columns) participate in the column map. Returns an empty object when the behavior
334
+ * does not contribute to the requested `target`.
335
+ *
336
+ * `info.allFields` is the post-behaviors-merge field map (i.e. user fields plus
337
+ * any fields contributed by earlier behaviors). Behaviors like `searchable()`
338
+ * use it to decide whether to put the column on `'main'` or `'translations'`
339
+ * based on each referenced field's `translatable` flag.
340
+ *
341
+ * Collisions with entity fields or other behaviors' contributions throw at
342
+ * schema-build time — see `schema-generator.ts:collectBehaviorContributions`.
343
+ */
344
+ columns?: (target: SchemaTarget, info: BehaviorSchemaInfo) => Record<string, PgColumnBuilderBase>;
345
+ /**
346
+ * Contribute table-level constraints (indexes, uniques, checks) to the entity's
347
+ * main table or `<entity>_translations` table. Runs INSIDE the `pgTable` builder
348
+ * callback once columns are resolved. Returns an empty array when the behavior
349
+ * does not contribute to the requested `target`.
350
+ *
351
+ * Constraint names must be globally unique within the table; collisions throw.
352
+ */
353
+ constraints?: (table: Record<string, PgColumn>, target: SchemaTarget, info: BehaviorSchemaInfo) => SchemaFragment[];
354
+ }
355
+ /**
356
+ * Subset of `Entity` passed to behavior `columns` / `constraints` callbacks.
357
+ * Structurally typed so `behaviors/types.ts` does not need to import the full
358
+ * `Entity` type from `../define-entity.js` (which would create the well-known
359
+ * types-↔-define-entity dance inside the package).
360
+ */
361
+ interface BehaviorSchemaInfo {
362
+ readonly entityName: string;
363
+ readonly allFields: Readonly<Record<string, FieldConfig>>;
301
364
  }
302
365
  //#endregion
303
366
  //#region src/cursor.d.ts
@@ -1 +1 @@
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":";;;;;;;;;;AAiBA;;;;;;;;;;;UAAiB,cAAA;EACf,GAAA,CAAI,GAAA;EACJ,GAAA,CAAI,GAAA,UAAa,KAAA;EAYjB;;;;;;;AC1BF;;;EDyBE,YAAA,CAAa,GAAA,UAAa,OAAA,QAAe,OAAA,WAAkB,OAAA;EAC3D,UAAA,CAAW,MAAA;AAAA;;;;;;;UC1BI,eAAA;EACf,QAAA;EACA,OAAA;EACA,YAAA;EACA,OAAA;EACA,MAAA;EDQI;;;;;;;;;;;;;;;;ECSJ,QAAA;EACA,MAAA;IACE,IAAA;IACA,IAAA;EAAA;AAAA;AAAA,UAIa,OAAA,SAAgB,eAAA;EAC/B,IAAA;AAAA;AAAA,UAGe,SAAA,SAAkB,eAAA;EACjC,IAAA;EACA,SAAA;EACA,SAAA;EACA,OAAA,GAAU,MAAA;AAAA;AAAA,UAGK,WAAA,SAAoB,eAAA;EACnC,IAAA;EACA,GAAA;EACA,GAAA;EACA,OAAA;AAAA;AAAA,UAGe,YAAA,SAAqB,eAAA;EACpC,IAAA;AAAA;AAAA,UAGe,SAAA,SAAkB,eAAA;EACjC,IAAA;EACA,OAAA,GAAU,IAAA;EACV,OAAA,GAAU,IAAA;AAAA;AAAA,UAGK,WAAA,SAAoB,eAAA;EACnC,IAAA;EACA,OAAA;AAAA;AAAA,UAGe,cAAA,SAAuB,eAAA;EACtC,IAAA;EACA,MAAA;EACA,WAAA;EACA,QAAA;AAAA;AAAA,UAGe,UAAA,SAAmB,eAAA;EAClC,IAAA;EACA,MAAA;EACA,OAAA;AAAA;AAAA,UAGe,aAAA,SAAsB,eAAA;EACrC,IAAA;EACA,MAAA;AAAA;AAAA,UAGe,SAAA,SAAkB,eAAA;EACjC,IAAA;EACA,IAAA;EACA,MAAA;AAAA;;;;;UAOe,kBAAA;EACf,IAAA;EACA,MAAA,EAAQ,MAAA,SAAe,WAAA;AAAA;;;;AAnCzB;;;;;UA8CiB,SAAA,SAAkB,eAAA;EACjC,IAAA;AAAA;AAAA,UAGe,WAAA,SAAoB,eAAA;EACnC,IAAA;EACA,MAAA,WAAiB,kBAAA;EACjB,GAAA;EACA,GAAA;EACA,SAAA;AAAA;AAAA,KAGU,WAAA,GACR,OAAA,GACA,SAAA,GACA,WAAA,GACA,YAAA,GACA,SAAA,GACA,WAAA,GACA,cAAA,GACA,UAAA,GACA,aAAA,GACA,SAAA,GACA,SAAA,GACA,WAAA;;;;;;;KClGQ,SAAA,sCAKR,SAAA;EAAA,CACG,GAAA,WAAc,SAAA;AAAA;;;;;KAUT,SAAA,WAAoB,WAAA,IAAe,CAAA,SAAU,OAAA,YAErD,CAAA,SAAU,SAAA,YAER,CAAA,SAAU,WAAA,YAER,CAAA,SAAU,YAAA,aAER,CAAA,SAAU,SAAA,GACR,IAAA,YACA,CAAA,SAAU,WAAA,GACR,CAAA,sBACA,CAAA,SAAU,cAAA,GACR,CAAA,qDAGA,CAAA,SAAU,UAAA,YAER,CAAA,SAAU,aAAA,GACR,MAAA,sBACA,CAAA,SAAU,SAAA,YAER,CAAA,SAAU,SAAA,GACR,SAAA,GACA,CAAA,SAAU,WAAA,GACR,KAAA;EAAQ,MAAA;EAAgB,GAAA;EAAA,CAAc,GAAA;AAAA;;ADzChE;;;;;AAIA;;KC2EY,cAAA,gBAA8B,MAAA,SAAe,WAAA;EAAkB,EAAA;AAAA,kBAC7D,MAAA,IAAU,CAAA,wBAElB,MAAA,CAAO,CAAA,6BACL,CAAA,WACQ,SAAA,CAAU,MAAA,CAAO,CAAA,qBAEnB,MAAA,IAAU,MAAA,CAAO,CAAA,qCAAsC,CAAA,IAAK,SAAA,CACtE,MAAA,CAAO,CAAA;;KASN,mBAAA;;ADrFL;;;;KC4FY,gBAAA,gBAAgC,MAAA,SAAe,WAAA,KAAgB,IAAA,eAE3D,MAAA,IAAU,CAAA,wBAElB,MAAA,CAAO,CAAA,6BACL,CAAA,WACQ,SAAA,CAAU,MAAA,CAAO,CAAA,qBAEnB,MAAA,IAAU,MAAA,CAAO,CAAA,qCAAsC,CAAA,IAAK,SAAA,CACtE,MAAA,CAAO,CAAA,aAGX,mBAAA;;KAQG,eAAA;AAAA,KAMO,gBAAA,gBAAgC,MAAA,SAAe,WAAA,mBAC7C,MAAA,IAAU,CAAA,SAAU,eAAA,WAA0B,CAAA,IAAK,SAAA,CAAU,MAAA,CAAO,CAAA;;;;;;;;;;;;;;UC5IjE,OAAA;EAAA,SACN,IAAA;AAAA;;AFpBX;;;;;;;;;;;;KEoCY,eAAA,IAAmB,GAAA,EAAK,OAAA,EAAS,OAAA;;;AFP7C;;;;;AAIA;;;;;;;;;;;;AAOA;KEkBY,sBAAA,IAA0B,EAAA,eAAiB,eAAA;;;;;;;;;;AFXvD;;;;;AAIA;;;;;;;;;;;;;;;;AAMA;;;;;;;;;AAKA;;;;UEyCiB,eAAA;EACf,IAAA;IAAS,EAAA;IAAY,IAAA;IAAe,KAAA;EAAA;EACpC,WAAA,SAAoB,OAAA,CAAQ,MAAA;EAC5B,WAAA;EACA,eAAA,GAAkB,eAAA;AAAA;AAAA,UAIH,QAAA,WAAmB,MAAA,SAAe,WAAA;EACjD,IAAA;EACA,MAAA,GAAS,CAAA;EACT,KAAA;IACE,YAAA,IACE,IAAA,EAAM,MAAA,mBACN,GAAA,GAAM,eAAA,KACH,OAAA,CAAQ,MAAA;IACb,WAAA,IAAe,MAAA,EAAQ,MAAA,mBAAyB,GAAA,GAAM,eAAA,KAAoB,OAAA;IAC1E,YAAA,IACE,EAAA,UACA,IAAA,EAAM,MAAA,mBACN,GAAA,GAAM,eAAA,KACH,OAAA,CAAQ,MAAA;IACb,WAAA,IAAe,MAAA,EAAQ,MAAA,mBAAyB,GAAA,GAAM,eAAA,KAAoB,OAAA;IAC1E,YAAA,IAAgB,EAAA,UAAY,GAAA,GAAM,eAAA,KAAoB,OAAA;IACtD,WAAA,IAAe,EAAA,UAAY,GAAA,GAAM,eAAA,KAAoB,OAAA;EAAA;AAAA;;;;UC3GxC,WAAA;EJMJ;EIJX,KAAA;EJIyB;EIFzB,KAAA;;EAEA,SAAA;EH1Be;EG4Bf,EAAA;AAAA;;;;;;;UC7Be,iBAAA;ELaA;EKXf,KAAA;;EAEA,KAAA;ELUA;EKRA,aAAA;ELSA;EKPA,IAAA;ELOiB;EKLjB,WAAA;ELgBa;EKdb,MAAA;ELc0B;EKZ1B,YAAA;ELaA;EKXA,aAAA;ELWyB;EKTzB,cAAA,GAAiB,MAAA;IAAiB,KAAA;IAAgB,WAAA;IAAsB,WAAA;EAAA;EJjB1C;EImB9B,WAAA;EJnB8B;EIqB9B,oBAAA;EJnBA;EIqBA,QAAA;EJnBA;EIqBA,UAAA;EJHA;EIKA,aAAA;EJHE;EIKF,SAAA;EJJM;;AAIR;;;EIME,MAAA;EJLI;AAGN;;;;EIQE,YAAA;EJPA;;;;EIYA,iBAAA;AAAA;;;AJjBF;;;;AAAA,UKmBiB,MAAA,mBACG,MAAA,SAAe,WAAA,IAAe,MAAA,SAAe,WAAA;EAE/D,IAAA;EACA,IAAA;EACA,MAAA,EAAQ,MAAA,SAAe,WAAA;EACvB,SAAA,GAAY,QAAA;EACZ,KAAA;EACA,MAAA;IACE,IAAA;IACA,MAAA;IACA,MAAA;IACA,MAAA;EAAA;ELvBc;EK0BhB,KAAA,GAAQ,iBAAA;EACR,SAAA,EAAW,SAAA;AAAA;;;;;;;;UC5CI,eAAA;EACf,IAAA;IAAQ,EAAA;IAAY,MAAA;IAAkB,IAAA;IAAe,KAAA;EAAA;EACrD,OAAA,GAAU,IAAA,UAAc,QAAA,UAAkB,MAAA;EAC1C,KAAA;IAAU,IAAA;IAAc,EAAA;EAAA;AAAA;;;;;;;;;KAWd,eAAA,SACR,eAAA,eAEA,OAAA,CAAQ,eAAA;;;;;;;;APzBZ;;;UQTiB,MAAA;EACf,IAAA,CAAK,GAAA,EAAK,MAAA,mBAAyB,GAAA;EACnC,KAAA,EAAO,GAAA,EAAK,MAAA,mBAAyB,GAAA;AAAA;;;;;;;;;;KCsC3B,cAAA,SAAuB,GAAA,SAAY,MAAA;AAAA,UAE9B,iBAAA,mBACG,MAAA,SAAe,WAAA,IAAe,MAAA,SAAe,WAAA;EAE/D,MAAA,EAAQ,MAAA,CAAO,SAAA;EACf,EAAA,EAAI,kBAAA;EACJ,MAAA,GAAS,MAAA;ERlDqB;EQoD9B,UAAA,GAAa,cAAA;ERpDiB;;;;;EQ0D9B,eAAA,GAAkB,eAAA;ERpClB;;;;;;EQ2CA,cAAA,GAAiB,cAAA;ERpCM;;;;AAIzB;;;;;;;;;;;;AAOA;EQ2CE,eAAA,GAAkB,eAAA;;;;;;;;;;ARpCpB;;;;EQkDE,sBAAA,GAAyB,sBAAA;AAAA;AAAA,UAGV,eAAA;EACf,KAAA,GAAQ,GAAA;EACR,KAAA;EACA,MAAA;EACA,OAAA,GAAU,GAAA,GAAM,GAAA;EAChB,MAAA;ERtDgD;;EQyDhD,aAAA;ERvDA;;;;;;AAIF;EQ2DE,MAAA,GAAS,WAAA;;;;;;EAMT,eAAA;AAAA;AAAA,UAGe,YAAA;EACf,KAAA,GAAQ,GAAA;AAAA;;;;;;;;;ARzDV;;;;;;;;;;AAMA;;;cQ2Ea,WAAA,mBACO,MAAA,SAAe,WAAA,IAAe,MAAA,SAAe,WAAA;EAAA,QAEvD,MAAA;EAAA,QACA,EAAA;EAAA,QACA,MAAA;ER9EF;EAAA,QQgFE,YAAA;ER7EO;EAAA,QQ+EP,YAAA;;UAEA,oBAAA;ERjFyB;EAAA,QQmFzB,kBAAA;EAAA,QAEA,KAAA;EAAA,QACA,UAAA;EAAA,QACA,eAAA;EAAA,QACA,cAAA;EAAA,QACA,eAAA;EAAA,QACA,sBAAA;;cAGI,GAAA,CAAA;ERlFZ;;;;;;AAYF;;;;;AAIA;;;EAhBE,QQoGQ,MAAA;ERpF2B;;;;;;;;;AAQrC;;;;;;EARqC,QQ4G3B,gBAAA;ER/FN;;;;;;;;;;;;;;EAAA,QQyHM,qBAAA;cASI,MAAA,EAAQ,iBAAA,CAAkB,SAAA;ERhIpC;;;;;;;EAAA,QQmLM,oBAAA;;;;APhRV;UO8RU,kBAAA;;;;;;;;AP9QV;;;;;;;;;;;;;;;;;;;;EOkTQ,MAAA,CACJ,IAAA,EAAM,gBAAA,CAAiB,SAAA,GACvB,OAAA;IAAY,EAAA,GAAK,kBAAA;EAAA,IAChB,OAAA,CAAQ,cAAA,CAAe,SAAA;EPnSV;;;;;;;EOkYV,QAAA,CACJ,EAAA,UACA,OAAA;IAAY,MAAA;IAAiB,aAAA;IAAwB,eAAA;EAAA,IACpD,OAAA,CAAQ,cAAA,CAAe,SAAA;EP9XG;;;EOqavB,QAAA,CAAS,OAAA,GAAU,eAAA,GAAkB,OAAA,CAAQ,cAAA,CAAe,SAAA;EP9bX;;;EOihBjD,KAAA,CAAM,OAAA,GAAU,YAAA,GAAe,OAAA;EP7gBvB;;;;;;;;;;;EOmjBR,MAAA,CACJ,EAAA,UACA,IAAA,EAAM,gBAAA,CAAiB,SAAA,GACvB,OAAA;IAAY,MAAA;IAAiB,EAAA,GAAK,kBAAA;EAAA,IACjC,OAAA,CAAQ,cAAA,CAAe,SAAA;EPziBA;;;;;;;;;;;;;;;AA6C5B;;EOmhBQ,cAAA,CACJ,EAAA,UACA,IAAA,EAAM,MAAA,mBACN,OAAA;IAAY,MAAA;IAAiB,EAAA,GAAK,kBAAA;EAAA,IACjC,OAAA,CAAQ,cAAA,CAAe,SAAA;EAAA,QAIZ,UAAA;EPxhBV;;;;;;;;;;;;;;;;;EAAA,QOyqBU,gBAAA;EP5qB2D;;;;;;;;;;;;;;EOktBnE,MAAA,CAAO,EAAA,UAAY,OAAA;IAAY,EAAA,GAAK,kBAAA;EAAA,IAAuB,OAAA;EP1sBxD;;;AAEV;;;;;AAcD;;;;;;;EO4wBQ,UAAA,CAAW,KAAA,EAAO,GAAA,EAAK,OAAA;IAAY,EAAA,GAAK,kBAAA;EAAA,IAAuB,OAAA;EPtwB3C;EAAA,wBOw0BF,iBAAA;EPx0BR;;;;;;;;;;;;;;;;EAAA,QO01BF,2BAAA;EP91BA;;;;;;;EAAA,QO4/BA,cAAA;EPt/BX;;;;;;;;;;;AAKJ;;;;;AAaD;;;;;;;;;;;;;;;;;;EO2iCQ,UAAA,CACJ,KAAA,EAAO,GAAA,EACP,IAAA,EAAM,OAAA,CAAQ,gBAAA,CAAiB,SAAA,IAC/B,OAAA;IACE,WAAA,GAAc,MAAA,SAAe,GAAA;IAC7B,aAAA;IACA,EAAA,GAAK,kBAAA;EAAA,IAEN,OAAA;EPljCsE;;;;;;;AC5I3E;;;;;AAiBA;;;;;;;;;AAsBA;;;;;EM6vCQ,SAAA,iBAA0B,MAAA,oBAA0B,MAAA,kBAAA,CAAyB,OAAA;INhtCrD,iGMktC5B,MAAA,EAAQ,MAAA,SAAe,GAAA,GAAM,UAAA,QAAkB,EAAA,INhtCrB;IMktC1B,OAAA,GAAU,GAAA,INhtCM;IMktChB,KAAA,GAAQ,GAAA,ENltCuB;IMotC/B,OAAA,GAAU,GAAA,GAAM,GAAA,INvtCT;IMytCP,KAAA;EAAA,IACE,OAAA,CAAQ,OAAA;ENztCZ;;;;;;;;AAMF;;;;;;;;;EM+vCE,QAAA,CAAA,GAAY,kBAAA;ENvvCa;;;;;;;;EMmwCzB,KAAA,CAAA,GAAS,kBAAA;EN7vCmE;;;EAAA,QMowCpE,oBAAA;ENlwC+C;;;;EAAA,QMuxC/C,oBAAA;ENvyCyC;;;;;;;;;;;;;EMk0C3C,eAAA,CACJ,QAAA,UACA,MAAA,UACA,YAAA,EAAc,MAAA,mBACd,OAAA;IAAY,EAAA,GAAK,kBAAA;EAAA,IAChB,OAAA;EN/zC+C;;;;;;;;;EMm3C5C,iBAAA,CACJ,QAAA,UACA,MAAA,WACA,OAAA;IAAY,EAAA,GAAK,kBAAA;EAAA,IAChB,OAAA;ENj3Cc;;;;;;;;;;;;;EMu5CX,qBAAA,CACJ,QAAA,UACA,MAAA,UACA,IAAA,EAAM,MAAA,mBACN,OAAA;IAAY,EAAA,GAAK,kBAAA;EAAA,IAChB,OAAA;;;;ALrgDL;;;;;EKylDQ,mBAAA,CACJ,QAAA,UACA,MAAA,UACA,IAAA,EAAM,MAAA,mBACN,OAAA;IAAY,EAAA,GAAK,kBAAA;EAAA,IAChB,OAAA;ELtlDD;;;;;AC7BJ;;;;ED6BI,QK0mDY,UAAA;EJnoDd;;;;;;;;;;;;EAAA,QIwsDc,QAAA;EJtrDd;;;;;;;;;;;;;EAAA,QIsvDQ,oBAAA;AAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/count-cache.ts","../../src/fields/base.ts","../../src/types/infer.ts","../../src/behaviors/schema-fragment.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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"}
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _$drizzle_orm0 from "drizzle-orm";
2
2
  import { SQL } from "drizzle-orm";
3
3
  import * as _$drizzle_orm_pg_core0 from "drizzle-orm/pg-core";
4
- import { PgTable } from "drizzle-orm/pg-core";
4
+ import { PgColumn, PgColumnBuilderBase, PgTable } from "drizzle-orm/pg-core";
5
5
  import { PostgresJsDatabase } from "drizzle-orm/postgres-js";
6
6
 
7
7
  //#region src/admin-config.d.ts
@@ -259,6 +259,35 @@ type InferEntity<E> = E extends {
259
259
  allFields: infer F extends Record<string, FieldConfig>;
260
260
  } ? InferEntityDTO<F> : never;
261
261
  //#endregion
262
+ //#region src/behaviors/schema-fragment.d.ts
263
+ /** Which table a behavior fragment targets. */
264
+ type SchemaTarget = 'main' | 'translations';
265
+ /**
266
+ * A constraint contributed by a behavior. The union is intentionally
267
+ * closed — there is NO `kind: 'raw'` escape hatch. If a future behavior
268
+ * needs a new constraint shape, add a typed variant to this union rather
269
+ * than reaching for raw SQL.
270
+ */
271
+ type SchemaFragment = {
272
+ kind: 'index';
273
+ name: string;
274
+ on: PgColumn[]; /** Defaults to btree. Pass `'gin'`/`'gist'` for FTS / vector indexes. */
275
+ using?: 'btree' | 'gin' | 'gist' | 'hash' | 'brin';
276
+ } | {
277
+ kind: 'uniqueConstraint';
278
+ /**
279
+ * Required even though Drizzle's `unique()` accepts an unnamed
280
+ * constraint — the schema generator uses `name` as the
281
+ * collision-detection key across behaviors.
282
+ */
283
+ name: string;
284
+ on: PgColumn[];
285
+ } | {
286
+ kind: 'checkConstraint';
287
+ name: string;
288
+ expression: SQL;
289
+ };
290
+ //#endregion
262
291
  //#region src/behaviors/types.d.ts
263
292
  /**
264
293
  * Structural shape of a queue `JobDefinition` as seen by behaviors.
@@ -373,6 +402,40 @@ interface Behavior<F extends Record<string, FieldConfig> = {}> {
373
402
  beforeDelete?: (id: string, ctx?: BehaviorContext) => Promise<void>;
374
403
  afterDelete?: (id: string, ctx?: BehaviorContext) => Promise<void>;
375
404
  };
405
+ /**
406
+ * Contribute extra columns to the entity's main table or `<entity>_translations` table.
407
+ * Runs BEFORE the Drizzle `pgTable()` call so contributions (including GENERATED
408
+ * columns) participate in the column map. Returns an empty object when the behavior
409
+ * does not contribute to the requested `target`.
410
+ *
411
+ * `info.allFields` is the post-behaviors-merge field map (i.e. user fields plus
412
+ * any fields contributed by earlier behaviors). Behaviors like `searchable()`
413
+ * use it to decide whether to put the column on `'main'` or `'translations'`
414
+ * based on each referenced field's `translatable` flag.
415
+ *
416
+ * Collisions with entity fields or other behaviors' contributions throw at
417
+ * schema-build time — see `schema-generator.ts:collectBehaviorContributions`.
418
+ */
419
+ columns?: (target: SchemaTarget, info: BehaviorSchemaInfo) => Record<string, PgColumnBuilderBase>;
420
+ /**
421
+ * Contribute table-level constraints (indexes, uniques, checks) to the entity's
422
+ * main table or `<entity>_translations` table. Runs INSIDE the `pgTable` builder
423
+ * callback once columns are resolved. Returns an empty array when the behavior
424
+ * does not contribute to the requested `target`.
425
+ *
426
+ * Constraint names must be globally unique within the table; collisions throw.
427
+ */
428
+ constraints?: (table: Record<string, PgColumn>, target: SchemaTarget, info: BehaviorSchemaInfo) => SchemaFragment[];
429
+ }
430
+ /**
431
+ * Subset of `Entity` passed to behavior `columns` / `constraints` callbacks.
432
+ * Structurally typed so `behaviors/types.ts` does not need to import the full
433
+ * `Entity` type from `../define-entity.js` (which would create the well-known
434
+ * types-↔-define-entity dance inside the package).
435
+ */
436
+ interface BehaviorSchemaInfo {
437
+ readonly entityName: string;
438
+ readonly allFields: Readonly<Record<string, FieldConfig>>;
376
439
  }
377
440
  //#endregion
378
441
  //#region src/behaviors/auditable.d.ts
@@ -396,6 +459,227 @@ declare function publishable(): Behavior<PublishableFields>;
396
459
  //#region src/behaviors/revisionable.d.ts
397
460
  declare function revisionable(): Behavior<RevisionableFields>;
398
461
  //#endregion
462
+ //#region src/define-entity.d.ts
463
+ /**
464
+ * Entity definition input (without behaviors — behaviors are typed separately
465
+ * on the `defineEntity` function to enable tuple inference).
466
+ *
467
+ * @typeParam F - The literal field map. Inferred automatically from the call site.
468
+ */
469
+ interface EntityDefinition<F extends Record<string, FieldConfig> = Record<string, FieldConfig>> {
470
+ name: string;
471
+ kind?: 'collection' | 'singleton';
472
+ fields: F;
473
+ scope?: 'global' | 'team' | 'user';
474
+ access?: {
475
+ view?: string;
476
+ create?: string;
477
+ update?: string;
478
+ delete?: string;
479
+ };
480
+ /** Admin UI configuration — controls sidebar, list, and form display */
481
+ admin?: EntityAdminConfig;
482
+ }
483
+ /**
484
+ * Full input for defineEntity (fields + behaviors + other config).
485
+ * Behaviors are typed as a tuple `B` for type extraction.
486
+ */
487
+ type EntityInput<F extends Record<string, FieldConfig> = Record<string, FieldConfig>, B extends Behavior[] = Behavior[]> = EntityDefinition<F> & {
488
+ behaviors?: B;
489
+ };
490
+ /**
491
+ * A fully resolved entity with merged behavior fields.
492
+ * @typeParam AllFields - The complete field map (id + behaviors + user fields).
493
+ */
494
+ interface Entity<AllFields extends Record<string, FieldConfig> = Record<string, FieldConfig>> {
495
+ name: string;
496
+ kind?: 'collection' | 'singleton';
497
+ fields: Record<string, FieldConfig>;
498
+ behaviors?: Behavior[];
499
+ scope?: 'global' | 'team' | 'user';
500
+ access?: {
501
+ view?: string;
502
+ create?: string;
503
+ update?: string;
504
+ delete?: string;
505
+ };
506
+ /** Admin UI configuration — controls sidebar, list, and form display */
507
+ admin?: EntityAdminConfig;
508
+ allFields: AllFields;
509
+ }
510
+ /**
511
+ * Extract and intersect behavior field types from a behaviors tuple.
512
+ * Walks the tuple recursively (depth bounded by number of behaviors, max ~5).
513
+ *
514
+ * Inferring `F` via `Behavior<infer F1>` is unreliable for inline hook-only
515
+ * behaviors: when the literal has no `fields` property, TS falls back to the
516
+ * `Behavior` constraint bound (`Record<string, FieldConfig>`) rather than the
517
+ * declared default. That bound would widen every `AllFields[K]` access to
518
+ * `FieldConfig` and break per-field type inference downstream (e.g. reference
519
+ * cardinality, select option literals). Instead, derive the field map from
520
+ * the behavior's `fields` property directly — if absent/undefined, contribute
521
+ * nothing (empty object) to the intersection.
522
+ */
523
+ type BehaviorFieldsOf<B> = B extends {
524
+ fields?: infer F;
525
+ } ? F extends Record<string, FieldConfig> ? F : {} : {};
526
+ type ExtractBehaviorFields<B extends Behavior[]> = B extends [infer B1, ...infer Rest extends Behavior[]] ? BehaviorFieldsOf<B1> & ExtractBehaviorFields<Rest> : {};
527
+ /**
528
+ * Define an entity with full type inference.
529
+ *
530
+ * @example
531
+ * const Article = defineEntity({
532
+ * name: 'article',
533
+ * fields: {
534
+ * title: field.text({ required: true }),
535
+ * featured: field.boolean(),
536
+ * },
537
+ * behaviors: [publishable(), auditable()],
538
+ * })
539
+ *
540
+ * type ArticleDTO = InferEntity<typeof Article>
541
+ * // { id: string; title: string; featured?: boolean | null; status?: ...; createdAt?: ...; }
542
+ */
543
+ declare function defineEntity<F extends Record<string, FieldConfig>, const B extends Behavior[] = []>(definition: EntityDefinition<F> & {
544
+ behaviors?: B;
545
+ }): Entity<{
546
+ id: IdField;
547
+ } & ExtractBehaviorFields<B> & F>;
548
+ //#endregion
549
+ //#region src/behaviors/searchable.d.ts
550
+ /**
551
+ * Locally-defined result-row shape. Structurally compatible with
552
+ * `@murumets-ee/search`'s `SearchResultRow` — see file-level note.
553
+ */
554
+ interface SearchableResultRow {
555
+ /** Stable id used by the consumer to navigate / select the row. */
556
+ id: string;
557
+ /** Headline / title rendered in the result list. */
558
+ label: string;
559
+ /** Optional secondary text. */
560
+ description?: string;
561
+ /** Optional URL the consumer can link to. */
562
+ url?: string;
563
+ /** Provider-specific extras (consumer-typed). */
564
+ data?: Record<string, unknown>;
565
+ }
566
+ /** Full-text search configuration. */
567
+ interface SearchableFts {
568
+ /**
569
+ * Subset of the entity's `fields` that participate in FTS. Order
570
+ * determines `setweight()` (first field → 'A', second → 'B', …).
571
+ */
572
+ readonly fields: readonly string[];
573
+ /**
574
+ * Postgres text-search configuration name. Defaults to `'simple'`
575
+ * (no stemming/stopwords). v1 only wires `'simple'`; locale-specific
576
+ * dictionaries are a future iteration.
577
+ */
578
+ readonly language?: string;
579
+ }
580
+ /**
581
+ * Cross-entity OR-search target. Allows the parent's `searchable()` to
582
+ * reach into related-entity tsvectors at query time (UNION ALL + GROUP
583
+ * BY shape) without denormalizing into the parent table.
584
+ *
585
+ * Requires the included entity to ALSO have a `searchable({ fts: ... })`
586
+ * declaration — its tsvector is what the parent's provider unions
587
+ * against.
588
+ */
589
+ interface SearchableInclude {
590
+ /** Name of the included entity (must have its own `searchable()`). */
591
+ readonly entity: string;
592
+ /**
593
+ * Foreign-key **field name** on the included entity that points back
594
+ * to the parent's `id`. Use the JS field name (`ticketId`), not the
595
+ * database column name (`ticket_id`) — `getTable()` returns
596
+ * Drizzle's typed accessor where keys match field names.
597
+ */
598
+ readonly fk: string;
599
+ }
600
+ /** The metadata a `searchable()` declaration attaches to its `Behavior`. */
601
+ interface SearchableConfig {
602
+ /**
603
+ * Fields searched in ILIKE mode AND used to construct the tsvector
604
+ * expression (when `fts` is set). Field names must exist on the entity.
605
+ */
606
+ readonly fields: readonly string[];
607
+ /** Optional FTS configuration. When set, the entity gains a tsvector + GIN. */
608
+ readonly fts?: SearchableFts;
609
+ /** Optional cross-entity includes for JOIN-mode search (commit #5). */
610
+ readonly includes?: readonly SearchableInclude[];
611
+ /**
612
+ * Filters applied to every search call unless the caller overrides
613
+ * them. The standard use case is bounding to active rows (e.g.
614
+ * `{ status: ['open', 'pending'] }` to exclude `closed`/`archived`).
615
+ */
616
+ readonly defaultFilters?: Readonly<Record<string, readonly string[]>>;
617
+ /**
618
+ * Project an entity row into a `SearchableResultRow`. Per D14 the
619
+ * provider does not synthesize a default — every entity declares its
620
+ * own projection so consumer-visible result shape is explicit.
621
+ */
622
+ readonly projection: (row: Record<string, unknown>) => SearchableResultRow;
623
+ }
624
+ /** Public options shape accepted by the `searchable()` factory. */
625
+ type SearchableOptions = SearchableConfig;
626
+ /**
627
+ * A {@link Behavior} returned by `searchable()`. Adds a typed `config`
628
+ * property so downstream consumers can read the metadata without
629
+ * casting to `any`.
630
+ */
631
+ interface SearchableBehavior extends Behavior {
632
+ readonly name: 'searchable';
633
+ readonly config: SearchableConfig;
634
+ }
635
+ /**
636
+ * Declare that an entity participates in admin/inbox search.
637
+ *
638
+ * ```ts
639
+ * defineEntity({
640
+ * name: 'ticket',
641
+ * behaviors: [
642
+ * auditable(),
643
+ * searchable({
644
+ * fields: ['subject', 'requesterEmail', 'requesterName'],
645
+ * fts: { fields: ['subject'], language: 'simple' },
646
+ * includes: [{ entity: 'ticket_message', fk: 'ticketId' }],
647
+ * defaultFilters: { status: ['open', 'pending', 'on_hold'] },
648
+ * projection: (row) => ({
649
+ * id: row.id as string,
650
+ * label: row.subject as string,
651
+ * description: row.requesterEmail as string,
652
+ * }),
653
+ * }),
654
+ * ],
655
+ * })
656
+ * ```
657
+ *
658
+ * Adding a field to `fts.fields` on an entity that already shipped FTS
659
+ * requires a manual two-step migration (drop the generated tsvector
660
+ * column, then re-run `pnpm db:migrate`) — Postgres does not allow
661
+ * `ALTER COLUMN` for GENERATED expressions, and drizzle-kit silently
662
+ * ignores the change. v1 is greenfield so this is documented for
663
+ * post-launch operators, not a blocker now.
664
+ */
665
+ declare function searchable(options: SearchableOptions): SearchableBehavior;
666
+ /**
667
+ * Runtime type predicate — narrows a `Behavior` to {@link SearchableBehavior}.
668
+ * Guards against accidental matches where another behavior happens to
669
+ * also be named `'searchable'` (defense in depth — shouldn't happen in
670
+ * practice).
671
+ */
672
+ declare function isSearchableBehavior(b: Behavior): b is SearchableBehavior;
673
+ /**
674
+ * Read the `searchable()` config from an entity. Returns `undefined`
675
+ * when the entity does not declare `searchable()`.
676
+ *
677
+ * Used by the admin search bootstrap (commit #6) to build a provider
678
+ * per searchable entity, and by the EntityList toolbar to know whether
679
+ * to enable the search input.
680
+ */
681
+ declare function getSearchableConfig(entity: Entity): SearchableConfig | undefined;
682
+ //#endregion
399
683
  //#region src/behaviors/sluggable.d.ts
400
684
  interface SluggableOptions {
401
685
  /** Make the slug translatable — each locale gets its own slug. Default: false */
@@ -499,6 +783,7 @@ declare const behavior: {
499
783
  revisionable: typeof revisionable;
500
784
  hierarchical: typeof hierarchical;
501
785
  timestamped: typeof timestamped;
786
+ searchable: typeof searchable;
502
787
  };
503
788
  //#endregion
504
789
  //#region src/count-cache.d.ts
@@ -639,93 +924,6 @@ declare function decodeCursor(encoded: string): DecodedCursor | null;
639
924
  */
640
925
  declare function buildCursorCondition(table: PgTable, cursor: DecodedCursor): SQL | null;
641
926
  //#endregion
642
- //#region src/define-entity.d.ts
643
- /**
644
- * Entity definition input (without behaviors — behaviors are typed separately
645
- * on the `defineEntity` function to enable tuple inference).
646
- *
647
- * @typeParam F - The literal field map. Inferred automatically from the call site.
648
- */
649
- interface EntityDefinition<F extends Record<string, FieldConfig> = Record<string, FieldConfig>> {
650
- name: string;
651
- kind?: 'collection' | 'singleton';
652
- fields: F;
653
- scope?: 'global' | 'team' | 'user';
654
- access?: {
655
- view?: string;
656
- create?: string;
657
- update?: string;
658
- delete?: string;
659
- };
660
- /** Admin UI configuration — controls sidebar, list, and form display */
661
- admin?: EntityAdminConfig;
662
- }
663
- /**
664
- * Full input for defineEntity (fields + behaviors + other config).
665
- * Behaviors are typed as a tuple `B` for type extraction.
666
- */
667
- type EntityInput<F extends Record<string, FieldConfig> = Record<string, FieldConfig>, B extends Behavior[] = Behavior[]> = EntityDefinition<F> & {
668
- behaviors?: B;
669
- };
670
- /**
671
- * A fully resolved entity with merged behavior fields.
672
- * @typeParam AllFields - The complete field map (id + behaviors + user fields).
673
- */
674
- interface Entity<AllFields extends Record<string, FieldConfig> = Record<string, FieldConfig>> {
675
- name: string;
676
- kind?: 'collection' | 'singleton';
677
- fields: Record<string, FieldConfig>;
678
- behaviors?: Behavior[];
679
- scope?: 'global' | 'team' | 'user';
680
- access?: {
681
- view?: string;
682
- create?: string;
683
- update?: string;
684
- delete?: string;
685
- };
686
- /** Admin UI configuration — controls sidebar, list, and form display */
687
- admin?: EntityAdminConfig;
688
- allFields: AllFields;
689
- }
690
- /**
691
- * Extract and intersect behavior field types from a behaviors tuple.
692
- * Walks the tuple recursively (depth bounded by number of behaviors, max ~5).
693
- *
694
- * Inferring `F` via `Behavior<infer F1>` is unreliable for inline hook-only
695
- * behaviors: when the literal has no `fields` property, TS falls back to the
696
- * `Behavior` constraint bound (`Record<string, FieldConfig>`) rather than the
697
- * declared default. That bound would widen every `AllFields[K]` access to
698
- * `FieldConfig` and break per-field type inference downstream (e.g. reference
699
- * cardinality, select option literals). Instead, derive the field map from
700
- * the behavior's `fields` property directly — if absent/undefined, contribute
701
- * nothing (empty object) to the intersection.
702
- */
703
- type BehaviorFieldsOf<B> = B extends {
704
- fields?: infer F;
705
- } ? F extends Record<string, FieldConfig> ? F : {} : {};
706
- type ExtractBehaviorFields<B extends Behavior[]> = B extends [infer B1, ...infer Rest extends Behavior[]] ? BehaviorFieldsOf<B1> & ExtractBehaviorFields<Rest> : {};
707
- /**
708
- * Define an entity with full type inference.
709
- *
710
- * @example
711
- * const Article = defineEntity({
712
- * name: 'article',
713
- * fields: {
714
- * title: field.text({ required: true }),
715
- * featured: field.boolean(),
716
- * },
717
- * behaviors: [publishable(), auditable()],
718
- * })
719
- *
720
- * type ArticleDTO = InferEntity<typeof Article>
721
- * // { id: string; title: string; featured?: boolean | null; status?: ...; createdAt?: ...; }
722
- */
723
- declare function defineEntity<F extends Record<string, FieldConfig>, const B extends Behavior[] = []>(definition: EntityDefinition<F> & {
724
- behaviors?: B;
725
- }): Entity<{
726
- id: IdField;
727
- } & ExtractBehaviorFields<B> & F>;
728
- //#endregion
729
927
  //#region src/refs/find-usages.d.ts
730
928
  interface EntityUsage {
731
929
  sourceEntity: string;
@@ -750,7 +948,7 @@ declare function generateSchema(entity: Entity): _$drizzle_orm_pg_core0.PgTableW
750
948
  name: string;
751
949
  schema: undefined;
752
950
  columns: {
753
- [x: string]: _$drizzle_orm_pg_core0.PgColumn<{
951
+ [x: string]: PgColumn<{
754
952
  name: string;
755
953
  tableName: string;
756
954
  dataType: _$drizzle_orm0.ColumnDataType;
@@ -783,7 +981,7 @@ declare function generateTranslationSchema(entity: Entity, parent?: PgTable): _$
783
981
  name: string;
784
982
  schema: undefined;
785
983
  columns: {
786
- [x: string]: _$drizzle_orm_pg_core0.PgColumn<{
984
+ [x: string]: PgColumn<{
787
985
  name: string;
788
986
  tableName: string;
789
987
  dataType: _$drizzle_orm0.ColumnDataType;
@@ -821,7 +1019,7 @@ declare function generateLayoutSchema(entity: Entity, parent?: PgTable): _$drizz
821
1019
  name: string;
822
1020
  schema: undefined;
823
1021
  columns: {
824
- id: _$drizzle_orm_pg_core0.PgColumn<{
1022
+ id: PgColumn<{
825
1023
  name: "id";
826
1024
  tableName: string;
827
1025
  dataType: "string";
@@ -838,7 +1036,7 @@ declare function generateLayoutSchema(entity: Entity, parent?: PgTable): _$drizz
838
1036
  identity: undefined;
839
1037
  generated: undefined;
840
1038
  }, {}, {}>;
841
- entityId: _$drizzle_orm_pg_core0.PgColumn<{
1039
+ entityId: PgColumn<{
842
1040
  name: "entity_id";
843
1041
  tableName: string;
844
1042
  dataType: "string";
@@ -855,7 +1053,7 @@ declare function generateLayoutSchema(entity: Entity, parent?: PgTable): _$drizz
855
1053
  identity: undefined;
856
1054
  generated: undefined;
857
1055
  }, {}, {}>;
858
- fieldName: _$drizzle_orm_pg_core0.PgColumn<{
1056
+ fieldName: PgColumn<{
859
1057
  name: "field_name";
860
1058
  tableName: string;
861
1059
  dataType: "string";
@@ -874,7 +1072,7 @@ declare function generateLayoutSchema(entity: Entity, parent?: PgTable): _$drizz
874
1072
  }, {}, {
875
1073
  length: 100;
876
1074
  }>;
877
- blockType: _$drizzle_orm_pg_core0.PgColumn<{
1075
+ blockType: PgColumn<{
878
1076
  name: "block_type";
879
1077
  tableName: string;
880
1078
  dataType: "string";
@@ -893,7 +1091,7 @@ declare function generateLayoutSchema(entity: Entity, parent?: PgTable): _$drizz
893
1091
  }, {}, {
894
1092
  length: 100;
895
1093
  }>;
896
- sortOrder: _$drizzle_orm_pg_core0.PgColumn<{
1094
+ sortOrder: PgColumn<{
897
1095
  name: "sort_order";
898
1096
  tableName: string;
899
1097
  dataType: "number";
@@ -910,7 +1108,7 @@ declare function generateLayoutSchema(entity: Entity, parent?: PgTable): _$drizz
910
1108
  identity: undefined;
911
1109
  generated: undefined;
912
1110
  }, {}, {}>;
913
- data: _$drizzle_orm_pg_core0.PgColumn<{
1111
+ data: PgColumn<{
914
1112
  name: "data";
915
1113
  tableName: string;
916
1114
  dataType: "json";
@@ -927,7 +1125,7 @@ declare function generateLayoutSchema(entity: Entity, parent?: PgTable): _$drizz
927
1125
  identity: undefined;
928
1126
  generated: undefined;
929
1127
  }, {}, {}>;
930
- locale: _$drizzle_orm_pg_core0.PgColumn<{
1128
+ locale: PgColumn<{
931
1129
  name: "locale";
932
1130
  tableName: string;
933
1131
  dataType: "string";
@@ -986,7 +1184,7 @@ declare function generateLayoutTranslationSchema(entity: Entity, layoutParent?:
986
1184
  name: string;
987
1185
  schema: undefined;
988
1186
  columns: {
989
- id: _$drizzle_orm_pg_core0.PgColumn<{
1187
+ id: PgColumn<{
990
1188
  name: "id";
991
1189
  tableName: string;
992
1190
  dataType: "string";
@@ -1003,7 +1201,7 @@ declare function generateLayoutTranslationSchema(entity: Entity, layoutParent?:
1003
1201
  identity: undefined;
1004
1202
  generated: undefined;
1005
1203
  }, {}, {}>;
1006
- layoutId: _$drizzle_orm_pg_core0.PgColumn<{
1204
+ layoutId: PgColumn<{
1007
1205
  name: "layout_id";
1008
1206
  tableName: string;
1009
1207
  dataType: "string";
@@ -1020,7 +1218,7 @@ declare function generateLayoutTranslationSchema(entity: Entity, layoutParent?:
1020
1218
  identity: undefined;
1021
1219
  generated: undefined;
1022
1220
  }, {}, {}>;
1023
- locale: _$drizzle_orm_pg_core0.PgColumn<{
1221
+ locale: PgColumn<{
1024
1222
  name: "locale";
1025
1223
  tableName: string;
1026
1224
  dataType: "string";
@@ -1039,7 +1237,7 @@ declare function generateLayoutTranslationSchema(entity: Entity, layoutParent?:
1039
1237
  }, {}, {
1040
1238
  length: 10;
1041
1239
  }>;
1042
- fields: _$drizzle_orm_pg_core0.PgColumn<{
1240
+ fields: PgColumn<{
1043
1241
  name: "fields";
1044
1242
  tableName: string;
1045
1243
  dataType: "json";
@@ -1111,5 +1309,5 @@ declare class ForbiddenError extends Error {
1111
1309
  constructor(message: string);
1112
1310
  }
1113
1311
  //#endregion
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 };
1312
+ export { type AuditableFields, type Behavior, type BehaviorContext, type BehaviorSchemaInfo, 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 SchemaFragment, type SchemaTarget, type SearchableBehavior, type SearchableConfig, type SearchableFts, type SearchableInclude, type SearchableOptions, type SearchableResultRow, type SecurityContext, type SelectField, type SlugField, type TextField, auditable, behavior, buildCursorCondition, buildEntitySchemaMap, decodeCursor, defineEntity, encodeCursor, estimateRowCount, field, generateLayoutSchema, generateLayoutTranslationSchema, generateSchema, generateTranslationSchema, getSearchableConfig, hasBehavior, hasBlocksFields, hasTranslatableBlocks, hierarchical, isPublishable, isSearchableBehavior, isVersionable, needsLocaleStatus, publishable, revisionable, searchable, sluggable, slugify, timestamped };
1115
1313
  //# sourceMappingURL=index.d.mts.map