@authhero/multi-tenancy 15.1.2 → 15.2.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.
@@ -1,9 +1,9 @@
1
1
  import { Hono as e } from "hono";
2
- import { MANAGEMENT_API_AUDIENCE as t, MANAGEMENT_API_SCOPES as n, auth0QuerySchema as r, brandingSchema as i, connectionInsertSchema as a, connectionOptionsSchema as o, connectionSchema as s, deepMergePatch as c, emailProviderSchema as l, escapeLuceneValue as u, fetchAll as d, hookInsertSchema as f, init as p, isInteractiveClient as m, listControlPlaneKeys as h, promptSettingSchema as g, provisionDefaultClients as _, resourceServerInsertSchema as v, tenantInsertSchema as y, tenantSchema as b } from "authhero";
3
- import { OpenAPIHono as x, createRoute as S, z as C } from "@hono/zod-openapi";
4
- import { HTTPException as w } from "hono/http-exception";
2
+ import { LogTypes as t, MANAGEMENT_API_AUDIENCE as n, MANAGEMENT_API_SCOPES as r, auth0QuerySchema as i, brandingSchema as a, connectionInsertSchema as o, connectionOptionsSchema as s, connectionSchema as c, deepMergePatch as l, emailProviderSchema as u, escapeLuceneValue as d, fetchAll as f, hookInsertSchema as p, init as m, isInteractiveClient as h, listControlPlaneKeys as g, promptSettingSchema as _, provisionDefaultClients as v, resourceServerInsertSchema as y, tenantInsertSchema as b, tenantSchema as x } from "authhero";
3
+ import { OpenAPIHono as S, createRoute as C, z as w } from "@hono/zod-openapi";
4
+ import { HTTPException as T } from "hono/http-exception";
5
5
  //#region src/hooks/access-control.ts
