@forklaunch/core 1.6.7 → 2.1.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.
@@ -5,6 +5,45 @@ import type { FieldEncryptor } from './fieldEncryptor';
5
5
  * Call this once at application bootstrap (e.g., in mikro-orm.config.ts).
6
6
  */
7
7
  export declare function registerEncryptor(encryptor: FieldEncryptor): void;
8
+ /**
9
+ * The empty string was offered as a tenant id.
10
+ *
11
+ * `''` used to mean "the global tenant", which made it impossible to tell a
12
+ * deliberate global row from a tenant that was never resolved — the two are
13
+ * the same key. Rows written by mistake under `''` read back fine from any
14
+ * other unbound path and fail only when a correctly-bound caller finally
15
+ * touches them, arbitrarily far from the code that caused it.
16
+ *
17
+ * Global rows need a tenant id you can name and search for — a constant like
18
+ * `'_internal'` that no organization can collide with. Pick one and pass it.
19
+ */
20
+ export declare class EmptyTenantError extends Error {
21
+ constructor(api: string);
22
+ }
23
+ /**
24
+ * An encrypted column was read or written with no tenant bound.
25
+ *
26
+ * This is the failure the empty tenant used to hide. An unbound write
27
+ * encrypted under `''` and looked like it worked; the row then failed to
28
+ * decrypt for the tenant that owned it, and the stack trace pointed at the
29
+ * innocent reader. Failing here names the actual culprit: the write path
30
+ * that never bound a tenant.
31
+ *
32
+ * Bind one with `wrapEmWithTenantContext(em, tenantId)` in the DI
33
+ * `EntityManager` factory, or `withEncryptionContext(tenantId, fn)` around
34
+ * the work. A raw manager — `orm.em.fork()`, or the `__em` off a wrapped
35
+ * entity — escapes the proxy and arrives here unbound.
36
+ */
37
+ export declare class UnboundTenantError extends Error {
38
+ constructor(operation: string);
39
+ }
40
+ /**
41
+ * Reject `''` at every door that binds a tenant.
42
+ *
43
+ * Exported so the binding helpers in this package share one rule, and so an
44
+ * application's own factory can apply the same one at its own boundary.
45
+ */
46
+ export declare function assertBindableTenantId(tenantId: string, api: string): asserts tenantId is string;
8
47
  /**
9
48
  * Set the encryption tenant ID for the current async context.
10
49
  *
@@ -39,10 +78,24 @@ export declare function setEncryptionTenantId(tenantId: string): void;
39
78
  */
40
79
  export declare function withEncryptionContext<T>(tenantId: string, fn: () => T): T;
41
80
  /**
42
- * Get the current tenant ID. Returns empty string when no context is set
43
- * (startup, seeders, better-auth, background jobs).
81
+ * Get the current tenant ID, or the empty string when none is bound.
82
+ *
83
+ * @deprecated The empty string it returns when nothing is bound is the whole
84
+ * problem: "no tenant" and "the global tenant" became the same value, so an
85
+ * unbound write encrypted under `''` and surfaced as somebody else's decrypt
86
+ * failure. Encryption no longer reads through this — it uses the bound tenant
87
+ * and throws {@link UnboundTenantError} when there is none. Use
88
+ * {@link getBoundTenantId} and handle `undefined` explicitly.
44
89
  */
45
90
  export declare function getCurrentTenantId(): string;
