@authhero/multi-tenancy 15.3.0 → 15.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/multi-tenancy.cjs +1 -1
- package/dist/multi-tenancy.mjs +1366 -621
- package/dist/types/inheritance/report.d.ts +6 -2
- package/dist/types/inheritance/report.d.ts.map +1 -1
- package/dist/types/init.d.ts +57 -2
- package/dist/types/init.d.ts.map +1 -1
- package/dist/types/middleware/config-sync-mode.d.ts +4 -1
- package/dist/types/middleware/config-sync-mode.d.ts.map +1 -1
- package/dist/types/operations/detach.d.ts +85 -0
- package/dist/types/operations/detach.d.ts.map +1 -0
- package/dist/types/operations/index.d.ts +4 -0
- package/dist/types/operations/index.d.ts.map +1 -1
- package/dist/types/operations/sync-defaults.d.ts +4 -1
- package/dist/types/operations/sync-defaults.d.ts.map +1 -1
- package/dist/types/operations/tenant-members-request.d.ts +97 -0
- package/dist/types/operations/tenant-members-request.d.ts.map +1 -0
- package/dist/types/rollout/resolved-sync.d.ts +21 -0
- package/dist/types/rollout/resolved-sync.d.ts.map +1 -1
- package/dist/types/rollouts/index.d.ts +2 -0
- package/dist/types/rollouts/index.d.ts.map +1 -1
- package/dist/types/rollouts/status.d.ts +1 -1
- package/dist/types/rollouts/status.d.ts.map +1 -1
- package/dist/types/rollouts/verify.d.ts +50 -0
- package/dist/types/rollouts/verify.d.ts.map +1 -0
- package/dist/types/routes/tenants.d.ts.map +1 -1
- package/dist/types/types.d.ts +9 -1
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils/tenant-settings.d.ts +13 -0
- package/dist/types/utils/tenant-settings.d.ts.map +1 -0
- package/package.json +5 -5
|
@@ -13,8 +13,12 @@ export interface InheritanceShadowOptions {
|
|
|
13
13
|
includeExpected?: boolean;
|
|
14
14
|
}
|
|
15
15
|
export interface ShadowReporter {
|
|
16
|
-
/**
|
|
17
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Starts a comparison for `tenantId` in the background, if due, and returns
|
|
18
|
+
* it (never rejecting) so a host that must keep the work alive, such as a
|
|
19
|
+
* Worker with `ctx.waitUntil`, can wait for it. Undefined when none started.
|
|
20
|
+
*/
|
|
21
|
+
schedule(tenantId: string, legacyControlPlane: string | undefined): Promise<void> | undefined;
|
|
18
22
|
}
|
|
19
23
|
export declare function createShadowReporter(adapters: DataAdapters, options: InheritanceShadowOptions): ShadowReporter;
|
|
20
24
|
//# sourceMappingURL=report.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../src/inheritance/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAY,MAAM,UAAU,CAAC;AAGlD;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAKD,MAAM,WAAW,cAAc;IAC7B
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../src/inheritance/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAY,MAAM,UAAU,CAAC;AAGlD;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAKD,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,QAAQ,CACN,QAAQ,EAAE,MAAM,EAChB,kBAAkB,EAAE,MAAM,GAAG,SAAS,GACrC,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC;CAC9B;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,wBAAwB,GAChC,cAAc,CAiDhB"}
|
package/dist/types/init.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { init, AuthHeroConfig, DataAdapters } from "authhero";
|
|
2
|
-
import
|
|
1
|
+
import { init, AuthHeroConfig, DataAdapters, type ExecuteTenantMemberRequestOptions, type TenantMembersBackend } from "authhero";
|
|
2
|
+
import { enqueueTenantMemberRequest } from "./operations";
|
|
3
|
+
import type { DetachConfigFn, ReconcileTenantMemberRequestsDeps, ReconcileTenantMemberRequestsResult, SyncConfigFn, TenantMemberRequestStore, TenantOperationExecutor } from "./operations";
|
|
3
4
|
import { type RolloutDeps } from "./rollouts";
|
|
4
5
|
import type { ControlPlaneResolver } from "./middleware";
|
|
5
6
|
import type { InheritanceShadowOptions } from "./inheritance";
|
|
@@ -72,6 +73,42 @@ export interface MultiTenantConfig extends Omit<AuthHeroConfig, "entityHooks" |
|
|
|
72
73
|
* (for example a dispatch push to the tenant worker) to reach those.
|
|
73
74
|
*/
|
|
74
75
|
syncDefaults?: SyncConfigFn;
|
|
76
|
+
/**
|
|
77
|
+
* How the `detach` tenant operation reaches a tenant's database. The default
|
|
78
|
+
* works on tenants that share the control plane's database, in-process, and
|
|
79
|
+
* refuses tenants with their own worker and database.
|
|
80
|
+
*/
|
|
81
|
+
detachTenant?: DetachConfigFn;
|
|
82
|
+
/**
|
|
83
|
+
* Carries out the team changes that tenants register as requests (issue
|
|
84
|
+
* #1550) as `tenant-members-request` tenant operations, and answers the
|
|
85
|
+
* request with the outcome. Needs the tenant operations adapters, and
|
|
86
|
+
* returns `memberRequests` for the notify endpoint and the scheduled sweep.
|
|
87
|
+
*/
|
|
88
|
+
tenantMemberRequests?: {
|
|
89
|
+
/**
|
|
90
|
+
* The control-plane team backend, built without a request in hand
|
|
91
|
+
* (`createLocalTenantMembersBackend` bound to the control-plane database).
|
|
92
|
+
*/
|
|
93
|
+
getBackend: () => TenantMembersBackend | Promise<TenantMembersBackend>;
|
|
94
|
+
/**
|
|
95
|
+
* How the requests are read and answered. The default reaches tenants that
|
|
96
|
+
* share the control plane's database; pass a transport (for example a
|
|
97
|
+
* dispatch push to the tenant worker) for tenants with their own database.
|
|
98
|
+
*/
|
|
99
|
+
store?: TenantMemberRequestStore;
|
|
100
|
+
/** Who may still ask. See `executeTenantMemberRequest`. */
|
|
101
|
+
isRequesterAllowed?: ExecuteTenantMemberRequestOptions["isRequesterAllowed"];
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* How long each isolate remembers a tenant's `config_sync` mode. The
|
|
105
|
+
* isolates that did not handle the `PATCH` notice a flip within this time.
|
|
106
|
+
* It does not cover a cached client bundle, which can keep serving what was
|
|
107
|
+
* read under the old mode for up to 15 minutes. Lower it for a faster flip at the cost of
|
|
108
|
+
* one more `tenants.get` per isolate and tenant per period.
|
|
109
|
+
* @default 10000
|
|
110
|
+
*/
|
|
111
|
+
configSyncCacheTtlMs?: number;
|
|
75
112
|
/**
|
|
76
113
|
* Starts the per-tenant operations of a fleet rollout. Defaults to the same
|
|
77
114
|
* inline executor as `sync-defaults` requests; Workflows deployments pass
|
|
@@ -140,6 +177,24 @@ export interface MultiTenantResult {
|
|
|
140
177
|
* ```
|
|
141
178
|
*/
|
|
142
179
|
rollouts?: RolloutDeps;
|
|
180
|
+
/**
|
|
181
|
+
* Present when `tenantMemberRequests` is configured and the control plane
|
|
182
|
+
* carries the tenant operations adapters.
|
|
183
|
+
*
|
|
184
|
+
* ```typescript
|
|
185
|
+
* // proxyControlPlane.tenantMembers.requests
|
|
186
|
+
* onNotify: (_c, tenantId, requestId) =>
|
|
187
|
+
* memberRequests.enqueue(tenantId, requestId).then(() => {}),
|
|
188
|
+
* // and in a scheduled handler, because a tenant worker cannot run a cron
|
|
189
|
+
* await memberRequests.reconcile();
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
memberRequests?: {
|
|
193
|
+
/** Runs the request for a tenant, once however often it is called. */
|
|
194
|
+
enqueue(tenantId: string, requestId: string): ReturnType<typeof enqueueTenantMemberRequest>;
|
|
195
|
+
/** Finds requests that were never run, or whose run failed, and runs them. */
|
|
196
|
+
reconcile(options?: Partial<Pick<ReconcileTenantMemberRequestsDeps, "tenantIds" | "graceMs" | "maxAttempts">>): Promise<ReconcileTenantMemberRequestsResult>;
|
|
197
|
+
};
|
|
143
198
|
}
|
|
144
199
|
/**
|
|
145
200
|
* Initialize a multi-tenant AuthHero application with sensible defaults.
|
package/dist/types/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,cAAc,EAEd,YAAY,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,11 +26,14 @@ export interface ConfigSyncResolverOptions {
|
|
|
26
26
|
controlPlaneTenantId?: string;
|
|
27
27
|
/**
|
|
28
28
|
* How long a tenant's mode is remembered, per isolate. A mode change reaches
|
|
29
|
-
* other isolates within this time
|
|
29
|
+
* other isolates within this time, so it is also how long to wait after a flip
|
|
30
|
+
* before judging the result. @default 10000
|
|
30
31
|
*/
|
|
31
32
|
ttlMs?: number;
|
|
32
33
|
/** Upper bound on remembered tenants. @default 1000 */
|
|
33
34
|
maxEntries?: number;
|
|
34
35
|
}
|
|
36
|
+
/** How long an isolate remembers a tenant's `config_sync` mode. */
|
|
37
|
+
export declare const DEFAULT_CONFIG_SYNC_TTL_MS = 10000;
|
|
35
38
|
export declare function createConfigSyncResolver(options: ConfigSyncResolverOptions): ConfigSyncResolver;
|
|
36
39
|
//# sourceMappingURL=config-sync-mode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-sync-mode.d.ts","sourceRoot":"","sources":["../../../src/middleware/config-sync-mode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAEnE;;;;;GAKG;AAEH,MAAM,WAAW,kBAAkB;IACjC,0FAA0F;IAC1F,OAAO,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACtE,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,sDAAsD;IACtD,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,yBAAyB;IACxC,yEAAyE;IACzE,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC1D,6DAA6D;IAC7D,SAAS,EAAE,CACT,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC;QAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACrD,kEAAkE;IAClE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B
|
|
1
|
+
{"version":3,"file":"config-sync-mode.d.ts","sourceRoot":"","sources":["../../../src/middleware/config-sync-mode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAEnE;;;;;GAKG;AAEH,MAAM,WAAW,kBAAkB;IACjC,0FAA0F;IAC1F,OAAO,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACtE,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,sDAAsD;IACtD,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,yBAAyB;IACxC,yEAAyE;IACzE,IAAI,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC1D,6DAA6D;IAC7D,SAAS,EAAE,CACT,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC;QAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACrD,kEAAkE;IAClE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,mEAAmE;AACnE,eAAO,MAAM,0BAA0B,QAAS,CAAC;AAEjD,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,yBAAyB,GACjC,kBAAkB,CA2CpB"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { DataAdapters, TenantOperation } from "authhero";
|
|
2
|
+
import type { OperationRecorder } from "./recorder";
|
|
3
|
+
/**
|
|
4
|
+
* `detach`: a synced tenant leaves its parent (docs/design/tenant-config-
|
|
5
|
+
* inheritance.md, open question 1). The copies a sync delivered (`sy` ids) are
|
|
6
|
+
* either turned into the tenant's own rows (a snapshot: the content is kept,
|
|
7
|
+
* the ids are normal, and `scope`, `override` and `enforce` are dropped, so
|
|
8
|
+
* nothing locks them), or with `clean` removed. The tenant row then gets
|
|
9
|
+
* `config_sync: "detached"` and no parent, so nothing inherits or syncs into it
|
|
10
|
+
* again.
|
|
11
|
+
*
|
|
12
|
+
* Platform rows (`scope: "platform"`) run for the tenant but are hidden from
|
|
13
|
+
* its admins, so converting them would expose code and secrets. They are kept
|
|
14
|
+
* as copies and reported; only `clean` removes them.
|
|
15
|
+
*/
|
|
16
|
+
export type DetachEntity = "connection" | "resourceServer" | "hookCode" | "action" | "hook";
|
|
17
|
+
export interface DetachOptions {
|
|
18
|
+
/** Report what would happen; write nothing. */
|
|
19
|
+
dryRun: boolean;
|
|
20
|
+
/** Remove the copies instead of turning them into the tenant's own rows. */
|
|
21
|
+
clean: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface DetachEntityOutcome {
|
|
24
|
+
converted: number;
|
|
25
|
+
removed: number;
|
|
26
|
+
skipped: number;
|
|
27
|
+
errors: string[];
|
|
28
|
+
}
|
|
29
|
+
export interface DetachRow {
|
|
30
|
+
entity: DetachEntity;
|
|
31
|
+
key: string;
|
|
32
|
+
/** `kept`: a platform row that stays as a copy (or code it runs). */
|
|
33
|
+
action: "converted" | "removed" | "kept";
|
|
34
|
+
}
|
|
35
|
+
export interface DetachResult {
|
|
36
|
+
status: "detached" | "dry-run" | "already-detached" | "partial";
|
|
37
|
+
/** `convert|remove|skip <entity>:<key>` for every row looked at. */
|
|
38
|
+
changes: string[];
|
|
39
|
+
/** The same rows, structured. */
|
|
40
|
+
rows: DetachRow[];
|
|
41
|
+
entities: Record<DetachEntity, DetachEntityOutcome>;
|
|
42
|
+
}
|
|
43
|
+
export type DetachConfigFn = (tenantId: string, options: DetachOptions) => Promise<DetachResult>;
|
|
44
|
+
/** Reads the operation's `input` (fixed at creation, never secrets). */
|
|
45
|
+
export declare function detachOptionsOf(operation: Pick<TenantOperation, "input">): DetachOptions;
|
|
46
|
+
/** Every per-entity error message the detach reported. */
|
|
47
|
+
export declare function detachErrors(result: DetachResult): string[];
|
|
48
|
+
/** The JSON-serialisable outcome stored in the operation's `result`. */
|
|
49
|
+
export declare function summarizeDetachResult(result: DetachResult, options: DetachOptions): Record<string, unknown>;
|
|
50
|
+
/** The step the executors run: detach, record the outcome, fail on errors. */
|
|
51
|
+
export declare function runDetachStep(params: {
|
|
52
|
+
operation: Pick<TenantOperation, "id" | "tenant_id" | "input">;
|
|
53
|
+
detachTenant: DetachConfigFn;
|
|
54
|
+
recorder: Pick<OperationRecorder, "setResult">;
|
|
55
|
+
/** Called after a run that really detached the tenant (not a preview). */
|
|
56
|
+
onDetached?: (tenantId: string) => void;
|
|
57
|
+
}): Promise<Record<string, unknown>>;
|
|
58
|
+
/** An empty result with the given status, for when nothing is looked at. */
|
|
59
|
+
export declare function emptyDetachResult(status: DetachResult["status"]): DetachResult;
|
|
60
|
+
/**
|
|
61
|
+
* Throws unless a tenant can be detached. Detaching keeps what the tenant
|
|
62
|
+
* holds, so the inherited config has to be in its database: a tenant that
|
|
63
|
+
* inherits on read has none of it there, and would lose it silently.
|
|
64
|
+
*/
|
|
65
|
+
export declare function assertDetachEligible(tenantId: string, tenant: {
|
|
66
|
+
config_sync?: string | null;
|
|
67
|
+
}): void;
|
|
68
|
+
/** The tenant row of a detached tenant: no parent and no sync state. */
|
|
69
|
+
export declare function markTenantDetached(adapters: Pick<DataAdapters, "tenants">, tenantId: string): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* The row work of a detach, in the database `adapters` reads and writes (the
|
|
72
|
+
* raw layer, so secrets are copied as stored). It does not look at the tenant
|
|
73
|
+
* row or change it: the caller checks eligibility and, when the status comes
|
|
74
|
+
* back `detached`, marks the tenant. A tenant worker runs this on its own
|
|
75
|
+
* database while the control plane holds the tenant row that decides.
|
|
76
|
+
* Rows are created before the copies they replace are removed.
|
|
77
|
+
*/
|
|
78
|
+
export declare function detachTenantRows(adapters: DataAdapters, tenantId: string, options: DetachOptions): Promise<DetachResult>;
|
|
79
|
+
/**
|
|
80
|
+
* Detaches `tenantId` from its parent in the database `adapters` reads and
|
|
81
|
+
* writes, which should be the raw layer so secrets are copied as stored
|
|
82
|
+
* (ciphertext).
|
|
83
|
+
*/
|
|
84
|
+
export declare function createInProcessDetach(adapters: DataAdapters): DetachConfigFn;
|
|
85
|
+
//# sourceMappingURL=detach.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detach.d.ts","sourceRoot":"","sources":["../../../src/operations/detach.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,5 +7,9 @@ export type { InlineExecutorConfig, TenantOperationDefinitions, TenantOperationS
|
|
|
7
7
|
export { createOperationRow, enqueueTenantOperation } from "./enqueue";
|
|
8
8
|
export { createInProcessSyncConfig, runSyncDefaultsStep, summarizeSyncResult, syncErrors, syncOptionsOf, } from "./sync-defaults";
|
|
9
9
|
export type { SyncConfigFn, SyncConfigOptions } from "./sync-defaults";
|
|
10
|
+
export { assertDetachEligible, createInProcessDetach, detachTenantRows, emptyDetachResult, markTenantDetached, detachErrors, detachOptionsOf, runDetachStep, summarizeDetachResult, } from "./detach";
|
|
11
|
+
export type { DetachConfigFn, DetachOptions, DetachResult } from "./detach";
|
|
10
12
|
export { runRecordedTenantOperation } from "./record-provision";
|
|
13
|
+
export { MAX_MEMBER_REQUEST_ATTEMPTS, createInProcessMemberRequestStore, enqueueTenantMemberRequest, memberRequestIdOf, reconcileTenantMemberRequests, runTenantMembersRequestStep, } from "./tenant-members-request";
|
|
14
|
+
export type { ReconcileTenantMemberRequestsDeps, ReconcileTenantMemberRequestsResult, RunTenantMembersRequestParams, TenantMemberRequestStore, } from "./tenant-members-request";
|
|
11
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/operations/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,qBAAqB,EACrB,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,YAAY,EACV,oBAAoB,EACpB,0BAA0B,EAC1B,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,EACnB,UAAU,EACV,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/operations/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,qBAAqB,EACrB,uBAAuB,EACvB,4BAA4B,GAC7B,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,YAAY,EACV,oBAAoB,EACpB,0BAA0B,EAC1B,mBAAmB,EACnB,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,EACnB,UAAU,EACV,aAAa,GACd,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACvE,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,aAAa,EACb,qBAAqB,GACtB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EACL,2BAA2B,EAC3B,iCAAiC,EACjC,0BAA0B,EAC1B,iBAAiB,EACjB,6BAA6B,EAC7B,2BAA2B,GAC5B,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,iCAAiC,EACjC,mCAAmC,EACnC,6BAA6B,EAC7B,wBAAwB,GACzB,MAAM,0BAA0B,CAAC"}
|
|
@@ -16,6 +16,8 @@ export interface SyncConfigOptions {
|
|
|
16
16
|
dryRun: boolean;
|
|
17
17
|
/** Apply even when the tenant's stored hash equals the block's. */
|
|
18
18
|
force: boolean;
|
|
19
|
+
/** Remove synced copies the parent no longer shares. */
|
|
20
|
+
prune?: boolean;
|
|
19
21
|
}
|
|
20
22
|
/** Syncs one tenant and returns what happened (or, for a dry run, what would). */
|
|
21
23
|
export type SyncConfigFn = (tenantId: string, options: SyncConfigOptions) => Promise<ApplyResolvedBlockResult>;
|
|
@@ -25,7 +27,8 @@ export declare function syncOptionsOf(operation: Pick<TenantOperation, "input">)
|
|
|
25
27
|
export declare function syncErrors(result: ApplyResolvedBlockResult): string[];
|
|
26
28
|
/**
|
|
27
29
|
* The JSON-serialisable outcome stored in the operation's `result`: the status,
|
|
28
|
-
* hash, per-entity counts
|
|
30
|
+
* hash, per-entity counts, the changed `entity:key` list, the same changes as
|
|
31
|
+
* structured `rows`, and a capped list of the error messages. Never row content
|
|
29
32
|
* or secrets.
|
|
30
33
|
*/
|
|
31
34
|
export declare function summarizeSyncResult(result: ApplyResolvedBlockResult, options: SyncConfigOptions): Record<string, unknown>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-defaults.d.ts","sourceRoot":"","sources":["../../../src/operations/sync-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,EACL,wBAAwB,EAGzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;;GAQG;AAEH,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAC;IAChB,mEAAmE;IACnE,KAAK,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"sync-defaults.d.ts","sourceRoot":"","sources":["../../../src/operations/sync-defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,EACL,wBAAwB,EAGzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;;GAQG;AAEH,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,MAAM,EAAE,OAAO,CAAC;IAChB,mEAAmE;IACnE,KAAK,EAAE,OAAO,CAAC;IACf,wDAAwD;IACxD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,kFAAkF;AAClF,MAAM,MAAM,YAAY,GAAG,CACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,iBAAiB,KACvB,OAAO,CAAC,wBAAwB,CAAC,CAAC;AAEvC,wEAAwE;AACxE,wBAAgB,aAAa,CAC3B,SAAS,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,GACxC,iBAAiB,CAOnB;AAED,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,MAAM,EAAE,wBAAwB,GAAG,MAAM,EAAE,CAErE;AAOD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,wBAAwB,EAChC,OAAO,EAAE,iBAAiB,GACzB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwBzB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE;IAChD,SAAS,EAAE,IAAI,CAAC,eAAe,EAAE,IAAI,GAAG,WAAW,GAAG,OAAO,CAAC,CAAC;IAC/D,UAAU,EAAE,YAAY,CAAC;IACzB,QAAQ,EAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;CAChD,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAqBnC;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE;IACN,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,YAAY,CA8Bd"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { type DataAdapters, type ExecuteTenantMemberRequestOptions, type TenantMemberRequest, type TenantMembersBackend, type TenantOperation } from "authhero";
|
|
2
|
+
import type { OperationRecorder } from "./recorder";
|
|
3
|
+
import type { TenantOperationExecutor, TenantOperationStores } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* The `tenant-members-request` tenant operation (issue #1550): carries out a
|
|
6
|
+
* team change that a tenant registered as a request in its own database.
|
|
7
|
+
*
|
|
8
|
+
* The request lives on the tenant's side, so the operation reaches it through
|
|
9
|
+
* a {@link TenantMemberRequestStore}: in-process for tenants that share the
|
|
10
|
+
* control plane's database, a dispatch push for tenants with their own. The
|
|
11
|
+
* operation's `input` is only `{ request_id }`: what was asked (addresses,
|
|
12
|
+
* ids) stays on the request row, because anyone who can read operations can
|
|
13
|
+
* read `input`.
|
|
14
|
+
*/
|
|
15
|
+
/** How the control plane reads and answers a tenant's requests. */
|
|
16
|
+
export interface TenantMemberRequestStore {
|
|
17
|
+
get(tenantId: string, id: string): Promise<TenantMemberRequest | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Writes the outcome, only while the request is still `pending`. Returns
|
|
20
|
+
* false when it was already finished, which makes a re-run harmless.
|
|
21
|
+
*/
|
|
22
|
+
report(tenantId: string, id: string, outcome: {
|
|
23
|
+
status: "succeeded" | "failed";
|
|
24
|
+
result?: Record<string, unknown> | null;
|
|
25
|
+
error?: string | null;
|
|
26
|
+
}): Promise<boolean>;
|
|
27
|
+
/** Requests still `pending` and created before `olderThan` (ISO 8601). */
|
|
28
|
+
listPending(tenantId: string, options: {
|
|
29
|
+
olderThan: string;
|
|
30
|
+
}): Promise<TenantMemberRequest[]>;
|
|
31
|
+
}
|
|
32
|
+
/** For tenants whose database is the control plane's own. */
|
|
33
|
+
export declare function createInProcessMemberRequestStore(adapters: Pick<DataAdapters, "tenantMemberRequests">): TenantMemberRequestStore;
|
|
34
|
+
/** The request an operation is about, from its `input`. */
|
|
35
|
+
export declare function memberRequestIdOf(operation: Pick<TenantOperation, "input">): string | undefined;
|
|
36
|
+
export interface RunTenantMembersRequestParams {
|
|
37
|
+
operation: Pick<TenantOperation, "id" | "tenant_id" | "input">;
|
|
38
|
+
store: TenantMemberRequestStore;
|
|
39
|
+
/** The control-plane team backend, built without a request in hand. */
|
|
40
|
+
getBackend: () => TenantMembersBackend | Promise<TenantMembersBackend>;
|
|
41
|
+
recorder: Pick<OperationRecorder, "setResult">;
|
|
42
|
+
executeOptions?: ExecuteTenantMemberRequestOptions;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The step both executors run. Reads the request, carries it out against the
|
|
46
|
+
* tenant's team (which checks the tenant and the requester again), and writes
|
|
47
|
+
* the outcome back to the request.
|
|
48
|
+
*
|
|
49
|
+
* - A request that cannot or must not run (the requester left the team, the
|
|
50
|
+
* payload is wrong) is a legitimate outcome: the request is reported
|
|
51
|
+
* `failed` with the reason and the operation `succeeded`, because the
|
|
52
|
+
* control plane did its job. Nothing retries it.
|
|
53
|
+
* - Any other error (the database, the team backend, the write-back) fails the
|
|
54
|
+
* operation and leaves the request `pending`, so a later run or the
|
|
55
|
+
* reconcile sweep tries again. That is safe: the work is idempotent.
|
|
56
|
+
*/
|
|
57
|
+
export declare function runTenantMembersRequestStep(params: RunTenantMembersRequestParams): Promise<Record<string, unknown>>;
|
|
58
|
+
/** How many failed runs a request gets before the sweep gives up on it. */
|
|
59
|
+
export declare const MAX_MEMBER_REQUEST_ATTEMPTS = 5;
|
|
60
|
+
/**
|
|
61
|
+
* Enqueues the operation for one request, once. A notification can arrive
|
|
62
|
+
* twice and the sweep can race it, so an operation that is already pending,
|
|
63
|
+
* running or succeeded for the request is returned instead of a new one.
|
|
64
|
+
*/
|
|
65
|
+
export declare function enqueueTenantMemberRequest(deps: {
|
|
66
|
+
stores: TenantOperationStores;
|
|
67
|
+
executor: TenantOperationExecutor;
|
|
68
|
+
}, tenantId: string, requestId: string, options?: {
|
|
69
|
+
initiatedBy?: string;
|
|
70
|
+
}): Promise<TenantOperation>;
|
|
71
|
+
export interface ReconcileTenantMemberRequestsDeps {
|
|
72
|
+
stores: TenantOperationStores;
|
|
73
|
+
executor: TenantOperationExecutor;
|
|
74
|
+
store: TenantMemberRequestStore;
|
|
75
|
+
/** The tenants to look at, for example the ones with their own database. */
|
|
76
|
+
tenantIds: () => Promise<string[]> | string[];
|
|
77
|
+
/** Requests younger than this are left to the notification. Default 5 minutes. */
|
|
78
|
+
graceMs?: number;
|
|
79
|
+
maxAttempts?: number;
|
|
80
|
+
now?: () => Date;
|
|
81
|
+
}
|
|
82
|
+
export interface ReconcileTenantMemberRequestsResult {
|
|
83
|
+
checked: number;
|
|
84
|
+
enqueued: number;
|
|
85
|
+
gaveUp: number;
|
|
86
|
+
/** Tenants whose requests could not be read, for example an unreachable shard. */
|
|
87
|
+
unreachable: string[];
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Sweep for requests the control plane never ran: the notification was lost,
|
|
91
|
+
* or the run failed. A tenant worker cannot run a cron, so this runs on the
|
|
92
|
+
* control plane. It enqueues the operation for a `pending` request that has
|
|
93
|
+
* none in flight, and after `maxAttempts` failed runs reports the request
|
|
94
|
+
* `failed` so it does not stay pending forever.
|
|
95
|
+
*/
|
|
96
|
+
export declare function reconcileTenantMemberRequests(deps: ReconcileTenantMemberRequestsDeps): Promise<ReconcileTenantMemberRequestsResult>;
|
|
97
|
+
//# sourceMappingURL=tenant-members-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-members-request.d.ts","sourceRoot":"","sources":["../../../src/operations/tenant-members-request.ts"],"names":[],"mappings":"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"}
|
|
@@ -63,6 +63,12 @@ export interface ApplyResolvedBlockOptions {
|
|
|
63
63
|
dryRun?: boolean;
|
|
64
64
|
/** Execute the block's explicit `deletes`. @default false */
|
|
65
65
|
deletes?: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Remove synced copies (`sy` ids) the block no longer carries, e.g. a row the
|
|
68
|
+
* parent stopped sharing. The tenant's own rows are never touched. A dry run
|
|
69
|
+
* lists them as `delete ...` whether or not this is set. @default false
|
|
70
|
+
*/
|
|
71
|
+
prune?: boolean;
|
|
66
72
|
/** Apply even when the stored hash equals the block hash. */
|
|
67
73
|
force?: boolean;
|
|
68
74
|
/**
|
|
@@ -86,6 +92,21 @@ export interface ApplyResolvedBlockResult {
|
|
|
86
92
|
entities: Record<SyncEntity | "emailProvider" | "branding" | "promptSettings", SyncEntityOutcome>;
|
|
87
93
|
/** `<entity>:<key>` of rows that would be/were added, changed or deleted. */
|
|
88
94
|
changes: string[];
|
|
95
|
+
/**
|
|
96
|
+
* The same changes as structured rows, so a reader can tell an added row from
|
|
97
|
+
* a changed one, and a kept one from a removed one. Older senders omit it.
|
|
98
|
+
*/
|
|
99
|
+
rows: SyncChangeRow[];
|
|
100
|
+
}
|
|
101
|
+
export interface SyncChangeRow {
|
|
102
|
+
entity: keyof ApplyResolvedBlockResult["entities"];
|
|
103
|
+
/** The row's key (`strategy:name`, identifier, name, `singleton`, ...). */
|
|
104
|
+
key: string;
|
|
105
|
+
/**
|
|
106
|
+
* `skipped`: the tenant has its own row with this key. `delete`: a copy that
|
|
107
|
+
* is or would be removed (removed only when the apply asked for it).
|
|
108
|
+
*/
|
|
109
|
+
action: "added" | "changed" | "skipped" | "delete";
|
|
89
110
|
}
|
|
90
111
|
export declare function applyResolvedConfigBlock(block: ResolvedConfigBlock, target: DataAdapters, tenantId: string, options?: ApplyResolvedBlockOptions): Promise<ApplyResolvedBlockResult>;
|
|
91
112
|
//# sourceMappingURL=resolved-sync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolved-sync.d.ts","sourceRoot":"","sources":["../../../src/rollout/resolved-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,aAAa,EACb,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,aAAa,EACb,cAAc,
|
|
1
|
+
{"version":3,"file":"resolved-sync.d.ts","sourceRoot":"","sources":["../../../src/rollout/resolved-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,8 @@ export { listRolloutOperations, planRollout } from "./plan";
|
|
|
7
7
|
export type { PlanResult } from "./plan";
|
|
8
8
|
export { advanceRollout, advanceRollouts, pauseRollout, resumeRollout, } from "./advance";
|
|
9
9
|
export type { AdvanceRolloutsOptions, RolloutTickOutcome, RolloutTickResult, } from "./advance";
|
|
10
|
+
export { verifyTenantConfig } from "./verify";
|
|
11
|
+
export type { ConfigSyncDifference, ConfigSyncVerification, VerifyConfigSyncDeps, } from "./verify";
|
|
10
12
|
export { getConfigSyncStatus } from "./status";
|
|
11
13
|
export type { ConfigSyncStatus, ConfigSyncStatusDeps } from "./status";
|
|
12
14
|
export { reconcileConfigDrift } from "./reconcile";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rollouts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,WAAW,EACX,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC5D,YAAY,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EACL,cAAc,EACd,eAAe,EACf,YAAY,EACZ,aAAa,GACd,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EACV,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC3E,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/rollouts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,WAAW,EACX,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC5D,YAAY,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EACL,cAAc,EACd,eAAe,EACf,YAAY,EACZ,aAAa,GACd,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EACV,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC3E,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -3,7 +3,7 @@ export type ConfigSyncStatusDeps = Pick<RolloutDeps, "adapters" | "controlPlaneT
|
|
|
3
3
|
export interface ConfigSyncStatus {
|
|
4
4
|
tenant_id: string;
|
|
5
5
|
parent_tenant_id: string | null;
|
|
6
|
-
config_sync: "inherit-on-read" | "synced";
|
|
6
|
+
config_sync: "inherit-on-read" | "synced" | "detached";
|
|
7
7
|
config_sync_hash: string | null;
|
|
8
8
|
config_synced_at: string | null;
|
|
9
9
|
/** The hash a sync would store now; null for a tenant that is not synced. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/rollouts/status.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,MAAM,MAAM,oBAAoB,GAAG,IAAI,CACrC,WAAW,EACX,UAAU,GAAG,sBAAsB,GAAG,qBAAqB,GAAG,UAAU,CACzE,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,iBAAiB,GAAG,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/rollouts/status.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,MAAM,MAAM,oBAAoB,GAAG,IAAI,CACrC,WAAW,EACX,UAAU,GAAG,sBAAsB,GAAG,qBAAqB,GAAG,UAAU,CACzE,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,iBAAiB,GAAG,QAAQ,GAAG,UAAU,CAAC;IACvD,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,6EAA6E;IAC7E,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,sEAAsE;IACtE,OAAO,EAAE,OAAO,CAAC;IACjB,yDAAyD;IACzD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,oBAAoB,EAC1B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAmFlC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { SyncConfigFn } from "../operations/sync-defaults";
|
|
2
|
+
import type { ConfigSyncStatusDeps } from "./status";
|
|
3
|
+
export interface ConfigSyncDifference {
|
|
4
|
+
entity: string;
|
|
5
|
+
key: string;
|
|
6
|
+
/**
|
|
7
|
+
* `missing`: the tenant lacks a row it should have. `extra`: it has a row it
|
|
8
|
+
* should not. `changed`: the row differs, `fields` names the fields. `stale`:
|
|
9
|
+
* a synced copy the parents no longer publish.
|
|
10
|
+
*/
|
|
11
|
+
kind: "missing" | "extra" | "changed" | "stale";
|
|
12
|
+
fields?: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface ConfigSyncVerification {
|
|
15
|
+
tenant_id: string;
|
|
16
|
+
config_sync: "inherit-on-read" | "synced" | "detached";
|
|
17
|
+
/**
|
|
18
|
+
* How it was checked. `read-time`: what read-time inheritance gives against
|
|
19
|
+
* what the parent chain resolves to. `sync-dry-run`: the tenant's own rows
|
|
20
|
+
* against what a sync would write, which is how a synced tenant, including
|
|
21
|
+
* one with its own database, is checked. `not-applicable`: a detached tenant
|
|
22
|
+
* has no parent to compare with.
|
|
23
|
+
*/
|
|
24
|
+
method: "read-time" | "sync-dry-run" | "not-applicable";
|
|
25
|
+
/** True when there is no difference and no error: the hard pass criterion. */
|
|
26
|
+
ok: boolean;
|
|
27
|
+
/** Ids and field names only, never content or secrets. */
|
|
28
|
+
differences: ConfigSyncDifference[];
|
|
29
|
+
errors: string[];
|
|
30
|
+
}
|
|
31
|
+
export interface VerifyConfigSyncDeps extends ConfigSyncStatusDeps {
|
|
32
|
+
/**
|
|
33
|
+
* Runs a sync as a dry run, which is the read-only check of a synced tenant.
|
|
34
|
+
* A tenant with its own database needs the dispatch transport, as for
|
|
35
|
+
* `sync-defaults`.
|
|
36
|
+
*/
|
|
37
|
+
syncConfig: SyncConfigFn;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Compares one tenant's config with what its parents publish, on demand and
|
|
41
|
+
* read-only (no write, no log). The pass criterion is `ok`: an empty
|
|
42
|
+
* `differences` and no `errors`. Returns null for an unknown tenant.
|
|
43
|
+
*
|
|
44
|
+
* A tenant that inherits on read is compared the way shadow mode does, without
|
|
45
|
+
* the rows only the sync model copies (`expected`). A synced tenant is checked
|
|
46
|
+
* with a sync dry run, which sees the tenant's own rows: a copy someone deleted
|
|
47
|
+
* or edited shows up here although the stored hash still matches.
|
|
48
|
+
*/
|
|
49
|
+
export declare function verifyTenantConfig(deps: VerifyConfigSyncDeps, tenantId: string): Promise<ConfigSyncVerification | null>;
|
|
50
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../../src/rollouts/verify.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;IAChD,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,iBAAiB,GAAG,QAAQ,GAAG,UAAU,CAAC;IACvD;;;;;;OAMG;IACH,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,gBAAgB,CAAC;IACxD,8EAA8E;IAC9E,EAAE,EAAE,OAAO,CAAC;IACZ,0DAA0D;IAC1D,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,oBAAqB,SAAQ,oBAAoB;IAChE;;;;OAIG;IACH,UAAU,EAAE,YAAY,CAAC;CAC1B;AAiCD;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,oBAAoB,EAC1B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,sBAAsB,GAAG,IAAI,CAAC,CA8DxC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenants.d.ts","sourceRoot":"","sources":["../../../src/routes/tenants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAYhE,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EAElB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"tenants.d.ts","sourceRoot":"","sources":["../../../src/routes/tenants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAYhE,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EAElB,MAAM,UAAU,CAAC;AA2DlB;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,kBAAkB,EAC1B,KAAK,EAAE,iBAAiB;cAGZ,oBAAoB;eACnB,qBAAqB;YA8xBnC"}
|
package/dist/types/types.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { CreateTenantParams, DataAdapters, Tenant } from "authhero";
|
|
|
2
2
|
import { Context } from "hono";
|
|
3
3
|
import type { StepReporter } from "./operations/types";
|
|
4
4
|
import type { ConfigSyncStatus } from "./rollouts/status";
|
|
5
|
+
import type { ConfigSyncVerification } from "./rollouts/verify";
|
|
5
6
|
/**
|
|
6
7
|
* Bindings type from authhero core - simplified version for this package
|
|
7
8
|
*/
|
|
@@ -213,10 +214,17 @@ export interface MultiTenancyConfig {
|
|
|
213
214
|
* Supplied by `initMultiTenant`; the route is not mounted without it.
|
|
214
215
|
*/
|
|
215
216
|
configSyncStatus?: (tenantId: string) => Promise<ConfigSyncStatus | null>;
|
|
217
|
+
/**
|
|
218
|
+
* Compares a tenant's config with what its parents publish, for
|
|
219
|
+
* `GET /tenants/{id}/config-sync/verify`. Supplied by `initMultiTenant`; the
|
|
220
|
+
* route is not mounted without it.
|
|
221
|
+
*/
|
|
222
|
+
verifyConfigSync?: (tenantId: string) => Promise<ConfigSyncVerification | null>;
|
|
216
223
|
/**
|
|
217
224
|
* Called after a tenant is created or its `config_sync` mode is changed, so
|
|
218
225
|
* the sync mode the runtime remembers for it is dropped. Other isolates still
|
|
219
|
-
* take up to the resolver's TTL (
|
|
226
|
+
* take up to the resolver's TTL (`configSyncCacheTtlMs`, 10 s by default) to
|
|
227
|
+
* notice. Supplied by `initMultiTenant`.
|
|
220
228
|
*/
|
|
221
229
|
onConfigSyncChange?: (tenantId: string) => void;
|
|
222
230
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TenantsDataAdapter } from "@authhero/adapter-interfaces";
|
|
2
|
+
/**
|
|
3
|
+
* The computed fields the settings routes add to the tenant (not persisted):
|
|
4
|
+
* `is_control_plane`, and `has_children`, true when another tenant inherits
|
|
5
|
+
* from it. Every other tenant sits below the control plane (a tenant without a
|
|
6
|
+
* parent inherits from it), so the control plane has children as soon as it is
|
|
7
|
+
* not alone; any other tenant needs a tenant that names it as its parent.
|
|
8
|
+
*/
|
|
9
|
+
export declare function computedTenantFields(tenants: TenantsDataAdapter, tenantId: string, controlPlaneTenantId: string | undefined): Promise<{
|
|
10
|
+
is_control_plane: boolean;
|
|
11
|
+
has_children: boolean;
|
|
12
|
+
}>;
|
|
13
|
+
//# sourceMappingURL=tenant-settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-settings.d.ts","sourceRoot":"","sources":["../../../src/utils/tenant-settings.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAEnB,MAAM,8BAA8B,CAAC;AAEtC;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,EAAE,MAAM,EAChB,oBAAoB,EAAE,MAAM,GAAG,SAAS,GACvC,OAAO,CAAC;IAAE,gBAAgB,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAAC,CAc/D"}
|