6
- function T(e) {
6
+ function E(e) {
7
7
  let { controlPlaneTenantId: t, requireOrganizationMatch: n = !0 } = e;
8
8
  return { async onTenantAccessValidation(e, r) {
9
9
  if (r === t) return !0;
@@ -14,14 +14,14 @@ function T(e) {
14
14
  return !0;
15
15
  } };
16
16
  }
17
- function E(e, t, n, r) {
17
+ function D(e, t, n, r) {
18
18
  if (t === n) return !0;
19
19
  let i = r || e;
20
20
  return i ? i.toLowerCase() === t.toLowerCase() : !1;
21
21
  }
22
22
  //#endregion
23
23
  //#region src/hooks/database.ts
24
- function D(e) {
24
+ function ee(e) {
25
25
  return { async resolveDataAdapters(t) {
26
26
  try {
27
27
  return await e.getAdapters(t);
@@ -43,7 +43,7 @@ function A(e) {
43
43
  }
44
44
  //#endregion
45
45
  //#region src/operations/recorder.ts
46
- var ee = 2048;
46
+ var te = 2048;
47
47
  function j(e) {
48
48
  let t;
49
49
  if (e instanceof Error) t = e.message;
@@ -52,7 +52,7 @@ function j(e) {
52
52
  } catch {
53
53
  t = Object.prototype.toString.call(e);
54
54
  }
55
- return t.slice(0, ee);
55
+ return t.slice(0, te);
56
56
  }
57
57
  function M(e) {
58
58
  let { tenantOperations: t, tenantOperationEvents: n } = e;
@@ -91,17 +91,17 @@ function M(e) {
91
91
  }
92
92
  };
93
93
  }
94
- function N(e) {
94
+ function ne(e) {
95
95
  return e === "succeeded" || e === "failed" || e === "cancelled";
96
96
  }
97
97
  //#endregion
98
98
  //#region src/operations/inline-executor.ts
99
- var te = { async do(e, t, n) {
99
+ var re = { async do(e, t, n) {
100
100
  let r = typeof t == "function" ? t : n;
101
101
  if (!r) throw Error("StepRunner.do called without a function");
102
102
  return r();
103
103
  } };
104
- function ne(e) {
104
+ function ie(e) {
105
105
  let t = M(e.stores);
106
106
  return {
107
107
  engine: "inline",
@@ -121,7 +121,7 @@ function ne(e) {
121
121
  try {
122
122
  let r = await e.run({
123
123
  operation: n,
124
- step: te
124
+ step: re
125
125
  });
126
126
  await t.appendEvent(n.id, {
127
127
  step: e.name,
@@ -142,7 +142,7 @@ function ne(e) {
142
142
  }
143
143
  //#endregion
144
144
  //#region src/operations/enqueue.ts
145
- async function re(e, t, n) {
145
+ async function ae(e, t, n) {
146
146
  let r = await e.tenantOperations.create({
147
147
  tenant_id: t.tenant_id,
148
148
  rollout_id: t.rollout_id,
@@ -165,14 +165,14 @@ async function re(e, t, n) {
165
165
  engine_instance_id: i
166
166
  };
167
167
  }
168
- async function ie(e, t, n) {
169
- let r = M(e), i = await re(e, n, t.engine);
168
+ async function oe(e, t, n) {
169
+ let r = M(e), i = await ae(e, n, t.engine);
170
170
  try {
171
171
  await t.start(i);
172
172
  } catch (t) {
173
173
  try {
174
174
  let n = await e.tenantOperations.get(i.id);
175
- n && !N(n.status) && await r.markFailed(i.id, t);
175
+ n && !ne(n.status) && await r.markFailed(i.id, t);
176
176
  } catch (e) {
177
177
  console.warn("Failed to record tenant operation failure:", e);
178
178
  }
@@ -186,14 +186,14 @@ async function ie(e, t, n) {
186
186
  }
187
187
  //#endregion
188
188
  //#region src/operations/record-provision.ts
189
- function ae(e) {
189
+ function se(e) {
190
190
  if (e.tenantOperations && e.tenantOperationEvents) return {
191
191
  tenantOperations: e.tenantOperations,
192
192
  tenantOperationEvents: e.tenantOperationEvents
193
193
  };
194
194
  }
195
- async function oe(e, t, n) {
196
- let r = ae(e);
195
+ async function ce(e, t, n) {
196
+ let r = se(e);
197
197
  if (!r) {
198
198
  await n(void 0);
199
199
  return;
@@ -206,7 +206,7 @@ async function oe(e, t, n) {
206
206
  }
207
207
  }, o;
208
208
  if (await a(async () => {
209
- let e = await re(r, t, "inline");
209
+ let e = await ae(r, t, "inline");
210
210
  o = e.id, await i.markRunning(e.id);
211
211
  }), !o) {
212
212
  await n(void 0);
@@ -241,30 +241,30 @@ async function oe(e, t, n) {
241
241
  }
242
242
  //#endregion
243
243
  //#region src/hooks/provisioning.ts
244
- function se(e) {
244
+ function le(e) {
245
245
  return `urn:authhero:tenant:${e.toLowerCase()}`;
246
246
  }
247
- function P(e) {
247
+ function N(e) {
248
248
  return {
249
249
  async beforeCreate(e, t) {
250
250
  return !t.audience && t.id ? {
251
251
  ...t,
252
- audience: se(t.id)
252
+ audience: le(t.id)
253
253
  } : t;
254
254
  },
255
- async afterCreate(r, i) {
255
+ async afterCreate(t, i) {
256
256
  let { accessControl: a, databaseIsolation: o } = e;
257
- if (a && r.ctx && await ce(r, i, a), o?.onProvision) {
257
+ if (a && t.ctx && await ue(t, i, a), o?.onProvision) {
258
258
  let e = o.onProvision;
259
- o.recordProvisionOperations === !1 ? await e(i.id) : await oe(r.adapters, {
259
+ o.recordProvisionOperations === !1 ? await e(i.id) : await ce(t.adapters, {
260
260
  kind: "provision",
261
261
  tenant_id: i.id,
262
- initiated_by: r.ctx?.var.user?.sub
262
+ initiated_by: t.ctx?.var.user?.sub
263
263
  }, (t) => e(i.id, t));
264
264
  } else try {
265
- await _(r.adapters, i.id, {
266
- managementApiIdentifier: t,
267
- managementApiScopes: n
265
+ await v(t.adapters, i.id, {
266
+ managementApiIdentifier: n,
267
+ managementApiScopes: r
268
268
  });
269
269
  } catch (e) {
270
270
  throw console.warn(`Failed to provision default clients for tenant ${i.id}:`, e), e;
@@ -286,14 +286,14 @@ function P(e) {
286
286
  }
287
287
  };
288
288
  }
289
- async function ce(e, t, n) {
289
+ async function ue(e, t, n) {
290
290
  let { controlPlaneTenantId: r, defaultPermissions: i, defaultRoles: a, issuer: o, adminRoleName: s = "Tenant Admin", adminRoleDescription: c = "Full access to all tenant management operations", addCreatorToOrganization: l = !0 } = n, u = await e.adapters.organizations.create(r, {
291
291
  name: t.id,
292
292
  display_name: t.friendly_name || t.id
293
293
  }), d;
294
- if (o && (d = await ue(e, r, s, c)), l && e.ctx) {
294
+ if (o && (d = await fe(e, r, s, c)), l && e.ctx) {
295
295
  let t = e.ctx.var.user;
296
- if (t?.sub && !await le(e, r, t.sub)) try {
296
+ if (t?.sub && !await de(e, r, t.sub)) try {
297
297
  await e.adapters.userOrganizations.create(r, {
298
298
  user_id: t.sub,
299
299
  organization_id: u.id
@@ -304,31 +304,31 @@ async function ce(e, t, n) {
304
304
  }
305
305
  a && a.length > 0 && console.log(`Would assign roles ${a.join(", ")} to organization ${u.id}`), i && i.length > 0 && console.log(`Would grant permissions ${i.join(", ")} to organization ${u.id}`);
306
306
  }
307
- async function le(e, n, r) {
308
- let i = await e.adapters.userRoles.list(n, r, void 0, "");
309
- for (let r of i) if ((await e.adapters.rolePermissions.list(n, r.id, { per_page: 1e3 })).some((e) => e.permission_name === "admin:organizations" && e.resource_server_identifier === t)) return !0;
307
+ async function de(e, t, r) {
308
+ let i = await e.adapters.userRoles.list(t, r, void 0, "");
309
+ for (let r of i) if ((await e.adapters.rolePermissions.list(t, r.id, { per_page: 1e3 })).some((e) => e.permission_name === "admin:organizations" && e.resource_server_identifier === n)) return !0;
310
310
  return !1;
311
311
  }
312
- async function ue(e, r, i, a) {
313
- let o = (await e.adapters.roles.list(r, {})).roles.find((e) => e.name === i);
312
+ async function fe(e, t, i, a) {
313
+ let o = (await e.adapters.roles.list(t, {})).roles.find((e) => e.name === i);
314
314
  if (o) return o.id;
315
- let s = await e.adapters.roles.create(r, {
315
+ let s = await e.adapters.roles.create(t, {
316
316
  name: i,
317
317
  description: a
318
- }), c = t, l = n.map((e) => ({
318
+ }), c = n, l = r.map((e) => ({
319
319
  role_id: s.id,
320
320
  resource_server_identifier: c,
321
321
  permission_name: e.value
322
322
  }));
323
- return await e.adapters.rolePermissions.assign(r, s.id, l), s.id;
323
+ return await e.adapters.rolePermissions.assign(t, s.id, l), s.id;
324
324
  }
325
325
  //#endregion
326
326
  //#region src/hooks/sync.ts
327
- function F(e, t, n = () => !0) {
327
+ function pe(e, t, n = () => !0) {
328
328
  let { controlPlaneTenantId: r, getChildTenantIds: i, getAdapters: a } = e, o = /* @__PURE__ */ new Map();
329
329
  async function s(e, n, r) {
330
330
  return (await t(e).list(n, {
331
- q: `name:${u(r)}`,
331
+ q: `name:${d(r)}`,
332
332
  per_page: 1
333
333
  }))[0] ?? null;
334
334
  }
@@ -379,11 +379,11 @@ function F(e, t, n = () => !0) {
379
379
  }
380
380
  };
381
381
  }
382
- function I(e, t, n = () => !0) {
382
+ function me(e, t, n = () => !0) {
383
383
  let { controlPlaneTenantId: r, getControlPlaneAdapters: i, getAdapters: a } = e;
384
384
  return { async afterCreate(e, o) {
385
385
  if (o.id !== r) try {
386
- let e = await i(), s = await a(o.id), c = t(e), l = t(s), u = await d((e) => c.listPaginated(r, e), c.listKey, {
386
+ let e = await i(), s = await a(o.id), c = t(e), l = t(s), u = await f((e) => c.listPaginated(r, e), c.listKey, {
387
387
  cursorField: "id",
388
388
  pageSize: 100
389
389
  });
@@ -403,7 +403,7 @@ function I(e, t, n = () => !0) {
403
403
  }
404
404
  } };
405
405
  }
406
- var L = (e) => ({
406
+ var he = (e) => ({
407
407
  list: async (t, n) => (await e.resourceServers.list(t, n)).resource_servers,
408
408
  listPaginated: (t, n) => e.resourceServers.list(t, n),
409
409
  get: (t, n) => e.resourceServers.get(t, n),
@@ -421,7 +421,7 @@ var L = (e) => ({
421
421
  token_lifetime: e.token_lifetime,
422
422
  token_lifetime_for_web: e.token_lifetime_for_web
423
423
  })
424
- }), R = (e) => ({
424
+ }), ge = (e) => ({
425
425
  list: async (t, n) => (await e.roles.list(t, n)).roles,
426
426
  listPaginated: (t, n) => e.roles.list(t, n),
427
427
  get: (t, n) => e.roles.get(t, n),
@@ -436,15 +436,15 @@ var L = (e) => ({
436
436
  description: e.description
437
437
  })
438
438
  });
439
- function z(e) {
439
+ function _e(e) {
440
440
  return e.metadata?.sync !== !1;
441
441
  }
442
- function B(e) {
443
- let { sync: t = {}, filters: n = {} } = e, r = t.resourceServers ?? !0, i = t.roles ?? !0, a = (e) => z(e) ? n.resourceServers ? n.resourceServers(e) : !0 : !1, o = (e) => z(e) ? n.roles ? n.roles(e) : !0 : !1, s = r ? F(e, L, a) : void 0, c = i ? F(e, R, o) : void 0, l = r ? I(e, L, a) : void 0, f = i ? I(e, R, o) : void 0, p = i ? { async afterCreate(t, r) {
442
+ function ve(e) {
443
+ let { sync: t = {}, filters: n = {} } = e, r = t.resourceServers ?? !0, i = t.roles ?? !0, a = (e) => _e(e) ? n.resourceServers ? n.resourceServers(e) : !0 : !1, o = (e) => _e(e) ? n.roles ? n.roles(e) : !0 : !1, s = r ? pe(e, he, a) : void 0, c = i ? pe(e, ge, o) : void 0, l = r ? me(e, he, a) : void 0, u = i ? me(e, ge, o) : void 0, p = i ? { async afterCreate(t, r) {
444
444
  if (r.id !== e.controlPlaneTenantId) {
445
- await f?.afterCreate?.(t, r);
445
+ await u?.afterCreate?.(t, r);
446
446
  try {
447
- let t = await e.getControlPlaneAdapters(), i = await e.getAdapters(r.id), a = await d((n) => t.roles.list(e.controlPlaneTenantId, n), "roles", {
447
+ let t = await e.getControlPlaneAdapters(), i = await e.getAdapters(r.id), a = await f((n) => t.roles.list(e.controlPlaneTenantId, n), "roles", {
448
448
  cursorField: "id",
449
449
  pageSize: 100
450
450
  }), o = /* @__PURE__ */ new Map();
@@ -472,7 +472,7 @@ function B(e) {
472
472
  } } : void 0;
473
473
  async function m(e, t, n) {
474
474
  return (await e.roles.list(t, {
475
- q: `name:${u(n)}`,
475
+ q: `name:${d(n)}`,
476
476
  per_page: 1
477
477
  })).roles[0] ?? null;
478
478
  }
@@ -482,7 +482,7 @@ function B(e) {
482
482
  roles: c
483
483
  },
484
484
  tenantHooks: { async afterCreate(e, t) {
485
- let n = [l?.afterCreate, p?.afterCreate ?? f?.afterCreate], r = [];
485
+ let n = [l?.afterCreate, p?.afterCreate ?? u?.afterCreate], r = [];
486
486
  for (let i of n) if (i) try {
487
487
  await i(e, t);
488
488
  } catch (e) {
@@ -495,48 +495,71 @@ function B(e) {
495
495
  }
496
496
  //#endregion
497
497
  //#region src/middleware/request-data.ts
498
- function V(e) {
498
+ function P(e) {
499
499
  return e.var.data ?? e.env.data;
500
500
  }
501
+ async function ye(e) {
502
+ let { tenantId: t, parentTenantId: n, getTenant: r, getChildren: i } = e, a = e.maxDepth ?? 2;
503
+ if (!n) return;
504
+ if (t && n === t) throw new T(400, { message: "A tenant cannot be its own parent" });
505
+ let o = new Set(t ? [t] : []), s = 0, c = n;
506
+ for (; c;) {
507
+ if (o.has(c)) throw new T(400, { message: `Setting parent_tenant_id to '${n}' would create a cycle` });
508
+ o.add(c);
509
+ let e = await r(c);
510
+ if (!e) throw new T(400, { message: `Parent tenant '${c}' not found` });
511
+ if (s += 1, s > a) throw new T(400, { message: `Tenant tree is limited to ${a} levels above a tenant` });
512
+ c = e.parent_tenant_id;
513
+ }
514
+ if (t && i) {
515
+ let e = new Set([t]), r = 0, o = [t];
516
+ for (; o.length > 0;) {
517
+ let t = [];
518
+ for (let n of o) for (let r of await i(n)) e.has(r) || (e.add(r), t.push(r));
519
+ if (t.length > 0 && (r += 1, s + r > a)) throw new T(400, { message: `Moving tenant under '${n}' would make its descendant '${t[0]}' exceed the tenant tree limit of ${a} levels` });
520
+ o = t;
521
+ }
522
+ }
523
+ }
501
524
  //#endregion
502
525
  //#region src/routes/tenants.ts
503
- var de = C.object({
504
- sub: C.string(),
505
- tenant_id: C.string().optional(),
506
- org_id: C.string().optional(),
507
- scope: C.string().optional(),
508
- permissions: C.array(C.string()).optional()
526
+ var be = w.object({
527
+ sub: w.string(),
528
+ tenant_id: w.string().optional(),
529
+ org_id: w.string().optional(),
530
+ scope: w.string().optional(),
531
+ permissions: w.array(w.string()).optional()
509
532
  }).passthrough();
510
- function fe(e) {
511
- let t = de.safeParse(e);
533
+ function xe(e) {
534
+ let t = be.safeParse(e);
512
535
  return t.success ? t.data : void 0;
513
536
  }
514
- function pe(e) {
537
+ function Se(e) {
515
538
  let t = e.permissions ?? [], n = e.scope ? e.scope.split(" ").filter(Boolean) : [], r = new Set([...t, ...n]);
516
539
  return r.has("delete:tenants") || r.has("admin:organizations");
517
540
  }
518
- function H(e, t) {
519
- let n = new x();
520
- return n.openapi(S({
541
+ function F(e, t) {
542
+ let n = new S();
543
+ return n.openapi(C({
521
544
  tags: ["tenants"],
522
545
  method: "get",
523
546
  path: "/",
524
- request: { query: r },
547
+ request: { query: i },
525
548
  security: [{ Bearer: [] }],
526
549
  responses: { 200: {
527
- content: { "application/json": { schema: C.object({
528
- tenants: C.array(b),
529
- start: C.number().optional(),
530
- limit: C.number().optional(),
531
- length: C.number().optional(),
532
- total: C.number().optional()
550
+ content: { "application/json": { schema: w.object({
551
+ tenants: w.array(x),
552
+ start: w.number().optional(),
553
+ limit: w.number().optional(),
554
+ length: w.number().optional(),
555
+ total: w.number().optional()
533
556
  }) } },
534
557
  description: "List of tenants"
535
558
  } }
536
559
  }), async (t) => {
537
560
  let { page: n, per_page: r, include_totals: i, q: a } = t.req.valid("query"), o = t.var.user, s = o?.permissions || [];
538
561
  if (!(o?.org_id ?? t.var.organization_id) && s.includes("admin:organizations")) {
539
- let e = await V(t).tenants.list({
562
+ let e = await P(t).tenants.list({
540
563
  page: n,
541
564
  per_page: r,
542
565
  include_totals: i,
@@ -550,10 +573,10 @@ function H(e, t) {
550
573
  total: e.totals?.length
551
574
  }) : t.json({ tenants: e.tenants });
552
575
  }
553
- let c = e.accessControl?.controlPlaneTenantId ?? V(t).multiTenancyConfig?.controlPlaneTenantId;
554
- if (c && !o?.sub) throw new w(403, { message: "Access denied: token has no subject" });
576
+ let c = e.accessControl?.controlPlaneTenantId ?? P(t).multiTenancyConfig?.controlPlaneTenantId;
577
+ if (c && !o?.sub) throw new T(403, { message: "Access denied: token has no subject" });
555
578
  if (c && o?.sub) {
556
- let e = (await d((e) => V(t).userOrganizations.listUserOrganizations(c, o.sub, e), "organizations")).map((e) => e.name);
579
+ let e = (await f((e) => P(t).userOrganizations.listUserOrganizations(c, o.sub, e), "organizations")).map((e) => e.name);
557
580
  if (e.length === 0) return i ? t.json({
558
581
  tenants: [],
559
582
  start: 0,
@@ -561,28 +584,28 @@ function H(e, t) {
561
584
  length: 0,
562
585
  total: 0
563
586
  }) : t.json({ tenants: [] });
564
- let s = e.length, l = n ?? 0, u = r ?? 50, f = l * u, p = e.slice(f, f + u);
587
+ let s = e.length, l = n ?? 0, u = r ?? 50, d = l * u, p = e.slice(d, d + u);
565
588
  if (p.length === 0) return i ? t.json({
566
589
  tenants: [],
567
- start: f,
590
+ start: d,
568
591
  limit: u,
569
592
  length: 0,
570
593
  total: s
571
594
  }) : t.json({ tenants: [] });
572
- let m = p.map((e) => `id:${e}`).join(" OR "), h = a ? `(${m}) AND (${a})` : m, g = await V(t).tenants.list({
595
+ let m = p.map((e) => `id:${e}`).join(" OR "), h = a ? `(${m}) AND (${a})` : m, g = await P(t).tenants.list({
573
596
  q: h,
574
597
  per_page: u,
575
598
  include_totals: !1
576
599
  });
577
600
  return i ? t.json({
578
601
  tenants: g.tenants,
579
- start: f,
602
+ start: d,
580
603
  limit: u,
581
604
  length: g.tenants.length,
582
605
  total: s
583
606
  }) : t.json({ tenants: g.tenants });
584
607
  }
585
- let l = await V(t).tenants.list({
608
+ let l = await P(t).tenants.list({
586
609
  page: n,
587
610
  per_page: r,
588
611
  include_totals: i,
@@ -595,34 +618,38 @@ function H(e, t) {
595
618
  length: l.tenants.length,
596
619
  total: l.totals?.length
597
620
  }) : t.json({ tenants: l.tenants });
598
- }), n.openapi(S({
621
+ }), n.openapi(C({
599
622
  tags: ["tenants"],
600
623
  method: "post",
601
624
  path: "/",
602
- request: { body: { content: { "application/json": { schema: y } } } },
625
+ request: { body: { content: { "application/json": { schema: b } } } },
603
626
  security: [{ Bearer: [] }],
604
627
  responses: {
605
628
  201: {
606
- content: { "application/json": { schema: b } },
629
+ content: { "application/json": { schema: x } },
607
630
  description: "Tenant created"
608
631
  },
609
632
  400: { description: "Validation error" },
610
633
  409: { description: "Tenant with this ID already exists" }
611
634
  }
612
635
  }), async (e) => {
613
- if (!e.var.user?.sub) throw new w(401, { message: "Authentication required to create tenants" });
636
+ if (!e.var.user?.sub) throw new T(401, { message: "Authentication required to create tenants" });
614
637
  let n = e.req.valid("json"), r = {
615
- adapters: V(e),
638
+ adapters: P(e),
616
639
  ctx: e
617
640
  };
618
- t.tenants?.beforeCreate && (n = await t.tenants.beforeCreate(r, n));
619
- let i = await V(e).tenants.create(n);
641
+ t.tenants?.beforeCreate && (n = await t.tenants.beforeCreate(r, n)), await ye({
642
+ tenantId: n.id,
643
+ parentTenantId: n.parent_tenant_id,
644
+ getTenant: (t) => P(e).tenants.get(t)
645
+ });
646
+ let i = await P(e).tenants.create(n);
620
647
  return t.tenants?.afterCreate && await t.tenants.afterCreate(r, i), e.json(i, 201);
621
- }), n.openapi(S({
648
+ }), n.openapi(C({
622
649
  tags: ["tenants"],
623
650
  method: "delete",
624
651
  path: "/{id}",
625
- request: { params: C.object({ id: C.string() }) },
652
+ request: { params: w.object({ id: w.string() }) },
626
653
  security: [{ Bearer: ["delete:tenants"] }],
627
654
  responses: {
628
655
  204: { description: "Tenant deleted" },
@@ -630,72 +657,78 @@ function H(e, t) {
630
657
  404: { description: "Tenant not found" }
631
658
  }
632
659
  }), async (n) => {
633
- let { id: r } = n.req.valid("param"), i = e.accessControl?.controlPlaneTenantId ?? V(n).multiTenancyConfig?.controlPlaneTenantId;
660
+ let { id: r } = n.req.valid("param"), i = e.accessControl?.controlPlaneTenantId ?? P(n).multiTenancyConfig?.controlPlaneTenantId;
634
661
  if (i) {
635
- let e = fe(n.var.user);
636
- if (!e?.sub) throw new w(401, { message: "Authentication required" });
637
- if (r === i) throw new w(403, { message: "Cannot delete the control plane" });
662
+ let e = xe(n.var.user);
663
+ if (!e?.sub) throw new T(401, { message: "Authentication required" });
664
+ if (r === i) throw new T(403, { message: "Cannot delete the control plane" });
638
665
  let t = n.var.org_name, a = r.toLowerCase(), o = !!t && t.toLowerCase() === a;
639
666
  if (!o) {
640
667
  let r = !!(e.org_id ?? n.var.organization_id ?? t), a = !e.tenant_id || e.tenant_id === i;
641
- !r && a && pe(e) && (o = !0);
668
+ !r && a && Se(e) && (o = !0);
642
669
  }
643
- if (o ||= (await d((t) => V(n).userOrganizations.listUserOrganizations(i, e.sub, t), "organizations")).some((e) => e.name?.toLowerCase() === a), !o) throw new w(403, { message: "Access denied to this tenant" });
670
+ if (o ||= (await f((t) => P(n).userOrganizations.listUserOrganizations(i, e.sub, t), "organizations")).some((e) => e.name?.toLowerCase() === a), !o) throw new T(403, { message: "Access denied to this tenant" });
644
671
  }
645
- if (!await V(n).tenants.get(r)) throw new w(404, { message: "Tenant not found" });
672
+ if (!await P(n).tenants.get(r)) throw new T(404, { message: "Tenant not found" });
646
673
  let a = {
647
- adapters: V(n),
674
+ adapters: P(n),
648
675
  ctx: n
649
676
  };
650
- return t.tenants?.beforeDelete && await t.tenants.beforeDelete(a, r), await V(n).tenants.remove(r), t.tenants?.afterDelete && await t.tenants.afterDelete(a, r), n.body(null, 204);
651
- }), n.openapi(S({
677
+ return t.tenants?.beforeDelete && await t.tenants.beforeDelete(a, r), await P(n).tenants.remove(r), t.tenants?.afterDelete && await t.tenants.afterDelete(a, r), n.body(null, 204);
678
+ }), n.openapi(C({
652
679
  tags: ["tenants", "settings"],
653
680
  method: "get",
654
681
  path: "/settings",
655
- request: { headers: C.object({ "tenant-id": C.string().optional() }) },
682
+ request: { headers: w.object({ "tenant-id": w.string().optional() }) },
656
683
  security: [{ Bearer: ["read:tenants"] }],
657
684
  responses: { 200: {
658
- content: { "application/json": { schema: b } },
685
+ content: { "application/json": { schema: x } },
659
686
  description: "Current tenant settings"
660
687
  } }
661
688
  }), async (e) => {
662
- let t = await V(e).tenants.get(e.var.tenant_id);
663
- if (!t) throw new w(404, { message: "Tenant not found" });
689
+ let t = await P(e).tenants.get(e.var.tenant_id);
690
+ if (!t) throw new T(404, { message: "Tenant not found" });
664
691
  return e.json(t);
665
- }), n.openapi(S({
692
+ }), n.openapi(C({
666
693
  tags: ["tenants", "settings"],
667
694
  method: "patch",
668
695
  path: "/settings",
669
696
  request: {
670
- headers: C.object({ "tenant-id": C.string().optional() }),
671
- body: { content: { "application/json": { schema: C.object(y.shape).partial() } } }
697
+ headers: w.object({ "tenant-id": w.string().optional() }),
698
+ body: { content: { "application/json": { schema: w.object(b.shape).partial() } } }
672
699
  },
673
700
  security: [{ Bearer: ["update:tenants"] }],
674
701
  responses: { 200: {
675
- content: { "application/json": { schema: b } },
702
+ content: { "application/json": { schema: x } },
676
703
  description: "Updated tenant settings"
677
704
  } }
678
705
  }), async (e) => {
679
- let { id: t, ...n } = e.req.valid("json"), r = await V(e).tenants.get(e.var.tenant_id);
680
- if (!r) throw new w(404, { message: "Tenant not found" });
706
+ let { id: t, ...n } = e.req.valid("json"), r = await P(e).tenants.get(e.var.tenant_id);
707
+ if (!r) throw new T(404, { message: "Tenant not found" });
681
708
  if ("default_client_id" in n) {
682
709
  let t = n.default_client_id;
683
710
  if (typeof t == "string" && t.length > 0) {
684
- let n = await V(e).clients.get(e.var.tenant_id, t);
685
- if (!n) throw new w(400, { message: `Client with id '${t}' not found` });
686
- if (!m(n)) throw new w(400, { message: `Client '${t}' is not an interactive client and cannot be used as the default client` });
711
+ let n = await P(e).clients.get(e.var.tenant_id, t);
712
+ if (!n) throw new T(400, { message: `Client with id '${t}' not found` });
713
+ if (!h(n)) throw new T(400, { message: `Client '${t}' is not an interactive client and cannot be used as the default client` });
687
714
  }
688
715
  }
689
- let i = c(r, n);
690
- await V(e).tenants.update(e.var.tenant_id, i);
691
- let a = await V(e).tenants.get(e.var.tenant_id);
692
- if (!a) throw new w(500, { message: "Failed to retrieve updated tenant" });
716
+ "parent_tenant_id" in n && await ye({
717
+ tenantId: e.var.tenant_id,
718
+ parentTenantId: n.parent_tenant_id,
719
+ getTenant: (t) => P(e).tenants.get(t),
720
+ getChildren: async (t) => (await f((t) => P(e).tenants.list(t), "tenants")).filter((e) => e.parent_tenant_id === t).map((e) => e.id)
721
+ });
722
+ let i = l(r, n);
723
+ await P(e).tenants.update(e.var.tenant_id, i);
724
+ let a = await P(e).tenants.get(e.var.tenant_id);
725
+ if (!a) throw new T(500, { message: "Failed to retrieve updated tenant" });
693
726
  return e.json(a);
694
727
  }), n;
695
728
  }
696
729
  //#endregion
697
730
  //#region src/middleware/protect-synced.ts
698
- function me(e) {
731
+ function Ce(e) {
699
732
  for (let { pattern: t, type: n } of [
700
733
  {
701
734
  pattern: /\/api\/v2\/resource-servers\/([^/]+)$/,
@@ -718,7 +751,7 @@ function me(e) {
718
751
  }
719
752
  return null;
720
753
  }
721
- async function he(e, t, n) {
754
+ async function we(e, t, n) {
722
755
  try {
723
756
  switch (n.type) {
724
757
  case "resource_server": return (await e.resourceServers.get(t, n.id))?.is_system === !0;
@@ -730,47 +763,495 @@ async function he(e, t, n) {
730
763
  return !1;
731
764
  }
732
765
  }
733
- function ge(e) {
766
+ function Te(e) {
734
767
  return {
735
768
  resource_server: "resource server",
736
769
  role: "role",
737
770
  connection: "connection"
738
771
  }[e];
739
772
  }
740
- function U() {
773
+ function Ee() {
741
774
  return async (e, t) => {
742
775
  if (![
743
776
  "PATCH",
744
777
  "PUT",
745
778
  "DELETE"
746
779
  ].includes(e.req.method)) return t();
747
- let n = me(e.req.path);
780
+ let n = Ce(e.req.path);
748
781
  if (!n) return t();
749
782
  let r = e.var.tenant_id || e.req.header("x-tenant-id") || e.req.header("tenant-id");
750
783
  if (!r) return t();
751
- if (await he(V(e), r, n)) throw new w(403, { message: `This ${ge(n.type)} is a system resource and cannot be modified. Make changes in the control plane instead.` });
784
+ if (await we(P(e), r, n)) throw new T(403, { message: `This ${Te(n.type)} is a system resource and cannot be modified. Make changes in the control plane instead.` });
752
785
  return t();
753
786
  };
754
787
  }
755
788
  //#endregion
789
+ //#region src/inheritance/chain.ts
790
+ async function De(e) {
791
+ let { tenantId: t, getTenant: n, legacyControlPlane: r } = e, i = e.maxDepth ?? 2, a = await n(t);
792
+ if (!a?.parent_tenant_id) return r && r !== t ? [r] : [];
793
+ let o = [], s = new Set([t]), c = a.parent_tenant_id;
794
+ for (; c;) {
795
+ if (s.has(c)) throw new T(400, { message: `Tenant chain for '${t}' contains a cycle at '${c}'` });
796
+ if (s.add(c), o.length >= i) throw new T(400, { message: `Tenant chain for '${t}' is deeper than ${i}` });
797
+ let e = await n(c);
798
+ if (!e) break;
799
+ o.push(c), c = e.parent_tenant_id;
800
+ }
801
+ return o;
802
+ }
803
+ //#endregion
804
+ //#region src/inheritance/legacy.ts
805
+ function Oe(e) {
806
+ let t = {};
807
+ for (let n of e ?? []) n.value !== void 0 && (t[n.name] = n.value);
808
+ return t;
809
+ }
810
+ function ke(e, t) {
811
+ if (!e.inherit) return e;
812
+ let n = t.find((t) => t.name === e.name && t.is_system);
813
+ if (!n) return e;
814
+ let r = {
815
+ ...Oe(n.secrets),
816
+ ...Oe(e.secrets)
817
+ };
818
+ return {
819
+ ...e,
820
+ code: n.code,
821
+ secrets: Object.entries(r).map(([e, t]) => ({
822
+ name: e,
823
+ value: t
824
+ }))
825
+ };
826
+ }
827
+ function Ae(e, t) {
828
+ if (!t) return e;
829
+ let n = new Set(e.hooks.map((e) => e.hook_id)), r = t.hooks.filter((e) => X(e) && !n.has(e.hook_id));
830
+ return {
831
+ connections: e.connections.map((e) => q(e, t.connections)),
832
+ resourceServers: e.resourceServers.map((e) => e.is_system ? Y(e, t.resourceServers.find((t) => t.id === e.id) ?? null) : e),
833
+ hooks: [...e.hooks, ...r],
834
+ actions: e.actions.map((e) => ke(e, t.actions)),
835
+ emailProvider: e.emailProvider ?? t.emailProvider,
836
+ branding: e.branding,
837
+ promptSettings: e.promptSettings
838
+ };
839
+ }
840
+ //#endregion
841
+ //#region src/inheritance/types.ts
842
+ var je = () => ({
843
+ connections: [],
844
+ resourceServers: [],
845
+ hooks: [],
846
+ actions: [],
847
+ emailProvider: null,
848
+ branding: null,
849
+ promptSettings: null
850
+ });
851
+ //#endregion
852
+ //#region src/inheritance/merge.ts
853
+ function I(e, t) {
854
+ if (t.scope) return t.scope;
855
+ switch (e) {
856
+ case "connection":
857
+ case "emailProvider": return "shared";
858
+ case "resourceServer":
859
+ case "action": return t.is_system ? "shared" : "local";
860
+ case "hook": return X(t) ? "shared" : "local";
861
+ default: return "local";
862
+ }
863
+ }
864
+ function L(e) {
865
+ return e.override ?? "fields";
866
+ }
867
+ var Me = /secret|password|private_key|api_key|token/i;
868
+ function Ne(e, t) {
869
+ let n = { ...e ?? {} };
870
+ for (let [e, r] of Object.entries(t ?? {})) Me.test(e) && (n[e] = r);
871
+ return n;
872
+ }
873
+ function R(e, t) {
874
+ switch (L(e)) {
875
+ case "none": return {
876
+ ...e,
877
+ id: t.id
878
+ };
879
+ case "secrets": return {
880
+ ...e,
881
+ id: t.id,
882
+ options: Ne(e.options, t.options)
883
+ };
884
+ default: return {
885
+ ...e,
886
+ ...t,
887
+ options: {
888
+ ...e.options ?? {},
889
+ ...t.options ?? {}
890
+ }
891
+ };
892
+ }
893
+ }
894
+ function Pe(e, t) {
895
+ switch (L(e)) {
896
+ case "none": return {
897
+ ...e,
898
+ id: t.id
899
+ };
900
+ case "secrets": return {
901
+ ...e,
902
+ id: t.id,
903
+ signing_secret: t.signing_secret ?? e.signing_secret
904
+ };
905
+ default: return {
906
+ ...t,
907
+ scopes: $e(t.scopes, e.scopes)
908
+ };
909
+ }
910
+ }
911
+ function Fe(e) {
912
+ return new Map((e ?? []).map((e) => [e.name, e]));
913
+ }
914
+ function Ie(e, t) {
915
+ let n = L(e);
916
+ if (n === "none") return {
917
+ ...e,
918
+ id: t.id
919
+ };
920
+ let r = Fe(e.secrets);
921
+ if (n === "secrets" || n === "fields") for (let [e, n] of Fe(t.secrets)) r.set(e, n);
922
+ return {
923
+ ...n === "fields" && !t.inherit ? t : e,
924
+ id: t.id,
925
+ secrets: [...r.values()]
926
+ };
927
+ }
928
+ function Le(e, t) {
929
+ let n = /* @__PURE__ */ new Set(), r = [...e].reverse().concat(t), i = (e, t, r, i) => r ? t : t.filter((t) => {
930
+ let r = I(e, t);
931
+ return r === "local" ? !1 : (r === "platform" && n.add(`${e}:${i(t)}`), !0);
932
+ }), a = je(), o = (e) => `${e.strategy}:${e.name}`, s = (e) => e.identifier, c = (e) => e.hook_id ?? "", l = (e) => e.name, u = /* @__PURE__ */ new Map(), d = [], f = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map();
933
+ r.forEach((e, t) => {
934
+ let h = t === r.length - 1;
935
+ for (let t of i("connection", e.connections, h, o)) {
936
+ let e = u.get(t.strategy);
937
+ h ? d.push(e ? R(e, t) : t) : u.set(t.strategy, e ? R(e, t) : t);
938
+ }
939
+ for (let t of i("resourceServer", e.resourceServers, h, s)) {
940
+ let e = f.get(s(t));
941
+ f.set(s(t), e ? Pe(e, t) : t);
942
+ }
943
+ for (let t of i("hook", e.hooks, h, c)) p.set(c(t), t);
944
+ for (let t of i("action", e.actions, h, l)) {
945
+ let e = m.get(l(t));
946
+ m.set(l(t), e ? Ie(e, t) : t);
947
+ }
948
+ for (let t of [
949
+ "emailProvider",
950
+ "branding",
951
+ "promptSettings"
952
+ ]) {
953
+ let r = e[t];
954
+ r && (h || I(t, r) !== "local") && (!h && I(t, r) === "platform" && n.add(`${t}:singleton`), a[t] = r);
955
+ }
956
+ });
957
+ let h = new Set(r[r.length - 1].connections.map((e) => e.strategy));
958
+ return a.connections = [...d, ...[...u.values()].filter((e) => !h.has(e.strategy))], a.resourceServers = [...f.values()], a.hooks = [...p.values()], a.actions = [...m.values()], {
959
+ ...a,
960
+ hidden: [...n]
961
+ };
962
+ }
963
+ //#endregion
964
+ //#region src/rollout/defaults-projection.ts
965
+ function z(e = {}) {
966
+ return {
967
+ connections: e.connections ?? !0,
968
+ resourceServers: e.resourceServers ?? !0,
969
+ hooks: e.hooks ?? !0,
970
+ emailProvider: e.emailProvider ?? !0,
971
+ branding: e.branding ?? !0,
972
+ promptSettings: e.promptSettings ?? !0
973
+ };
974
+ }
975
+ function B() {
976
+ return {
977
+ upserted: 0,
978
+ errors: []
979
+ };
980
+ }
981
+ function Re(e) {
982
+ return {
983
+ tenantId: e,
984
+ connections: B(),
985
+ resourceServers: B(),
986
+ hooks: B(),
987
+ emailProvider: B(),
988
+ branding: B(),
989
+ promptSettings: B()
990
+ };
991
+ }
992
+ function ze(e) {
993
+ let t = e.metadata;
994
+ return !!(t && t.inheritable === !0);
995
+ }
996
+ async function V(e, t, n, r) {
997
+ try {
998
+ await r();
999
+ } catch (r) {
1000
+ let i = `${t}: ${r instanceof Error ? r.message : String(r)}`;
1001
+ if (!n) throw Error(i, { cause: r });
1002
+ e.errors.push(i);
1003
+ }
1004
+ }
1005
+ async function H(e, t, n) {
1006
+ return {
1007
+ connections: n.connections ? await f((n) => e.connections.list(t, n), "connections", {
1008
+ cursorField: "id",
1009
+ pageSize: 100
1010
+ }) : [],
1011
+ resourceServers: n.resourceServers ? await f((n) => e.resourceServers.list(t, n), "resource_servers", {
1012
+ cursorField: "id",
1013
+ pageSize: 100
1014
+ }) : [],
1015
+ hooks: n.hooks ? await f((n) => e.hooks.list(t, n), "hooks", {
1016
+ cursorField: "hook_id",
1017
+ pageSize: 100
1018
+ }) : [],
1019
+ emailProvider: n.emailProvider ? await e.emailProviders.get(t) ?? null : null,
1020
+ branding: n.branding ? await e.branding.get(t) ?? null : null,
1021
+ promptSettings: n.promptSettings ? await e.promptSettings.get(t) ?? null : null
1022
+ };
1023
+ }
1024
+ async function Be(e, t, n, r, i, a) {
1025
+ if (r.connections) for (let r of e.connections) {
1026
+ let e = r.id;
1027
+ e && await V(a.connections, `connection ${e}`, i, async () => {
1028
+ let i = o.parse(r);
1029
+ await t.connections.get(n, e) ? await t.connections.update(n, e, i) : await t.connections.create(n, i), a.connections.upserted += 1;
1030
+ });
1031
+ }
1032
+ if (r.resourceServers) for (let r of e.resourceServers) !r.is_system || !r.id || await V(a.resourceServers, `resource_server ${r.id}`, i, async () => {
1033
+ let e = y.parse(r);
1034
+ await t.resourceServers.get(n, r.id) ? await t.resourceServers.update(n, r.id, e) : await t.resourceServers.create(n, e), a.resourceServers.upserted += 1;
1035
+ });
1036
+ if (r.hooks) for (let r of e.hooks) !ze(r) || !r.hook_id || await V(a.hooks, `hook ${r.hook_id}`, i, async () => {
1037
+ let e = p.parse(r);
1038
+ await t.hooks.get(n, r.hook_id) ? await t.hooks.update(n, r.hook_id, e) : await t.hooks.create(n, e), a.hooks.upserted += 1;
1039
+ });
1040
+ r.emailProvider && e.emailProvider && await V(a.emailProvider, "email_provider", i, async () => {
1041
+ let r = e.emailProvider;
1042
+ await t.emailProviders.get(n) ? await t.emailProviders.update(n, r) : await t.emailProviders.create(n, r), a.emailProvider.upserted += 1;
1043
+ }), r.branding && e.branding && await V(a.branding, "branding", i, async () => {
1044
+ await t.branding.set(n, e.branding), a.branding.upserted += 1;
1045
+ }), r.promptSettings && e.promptSettings && await V(a.promptSettings, "prompt_settings", i, async () => {
1046
+ await t.promptSettings.set(n, e.promptSettings), a.promptSettings.upserted += 1;
1047
+ });
1048
+ }
1049
+ async function U(e, t) {
1050
+ let { controlPlaneTenantId: n, getControlPlaneAdapters: r, getAdapters: i, entities: a, continueOnError: o = !1 } = e, s = z(a), c = await H(await r(), n, s), l = await i(t), u = Re(t);
1051
+ return await Be(c, l, n, s, o, u), u;
1052
+ }
1053
+ //#endregion
1054
+ //#region src/inheritance/read.ts
1055
+ async function W(e, t) {
1056
+ let n = await H(e, t, {
1057
+ connections: !0,
1058
+ resourceServers: !0,
1059
+ hooks: !0,
1060
+ emailProvider: !0,
1061
+ branding: !0,
1062
+ promptSettings: !0
1063
+ }), r = await f((n) => e.actions.list(t, n), "actions", {
1064
+ cursorField: "id",
1065
+ pageSize: 100
1066
+ });
1067
+ return {
1068
+ ...n,
1069
+ actions: r
1070
+ };
1071
+ }
1072
+ //#endregion
1073
+ //#region src/inheritance/shadow.ts
1074
+ var Ve = /secret|password|private_key|api_key|token/i, He = new Set([
1075
+ "id",
1076
+ "tenant_id",
1077
+ "created_at",
1078
+ "updated_at",
1079
+ "scope",
1080
+ "override",
1081
+ "enforce",
1082
+ "enabled_clients"
1083
+ ]);
1084
+ async function G(e) {
1085
+ let t = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(e));
1086
+ return [...new Uint8Array(t)].map((e) => e.toString(16).padStart(2, "0")).join("").slice(0, 16);
1087
+ }
1088
+ async function K(e, t = "") {
1089
+ if (Array.isArray(e)) {
1090
+ if (t === "secrets") {
1091
+ let t = {};
1092
+ for (let n of e) t[n.name] = n.value === void 0 ? null : `sha256:${await G(n.value)}`;
1093
+ return t;
1094
+ }
1095
+ return Promise.all(e.map((e) => K(e, t)));
1096
+ }
1097
+ if (e && typeof e == "object") {
1098
+ let t = {};
1099
+ for (let n of Object.keys(e).sort()) {
1100
+ let r = e[n];
1101
+ r != null && (t[n] = typeof r == "string" && Ve.test(n) ? `sha256:${await G(r)}` : await K(r, n));
1102
+ }
1103
+ return t;
1104
+ }
1105
+ return e;
1106
+ }
1107
+ async function Ue(e) {
1108
+ let t = {};
1109
+ for (let [n, r] of Object.entries(e)) He.has(n) || (t[n] = r);
1110
+ return await K(t);
1111
+ }
1112
+ var We = {
1113
+ connection: (e) => `${e.strategy}:${e.name}`,
1114
+ resourceServer: (e) => e.identifier,
1115
+ hook: (e) => e.hook_id,
1116
+ action: (e) => e.name
1117
+ }, Ge = new Set([
1118
+ "connection",
1119
+ "resourceServer",
1120
+ "action",
1121
+ "emailProvider",
1122
+ "branding",
1123
+ "promptSettings"
1124
+ ]);
1125
+ async function Ke(e) {
1126
+ let t = /* @__PURE__ */ new Map(), n = async (e, n, r) => {
1127
+ let i = t.get(e) ?? /* @__PURE__ */ new Map();
1128
+ i.set(n, await Ue(r)), t.set(e, i);
1129
+ };
1130
+ for (let [t, r] of Object.entries(We)) {
1131
+ let i = e[{
1132
+ connection: "connections",
1133
+ resourceServer: "resourceServers",
1134
+ hook: "hooks",
1135
+ action: "actions"
1136
+ }[t]];
1137
+ for (let e of i) await n(t, r(e), e);
1138
+ }
1139
+ for (let t of [
1140
+ "emailProvider",
1141
+ "branding",
1142
+ "promptSettings"
1143
+ ]) e[t] && await n(t, "singleton", e[t]);
1144
+ return t;
1145
+ }
1146
+ async function qe(e, t) {
1147
+ let [n, r] = await Promise.all([Ke(e), Ke(t)]), i = [], a = new Set([...n.keys(), ...r.keys()]);
1148
+ for (let e of a) {
1149
+ let t = n.get(e) ?? /* @__PURE__ */ new Map(), a = r.get(e) ?? /* @__PURE__ */ new Map();
1150
+ for (let n of new Set([...t.keys(), ...a.keys()])) {
1151
+ let r = t.get(n), o = a.get(n);
1152
+ if (r && !o) i.push({
1153
+ entity: e,
1154
+ key: n,
1155
+ kind: "missing",
1156
+ fields: [],
1157
+ expected: !1
1158
+ });
1159
+ else if (!r && o) i.push({
1160
+ entity: e,
1161
+ key: n,
1162
+ kind: "extra",
1163
+ fields: [],
1164
+ expected: Ge.has(e)
1165
+ });
1166
+ else if (r && o) {
1167
+ let t = JSON.stringify(r), a = JSON.stringify(o);
1168
+ if (t === a) continue;
1169
+ let s = [...new Set([...Object.keys(r), ...Object.keys(o)])].filter((e) => JSON.stringify(r[e]) !== JSON.stringify(o[e])).sort();
1170
+ i.push({
1171
+ entity: e,
1172
+ key: n,
1173
+ kind: "changed",
1174
+ fields: s,
1175
+ expected: !1,
1176
+ legacy_hash: await G(t),
1177
+ new_hash: await G(a)
1178
+ });
1179
+ }
1180
+ }
1181
+ }
1182
+ return i;
1183
+ }
1184
+ async function Je(e) {
1185
+ let { adapters: t, tenantId: n, legacyControlPlane: r } = e, i = await De({
1186
+ tenantId: n,
1187
+ getTenant: (e) => t.tenants.get(e),
1188
+ legacyControlPlane: r,
1189
+ maxDepth: e.maxDepth
1190
+ }), a = await W(t, n), o = await Promise.all(i.map((e) => W(t, e))), s = r && r !== n ? await W(t, r) : void 0, { hidden: c, ...l } = Le(o, a), u = new Set(c);
1191
+ return (await qe(Ae(a, s), l)).filter((e) => !u.has(`${e.entity}:${e.key}`));
1192
+ }
1193
+ //#endregion
1194
+ //#region src/inheritance/report.ts
1195
+ var Ye = 3600 * 1e3, Xe = 1e4;
1196
+ function Ze(e, t) {
1197
+ let n = t.sample ?? 1, r = t.intervalMs ?? 6e4, i = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Map();
1198
+ async function s(n, r) {
1199
+ let i = await Je({
1200
+ adapters: e,
1201
+ tenantId: n,
1202
+ legacyControlPlane: r
1203
+ }), a = Date.now();
1204
+ o.size > Xe && o.clear();
1205
+ for (let s of i) {
1206
+ if (s.expected && !t.includeExpected) continue;
1207
+ let i = await G([
1208
+ n,
1209
+ s.entity,
1210
+ s.key,
1211
+ s.kind,
1212
+ s.fields.join(",")
1213
+ ].join("|")), c = o.get(i);
1214
+ c !== void 0 && a - c < Ye || (o.set(i, a), await Qe(e, n, s, r));
1215
+ }
1216
+ }
1217
+ return { schedule(e, t) {
1218
+ if (a.has(e) || n < 1 && Math.random() >= n) return;
1219
+ let o = Date.now(), c = i.get(e);
1220
+ c !== void 0 && o - c < r || (i.set(e, o), a.add(e), s(e, t).catch(() => {}).finally(() => a.delete(e)));
1221
+ } };
1222
+ }
1223
+ async function Qe(e, n, r, i) {
1224
+ await e.logs.create(n, {
1225
+ type: t.CONFIG_INHERITANCE_DIFF,
1226
+ date: (/* @__PURE__ */ new Date()).toISOString(),
1227
+ isMobile: !1,
1228
+ description: `${r.kind} ${r.entity} ${r.key}`,
1229
+ details: {
1230
+ shadow: "config-inheritance",
1231
+ legacy_control_plane: i,
1232
+ ...r
1233
+ }
1234
+ });
1235
+ }
1236
+ //#endregion
756
1237
  //#region src/middleware/settings-inheritance.ts
757
- function W(e, t) {
1238
+ function q(e, t) {
758
1239
  let n = t.find((t) => t.strategy === e.strategy);
759
1240
  if (!n?.options) return e;
760
- let r = s.passthrough().parse({
1241
+ let r = c.passthrough().parse({
761
1242
  ...n,
762
1243
  ...e
763
1244
  });
764
- return r.options = o.passthrough().parse({
1245
+ return r.options = s.passthrough().parse({
765
1246
  ...n.options || {},
766
1247
  ...e.options
767
1248
  }), r;
768
1249
  }
769
- function G(e, t) {
1250
+ function J(e, t) {
770
1251
  let n = [...t || [], ...e || []];
771
1252
  return [...new Set(n)];
772
1253
  }
773
- function _e(e, t) {
1254
+ function $e(e, t) {
774
1255
  if (!t?.length) return e || [];
775
1256
  if (!e?.length) return t;
776
1257
  let n = /* @__PURE__ */ new Map();
@@ -778,22 +1259,22 @@ function _e(e, t) {
778
1259
  for (let t of e) n.set(t.value, t);
779
1260
  return Array.from(n.values());
780
1261
  }
781
- function ve(e, t) {
1262
+ function Y(e, t) {
782
1263
  return t ? {
783
1264
  ...e,
784
- scopes: _e(e.scopes, t.scopes)
1265
+ scopes: $e(e.scopes, t.scopes)
785
1266
  } : e;
786
1267
  }
787
- function ye(e, t) {
1268
+ function et(e, t) {
788
1269
  return t ? {
789
1270
  ...e,
790
- callbacks: G(e.callbacks, t.callbacks),
791
- web_origins: G(e.web_origins, t.web_origins),
792
- allowed_logout_urls: G(e.allowed_logout_urls, t.allowed_logout_urls),
793
- allowed_origins: G(e.allowed_origins, t.allowed_origins)
1271
+ callbacks: J(e.callbacks, t.callbacks),
1272
+ web_origins: J(e.web_origins, t.web_origins),
1273
+ allowed_logout_urls: J(e.allowed_logout_urls, t.allowed_logout_urls),
1274
+ allowed_origins: J(e.allowed_origins, t.allowed_origins)
794
1275
  } : e;
795
1276
  }
796
- function be(e) {
1277
+ function tt(e) {
797
1278
  let { controlPlaneTenantId: t, controlPlaneClientId: n, resolveControlPlane: r } = e;
798
1279
  if (r) return async (e) => r({ tenant_id: e });
799
1280
  if (!t) return async () => void 0;
@@ -803,14 +1284,14 @@ function be(e) {
803
1284
  };
804
1285
  return async () => i;
805
1286
  }
806
- function xe(e, t) {
1287
+ function nt(e, t) {
807
1288
  return {
808
1289
  ...e.resourceServers,
809
1290
  get: async (n, r) => {
810
1291
  let i = await e.resourceServers.get(n, r);
811
1292
  if (!i) return i;
812
1293
  let a = await t(n);
813
- return !a || n === a.tenantId || !i.is_system ? i : ve(i, await e.resourceServers.get(a.tenantId, r));
1294
+ return !a || n === a.tenantId || !i.is_system ? i : Y(i, await e.resourceServers.get(a.tenantId, r));
814
1295
  },
815
1296
  list: async (n, r) => {
816
1297
  let i = await e.resourceServers.list(n, r), a = await t(n);
@@ -822,7 +1303,7 @@ function xe(e, t) {
822
1303
  let n = await e.resourceServers.get(o, t);
823
1304
  n && c.set(t, n);
824
1305
  }));
825
- let l = i.resource_servers.map((e) => e.is_system && e.id ? ve(e, c.get(e.id) ?? null) : e);
1306
+ let l = i.resource_servers.map((e) => e.is_system && e.id ? Y(e, c.get(e.id) ?? null) : e);
826
1307
  return {
827
1308
  ...i,
828
1309
  resource_servers: l
@@ -830,22 +1311,25 @@ function xe(e, t) {
830
1311
  }
831
1312
  };
832
1313
  }
833
- function Se(e, t) {
834
- let n = be({
1314
+ function rt(e, t) {
1315
+ let n = tt({
835
1316
  controlPlaneTenantId: t.controlPlaneTenantId,
836
1317
  resolveControlPlane: t.resolveControlPlane
837
1318
  });
838
1319
  return {
839
1320
  ...e,
840
- resourceServers: xe(e, n)
1321
+ resourceServers: nt(e, n)
841
1322
  };
842
1323
  }
843
- function Ce(e, t) {
844
- let { controlPlaneTenantId: n, controlPlaneClientId: r, resolveControlPlane: i } = t, a = be({
1324
+ function it(e, t) {
1325
+ let { controlPlaneTenantId: n, controlPlaneClientId: r, resolveControlPlane: i, inheritanceShadow: a } = t, o = tt({
845
1326
  controlPlaneTenantId: n,
846
1327
  controlPlaneClientId: r,
847
1328
  resolveControlPlane: i
848
- });
1329
+ }), s = a ? Ze(e, a === !0 ? {} : a) : void 0, c = s ? async (e) => {
1330
+ let t = await o(e);
1331
+ return s.schedule(e, t?.tenantId), t;
1332
+ } : o;
849
1333
  return {
850
1334
  ...e,
851
1335
  multiTenancyConfig: {
@@ -858,16 +1342,16 @@ function Ce(e, t) {
858
1342
  get: async (t, n) => {
859
1343
  let r = await e.connections.get(t, n);
860
1344
  if (!r) return r;
861
- let i = await a(t);
862
- return !i || t === i.tenantId ? r : W(r, (await e.connections.list(i.tenantId)).connections || []);
1345
+ let i = await c(t);
1346
+ return !i || t === i.tenantId ? r : q(r, (await e.connections.list(i.tenantId)).connections || []);
863
1347
  },
864
1348
  list: async (t, n) => {
865
- let r = await e.connections.list(t, n), i = await a(t);
1349
+ let r = await e.connections.list(t, n), i = await c(t);
866
1350
  if (!i || t === i.tenantId) return r;
867
- let o = await e.connections.list(i.tenantId), s = r.connections.map((e) => W(e, o.connections || []));
1351
+ let a = await e.connections.list(i.tenantId), o = r.connections.map((e) => q(e, a.connections || []));
868
1352
  return {
869
1353
  ...r,
870
- connections: s
1354
+ connections: o
871
1355
  };
872
1356
  }
873
1357
  },
@@ -876,10 +1360,10 @@ function Ce(e, t) {
876
1360
  listByClient: async (t, n) => {
877
1361
  let r = await e.clientConnections.listByClient(t, n);
878
1362
  r.length === 0 && (r = (await e.connections.list(t)).connections || []);
879
- let i = await a(t);
1363
+ let i = await c(t);
880
1364
  if (!i || t === i.tenantId) return r;
881
- let o = await e.connections.list(i.tenantId);
882
- return r.map((e) => W(e, o.connections || []));
1365
+ let a = await e.connections.list(i.tenantId);
1366
+ return r.map((e) => q(e, a.connections || []));
883
1367
  }
884
1368
  },
885
1369
  emailProviders: {
@@ -887,26 +1371,26 @@ function Ce(e, t) {
887
1371
  get: async (t) => {
888
1372
  let n = await e.emailProviders.get(t);
889
1373
  if (n) return n;
890
- let r = await a(t);
1374
+ let r = await c(t);
891
1375
  return !r || t === r.tenantId ? null : e.emailProviders.get(r.tenantId);
892
1376
  }
893
1377
  },
894
- resourceServers: xe(e, a),
895
- hooks: Te(e, a)
1378
+ resourceServers: nt(e, c),
1379
+ hooks: at(e, c)
896
1380
  };
897
1381
  }
898
- function we(e) {
1382
+ function X(e) {
899
1383
  if (!e || typeof e != "object") return !1;
900
1384
  let t = e.metadata;
901
1385
  return !t || typeof t != "object" ? !1 : t.inheritable === !0;
902
1386
  }
903
- function Te(e, t) {
1387
+ function at(e, t) {
904
1388
  return {
905
1389
  ...e.hooks,
906
1390
  list: async (n, r) => {
907
1391
  let i = await e.hooks.list(n, r), a = await t(n);
908
1392
  if (!a || n === a.tenantId) return i;
909
- let o = ((await e.hooks.list(a.tenantId, r)).hooks || []).filter(we);
1393
+ let o = ((await e.hooks.list(a.tenantId, r)).hooks || []).filter(X);
910
1394
  if (o.length === 0) return i;
911
1395
  let s = new Set((i.hooks || []).map((e) => e.hook_id)), c = o.filter((e) => !s.has(e.hook_id));
912
1396
  return {
@@ -921,31 +1405,31 @@ function Te(e, t) {
921
1405
  let a = await t(n);
922
1406
  if (!a || n === a.tenantId) return i;
923
1407
  let o = await e.hooks.get(a.tenantId, r);
924
- return o && we(o) ? o : null;
1408
+ return o && X(o) ? o : null;
925
1409
  }
926
1410
  };
927
1411
  }
928
- function K(e, t) {
929
- return Ce(e, t);
1412
+ function Z(e, t) {
1413
+ return it(e, t);
930
1414
  }
931
1415
  //#endregion
932
1416
  //#region src/middleware/index.ts
933
- function Ee(e) {
1417
+ function ot(e) {
934
1418
  return async (t, n) => {
935
1419
  let r = t.var.user;
936
1420
  return r?.tenant_id === e && r.org_name && t.set("tenant_id", r.org_name), n();
937
1421
  };
938
1422
  }
939
- function De(e) {
940
- return async (n, r) => {
1423
+ function st(e) {
1424
+ return async (t, r) => {
941
1425
  if (!e.accessControl) return r();
942
- let { controlPlaneTenantId: i } = e.accessControl, a = n.var.org_name, o = n.var.organization_id, s = a || o, c = n.var.tenant_id, l = n.var.user, u = (l?.aud ? Array.isArray(l.aud) ? l.aud : [l.aud] : []).includes(t);
943
- if (!c && s && u && (n.set("tenant_id", s), c = s), !c) throw new w(400, { message: "Tenant ID not found in request" });
944
- if (!E(o, c, i, a)) throw new w(403, { message: `Access denied to tenant ${c}` });
1426
+ let { controlPlaneTenantId: i } = e.accessControl, a = t.var.org_name, o = t.var.organization_id, s = a || o, c = t.var.tenant_id, l = t.var.user, u = (l?.aud ? Array.isArray(l.aud) ? l.aud : [l.aud] : []).includes(n);
1427
+ if (!c && s && u && (t.set("tenant_id", s), c = s), !c) throw new T(400, { message: "Tenant ID not found in request" });
1428
+ if (!D(o, c, i, a)) throw new T(403, { message: `Access denied to tenant ${c}` });
945
1429
  return r();
946
1430
  };
947
1431
  }
948
- function Oe(e) {
1432
+ function ct(e) {
949
1433
  return async (t, n) => {
950
1434
  if (!e.subdomainRouting) return n();
951
1435
  let { baseDomain: r, reservedSubdomains: i = [], resolveSubdomain: a } = e.subdomainRouting, o = t.req.header("x-forwarded-host") || t.req.header("host") || "", s = null;
@@ -957,18 +1441,18 @@ function Oe(e) {
957
1441
  let c = null;
958
1442
  if (a) c = await a(s);
959
1443
  else if (e.subdomainRouting.useOrganizations !== !1 && e.accessControl) try {
960
- let n = await V(t).organizations.get(e.accessControl.controlPlaneTenantId, s);
1444
+ let n = await P(t).organizations.get(e.accessControl.controlPlaneTenantId, s);
961
1445
  n && (c = n.id);
962
1446
  } catch {}
963
- if (!c) throw new w(404, { message: `Tenant not found for subdomain: ${s}` });
1447
+ if (!c) throw new T(404, { message: `Tenant not found for subdomain: ${s}` });
964
1448
  return t.set("tenant_id", c), n();
965
1449
  };
966
1450
  }
967
- function ke(e) {
1451
+ function lt(e) {
968
1452
  return async (t, n) => {
969
1453
  if (!e.databaseIsolation) return n();
970
1454
  let r = t.var.tenant_id;
971
- if (!r) throw new w(400, { message: "Tenant ID not found in request" });
1455
+ if (!r) throw new T(400, { message: "Tenant ID not found in request" });
972
1456
  try {
973
1457
  let n = await e.databaseIsolation.getAdapters(r);
974
1458
  t.set("baseData", n), t.env = {
@@ -976,30 +1460,31 @@ function ke(e) {
976
1460
  data: n
977
1461
  };
978
1462
  } catch (e) {
979
- throw console.error(`Failed to resolve database for tenant ${r}:`, e), new w(500, { message: "Failed to resolve tenant database" });
1463
+ throw console.error(`Failed to resolve database for tenant ${r}:`, e), new T(500, { message: "Failed to resolve tenant database" });
980
1464
  }
981
1465
  return n();
982
1466
  };
983
1467
  }
984
- function q(e) {
985
- let t = Oe(e), n = De(e), r = ke(e);
1468
+ function Q(e) {
1469
+ let t = ct(e), n = st(e), r = lt(e);
986
1470
  return async (e, i) => (await t(e, async () => {}), await n(e, async () => {}), await r(e, async () => {}), i());
987
1471
  }
988
1472
  //#endregion
989
1473
  //#region src/init.ts
990
- function Ae(e) {
991
- let { dataAdapter: t, controlPlane: n, controlPlane: { tenantId: r = "control_plane", clientId: i } = {}, resolveControlPlane: a, sync: o = {
1474
+ function ut(e) {
1475
+ let { dataAdapter: t, controlPlane: n, controlPlane: { tenantId: r = "control_plane", clientId: i } = {}, resolveControlPlane: a, inheritanceShadow: o, sync: s = {
992
1476
  resourceServers: !0,
993
1477
  roles: !0
994
- }, defaultPermissions: s = ["tenant:admin"], requireOrganizationMatch: c = !1, managementApiExtensions: l = [], entityHooks: u, getChildTenantIds: f, getAdapters: m, ...h } = e;
1478
+ }, defaultPermissions: c = ["tenant:admin"], requireOrganizationMatch: l = !1, managementApiExtensions: u = [], entityHooks: d, getChildTenantIds: p, getAdapters: h, ...g } = e;
995
1479
  if (a && !n) throw Error("initMultiTenant: `resolveControlPlane` requires `controlPlane` to be set. The static `controlPlane.tenantId` is used for access control, sync direction, and tenant management routing; the resolver only overrides per-tenant runtime inheritance lookups on top of it.");
996
- let g = t, _ = t;
997
- n && (g = K(t, {
1480
+ let _ = t, v = t;
1481
+ n && (_ = Z(t, {
998
1482
  controlPlaneTenantId: r,
999
1483
  controlPlaneClientId: i,
1000
- resolveControlPlane: a
1001
- }), _ = {
1002
- ...Se(t, {
1484
+ resolveControlPlane: a,
1485
+ inheritanceShadow: o
1486
+ }), v = {
1487
+ ...rt(t, {
1003
1488
  controlPlaneTenantId: r,
1004
1489
  resolveControlPlane: a
1005
1490
  }),
@@ -1009,12 +1494,12 @@ function Ae(e) {
1009
1494
  resolveControlPlane: a
1010
1495
  }
1011
1496
  });
1012
- let v = h.tenantOperationExecutor;
1013
- if (!v && t.tenantOperations && t.tenantOperationEvents && h.tenantUpgrade) {
1497
+ let y = g.tenantOperationExecutor;
1498
+ if (!y && t.tenantOperations && t.tenantOperationEvents && g.tenantUpgrade) {
1014
1499
  let e = {
1015
1500
  tenantOperations: t.tenantOperations,
1016
1501
  tenantOperationEvents: t.tenantOperationEvents
1017
- }, n = h.tenantUpgrade, r = ne({
1502
+ }, n = g.tenantUpgrade, r = ie({
1018
1503
  stores: e,
1019
1504
  definitions: { upgrade: (e) => [{
1020
1505
  name: "upgrade",
@@ -1024,172 +1509,82 @@ function Ae(e) {
1024
1509
  }
1025
1510
  }] }
1026
1511
  });
1027
- v = {
1512
+ y = {
1028
1513
  engine: r.engine,
1029
- enqueue: (t) => ie(e, r, {
1514
+ enqueue: (t) => oe(e, r, {
1030
1515
  ...t,
1031
1516
  tenant_id: t.tenant_id
1032
1517
  })
1033
1518
  };
1034
1519
  }
1035
- let y = o !== !1, b = y ? {
1036
- resourceServers: o.resourceServers ?? !0,
1037
- roles: o.roles ?? !0
1520
+ let b = s !== !1, x = b ? {
1521
+ resourceServers: s.resourceServers ?? !0,
1522
+ roles: s.roles ?? !0
1038
1523
  } : {
1039
1524
  resourceServers: !1,
1040
1525
  roles: !1
1041
- }, { entityHooks: x, tenantHooks: S } = B({
1526
+ }, { entityHooks: S, tenantHooks: C } = ve({
1042
1527
  controlPlaneTenantId: r,
1043
- getChildTenantIds: f ?? (async () => (await d((e) => g.tenants.list(e), "tenants", {
1528
+ getChildTenantIds: p ?? (async () => (await f((e) => _.tenants.list(e), "tenants", {
1044
1529
  cursorField: "id",
1045
1530
  pageSize: 100
1046
1531
  })).filter((e) => e.id !== r).map((e) => e.id)),
1047
- getAdapters: m ?? (async () => g),
1048
- getControlPlaneAdapters: async () => g,
1049
- sync: b
1050
- }), C = {
1051
- resourceServers: [x.resourceServers, ...u?.resourceServers ?? []],
1052
- roles: [x.roles, ...u?.roles ?? []],
1053
- connections: u?.connections ?? [],
1054
- tenants: u?.tenants ?? [],
1055
- rolePermissions: u?.rolePermissions ?? []
1056
- }, w = P({ accessControl: {
1532
+ getAdapters: h ?? (async () => _),
1533
+ getControlPlaneAdapters: async () => _,
1534
+ sync: x
1535
+ }), w = {
1536
+ resourceServers: [S.resourceServers, ...d?.resourceServers ?? []],
1537
+ roles: [S.roles, ...d?.roles ?? []],
1538
+ connections: d?.connections ?? [],
1539
+ tenants: d?.tenants ?? [],
1540
+ rolePermissions: d?.rolePermissions ?? []
1541
+ }, T = N({ accessControl: {
1057
1542
  controlPlaneTenantId: r,
1058
- requireOrganizationMatch: c,
1059
- defaultPermissions: s
1060
- } }), T = H({ accessControl: {
1543
+ requireOrganizationMatch: l,
1544
+ defaultPermissions: c
1545
+ } }), E = F({ accessControl: {
1061
1546
  controlPlaneTenantId: r,
1062
- requireOrganizationMatch: c,
1063
- defaultPermissions: s
1547
+ requireOrganizationMatch: l,
1548
+ defaultPermissions: c
1064
1549
  } }, { tenants: {
1065
1550
  async beforeCreate(e, t) {
1066
- return w.beforeCreate && (t = await w.beforeCreate(e, t)), S.beforeCreate && (t = await S.beforeCreate(e, t)), t;
1551
+ return T.beforeCreate && (t = await T.beforeCreate(e, t)), C.beforeCreate && (t = await C.beforeCreate(e, t)), t;
1067
1552
  },
1068
1553
  async afterCreate(e, t) {
1069
- await w.afterCreate?.(e, t), await S.afterCreate?.(e, t);
1554
+ await T.afterCreate?.(e, t), await C.afterCreate?.(e, t);
1070
1555
  },
1071
1556
  async beforeDelete(e, t) {
1072
- await w.beforeDelete?.(e, t), await S.beforeDelete?.(e, t);
1557
+ await T.beforeDelete?.(e, t), await C.beforeDelete?.(e, t);
1073
1558
  }
1074
- } }), { app: E } = p({
1075
- dataAdapter: g,
1076
- managementDataAdapter: _,
1077
- ...h,
1078
- tenantOperationExecutor: v,
1079
- entityHooks: C,
1080
- managementApiExtensions: [...l, {
1559
+ } }), { app: D } = m({
1560
+ dataAdapter: _,
1561
+ managementDataAdapter: v,
1562
+ ...g,
1563
+ tenantOperationExecutor: y,
1564
+ entityHooks: w,
1565
+ managementApiExtensions: [...u, {
1081
1566
  path: "/tenants",
1082
- router: T
1567
+ router: E
1083
1568
  }],
1084
- managementApiMiddleware: [...h.managementApiMiddleware ?? [], ...y ? [U()] : []]
1569
+ managementApiMiddleware: [...g.managementApiMiddleware ?? [], ...b ? [Ee()] : []]
1085
1570
  });
1086
1571
  return {
1087
- app: E,
1572
+ app: D,
1088
1573
  controlPlaneTenantId: r
1089
1574
  };
1090
1575
  }
1091
1576
  //#endregion
1092
- //#region src/rollout/defaults-projection.ts
1093
- function J(e = {}) {
1094
- return {
1095
- connections: e.connections ?? !0,
1096
- resourceServers: e.resourceServers ?? !0,
1097
- hooks: e.hooks ?? !0,
1098
- emailProvider: e.emailProvider ?? !0,
1099
- branding: e.branding ?? !0,
1100
- promptSettings: e.promptSettings ?? !0
1101
- };
1102
- }
1103
- function Y() {
1104
- return {
1105
- upserted: 0,
1106
- errors: []
1107
- };
1108
- }
1109
- function je(e) {
1110
- return {
1111
- tenantId: e,
1112
- connections: Y(),
1113
- resourceServers: Y(),
1114
- hooks: Y(),
1115
- emailProvider: Y(),
1116
- branding: Y(),
1117
- promptSettings: Y()
1118
- };
1119
- }
1120
- function Me(e) {
1121
- let t = e.metadata;
1122
- return !!(t && t.inheritable === !0);
1123
- }
1124
- async function X(e, t, n, r) {
1125
- try {
1126
- await r();
1127
- } catch (r) {
1128
- let i = `${t}: ${r instanceof Error ? r.message : String(r)}`;
1129
- if (!n) throw Error(i, { cause: r });
1130
- e.errors.push(i);
1131
- }
1132
- }
1133
- async function Ne(e, t, n) {
1134
- return {
1135
- connections: n.connections ? await d((n) => e.connections.list(t, n), "connections", {
1136
- cursorField: "id",
1137
- pageSize: 100
1138
- }) : [],
1139
- resourceServers: n.resourceServers ? await d((n) => e.resourceServers.list(t, n), "resource_servers", {
1140
- cursorField: "id",
1141
- pageSize: 100
1142
- }) : [],
1143
- hooks: n.hooks ? await d((n) => e.hooks.list(t, n), "hooks", {
1144
- cursorField: "hook_id",
1145
- pageSize: 100
1146
- }) : [],
1147
- emailProvider: n.emailProvider ? await e.emailProviders.get(t) ?? null : null,
1148
- branding: n.branding ? await e.branding.get(t) ?? null : null,
1149
- promptSettings: n.promptSettings ? await e.promptSettings.get(t) ?? null : null
1150
- };
1151
- }
1152
- async function Pe(e, t, n, r, i, o) {
1153
- if (r.connections) for (let r of e.connections) {
1154
- let e = r.id;
1155
- e && await X(o.connections, `connection ${e}`, i, async () => {
1156
- let i = a.parse(r);
1157
- await t.connections.get(n, e) ? await t.connections.update(n, e, i) : await t.connections.create(n, i), o.connections.upserted += 1;
1158
- });
1159
- }
1160
- if (r.resourceServers) for (let r of e.resourceServers) !r.is_system || !r.id || await X(o.resourceServers, `resource_server ${r.id}`, i, async () => {
1161
- let e = v.parse(r);
1162
- await t.resourceServers.get(n, r.id) ? await t.resourceServers.update(n, r.id, e) : await t.resourceServers.create(n, e), o.resourceServers.upserted += 1;
1163
- });
1164
- if (r.hooks) for (let r of e.hooks) !Me(r) || !r.hook_id || await X(o.hooks, `hook ${r.hook_id}`, i, async () => {
1165
- let e = f.parse(r);
1166
- await t.hooks.get(n, r.hook_id) ? await t.hooks.update(n, r.hook_id, e) : await t.hooks.create(n, e), o.hooks.upserted += 1;
1167
- });
1168
- r.emailProvider && e.emailProvider && await X(o.emailProvider, "email_provider", i, async () => {
1169
- let r = e.emailProvider;
1170
- await t.emailProviders.get(n) ? await t.emailProviders.update(n, r) : await t.emailProviders.create(n, r), o.emailProvider.upserted += 1;
1171
- }), r.branding && e.branding && await X(o.branding, "branding", i, async () => {
1172
- await t.branding.set(n, e.branding), o.branding.upserted += 1;
1173
- }), r.promptSettings && e.promptSettings && await X(o.promptSettings, "prompt_settings", i, async () => {
1174
- await t.promptSettings.set(n, e.promptSettings), o.promptSettings.upserted += 1;
1175
- });
1176
- }
1177
- async function Z(e, t) {
1178
- let { controlPlaneTenantId: n, getControlPlaneAdapters: r, getAdapters: i, entities: a, continueOnError: o = !1 } = e, s = J(a), c = await Ne(await r(), n, s), l = await i(t), u = je(t);
1179
- return await Pe(c, l, n, s, o, u), u;
1180
- }
1181
- //#endregion
1182
1577
  //#region src/rollout/payload.ts
1183
- function Fe(e) {
1578
+ function dt(e) {
1184
1579
  let { pkcs7: t, tenant_id: n, ...r } = e;
1185
1580
  return r;
1186
1581
  }
1187
- async function Ie(e, t, n = {}, r) {
1188
- let i = J(n), a = n.signingKeys ?? !0, o = n.tenants ?? !0, s = await Ne(e, t, i), c = a ? (await h(e.keys)).map(Fe) : [], l = o ? await Le(e, t, r) : [];
1582
+ async function ft(e, t, n = {}, r) {
1583
+ let i = z(n), a = n.signingKeys ?? !0, o = n.tenants ?? !0, s = await H(e, t, i), c = a ? (await g(e.keys)).map(dt) : [], l = o ? await pt(e, t, r) : [];
1189
1584
  return {
1190
1585
  connections: s.connections,
1191
1586
  resourceServers: s.resourceServers.filter((e) => e.is_system),
1192
- hooks: s.hooks.filter(Me),
1587
+ hooks: s.hooks.filter(ze),
1193
1588
  emailProvider: s.emailProvider,
1194
1589
  branding: s.branding,
1195
1590
  promptSettings: s.promptSettings,
@@ -1197,7 +1592,7 @@ async function Ie(e, t, n = {}, r) {
1197
1592
  tenants: l
1198
1593
  };
1199
1594
  }
1200
- async function Le(e, t, n) {
1595
+ async function pt(e, t, n) {
1201
1596
  let r = n && n !== t ? [t, n] : [t], i = [];
1202
1597
  for (let t of r) {
1203
1598
  let n = await e.tenants.get(t);
@@ -1208,19 +1603,19 @@ async function Le(e, t, n) {
1208
1603
  }
1209
1604
  return i;
1210
1605
  }
1211
- async function Re(e, t, n) {
1212
- let r = Y();
1606
+ async function mt(e, t, n) {
1607
+ let r = B();
1213
1608
  if (e.length === 0) return r;
1214
- let i = await h(t.keys), a = new Set(i.map((e) => e.kid));
1215
- for (let i of e) await X(r, `signing_key ${i.kid}`, n, async () => {
1216
- let e = Fe(i);
1609
+ let i = await g(t.keys), a = new Set(i.map((e) => e.kid));
1610
+ for (let i of e) await V(r, `signing_key ${i.kid}`, n, async () => {
1611
+ let e = dt(i);
1217
1612
  a.has(e.kid) || (await t.keys.create(e), a.add(e.kid), r.upserted += 1);
1218
1613
  });
1219
1614
  return r;
1220
1615
  }
1221
- async function ze(e, t, n) {
1222
- let r = Y();
1223
- for (let i of e) await X(r, `tenant ${i.id}`, n, async () => {
1616
+ async function ht(e, t, n) {
1617
+ let r = B();
1618
+ for (let i of e) await V(r, `tenant ${i.id}`, n, async () => {
1224
1619
  await t.tenants.get(i.id) || (await t.tenants.create({
1225
1620
  id: i.id,
1226
1621
  friendly_name: i.friendly_name
@@ -1228,17 +1623,17 @@ async function ze(e, t, n) {
1228
1623
  });
1229
1624
  return r;
1230
1625
  }
1231
- async function Be(e, t, n, r = {}) {
1232
- let a = r.continueOnError ?? !1, o = J(r.entities), s = r.entities?.signingKeys ?? !0, c = r.entities?.tenants ?? !0, u = {
1626
+ async function gt(e, t, n, r = {}) {
1627
+ let i = r.continueOnError ?? !1, o = z(r.entities), s = r.entities?.signingKeys ?? !0, c = r.entities?.tenants ?? !0, l = {
1233
1628
  connections: e.connections,
1234
1629
  resourceServers: e.resourceServers,
1235
1630
  hooks: e.hooks,
1236
- emailProvider: e.emailProvider ? l.parse(e.emailProvider) : null,
1237
- branding: e.branding ? i.parse(e.branding) : null,
1238
- promptSettings: e.promptSettings ? g.parse(e.promptSettings) : null
1239
- }, d = c ? await ze(e.tenants ?? [], t, a) : Y(), f = je(n);
1240
- await Pe(u, t, n, o, a, f);
1241
- let p = s ? await Re(e.signingKeys, t, a) : Y();
1631
+ emailProvider: e.emailProvider ? u.parse(e.emailProvider) : null,
1632
+ branding: e.branding ? a.parse(e.branding) : null,
1633
+ promptSettings: e.promptSettings ? _.parse(e.promptSettings) : null
1634
+ }, d = c ? await ht(e.tenants ?? [], t, i) : B(), f = Re(n);
1635
+ await Be(l, t, n, o, i, f);
1636
+ let p = s ? await mt(e.signingKeys, t, i) : B();
1242
1637
  return {
1243
1638
  ...f,
1244
1639
  signingKeys: p,
@@ -1247,27 +1642,27 @@ async function Be(e, t, n, r = {}) {
1247
1642
  }
1248
1643
  //#endregion
1249
1644
  //#region src/rollout/index.ts
1250
- function Ve(e) {
1645
+ function _t(e) {
1251
1646
  return {
1252
- syncDefaults: (t) => Z(e, t),
1647
+ syncDefaults: (t) => U(e, t),
1253
1648
  syncDefaultsToTenants: async (t) => {
1254
1649
  let n = [];
1255
- for (let r of t) n.push(await Z(e, r));
1650
+ for (let r of t) n.push(await U(e, r));
1256
1651
  return n;
1257
1652
  }
1258
1653
  };
1259
1654
  }
1260
1655
  //#endregion
1261
1656
  //#region src/plugin.ts
1262
- function He(e) {
1263
- let t = Q(e);
1657
+ function vt(e) {
1658
+ let t = $(e);
1264
1659
  return {
1265
1660
  name: "multi-tenancy",
1266
- middleware: q(e),
1661
+ middleware: Q(e),
1267
1662
  hooks: t,
1268
1663
  routes: [{
1269
1664
  path: "/management",
1270
- handler: H(e, t)
1665
+ handler: F(e, t)
1271
1666
  }],
1272
1667
  onRegister: async () => {
1273
1668
  console.log("Multi-tenancy plugin registered"), e.accessControl && console.log(` - Access control enabled (control plane: ${e.accessControl.controlPlaneTenantId})`), e.subdomainRouting && console.log(` - Subdomain routing enabled (base domain: ${e.subdomainRouting.baseDomain})`), e.databaseIsolation && console.log(" - Database isolation enabled");
@@ -1276,29 +1671,29 @@ function He(e) {
1276
1671
  }
1277
1672
  //#endregion
1278
1673
  //#region src/index.ts
1279
- function Q(e) {
1280
- let t = e.accessControl ? T(e.accessControl) : {}, n = e.databaseIsolation ? D(e.databaseIsolation) : {}, r = P(e);
1674
+ function $(e) {
1675
+ let t = e.accessControl ? E(e.accessControl) : {}, n = e.databaseIsolation ? ee(e.databaseIsolation) : {}, r = N(e);
1281
1676
  return {
1282
1677
  ...t,
1283
1678
  ...n,
1284
1679
  tenants: r
1285
1680
  };
1286
1681
  }
1287
- function $(t) {
1288
- let n = new e(), r = Q(t);
1289
- return n.route("/tenants", H(t, r)), n;
1682
+ function yt(t) {
1683
+ let n = new e(), r = $(t);
1684
+ return n.route("/tenants", F(t, r)), n;
1290
1685
  }
1291
- function Ue(e) {
1686
+ function bt(e) {
1292
1687
  return {
1293
- hooks: Q(e),
1294
- middleware: q(e),
1295
- app: $(e),
1688
+ hooks: $(e),
1689
+ middleware: Q(e),
1690
+ app: yt(e),
1296
1691
  config: e,
1297
- wrapAdapters: (t, n) => K(t, {
1692
+ wrapAdapters: (t, n) => Z(t, {
1298
1693
  controlPlaneTenantId: e.accessControl?.controlPlaneTenantId,
1299
1694
  controlPlaneClientId: n?.controlPlaneClientId
1300
1695
  })
1301
1696
  };
1302
1697
  }
1303
1698
  //#endregion
1304
- export { Be as applyControlPlaneDefaultsPayload, Ie as buildControlPlaneDefaultsPayload, A as buildEngineInstanceId, T as createAccessControlHooks, De as createAccessControlMiddleware, Ee as createControlPlaneTenantMiddleware, D as createDatabaseHooks, ke as createDatabaseMiddleware, Ve as createDirectRolloutAdapter, ne as createInlineExecutor, $ as createMultiTenancy, Q as createMultiTenancyHooks, q as createMultiTenancyMiddleware, He as createMultiTenancyPlugin, M as createOperationRecorder, U as createProtectSyncedMiddleware, P as createProvisioningHooks, Ce as createRuntimeFallbackAdapter, Oe as createSubdomainMiddleware, B as createSyncHooks, H as createTenantsOpenAPIRouter, ie as enqueueTenantOperation, j as errorToMessage, Ae as initMultiTenant, te as inlineStepRunner, N as isTerminalStatus, ye as mergeClientWithFallback, Z as projectControlPlaneDefaults, oe as runRecordedTenantOperation, Ue as setupMultiTenancy, E as validateTenantAccess, K as withRuntimeFallback, Se as withSystemResourceServerInheritance };
1699
+ export { gt as applyControlPlaneDefaultsPayload, ft as buildControlPlaneDefaultsPayload, A as buildEngineInstanceId, Je as compareShadow, Ae as computeLegacyConfig, E as createAccessControlHooks, st as createAccessControlMiddleware, ot as createControlPlaneTenantMiddleware, ee as createDatabaseHooks, lt as createDatabaseMiddleware, _t as createDirectRolloutAdapter, ie as createInlineExecutor, yt as createMultiTenancy, $ as createMultiTenancyHooks, Q as createMultiTenancyMiddleware, vt as createMultiTenancyPlugin, M as createOperationRecorder, Ee as createProtectSyncedMiddleware, N as createProvisioningHooks, it as createRuntimeFallbackAdapter, Ze as createShadowReporter, ct as createSubdomainMiddleware, ve as createSyncHooks, F as createTenantsOpenAPIRouter, qe as diffConfig, L as effectiveOverride, I as effectiveScope, oe as enqueueTenantOperation, j as errorToMessage, ut as initMultiTenant, re as inlineStepRunner, ne as isTerminalStatus, et as mergeClientWithFallback, Le as mergeConfig, U as projectControlPlaneDefaults, W as readConfigRows, De as resolveTenantChain, ce as runRecordedTenantOperation, bt as setupMultiTenancy, D as validateTenantAccess, Z as withRuntimeFallback, rt as withSystemResourceServerInheritance };