@w6w/sdk 0.6.0 → 0.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +166 -16
- package/dist/mod.d.ts +7 -5
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +1 -0
- package/dist/mod.js.map +1 -1
- package/dist/src/client.d.ts +11 -2
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/client.js +12 -2
- package/dist/src/client.js.map +1 -1
- package/dist/src/config.d.ts +83 -6
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +40 -4
- package/dist/src/config.js.map +1 -1
- package/dist/src/connections.d.ts +3 -2
- package/dist/src/connections.d.ts.map +1 -1
- package/dist/src/connections.js +7 -2
- package/dist/src/connections.js.map +1 -1
- package/dist/src/console/api-calls.d.ts +4 -3
- package/dist/src/console/api-calls.d.ts.map +1 -1
- package/dist/src/console/api-calls.js +4 -3
- package/dist/src/console/api-calls.js.map +1 -1
- package/dist/src/console/apps.d.ts +181 -8
- package/dist/src/console/apps.d.ts.map +1 -1
- package/dist/src/console/apps.js +67 -12
- package/dist/src/console/apps.js.map +1 -1
- package/dist/src/console/auth.d.ts +43 -3
- package/dist/src/console/auth.d.ts.map +1 -1
- package/dist/src/console/auth.js +23 -4
- package/dist/src/console/auth.js.map +1 -1
- package/dist/src/console/commerce.d.ts +428 -0
- package/dist/src/console/commerce.d.ts.map +1 -0
- package/dist/src/console/commerce.js +220 -0
- package/dist/src/console/commerce.js.map +1 -0
- package/dist/src/console/dashboard.d.ts +8 -0
- package/dist/src/console/dashboard.d.ts.map +1 -1
- package/dist/src/console/dashboard.js.map +1 -1
- package/dist/src/console/endpoints.d.ts +57 -2
- package/dist/src/console/endpoints.d.ts.map +1 -1
- package/dist/src/console/endpoints.js.map +1 -1
- package/dist/src/console/functions.d.ts +35 -4
- package/dist/src/console/functions.d.ts.map +1 -1
- package/dist/src/console/functions.js +13 -0
- package/dist/src/console/functions.js.map +1 -1
- package/dist/src/console/mod.d.ts +22 -7
- package/dist/src/console/mod.d.ts.map +1 -1
- package/dist/src/console/mod.js +16 -1
- package/dist/src/console/mod.js.map +1 -1
- package/dist/src/console/otp.d.ts +127 -0
- package/dist/src/console/otp.d.ts.map +1 -0
- package/dist/src/console/otp.js +118 -0
- package/dist/src/console/otp.js.map +1 -0
- package/dist/src/console/reliability.d.ts +101 -6
- package/dist/src/console/reliability.d.ts.map +1 -1
- package/dist/src/console/reliability.js +16 -5
- package/dist/src/console/reliability.js.map +1 -1
- package/dist/src/console/step-tests.d.ts +7 -1
- package/dist/src/console/step-tests.d.ts.map +1 -1
- package/dist/src/console/step-tests.js +1 -1
- package/dist/src/console/step-tests.js.map +1 -1
- package/dist/src/console/subscriptions.d.ts +38 -16
- package/dist/src/console/subscriptions.d.ts.map +1 -1
- package/dist/src/console/subscriptions.js +7 -13
- package/dist/src/console/subscriptions.js.map +1 -1
- package/dist/src/console/tenant-login-flags.d.ts +106 -0
- package/dist/src/console/tenant-login-flags.d.ts.map +1 -0
- package/dist/src/console/tenant-login-flags.js +113 -0
- package/dist/src/console/tenant-login-flags.js.map +1 -0
- package/dist/src/console/tenant-oauth-apps.d.ts +75 -14
- package/dist/src/console/tenant-oauth-apps.d.ts.map +1 -1
- package/dist/src/console/tenant-oauth-apps.js +37 -11
- package/dist/src/console/tenant-oauth-apps.js.map +1 -1
- package/dist/src/console/tokens.d.ts +2 -0
- package/dist/src/console/tokens.d.ts.map +1 -1
- package/dist/src/console/tokens.js.map +1 -1
- package/dist/src/console/workflows.d.ts +14 -0
- package/dist/src/console/workflows.d.ts.map +1 -1
- package/dist/src/console/workflows.js +13 -0
- package/dist/src/console/workflows.js.map +1 -1
- package/dist/src/documents.d.ts +9 -5
- package/dist/src/documents.d.ts.map +1 -1
- package/dist/src/documents.js +6 -3
- package/dist/src/documents.js.map +1 -1
- package/dist/src/functions.d.ts +149 -1
- package/dist/src/functions.d.ts.map +1 -1
- package/dist/src/functions.js +145 -0
- package/dist/src/functions.js.map +1 -1
- package/dist/src/http.d.ts +58 -10
- package/dist/src/http.d.ts.map +1 -1
- package/dist/src/http.js +82 -11
- package/dist/src/http.js.map +1 -1
- package/dist/src/me.d.ts +3 -2
- package/dist/src/me.d.ts.map +1 -1
- package/dist/src/me.js +7 -2
- package/dist/src/me.js.map +1 -1
- package/dist/src/run.d.ts +11 -2
- package/dist/src/run.d.ts.map +1 -1
- package/dist/src/run.js +11 -2
- package/dist/src/run.js.map +1 -1
- package/dist/src/server/mod.d.ts +100 -0
- package/dist/src/server/mod.d.ts.map +1 -0
- package/dist/src/server/mod.js +121 -0
- package/dist/src/server/mod.js.map +1 -0
- package/dist/src/team.d.ts +204 -0
- package/dist/src/team.d.ts.map +1 -0
- package/dist/src/team.js +161 -0
- package/dist/src/team.js.map +1 -0
- package/dist/src/types.d.ts +143 -10
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +27 -0
- package/dist/src/types.js.map +1 -1
- package/dist/src/vars.d.ts +5 -3
- package/dist/src/vars.d.ts.map +1 -1
- package/dist/src/vars.js +14 -4
- package/dist/src/vars.js.map +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/workflows.d.ts +261 -9
- package/dist/src/workflows.d.ts.map +1 -1
- package/dist/src/workflows.js +246 -7
- package/dist/src/workflows.js.map +1 -1
- package/package.json +5 -1
package/dist/src/http.d.ts
CHANGED
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The transport: one `request()`, three failure modes,
|
|
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.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
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.
|
|
49
|
-
*
|
|
50
|
-
* (`authorization`) and, when a body is present, `content-type
|
|
51
|
-
* *after*
|
|
52
|
-
*
|
|
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.
|
package/dist/src/http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"AAAA
|
|
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,
|
|
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.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
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
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
const headers = new 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
|
-
|
|
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
|
}
|
package/dist/src/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"AAAA
|
|
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
|
package/dist/src/me.d.ts.map
CHANGED
|
@@ -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;
|
|
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({
|
|
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
|
package/dist/src/me.js.map
CHANGED
|
@@ -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
|
|
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`
|
|
16
|
-
*
|
|
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
|
package/dist/src/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/run.ts"],"names":[],"mappings":"AAAA
|
|
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`
|
|
16
|
-
*
|
|
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
|
package/dist/src/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/run.ts"],"names":[],"mappings":"AAAA
|
|
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"}
|