@murumets-ee/entity 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -232,16 +232,29 @@ type InferEntity<E> = E extends {
232
232
  } ? InferEntityDTO<F> : never;
233
233
  //#endregion
234
234
  //#region src/behaviors/types.d.ts
235
+ /**
236
+ * Context passed to behavior hooks. Resolved once per request by AdminClient
237
+ * from its `contextResolver` and forwarded into every hook so behaviors never
238
+ * have to reach into AsyncLocalStorage themselves — that pattern breaks under
239
+ * bundlers (e.g. Turbopack) that duplicate module instances across boundaries.
240
+ */
241
+ interface BehaviorContext {
242
+ user?: {
243
+ id: string;
244
+ name?: string;
245
+ email?: string;
246
+ };
247
+ }
235
248
  interface Behavior<F extends Record<string, FieldConfig> = {}> {
236
249
  name: string;
237
250
  fields?: F;
238
251
  hooks?: {
239
- beforeCreate?: (data: Record<string, unknown>) => Promise<Record<string, unknown>>;
240
- afterCreate?: (entity: Record<string, unknown>) => Promise<void>;
241
- beforeUpdate?: (id: string, data: Record<string, unknown>) => Promise<Record<string, unknown>>;
242
- afterUpdate?: (entity: Record<string, unknown>) => Promise<void>;
243
- beforeDelete?: (id: string) => Promise<void>;
244
- afterDelete?: (id: string) => Promise<void>;
252
+ beforeCreate?: (data: Record<string, unknown>, ctx?: BehaviorContext) => Promise<Record<string, unknown>>;
253
+ afterCreate?: (entity: Record<string, unknown>, ctx?: BehaviorContext) => Promise<void>;
254
+ beforeUpdate?: (id: string, data: Record<string, unknown>, ctx?: BehaviorContext) => Promise<Record<string, unknown>>;
255
+ afterUpdate?: (entity: Record<string, unknown>, ctx?: BehaviorContext) => Promise<void>;
256
+ beforeDelete?: (id: string, ctx?: BehaviorContext) => Promise<void>;
257
+ afterDelete?: (id: string, ctx?: BehaviorContext) => Promise<void>;
245
258
  };
246
259
  }
247
260
  //#endregion
