@w6w/sdk 0.6.0 → 0.9.8

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 (120) hide show
  1. package/README.md +166 -16
  2. package/dist/mod.d.ts +7 -5
  3. package/dist/mod.d.ts.map +1 -1
  4. package/dist/mod.js +1 -0
  5. package/dist/mod.js.map +1 -1
  6. package/dist/src/client.d.ts +11 -2
  7. package/dist/src/client.d.ts.map +1 -1
  8. package/dist/src/client.js +12 -2
  9. package/dist/src/client.js.map +1 -1
  10. package/dist/src/config.d.ts +83 -6
  11. package/dist/src/config.d.ts.map +1 -1
  12. package/dist/src/config.js +40 -4
  13. package/dist/src/config.js.map +1 -1
  14. package/dist/src/connections.d.ts +3 -2
  15. package/dist/src/connections.d.ts.map +1 -1
  16. package/dist/src/connections.js +7 -2
  17. package/dist/src/connections.js.map +1 -1
  18. package/dist/src/console/api-calls.d.ts +4 -3
  19. package/dist/src/console/api-calls.d.ts.map +1 -1
  20. package/dist/src/console/api-calls.js +4 -3
  21. package/dist/src/console/api-calls.js.map +1 -1
  22. package/dist/src/console/apps.d.ts +181 -8
  23. package/dist/src/console/apps.d.ts.map +1 -1
  24. package/dist/src/console/apps.js +67 -12
  25. package/dist/src/console/apps.js.map +1 -1
  26. package/dist/src/console/auth.d.ts +43 -3
  27. package/dist/src/console/auth.d.ts.map +1 -1
  28. package/dist/src/console/auth.js +23 -4
  29. package/dist/src/console/auth.js.map +1 -1
  30. package/dist/src/console/commerce.d.ts +428 -0
  31. package/dist/src/console/commerce.d.ts.map +1 -0
  32. package/dist/src/console/commerce.js +220 -0
  33. package/dist/src/console/commerce.js.map +1 -0
  34. package/dist/src/console/dashboard.d.ts +8 -0
  35. package/dist/src/console/dashboard.d.ts.map +1 -1
  36. package/dist/src/console/dashboard.js.map +1 -1
  37. package/dist/src/console/endpoints.d.ts +57 -2
  38. package/dist/src/console/endpoints.d.ts.map +1 -1
  39. package/dist/src/console/endpoints.js.map +1 -1
  40. package/dist/src/console/functions.d.ts +35 -4
  41. package/dist/src/console/functions.d.ts.map +1 -1
  42. package/dist/src/console/functions.js +13 -0
  43. package/dist/src/console/functions.js.map +1 -1
  44. package/dist/src/console/mod.d.ts +22 -7
  45. package/dist/src/console/mod.d.ts.map +1 -1
  46. package/dist/src/console/mod.js +16 -1
  47. package/dist/src/console/mod.js.map +1 -1
  48. package/dist/src/console/otp.d.ts +127 -0
  49. package/dist/src/console/otp.d.ts.map +1 -0
  50. package/dist/src/console/otp.js +118 -0
  51. package/dist/src/console/otp.js.map +1 -0
  52. package/dist/src/console/reliability.d.ts +101 -6
  53. package/dist/src/console/reliability.d.ts.map +1 -1
  54. package/dist/src/console/reliability.js +16 -5
  55. package/dist/src/console/reliability.js.map +1 -1
  56. package/dist/src/console/step-tests.d.ts +7 -1
  57. package/dist/src/console/step-tests.d.ts.map +1 -1
  58. package/dist/src/console/step-tests.js +1 -1
  59. package/dist/src/console/step-tests.js.map +1 -1
  60. package/dist/src/console/subscriptions.d.ts +38 -16
  61. package/dist/src/console/subscriptions.d.ts.map +1 -1
  62. package/dist/src/console/subscriptions.js +7 -13
  63. package/dist/src/console/subscriptions.js.map +1 -1
  64. package/dist/src/console/tenant-login-flags.d.ts +106 -0
  65. package/dist/src/console/tenant-login-flags.d.ts.map +1 -0
  66. package/dist/src/console/tenant-login-flags.js +113 -0
  67. package/dist/src/console/tenant-login-flags.js.map +1 -0
  68. package/dist/src/console/tenant-oauth-apps.d.ts +75 -14
  69. package/dist/src/console/tenant-oauth-apps.d.ts.map +1 -1
  70. package/dist/src/console/tenant-oauth-apps.js +37 -11
  71. package/dist/src/console/tenant-oauth-apps.js.map +1 -1
  72. package/dist/src/console/tokens.d.ts +2 -0
  73. package/dist/src/console/tokens.d.ts.map +1 -1
  74. package/dist/src/console/tokens.js.map +1 -1
  75. package/dist/src/console/workflows.d.ts +14 -0
  76. package/dist/src/console/workflows.d.ts.map +1 -1
  77. package/dist/src/console/workflows.js +13 -0
  78. package/dist/src/console/workflows.js.map +1 -1
  79. package/dist/src/documents.d.ts +9 -5
  80. package/dist/src/documents.d.ts.map +1 -1
  81. package/dist/src/documents.js +6 -3
  82. package/dist/src/documents.js.map +1 -1
  83. package/dist/src/functions.d.ts +149 -1
  84. package/dist/src/functions.d.ts.map +1 -1
  85. package/dist/src/functions.js +145 -0
  86. package/dist/src/functions.js.map +1 -1
  87. package/dist/src/http.d.ts +58 -10
  88. package/dist/src/http.d.ts.map +1 -1
  89. package/dist/src/http.js +82 -11
  90. package/dist/src/http.js.map +1 -1
  91. package/dist/src/me.d.ts +3 -2
  92. package/dist/src/me.d.ts.map +1 -1
  93. package/dist/src/me.js +7 -2
  94. package/dist/src/me.js.map +1 -1
  95. package/dist/src/run.d.ts +11 -2
  96. package/dist/src/run.d.ts.map +1 -1
  97. package/dist/src/run.js +11 -2
  98. package/dist/src/run.js.map +1 -1
  99. package/dist/src/server/mod.d.ts +100 -0
  100. package/dist/src/server/mod.d.ts.map +1 -0
  101. package/dist/src/server/mod.js +121 -0
  102. package/dist/src/server/mod.js.map +1 -0
  103. package/dist/src/team.d.ts +204 -0
  104. package/dist/src/team.d.ts.map +1 -0
  105. package/dist/src/team.js +161 -0
  106. package/dist/src/team.js.map +1 -0
  107. package/dist/src/types.d.ts +143 -10
  108. package/dist/src/types.d.ts.map +1 -1
  109. package/dist/src/types.js +27 -0
  110. package/dist/src/types.js.map +1 -1
  111. package/dist/src/vars.d.ts +5 -3
  112. package/dist/src/vars.d.ts.map +1 -1
  113. package/dist/src/vars.js +14 -4
  114. package/dist/src/vars.js.map +1 -1
  115. package/dist/src/version.js +1 -1
  116. package/dist/src/workflows.d.ts +261 -9
  117. package/dist/src/workflows.d.ts.map +1 -1
  118. package/dist/src/workflows.js +246 -7
  119. package/dist/src/workflows.js.map +1 -1
  120. package/package.json +5 -1
