@owlmeans/api 0.1.18-rc.45 → 0.1.18-rc.47

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.
Files changed (91) hide show
  1. package/README.md +2 -2
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/api/SKILL.md +22 -20
  4. package/build/index.d.ts +3 -2
  5. package/build/index.d.ts.map +1 -1
  6. package/build/index.js +1 -1
  7. package/build/index.js.map +1 -1
  8. package/build/service.d.ts +1 -6
  9. package/build/service.d.ts.map +1 -1
  10. package/build/service.js +6 -6
  11. package/build/service.js.map +1 -1
  12. package/build/status/consts.d.ts +5 -0
  13. package/build/status/consts.d.ts.map +1 -0
  14. package/build/status/consts.js +5 -0
  15. package/build/status/consts.js.map +1 -0
  16. package/build/status/consts.local.d.ts +10 -0
  17. package/build/status/consts.local.d.ts.map +1 -0
  18. package/build/status/consts.local.js +10 -0
  19. package/build/status/consts.local.js.map +1 -0
  20. package/build/status/helper.d.ts +4 -0
  21. package/build/status/helper.d.ts.map +1 -0
  22. package/build/status/helper.js +49 -0
  23. package/build/status/helper.js.map +1 -0
  24. package/build/status/index.d.ts +5 -27
  25. package/build/status/index.d.ts.map +1 -1
  26. package/build/status/index.js +6 -62
  27. package/build/status/index.js.map +1 -1
  28. package/build/status/marker.d.ts +1 -10
  29. package/build/status/marker.d.ts.map +1 -1
  30. package/build/status/marker.js +1 -12
  31. package/build/status/marker.js.map +1 -1
  32. package/build/status/types.d.ts +35 -0
  33. package/build/status/types.d.ts.map +1 -0
  34. package/build/status/types.js +2 -0
  35. package/build/status/types.js.map +1 -0
  36. package/build/types.local.d.ts +6 -0
  37. package/build/types.local.d.ts.map +1 -0
  38. package/build/types.local.js +2 -0
  39. package/build/types.local.js.map +1 -0
  40. package/build/utils/body/types.d.ts +36 -0
  41. package/build/utils/body/types.d.ts.map +1 -0
  42. package/build/utils/body/types.js +2 -0
  43. package/build/utils/body/types.js.map +1 -0
  44. package/build/utils/body.d.ts +3 -33
  45. package/build/utils/body.d.ts.map +1 -1
  46. package/build/utils/body.js +51 -66
  47. package/build/utils/body.js.map +1 -1
  48. package/build/utils/consts.d.ts +2 -0
  49. package/build/utils/consts.d.ts.map +1 -0
  50. package/build/utils/consts.js +2 -0
  51. package/build/utils/consts.js.map +1 -0
  52. package/build/utils/consts.local.d.ts +2 -0
  53. package/build/utils/consts.local.d.ts.map +1 -0
  54. package/build/utils/consts.local.js +2 -0
  55. package/build/utils/consts.local.js.map +1 -0
  56. package/build/utils/index.d.ts +2 -1
  57. package/build/utils/index.d.ts.map +1 -1
  58. package/build/utils/index.js +1 -1
  59. package/build/utils/index.js.map +1 -1
  60. package/build/utils/response/types.d.ts +15 -0
  61. package/build/utils/response/types.d.ts.map +1 -0
  62. package/build/utils/response/types.js +2 -0
  63. package/build/utils/response/types.js.map +1 -0
  64. package/build/utils/response.d.ts +4 -0
  65. package/build/utils/response.d.ts.map +1 -0
  66. package/build/utils/response.js +99 -0
  67. package/build/utils/response.js.map +1 -0
  68. package/package.json +14 -14
  69. package/src/index.ts +3 -2
  70. package/src/service.ts +8 -15
  71. package/src/status/consts.local.ts +11 -0
  72. package/src/status/consts.ts +5 -0
  73. package/src/status/helper.ts +63 -0
  74. package/src/status/index.ts +7 -81
  75. package/src/status/marker.ts +3 -21
  76. package/src/status/types.ts +36 -0
  77. package/src/types.local.ts +7 -0
  78. package/src/utils/body/types.ts +37 -0
  79. package/src/utils/body.ts +53 -76
  80. package/src/utils/consts.local.ts +1 -0
  81. package/src/utils/consts.ts +1 -0
  82. package/src/utils/index.ts +2 -1
  83. package/src/utils/response/types.ts +15 -0
  84. package/src/utils/response.ts +117 -0
  85. package/tests/body.spec.ts +30 -31
  86. package/tests/handler.spec.ts +45 -45
  87. package/build/utils/handler.d.ts +0 -11
  88. package/build/utils/handler.d.ts.map +0 -1
  89. package/build/utils/handler.js +0 -95
  90. package/build/utils/handler.js.map +0 -1
  91. package/src/utils/handler.ts +0 -111
