@stratum-hq/sdk 1.0.1 → 1.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.
package/README.md CHANGED
@@ -5,7 +5,7 @@ HTTP client, LRU cache, and Express/Fastify middleware for the [Stratum](https:/
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install @stratum-hq/sdk @stratum-hq/core
8
+ npm install @stratum-hq/sdk @stratum-hq/core jsonwebtoken
9
9
  ```
10
10
 
11
11
  ## Quick Start
@@ -18,11 +18,19 @@ const s = stratum({
18
18
  apiKey: "sk_live_your_key",
19
19
  });
20
20
 
21
+ // The tenant binding comes from a signed token, so the server does not start
22
+ // without the key that verifies it. Without jwtSecret, the middleware reads
23
+ // the tenant from the X-Tenant-ID header instead.
24
+ const jwtSecret = process.env.JWT_SECRET;
25
+ if (!jwtSecret) {
26
+ throw new Error("JWT_SECRET is required to verify bearer tokens.");
27
+ }
28
+
21
29
  // Express
22
- app.use(s.middleware({ jwtClaimPath: "tenant_id" }));
30
+ app.use(s.middleware({ jwtClaimPath: "tenant_id", jwtSecret }));
23
31
 
24
32
  // Fastify
25
- app.register(s.plugin({ jwtClaimPath: "tenant_id" }));
33
+ app.register(s.plugin({ jwtClaimPath: "tenant_id", jwtSecret }));
26
34
 
27
35
  // Direct client access
28
36
  const ctx = await s.client.resolveTenant("tenant-uuid");
@@ -39,10 +47,14 @@ const client = new StratumClient({
39
47
  cache: { enabled: true, ttlMs: 60000, maxSize: 100 },
40
48
  });
41
49
 
50
+ const jwtSecret = process.env.JWT_SECRET;
51
+ if (!jwtSecret) {
52
+ throw new Error("JWT_SECRET is required to verify bearer tokens.");
53
+ }
54
+
42
55
  app.use(expressMiddleware(client, {
43
56
  jwtClaimPath: "tenant_id",
44
- jwtSecret: process.env.JWT_SECRET,
45
- headerName: "X-Tenant-ID",
57
+ jwtSecret,
46
58
  }));
47
59
 
48
60
  app.get("/data", (req, res) => {
@@ -52,21 +64,72 @@ app.get("/data", (req, res) => {
52
64
 
53
65
  ## Features
54
66
 
55
- - **`StratumClient`** — HTTP client for the control plane API (`resolveTenant`, `getTenantTree`, `createTenant`, `createWebhook`, `listRegions`, …) with a built-in LRU cache that auto-invalidates on mutations.
67
+ - **`StratumClient`** — HTTP client for the control plane API (`resolveTenant`, `getTenantTree`, `createTenant`, `createWebhook`, `listRegions`, …) with a built-in LRU cache. Mutations made through the client invalidate affected entries (a move clears the whole cache); changes made elsewhere, such as a suspension or a config or permission change, are picked up when the entry expires, so the cache TTL (`cache.ttlMs`, default 60s) bounds how stale a context can be.
56
68
  - **`expressMiddleware` / `fastifyPlugin`** — resolve the tenant from a JWT claim, `X-Tenant-ID` header, or custom resolvers (tried in that order), then populate `req.tenant`.
57
69
  - **AsyncLocalStorage context** — `getTenantContext()` and `runWithTenantContext()` make the resolved context available to services that never see the request object.
58
70
  - **Custom resolvers** — supply async functions (e.g. subdomain- or query-based) via the `resolvers` option.
59
71
 
60
- JWT resolution activates only when `jwtSecret` or `jwtVerify` is provided; otherwise Bearer tokens are ignored. If no tenant is found, the middleware returns `400 MISSING_TENANT`.
72
+ JWT resolution activates only when `jwtSecret` or `jwtVerify` is provided; otherwise Bearer tokens are ignored. When it is active, the verified JWT is the tenant binding: a Bearer token that fails verification is rejected with `401 INVALID_TOKEN`, and the tenant header is not read unless you set `trustTenantHeader: true`. If no tenant is found, the middleware returns `400 MISSING_TENANT`.
73
+
74
+ `jwtSecret` verifies HS256 tokens with [`jsonwebtoken`](https://www.npmjs.com/package/jsonwebtoken), an optional peer dependency: install it alongside the SDK (`npm install jsonwebtoken`) or pass `jwtVerify` instead. The middleware throws at construction if `jwtSecret` is set and `jsonwebtoken` cannot be loaded.
75
+
76
+ `headerName` replaces the default `X-Tenant-ID` header: when it is set, only that header is read.
77
+
78
+ ## Archive or purge a tenant
79
+
80
+ `archiveTenant` and `purgeTenant` do different things. Choose the correct one before you call it.
81
+
82
+ - `archiveTenant(id)` is a soft delete. The tenant row and its data stay in the database, and the archive is reversible.
83
+ - `purgeTenant(id)` permanently deletes the tenant and its data (GDPR Article 17). You cannot undo a purge. The API key must have the `admin` scope, and the tenant must have no children. For a tenant with its own schema or database, the control plane also drops that schema or database. Rows in your own tables that share a database with other tenants stay: delete them yourself.
84
+
85
+ `deleteTenant(id)` is deprecated. It sends the same request as `archiveTenant`, so it does not remove data.
61
86
 
62
87
  ## Error Handling
63
88
 
64
89
  The SDK throws typed errors from `@stratum-hq/core`:
65
90
 
66
91
  ```typescript
67
- import { TenantNotFoundError, UnauthorizedError } from "@stratum-hq/core";
92
+ import {
93
+ ForbiddenError,
94
+ RegionInUseError,
95
+ RegionNotActiveError,
96
+ RegionNotFoundError,
97
+ TenantArchivedError,
98
+ TenantNotFoundError,
99
+ TenantSuspendedError,
100
+ UnauthorizedError,
101
+ ValidationError,
102
+ WebhookNotFoundError,
103
+ } from "@stratum-hq/core";
68
104
  ```
69
105
 
106
+ | Control plane response | Error |
107
+ |---|---|
108
+ | 400 `VALIDATION_ERROR` | `ValidationError`, with the issues in `details.issues` |
109
+ | 400, any other code | `Error`, with the control plane's message |
110
+ | 401 | `UnauthorizedError` |
111
+ | 403 `TENANT_SUSPENDED` | `TenantSuspendedError` |
112
+ | 403, any other code | `ForbiddenError` |
113
+ | 404 `TENANT_NOT_FOUND` | `TenantNotFoundError` |
114
+ | 404 `WEBHOOK_NOT_FOUND` | `WebhookNotFoundError` |
115
+ | 404 `REGION_NOT_FOUND` | `RegionNotFoundError` |
116
+ | 404, any other code | `Error`, with the control plane's message |
117
+ | 409 `REGION_IN_USE` | `RegionInUseError`, with the region ID in `details.region_id` |
118
+ | 409 `REGION_NOT_ACTIVE` | `RegionNotActiveError`, with the region ID in `details.region_id`. Only `POST /api/v1/tenants/{id}/migrate-region` sends this code, and the SDK has no method for that route yet. |
119
+ | 410 `TENANT_ARCHIVED` | `TenantArchivedError` |
120
+
121
+ An API key that is scoped to a tenant gets `ForbiddenError` (403 `FORBIDDEN`) for a descendant that is suspended or archived, not `TenantSuspendedError` or `TenantArchivedError`. An API key without the `admin` scope gets `ForbiddenError` from an admin operation, for example `purgeTenant`.
122
+
123
+ The middleware answers these tenant errors with 404, 403, or 410, for the caller's tenant and for an impersonation target, and does not call `onError` for them. A control plane timeout gets 504 `CONTROL_PLANE_TIMEOUT`. An `UnauthorizedError` for the SDK's own API key gets 500 `CONTROL_PLANE_AUTH_FAILED` and a `console.error` line. The middleware calls `onError` for these two. Other errors go to your framework's error handler. Other adapters can use the same mapping: import `tenantErrorResponse` and `controlPlaneErrorResponse`.
124
+
125
+ Each control plane request has a time limit of `timeoutMs` milliseconds (default 10000). A request that takes longer rejects with a `TimeoutError` `DOMException`. The value must be an integer from 1 to 4294967295, or `Infinity` to turn the time limit off. Any other value makes the constructor throw a `RangeError`:
126
+
127
+ ```typescript
128
+ const client = new StratumClient({ controlPlaneUrl, apiKey, timeoutMs: 5000 });
129
+ ```
130
+
131
+ A timeout does not mean that the operation failed. If `purgeTenant` times out, the purge can still complete. Call `getTenant(id)` to find out.
132
+
70
133
  ## Links
71
134
 
72
135
  - Documentation: https://docs.stratum-hq.org/packages/sdk/
package/dist/client.d.ts CHANGED
@@ -8,6 +8,16 @@ export interface StratumClientOptions {
8
8
  ttlMs?: number;
9
9
  maxSize?: number;
10
10
  };
11
+ /**
12
+ * Time limit in milliseconds for each control plane request, including the
13
+ * response body. A request that exceeds it rejects with a `TimeoutError`
14
+ * DOMException. Default: 10000.
15
+ *
16
+ * The value must be an integer from 1 to 4294967295, or `Infinity`.
17
+ * `Infinity` turns the time limit off. Any other value makes the
18
+ * constructor throw a `RangeError`.
19
+ */
20
+ timeoutMs?: number;
11
21
  }
12
22
  export declare class StratumClient {
13
23
  private readonly baseUrl;
@@ -15,6 +25,7 @@ export declare class StratumClient {
15
25
  private readonly regionUrl;
16
26
  private readonly cache;
17
27
  private readonly cacheEnabled;
28
+ private readonly timeoutMs;
18
29
  constructor(options: StratumClientOptions);
19
30
  private fetch;
20
31
  resolveTenant(tenantId: string): Promise<ResolvedTenantContext>;
@@ -24,7 +35,34 @@ export declare class StratumClient {
24
35
  updateTenant(tenantId: string, input: UpdateTenantInput): Promise<TenantNode>;
25
36
  moveTenant(tenantId: string, input: MoveTenantInput): Promise<TenantNode>;
26
37
  archiveTenant(tenantId: string): Promise<void>;
38
+ /**
39
+ * Archive the tenant. This is a soft delete, and it is identical to `archiveTenant`.
40
+ *
41
+ * The tenant row and its data stay in the database, and the archive is reversible.
42
+ * To remove the tenant data permanently, call `purgeTenant`.
43
+ *
44
+ * @deprecated The name suggests that the data is removed. Use `archiveTenant` for
45
+ * a soft delete, or `purgeTenant` for an irreversible hard delete.
46
+ */
27
47
  deleteTenant(tenantId: string): Promise<void>;
48
+ /**
49
+ * Permanently remove the tenant and its Stratum records (GDPR Article 17). You cannot undo this.
50
+ *
51
+ * The control plane deletes the tenant row and the tenant's records in the Stratum tables:
52
+ * config, permissions, API keys, roles, webhooks, consent records and audit logs.
53
+ * For a tenant with its own schema or database, it also drops that schema or database.
54
+ * For a pending tenant, the purge removes the records and never drops storage.
55
+ * Rows in your own tables that share a database with other tenants stay; delete them yourself.
56
+ * The API key must have the `admin` scope.
57
+ *
58
+ * @param tenantId - The id of the tenant to purge. The tenant must have no children.
59
+ * @returns A promise that rejects when the control plane refuses the purge, for example
60
+ * because the tenant has children, or with `ForbiddenError` because the API key does not
61
+ * have the `admin` scope. A rejection with a `TimeoutError` does not mean that the purge
62
+ * failed: the control plane can complete it after the client stops waiting. Call
63
+ * `getTenant` to find out whether the tenant still exists.
64
+ */
65
+ purgeTenant(tenantId: string): Promise<void>;
28
66
  invalidateCache(tenantId: string): void;
29
67
  clearCache(): void;
30
68
  createWebhook(input: CreateWebhookInput): Promise<Webhook>;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -3,17 +3,121 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.StratumClient = void 0;
4
4
  const core_1 = require("@stratum-hq/core");
5
5
  const cache_js_1 = require("./cache.js");
6
+ const DEFAULT_TIMEOUT_MS = 10_000;
7
+ // The largest delay that AbortSignal.timeout accepts.
8
+ const MAX_TIMEOUT_MS = 4_294_967_295;
9
+ function validTimeoutMs(value) {
10
+ if (value === Number.POSITIVE_INFINITY)
11
+ return value;
12
+ if (!Number.isInteger(value) || value < 1 || value > MAX_TIMEOUT_MS) {
13
+ throw new RangeError(`timeoutMs must be an integer from 1 to ${MAX_TIMEOUT_MS}, or Infinity to turn the time limit off. Received ${value}`);
14
+ }
15
+ return value;
16
+ }
17
+ /**
18
+ * Give a typed error the control plane's own message. The core error
19
+ * constructors add a prefix, and the control plane message already has it.
20
+ */
21
+ function withMessage(err, message) {
22
+ if (message)
23
+ err.message = message;
24
+ return err;
25
+ }
26
+ /**
27
+ * Map a failed control plane response to the core error class for its status
28
+ * and error code. A response without a typed error becomes a plain Error.
29
+ */
30
+ function responseError(status, body) {
31
+ // Fastify's default 404 body has a string `error`, so it has no code.
32
+ const error = typeof body.error === "object" && body.error !== null ? body.error : undefined;
33
+ const code = error?.code;
34
+ const message = error?.message;
35
+ const rawTenantId = error?.details?.tenant_id;
36
+ const tenantId = typeof rawTenantId === "string" ? rawTenantId : "unknown";
37
+ const rawRegionId = error?.details?.region_id;
38
+ const regionId = typeof rawRegionId === "string" ? rawRegionId : "unknown";
39
+ if (status === 400 && code === core_1.ErrorCode.VALIDATION_ERROR) {
40
+ const details = isObject(error?.details) ? error.details : undefined;
41
+ const legacyIssues = error?.issues;
42
+ // An older control plane sends the issues only in the deprecated error.issues field.
43
+ if (!Array.isArray(details?.issues) && Array.isArray(legacyIssues)) {
44
+ return new core_1.ValidationError(message ?? "Validation failed", { ...details, issues: legacyIssues });
45
+ }
46
+ return new core_1.ValidationError(message ?? "Validation failed", details);
47
+ }
48
+ // Every route can answer 404, so only the error code tells what is missing.
49
+ if (status === 404 && code === core_1.ErrorCode.TENANT_NOT_FOUND) {
50
+ return withMessage(new core_1.TenantNotFoundError(tenantId), message);
51
+ }
52
+ if (status === 404 && code === core_1.ErrorCode.WEBHOOK_NOT_FOUND) {
53
+ return withMessage(new core_1.WebhookNotFoundError("unknown"), message);
54
+ }
55
+ if (status === 404 && code === core_1.ErrorCode.REGION_NOT_FOUND) {
56
+ return withMessage(new core_1.RegionNotFoundError(regionId), message);
57
+ }
58
+ if (status === 409 && code === core_1.ErrorCode.REGION_IN_USE) {
59
+ return withMessage(new core_1.RegionInUseError(regionId), message);
60
+ }
61
+ if (status === 409 && code === core_1.ErrorCode.REGION_NOT_ACTIVE) {
62
+ return withMessage(new core_1.RegionNotActiveError(regionId), message);
63
+ }
64
+ if (status === 403) {
65
+ return code === core_1.ErrorCode.TENANT_SUSPENDED
66
+ ? withMessage(new core_1.TenantSuspendedError(tenantId), message)
67
+ : new core_1.ForbiddenError(message);
68
+ }
69
+ if (status === 410 && code === core_1.ErrorCode.TENANT_ARCHIVED) {
70
+ return withMessage(new core_1.TenantArchivedError(tenantId), message);
71
+ }
72
+ return new Error(message ?? `HTTP ${status}`);
73
+ }
74
+ /**
75
+ * Encode an ID for use as a single URL path segment. Dot segments are refused
76
+ * because URL parsing would resolve them against the surrounding path.
77
+ */
78
+ function pathSegment(id) {
79
+ if (id === "" || id === "." || id === "..") {
80
+ throw new Error("Invalid identifier");
81
+ }
82
+ return encodeURIComponent(id);
83
+ }
84
+ function cacheKey(tenantId) {
85
+ return tenantId.toLowerCase();
86
+ }
87
+ function isObject(value) {
88
+ return typeof value === "object" && value !== null && !Array.isArray(value);
89
+ }
90
+ /**
91
+ * Check that a /context response is a ResolvedTenantContext for the requested
92
+ * tenant. Anything else fails closed rather than being bound as the request's
93
+ * tenant.
94
+ */
95
+ function assertResolvedTenantContext(value, tenantId) {
96
+ const ok = isObject(value) &&
97
+ typeof value["tenant_id"] === "string" &&
98
+ value["tenant_id"].toLowerCase() === tenantId.toLowerCase() &&
99
+ typeof value["ancestry_path"] === "string" &&
100
+ typeof value["depth"] === "number" &&
101
+ isObject(value["resolved_config"]) &&
102
+ isObject(value["resolved_permissions"]) &&
103
+ typeof value["isolation_strategy"] === "string";
104
+ if (!ok) {
105
+ throw new Error("Control plane returned an invalid tenant context");
106
+ }
107
+ }
6
108
  class StratumClient {
7
109
  baseUrl;
8
110
  apiKey;
9
111
  regionUrl;
10
112
  cache;
11
113
  cacheEnabled;
114
+ timeoutMs;
12
115
  constructor(options) {
13
116
  this.baseUrl = options.controlPlaneUrl.replace(/\/$/, "");
14
117
  this.apiKey = options.apiKey;
15
118
  this.regionUrl = options.regionUrl?.replace(/\/$/, "");
16
119
  this.cacheEnabled = options.cache?.enabled !== false;
120
+ this.timeoutMs = validTimeoutMs(options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
17
121
  this.cache = new cache_js_1.LRUCache({
18
122
  ttlMs: options.cache?.ttlMs,
19
123
  maxSize: options.cache?.maxSize,
@@ -23,8 +127,10 @@ class StratumClient {
23
127
  const url = `${this.baseUrl}${path}`;
24
128
  const response = await globalThis.fetch(url, {
25
129
  ...init,
130
+ signal: this.timeoutMs === Number.POSITIVE_INFINITY ? undefined : AbortSignal.timeout(this.timeoutMs),
26
131
  headers: {
27
- "Content-Type": "application/json",
132
+ // The control plane rejects the JSON content type on an empty body.
133
+ ...(init?.body !== undefined ? { "Content-Type": "application/json" } : {}),
28
134
  "X-API-Key": this.apiKey,
29
135
  ...init?.headers,
30
136
  },
@@ -33,32 +139,33 @@ class StratumClient {
33
139
  if (response.status === 401) {
34
140
  throw new core_1.UnauthorizedError("Invalid or missing API key");
35
141
  }
36
- if (response.status === 404) {
37
- const body = await response.json().catch(() => ({}));
38
- throw new core_1.TenantNotFoundError(body?.error?.message ?? "unknown");
39
- }
40
142
  const body = await response.json().catch(() => ({}));
41
- throw new Error(body?.error?.message ?? `HTTP ${response.status}`);
143
+ throw responseError(response.status, body ?? {});
42
144
  }
43
145
  if (response.status === 204)
44
146
  return undefined;
45
147
  return response.json();
46
148
  }
47
149
  async resolveTenant(tenantId) {
150
+ if (tenantId === "" || tenantId === "." || tenantId === "..") {
151
+ throw new core_1.TenantNotFoundError(tenantId);
152
+ }
153
+ const path = `/api/v1/tenants/${pathSegment(tenantId)}/context`;
48
154
  if (this.cacheEnabled) {
49
- const cached = this.cache.get(tenantId);
155
+ const cached = this.cache.get(cacheKey(tenantId));
50
156
  if (cached)
51
157
  return cached;
52
158
  }
53
- const context = await this.fetch(`/api/v1/tenants/${tenantId}/context`);
159
+ const context = await this.fetch(path);
160
+ assertResolvedTenantContext(context, tenantId);
54
161
  if (this.cacheEnabled) {
55
- this.cache.set(tenantId, context);
162
+ this.cache.set(cacheKey(tenantId), context);
56
163
  }
57
164
  return context;
58
165
  }
59
166
  async getTenantTree(rootId) {
60
167
  if (rootId) {
61
- return this.fetch(`/api/v1/tenants/${rootId}/descendants`);
168
+ return this.fetch(`/api/v1/tenants/${pathSegment(rootId)}/descendants`);
62
169
  }
63
170
  const result = await this.fetch(`/api/v1/tenants`);
64
171
  return result.data;
@@ -70,38 +177,76 @@ class StratumClient {
70
177
  });
71
178
  }
72
179
  async getTenant(tenantId) {
73
- return this.fetch(`/api/v1/tenants/${tenantId}`);
180
+ return this.fetch(`/api/v1/tenants/${pathSegment(tenantId)}`);
74
181
  }
75
182
  async updateTenant(tenantId, input) {
76
- const node = await this.fetch(`/api/v1/tenants/${tenantId}`, {
183
+ const node = await this.fetch(`/api/v1/tenants/${pathSegment(tenantId)}`, {
77
184
  method: "PATCH",
78
185
  body: JSON.stringify(input),
79
186
  });
80
- this.cache.invalidate(tenantId);
187
+ this.cache.invalidate(cacheKey(tenantId));
81
188
  return node;
82
189
  }
83
190
  async moveTenant(tenantId, input) {
84
- const node = await this.fetch(`/api/v1/tenants/${tenantId}/move`, {
191
+ const node = await this.fetch(`/api/v1/tenants/${pathSegment(tenantId)}/move`, {
85
192
  method: "POST",
86
193
  body: JSON.stringify(input),
87
194
  });
88
- this.cache.invalidate(tenantId);
195
+ // Descendants' cached ancestry, config and permissions change with the move.
196
+ this.cache.clear();
89
197
  return node;
90
198
  }
91
199
  async archiveTenant(tenantId) {
92
- await this.fetch(`/api/v1/tenants/${tenantId}`, {
200
+ await this.fetch(`/api/v1/tenants/${pathSegment(tenantId)}`, {
93
201
  method: "DELETE",
94
202
  });
95
- this.cache.invalidate(tenantId);
203
+ this.cache.invalidate(cacheKey(tenantId));
96
204
  }
205
+ /**
206
+ * Archive the tenant. This is a soft delete, and it is identical to `archiveTenant`.
207
+ *
208
+ * The tenant row and its data stay in the database, and the archive is reversible.
209
+ * To remove the tenant data permanently, call `purgeTenant`.
210
+ *
211
+ * @deprecated The name suggests that the data is removed. Use `archiveTenant` for
212
+ * a soft delete, or `purgeTenant` for an irreversible hard delete.
213
+ */
97
214
  async deleteTenant(tenantId) {
98
- await this.fetch(`/api/v1/tenants/${tenantId}`, {
215
+ await this.fetch(`/api/v1/tenants/${pathSegment(tenantId)}`, {
99
216
  method: "DELETE",
100
217
  });
101
- this.cache.invalidate(tenantId);
218
+ this.cache.invalidate(cacheKey(tenantId));
219
+ }
220
+ /**
221
+ * Permanently remove the tenant and its Stratum records (GDPR Article 17). You cannot undo this.
222
+ *
223
+ * The control plane deletes the tenant row and the tenant's records in the Stratum tables:
224
+ * config, permissions, API keys, roles, webhooks, consent records and audit logs.
225
+ * For a tenant with its own schema or database, it also drops that schema or database.
226
+ * For a pending tenant, the purge removes the records and never drops storage.
227
+ * Rows in your own tables that share a database with other tenants stay; delete them yourself.
228
+ * The API key must have the `admin` scope.
229
+ *
230
+ * @param tenantId - The id of the tenant to purge. The tenant must have no children.
231
+ * @returns A promise that rejects when the control plane refuses the purge, for example
232
+ * because the tenant has children, or with `ForbiddenError` because the API key does not
233
+ * have the `admin` scope. A rejection with a `TimeoutError` does not mean that the purge
234
+ * failed: the control plane can complete it after the client stops waiting. Call
235
+ * `getTenant` to find out whether the tenant still exists.
236
+ */
237
+ async purgeTenant(tenantId) {
238
+ try {
239
+ await this.fetch(`/api/v1/tenants/${pathSegment(tenantId)}/purge`, {
240
+ method: "POST",
241
+ });
242
+ }
243
+ finally {
244
+ // A failed request can still have purged the tenant, so the cached context goes either way.
245
+ this.cache.invalidate(cacheKey(tenantId));
246
+ }
102
247
  }
103
248
  invalidateCache(tenantId) {
104
- this.cache.invalidate(tenantId);
249
+ this.cache.invalidate(cacheKey(tenantId));
105
250
  }
106
251
  clearCache() {
107
252
  this.cache.clear();
@@ -119,21 +264,21 @@ class StratumClient {
119
264
  return this.fetch(path);
120
265
  }
121
266
  async getWebhook(id) {
122
- return this.fetch(`/api/v1/webhooks/${id}`);
267
+ return this.fetch(`/api/v1/webhooks/${pathSegment(id)}`);
123
268
  }
124
269
  async updateWebhook(id, input) {
125
- return this.fetch(`/api/v1/webhooks/${id}`, {
270
+ return this.fetch(`/api/v1/webhooks/${pathSegment(id)}`, {
126
271
  method: "PATCH",
127
272
  body: JSON.stringify(input),
128
273
  });
129
274
  }
130
275
  async deleteWebhook(id) {
131
- await this.fetch(`/api/v1/webhooks/${id}`, {
276
+ await this.fetch(`/api/v1/webhooks/${pathSegment(id)}`, {
132
277
  method: "DELETE",
133
278
  });
134
279
  }
135
280
  async rotateApiKey(keyId, name) {
136
- return this.fetch(`/api/v1/api-keys/${keyId}/rotate`, {
281
+ return this.fetch(`/api/v1/api-keys/${pathSegment(keyId)}/rotate`, {
137
282
  method: "POST",
138
283
  body: JSON.stringify(name ? { name } : {}),
139
284
  });
@@ -161,13 +306,13 @@ class StratumClient {
161
306
  });
162
307
  }
163
308
  async updateRegion(id, input) {
164
- return this.fetch(`/api/v1/regions/${id}`, {
309
+ return this.fetch(`/api/v1/regions/${pathSegment(id)}`, {
165
310
  method: "PATCH",
166
311
  body: JSON.stringify(input),
167
312
  });
168
313
  }
169
314
  async deleteRegion(id) {
170
- await this.fetch(`/api/v1/regions/${id}`, {
315
+ await this.fetch(`/api/v1/regions/${pathSegment(id)}`, {
171
316
  method: "DELETE",
172
317
  });
173
318
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -24,8 +24,12 @@ export type { StratumClientOptions } from "./client.js";
24
24
  export { getTenantContext, runWithTenantContext, setTenantContext } from "./context.js";
25
25
  export { expressMiddleware } from "./middleware/express.js";
26
26
  export { fastifyPlugin } from "./middleware/fastify.js";
27
+ export { tenantErrorResponse, controlPlaneErrorResponse } from "./middleware/tenant-errors.js";
28
+ export type { TenantErrorResponse } from "./middleware/tenant-errors.js";
27
29
  export { resolveFromHeader } from "./resolvers/header.js";
28
- export { resolveFromJwt } from "./resolvers/jwt.js";
30
+ export { resolveFromJwt, assertJwtSupport } from "./resolvers/jwt.js";
31
+ export { resolveTenantId } from "./resolvers/resolve.js";
32
+ export type { TenantIdResolution } from "./resolvers/resolve.js";
29
33
  export type { TenantResolver } from "./resolvers/custom.js";
30
34
  export type { MiddlewareOptions } from "./types.js";
31
35
  export type { ResolvedTenantContext, TenantNode, CreateTenantInput, UpdateTenantInput, MoveTenantInput, ResolvedPermission, } from "@stratum-hq/core";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,wBAAgB,OAAO,CAAC,OAAO,EAAE,oBAAoB;;wBAI7B,iBAAiB;;;;;;;;;;oBACrB,iBAAiB,MAE7B,SAAS,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,EAC5C,OAAO,OAAO,EACd,MAAM,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;;;EAMhD;AAGD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGpD,YAAY,EACV,qBAAqB,EACrB,UAAU,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,GACnB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,wBAAgB,OAAO,CAAC,OAAO,EAAE,oBAAoB;;wBAI7B,iBAAiB;;;;;;;;;;oBACrB,iBAAiB,eAEpB,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,SACrC,OAAO,QACR,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;;;EAShD;AAGD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC/F,YAAY,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGpD,YAAY,EACV,qBAAqB,EACrB,UAAU,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,GACnB,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveFromJwt = exports.resolveFromHeader = exports.fastifyPlugin = exports.expressMiddleware = exports.setTenantContext = exports.runWithTenantContext = exports.getTenantContext = exports.StratumClient = void 0;
3
+ exports.resolveTenantId = exports.assertJwtSupport = exports.resolveFromJwt = exports.resolveFromHeader = exports.controlPlaneErrorResponse = exports.tenantErrorResponse = exports.fastifyPlugin = exports.expressMiddleware = exports.setTenantContext = exports.runWithTenantContext = exports.getTenantContext = exports.StratumClient = void 0;
4
4
  exports.stratum = stratum;
5
5
  const client_js_1 = require("./client.js");
6
6
  const express_js_1 = require("./middleware/express.js");
@@ -11,7 +11,12 @@ function stratum(options) {
11
11
  return {
12
12
  client,
13
13
  middleware: (opts) => (0, express_js_1.expressMiddleware)(client, opts),
14
- plugin: (opts) => (fastify, _opts, done) => (0, fastify_js_1.fastifyPlugin)(fastify, { client, ...opts }, done),
14
+ plugin: (opts) => {
15
+ const plugin = (fastify, _opts, done) => (0, fastify_js_1.fastifyPlugin)(fastify, { client, ...opts }, done);
16
+ // Same non-encapsulated registration as fastifyPlugin itself.
17
+ plugin[Symbol.for("skip-override")] = true;
18
+ return plugin;
19
+ },
15
20
  getTenantContext: context_js_1.getTenantContext,
16
21
  runWithTenantContext: context_js_1.runWithTenantContext,
17
22
  };
@@ -27,8 +32,14 @@ var express_js_2 = require("./middleware/express.js");
27
32
  Object.defineProperty(exports, "expressMiddleware", { enumerable: true, get: function () { return express_js_2.expressMiddleware; } });
28
33
  var fastify_js_2 = require("./middleware/fastify.js");
29
34
  Object.defineProperty(exports, "fastifyPlugin", { enumerable: true, get: function () { return fastify_js_2.fastifyPlugin; } });
35
+ var tenant_errors_js_1 = require("./middleware/tenant-errors.js");
36
+ Object.defineProperty(exports, "tenantErrorResponse", { enumerable: true, get: function () { return tenant_errors_js_1.tenantErrorResponse; } });
37
+ Object.defineProperty(exports, "controlPlaneErrorResponse", { enumerable: true, get: function () { return tenant_errors_js_1.controlPlaneErrorResponse; } });
30
38
  var header_js_1 = require("./resolvers/header.js");
31
39
  Object.defineProperty(exports, "resolveFromHeader", { enumerable: true, get: function () { return header_js_1.resolveFromHeader; } });
32
40
  var jwt_js_1 = require("./resolvers/jwt.js");
33
41
  Object.defineProperty(exports, "resolveFromJwt", { enumerable: true, get: function () { return jwt_js_1.resolveFromJwt; } });
42
+ Object.defineProperty(exports, "assertJwtSupport", { enumerable: true, get: function () { return jwt_js_1.assertJwtSupport; } });
43
+ var resolve_js_1 = require("./resolvers/resolve.js");
44
+ Object.defineProperty(exports, "resolveTenantId", { enumerable: true, get: function () { return resolve_js_1.resolveTenantId; } });
34
45
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAOA,0BAeC;AAtBD,2CAA4C;AAE5C,wDAA4D;AAC5D,wDAAwD;AACxD,6CAAsE;AAGtE,SAAgB,OAAO,CAAC,OAA6B;IACnD,MAAM,MAAM,GAAG,IAAI,yBAAa,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO;QACL,MAAM;QACN,UAAU,EAAE,CAAC,IAAwB,EAAE,EAAE,CAAC,IAAA,8BAAiB,EAAC,MAAM,EAAE,IAAI,CAAC;QACzE,MAAM,EAAE,CAAC,IAAwB,EAAE,EAAE,CACnC,CACE,OAA4C,EAC5C,KAAc,EACd,IAAyC,EACzC,EAAE,CACF,IAAA,0BAAa,EAAC,OAAO,EAAE,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,IAAI,CAAC;QACrD,gBAAgB,EAAhB,6BAAgB;QAChB,oBAAoB,EAApB,iCAAoB;KACrB,CAAC;AACJ,CAAC;AAED,iCAAiC;AACjC,yCAA4C;AAAnC,0GAAA,aAAa,OAAA;AAEtB,2CAAwF;AAA/E,8GAAA,gBAAgB,OAAA;AAAE,kHAAA,oBAAoB,OAAA;AAAE,8GAAA,gBAAgB,OAAA;AACjE,sDAA4D;AAAnD,+GAAA,iBAAiB,OAAA;AAC1B,sDAAwD;AAA/C,2GAAA,aAAa,OAAA;AACtB,mDAA0D;AAAjD,8GAAA,iBAAiB,OAAA;AAC1B,6CAAoD;AAA3C,wGAAA,cAAc,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAOA,0BAkBC;AAzBD,2CAA4C;AAE5C,wDAA4D;AAC5D,wDAAwD;AACxD,6CAAsE;AAGtE,SAAgB,OAAO,CAAC,OAA6B;IACnD,MAAM,MAAM,GAAG,IAAI,yBAAa,CAAC,OAAO,CAAC,CAAC;IAC1C,OAAO;QACL,MAAM;QACN,UAAU,EAAE,CAAC,IAAwB,EAAE,EAAE,CAAC,IAAA,8BAAiB,EAAC,MAAM,EAAE,IAAI,CAAC;QACzE,MAAM,EAAE,CAAC,IAAwB,EAAE,EAAE;YACnC,MAAM,MAAM,GAAG,CACb,OAA4C,EAC5C,KAAc,EACd,IAAyC,EACzC,EAAE,CAAC,IAAA,0BAAa,EAAC,OAAO,EAAE,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;YACvD,8DAA8D;YAC7D,MAA6C,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,GAAG,IAAI,CAAC;YACnF,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,gBAAgB,EAAhB,6BAAgB;QAChB,oBAAoB,EAApB,iCAAoB;KACrB,CAAC;AACJ,CAAC;AAED,iCAAiC;AACjC,yCAA4C;AAAnC,0GAAA,aAAa,OAAA;AAEtB,2CAAwF;AAA/E,8GAAA,gBAAgB,OAAA;AAAE,kHAAA,oBAAoB,OAAA;AAAE,8GAAA,gBAAgB,OAAA;AACjE,sDAA4D;AAAnD,+GAAA,iBAAiB,OAAA;AAC1B,sDAAwD;AAA/C,2GAAA,aAAa,OAAA;AACtB,kEAA+F;AAAtF,uHAAA,mBAAmB,OAAA;AAAE,6HAAA,yBAAyB,OAAA;AAEvD,mDAA0D;AAAjD,8GAAA,iBAAiB,OAAA;AAC1B,6CAAsE;AAA7D,wGAAA,cAAc,OAAA;AAAE,0GAAA,gBAAgB,OAAA;AACzC,qDAAyD;AAAhD,6GAAA,eAAe,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/middleware/express.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAOrD,KAAK,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAEtC,KAAK,kBAAkB,GAAG;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACxD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;KAAE,CAAC;CACrD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,iBAAiB,IACpE,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC,CAqF9F"}
1
+ {"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/middleware/express.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAQrD,KAAK,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAEtC,KAAK,kBAAkB,GAAG;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACxD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;KAAE,CAAC;CACrD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,iBAAiB,IAEpE,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,MAAM,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC,CA4F9F"}