drizzle-multitenant 1.0.1 → 1.0.2

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.
@@ -8,7 +8,9 @@
8
8
  "Bash(tree:*)",
9
9
  "Bash(find:*)",
10
10
  "Bash(mkdir:*)",
11
- "Bash(node ./bin/drizzle-multitenant.js:*)"
11
+ "Bash(node ./bin/drizzle-multitenant.js:*)",
12
+ "Bash(ls:*)",
13
+ "Bash(npm run test:*)"
12
14
  ]
13
15
  }
14
16
  }
@@ -9478,18 +9478,50 @@ function createTenantProviders() {
9478
9478
  },
9479
9479
  inject: [TENANT_MODULE_OPTIONS]
9480
9480
  },
9481
- // TenantDb - request scoped
9481
+ // TenantDb - request scoped with lazy resolution via Proxy
9482
+ // This fixes the timing issue where TENANT_DB is resolved before TenantGuard executes
9482
9483
  {
9483
9484
  provide: TENANT_DB,
9484
9485
  scope: Scope.REQUEST,
9485
- useFactory: (request, manager) => {
9486
- const tenantId = request.tenantContext?.tenantId ?? request.tenantId;
9487
- if (!tenantId) {
9488
- return null;
9489
- }
9490
- return manager.getDb(tenantId);
9486
+ useFactory: (request, manager, options) => {
9487
+ return new Proxy({}, {
9488
+ get(_target, prop) {
9489
+ let tenantId = request.tenantContext?.tenantId ?? request.tenantId;
9490
+ if (!tenantId && options.extractTenantId) {
9491
+ const extracted = options.extractTenantId(request);
9492
+ if (typeof extracted === "string") {
9493
+ tenantId = extracted;
9494
+ }
9495
+ }
9496
+ if (!tenantId) {
9497
+ throw new Error(
9498
+ "[drizzle-multitenant] No tenant context found. Ensure the route has a tenant ID or use @PublicRoute() decorator."
9499
+ );
9500
+ }
9501
+ const db = manager.getDb(tenantId);
9502
+ return db[prop];
9503
+ },
9504
+ has(_target, prop) {
9505
+ const tenantId = request.tenantContext?.tenantId ?? request.tenantId;
9506
+ if (!tenantId) return false;
9507
+ const db = manager.getDb(tenantId);
9508
+ return prop in db;
9509
+ },
9510
+ ownKeys() {
9511
+ const tenantId = request.tenantContext?.tenantId ?? request.tenantId;
9512
+ if (!tenantId) return [];
9513
+ const db = manager.getDb(tenantId);
9514
+ return Reflect.ownKeys(db);
9515
+ },
9516
+ getOwnPropertyDescriptor(_target, prop) {
9517
+ const tenantId = request.tenantContext?.tenantId ?? request.tenantId;
9518
+ if (!tenantId) return void 0;
9519
+ const db = manager.getDb(tenantId);
9520
+ return Object.getOwnPropertyDescriptor(db, prop);
9521
+ }
9522
+ });
9491
9523
  },
9492
- inject: [REQUEST, TENANT_MANAGER]
9524
+ inject: [REQUEST, TENANT_MANAGER, TENANT_MODULE_OPTIONS]
9493
9525
  },
9494
9526
  // SharedDb - singleton (doesn't need request scope)
9495
9527
  {
@@ -9499,14 +9531,57 @@ function createTenantProviders() {
9499
9531
  },
9500
9532
  inject: [TENANT_MANAGER]
9501
9533
  },
9502
- // TenantContext - request scoped
9534
+ // TenantContext - request scoped with lazy resolution via Proxy
9535
+ // This fixes the timing issue where TENANT_CONTEXT is resolved before TenantGuard executes
9503
9536
  {
9504
9537
  provide: TENANT_CONTEXT,
9505
9538
  scope: Scope.REQUEST,
9506
- useFactory: (request) => {
9507
- return request.tenantContext ?? null;
9539
+ useFactory: (request, manager, options) => {
9540
+ return new Proxy({}, {
9541
+ get(_target, prop) {
9542
+ if (request.tenantContext) {
9543
+ return request.tenantContext[prop];
9544
+ }
9545
+ let tenantId = request.tenantId;
9546
+ if (!tenantId && options.extractTenantId) {
9547
+ const extracted = options.extractTenantId(request);
9548
+ if (typeof extracted === "string") {
9549
+ tenantId = extracted;
9550
+ }
9551
+ }
9552
+ if (!tenantId) {
9553
+ throw new Error(
9554
+ "[drizzle-multitenant] No tenant context found. Ensure the route has a tenant ID or use @PublicRoute() decorator."
9555
+ );
9556
+ }
9557
+ const schemaName = manager.getSchemaName(tenantId);
9558
+ const context = { tenantId, schemaName };
9559
+ return context[prop];
9560
+ },
9561
+ has(_target, prop) {
9562
+ if (request.tenantContext) {
9563
+ return prop in request.tenantContext;
9564
+ }
9565
+ return prop === "tenantId" || prop === "schemaName";
9566
+ },
9567
+ ownKeys() {
9568
+ if (request.tenantContext) {
9569
+ return Reflect.ownKeys(request.tenantContext);
9570
+ }
9571
+ return ["tenantId", "schemaName"];
9572
+ },
9573
+ getOwnPropertyDescriptor(_target, prop) {
9574
+ if (request.tenantContext) {
9575
+ return Object.getOwnPropertyDescriptor(request.tenantContext, prop);
9576
+ }
9577
+ if (prop === "tenantId" || prop === "schemaName") {
9578
+ return { configurable: true, enumerable: true, writable: true };
9579
+ }
9580
+ return void 0;
9581
+ }
9582
+ });
9508
9583
  },
9509
- inject: [REQUEST]
9584
+ inject: [REQUEST, TENANT_MANAGER, TENANT_MODULE_OPTIONS]
9510
9585
  }
9511
9586
  ];
9512
9587
  }