package/README.md CHANGED
@@ -12,7 +12,7 @@ HTTP API client service for OwlMeans client contexts — carries entrypoint call
12
12
  ## Installation
13
13
 
14
14
  ```bash
15
- bun add @owlmeans/api@^0.1.18-rc.45
15
+ bun add @owlmeans/api@^0.1.18-rc.47
16
16
  ```
17
17
 
18
18
  ## Usage
@@ -73,7 +73,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
73
73
  your project's skill store (`.agents/skills/`):
74
74
 
75
75
  ```sh
76
- npx @owlmeans/agent-skills@^0.1.18-rc.47
76
+ npx @owlmeans/agent-skills@^0.1.18-rc.49
77
77
  ```
78
78
 
79
79
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/api",
4
- "version": "0.1.18-rc.45",
5
- "generatedAt": "2026-10-03T20:05:07.613Z",
4
+ "version": "0.1.18-rc.47",
5
+ "generatedAt": "2026-10-05T21:03:06.419Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/api
9
9
 
10
10
  **Layer:** Core
11
- **Install:** `"@owlmeans/api": "^0.1.18-rc.45"` in `dependencies`
11
+ **Install:** `"@owlmeans/api": "^0.1.18-rc.47"` in `dependencies`
12
12
 
13
13
  ## Key Exports
14
14
 
@@ -18,16 +18,17 @@ user-invocable: false
18
18
  | `appendApiClient(ctx, alias?)` | Register it and make it the context's default `webService` when none is set |
19
19
  | `ApiClient` | Service interface — a single `handler(req, reply)` |
20
20
  | `ApiError`, `ApiClientError`, `ServerCrashedError`, `ServerAuthError`, `ApiStatusError` | Typed transport errors; an `ApiClientError` carries the answered `status` and the server's `incidentId` |
21
- | `httpStatusOf`, `incidentIdOf`, `isAccessDenied`, `isIncidentBody`, `parseClientMarker`, `API_CLIENT_MARKER`, `API_STATUS_MARKER` | Read a failure's HTTP status, incident id and IAM denial marker (also the `./status` subpath) |
21
+ | `apiStatusHelper` (`httpStatusOf`, `incidentIdOf`, `isAccessDenied`, `isIncidentBody`), `parseClientMarker`, `API_CLIENT_MARKER`, `API_STATUS_MARKER` | Read a failure's HTTP status, incident id and IAM denial marker (also the `./status` subpath) |
22
22
  | Constants | Status codes (`OK`, `CREATED`, `ACCEPTED`, `FINISHED`, `UNAUTHORIZED_ERROR`, `FORBIDDEN_ERROR`, `SERVER_ERROR`), `INCIDENT_ID_HEADER` (`X-Incident-ID`), `DEFAULT_ALIAS` (`web-client`) |
23
23
 
24
- Subpath `./status` — `httpStatusOf`, `incidentIdOf`, `isIncidentBody`, `parseClientMarker`, the
25
- markers and `INCIDENT_ID_HEADER`, importing only `@owlmeans/error`: a browser package reads a
26
- status without pulling axios in.
24
+ Subpath `./status` — `apiStatusHelper` (`httpStatusOf`, `incidentIdOf`, `isAccessDenied`,
25
+ `isIncidentBody`), `parseClientMarker`, the markers and `INCIDENT_ID_HEADER`, importing only
26
+ `@owlmeans/error`: a browser package reads a status without pulling axios in.
27
27
 
28
- `isAccessDenied(error)` requires the server's `X-OwlMeans-Denial: access-denied` marker and a 403.
29
- Do not classify all 403 responses as IAM denials: entitlement and other refusals use that status
30
- too. The API client stamps the marker on its rejection even under production error exposure.
28
+ `apiStatusHelper.isAccessDenied(error)` requires the server's `X-OwlMeans-Denial: access-denied`
29
+ marker and a 403. Do not classify all 403 responses as IAM denials: entitlement and other refusals
30
+ use that status too. The API client stamps the marker on its rejection even under production error
31
+ exposure.
31
32
 
32
33
  ## How a call is carried
33
34
 
@@ -94,15 +95,15 @@ browser reads that header cross-origin only when the server exposes it, the body
94
95
  | Production — a bare incident UUID; also proxy HTML, framework JSON, anything else | `ServerCrashedError` `api:client:crashed:<id>` (500) · `ServerAuthError` `api:client:auth:<id>` (401) · `ApiClientError` `api:client:forbidden[:<id>]` (403) · `ApiStatusError` `api:client:status:<n>[:<id>]` (every other status) |
95
96
 
96
97
  An `@owlmeans/server-api` boundary in production exposure sends ONLY the incident id, so a typed