@@ -1,12 +1,24 @@
1
1
  /**
2
- * The transport: one `request()`, three failure modes, no policy.
2
+ * The transport: one `request()`, three failure modes, and one opt-in policy.
3
3
  *
4
4
  * Everything the operation modules do goes through {@linkcode request}. It
5
5
  * attaches the bearer, serialises a JSON body, reads the response exactly once,
6
6
  * parses it guardedly, and raises one of the three failure modes pinned in
7
- * `docs/implementation.md` §3 — and nothing else. In particular it does **not**
8
- * retry, does **not** refresh a token, does **not** poll, and does **not**
9
- * inspect an error code to decide on a side effect. A `401` raises and stops.
7
+ * `docs/implementation.md` §3 — and nothing else. It does **not** poll and does
8
+ * **not** inspect an error code to decide on a side effect, beyond the one
9
+ * policy described next.
10
+ *
11
+ * **The one exception is opt-in**: when `config.refreshOnUnauthorized` is
12
+ * `true`, `config.token` is a function, and the request used a bearer
13
+ * (`requireAuth !== false`), a `401` whose `code` is exactly `"unauthorized"`
14
+ * is given a single recovery attempt — the provider is called once more with
15
+ * `{forceRefresh: true}` and, if that yields a usable token, the identical
16
+ * request is re-sent once with it by calling `request()` a second time (never
17
+ * a third). Off by default, this is exactly the old unconditional "a `401`
18
+ * raises and stops" behaviour. `config.onUnauthorized`, when set, receives the
19
+ * terminal `401`/`unauthorized` `ApiError` of a bearer request — after a failed
20
+ * retry, or immediately when recovery is off or impossible — at most once per
21
+ * call, never on success, and never for a `requireAuth: false` request.
10
22
  *
11
23
  * It also returns the **HTTP status** alongside the parsed body, because a
12
24
  * `202` is a normal outcome on this API (a queued workflow run), not an error —
@@ -45,12 +57,12 @@ export interface RequestOptions {
45
57
  /** Request body. Serialised as JSON when present; omit it for a bodiless request. */
46
58
  body?: unknown;
47
59
  /**
48
- * Extra headers to send with this request. Applied as the **base** the
49
- * transport builds on, never the other way around: the bearer
50
- * (`authorization`) and, when a body is present, `content-type` are set
51
- * *after* this base, so a caller-supplied entry with either of those names
52
- * can never override what this transport sets. Any other header name passes
53
- * through untouched.
60
+ * Extra headers to send with this request. Precedence, low to high: the
61
+ * client's own `headers` default < this option < the bearer
62
+ * (`authorization`) and, when a body is present, `content-type`, which this
63
+ * transport sets *after* both and which neither can ever override. A
64
+ * same-named entry here beats the client default; any other header name
65
+ * passes through untouched.
54
66
  */
55
67
  headers?: Record<string, string>;
56
68
  /**
@@ -67,6 +79,32 @@ export interface RequestOptions {
67
79
  * in the first place.
68
80
  */
69
81
  requireAuth?: boolean;
82
+ /**
83
+ * Abort this specific request. Local request control only — it is never
84
+ * serialized into the URL or the body, and the server never sees it. Wired
85
+ * straight through to the injected `fetch`'s own `RequestInit.signal`, so
86
+ * cancellation semantics are whatever the runtime's `fetch` already gives an
87
+ * aborted request; this transport adds no polling, retry or timeout policy
88
+ * on top of it (see this module's header).
89
+ */
90
+ signal?: AbortSignal;
91
+ }
92
+ /**
93
+ * Per-call transport options shared by every read method a react hook calls
94
+ * (R-7): today, just an optional {@linkcode AbortSignal}. A thin, deliberately
95
+ * minimal bag rather than reusing {@linkcode RequestOptions} itself — the
96
+ * typed per-method option interfaces (`DocumentOptions`,
97
+ * `WorkflowListOptions`, …) extend this one, and a method with no options
98
+ * today takes a bare `options?: CallOptions`, so `signal` lands in exactly one
99
+ * place for every read operation.
100
+ *
101
+ * `signal` reaches the injected `fetch` unchanged through
102
+ * {@linkcode RequestOptions.signal} and is NEVER serialized into the URL or
103
+ * the body — see that field's own doc for the cancellation semantics.
104
+ */
105
+ export interface CallOptions {
106
+ /** Abort this call. See {@linkcode RequestOptions.signal}. */
107
+ signal?: AbortSignal;
70
108
  }
