pipework 0.201.0 → 0.202.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/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.202.0
4
+
5
+ - **Added: `assign` on `alerts.clientFaults` and `alerts.requestFaults`** (#773). `assign(report)` (or `assign(fault)`) may return `{ owner?, runbook? }` to choose who gets that one alert. A field it leaves undefined keeps the app's (or the hook's) value. A request report whose refusal the server caused can now go to the server's owner, not the page's. For `clientFaults`, an `assign` that throws is handled the way a throwing `key` is: it is logged and recorded as a fault, nothing is raised, and the answer is still 204.
6
+
3
7
  ## 0.201.0
4
8
 
5
9
  - **Fixed: a request answered with an error left no record of why in its trace** (#768). Every error response from a route now records one `http.error` step on the request's trace. It records:
package/REFERENCE.md CHANGED
@@ -1892,7 +1892,7 @@ When a source's `evaluate()` throws, the tick raises `alert-source-failed:<sourc
1892
1892
 
1893
1893
  `table` is the jobs table, default `pipework_jobs`. A custom source is `{ name, evaluate(): Promise<{ key, severity, message, subject? }[]>, owns?(key) }`; with `owns`, an open alert it owns that `evaluate` no longer returns is resolved.
1894
1894
 
1895
- `alerts.requestFaults(handle, { owner?, runbook?, severity? = 'error' })` returns a hook for the HTTP server's `onInternalError`: each internal 5xx raises `request-fault:<METHOD> <route pattern>` with message `<METHOD> <route>: <error message>`, context `{ method, route, requestId, traceId, message }` and the request's tenant as subject; repeats on one route group into one alert. Pass it as `createServer(m, { onInternalError: alerts.requestFaults(ops, { owner: 'platform' }) })` or `surface.http({ onInternalError: ... })`.
1895
+ `alerts.requestFaults(handle, { owner?, runbook?, assign?, severity? = 'error' })` returns a hook for the HTTP server's `onInternalError`: each internal 5xx raises `request-fault:<METHOD> <route pattern>` with message `<METHOD> <route>: <error message>`, context `{ method, route, requestId, traceId, message }` and the request's tenant as subject; repeats on one route group into one alert. `assign(fault)` may return `{ owner?, runbook? }` to choose them per fault; an undefined result or field keeps `owner` / `runbook`. Pass it as `createServer(m, { onInternalError: alerts.requestFaults(ops, { owner: 'platform' }) })` or `surface.http({ onInternalError: ... })`.
1896
1896
 
1897
1897
  ```ts
1898
1898
  const sink = alerts.webhook({ url: process.env.OPS_HOOK!, secret: process.env.OPS_SECRET! })
@@ -1908,11 +1908,11 @@ await ops.resolve('engine-unavailable')
1908
1908
 
1909
1909
  ### Client faults
1910
1910
 
1911
- `alerts.clientFaults(handle, { path, apps, key?, cors?, rateLimit? })` returns one POST route for failures that browser code reports; register it with the other handlers. It answers 204 with no body and needs no session (sign-in and public pages have none); with one, the tenant and user are used.
1911
+ `alerts.clientFaults(handle, { path, apps, key?, assign?, cors?, rateLimit? })` returns one POST route for failures that browser code reports; register it with the other handlers. It answers 204 with no body and needs no session (sign-in and public pages have none); with one, the tenant and user are used.
1912
1912
 
1913
- - `apps` — `{ web: { owner?, runbook? } }`, at least one; a report's `app` must be one of its keys. `key(report)` — default `client-fault:<app>:<where>`. `cors` — the route's grant (see `Builder.cors`). `rateLimit` — a `rateLimits` class; omitted, the route's default class.
1913
+ - `apps` — `{ web: { owner?, runbook? } }`, at least one; a report's `app` must be one of its keys. `key(report)` — default `client-fault:<app>:<where>`. `assign(report)` — returns `{ owner?, runbook? }` for one report, over the app's: an undefined result or field keeps the app's; a throw is logged and recorded like a throwing `key`, nothing is raised, the answer is still 204. `cors` — the route's grant (see `Builder.cors`). `rateLimit` — a `rateLimits` class; omitted, the route's default class.
1914
1914
  - Body, strict (an unknown field is 400, and nothing is raised): `app`, `where` (1-100 of `A-Za-z0-9._:/-`), `kind` (`error | rejection | render | request`), `severity?` (`warning | error`, default `error`), `code?` (100), `message` (1-500), `stack?` (4096), `route?` (200, starts with `/`, no `?`, `#` or `://`: a route pattern, never a page URL), `release?` (100), `traceId?` (a uuid: the `x-pipework-trace-id` of an answer), `requestId?` (1-100 of `A-Za-z0-9._:-`: the `x-request-id` of an answer).
1915
- - Each report is a trace step `pipework/alerts:client-fault` capturing the report, and raises the key with severity as sent, the app's `owner` and `runbook`, and context `{ app, where, kind, code?, route?, release?, traceId?, requestId? }`. The stack is in the step's capture only. A raise that fails is logged; the answer is still 204.
1915
+ - Each report is a trace step `pipework/alerts:client-fault` capturing the report, and raises the key with severity as sent, the app's `owner` and `runbook` (or the report's from `assign`), and context `{ app, where, kind, code?, route?, release?, traceId?, requestId? }`. The stack is in the step's capture only. A raise that fails is logged; the answer is still 204.
1916
1916
 
1917
1917
  `reportClientFault(url, report)` from `pipework/client` sends a report with `keepalive` and `credentials: 'include'`, cuts `message` and `stack` to their caps, and never throws.
1918
1918
 
@@ -13,6 +13,14 @@ export interface ClientFaultsOptions {
13
13
  }>>;
14
14
  /** The alert key for a report. Default `client-fault:<app>:<where>`. */
15
15
  readonly key?: (report: ClientFaultReport) => string;
16
+ /**
17
+ * The owner and runbook for one report, over the app's: each field returned replaces the app's, an undefined
18
+ * field or result keeps it. A throw is handled as a throwing `key`: logged and recorded, nothing raised, still 204.
19
+ */
20
+ readonly assign?: (report: ClientFaultReport) => {
21
+ readonly owner?: string;
22
+ readonly runbook?: string;
23
+ } | undefined;
16
24
  /** This route's CORS grant (see `Builder.cors`). */
17
25
  readonly cors?: CorsConfig;
18
26
  /** A `rateLimits` class for the route. Default: the class of a route with optional auth. */
@@ -22,7 +30,7 @@ export interface ClientFaultsOptions {
22
30
  * One POST route at `options.path` that takes failures reported by browser code (see `reportClientFault` in
23
31
  * `pipework/client`) and answers 204. No session is needed; the tenant and user are used when there is one.
24
32
  * Each report is a trace step `pipework/alerts:client-fault` capturing the report, and raises
25
- * `client-fault:<app>:<where>` (or `options.key`) with the app's owner and runbook. The stack stays in the
33
+ * `client-fault:<app>:<where>` (or `options.key`) with the app's owner and runbook, or the report's own from `options.assign`. The stack stays in the
26
34
  * step's capture, not the alert. A body that breaks the contract is 400 and raises nothing.
27
35
  */
28
36
  export declare function clientFaults(handle: Alerts, options: ClientFaultsOptions): Handler<Record<string, unknown>, unknown>[];
@@ -1 +1 @@
1
- {"version":3,"file":"client-faults.d.ts","sourceRoot":"","sources":["../../../src/infra/alerts/client-faults.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAM7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AAErE,OAAO,KAAK,EAAE,MAAM,EAAa,MAAM,aAAa,CAAA;AAGpD,YAAY,EAAE,iBAAiB,EAAE,CAAA;AAEjC,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAA;IAC/F,wEAAwE;IACxE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,MAAM,CAAA;IACpD,oDAAoD;IACpD,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAA;IAC1B,4FAA4F;IAC5F,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAmBD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,CAiDtH"}
1
+ {"version":3,"file":"client-faults.d.ts","sourceRoot":"","sources":["../../../src/infra/alerts/client-faults.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAM7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAA;AAErE,OAAO,KAAK,EAAE,MAAM,EAAa,MAAM,aAAa,CAAA;AAGpD,YAAY,EAAE,iBAAiB,EAAE,CAAA;AAEjC,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAA;IAC/F,wEAAwE;IACxE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,MAAM,CAAA;IACpD;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAA;IACnH,oDAAoD;IACpD,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAA;IAC1B,4FAA4F;IAC5F,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAmBD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,CAqDtH"}
@@ -25,7 +25,7 @@ const REF = 'pipework/alerts:client-fault';
25
25
  * One POST route at `options.path` that takes failures reported by browser code (see `reportClientFault` in
26
26
  * `pipework/client`) and answers 204. No session is needed; the tenant and user are used when there is one.
27
27
  * Each report is a trace step `pipework/alerts:client-fault` capturing the report, and raises
28
- * `client-fault:<app>:<where>` (or `options.key`) with the app's owner and runbook. The stack stays in the
28
+ * `client-fault:<app>:<where>` (or `options.key`) with the app's owner and runbook, or the report's own from `options.assign`. The stack stays in the
29
29
  * step's capture, not the alert. A body that breaks the contract is 400 and raises nothing.
30
30
  */
31
31
  export function clientFaults(handle, options) {
@@ -44,12 +44,16 @@ export function clientFaults(handle, options) {
44
44
  context[field] = report[field];
45
45
  }
46
46
  try {
47
- await handle.raise(options.key?.(report) ?? `client-fault:${report.app}:${report.where}`, {
47
+ const key = options.key?.(report) ?? `client-fault:${report.app}:${report.where}`;
48
+ const assigned = options.assign?.(report);
49
+ const owner = assigned?.owner ?? app.owner;
50
+ const runbook = assigned?.runbook ?? app.runbook;
51
+ await handle.raise(key, {
48
52
  severity: report.severity ?? 'error',
49
53
  message: `${report.app} ${report.where}: ${report.message}`,
50
54
  subject: { ...(flow?.tenant != null ? { tenantId: flow.tenant } : {}), entity: 'client', entityId: report.where },
51
- ...(app.owner !== undefined ? { owner: app.owner } : {}),
52
- ...(app.runbook !== undefined ? { runbook: app.runbook } : {}),
55
+ ...(owner !== undefined ? { owner } : {}),
56
+ ...(runbook !== undefined ? { runbook } : {}),
53
57
  context,
54
58
  });
55
59
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client-faults.js","sourceRoot":"","sources":["../../../src/infra/alerts/client-faults.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client-faults.js","sourceRoot":"","sources":["../../../src/infra/alerts/client-faults.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAGrD,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAC3D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAA;AAE7D,OAAO,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AAE/F,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAsB3C,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAA;AACtB,MAAM,YAAY,GAAG,CAAC,IAAuB,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;IAC/D,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,kBAAkB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAClF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC;IAC9D,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IACzD,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE;IACjD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IACpC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,wBAAwB,CAAC;IACxD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,QAAQ,EAAE;IACxD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,yCAAyC,CAAC,CAAC,QAAQ,EAAE;IACnI,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IACvC,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;IAC5B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,QAAQ,EAAE;CAC7E,CAAC,CAAA;AAEF,MAAM,GAAG,GAAG,8BAA8B,CAAA;AAE1C;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,OAA4B;IACvE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3F,MAAM,IAAI,KAAK,CAAC,8BAA8B,OAAO,CAAC,IAAI,0EAA0E,CAAC,CAAA;IACvI,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,mFAAmF,CAAC,CAAA;IACtG,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,MAAyB,EAAiB,EAAE;QAC1G,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAE,CAAA;QACrC,MAAM,IAAI,GAAG,UAAU,EAAE,CAAA;QACzB,MAAM,OAAO,GAA8B,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAA;QACtG,KAAK,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,CAAU,EAAE,CAAC;YAClF,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS;gBAAE,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;QACjE,CAAC;QACD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,gBAAgB,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,KAAK,EAAE,CAAA;YACjF,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAA;YACzC,MAAM,KAAK,GAAG,QAAQ,EAAE,KAAK,IAAI,GAAG,CAAC,KAAK,CAAA;YAC1C,MAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,IAAI,GAAG,CAAC,OAAO,CAAA;YAChD,MAAM,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;gBACtB,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,OAAO;gBACpC,OAAO,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,OAAO,EAAE;gBAC3D,OAAO,EAAE,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE;gBACjH,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzC,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7C,OAAO;aACR,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,aAAa,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,gCAAgC,CAAC,CAAA;YACtG,KAAK,WAAW,CAAC,oBAAoB,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAA;QAChF,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;IAC3D,IAAI,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;IAC7D,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACpE,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS;QAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAEnF,OAAO;QACL,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;YAC1D,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;YAC3C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;gBACpC,MAAM,IAAI,GAAG,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAA;gBACxC,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;gBACzC,MAAM,IAAI,eAAe,CAAC,WAAW,KAAK,KAAK,KAAK,EAAE,OAAO,IAAI,0CAA0C,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;YAC5H,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAyB,CAAA;YAC/C,MAAM,MAAM,CAAC,MAAM,CAAC,CAAA;YACpB,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAA;QACxB,CAAC,CAAyD;KAC3D,CAAA;AACH,CAAC"}
@@ -3,6 +3,11 @@ import type { InternalErrorFault } from '../../request/http/types.js';
3
3
  export interface RequestFaultsOptions {
4
4
  readonly owner?: string;
5
5
  readonly runbook?: string;
6
+ /** The owner and runbook for one fault, over `owner` and `runbook`: an undefined field or result keeps them. */
7
+ readonly assign?: (fault: InternalErrorFault) => {
8
+ readonly owner?: string;
9
+ readonly runbook?: string;
10
+ } | undefined;
6
11
  /** Default `'error'`. */
7
12
  readonly severity?: AlertSeverity;
8
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"request-faults.d.ts","sourceRoot":"","sources":["../../../src/infra/alerts/request-faults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAErE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,yBAAyB;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAA;CAClC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAkBlI"}
1
+ {"version":3,"file":"request-faults.d.ts","sourceRoot":"","sources":["../../../src/infra/alerts/request-faults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAErE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,gHAAgH;IAChH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAA;IACnH,yBAAyB;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,aAAa,CAAA;CAClC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAqBlI"}
@@ -6,12 +6,15 @@
6
6
  export function requestFaultsHook(handle, options = {}) {
7
7
  return async (fault) => {
8
8
  const detail = fault.error instanceof Error ? fault.error.message : String(fault.error);
9
+ const assigned = options.assign?.(fault);
10
+ const owner = assigned?.owner ?? options.owner;
11
+ const runbook = assigned?.runbook ?? options.runbook;
9
12
  await handle.raise(`request-fault:${fault.method} ${fault.route}`, {
10
13
  severity: options.severity ?? 'error',
11
14
  message: `${fault.method} ${fault.route}: ${detail}`,
12
15
  ...(fault.tenantId !== null ? { subject: { tenantId: fault.tenantId } } : {}),
13
- ...(options.owner !== undefined ? { owner: options.owner } : {}),
14
- ...(options.runbook !== undefined ? { runbook: options.runbook } : {}),
16
+ ...(owner !== undefined ? { owner } : {}),
17
+ ...(runbook !== undefined ? { runbook } : {}),
15
18
  context: {
16
19
  method: fault.method,
17
20
  route: fault.route,
@@ -1 +1 @@
1
- {"version":3,"file":"request-faults.js","sourceRoot":"","sources":["../../../src/infra/alerts/request-faults.ts"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,UAAgC,EAAE;IAClF,OAAO,KAAK,EAAE,KAAK,EAAE,EAAE;QACrB,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACvF,MAAM,MAAM,CAAC,KAAK,CAAC,iBAAiB,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE;YACjE,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,OAAO;YACrC,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,EAAE;YACpD,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7E,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChE,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,OAAO,EAAE;gBACP,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,OAAO,EAAE,MAAM;aAChB;SACF,CAAC,CAAA;IACJ,CAAC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"request-faults.js","sourceRoot":"","sources":["../../../src/infra/alerts/request-faults.ts"],"names":[],"mappings":"AAYA;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,UAAgC,EAAE;IAClF,OAAO,KAAK,EAAE,KAAK,EAAE,EAAE;QACrB,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACvF,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAA;QACxC,MAAM,KAAK,GAAG,QAAQ,EAAE,KAAK,IAAI,OAAO,CAAC,KAAK,CAAA;QAC9C,MAAM,OAAO,GAAG,QAAQ,EAAE,OAAO,IAAI,OAAO,CAAC,OAAO,CAAA;QACpD,MAAM,MAAM,CAAC,KAAK,CAAC,iBAAiB,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE;YACjE,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,OAAO;YACrC,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,KAAK,MAAM,EAAE;YACpD,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7E,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzC,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,OAAO,EAAE;gBACP,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,OAAO,EAAE,MAAM;aAChB;SACF,CAAC,CAAA;IACJ,CAAC,CAAA;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pipework",
3
- "version": "0.201.0",
3
+ "version": "0.202.0",
4
4
  "description": "TypeScript framework for multi-tenant SaaS applications. PostgreSQL-only.",
5
5
  "type": "module",
6
6
  "license": "MIT",