97
- refusal's class never reaches the browser — its status does. Read it with `httpStatusOf(e)`: the
98
- stamped `responseStatus`, else an `ApiClientError`'s parsed `status`, else a class's declared
99
- `httpStatus` (a 4xx; a 5xx only with `allowServerErrorStatus`, exactly what the server answers),
100
- else an `api:client:*` marker in the message or type; `null` when nothing states one. A consumer
101
- that acts on a refusal checks the class/marker AND the status (`consentRefusalOf(e) ||
102
- httpStatusOf(e) === 428`). Markers without an id stay as they were (`api:client:crashed:error`,
103
- `api:client:forbidden`). The status and id are rebuilt from the marker in `finalizeUnmarshal()`,
104
- so they survive a marshal. No class of this family declares a static `httpStatus`: a server that
105
- rethrows one still answers 500.
98
+ refusal's class never reaches the browser — its status does. Read it with
99
+ `apiStatusHelper.httpStatusOf(e)`: the stamped `responseStatus`, else an `ApiClientError`'s parsed
100
+ `status`, else a class's declared `httpStatus` (a 4xx; a 5xx only with `allowServerErrorStatus`,
101
+ exactly what the server answers), else an `api:client:*` marker in the message or type; `null` when
102
+ nothing states one. A consumer that acts on a refusal checks the class/marker AND the status
103
+ (`consentRefusalOf(e) || apiStatusHelper.httpStatusOf(e) === 428`). Markers without an id stay as
104
+ they were (`api:client:crashed:error`, `api:client:forbidden`). The status and id are rebuilt from
105
+ the marker in `finalizeUnmarshal()`, so they survive a marshal. No class of this family declares a
106
+ static `httpStatus`: a server that rethrows one still answers 500.
106
107
 
107
108
  **A failure with no answer at all is a different family.** Suppressing status errors does not wrap