71
109
  /**
72
110
  * A successful response: the parsed body plus the status that carried it.
@@ -149,6 +187,16 @@ export declare function buildUrl(config: ResolvedConfig, options: RequestOptions
149
187
  * deliberately a 4xx so Cloudflare cannot swallow it. It is never a transport
150
188
  * error and is never normalised into a 5xx.
151
189
  *
190
+ * **Recovery (opt-in, this module's header).** When a `401`/`unauthorized`
191
+ * {@linkcode ApiError} is about to be raised and `config.refreshOnUnauthorized
192
+ * === true && typeof config.token === "function" && options.requireAuth !==
193
+ * false`, this function calls `config.token({forceRefresh: true})` once; a
194
+ * usable result re-enters `request()` itself — never a second mapper — with a
195
+ * config carrying that **string**, which is what caps the retry at one: the
196
+ * recursive call's `config.token` is no longer a function, so its own recovery
197
+ * check is false by construction. `config.onUnauthorized` is invoked with
198
+ * whichever `401`/`unauthorized` error turns out to be terminal.
199
+ *
152
200
  * @param config - Resolved configuration (base URL and credential).
153
201
  * @param fetchImpl - The transport to use; injected, never read from a module global.
154
202
  * @param options - The request.
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAgB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAGhF;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;AAErE;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;AAEhF,oCAAoC;AACpC,MAAM,WAAW,cAAc;IAC7B,mBAAmB;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,qFAAqF;IACrF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;;;;;;;;;;OAYG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,CAAC;CACT;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAM/E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAOhF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,OAAO,CAAC,CAAC,EAC7B,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAiE1B"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAgB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAGhF;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAC;AAErE;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;AAEhF,oCAAoC;AACpC,MAAM,WAAW,cAAc;IAC7B,mBAAmB;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,qFAAqF;IACrF,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;;;;;;;;;;OAYG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,WAAW;IAC1B,8DAA8D;IAC9D,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,CAAC;CACT;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAM/E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAOhF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAsB,OAAO,CAAC,CAAC,EAC7B,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CA2H1B"}
package/dist/src/http.js CHANGED
@@ -1,12 +1,24 @@
1
1
  /**
2
- * The transport: one `request()`, three failure modes, no policy.
2
+ * The transport: one `request()`, three failure modes, and one opt-in policy.
3
3
  *
4
4
  * Everything the operation modules do goes through {@linkcode request}. It
5
5
  * attaches the bearer, serialises a JSON body, reads the response exactly once,
6
6
  * parses it guardedly, and raises one of the three failure modes pinned in
7
- * `docs/implementation.md` §3 — and nothing else. In particular it does **not**
8
- * retry, does **not** refresh a token, does **not** poll, and does **not**
9
- * inspect an error code to decide on a side effect. A `401` raises and stops.
7
+ * `docs/implementation.md` §3 — and nothing else. It does **not** poll and does
8
+ * **not** inspect an error code to decide on a side effect, beyond the one
9
+ * policy described next.
10
+ *
11
+ * **The one exception is opt-in**: when `config.refreshOnUnauthorized` is
12
+ * `true`, `config.token` is a function, and the request used a bearer
13
+ * (`requireAuth !== false`), a `401` whose `code` is exactly `"unauthorized"`
14
+ * is given a single recovery attempt — the provider is called once more with
15
+ * `{forceRefresh: true}` and, if that yields a usable token, the identical
16
+ * request is re-sent once with it by calling `request()` a second time (never
17
+ * a third). Off by default, this is exactly the old unconditional "a `401`
18
+ * raises and stops" behaviour. `config.onUnauthorized`, when set, receives the
19
+ * terminal `401`/`unauthorized` `ApiError` of a bearer request — after a failed
20
+ * retry, or immediately when recovery is off or impossible — at most once per
21
+ * call, never on success, and never for a `requireAuth: false` request.
10
22
  *
11
23
  * It also returns the **HTTP status** alongside the parsed body, because a
12
24
  * `202` is a normal outcome on this API (a queued workflow run), not an error —
@@ -98,6 +110,16 @@ export function buildUrl(config, options) {
98
110
  * deliberately a 4xx so Cloudflare cannot swallow it. It is never a transport
99
111
  * error and is never normalised into a 5xx.
100
112
  *
113
+ * **Recovery (opt-in, this module's header).** When a `401`/`unauthorized`
114
+ * {@linkcode ApiError} is about to be raised and `config.refreshOnUnauthorized
115
+ * === true && typeof config.token === "function" && options.requireAuth !==
116
+ * false`, this function calls `config.token({forceRefresh: true})` once; a
117
+ * usable result re-enters `request()` itself — never a second mapper — with a
118
+ * config carrying that **string**, which is what caps the retry at one: the
119
+ * recursive call's `config.token` is no longer a function, so its own recovery
120
+ * check is false by construction. `config.onUnauthorized` is invoked with
121
+ * whichever `401`/`unauthorized` error turns out to be terminal.
122
+ *
101
123
  * @param config - Resolved configuration (base URL and credential).
102
124
  * @param fetchImpl - The transport to use; injected, never read from a module global.
103
125
  * @param options - The request.
@@ -107,18 +129,21 @@ export function buildUrl(config, options) {
107
129
  */
108
130
  export async function request(config, fetchImpl, options) {
109
131
  const url = buildUrl(config, options);
110
- // The caller-supplied headers are the BASE the transport builds on, never the
111
- // reverse: `authorization` and `content-type` are set below, after this base,
112
- // so nothing a caller passes here can shadow the bearer this transport
113
- // attaches or the content-type it advertises for a JSON body.
114
- const headers = new Headers(options.headers);
132
+ // Precedence, low to high: the client's own default `headers` < this
133
+ // request's `headers` < the bearer/content-type this transport re-pins
134
+ // below. `.set` on an already-present name overrides it, which is what lets
135
+ // a per-request header beat a same-named client default.
136
+ const headers = new Headers(config.headers);
137
+ for (const [name, value] of Object.entries(options.headers ?? {})) {
138
+ headers.set(name, value);
139
+ }
115
140
  // Resolved per request rather than at construction: a client with no token is
116
141
  // constructible (so a CLI's --help works offline) and fails here instead.
117
142
  // Skipped entirely when `requireAuth: false` — not just left unset, but never
118
143
  // even attempted, so a tokenless client can call a public route without
119
144
  // `requireToken` raising first.
120
145
  if (options.requireAuth !== false) {
121
- headers.set("authorization", `Bearer ${requireToken(config)}`);
146
+ headers.set("authorization", `Bearer ${await requireToken(config)}`);
122
147
  }
123
148
  const hasBody = options.body !== undefined;
124
149
  if (hasBody)
@@ -129,9 +154,22 @@ export async function request(config, fetchImpl, options) {
129
154
  method: options.method,
130
155
  headers,
131
156
  body: hasBody ? JSON.stringify(options.body) : undefined,
157
+ signal: options.signal,
132
158
  });