91
+ /**
92
+ * The tenant bound to the current async context, or `undefined` if none is.
93
+ *
94
+ * The distinction {@link getCurrentTenantId} cannot make: `undefined` is
95
+ * "nobody bound a tenant", which is a bug on any path that touches an
96
+ * encrypted column, and never a key.
97
+ */
98
+ export declare function getBoundTenantId(): string | undefined;
46
99
  /**
47
100
  * Resolve a MikroORM type value (string, constructor, or instance) to a
48
101
  * Type instance. Returns undefined if unresolvable.
@@ -1 +1 @@
1
- {"version":3,"file":"encryptedType.d.ts","sourceRoot":"","sources":["../../src/persistence/encryptedType.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE7E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAoBvD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,CAEjE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAEzE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAMD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,OAAO,GACZ,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,SAAS,CAWpC;AAwCD;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAc,SAAQ,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAI7D,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC;IAE5C;;;;;;OAMG;IACH,YACE,kBAAkB,GAAE,MAAiB,EACrC,OAAO,GAAE,OAAe,EACxB,UAAU,CAAC,EAAE,OAAO,EAAE,EAMvB;IAEQ,sBAAsB,CAC7B,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,MAAM,GAAG,IAAI,CA4Bf;IAEQ,gBAAgB,CACvB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,SAAS,EAAE,QAAQ,GAClB,OAAO,CA2BT;IAEQ,aAAa,IAAI,MAAM,CAE/B;IAED,IAAa,WAAW,IAAI,MAAM,CAGjC;IAEQ,gBAAgB,IAAI,OAAO,CAEnC;IAMD,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,WAAW;IAiCnB,OAAO,CAAC,YAAY;CAOrB"}
1
+ {"version":3,"file":"encryptedType.d.ts","sourceRoot":"","sources":["../../src/persistence/encryptedType.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,QAAQ,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE7E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAoBvD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,CAEjE;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,YAAY,GAAG,EAAE,MAAM,EAQtB;CACF;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,SAAS,EAAE,MAAM,EAQ5B;CACF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,QAAQ,IAAI,MAAM,CAI5B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAG5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAGzE;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAErD;AAeD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,OAAO,GACZ,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,SAAS,CAWpC;AAwCD;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAc,SAAQ,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAI7D,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC;IAE5C;;;;;;OAMG;IACH,YACE,kBAAkB,GAAE,MAAiB,EACrC,OAAO,GAAE,OAAe,EACxB,UAAU,CAAC,EAAE,OAAO,EAAE,EAMvB;IAEQ,sBAAsB,CAC7B,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,MAAM,GAAG,IAAI,CAmCf;IAEQ,gBAAgB,CACvB,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,SAAS,EAAE,QAAQ,GAClB,OAAO,CA2BT;IAEQ,aAAa,IAAI,MAAM,CAE/B;IAED,IAAa,WAAW,IAAI,MAAM,CAGjC;IAEQ,gBAAgB,IAAI,OAAO,CAEnC;IAMD,OAAO,CAAC,SAAS;IASjB,OAAO,CAAC,WAAW;IAiCnB,OAAO,CAAC,YAAY;CAOrB"}
@@ -4,7 +4,7 @@ export { asEncryptionSafe, type ContextFreeKeysOfSchema, type ContextFreeReadOpt
4
4
  export { fp } from './compliancePropertyBuilder';
5
5
  export { defineComplianceEntity } from './defineComplianceEntity';
6
6
  export { wrapEmWithNativeQueryBlocking } from './complianceEventSubscriber';
7
- export { EncryptedType, registerEncryptor, setEncryptionTenantId, withEncryptionContext, getCurrentTenantId } from './encryptedType';
7
+ export { EncryptedType, registerEncryptor, setEncryptionTenantId, withEncryptionContext, getCurrentTenantId, getBoundTenantId, assertBindableTenantId, EmptyTenantError, UnboundTenantError } from './encryptedType';
8
8
  export { FieldEncryptor, MissingEncryptionKeyError, DecryptionError, EncryptionRequiredError, parseEncryptionKeyList, encryptionKeyId, stampedKeyId, stampedPrefix, isEncryptedCiphertext, ENCRYPTED_PREFIXES, ENCRYPTION_FORMAT_ENV, ENCRYPTION_KEY_ENV, LEGACY_ENCRYPTION_KEYS_ENV, LEGACY_ENCRYPTION_KEY_ENV, type FieldEncryptorOptions, type OpenedCiphertext, type CiphertextFormat } from './fieldEncryptor';
9
9
  export { reencryptEncryptedColumns, classifyEncryptedValue, collectFallbackTenantIds, defaultTenantIdsFor, entityMetadataList, rotationTotals, countValuesByKeyId, isEncryptedValue, type ReencryptOptions, type RotationOutcome, type RotationTableReport, type SqlExecute, type EntityMetadataLike } from './keyRotation';
10
10
  export { setupTenantFilter, getSuperAdminContext, createTenantFilterDef, TENANT_FILTER_NAME } from './tenantFilter';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/persistence/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,KAAK,eAAe,IAAI,mBAAmB,EAC3C,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EAExB,eAAe,EACf,KAAK,eAAe,IAAI,mBAAmB,EAC3C,KAAK,eAAe,EACpB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,KAAK,cAAc,EACnB,kBAAkB,EAClB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,yBAAyB,EAC9B,KAAK,+BAA+B,EACrC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,6BAA6B,EAC7B,KAAK,yBAAyB,EAC/B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,+BAA+B,EACrC,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,EAAE,EAAE,MAAM,6BAA6B,CAAC;AAGjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAG5E,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,eAAe,EACf,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,kBAAkB,EACxB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAErE,YAAY,EACV,WAAW,EACX,cAAc,EACd,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/persistence/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,eAAe,EACf,KAAK,eAAe,IAAI,mBAAmB,EAC3C,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EAExB,eAAe,EACf,KAAK,eAAe,IAAI,mBAAmB,EAC3C,KAAK,eAAe,EACpB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,EAChB,KAAK,cAAc,EACnB,kBAAkB,EAClB,uBAAuB,EACvB,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,yBAAyB,EAC9B,KAAK,+BAA+B,EACrC,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,6BAA6B,EAC7B,KAAK,yBAAyB,EAC/B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAC/B,KAAK,2BAA2B,EAChC,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,+BAA+B,EACrC,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,EAAE,EAAE,MAAM,6BAA6B,CAAC;AAGjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,EAAE,6BAA6B,EAAE,MAAM,6BAA6B,CAAC;AAG5E,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,eAAe,EACf,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EAClB,0BAA0B,EAC1B,yBAAyB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,kBAAkB,EACxB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAErE,YAAY,EACV,WAAW,EACX,cAAc,EACd,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAI1B,OAAO,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC"}
@@ -35,6 +35,7 @@ __export(persistence_exports, {
35
35
  ENCRYPTED_PREFIXES: () => ENCRYPTED_PREFIXES2,
36
36
  ENCRYPTION_FORMAT_ENV: () => ENCRYPTION_FORMAT_ENV,
37
37
  ENCRYPTION_KEY_ENV: () => ENCRYPTION_KEY_ENV,
38
+ EmptyTenantError: () => EmptyTenantError,
38
39
  EncryptedType: () => EncryptedType,
39
40
  EncryptionRequiredError: () => EncryptionRequiredError,
40
41
  FieldEncryptor: () => FieldEncryptor,
@@ -45,7 +46,9 @@ __export(persistence_exports, {
45
46
  RetentionDuration: () => RetentionDuration,
46
47
  RlsEventSubscriber: () => RlsEventSubscriber,
47
48
  TENANT_FILTER_NAME: () => TENANT_FILTER_NAME,
49
+ UnboundTenantError: () => UnboundTenantError,
48
50
  asEncryptionSafe: () => asEncryptionSafe,
51
+ assertBindableTenantId: () => assertBindableTenantId,
49
52
  classifyEncryptedValue: () => classifyEncryptedValue,
50
53
  collectFallbackTenantIds: () => collectFallbackTenantIds,
51
54
  countValuesByKeyId: () => countValuesByKeyId,
@@ -58,6 +61,7 @@ __export(persistence_exports, {
58
61
  fp: () => fp,
59
62
  getAllRetentionPolicies: () => getAllRetentionPolicies,
60
63
  getAllUserIdFields: () => getAllUserIdFields,
64
+ getBoundTenantId: () => getBoundTenantId,
61
65
  getComplianceMetadata: () => getComplianceMetadata,
62
66
  getCurrentTenantId: () => getCurrentTenantId,
63
67
  getEntityComplianceFields: () => getEntityComplianceFields,
@@ -261,15 +265,48 @@ var _tenantContext = new import_node_async_hooks.AsyncLocalStorage();
261
265
  function registerEncryptor(encryptor) {
262
266
  _encryptor = encryptor;
263
267
  }
268
+ var EmptyTenantError = class extends Error {
269
+ constructor(api) {
270
+ super(
271
+ `${api}: '' is not a tenant id. It used to mean "global", which made a deliberate global row indistinguishable from a tenant nobody resolved. Bind an explicit constant (for example '_internal') for rows that genuinely belong to no organization.`
272
+ );
273
+ this.name = "EmptyTenantError";
274
+ }
275
+ };
276
+ var UnboundTenantError = class extends Error {
277
+ constructor(operation) {
278
+ super(
279
+ `Cannot ${operation} an encrypted column with no tenant bound. Wrap the work in withEncryptionContext(tenantId, fn), or take the entity manager from a factory that calls wrapEmWithTenantContext. A raw em.fork() (or wrap(entity).__em) escapes the tenant proxy.`
280
+ );
281
+ this.name = "UnboundTenantError";
282
+ }
283
+ };
284
+ function assertBindableTenantId(tenantId, api) {
285
+ if (tenantId === "") {
286
+ throw new EmptyTenantError(api);
287
+ }
288
+ }
264
289
  function setEncryptionTenantId(tenantId) {
290
+ assertBindableTenantId(tenantId, "setEncryptionTenantId");
265
291
  _tenantContext.enterWith({ tenantId });
266
292
  }
267
293
  function withEncryptionContext(tenantId, fn) {
294
+ assertBindableTenantId(tenantId, "withEncryptionContext");
268
295
  return _tenantContext.run({ tenantId }, fn);
269
296
  }
270
297
  function getCurrentTenantId() {
271
298
  return _tenantContext.getStore()?.tenantId ?? "";
272
299
  }
300
+ function getBoundTenantId() {
301
+ return _tenantContext.getStore()?.tenantId;
302
+ }
303
+ function requireBoundTenantId(operation) {
304
+ const tenantId = _tenantContext.getStore()?.tenantId;
305
+ if (tenantId === void 0 || tenantId === "") {
306
+ throw new UnboundTenantError(operation);
307
+ }
308
+ return tenantId;
309
+ }
273
310
  function resolveTypeInstance(type) {
274
311
  if (type instanceof import_core.Type) return type;
275
312
  if (typeof type === "function") {
@@ -343,7 +380,7 @@ var EncryptedType = class extends import_core.Type {
343
380
  return value;
344
381
  }
345
382
  const serialized = this.serialize(value);
346
- return _encryptor.encrypt(serialized, getCurrentTenantId()) ?? serialized;
383
+ return _encryptor.encrypt(serialized, requireBoundTenantId("write")) ?? serialized;
347
384
  }
348
385
  convertToJSValue(value, _platform) {
349
386
  if (value === null || value === void 0) return null;
@@ -357,7 +394,7 @@ var EncryptedType = class extends import_core.Type {
357
394
  );
358
395
  }
359
396
  let decrypted;
360
- const tenantId = getCurrentTenantId();
397
+ const tenantId = requireBoundTenantId("read");
361
398
  try {
362
399
  decrypted = _encryptor.decrypt(value, tenantId);
363
400
  } catch (err) {
@@ -1280,9 +1317,8 @@ function wrapEmWithTenantContext(em, tenantId) {
1280
1317
  if (tenantId === void 0) {
1281
1318
  return em;
1282
1319
  }
1283
- if (tenantId) {
1284
- em.setFilterParams("tenant", { tenantId });
1285
- }
1320
+ assertBindableTenantId(tenantId, "wrapEmWithTenantContext");
1321
+ em.setFilterParams("tenant", { tenantId });
1286
1322
  const proxy = new Proxy(em, {
1287
1323
  get(target, prop, receiver) {
1288
1324
  const value = Reflect.get(target, prop, receiver);
@@ -1310,6 +1346,7 @@ function rebind(result, target, proxy) {
1310
1346
  ENCRYPTED_PREFIXES,
1311
1347
  ENCRYPTION_FORMAT_ENV,
1312
1348
  ENCRYPTION_KEY_ENV,
1349
+ EmptyTenantError,
1313
1350
  EncryptedType,
1314
1351
  EncryptionRequiredError,
1315
1352
  FieldEncryptor,
@@ -1320,7 +1357,9 @@ function rebind(result, target, proxy) {
1320
1357
  RetentionDuration,
1321
1358
  RlsEventSubscriber,
1322
1359
  TENANT_FILTER_NAME,
1360
+ UnboundTenantError,
1323
1361
  asEncryptionSafe,
1362
+ assertBindableTenantId,
1324
1363
  classifyEncryptedValue,
1325
1364
  collectFallbackTenantIds,
1326
1365
  countValuesByKeyId,
@@ -1333,6 +1372,7 @@ function rebind(result, target, proxy) {
1333
1372
  fp,
1334
1373
  getAllRetentionPolicies,
1335
1374
  getAllUserIdFields,
1375
+ getBoundTenantId,
1336
1376
  getComplianceMetadata,
1337
1377
  getCurrentTenantId,
1338
1378
  getEntityComplianceFields,