@authhero/multi-tenancy 15.1.1 → 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,47 +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()
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()
532
556
  }) } },
533
557
  description: "List of tenants"
534
558
  } }
535
559
  }), async (t) => {
536
560
  let { page: n, per_page: r, include_totals: i, q: a } = t.req.valid("query"), o = t.var.user, s = o?.permissions || [];
537
561
  if (!(o?.org_id ?? t.var.organization_id) && s.includes("admin:organizations")) {
538
- let e = await V(t).tenants.list({
562
+ let e = await P(t).tenants.list({
539
563
  page: n,
540
564
  per_page: r,
541
565
  include_totals: i,
@@ -545,39 +569,43 @@ function H(e, t) {
545
569
  tenants: e.tenants,
546
570
  start: e.totals?.start ?? 0,
547
571
  limit: e.totals?.limit ?? r,
548
- length: e.tenants.length
572
+ length: e.tenants.length,
573
+ total: e.totals?.length
549
574
  }) : t.json({ tenants: e.tenants });
550
575
  }
551
- let c = e.accessControl?.controlPlaneTenantId ?? V(t).multiTenancyConfig?.controlPlaneTenantId;
552
- 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" });
553
578
  if (c && o?.sub) {
554
- 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);
555
580
  if (e.length === 0) return i ? t.json({
556
581
  tenants: [],
557
582
  start: 0,
558
583
  limit: r ?? 50,
559
- length: 0
584
+ length: 0,
585
+ total: 0
560
586
  }) : t.json({ tenants: [] });
561
- 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);
562
588
  if (p.length === 0) return i ? t.json({
563
589
  tenants: [],
564
- start: f,
590
+ start: d,
565
591
  limit: u,
566
- length: s
592
+ length: 0,
593
+ total: s
567
594
  }) : t.json({ tenants: [] });
568
- 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({
569
596
  q: h,
570
597
  per_page: u,
571
598
  include_totals: !1
572
599
  });
573
600
  return i ? t.json({
574
601
  tenants: g.tenants,
575
- start: f,
602
+ start: d,
576
603
  limit: u,
577
- length: s
604
+ length: g.tenants.length,
605
+ total: s
578
606
  }) : t.json({ tenants: g.tenants });
579
607
  }
580
- let l = await V(t).tenants.list({
608
+ let l = await P(t).tenants.list({
581
609
  page: n,
582
610
  per_page: r,
583
611
  include_totals: i,
@@ -587,36 +615,41 @@ function H(e, t) {
587
615
  tenants: l.tenants,
588
616
  start: l.totals?.start ?? 0,
589
617
  limit: l.totals?.limit ?? r,
590
- length: l.tenants.length
618
+ length: l.tenants.length,
619
+ total: l.totals?.length
591
620
  }) : t.json({ tenants: l.tenants });
592
- }), n.openapi(S({
621
+ }), n.openapi(C({
593
622
  tags: ["tenants"],
594
623
  method: "post",
595
624
  path: "/",
596
- request: { body: { content: { "application/json": { schema: y } } } },
625
+ request: { body: { content: { "application/json": { schema: b } } } },
597
626
  security: [{ Bearer: [] }],
598
627
  responses: {
599
628
  201: {
600
- content: { "application/json": { schema: b } },
629
+ content: { "application/json": { schema: x } },
601
630
  description: "Tenant created"
602
631
  },
603
632
  400: { description: "Validation error" },
604
633
  409: { description: "Tenant with this ID already exists" }
605
634
  }
606
635
  }), async (e) => {
607
- 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" });
608
637
  let n = e.req.valid("json"), r = {
609
- adapters: V(e),
638
+ adapters: P(e),
610
639
  ctx: e
611
640
  };
612
- t.tenants?.beforeCreate && (n = await t.tenants.beforeCreate(r, n));
613
- 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);
614
647
  return t.tenants?.afterCreate && await t.tenants.afterCreate(r, i), e.json(i, 201);
615
- }), n.openapi(S({
648
+ }), n.openapi(C({
616
649
  tags: ["tenants"],
617
650
  method: "delete",
618
651
  path: "/{id}",
619
- request: { params: C.object({ id: C.string() }) },
652
+ request: { params: w.object({ id: w.string() }) },
620
653
  security: [{ Bearer: ["delete:tenants"] }],
621
654
  responses: {
622
655
  204: { description: "Tenant deleted" },
@@ -624,72 +657,78 @@ function H(e, t) {
624
657
  404: { description: "Tenant not found" }
625
658
  }
626
659
  }), async (n) => {
627
- 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;
628
661
  if (i) {
629
- let e = fe(n.var.user);
630
- if (!e?.sub) throw new w(401, { message: "Authentication required" });
631
- 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" });
632
665
  let t = n.var.org_name, a = r.toLowerCase(), o = !!t && t.toLowerCase() === a;
633
666
  if (!o) {
634
667
  let r = !!(e.org_id ?? n.var.organization_id ?? t), a = !e.tenant_id || e.tenant_id === i;
635
- !r && a && pe(e) && (o = !0);
668
+ !r && a && Se(e) && (o = !0);
636
669
  }
637
- 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" });
638
671
  }
639
- 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" });
640
673
  let a = {
641
- adapters: V(n),
674
+ adapters: P(n),
642
675
  ctx: n
643
676
  };
644
- 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);
645
- }), 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({
646
679
  tags: ["tenants", "settings"],
647
680
  method: "get",
648
681
  path: "/settings",
649
- request: { headers: C.object({ "tenant-id": C.string().optional() }) },
682
+ request: { headers: w.object({ "tenant-id": w.string().optional() }) },
650
683
  security: [{ Bearer: ["read:tenants"] }],
651
684
  responses: { 200: {
652
- content: { "application/json": { schema: b } },
685
+ content: { "application/json": { schema: x } },
653
686
  description: "Current tenant settings"
654
687
  } }
655
688
  }), async (e) => {
656
- let t = await V(e).tenants.get(e.var.tenant_id);
657
- 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" });
658
691
  return e.json(t);
659
- }), n.openapi(S({
692
+ }), n.openapi(C({
660
693
  tags: ["tenants", "settings"],
661
694
  method: "patch",
662
695
  path: "/settings",
663
696
  request: {
664
- headers: C.object({ "tenant-id": C.string().optional() }),
665
- 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() } } }
666
699
  },
667
700
  security: [{ Bearer: ["update:tenants"] }],
668
701
  responses: { 200: {
669
- content: { "application/json": { schema: b } },
702
+ content: { "application/json": { schema: x } },
670
703
  description: "Updated tenant settings"
671
704
  } }
672
705
  }), async (e) => {
673
- let { id: t, ...n } = e.req.valid("json"), r = await V(e).tenants.get(e.var.tenant_id);
674
- 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" });
675
708
  if ("default_client_id" in n) {
676
709
  let t = n.default_client_id;
677
710
  if (typeof t == "string" && t.length > 0) {
678
- let n = await V(e).clients.get(e.var.tenant_id, t);
679
- if (!n) throw new w(400, { message: `Client with id '${t}' not found` });
680
- 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` });
681
714
  }
682
715
  }
683
- let i = c(r, n);
684
- await V(e).tenants.update(e.var.tenant_id, i);
685
- let a = await V(e).tenants.get(e.var.tenant_id);
686
- 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" });
687
726
  return e.json(a);
688
727
  }), n;
689
728
  }
690
729
  //#endregion
691
730
  //#region src/middleware/protect-synced.ts
692
- function me(e) {
731
+ function Ce(e) {
693
732
  for (let { pattern: t, type: n } of [
694
733
  {
695
734
  pattern: /\/api\/v2\/resource-servers\/([^/]+)$/,
@@ -712,7 +751,7 @@ function me(e) {
712
751
  }
713
752
  return null;
714
753
  }
715
- async function he(e, t, n) {
754
+ async function we(e, t, n) {
716
755
  try {
717
756
  switch (n.type) {
718
757
  case "resource_server": return (await e.resourceServers.get(t, n.id))?.is_system === !0;
@@ -724,47 +763,495 @@ async function he(e, t, n) {
724
763
  return !1;
725
764
  }
726
765
  }
727
- function ge(e) {
766
+ function Te(e) {
728
767
  return {
729
768
  resource_server: "resource server",
730
769
  role: "role",
731
770
  connection: "connection"
732
771
  }[e];
733
772
  }
734
- function U() {
773
+ function Ee() {
735
774
  return async (e, t) => {
736
775
  if (![
737
776
  "PATCH",
738
777
  "PUT",
739
778
  "DELETE"
740
779
  ].includes(e.req.method)) return t();
741
- let n = me(e.req.path);
780
+ let n = Ce(e.req.path);
742
781
  if (!n) return t();
743
782
  let r = e.var.tenant_id || e.req.header("x-tenant-id") || e.req.header("tenant-id");
744
783
  if (!r) return t();
745
- 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.` });
746
785
  return t();
747
786
  };
748
787
  }
749
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
750
1237
  //#region src/middleware/settings-inheritance.ts
751
- function W(e, t) {
1238
+ function q(e, t) {
752
1239
  let n = t.find((t) => t.strategy === e.strategy);
753
1240
  if (!n?.options) return e;
754
- let r = s.passthrough().parse({
1241
+ let r = c.passthrough().parse({
755
1242
  ...n,
756
1243
  ...e
757
1244
  });
758
- return r.options = o.passthrough().parse({
1245
+ return r.options = s.passthrough().parse({
759
1246
  ...n.options || {},
760
1247
  ...e.options
761
1248
  }), r;
762
1249
  }
763
- function G(e, t) {
1250
+ function J(e, t) {
764
1251
  let n = [...t || [], ...e || []];
765
1252
  return [...new Set(n)];
766
1253
  }
767
- function _e(e, t) {
1254
+ function $e(e, t) {
768
1255
  if (!t?.length) return e || [];
769
1256
  if (!e?.length) return t;
770
1257
  let n = /* @__PURE__ */ new Map();
@@ -772,22 +1259,22 @@ function _e(e, t) {
772
1259
  for (let t of e) n.set(t.value, t);
773
1260
  return Array.from(n.values());
774
1261
  }
775
- function ve(e, t) {
1262
+ function Y(e, t) {
776
1263
  return t ? {
777
1264
  ...e,
778
- scopes: _e(e.scopes, t.scopes)
1265
+ scopes: $e(e.scopes, t.scopes)
779
1266
  } : e;
780
1267
  }
781
- function ye(e, t) {
1268
+ function et(e, t) {
782
1269
  return t ? {
783
1270
  ...e,
784
- callbacks: G(e.callbacks, t.callbacks),
785
- web_origins: G(e.web_origins, t.web_origins),
786
- allowed_logout_urls: G(e.allowed_logout_urls, t.allowed_logout_urls),
787
- 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)
788
1275
  } : e;
789
1276
  }
790
- function be(e) {
1277
+ function tt(e) {
791
1278
  let { controlPlaneTenantId: t, controlPlaneClientId: n, resolveControlPlane: r } = e;
792
1279
  if (r) return async (e) => r({ tenant_id: e });
793
1280
  if (!t) return async () => void 0;
@@ -797,14 +1284,14 @@ function be(e) {
797
1284
  };
798
1285
  return async () => i;
799
1286
  }
800
- function xe(e, t) {
1287
+ function nt(e, t) {
801
1288
  return {
802
1289
  ...e.resourceServers,
803
1290
  get: async (n, r) => {
804
1291
  let i = await e.resourceServers.get(n, r);
805
1292
  if (!i) return i;
806
1293
  let a = await t(n);
807
- 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));
808
1295
  },
809
1296
  list: async (n, r) => {
810
1297
  let i = await e.resourceServers.list(n, r), a = await t(n);
@@ -816,7 +1303,7 @@ function xe(e, t) {
816
1303
  let n = await e.resourceServers.get(o, t);
817
1304
  n && c.set(t, n);
818
1305
  }));
819
- 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);
820
1307
  return {
821
1308
  ...i,
822
1309
  resource_servers: l
@@ -824,22 +1311,25 @@ function xe(e, t) {
824
1311
  }
825
1312
  };
826
1313
  }
827
- function Se(e, t) {
828
- let n = be({
1314
+ function rt(e, t) {
1315
+ let n = tt({
829
1316
  controlPlaneTenantId: t.controlPlaneTenantId,
830
1317
  resolveControlPlane: t.resolveControlPlane
831
1318
  });
832
1319
  return {
833
1320
  ...e,
834
- resourceServers: xe(e, n)
1321
+ resourceServers: nt(e, n)
835
1322
  };
836
1323
  }
837
- function Ce(e, t) {
838
- 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({
839
1326
  controlPlaneTenantId: n,
840
1327
  controlPlaneClientId: r,
841
1328
  resolveControlPlane: i
842
- });
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;
843
1333
  return {
844
1334
  ...e,
845
1335
  multiTenancyConfig: {
@@ -852,16 +1342,16 @@ function Ce(e, t) {
852
1342
  get: async (t, n) => {
853
1343
  let r = await e.connections.get(t, n);
854
1344
  if (!r) return r;
855
- let i = await a(t);
856
- 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 || []);
857
1347
  },
858
1348
  list: async (t, n) => {
859
- 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);
860
1350
  if (!i || t === i.tenantId) return r;
861
- 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 || []));
862
1352
  return {
863
1353
  ...r,
864
- connections: s
1354
+ connections: o
865
1355
  };
866
1356
  }
867
1357
  },
@@ -870,10 +1360,10 @@ function Ce(e, t) {
870
1360
  listByClient: async (t, n) => {
871
1361
  let r = await e.clientConnections.listByClient(t, n);
872
1362
  r.length === 0 && (r = (await e.connections.list(t)).connections || []);
873
- let i = await a(t);
1363
+ let i = await c(t);
874
1364
  if (!i || t === i.tenantId) return r;
875
- let o = await e.connections.list(i.tenantId);
876
- 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 || []));
877
1367
  }
878
1368
  },
879
1369
  emailProviders: {
@@ -881,26 +1371,26 @@ function Ce(e, t) {
881
1371
  get: async (t) => {
882
1372
  let n = await e.emailProviders.get(t);
883
1373
  if (n) return n;
884
- let r = await a(t);
1374
+ let r = await c(t);
885
1375
  return !r || t === r.tenantId ? null : e.emailProviders.get(r.tenantId);
886
1376
  }
887
1377
  },
888
- resourceServers: xe(e, a),
889
- hooks: Te(e, a)
1378
+ resourceServers: nt(e, c),
1379
+ hooks: at(e, c)
890
1380
  };
891
1381
  }
892
- function we(e) {
1382
+ function X(e) {
893
1383
  if (!e || typeof e != "object") return !1;
894
1384
  let t = e.metadata;
895
1385
  return !t || typeof t != "object" ? !1 : t.inheritable === !0;
896
1386
  }
897
- function Te(e, t) {
1387
+ function at(e, t) {
898
1388
  return {
899
1389
  ...e.hooks,
900
1390
  list: async (n, r) => {
901
1391
  let i = await e.hooks.list(n, r), a = await t(n);
902
1392
  if (!a || n === a.tenantId) return i;
903
- 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);
904
1394
  if (o.length === 0) return i;
905
1395
  let s = new Set((i.hooks || []).map((e) => e.hook_id)), c = o.filter((e) => !s.has(e.hook_id));
906
1396
  return {
@@ -915,31 +1405,31 @@ function Te(e, t) {
915
1405
  let a = await t(n);
916
1406
  if (!a || n === a.tenantId) return i;
917
1407
  let o = await e.hooks.get(a.tenantId, r);
918
- return o && we(o) ? o : null;
1408
+ return o && X(o) ? o : null;
919
1409
  }
920
1410
  };
921
1411
  }
922
- function K(e, t) {
923
- return Ce(e, t);
1412
+ function Z(e, t) {
1413
+ return it(e, t);
924
1414
  }
925
1415
  //#endregion
926
1416
  //#region src/middleware/index.ts
927
- function Ee(e) {
1417
+ function ot(e) {
928
1418
  return async (t, n) => {
929
1419
  let r = t.var.user;
930
1420
  return r?.tenant_id === e && r.org_name && t.set("tenant_id", r.org_name), n();
931
1421
  };
932
1422
  }
933
- function De(e) {
934
- return async (n, r) => {
1423
+ function st(e) {
1424
+ return async (t, r) => {
935
1425
  if (!e.accessControl) return r();
936
- 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);
937
- if (!c && s && u && (n.set("tenant_id", s), c = s), !c) throw new w(400, { message: "Tenant ID not found in request" });
938
- 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}` });
939
1429
  return r();
940
1430
  };
941
1431
  }
942
- function Oe(e) {
1432
+ function ct(e) {
943
1433
  return async (t, n) => {
944
1434
  if (!e.subdomainRouting) return n();
945
1435
  let { baseDomain: r, reservedSubdomains: i = [], resolveSubdomain: a } = e.subdomainRouting, o = t.req.header("x-forwarded-host") || t.req.header("host") || "", s = null;
@@ -951,18 +1441,18 @@ function Oe(e) {
951
1441
  let c = null;
952
1442
  if (a) c = await a(s);
953
1443
  else if (e.subdomainRouting.useOrganizations !== !1 && e.accessControl) try {
954
- let n = await V(t).organizations.get(e.accessControl.controlPlaneTenantId, s);
1444
+ let n = await P(t).organizations.get(e.accessControl.controlPlaneTenantId, s);
955
1445
  n && (c = n.id);
956
1446
  } catch {}
957
- 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}` });
958
1448
  return t.set("tenant_id", c), n();
959
1449
  };
960
1450
  }
961
- function ke(e) {
1451
+ function lt(e) {
962
1452
  return async (t, n) => {
963
1453
  if (!e.databaseIsolation) return n();
964
1454
  let r = t.var.tenant_id;
965
- 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" });
966
1456
  try {
967
1457
  let n = await e.databaseIsolation.getAdapters(r);
968
1458
  t.set("baseData", n), t.env = {
@@ -970,30 +1460,31 @@ function ke(e) {
970
1460
  data: n
971
1461
  };
972
1462
  } catch (e) {
973
- 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" });
974
1464
  }
975
1465
  return n();
976
1466
  };
977
1467
  }
978
- function q(e) {
979
- 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);
980
1470
  return async (e, i) => (await t(e, async () => {}), await n(e, async () => {}), await r(e, async () => {}), i());
981
1471
  }
982
1472
  //#endregion
983
1473
  //#region src/init.ts
984
- function Ae(e) {
985
- 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 = {
986
1476
  resourceServers: !0,
987
1477
  roles: !0
988
- }, 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;
989
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.");
990
- let g = t, _ = t;
991
- n && (g = K(t, {
1480
+ let _ = t, v = t;
1481
+ n && (_ = Z(t, {
992
1482
  controlPlaneTenantId: r,
993
1483
  controlPlaneClientId: i,
994
- resolveControlPlane: a
995
- }), _ = {
996
- ...Se(t, {
1484
+ resolveControlPlane: a,
1485
+ inheritanceShadow: o
1486
+ }), v = {
1487
+ ...rt(t, {
997
1488
  controlPlaneTenantId: r,
998
1489
  resolveControlPlane: a
999
1490
  }),
@@ -1003,12 +1494,12 @@ function Ae(e) {
1003
1494
  resolveControlPlane: a
1004
1495
  }
1005
1496
  });
1006
- let v = h.tenantOperationExecutor;
1007
- if (!v && t.tenantOperations && t.tenantOperationEvents && h.tenantUpgrade) {
1497
+ let y = g.tenantOperationExecutor;
1498
+ if (!y && t.tenantOperations && t.tenantOperationEvents && g.tenantUpgrade) {
1008
1499
  let e = {
1009
1500
  tenantOperations: t.tenantOperations,
1010
1501
  tenantOperationEvents: t.tenantOperationEvents
1011
- }, n = h.tenantUpgrade, r = ne({
1502
+ }, n = g.tenantUpgrade, r = ie({
1012
1503
  stores: e,
1013
1504
  definitions: { upgrade: (e) => [{
1014
1505
  name: "upgrade",
@@ -1018,172 +1509,82 @@ function Ae(e) {
1018
1509
  }
1019
1510
  }] }
1020
1511
  });
1021
- v = {
1512
+ y = {
1022
1513
  engine: r.engine,
1023
- enqueue: (t) => ie(e, r, {
1514
+ enqueue: (t) => oe(e, r, {
1024
1515
  ...t,
1025
1516
  tenant_id: t.tenant_id
1026
1517
  })
1027
1518
  };
1028
1519
  }
1029
- let y = o !== !1, b = y ? {
1030
- resourceServers: o.resourceServers ?? !0,
1031
- roles: o.roles ?? !0
1520
+ let b = s !== !1, x = b ? {
1521
+ resourceServers: s.resourceServers ?? !0,
1522
+ roles: s.roles ?? !0
1032
1523
  } : {
1033
1524
  resourceServers: !1,
1034
1525
  roles: !1
1035
- }, { entityHooks: x, tenantHooks: S } = B({
1526
+ }, { entityHooks: S, tenantHooks: C } = ve({
1036
1527
  controlPlaneTenantId: r,
1037
- getChildTenantIds: f ?? (async () => (await d((e) => g.tenants.list(e), "tenants", {
1528
+ getChildTenantIds: p ?? (async () => (await f((e) => _.tenants.list(e), "tenants", {
1038
1529
  cursorField: "id",
1039
1530
  pageSize: 100
1040
1531
  })).filter((e) => e.id !== r).map((e) => e.id)),
1041
- getAdapters: m ?? (async () => g),
1042
- getControlPlaneAdapters: async () => g,
1043
- sync: b
1044
- }), C = {
1045
- resourceServers: [x.resourceServers, ...u?.resourceServers ?? []],
1046
- roles: [x.roles, ...u?.roles ?? []],
1047
- connections: u?.connections ?? [],
1048
- tenants: u?.tenants ?? [],
1049
- rolePermissions: u?.rolePermissions ?? []
1050
- }, 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: {
1051
1542
  controlPlaneTenantId: r,
1052
- requireOrganizationMatch: c,
1053
- defaultPermissions: s
1054
- } }), T = H({ accessControl: {
1543
+ requireOrganizationMatch: l,
1544
+ defaultPermissions: c
1545
+ } }), E = F({ accessControl: {
1055
1546
  controlPlaneTenantId: r,
1056
- requireOrganizationMatch: c,
1057
- defaultPermissions: s
1547
+ requireOrganizationMatch: l,
1548
+ defaultPermissions: c
1058
1549
  } }, { tenants: {
1059
1550
  async beforeCreate(e, t) {
1060
- 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;
1061
1552
  },
1062
1553
  async afterCreate(e, t) {
1063
- await w.afterCreate?.(e, t), await S.afterCreate?.(e, t);
1554
+ await T.afterCreate?.(e, t), await C.afterCreate?.(e, t);
1064
1555
  },
1065
1556
  async beforeDelete(e, t) {
1066
- await w.beforeDelete?.(e, t), await S.beforeDelete?.(e, t);
1557
+ await T.beforeDelete?.(e, t), await C.beforeDelete?.(e, t);
1067
1558
  }
1068
- } }), { app: E } = p({
1069
- dataAdapter: g,
1070
- managementDataAdapter: _,
1071
- ...h,
1072
- tenantOperationExecutor: v,
1073
- entityHooks: C,
1074
- managementApiExtensions: [...l, {
1559
+ } }), { app: D } = m({
1560
+ dataAdapter: _,
1561
+ managementDataAdapter: v,
1562
+ ...g,
1563
+ tenantOperationExecutor: y,
1564
+ entityHooks: w,
1565
+ managementApiExtensions: [...u, {
1075
1566
  path: "/tenants",
1076
- router: T
1567
+ router: E
1077
1568
  }],
1078
- managementApiMiddleware: [...h.managementApiMiddleware ?? [], ...y ? [U()] : []]
1569
+ managementApiMiddleware: [...g.managementApiMiddleware ?? [], ...b ? [Ee()] : []]
1079
1570
  });
1080
1571
  return {
1081
- app: E,
1572
+ app: D,
1082
1573
  controlPlaneTenantId: r
1083
1574
  };
1084
1575
  }
1085
1576
  //#endregion
1086
- //#region src/rollout/defaults-projection.ts
1087
- function J(e = {}) {
1088
- return {
1089
- connections: e.connections ?? !0,
1090
- resourceServers: e.resourceServers ?? !0,
1091
- hooks: e.hooks ?? !0,
1092
- emailProvider: e.emailProvider ?? !0,
1093
- branding: e.branding ?? !0,
1094
- promptSettings: e.promptSettings ?? !0
1095
- };
1096
- }
1097
- function Y() {
1098
- return {
1099
- upserted: 0,
1100
- errors: []
1101
- };
1102
- }
1103
- function je(e) {
1104
- return {
1105
- tenantId: e,
1106
- connections: Y(),
1107
- resourceServers: Y(),
1108
- hooks: Y(),
1109
- emailProvider: Y(),
1110
- branding: Y(),
1111
- promptSettings: Y()
1112
- };
1113
- }
1114
- function Me(e) {
1115
- let t = e.metadata;
1116
- return !!(t && t.inheritable === !0);
1117
- }
1118
- async function X(e, t, n, r) {
1119
- try {
1120
- await r();
1121
- } catch (r) {
1122
- let i = `${t}: ${r instanceof Error ? r.message : String(r)}`;
1123
- if (!n) throw Error(i, { cause: r });
1124
- e.errors.push(i);
1125
- }
1126
- }
1127
- async function Ne(e, t, n) {
1128
- return {
1129
- connections: n.connections ? await d((n) => e.connections.list(t, n), "connections", {
1130
- cursorField: "id",
1131
- pageSize: 100
1132
- }) : [],
1133
- resourceServers: n.resourceServers ? await d((n) => e.resourceServers.list(t, n), "resource_servers", {
1134
- cursorField: "id",
1135
- pageSize: 100
1136
- }) : [],
1137
- hooks: n.hooks ? await d((n) => e.hooks.list(t, n), "hooks", {
1138
- cursorField: "hook_id",
1139
- pageSize: 100
1140
- }) : [],
1141
- emailProvider: n.emailProvider ? await e.emailProviders.get(t) ?? null : null,
1142
- branding: n.branding ? await e.branding.get(t) ?? null : null,
1143
- promptSettings: n.promptSettings ? await e.promptSettings.get(t) ?? null : null
1144
- };
1145
- }
1146
- async function Pe(e, t, n, r, i, o) {
1147
- if (r.connections) for (let r of e.connections) {
1148
- let e = r.id;
1149
- e && await X(o.connections, `connection ${e}`, i, async () => {
1150
- let i = a.parse(r);
1151
- await t.connections.get(n, e) ? await t.connections.update(n, e, i) : await t.connections.create(n, i), o.connections.upserted += 1;
1152
- });
1153
- }
1154
- if (r.resourceServers) for (let r of e.resourceServers) !r.is_system || !r.id || await X(o.resourceServers, `resource_server ${r.id}`, i, async () => {
1155
- let e = v.parse(r);
1156
- 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;
1157
- });
1158
- if (r.hooks) for (let r of e.hooks) !Me(r) || !r.hook_id || await X(o.hooks, `hook ${r.hook_id}`, i, async () => {
1159
- let e = f.parse(r);
1160
- 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;
1161
- });
1162
- r.emailProvider && e.emailProvider && await X(o.emailProvider, "email_provider", i, async () => {
1163
- let r = e.emailProvider;
1164
- await t.emailProviders.get(n) ? await t.emailProviders.update(n, r) : await t.emailProviders.create(n, r), o.emailProvider.upserted += 1;
1165
- }), r.branding && e.branding && await X(o.branding, "branding", i, async () => {
1166
- await t.branding.set(n, e.branding), o.branding.upserted += 1;
1167
- }), r.promptSettings && e.promptSettings && await X(o.promptSettings, "prompt_settings", i, async () => {
1168
- await t.promptSettings.set(n, e.promptSettings), o.promptSettings.upserted += 1;
1169
- });
1170
- }
1171
- async function Z(e, t) {
1172
- 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);
1173
- return await Pe(c, l, n, s, o, u), u;
1174
- }
1175
- //#endregion
1176
1577
  //#region src/rollout/payload.ts
1177
- function Fe(e) {
1578
+ function dt(e) {
1178
1579
  let { pkcs7: t, tenant_id: n, ...r } = e;
1179
1580
  return r;
1180
1581
  }
1181
- async function Ie(e, t, n = {}, r) {
1182
- 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) : [];
1183
1584
  return {
1184
1585
  connections: s.connections,
1185
1586
  resourceServers: s.resourceServers.filter((e) => e.is_system),
1186
- hooks: s.hooks.filter(Me),
1587
+ hooks: s.hooks.filter(ze),
1187
1588
  emailProvider: s.emailProvider,
1188
1589
  branding: s.branding,
1189
1590
  promptSettings: s.promptSettings,
@@ -1191,7 +1592,7 @@ async function Ie(e, t, n = {}, r) {
1191
1592
  tenants: l
1192
1593
  };
1193
1594
  }
1194
- async function Le(e, t, n) {
1595
+ async function pt(e, t, n) {
1195
1596
  let r = n && n !== t ? [t, n] : [t], i = [];
1196
1597
  for (let t of r) {
1197
1598
  let n = await e.tenants.get(t);
@@ -1202,19 +1603,19 @@ async function Le(e, t, n) {
1202
1603
  }
1203
1604
  return i;
1204
1605
  }
1205
- async function Re(e, t, n) {
1206
- let r = Y();
1606
+ async function mt(e, t, n) {
1607
+ let r = B();
1207
1608
  if (e.length === 0) return r;
1208
- let i = await h(t.keys), a = new Set(i.map((e) => e.kid));
1209
- for (let i of e) await X(r, `signing_key ${i.kid}`, n, async () => {
1210
- 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);
1211
1612
  a.has(e.kid) || (await t.keys.create(e), a.add(e.kid), r.upserted += 1);
1212
1613
  });
1213
1614
  return r;
1214
1615
  }
1215
- async function ze(e, t, n) {
1216
- let r = Y();
1217
- 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 () => {
1218
1619
  await t.tenants.get(i.id) || (await t.tenants.create({
1219
1620
  id: i.id,
1220
1621
  friendly_name: i.friendly_name
@@ -1222,17 +1623,17 @@ async function ze(e, t, n) {
1222
1623
  });
1223
1624
  return r;
1224
1625
  }
1225
- async function Be(e, t, n, r = {}) {
1226
- 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 = {
1227
1628
  connections: e.connections,
1228
1629
  resourceServers: e.resourceServers,
1229
1630
  hooks: e.hooks,
1230
- emailProvider: e.emailProvider ? l.parse(e.emailProvider) : null,
1231
- branding: e.branding ? i.parse(e.branding) : null,
1232
- promptSettings: e.promptSettings ? g.parse(e.promptSettings) : null
1233
- }, d = c ? await ze(e.tenants ?? [], t, a) : Y(), f = je(n);
1234
- await Pe(u, t, n, o, a, f);
1235
- 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();
1236
1637
  return {
1237
1638
  ...f,
1238
1639
  signingKeys: p,
@@ -1241,27 +1642,27 @@ async function Be(e, t, n, r = {}) {
1241
1642
  }
1242
1643
  //#endregion
1243
1644
  //#region src/rollout/index.ts
1244
- function Ve(e) {
1645
+ function _t(e) {
1245
1646
  return {
1246
- syncDefaults: (t) => Z(e, t),
1647
+ syncDefaults: (t) => U(e, t),
1247
1648
  syncDefaultsToTenants: async (t) => {
1248
1649
  let n = [];
1249
- for (let r of t) n.push(await Z(e, r));
1650
+ for (let r of t) n.push(await U(e, r));
1250
1651
  return n;
1251
1652
  }
1252
1653
  };
1253
1654
  }
1254
1655
  //#endregion
1255
1656
  //#region src/plugin.ts
1256
- function He(e) {
1257
- let t = Q(e);
1657
+ function vt(e) {
1658
+ let t = $(e);
1258
1659
  return {
1259
1660
  name: "multi-tenancy",
1260
- middleware: q(e),
1661
+ middleware: Q(e),
1261
1662
  hooks: t,
1262
1663
  routes: [{
1263
1664
  path: "/management",
1264
- handler: H(e, t)
1665
+ handler: F(e, t)
1265
1666
  }],
1266
1667
  onRegister: async () => {
1267
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");
@@ -1270,29 +1671,29 @@ function He(e) {
1270
1671
  }
1271
1672
  //#endregion
1272
1673
  //#region src/index.ts
1273
- function Q(e) {
1274
- 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);
1275
1676
  return {
1276
1677
  ...t,
1277
1678
  ...n,
1278
1679
  tenants: r
1279
1680
  };
1280
1681
  }
1281
- function $(t) {
1282
- let n = new e(), r = Q(t);
1283
- 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;
1284
1685
  }
1285
- function Ue(e) {
1686
+ function bt(e) {
1286
1687
  return {
1287
- hooks: Q(e),
1288
- middleware: q(e),
1289
- app: $(e),
1688
+ hooks: $(e),
1689
+ middleware: Q(e),
1690
+ app: yt(e),
1290
1691
  config: e,
1291
- wrapAdapters: (t, n) => K(t, {
1692
+ wrapAdapters: (t, n) => Z(t, {
1292
1693
  controlPlaneTenantId: e.accessControl?.controlPlaneTenantId,
1293
1694
  controlPlaneClientId: n?.controlPlaneClientId
1294
1695
  })
1295
1696
  };
1296
1697
  }
1297
1698
  //#endregion
1298
- 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 };