133
159
  }
134
160
  catch (err) {
161
+ // An aborted request is a distinct, recognizable outcome from an actual
162
+ // network failure — a caller that cancelled a stale search/tab-switch
163
+ // request must be able to tell "I cancelled this" from "the server is
164
+ // unreachable" without inspecting `err.message` text. `signal.aborted` is
165
+ // checked rather than matching only on `err.name === "AbortError"`
166
+ // because it is the runtime-agnostic source of truth (the DOM/undici
167
+ // `fetch` both set it synchronously before the promise rejects).
168
+ const cancelled = options.signal?.aborted === true ||
169
+ (err instanceof Error && err.name === "AbortError");
170
+ if (cancelled) {
171
+ throw new ApiError(0, "cancelled", `Request cancelled (${options.method} ${url}).`);
172
+ }
135
173
  throw new ApiError(0, "network_error", `Could not reach the w6w server (${options.method} ${url}). ` +
136
174
  `It may be down or unreachable. (${err instanceof Error ? err.message : String(err)})`);
137
175
  }
@@ -152,7 +190,40 @@ export async function request(config, fetchImpl, options) {
152
190
  }
153
191
  if (!res.ok) {
154
192
  const envelope = data?.error ?? {};
155
- throw new ApiError(res.status, envelope.code ?? "error", envelope.message ?? res.statusText, data);
193
+ const apiError = new ApiError(res.status, envelope.code ?? "error", envelope.message ?? res.statusText, data);
194
+ const isUnauthorized = apiError.status === 401 && apiError.code === "unauthorized";
195
+ const { token } = config;
196
+ if (config.refreshOnUnauthorized === true &&
197
+ typeof token === "function" &&
198
+ options.requireAuth !== false &&
199
+ isUnauthorized) {
200
+ let refreshed;
201
+ try {
202
+ // The one and only forced refresh: never passed by ordinary
203
+ // resolution, passed here exactly once.
204
+ refreshed = await token({ forceRefresh: true });
205
+ }
206
+ catch {
207
+ refreshed = undefined;
208
+ }
209
+ if (typeof refreshed === "string" && refreshed.trim().length > 0) {
210
+ // Re-enter request() itself — the only status→ApiError mapper in this
211
+ // module — rather than re-implementing it. The retried config carries
212
+ // the refreshed token as a plain STRING, so this recursive call's own
213
+ // `typeof config.token === "function"` check is false: that is what
214
+ // caps this at one retry, never a third attempt, AND it is why the
215
+ // recursive call's own terminal-error handling below (not a second
216
+ // copy of it here) is what calls `onUnauthorized` on a retry that
217
+ // still comes back 401 — calling it here too would fire it twice.
218
+ return await request({ ...config, token: refreshed }, fetchImpl, options);
219
+ }
220
+ // No usable refreshed token (nullish, blank, or the provider threw):
221
+ // no retry — fall through and report the ORIGINAL 401.
222
+ }
223
+ if (isUnauthorized && options.requireAuth !== false) {
224
+ config.onUnauthorized?.(apiError);
225
+ }
226
+ throw apiError;
156
227
  }
157
228
  return { status: res.status, body: data };
158
229
  }
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAkB,YAAY,EAAuB,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAoEvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,IAAI,CAAC,OAA6B,EAAE,GAAG,MAAgB;IACrE,OAAO,OAAO,CAAC,MAAM,CACnB,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,CACnB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,EAAE,EAC9E,EAAE,CACH,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAsB,EAAE,OAAuB;IACtE,MAAM,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;QAChE,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;IAChC,OAAO,GAAG,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACvE,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,MAAsB,EACtB,SAAoB,EACpB,OAAuB;IAEvB,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,8EAA8E;IAC9E,8EAA8E;IAC9E,uEAAuE;IACvE,8DAA8D;IAC9D,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,8EAA8E;IAC9E,0EAA0E;IAC1E,8EAA8E;IAC9E,wEAAwE;IACxE,gCAAgC;IAChC,IAAI,OAAO,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC;IAC3C,IAAI,OAAO;QAAE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;IAE7D,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE;YACzB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO;YACP,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SACzD,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,QAAQ,CAChB,CAAC,EACD,eAAe,EACf,mCAAmC,OAAO,CAAC,MAAM,IAAI,GAAG,KAAK;YAC3D,mCAAmC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CACzF,CAAC;IACJ,CAAC;IAED,4EAA4E;IAC5E,6EAA6E;IAC7E,6CAA6C;IAC7C,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,IAAI,GAAY,IAAI,CAAC;IACzB,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,IAAI,QAAQ,CAChB,GAAG,CAAC,MAAM,EACV,cAAc,EACd,8BAA8B,GAAG,CAAC,MAAM,cAAc,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAC3E,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,QAAQ,GAAI,IAA+D,EAAE,KAAK,IAAI,EAAE,CAAC;QAC/F,MAAM,IAAI,QAAQ,CAChB,GAAG,CAAC,MAAM,EACV,QAAQ,CAAC,IAAI,IAAI,OAAO,EACxB,QAAQ,CAAC,OAAO,IAAI,GAAG,CAAC,UAAU,EAClC,IAAI,CACL,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,IAAS,EAAE,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"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"}
package/dist/src/me.d.ts CHANGED
@@ -21,7 +21,7 @@
21
21
  *