@@ -391,10 +404,22 @@ declare const behavior: {
391
404
  interface CountCacheLike {
392
405
  get(key: string): number | undefined;
393
406
  set(key: string, count: number): void;
407
+ /**
408
+ * Cache-or-compute with single-flight semantics.
409
+ *
410
+ * If the entry is cached and unexpired, returns it immediately (no promise
411
+ * allocation in the hot path). Otherwise, if a refresh is already in flight
412
+ * for the same key, returns that in-flight promise instead of starting a
413
+ * second one — preventing the thundering-herd burst of identical
414
+ * `count(*)` queries when N concurrent requests cross the TTL boundary
415
+ * together.
416
+ */
417
+ getOrCompute(key: string, compute: () => Promise<number>): Promise<number> | number;
394
418
  invalidate(prefix: string): void;
395
419
  }
396
420
  declare class CountCache implements CountCacheLike {
397
421
  private cache;
422
+ private inflight;
398
423
  private ttlMs;
399
424
  constructor(ttlMs?: number);
400
425
  /**
@@ -406,10 +431,23 @@ declare class CountCache implements CountCacheLike {
406
431
  */
407
432
  set(key: string, count: number): void;
408
433
  /**
409
- * Invalidate all cache entries whose key starts with the given prefix.
410
- * Typically called with the entity name after mutations (create/update/delete).
434
+ * Cache-or-compute with single-flight semantics. See `CountCacheLike` doc.
435
+ *
436
+ * Cache hits return synchronously (the call site keeps the await but no
437
+ * actual microtask is scheduled). Cache misses register an in-flight
438
+ * promise so concurrent callers share one DB round-trip; the promise is
439
+ * removed once it resolves (or rejects) so the next miss can refresh.
440
+ * On rejection, nothing is cached — the next caller retries.
411
441
  */
412
- invalidate(prefix: string): void;
442
+ getOrCompute(key: string, compute: () => Promise<number>): Promise<number> | number;
443
+ /**
444
+ * Invalidate all cache entries for a given entity name.
445
+ * Matches the exact entity name OR any key where the entity is followed
446
+ * by one of the cache-key separators (`:` for WHERE, `@` for scope).
447
+ * Avoids accidental cross-entity invalidation (e.g. invalidating 'user'
448
+ * must not clear 'users:where=...' entries).
449
+ */
450
+ invalidate(entityName: string): void;
413
451
  /**
414
452
  * Remove all expired entries. Useful for periodic cleanup in long-running processes.
415
453
  */
@@ -571,40 +609,6 @@ declare function defineEntity<F extends Record<string, FieldConfig>, const B ext
571
609
  id: IdField;
572
610
  } & ExtractBehaviorFields<B> & F>;
573
611
  //#endregion
574
- //#region src/shared/entity-data-ops.d.ts
575
- /**
576
- * Security context resolved per-request. Provided by the consumer
577
- * (e.g., via React.cache() in Next.js, or runAsCli for CLI).
578
- * The entity package has zero knowledge of how this is resolved.
579
- */
580
- interface SecurityContext {
581
- user: {
582
- id: string;
583
- groups: string[];
584
- };
585
- checker: (role: string, resource: string, action: string) => boolean;
586
- scope?: {
587
- type: string;
588
- id: string;
589
- };
590
- }
591
- /**
592
- * Function that resolves the current request's security context.
593
- * Injected at construction time — the entity package never imports
594
- * @murumets-ee/core or any framework-specific code.
595
- *
596
- * Returns undefined only when intentionally skipping enforcement
597
- * (should not happen in production — throw ForbiddenError instead).
598
- */
599
- type ContextResolver = () => SecurityContext | undefined | Promise<SecurityContext | undefined>;
600
- /**
601
- * Thrown when a user lacks permission for an entity operation.
602
- * Consumers (api-handler) catch this and return HTTP 403.
603
- */
604
- declare class ForbiddenError extends Error {
605
- constructor(message: string);
606
- }
607
- //#endregion
608
612
  //#region src/refs/find-usages.d.ts
609
613
  interface EntityUsage {
610
614
  sourceEntity: string;
@@ -841,8 +845,18 @@ declare function needsLocaleStatus(entity: Entity): boolean;
841
845
  * Check if an entity is publishable (has publishable() behavior).
842
846
  */
843
847
  declare function isPublishable(entity: Entity): boolean;
844
- /** Per-locale publish status table for publishable + translatable entities. */
845
- declare function generateLocaleStatusSchema(entity: Entity, parent: PgTable): _$drizzle_orm_pg_core0.PgTableWithColumns<{
848
+ /**
849
+ * Check if an entity has blocks fields with translatable block content (non-localized mode).
850
+ */
851
+ declare function hasTranslatableBlocks(entity: Entity): boolean;
852
+ /**
853
+ * Generate layout translation table for non-localized blocks with translatable fields.
854
+ *
855
+ * `layoutParent` is optional — when provided, emits a `.references()` FK
856
+ * pointing at the corresponding `{entity}_layout` table (for migration
857
+ * generation).
858
+ */
859
+ declare function generateLayoutTranslationSchema(entity: Entity, layoutParent?: PgTable): _$drizzle_orm_pg_core0.PgTableWithColumns<{
846
860
  name: string;
847
861
  schema: undefined;
848
862
  columns: {
@@ -863,8 +877,8 @@ declare function generateLocaleStatusSchema(entity: Entity, parent: PgTable): _$
863
877
  identity: undefined;
864
878
  generated: undefined;
865
879
  }, {}, {}>;
866
- entityId: _$drizzle_orm_pg_core0.PgColumn<{
867
- name: "entity_id";
880
+ layoutId: _$drizzle_orm_pg_core0.PgColumn<{
881
+ name: "layout_id";
868
882
  tableName: string;
869
883
  dataType: "string";
870
884
  columnType: "PgUUID";
@@ -899,625 +913,8 @@ declare function generateLocaleStatusSchema(entity: Entity, parent: PgTable): _$
899
913
  }, {}, {
900
914
  length: 10;
901
915
  }>;
902
- status: _$drizzle_orm_pg_core0.PgColumn<{
903
- name: "status";
904
- tableName: string;
905
- dataType: "string";
906
- columnType: "PgVarchar";
907
- data: string;
908
- driverParam: string;
909
- notNull: true;
910
- hasDefault: true;
911
- isPrimaryKey: false;
912
- isAutoincrement: false;
913
- hasRuntimeDefault: false;
914
- enumValues: [string, ...string[]];
915
- baseColumn: never;
916
- identity: undefined;
917
- generated: undefined;
918
- }, {}, {
919
- length: 20;
920
- }>;
921
- publishedAt: _$drizzle_orm_pg_core0.PgColumn<{
922
- name: "published_at";
923
- tableName: string;
924
- dataType: "date";
925
- columnType: "PgTimestamp";
926
- data: Date;
927
- driverParam: string;
928
- notNull: false;
929
- hasDefault: false;
930
- isPrimaryKey: false;
931
- isAutoincrement: false;
932
- hasRuntimeDefault: false;
933
- enumValues: undefined;
934
- baseColumn: never;
935
- identity: undefined;
936
- generated: undefined;
937
- }, {}, {}>;
938
- };
939
- dialect: "pg";
940
- }>;
941
- /** Drafts overlay table for publishable entities. */
942
- declare function generateDraftsSchema(entity: Entity, parent: PgTable): _$drizzle_orm_pg_core0.PgTableWithColumns<{
943
- name: string;
944
- schema: undefined;
945
- columns: {
946
- id: _$drizzle_orm_pg_core0.PgColumn<{
947
- name: "id";
948
- tableName: string;
949
- dataType: "string";
950
- columnType: "PgUUID";
951
- data: string;
952
- driverParam: string;
953
- notNull: true;
954
- hasDefault: true;
955
- isPrimaryKey: true;
956
- isAutoincrement: false;
957
- hasRuntimeDefault: false;
958
- enumValues: undefined;
959
- baseColumn: never;
960
- identity: undefined;
961
- generated: undefined;
962
- }, {}, {}>;
963
- entityId: _$drizzle_orm_pg_core0.PgColumn<{
964
- name: "entity_id";
965
- tableName: string;
966
- dataType: "string";
967
- columnType: "PgUUID";
968
- data: string;
969
- driverParam: string;
970
- notNull: true;
971
- hasDefault: false;
972
- isPrimaryKey: false;
973
- isAutoincrement: false;
974
- hasRuntimeDefault: false;
975
- enumValues: undefined;
976
- baseColumn: never;
977
- identity: undefined;
978
- generated: undefined;
979
- }, {}, {}>;
980
- locale: _$drizzle_orm_pg_core0.PgColumn<{
981
- name: "locale";
982
- tableName: string;
983
- dataType: "string";
984
- columnType: "PgVarchar";
985
- data: string;
986
- driverParam: string;
987
- notNull: true;
988
- hasDefault: true;
989
- isPrimaryKey: false;
990
- isAutoincrement: false;
991
- hasRuntimeDefault: false;
992
- enumValues: [string, ...string[]];
993
- baseColumn: never;
994
- identity: undefined;
995
- generated: undefined;
996
- }, {}, {
997
- length: 10;
998
- }>;
999
- data: _$drizzle_orm_pg_core0.PgColumn<{
1000
- name: "data";
1001
- tableName: string;
1002
- dataType: "json";
1003
- columnType: "PgJsonb";
1004
- data: unknown;
1005
- driverParam: unknown;
1006
- notNull: true;
1007
- hasDefault: false;
1008
- isPrimaryKey: false;
1009
- isAutoincrement: false;
1010
- hasRuntimeDefault: false;
1011
- enumValues: undefined;
1012
- baseColumn: never;
1013
- identity: undefined;
1014
- generated: undefined;
1015
- }, {}, {}>;
1016
- createdBy: _$drizzle_orm_pg_core0.PgColumn<{
1017
- name: "created_by";
1018
- tableName: string;
1019
- dataType: "string";
1020
- columnType: "PgVarchar";
1021
- data: string;
1022
- driverParam: string;
1023
- notNull: true;
1024
- hasDefault: false;
1025
- isPrimaryKey: false;
1026
- isAutoincrement: false;
1027
- hasRuntimeDefault: false;
1028
- enumValues: [string, ...string[]];
1029
- baseColumn: never;
1030
- identity: undefined;
1031
- generated: undefined;
1032
- }, {}, {
1033
- length: 255;
1034
- }>;
1035
- createdByName: _$drizzle_orm_pg_core0.PgColumn<{
1036
- name: "created_by_name";
1037
- tableName: string;
1038
- dataType: "string";
1039
- columnType: "PgVarchar";
1040
- data: string;
1041
- driverParam: string;
1042
- notNull: false;
1043
- hasDefault: false;
1044
- isPrimaryKey: false;
1045
- isAutoincrement: false;
1046
- hasRuntimeDefault: false;
1047
- enumValues: [string, ...string[]];
1048
- baseColumn: never;
1049
- identity: undefined;
1050
- generated: undefined;
1051
- }, {}, {
1052
- length: 255;
1053
- }>;
1054
- createdAt: _$drizzle_orm_pg_core0.PgColumn<{
1055
- name: "created_at";
1056
- tableName: string;
1057
- dataType: "date";
1058
- columnType: "PgTimestamp";
1059
- data: Date;
1060
- driverParam: string;
1061
- notNull: true;
1062
- hasDefault: true;
1063
- isPrimaryKey: false;
1064
- isAutoincrement: false;
1065
- hasRuntimeDefault: false;
1066
- enumValues: undefined;
1067
- baseColumn: never;
1068
- identity: undefined;
1069
- generated: undefined;
1070
- }, {}, {}>;
1071
- updatedAt: _$drizzle_orm_pg_core0.PgColumn<{
1072
- name: "updated_at";
1073
- tableName: string;
1074
- dataType: "date";
1075
- columnType: "PgTimestamp";
1076
- data: Date;
1077
- driverParam: string;
1078
- notNull: true;
1079
- hasDefault: true;
1080
- isPrimaryKey: false;
1081
- isAutoincrement: false;
1082
- hasRuntimeDefault: false;
1083
- enumValues: undefined;
1084
- baseColumn: never;
1085
- identity: undefined;
1086
- generated: undefined;
1087
- }, {}, {}>;
1088
- };
1089
- dialect: "pg";
1090
- }>;
1091
- /** Versions history table for versionable entities. */
1092
- declare function generateVersionsSchema(entity: Entity, parent: PgTable): _$drizzle_orm_pg_core0.PgTableWithColumns<{
1093
- name: string;
1094
- schema: undefined;
1095
- columns: {
1096
- id: _$drizzle_orm_pg_core0.PgColumn<{
1097
- name: "id";
1098
- tableName: string;
1099
- dataType: "string";
1100
- columnType: "PgUUID";
1101
- data: string;
1102
- driverParam: string;
1103
- notNull: true;
1104
- hasDefault: true;
1105
- isPrimaryKey: true;
1106
- isAutoincrement: false;
1107
- hasRuntimeDefault: false;
1108
- enumValues: undefined;
1109
- baseColumn: never;
1110
- identity: undefined;
1111
- generated: undefined;
1112
- }, {}, {}>;
1113
- entityId: _$drizzle_orm_pg_core0.PgColumn<{
1114
- name: "entity_id";
1115
- tableName: string;
1116
- dataType: "string";
1117
- columnType: "PgUUID";
1118
- data: string;
1119
- driverParam: string;
1120
- notNull: true;
1121
- hasDefault: false;
1122
- isPrimaryKey: false;
1123
- isAutoincrement: false;
1124
- hasRuntimeDefault: false;
1125
- enumValues: undefined;
1126
- baseColumn: never;
1127
- identity: undefined;
1128
- generated: undefined;
1129
- }, {}, {}>;
1130
- version: _$drizzle_orm_pg_core0.PgColumn<{
1131
- name: "version";
1132
- tableName: string;
1133
- dataType: "number";
1134
- columnType: "PgInteger";
1135
- data: number;
1136
- driverParam: string | number;
1137
- notNull: true;
1138
- hasDefault: false;
1139
- isPrimaryKey: false;
1140
- isAutoincrement: false;
1141
- hasRuntimeDefault: false;
1142
- enumValues: undefined;
1143
- baseColumn: never;
1144
- identity: undefined;
1145
- generated: undefined;
1146
- }, {}, {}>;
1147
- locale: _$drizzle_orm_pg_core0.PgColumn<{
1148
- name: "locale";
1149
- tableName: string;
1150
- dataType: "string";
1151
- columnType: "PgVarchar";
1152
- data: string;
1153
- driverParam: string;
1154
- notNull: true;
1155
- hasDefault: true;
1156
- isPrimaryKey: false;
1157
- isAutoincrement: false;
1158
- hasRuntimeDefault: false;
1159
- enumValues: [string, ...string[]];
1160
- baseColumn: never;
1161
- identity: undefined;
1162
- generated: undefined;
1163
- }, {}, {
1164
- length: 10;
1165
- }>;
1166
- data: _$drizzle_orm_pg_core0.PgColumn<{
1167
- name: "data";
1168
- tableName: string;
1169
- dataType: "json";
1170
- columnType: "PgJsonb";
1171
- data: unknown;
1172
- driverParam: unknown;
1173
- notNull: true;
1174
- hasDefault: false;
1175
- isPrimaryKey: false;
1176
- isAutoincrement: false;
1177
- hasRuntimeDefault: false;
1178
- enumValues: undefined;
1179
- baseColumn: never;
1180
- identity: undefined;
1181
- generated: undefined;
1182
- }, {}, {}>;
1183
- delta: _$drizzle_orm_pg_core0.PgColumn<{
1184
- name: "delta";
1185
- tableName: string;
1186
- dataType: "json";
1187
- columnType: "PgJsonb";
1188
- data: unknown;
1189
- driverParam: unknown;
1190
- notNull: false;
1191
- hasDefault: false;
1192
- isPrimaryKey: false;
1193
- isAutoincrement: false;
1194
- hasRuntimeDefault: false;
1195
- enumValues: undefined;
1196
- baseColumn: never;
1197
- identity: undefined;
1198
- generated: undefined;
1199
- }, {}, {}>;
1200
- status: _$drizzle_orm_pg_core0.PgColumn<{
1201
- name: "status";
1202
- tableName: string;
1203
- dataType: "string";
1204
- columnType: "PgVarchar";
1205
- data: string;
1206
- driverParam: string;
1207
- notNull: false;
1208
- hasDefault: false;
1209
- isPrimaryKey: false;
1210
- isAutoincrement: false;
1211
- hasRuntimeDefault: false;
1212
- enumValues: [string, ...string[]];
1213
- baseColumn: never;
1214
- identity: undefined;
1215
- generated: undefined;
1216
- }, {}, {
1217
- length: 20;
1218
- }>;
1219
- createdBy: _$drizzle_orm_pg_core0.PgColumn<{
1220
- name: "created_by";
1221
- tableName: string;
1222
- dataType: "string";
1223
- columnType: "PgVarchar";
1224
- data: string;
1225
- driverParam: string;
1226
- notNull: false;
1227
- hasDefault: false;
1228
- isPrimaryKey: false;
1229
- isAutoincrement: false;
1230
- hasRuntimeDefault: false;
1231
- enumValues: [string, ...string[]];
1232
- baseColumn: never;
1233
- identity: undefined;
1234
- generated: undefined;
1235
- }, {}, {
1236
- length: 255;
1237
- }>;
1238
- createdByName: _$drizzle_orm_pg_core0.PgColumn<{
1239
- name: "created_by_name";
1240
- tableName: string;
1241
- dataType: "string";
1242
- columnType: "PgVarchar";
1243
- data: string;
1244
- driverParam: string;
1245
- notNull: false;
1246
- hasDefault: false;
1247
- isPrimaryKey: false;
1248
- isAutoincrement: false;
1249
- hasRuntimeDefault: false;
1250
- enumValues: [string, ...string[]];
1251
- baseColumn: never;
1252
- identity: undefined;
1253
- generated: undefined;
1254
- }, {}, {
1255
- length: 255;
1256
- }>;
1257
- createdAt: _$drizzle_orm_pg_core0.PgColumn<{
1258
- name: "created_at";
1259
- tableName: string;
1260
- dataType: "date";
1261
- columnType: "PgTimestamp";
1262
- data: Date;
1263
- driverParam: string;
1264
- notNull: true;
1265
- hasDefault: true;
1266
- isPrimaryKey: false;
1267
- isAutoincrement: false;
1268
- hasRuntimeDefault: false;
1269
- enumValues: undefined;
1270
- baseColumn: never;
1271
- identity: undefined;
1272
- generated: undefined;
1273
- }, {}, {}>;
1274
- isAutosave: _$drizzle_orm_pg_core0.PgColumn<{
1275
- name: "is_autosave";
1276
- tableName: string;
1277
- dataType: "boolean";
1278
- columnType: "PgBoolean";
1279
- data: boolean;
1280
- driverParam: boolean;
1281
- notNull: true;
1282
- hasDefault: true;
1283
- isPrimaryKey: false;
1284
- isAutoincrement: false;
1285
- hasRuntimeDefault: false;
1286
- enumValues: undefined;
1287
- baseColumn: never;
1288
- identity: undefined;
1289
- generated: undefined;
1290
- }, {}, {}>;
1291
- };
1292
- dialect: "pg";
1293
- }>;
1294
- /**
1295
- * Shared content locks table — one per project, independent of any entity.
1296
- * Included exactly once in `buildRuntimeSchema()` when any entity is publishable.
1297
- */
1298
- declare function generateContentLocksSchema(): _$drizzle_orm_pg_core0.PgTableWithColumns<{
1299
- name: "toolkit_content_locks";
1300
- schema: undefined;
1301
- columns: {
1302
- id: _$drizzle_orm_pg_core0.PgColumn<{
1303
- name: "id";
1304
- tableName: "toolkit_content_locks";
1305
- dataType: "string";
1306
- columnType: "PgUUID";
1307
- data: string;
1308
- driverParam: string;
1309
- notNull: true;
1310
- hasDefault: true;
1311
- isPrimaryKey: true;
1312
- isAutoincrement: false;
1313
- hasRuntimeDefault: false;
1314
- enumValues: undefined;
1315
- baseColumn: never;
1316
- identity: undefined;
1317
- generated: undefined;
1318
- }, {}, {}>;
1319
- entityType: _$drizzle_orm_pg_core0.PgColumn<{
1320
- name: "entity_type";
1321
- tableName: "toolkit_content_locks";
1322
- dataType: "string";
1323
- columnType: "PgVarchar";
1324
- data: string;
1325
- driverParam: string;
1326
- notNull: true;
1327
- hasDefault: false;
1328
- isPrimaryKey: false;
1329
- isAutoincrement: false;
1330
- hasRuntimeDefault: false;
1331
- enumValues: [string, ...string[]];
1332
- baseColumn: never;
1333
- identity: undefined;
1334
- generated: undefined;
1335
- }, {}, {
1336
- length: 100;
1337
- }>;
1338
- entityId: _$drizzle_orm_pg_core0.PgColumn<{
1339
- name: "entity_id";
1340
- tableName: "toolkit_content_locks";
1341
- dataType: "string";
1342
- columnType: "PgVarchar";
1343
- data: string;
1344
- driverParam: string;
1345
- notNull: true;
1346
- hasDefault: false;
1347
- isPrimaryKey: false;
1348
- isAutoincrement: false;
1349
- hasRuntimeDefault: false;
1350
- enumValues: [string, ...string[]];
1351
- baseColumn: never;
1352
- identity: undefined;
1353
- generated: undefined;
1354
- }, {}, {
1355
- length: 255;
1356
- }>;
1357
- locale: _$drizzle_orm_pg_core0.PgColumn<{
1358
- name: "locale";
1359
- tableName: "toolkit_content_locks";
1360
- dataType: "string";
1361
- columnType: "PgVarchar";
1362
- data: string;
1363
- driverParam: string;
1364
- notNull: true;
1365
- hasDefault: true;
1366
- isPrimaryKey: false;
1367
- isAutoincrement: false;
1368
- hasRuntimeDefault: false;
1369
- enumValues: [string, ...string[]];
1370
- baseColumn: never;
1371
- identity: undefined;
1372
- generated: undefined;
1373
- }, {}, {
1374
- length: 10;
1375
- }>;
1376
- lockedBy: _$drizzle_orm_pg_core0.PgColumn<{
1377
- name: "locked_by";
1378
- tableName: "toolkit_content_locks";
1379
- dataType: "string";
1380
- columnType: "PgVarchar";
1381
- data: string;
1382
- driverParam: string;
1383
- notNull: true;
1384
- hasDefault: false;
1385
- isPrimaryKey: false;
1386
- isAutoincrement: false;
1387
- hasRuntimeDefault: false;
1388
- enumValues: [string, ...string[]];
1389
- baseColumn: never;
1390
- identity: undefined;
1391
- generated: undefined;
1392
- }, {}, {
1393
- length: 255;
1394
- }>;
1395
- lockedByName: _$drizzle_orm_pg_core0.PgColumn<{
1396
- name: "locked_by_name";
1397
- tableName: "toolkit_content_locks";
1398
- dataType: "string";
1399
- columnType: "PgVarchar";
1400
- data: string;
1401
- driverParam: string;
1402
- notNull: false;
1403
- hasDefault: false;
1404
- isPrimaryKey: false;
1405
- isAutoincrement: false;
1406
- hasRuntimeDefault: false;
1407
- enumValues: [string, ...string[]];
1408
- baseColumn: never;
1409
- identity: undefined;
1410
- generated: undefined;
1411
- }, {}, {
1412
- length: 255;
1413
- }>;
1414
- lockedAt: _$drizzle_orm_pg_core0.PgColumn<{
1415
- name: "locked_at";
1416
- tableName: "toolkit_content_locks";
1417
- dataType: "date";
1418
- columnType: "PgTimestamp";
1419
- data: Date;
1420
- driverParam: string;
1421
- notNull: true;
1422
- hasDefault: true;
1423
- isPrimaryKey: false;
1424
- isAutoincrement: false;
1425
- hasRuntimeDefault: false;
1426
- enumValues: undefined;
1427
- baseColumn: never;
1428
- identity: undefined;
1429
- generated: undefined;
1430
- }, {}, {}>;
1431
- expiresAt: _$drizzle_orm_pg_core0.PgColumn<{
1432
- name: "expires_at";
1433
- tableName: "toolkit_content_locks";
1434
- dataType: "date";
1435
- columnType: "PgTimestamp";
1436
- data: Date;
1437
- driverParam: string;
1438
- notNull: true;
1439
- hasDefault: false;
1440
- isPrimaryKey: false;
1441
- isAutoincrement: false;
1442
- hasRuntimeDefault: false;
1443
- enumValues: undefined;
1444
- baseColumn: never;
1445
- identity: undefined;
1446
- generated: undefined;
1447
- }, {}, {}>;
1448
- };
1449
- dialect: "pg";
1450
- }>;
1451
- /**
1452
- * Check if an entity has blocks fields with translatable block content (non-localized mode).
1453
- */
1454
- declare function hasTranslatableBlocks(entity: Entity): boolean;
1455
- /**
1456
- * Generate layout translation table for non-localized blocks with translatable fields.
1457
- *
1458
- * `layoutParent` is optional — when provided, emits a `.references()` FK
1459
- * pointing at the corresponding `{entity}_layout` table (for migration
1460
- * generation).
1461
- */
1462
- declare function generateLayoutTranslationSchema(entity: Entity, layoutParent?: PgTable): _$drizzle_orm_pg_core0.PgTableWithColumns<{
1463
- name: string;
1464
- schema: undefined;
1465
- columns: {
1466
- id: _$drizzle_orm_pg_core0.PgColumn<{
1467
- name: "id";
1468
- tableName: string;
1469
- dataType: "string";
1470
- columnType: "PgUUID";
1471
- data: string;
1472
- driverParam: string;
1473
- notNull: true;
1474
- hasDefault: true;
1475
- isPrimaryKey: true;
1476
- isAutoincrement: false;
1477
- hasRuntimeDefault: false;
1478
- enumValues: undefined;
1479
- baseColumn: never;
1480
- identity: undefined;
1481
- generated: undefined;
1482
- }, {}, {}>;
1483
- layoutId: _$drizzle_orm_pg_core0.PgColumn<{
1484
- name: "layout_id";
1485
- tableName: string;
1486
- dataType: "string";
1487
- columnType: "PgUUID";
1488
- data: string;
1489
- driverParam: string;
1490
- notNull: true;
1491
- hasDefault: false;
1492
- isPrimaryKey: false;
1493
- isAutoincrement: false;
1494
- hasRuntimeDefault: false;
1495
- enumValues: undefined;
1496
- baseColumn: never;
1497
- identity: undefined;
1498
- generated: undefined;
1499
- }, {}, {}>;
1500
- locale: _$drizzle_orm_pg_core0.PgColumn<{
1501
- name: "locale";
1502
- tableName: string;
1503
- dataType: "string";
1504
- columnType: "PgVarchar";
1505
- data: string;
1506
- driverParam: string;
1507
- notNull: true;
1508
- hasDefault: false;
1509
- isPrimaryKey: false;
1510
- isAutoincrement: false;
1511
- hasRuntimeDefault: false;
1512
- enumValues: [string, ...string[]];
1513
- baseColumn: never;
1514
- identity: undefined;
1515
- generated: undefined;
1516
- }, {}, {
1517
- length: 10;
1518
- }>;
1519
- fields: _$drizzle_orm_pg_core0.PgColumn<{
1520
- name: "fields";
916
+ fields: _$drizzle_orm_pg_core0.PgColumn<{
917
+ name: "fields";
1521
918
  tableName: string;
1522
919
  dataType: "json";
1523
920
  columnType: "PgJsonb";
@@ -1552,5 +949,41 @@ declare function generateLayoutTranslationSchema(entity: Entity, layoutParent?:
1552
949
  */
1553
950
  declare function buildEntitySchemaMap(entities: Entity[]): Record<string, PgTable>;
1554
951
  //#endregion
1555
- export { type AuditableFields, type Behavior, 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, generateContentLocksSchema, generateDraftsSchema, generateLayoutSchema, generateLayoutTranslationSchema, generateLocaleStatusSchema, generateSchema, generateTranslationSchema, generateVersionsSchema, hasBlocksFields, hasTranslatableBlocks, hierarchical, isPublishable, isVersionable, needsLocaleStatus, publishable, revisionable, sluggable, slugify, timestamped };
952
+ //#region src/shared/entity-data-ops.d.ts
953
+ /**
954
+ * Security context resolved per-request. Provided by the consumer
955
+ * (e.g., via React.cache() in Next.js, or runAsCli for CLI).
956
+ * The entity package has zero knowledge of how this is resolved.
957
+ */
958
+ interface SecurityContext {
959
+ user: {
960
+ id: string;
961
+ groups: string[];
962
+ name?: string;
963
+ email?: string;
964
+ };
965
+ checker: (role: string, resource: string, action: string) => boolean;
966
+ scope?: {
967
+ type: string;
968
+ id: string;
969
+ };
970
+ }
971
+ /**
972
+ * Function that resolves the current request's security context.
973
+ * Injected at construction time — the entity package never imports
974
+ * @murumets-ee/core or any framework-specific code.
975
+ *
976
+ * Returns undefined only when intentionally skipping enforcement
977
+ * (should not happen in production — throw ForbiddenError instead).
978
+ */
979
+ type ContextResolver = () => SecurityContext | undefined | Promise<SecurityContext | undefined>;
980
+ /**
981
+ * Thrown when a user lacks permission for an entity operation.
982
+ * Consumers (api-handler) catch this and return HTTP 403.
983
+ */
984
+ declare class ForbiddenError extends Error {
985
+ constructor(message: string);
986
+ }
987
+ //#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 };
1556
989
  //# sourceMappingURL=index.d.mts.map