108
109
  the call: an expired `timeout` (`ECONNABORTED`), an aborted `signal` (`CanceledError` /
@@ -114,8 +115,9 @@ An `auth-token-refresh` response header is consumed here: when the context has a
114
115
  rotated token is handed to it, which is what keeps a long session alive without the caller doing
115
116
  anything.
116
117
 
117
- Building a URL without making the call is a different question — that is `entrypointUrl` from
118
- `@owlmeans/client-entrypoint/utils`, or `ep.url(req, { absolute })`.
118
+ Building a URL without making the call is a different question — that is
119
+ `apiCallOf(ref).entrypointUrl(req, opts)` from `@owlmeans/client-entrypoint/utils`, or
120
+ `ep.url(req, { absolute })`.
119
121
 
120
122
  ## Usage
121
123
 
@@ -132,7 +134,7 @@ transport keeps it.
132
134
  ## Depends On
133
135
 
134
136
  - `@owlmeans/context` — service registration
135
- - `@owlmeans/entrypoint` — the entrypoint being addressed, `@owlmeans/client-route` — `extractParams`
137
+ - `@owlmeans/entrypoint` — the entrypoint being addressed, `@owlmeans/client-route` — `clientRouteHelper.extractParams`
136
138
  - `@owlmeans/config` — `makeSecurityHelper`, `@owlmeans/client-config` — the config shape
137
139
  - `@owlmeans/auth-common` — the token-refresh header and the auth service it updates
138
140
  - `@owlmeans/error`, `@owlmeans/route`
package/build/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from './errors.js';
2
2
  export * from './consts.js';
3
3
  export * from './service.js';
4
4
  export type * from './types.js';
5
- export { httpStatusOf, incidentIdOf, isIncidentBody, parseClientMarker, API_CLIENT_MARKER, API_STATUS_MARKER, } from './status/index.js';
6
- export type { ClientMarker, ResponseStatusCarrier } from './status/index.js';
5
+ export { httpStatusOf, apiStatusHelper, createApiStatusHelper, parseClientMarker, API_CLIENT_MARKER, API_STATUS_MARKER, } from './status/index.js';
6
+ export type { ClientMarker, ApiStatusHelper } from './status/index.js';
7
+ export type { ResponseStatusCarrier } from './status/types.js';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,mBAAmB,YAAY,CAAA;AAC/B,OAAO,EACL,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,GACpG,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,mBAAmB,YAAY,CAAA;AAC/B,OAAO,EACL,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,GAC9G,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACtE,YAAY,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA"}
package/build/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export * from './errors.js';
2
2
  export * from './consts.js';
3
3
  export * from './service.js';
4
- export { httpStatusOf, incidentIdOf, isIncidentBody, parseClientMarker, API_CLIENT_MARKER, API_STATUS_MARKER, } from './status/index.js';
4
+ export { httpStatusOf, apiStatusHelper, createApiStatusHelper, parseClientMarker, API_CLIENT_MARKER, API_STATUS_MARKER, } from './status/index.js';
5
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAE5B,OAAO,EACL,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,GACpG,MAAM,mBAAmB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAE5B,OAAO,EACL,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,GAC9G,MAAM,mBAAmB,CAAA"}
@@ -1,10 +1,5 @@
1
- import type { BasicContext } from '@owlmeans/context';
2
1
  import type { ApiClient } from './types.js';
3
- import { BasicClientConfig } from '@owlmeans/client-config';
4
- type Config = BasicClientConfig;
5
- interface Context<C extends Config = Config> extends BasicContext<C> {
6
- }
2
+ import type { Config, Context } from './types.local.js';
7
3
  export declare const createApiService: (alias?: string) => ApiClient;
8
4
  export declare const appendApiClient: <C extends Config, T extends Context<C>>(ctx: T, alias?: string) => T;
9
- export {};
10
5
  //# sourceMappingURL=service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAO3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAW3D,KAAK,MAAM,GAAG,iBAAiB,CAAA;AAE/B,UAAU,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,YAAY,CAAC,CAAC,CAAC;CACnE;AAED,eAAO,MAAM,gBAAgB,WAAW,MAAM,KAAmB,SAsFhE,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,UAAS,MAAM,KAAmB,CAU/G,CAAA"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAQ3C,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AASvD,eAAO,MAAM,gBAAgB,WAAW,MAAM,KAAmB,SAsFhE,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,UAAS,MAAM,KAAmB,CAU/G,CAAA"}
package/build/service.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { assertContext, createService } from '@owlmeans/context';
2
- import { extractParams } from '@owlmeans/client-route';
2
+ import { clientRouteHelper } from '@owlmeans/client-route';
3
3
  import axios from 'axios';
4
4
  import { DEFAULT_ALIAS, UNAUTHORIZED_ERROR } from './consts.js';
5
- import { requestBodyOf } from './utils/body.js';
6
- import { processResponse } from './utils/handler.js';
5
+ import { responseUtils } from './utils/response.js';
7
6
  import { makeSecurityHelper } from '@owlmeans/config';
8
7
  import { AUTH_HEADER, DEF_AUTH_SRV, TOKEN_UPDATE } from '@owlmeans/auth-common';
8
+ import { bodyUtils } from './utils/body.js';
9
9
  /** Whether a request carried an authentication header of its own. */
10
10
  const presented = (headers) => headers != null && Object.entries(headers).some(([key, value]) => key.toLowerCase() === AUTH_HEADER && value != null && value !== '');
11
11
  export const createApiService = (alias = DEFAULT_ALIAS) => {
@@ -19,7 +19,7 @@ export const createApiService = (alias = DEFAULT_ALIAS) => {
19
19
  const module = context.entrypoint(request.alias);
20
20
  const route = module.route.route;
21
21
  let path = module.path();
22
- const params = extractParams(path);
22
+ const params = clientRouteHelper.extractParams(path);
23
23
  path = params.reduce((path, param) => {
24
24
  if (request.params[param] == null) {
25
25
  throw new SyntaxError(`No value for param ${param}`);
@@ -32,7 +32,7 @@ export const createApiService = (alias = DEFAULT_ALIAS) => {
32
32
  const url = helper.makeUrl(module.address(), path, { host: request.host, base: request.base, forceUnsecure: request.unsecure });
33
33
  // A scalar JSON body (a string, a number, a boolean) is serialized here, so the server parses
34
34
  // back the value the caller sent; objects and arrays are left to axios.
35
- const body = requestBodyOf(request.body, request.headers, route.method, module.filter?.body);
35
+ const body = bodyUtils.requestBodyOf(request.body, request.headers, route.method, module.filter?.body);
36
36
  const transformer = body.verbatim ? data => data : undefined;
37
37
  const requestHeaders = body.contentType != null
38
38
  ? { ...request.headers, 'content-type': body.contentType }
@@ -74,7 +74,7 @@ export const createApiService = (alias = DEFAULT_ALIAS) => {
74
74
  */
75
75
  await context.service(DEF_AUTH_SRV).update(undefined);
76
76
  }
77
- processResponse(response, reply);
77
+ responseUtils.processResponse(response, reply);
78
78
  return [reply.error ?? reply.value, reply.outcome];
79
79
  }
80
80
  }, service => async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** The prefix every `ApiClientError` message carries. */
2
+ export declare const API_CLIENT_MARKER = "api:client:";
3
+ /** The marker of an `ApiStatusError`: `api:client:status:<n>[:<incident id>]`. */
4
+ export declare const API_STATUS_MARKER = "api:client:status:";
5
+ //# sourceMappingURL=consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../../src/status/consts.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,eAAO,MAAM,iBAAiB,gBAAgB,CAAA;AAE9C,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,uBAAgC,CAAA"}
@@ -0,0 +1,5 @@
1
+ /** The prefix every `ApiClientError` message carries. */
2
+ export const API_CLIENT_MARKER = 'api:client:';
3
+ /** The marker of an `ApiStatusError`: `api:client:status:<n>[:<incident id>]`. */
4
+ export const API_STATUS_MARKER = `${API_CLIENT_MARKER}status:`;
5
+ //# sourceMappingURL=consts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../../src/status/consts.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAA;AAE9C,kFAAkF;AAClF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,iBAAiB,SAAS,CAAA"}
@@ -0,0 +1,10 @@
1
+ export declare const UUID: RegExp;
2
+ /**
3
+ * `crashed` / `auth` / `forbidden` / `status:<n>` / the legacy bare `<n>`, then an optional
4
+ * `:<incident id>`. The look-ahead refuses a match that runs on into more marker text, so a
5
+ * doubled prefix (a subclass constructor handed a whole marshaled message) resolves to the inner,
6
+ * complete marker.
7
+ */
8
+ export declare const MARKER: RegExp;
9
+ export declare const NAMED_STATUS: Record<string, number>;
10
+ //# sourceMappingURL=consts.local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.local.d.ts","sourceRoot":"","sources":["../../src/status/consts.local.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,QAAoE,CAAA;AAErF;;;;;GAKG;AACH,eAAO,MAAM,MAAM,QAAmG,CAAA;AAEtH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAA+C,CAAA"}
@@ -0,0 +1,10 @@
1
+ export const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
2
+ /**
3
+ * `crashed` / `auth` / `forbidden` / `status:<n>` / the legacy bare `<n>`, then an optional
4
+ * `:<incident id>`. The look-ahead refuses a match that runs on into more marker text, so a
5
+ * doubled prefix (a subclass constructor handed a whole marshaled message) resolves to the inner,
6
+ * complete marker.
7
+ */
8
+ export const MARKER = /api:client:(?:(crashed|auth|forbidden)|status:(\d{3})|(\d{3}))(?::([\w.-]{1,128}))?(?![\w.:-])/;
9
+ export const NAMED_STATUS = { crashed: 500, auth: 401, forbidden: 403 };
10
+ //# sourceMappingURL=consts.local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.local.js","sourceRoot":"","sources":["../../src/status/consts.local.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG,iEAAiE,CAAA;AAErF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,gGAAgG,CAAA;AAEtH,MAAM,CAAC,MAAM,YAAY,GAA2B,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAA"}
@@ -0,0 +1,4 @@
1
+ import type { ApiStatusHelper } from './types.js';
2
+ export declare const createApiStatusHelper: () => ApiStatusHelper;
3
+ export declare const apiStatusHelper: ApiStatusHelper;
4
+ //# sourceMappingURL=helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../../src/status/helper.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAuC,MAAM,YAAY,CAAA;AAEtF,eAAO,MAAM,qBAAqB,QAAO,eAqDxC,CAAA;AAED,eAAO,MAAM,eAAe,iBAA0B,CAAA"}
@@ -0,0 +1,49 @@
1
+ import { ResilientError } from '@owlmeans/error';
2
+ import { ApiClientError } from '../errors.js';
3
+ import { parseClientMarker } from './marker.js';
4
+ import { ACCESS_DENIED_KIND } from '../consts.js';
5
+ import { UUID } from './consts.local.js';
6
+ export const createApiStatusHelper = () => {
7
+ const isAccessDenied = (error) => httpStatusOf(error) === 403
8
+ && typeof error === 'object' && error != null
9
+ && error.denialKind === ACCESS_DENIED_KIND;
10
+ const httpStatus = (value) => typeof value === 'number' && Number.isInteger(value) && value >= 100 && value <= 599 ? value : null;
11
+ /** The first `api:client:*` marker in an error's `message`, else in its `type`. */
12
+ const markerOf = (error) => {
13
+ const { message, type } = error;
14
+ return (typeof message === 'string' ? parseClientMarker(message) : null)
15
+ ?? (typeof type === 'string' ? parseClientMarker(type) : null);
16
+ };
17
+ const httpStatusOf = (error) => {
18
+ if (error == null || typeof error !== 'object') {
19
+ return null;
20
+ }
21
+ const stamped = httpStatus(error.responseStatus);
22
+ if (stamped != null) {
23
+ return stamped;
24
+ }
25
+ if (error instanceof ApiClientError && httpStatus(error.status) != null) {
26
+ return error.status;
27
+ }
28
+ const declaration = error.constructor;
29
+ const declared = httpStatus(declaration?.httpStatus);
30
+ if (declared != null && (declared < 500 || declaration?.allowServerErrorStatus === true)) {
31
+ return declared;
32
+ }
33
+ return markerOf(error)?.status ?? null;
34
+ };
35
+ const incidentIdOf = (error) => {
36
+ if (error == null || typeof error !== 'object') {
37
+ return null;
38
+ }
39
+ const own = error.incidentId;
40
+ if (typeof own === 'string' && own !== '') {
41
+ return own;
42
+ }
43
+ return markerOf(error)?.incidentId ?? null;
44
+ };
45
+ const isIncidentBody = (data) => typeof data === 'string' && !data.includes(ResilientError.separator) && UUID.test(data.trim());
46
+ return { isAccessDenied, httpStatusOf, incidentIdOf, isIncidentBody };
47
+ };
48
+ export const apiStatusHelper = createApiStatusHelper();
49
+ //# sourceMappingURL=helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helper.js","sourceRoot":"","sources":["../../src/status/helper.ts"],"names":[],"mappings":"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"}
@@ -1,31 +1,9 @@
1
1
  export { INCIDENT_ID_HEADER } from '../consts.js';
2
2
  export { DENIAL_KIND_HEADER, ACCESS_DENIED_KIND } from '../consts.js';
3
- export { API_CLIENT_MARKER, API_STATUS_MARKER, parseClientMarker } from './marker.js';
4
- export type { ClientMarker } from './marker.js';
5
- /** The HTTP status the API client stamps on an error it rebuilt from a response body. */
6
- export interface ResponseStatusCarrier {
7
- responseStatus?: number;
8
- denialKind?: string;
9
- }
10
- /** True only for a server-labelled auth/IAM refusal, never an unrelated 403. */
11
- export declare const isAccessDenied: (error: unknown) => boolean;
12
- /**
13
- * The HTTP status an error answers to, or `null` when nothing states one.
14
- *
15
- * Read in order: the status the API client stamped on the error it rebuilt from a response
16
- * (`responseStatus`); the status an `ApiClientError` parsed from its marker; the `httpStatus` its
17
- * class declares — a 4xx always, a 5xx only with `allowServerErrorStatus`, exactly what an
18
- * `@owlmeans/server-api` boundary answers with; finally an `api:client:*` marker in the message or
19
- * the type of anything else. This is what lets a browser recognise a refusal from its status
20
- * alone when a production body carries nothing but an incident id.
21
- */
3
+ export { parseClientMarker } from './marker.js';
4
+ export { API_CLIENT_MARKER, API_STATUS_MARKER } from './consts.js';
5
+ export type { ClientMarker, ResponseStatusCarrier, ApiStatusHelper } from './types.js';
6
+ export { apiStatusHelper, createApiStatusHelper } from './helper.js';
7
+ /** @deprecated compat:factory-refactor — use `apiStatusHelper.httpStatusOf(…)` */
22
8
  export declare const httpStatusOf: (error: unknown) => number | null;
23
- /** The server's incident id carried by an error — its own field, else its marker — or `null`. */
24
- export declare const incidentIdOf: (error: unknown) => string | null;
25
- /**
26
- * Whether a response body is a production incident body — the bare incident UUID an
27
- * `@owlmeans/server-api` boundary sends instead of the marshaled error. A development body
28
- * carries the `ResilientError` separator and is never one.
29
- */
30
- export declare const isIncidentBody: (data: unknown) => data is string;
31
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/status/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAErE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACrF,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C,yFAAyF;AACzF,MAAM,WAAW,qBAAqB;IACpC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,gFAAgF;AAChF,eAAO,MAAM,cAAc,UAAW,OAAO,KAAG,OAGuB,CAAA;AAavE;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,UAAW,OAAO,KAAG,MAAM,GAAG,IAkBtD,CAAA;AAED,iGAAiG;AACjG,eAAO,MAAM,YAAY,UAAW,OAAO,KAAG,MAAM,GAAG,IAUtD,CAAA;AAID;;;;GAIG;AACH,eAAO,MAAM,cAAc,SAAU,OAAO,KAAG,IAAI,IAAI,MACyC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/status/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAClE,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AACtF,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEpE,kFAAkF;AAClF,eAAO,MAAM,YAAY,UAAW,OAAO,KAAG,MAAM,GAAG,IAA2C,CAAA"}
@@ -1,65 +1,9 @@
1
- import { ResilientError } from '@owlmeans/error';
2
- import { ApiClientError } from '../errors.js';
3
- import { parseClientMarker } from './marker.js';
1
+ import { apiStatusHelper } from './helper.js';
4
2
  export { INCIDENT_ID_HEADER } from '../consts.js';
5
3
  export { DENIAL_KIND_HEADER, ACCESS_DENIED_KIND } from '../consts.js';
6
- import { ACCESS_DENIED_KIND } from '../consts.js';
7
- export { API_CLIENT_MARKER, API_STATUS_MARKER, parseClientMarker } from './marker.js';
8
- /** True only for a server-labelled auth/IAM refusal, never an unrelated 403. */
9
- export const isAccessDenied = (error) => httpStatusOf(error) === 403
10
- && typeof error === 'object' && error != null
11
- && error.denialKind === ACCESS_DENIED_KIND;
12
- const httpStatus = (value) => typeof value === 'number' && Number.isInteger(value) && value >= 100 && value <= 599 ? value : null;
13
- /** The first `api:client:*` marker in an error's `message`, else in its `type`. */
14
- const markerOf = (error) => {
15
- const { message, type } = error;
16
- return (typeof message === 'string' ? parseClientMarker(message) : null)
17
- ?? (typeof type === 'string' ? parseClientMarker(type) : null);
18
- };
19
- /**
20
- * The HTTP status an error answers to, or `null` when nothing states one.
21
- *
22
- * Read in order: the status the API client stamped on the error it rebuilt from a response
23
- * (`responseStatus`); the status an `ApiClientError` parsed from its marker; the `httpStatus` its
24
- * class declares — a 4xx always, a 5xx only with `allowServerErrorStatus`, exactly what an
25
- * `@owlmeans/server-api` boundary answers with; finally an `api:client:*` marker in the message or
26
- * the type of anything else. This is what lets a browser recognise a refusal from its status
27
- * alone when a production body carries nothing but an incident id.
28
- */
29
- export const httpStatusOf = (error) => {
30
- if (error == null || typeof error !== 'object') {
31
- return null;
32
- }
33
- const stamped = httpStatus(error.responseStatus);
34
- if (stamped != null) {
35
- return stamped;
36
- }
37
- if (error instanceof ApiClientError && httpStatus(error.status) != null) {
38
- return error.status;
39
- }
40
- const declaration = error.constructor;
41
- const declared = httpStatus(declaration?.httpStatus);
42
- if (declared != null && (declared < 500 || declaration?.allowServerErrorStatus === true)) {
43
- return declared;
44
- }
45
- return markerOf(error)?.status ?? null;
46
- };
47
- /** The server's incident id carried by an error — its own field, else its marker — or `null`. */
48
- export const incidentIdOf = (error) => {
49
- if (error == null || typeof error !== 'object') {
50
- return null;
51
- }
52
- const own = error.incidentId;
53
- if (typeof own === 'string' && own !== '') {
54
- return own;
55
- }
56
- return markerOf(error)?.incidentId ?? null;
57
- };
58
- const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
59
- /**
60
- * Whether a response body is a production incident body — the bare incident UUID an
61
- * `@owlmeans/server-api` boundary sends instead of the marshaled error. A development body
62
- * carries the `ResilientError` separator and is never one.
63
- */
64
- export const isIncidentBody = (data) => typeof data === 'string' && !data.includes(ResilientError.separator) && UUID.test(data.trim());
4
+ export { parseClientMarker } from './marker.js';
5
+ export { API_CLIENT_MARKER, API_STATUS_MARKER } from './consts.js';
6
+ export { apiStatusHelper, createApiStatusHelper } from './helper.js';
7
+ /** @deprecated compat:factory-refactor — use `apiStatusHelper.httpStatusOf(…)` */
8
+ export const httpStatusOf = (error) => apiStatusHelper.httpStatusOf(error);
65
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/status/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/status/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAElE,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEpE,kFAAkF;AAClF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAc,EAAiB,EAAE,CAAC,eAAe,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA"}
@@ -1,12 +1,3 @@
1
- /** The prefix every `ApiClientError` message carries. */
2
- export declare const API_CLIENT_MARKER = "api:client:";
3
- /** The marker of an `ApiStatusError`: `api:client:status:<n>[:<incident id>]`. */
4
- export declare const API_STATUS_MARKER = "api:client:status:";
5
- /** What an `api:client:*` marker states. */
6
- export interface ClientMarker {
7
- status?: number;
8
- incidentId?: string;
9
- }
10
- /** Read the first `api:client:*` marker in a text, or `null` when it carries none. */
1
+ import type { ClientMarker } from './types.js';
11
2
  export declare const parseClientMarker: (text: string) => ClientMarker | null;
12
3
  //# sourceMappingURL=marker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"marker.d.ts","sourceRoot":"","sources":["../../src/status/marker.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,eAAO,MAAM,iBAAiB,gBAAgB,CAAA;AAE9C,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,uBAAgC,CAAA;AAY9D,4CAA4C;AAC5C,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,sFAAsF;AACtF,eAAO,MAAM,iBAAiB,SAAU,MAAM,KAAG,YAAY,GAAG,IAa/D,CAAA"}
1
+ {"version":3,"file":"marker.d.ts","sourceRoot":"","sources":["../../src/status/marker.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,eAAO,MAAM,iBAAiB,SAAU,MAAM,KAAG,YAAY,GAAG,IAa/D,CAAA"}
@@ -1,16 +1,5 @@
1
- /** The prefix every `ApiClientError` message carries. */
2
- export const API_CLIENT_MARKER = 'api:client:';
3
- /** The marker of an `ApiStatusError`: `api:client:status:<n>[:<incident id>]`. */
4
- export const API_STATUS_MARKER = `${API_CLIENT_MARKER}status:`;
5
- /**
6
- * `crashed` / `auth` / `forbidden` / `status:<n>` / the legacy bare `<n>`, then an optional
7
- * `:<incident id>`. The look-ahead refuses a match that runs on into more marker text, so a
8
- * doubled prefix (a subclass constructor handed a whole marshaled message) resolves to the inner,
9
- * complete marker.
10
- */
11
- const MARKER = /api:client:(?:(crashed|auth|forbidden)|status:(\d{3})|(\d{3}))(?::([\w.-]{1,128}))?(?![\w.:-])/;
12
- const NAMED_STATUS = { crashed: 500, auth: 401, forbidden: 403 };
13
1
  /** Read the first `api:client:*` marker in a text, or `null` when it carries none. */
2
+ import { MARKER, NAMED_STATUS } from './consts.local.js';
14
3
  export const parseClientMarker = (text) => {
15
4
  const match = MARKER.exec(text);
16
5
  if (match == null) {
@@ -1 +1 @@
1
- {"version":3,"file":"marker.js","sourceRoot":"","sources":["../../src/status/marker.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAA;AAE9C,kFAAkF;AAClF,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,iBAAiB,SAAS,CAAA;AAE9D;;;;;GAKG;AACH,MAAM,MAAM,GAAG,gGAAgG,CAAA;AAE/G,MAAM,YAAY,GAA2B,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,CAAA;AAQxF,sFAAsF;AACtF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAuB,EAAE;IACrE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC/B,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,KAAK,CAAA;IAC1C,MAAM,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,CAAA;IAE1E,OAAO;QACL,MAAM,EAAE,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QACrD,0EAA0E;QAC1E,UAAU,EAAE,EAAE,IAAI,IAAI,IAAI,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;KAC1D,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"marker.js","sourceRoot":"","sources":["../../src/status/marker.ts"],"names":[],"mappings":"AACA,sFAAsF;AACtF,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGxD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAuB,EAAE;IACrE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC/B,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,KAAK,CAAA;IAC1C,MAAM,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,CAAA;IAE1E,OAAO;QACL,MAAM,EAAE,IAAI,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QACrD,0EAA0E;QAC1E,UAAU,EAAE,EAAE,IAAI,IAAI,IAAI,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;KAC1D,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,35 @@
1
+ /** The HTTP status the API client stamps on an error it rebuilt from a response body. */
2
+ export interface ResponseStatusCarrier {
3
+ responseStatus?: number;
4
+ denialKind?: string;
5
+ }
6
+ /** What an `api:client:*` marker states. */
7
+ export interface ClientMarker {
8
+ status?: number;
9
+ incidentId?: string;
10
+ }
11
+ /** Reads the HTTP status, the incident id and the denial kind a failed call carries. */
12
+ export interface ApiStatusHelper {
13
+ /** True only for a server-labelled auth/IAM refusal, never an unrelated 403. */
14
+ isAccessDenied: (error: unknown) => boolean;
15
+ /**
16
+ * The HTTP status an error answers to, or `null` when nothing states one.
17
+ *
18
+ * Read in order: the status the API client stamped on the error it rebuilt from a response
19
+ * (`responseStatus`); the status an `ApiClientError` parsed from its marker; the `httpStatus` its
20
+ * class declares — a 4xx always, a 5xx only with `allowServerErrorStatus`, exactly what an
21
+ * `@owlmeans/server-api` boundary answers with; finally an `api:client:*` marker in the message or
22
+ * the type of anything else. This is what lets a browser recognise a refusal from its status
23
+ * alone when a production body carries nothing but an incident id.
24
+ */
25
+ httpStatusOf: (error: unknown) => number | null;
26
+ /** The server's incident id carried by an error — its own field, else its marker — or `null`. */
27
+ incidentIdOf: (error: unknown) => string | null;
28
+ /**
29
+ * Whether a response body is a production incident body — the bare incident UUID an
30
+ * `@owlmeans/server-api` boundary sends instead of the marshaled error. A development body
31
+ * carries the `ResilientError` separator and is never one.
32
+ */
33
+ isIncidentBody: (data: unknown) => data is string;
34
+ }
35
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/status/types.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,MAAM,WAAW,qBAAqB;IACpC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,4CAA4C;AAC5C,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,wFAAwF;AACxF,MAAM,WAAW,eAAe;IAC9B,gFAAgF;IAChF,cAAc,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAA;IAC3C;;;;;;;;;OASG;IACH,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,GAAG,IAAI,CAAA;IAC/C,iGAAiG;IACjG,YAAY,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,GAAG,IAAI,CAAA;IAC/C;;;;OAIG;IACH,cAAc,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,IAAI,MAAM,CAAA;CAClD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/status/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import { BasicClientConfig } from '@owlmeans/client-config';
2
+ import type { BasicContext } from '@owlmeans/context';
3
+ export type Config = BasicClientConfig;
4
+ export interface Context<C extends Config = Config> extends BasicContext<C> {
5
+ }
6
+ //# sourceMappingURL=types.local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.local.d.ts","sourceRoot":"","sources":["../src/types.local.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErD,MAAM,MAAM,MAAM,GAAG,iBAAiB,CAAA;AAEtC,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,YAAY,CAAC,CAAC,CAAC;CAC1E"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.local.js","sourceRoot":"","sources":["../src/types.local.ts"],"names":[],"mappings":""}