22
22
  * @module
23
23
  */
24
- import type { HttpResponse, RequestOptions } from "./http.ts";
24
+ import type { CallOptions, HttpResponse, RequestOptions } from "./http.ts";
25
25
  import type { Me } from "./types.ts";
26
26
  /**
27
27
  * The slice of `W6WClient` this operation needs: the transport, and nothing
@@ -43,11 +43,12 @@ export interface MeHost {
43
43
  * the server sent the block at all.
44
44
  *
45
45
  * @param host - The client this operation issues its request through.
46
+ * @param options - Optional per-call transport options (`signal` to abort).
46
47
  * @returns The caller's identity, with `versions.wrapper` filled in.
47
48
  * @throws {ApiError} On any non-2xx, e.g. `401` when the token is not accepted.
48
49
  * @throws {ApiError} `bad_response` when a 2xx body is not a plain object — an
49
50
  * array included, since `typeof [] === "object"` and a spread array yields
50
51
  * character-indexed keys rather than identity fields.
51
52
  */
52
- export declare function fetchMe(host: MeHost): Promise<Me>;
53
+ export declare function fetchMe(host: MeHost, options?: CallOptions): Promise<Me>;
53
54
  //# sourceMappingURL=me.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"me.d.ts","sourceRoot":"","sources":["../../src/me.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAGrC;;;;;GAKG;AACH,MAAM,WAAW,MAAM;IACrB,2BAA2B;IAC3B,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,CAuCvD"}
1
+ {"version":3,"file":"me.d.ts","sourceRoot":"","sources":["../../src/me.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAGrC;;;;;GAKG;AACH,MAAM,WAAW,MAAM;IACrB,2BAA2B;IAC3B,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,EAAE,CAAC,CA2C9E"}
package/dist/src/me.js CHANGED
@@ -33,14 +33,19 @@ import { VERSION } from "./version.js";
33
33
  * the server sent the block at all.
34
34
  *
35
35
  * @param host - The client this operation issues its request through.
36
+ * @param options - Optional per-call transport options (`signal` to abort).
36
37
  * @returns The caller's identity, with `versions.wrapper` filled in.
37
38
  * @throws {ApiError} On any non-2xx, e.g. `401` when the token is not accepted.
38
39
  * @throws {ApiError} `bad_response` when a 2xx body is not a plain object — an
39
40
  * array included, since `typeof [] === "object"` and a spread array yields
40
41
  * character-indexed keys rather than identity fields.
41
42
  */
42
- export async function fetchMe(host) {
43
- const res = await host.request({ method: "GET", path: "/auth/me" });
43
+ export async function fetchMe(host, options) {
44
+ const res = await host.request({
45
+ method: "GET",
46
+ path: "/auth/me",
47
+ signal: options?.signal,
48
+ });
44
49
  const body = res.body;
45
50
  // A body that is not an object cannot be identity data. Raise rather than
46
51
  // spread it — the same `bad_response` class the envelope reader uses for the
@@ -1 +1 @@
1
- {"version":3,"file":"me.js","sourceRoot":"","sources":["../../src/me.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAavC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAY;IACxC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IACxE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IACtB,0EAA0E;IAC1E,6EAA6E;IAC7E,uEAAuE;IACvE,0EAA0E;IAC1E,SAAS;IACT,EAAE;IACF,iFAAiF;IACjF,iFAAiF;IACjF,6EAA6E;IAC7E,iFAAiF;IACjF,+EAA+E;IAC/E,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,QAAQ,CAChB,GAAG,CAAC,MAAM,EACV,cAAc,EACd,qBAAqB,GAAG,CAAC,MAAM,wCAAwC,EACvE,IAAI,CACL,CAAC;IACJ,CAAC;IACD,+EAA+E;IAC/E,mEAAmE;IACnE,gFAAgF;IAChF,6EAA6E;IAC7E,4EAA4E;IAC5E,+EAA+E;IAC/E,sEAAsE;IACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC/B,MAAM,MAAM,GAAG,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC1F,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,SAAS,CAAC;IACd,OAAO;QACL,GAAG,IAAI;QACP,2EAA2E;QAC3E,oEAAoE;QACpE,QAAQ,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE;KAC1C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"me.js","sourceRoot":"","sources":["../../src/me.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAavC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAY,EAAE,OAAqB;IAC/D,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAK;QACjC,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,OAAO,EAAE,MAAM;KACxB,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IACtB,0EAA0E;IAC1E,6EAA6E;IAC7E,uEAAuE;IACvE,0EAA0E;IAC1E,SAAS;IACT,EAAE;IACF,iFAAiF;IACjF,iFAAiF;IACjF,6EAA6E;IAC7E,iFAAiF;IACjF,+EAA+E;IAC/E,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,QAAQ,CAChB,GAAG,CAAC,MAAM,EACV,cAAc,EACd,qBAAqB,GAAG,CAAC,MAAM,wCAAwC,EACvE,IAAI,CACL,CAAC;IACJ,CAAC;IACD,+EAA+E;IAC/E,mEAAmE;IACnE,gFAAgF;IAChF,6EAA6E;IAC7E,4EAA4E;IAC5E,+EAA+E;IAC/E,sEAAsE;IACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC/B,MAAM,MAAM,GAAG,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC1F,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,SAAS,CAAC;IACd,OAAO;QACL,GAAG,IAAI;QACP,2EAA2E;QAC3E,oEAAoE;QACpE,QAAQ,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,EAAE;KAC1C,CAAC;AACJ,CAAC"}
package/dist/src/run.d.ts CHANGED
@@ -12,11 +12,20 @@
12
12
  * | `"function"` | `output` | `200` |
13
13
  * | `"workflow"` | `runId` + `status` | `202` |
14
14
  *
15
- * `value` and `output` are **deliberately different names** and are never
16
- * normalised into one field: the discrimination is the whole point of the
15
+ * `value` and `output` were **deliberately different names** and `value` is
16
+ * never removed: the discrimination is the whole point of the
17
17
  * operation (D3). `202` on the workflow arm is **success** — the run is queued
18
18
  * and `runId` is how the caller follows it.
19
19
  *
20
+ * ── The invocation frame ──
21
+ * Since 2026-08-20 every arm also carries the platform's own record of the
22
+ * attempt — `invocationId` (`inv_…`), `status`, `startedAt`, `finishedAt`,
23
+ * `durationMs` — and the action arm carries `output` beside `value`, with the
24
+ * identical payload. All additive; nothing was renamed. `status` is the
25
+ * PLATFORM's verdict (`succeeded` | `failed` | `queued`), not one the target
26
+ * reported inside its own payload, and `invocationId` (this call) is not
27
+ * `runId` (the queued workflow run a call may have started).
28
+ *
20
29
  * ── The unknown fourth kind ──
21
30
  * A `kind` this release has never heard of is **returned verbatim**, never
22
31
  * raised (`docs/implementation.md` §5). `run` dispatches on whatever a URN
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACtB,2BAA2B;IAC3B,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/D;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACvB;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CA8BjF"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACtB,2BAA2B;IAC3B,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/D;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,QAAQ;IACvB;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,CA8BjF"}
package/dist/src/run.js CHANGED
@@ -12,11 +12,20 @@
12
12
  * | `"function"` | `output` | `200` |
13
13
  * | `"workflow"` | `runId` + `status` | `202` |
14
14
  *
15
- * `value` and `output` are **deliberately different names** and are never
16
- * normalised into one field: the discrimination is the whole point of the
15
+ * `value` and `output` were **deliberately different names** and `value` is
16
+ * never removed: the discrimination is the whole point of the
17
17
  * operation (D3). `202` on the workflow arm is **success** — the run is queued
18
18
  * and `runId` is how the caller follows it.
19
19
  *
20
+ * ── The invocation frame ──
21
+ * Since 2026-08-20 every arm also carries the platform's own record of the
22
+ * attempt — `invocationId` (`inv_…`), `status`, `startedAt`, `finishedAt`,
23
+ * `durationMs` — and the action arm carries `output` beside `value`, with the
24
+ * identical payload. All additive; nothing was renamed. `status` is the
25
+ * PLATFORM's verdict (`succeeded` | `failed` | `queued`), not one the target
26
+ * reported inside its own payload, and `invocationId` (this call) is not
27
+ * `runId` (the queued workflow run a call may have started).
28
+ *
20
29
  * ── The unknown fourth kind ──
21
30
  * A `kind` this release has never heard of is **returned verbatim**, never
22
31
  * raised (`docs/implementation.md` §5). `run` dispatches on whatever a URN
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAwCvC;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAa,EAAE,KAAe;IACzD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAU;QACtC,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE;YACJ,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,oEAAoE;YACpE,0EAA0E;YAC1E,mBAAmB;YACnB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE;SAC7B;KACF,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IACtB,IACE,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;QACzC,OAAQ,IAA2B,CAAC,IAAI,KAAK,QAAQ,EACrD,CAAC;QACD,MAAM,IAAI,QAAQ,CAChB,GAAG,CAAC,MAAM,EACV,cAAc,EACd,qBAAqB,GAAG,CAAC,MAAM,uCAAuC,EACtE,IAAI,CACL,CAAC;IACJ,CAAC;IACD,qEAAqE;IACrE,yEAAyE;IACzE,wBAAwB;IACxB,OAAO,IAAmB,CAAC;AAC7B,CAAC"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/run.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAwCvC;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAa,EAAE,KAAe;IACzD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAU;QACtC,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE;YACJ,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,oEAAoE;YACpE,0EAA0E;YAC1E,mBAAmB;YACnB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE;SAC7B;KACF,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;IACtB,IACE,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;QACzC,OAAQ,IAA2B,CAAC,IAAI,KAAK,QAAQ,EACrD,CAAC;QACD,MAAM,IAAI,QAAQ,CAChB,GAAG,CAAC,MAAM,EACV,cAAc,EACd,qBAAqB,GAAG,CAAC,MAAM,uCAAuC,EACtE,IAAI,CACL,CAAC;IACJ,CAAC;IACD,qEAAqE;IACrE,yEAAyE;IACzE,wBAAwB;IACxB,OAAO,IAAmB,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * `@w6w/sdk/server` — a backend-only token exchange, for a partner embedding
3
+ * w6w inside its own product.
4
+ *
5
+ * A **separate** entry point from the package root (`@w6w/sdk`) and from
6
+ * `@w6w/sdk/console`: deliberately excluded from `endpoints.json`'s
7
+ * `operations[]` and from the root barrel (`../../mod.ts`), documented
8
+ * instead in `docs/sdk-surface.md` (R-5). Nothing here is reachable from
9
+ * either of those entry points, and this module imports nothing from
10
+ * `../console/mod.ts`.
11
+ *
12
+ * **Egress / trust boundary.** {@linkcode exchangeToken} sends a tenant's
13
+ * client secret over the wire, once per call, and only as an HTTP Basic
14
+ * credential — never in the body, the URL or a query string. It is built on
15
+ * the package's existing transport (`../http.ts`'s `request`, `../config.ts`'s
16
+ * `resolveConfig`) with `requireAuth: false` — the same escape hatch
17
+ * `console.auth.login` uses for a route that authenticates itself rather than
18
+ * via a bearer — so this is a thin caller of the one HTTP path this package
19
+ * has, never a second one.
20
+ *
21
+ * This function is meant to run on a partner's OWN backend, never in a
22
+ * browser: the client secret it takes must never reach client-side code. See
23
+ * `README.md`'s "Embedding for enterprise tenants" section for the worked
24
+ * route this is designed to sit behind.
25
+ *
26
+ * @module
27
+ */
28
+ import { type FetchLike } from "../config.ts";
29
+ /** Options for {@linkcode exchangeToken}. */
30
+ export interface ExchangeTokenOptions {
31
+ /**
32
+ * The w6w server's origin, e.g. `https://api.example.com`. Same rules as
33
+ * {@linkcode W6WClientOptions.baseUrl} — an absolute `http(s)` URL with a
34
+ * host.
35
+ */
36
+ baseUrl: string;
37
+ /** The tenant's client id. Must not contain `:` or a non-latin-1 character. */
38
+ clientId: string;
39
+ /** The tenant's client secret. Must be latin-1 encodable. */
40
+ clientSecret: string;
41
+ /**
42
+ * The partner's end-user id. Minted into the returned token's `sub` claim
43
+ * verbatim — this function does not validate or canonicalise it.
44
+ */
45
+ subject: string;
46
+ /**
47
+ * Optional account claim. **Trusted verbatim**: the server mints whatever
48
+ * `account` it is given into the token, so the caller — this function's own
49
+ * caller, on the partner's backend — is responsible for deriving it from
50
+ * ITS OWN membership data, never from an unauthenticated client input. See
51
+ * `README.md`'s embedding example.
52
+ */
53
+ account?: string;
54
+ /** Transport override. Defaults to `globalThis.fetch`, bound. */
55
+ fetch?: FetchLike;
56
+ }
57
+ /** The shape `POST /auth/exchange` answers with on success. */
58
+ export interface ExchangeTokenResult {
59
+ /** The minted, short-lived bearer token. */
60
+ token: string;
61
+ /** The identity the token carries. */
62
+ user: {
63
+ /** The `subject` this call passed, echoed back. */
64
+ subject: string;
65
+ /** The tenant the client credentials resolved to. */
66
+ tenant: string;
67
+ /** Always `"user"` for a token minted this way. */
68
+ role: string;
69
+ /** The resolved account claim — the `account` passed, or the tenant id when omitted. */
70
+ account: string;
71
+ };
72
+ /** Token lifetime, in seconds. */
73
+ expiresIn: number;
74
+ }
75
+ /**
76
+ * Exchange a tenant's client credentials for a short-lived, per-user w6w
77
+ * token: `POST /auth/exchange`.
78
+ *
79
+ * Credentials travel ONLY as `Authorization: Basic base64(clientId:clientSecret)`
80
+ * — never in the body, the URL or a query string. The body sent is exactly
81
+ * `{ subject }`, or `{ subject, account }` when `account` is given; omitting
82
+ * `account` never puts the key in the body at all (not even as `null` or
83
+ * `undefined`).
84
+ *
85
+ * Every validation failure below is a local {@linkcode ConfigError}, raised
86
+ * **before any network call**, and none of them ever echo `clientSecret`.
87
+ *
88
+ * @param options - See {@linkcode ExchangeTokenOptions}.
89
+ * @returns The minted token and the identity it carries.
90
+ * @throws {ConfigError} Blank `clientId`/`clientSecret`/`subject`; a `clientId`
91
+ * containing `:`; a `clientId`/`clientSecret` outside latin-1; no base URL;
92
+ * no runtime `fetch`.
93
+ * @throws {ApiError} `invalid_client` (401, unknown/disabled credentials),
94
+ * `invalid_body` / `invalid_subject` / `invalid_account` (400), or any of
95
+ * the transport's own failure modes (`../http.ts`). Never retried: this
96
+ * call always passes `requireAuth: false`, which `request()` never grants a
97
+ * recovery attempt.
98
+ */
99
+ export declare function exchangeToken(options: ExchangeTokenOptions): Promise<ExchangeTokenResult>;
100
+ //# sourceMappingURL=mod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../../src/server/mod.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,cAAc,CAAC;AAI7D,6CAA6C;AAC7C,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED,+DAA+D;AAC/D,MAAM,WAAW,mBAAmB;IAClC,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,IAAI,EAAE;QACJ,mDAAmD;QACnD,OAAO,EAAE,MAAM,CAAC;QAChB,qDAAqD;QACrD,MAAM,EAAE,MAAM,CAAC;QACf,mDAAmD;QACnD,IAAI,EAAE,MAAM,CAAC;QACb,wFAAwF;QACxF,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;CACnB;AAsDD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,aAAa,CACjC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAwB9B"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * `@w6w/sdk/server` — a backend-only token exchange, for a partner embedding
3
+ * w6w inside its own product.
4
+ *
5
+ * A **separate** entry point from the package root (`@w6w/sdk`) and from
6
+ * `@w6w/sdk/console`: deliberately excluded from `endpoints.json`'s
7
+ * `operations[]` and from the root barrel (`../../mod.ts`), documented
8
+ * instead in `docs/sdk-surface.md` (R-5). Nothing here is reachable from
9
+ * either of those entry points, and this module imports nothing from
10
+ * `../console/mod.ts`.
11
+ *
12
+ * **Egress / trust boundary.** {@linkcode exchangeToken} sends a tenant's
13
+ * client secret over the wire, once per call, and only as an HTTP Basic
14
+ * credential — never in the body, the URL or a query string. It is built on
15
+ * the package's existing transport (`../http.ts`'s `request`, `../config.ts`'s
16
+ * `resolveConfig`) with `requireAuth: false` — the same escape hatch
17
+ * `console.auth.login` uses for a route that authenticates itself rather than
18
+ * via a bearer — so this is a thin caller of the one HTTP path this package
19
+ * has, never a second one.
20
+ *
21
+ * This function is meant to run on a partner's OWN backend, never in a
22
+ * browser: the client secret it takes must never reach client-side code. See
23
+ * `README.md`'s "Embedding for enterprise tenants" section for the worked
24
+ * route this is designed to sit behind.
25
+ *
26
+ * @module
27
+ */
28
+ import { resolveConfig } from "../config.js";
29
+ import { ConfigError } from "../errors.js";
30
+ import { request } from "../http.js";
31
+ /** Non-blank after trimming. */
32
+ function required(value, field) {
33
+ if (value.trim().length === 0) {
34
+ throw new ConfigError(`exchangeToken: \`${field}\` must not be blank.`);
35
+ }
36
+ }
37
+ /**
38
+ * Base64-encode `clientId:clientSecret` the way the server decodes it:
39
+ * latin-1 (`atob`'s own alphabet), via `btoa`.
40
+ *
41
+ * `btoa` itself rejects any character outside latin-1 (U+0000–U+00FF),
42
+ * raising for us — this is NOT re-implemented with a UTF-8 path, because that
43
+ * would silently encode a secret the server's `atob` could never decode back
44
+ * to the same bytes.
45
+ *
46
+ * @throws {ConfigError} When `clientId` contains `:` (indistinguishable from
47
+ * the Basic separator on decode) or either value is not latin-1.
48
+ */
49
+ function basicAuthHeader(clientId, clientSecret) {
50
+ if (clientId.includes(":")) {
51
+ throw new ConfigError('exchangeToken: `clientId` must not contain ":" — the server splits a ' +
52
+ "decoded Basic credential on the FIRST colon, so a colon in `clientId` " +
53
+ "would be read as part of the secret instead.");
54
+ }
55
+ try {
56
+ return btoa(`${clientId}:${clientSecret}`);
57
+ }
58
+ catch {
59
+ throw new ConfigError("exchangeToken: `clientId`/`clientSecret` must be representable as " +
60
+ "latin-1 (ISO-8859-1) — the server decodes the Basic header with " +
61
+ "`atob`, which cannot represent a wider character set.");
62
+ }
63
+ }
64
+ function resolveFetch(fetchOption) {
65
+ if (fetchOption)
66
+ return fetchOption;
67
+ const global = globalThis.fetch;
68
+ if (typeof global !== "function") {
69
+ throw new ConfigError("This runtime has no global fetch. Pass an implementation " +
70
+ "(exchangeToken({ ..., fetch })) or run on Node 18+, Deno or Bun.");
71
+ }
72
+ // Bound, so it keeps working when called as a bare function reference —
73
+ // exactly W6WClient's own default (../client.ts).
74
+ return global.bind(globalThis);
75
+ }
76
+ /**
77
+ * Exchange a tenant's client credentials for a short-lived, per-user w6w
78
+ * token: `POST /auth/exchange`.
79
+ *
80
+ * Credentials travel ONLY as `Authorization: Basic base64(clientId:clientSecret)`
81
+ * — never in the body, the URL or a query string. The body sent is exactly
82
+ * `{ subject }`, or `{ subject, account }` when `account` is given; omitting
83
+ * `account` never puts the key in the body at all (not even as `null` or
84
+ * `undefined`).
85
+ *
86
+ * Every validation failure below is a local {@linkcode ConfigError}, raised
87
+ * **before any network call**, and none of them ever echo `clientSecret`.
88
+ *
89
+ * @param options - See {@linkcode ExchangeTokenOptions}.
90
+ * @returns The minted token and the identity it carries.
91
+ * @throws {ConfigError} Blank `clientId`/`clientSecret`/`subject`; a `clientId`
92
+ * containing `:`; a `clientId`/`clientSecret` outside latin-1; no base URL;
93
+ * no runtime `fetch`.
94
+ * @throws {ApiError} `invalid_client` (401, unknown/disabled credentials),
95
+ * `invalid_body` / `invalid_subject` / `invalid_account` (400), or any of
96
+ * the transport's own failure modes (`../http.ts`). Never retried: this
97
+ * call always passes `requireAuth: false`, which `request()` never grants a
98
+ * recovery attempt.
99
+ */
100
+ export async function exchangeToken(options) {
101
+ const { baseUrl, clientId, clientSecret, subject, account } = options;
102
+ required(clientId, "clientId");
103
+ required(clientSecret, "clientSecret");
104
+ required(subject, "subject");
105
+ const basic = basicAuthHeader(clientId, clientSecret);
106
+ const config = resolveConfig({ baseUrl });
107
+ const fetchImpl = resolveFetch(options.fetch);
108
+ const body = { subject };
109
+ if (account !== undefined) {
110
+ body.account = account;
111
+ }
112
+ const res = await request(config, fetchImpl, {
113
+ method: "POST",
114
+ path: "/auth/exchange",
115
+ body,
116
+ headers: { authorization: `Basic ${basic}` },
117
+ requireAuth: false,
118
+ });
119
+ return res.body;
120
+ }
121
+ //# sourceMappingURL=mod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.js","sourceRoot":"","sources":["../../../src/server/mod.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAkB,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAkDrC,gCAAgC;AAChC,SAAS,QAAQ,CAAC,KAAa,EAAE,KAAa;IAC5C,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,WAAW,CAAC,oBAAoB,KAAK,uBAAuB,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,eAAe,CAAC,QAAgB,EAAE,YAAoB;IAC7D,IAAI,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,WAAW,CACnB,uEAAuE;YACrE,wEAAwE;YACxE,8CAA8C,CACjD,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,GAAG,QAAQ,IAAI,YAAY,EAAE,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,WAAW,CACnB,oEAAoE;YAClE,kEAAkE;YAClE,uDAAuD,CAC1D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,WAAkC;IACtD,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IACpC,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC;IAChC,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;QACjC,MAAM,IAAI,WAAW,CACnB,2DAA2D;YACzD,kEAAkE,CACrE,CAAC;IACJ,CAAC;IACD,wEAAwE;IACxE,kDAAkD;IAClD,OAAO,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAA6B;IAE7B,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IAEtE,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC7B,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IAEtD,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAE9C,MAAM,IAAI,GAA0C,EAAE,OAAO,EAAE,CAAC;IAChE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,OAAO,CAAsB,MAAM,EAAE,SAAS,EAAE;QAChE,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,gBAAgB;QACtB,IAAI;QACJ,OAAO,EAAE,EAAE,aAAa,EAAE,SAAS,KAAK,EAAE,EAAE;QAC5C,WAAW,EAAE,KAAK;KACnB,CAAC,CAAC;IACH,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC"}