@w6w/sdk 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +20 -17
  2. package/dist/mod.d.ts +4 -0
  3. package/dist/mod.d.ts.map +1 -1
  4. package/dist/mod.js +2 -0
  5. package/dist/mod.js.map +1 -1
  6. package/dist/src/client.d.ts +26 -3
  7. package/dist/src/client.d.ts.map +1 -1
  8. package/dist/src/client.js +28 -3
  9. package/dist/src/client.js.map +1 -1
  10. package/dist/src/config.js +1 -1
  11. package/dist/src/config.js.map +1 -1
  12. package/dist/src/console/aliases.d.ts +137 -0
  13. package/dist/src/console/aliases.d.ts.map +1 -0
  14. package/dist/src/console/aliases.js +113 -0
  15. package/dist/src/console/aliases.js.map +1 -0
  16. package/dist/src/console/auth.d.ts +202 -4
  17. package/dist/src/console/auth.d.ts.map +1 -1
  18. package/dist/src/console/auth.js +154 -4
  19. package/dist/src/console/auth.js.map +1 -1
  20. package/dist/src/console/endpoints.d.ts +23 -5
  21. package/dist/src/console/endpoints.d.ts.map +1 -1
  22. package/dist/src/console/endpoints.js.map +1 -1
  23. package/dist/src/console/mod.d.ts +12 -2
  24. package/dist/src/console/mod.d.ts.map +1 -1
  25. package/dist/src/console/mod.js +10 -0
  26. package/dist/src/console/mod.js.map +1 -1
  27. package/dist/src/console/passkeys.d.ts +246 -0
  28. package/dist/src/console/passkeys.d.ts.map +1 -0
  29. package/dist/src/console/passkeys.js +192 -0
  30. package/dist/src/console/passkeys.js.map +1 -0
  31. package/dist/src/endpoints.d.ts +75 -0
  32. package/dist/src/endpoints.d.ts.map +1 -0
  33. package/dist/src/endpoints.js +47 -0
  34. package/dist/src/endpoints.js.map +1 -0
  35. package/dist/src/functions.d.ts +88 -0
  36. package/dist/src/functions.d.ts.map +1 -0
  37. package/dist/src/functions.js +56 -0
  38. package/dist/src/functions.js.map +1 -0
  39. package/dist/src/run.d.ts +8 -3
  40. package/dist/src/run.d.ts.map +1 -1
  41. package/dist/src/run.js +3 -2
  42. package/dist/src/run.js.map +1 -1
  43. package/dist/src/version.js +1 -1
  44. package/package.json +1 -1
@@ -17,6 +17,7 @@
17
17
  *
18
18
  * @module
19
19
  */
20
+ import { AliasesApi } from "./aliases.js";
20
21
  import { ApiCallsApi } from "./api-calls.js";
21
22
  import { AppsApi } from "./apps.js";
22
23
  import { AuthApi } from "./auth.js";
@@ -24,6 +25,7 @@ import { ConnectionsApi } from "./connections.js";
24
25
  import { DashboardApi } from "./dashboard.js";
25
26
  import { EndpointsApi } from "./endpoints.js";
26
27
  import { FunctionsApi } from "./functions.js";
28
+ import { PasskeysApi } from "./passkeys.js";
27
29
  import { ReliabilityApi } from "./reliability.js";
28
30
  import { ProjectsApi } from "./projects.js";
29
31
  import { SavedTestsApi } from "./saved-tests.js";
@@ -35,6 +37,7 @@ import { TokensApi } from "./tokens.js";
35
37
  import { VaultApi } from "./vault.js";
36
38
  import { WorkflowsApi } from "./workflows.js";
37
39
  export { AuthApi } from "./auth.js";
40
+ export { PasskeysApi } from "./passkeys.js";
38
41
  export { DashboardApi } from "./dashboard.js";
39
42
  export { ReliabilityApi } from "./reliability.js";
40
43
  export { ProjectsApi } from "./projects.js";
@@ -48,6 +51,7 @@ export { VaultApi } from "./vault.js";
48
51
  export { TokensApi } from "./tokens.js";
49
52
  export { FunctionsApi } from "./functions.js";
50
53
  export { EndpointsApi, SECRET_MASK } from "./endpoints.js";
54
+ export { AliasesApi } from "./aliases.js";
51
55
  export { SubscriptionsApi } from "./subscriptions.js";
52
56
  export { ApiCallsApi } from "./api-calls.js";
53
57
  export { TenantOAuthAppsApi } from "./tenant-oauth-apps.js";
@@ -89,12 +93,16 @@ export class ConsoleApi {
89
93
  functions;
90
94
  /** `console.endpoints.*`. */
91
95
  endpoints;
96
+ /** `console.aliases.*`. */
97
+ aliases;
92
98
  /** `console.subscriptions.*`. */
93
99
  subscriptions;
94
100
  /** `console.apiCalls.*`. */
95
101
  apiCalls;
96
102
  /** `console.tenantOAuthApps.*` — the caller's OWN tenant, never a tenant of its choosing. */
97
103
  tenantOAuthApps;
104
+ /** `console.passkeys.*`. */
105
+ passkeys;
98
106
  /**
99
107
  * @param host - The client this namespace group issues requests through.
100
108
  */
@@ -113,9 +121,11 @@ export class ConsoleApi {
113
121
  this.tokens = new TokensApi(host);
114
122
  this.functions = new FunctionsApi(host);
115
123
  this.endpoints = new EndpointsApi(host);
124
+ this.aliases = new AliasesApi(host);
116
125
  this.subscriptions = new SubscriptionsApi(host);
117
126
  this.apiCalls = new ApiCallsApi(host);
118
127
  this.tenantOAuthApps = new TenantOAuthAppsApi(host);
128
+ this.passkeys = new PasskeysApi(host);
119
129
  }
120
130
  }
121
131
  //# sourceMappingURL=mod.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mod.js","sourceRoot":"","sources":["../../../src/console/mod.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mod.js","sourceRoot":"","sources":["../../../src/console/mod.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,246 @@
1
+ /**
2
+ * `client.console.passkeys.*` — WebAuthn passkey management and login for
3
+ * self-serve Studio users (T1.1.5).
4
+ *
5
+ * **Studio-internal, not the published partner contract.** This namespace
6
+ * lives under the `console` subpath export (`@w6w/sdk/console`), excluded from
7
+ * `endpoints.json` and from the root barrel (`mod.ts`) — see `docs/console.md`
8
+ * and HITL-1 in this task's contract. `@w6w/sdk`'s instance-state mechanism
9
+ * pin still applies here exactly as it does to every other namespace
10
+ * (`docs/implementation.md` §MECHANISM PIN — instance state, never globals):
11
+ * this class holds no state of its own beyond the injected host, so two
12
+ * clients in one process never share a credential.
13
+ *
14
+ * **Who this is for (HITL-3).** Passkeys belong to self-serve Studio users
15
+ * only; a partner-tenant user's IdP owns its identity. No eligibility logic
16
+ * lives here — the server enforces it (`PasskeyNotEligibleError`), and this
17
+ * module is a plain transport shim over whatever it decides.
18
+ *
19
+ * **Two routes, four methods, split by who is authenticated.** The management
20
+ * quartet (`registrationOptions`, `registrationVerify`, `list`, `revoke`) is
21
+ * GUARDED, mirroring `packages/server/packages/api/data/passkeys.ts`'s own
22
+ * doc comment ("Registered BELOW the auth guard"). The login pair
23
+ * (`authenticationOptions`, `authenticationVerify`) is PUBLIC, mirroring
24
+ * `packages/server/packages/api/id/passkey-login.ts`'s own doc comment ("BOTH
25
+ * routes are PUBLIC and UNAUTHENTICATED by construction") — discoverable
26
+ * credentials, no identifier in the request body (P1). Each of those two
27
+ * methods passes `requireAuth: false`, the same mechanism
28
+ * `console.auth.login`/`signup`/`checkAccountSlug` rely on: without it a
29
+ * tokenless client (the normal case at the login screen, before any session
30
+ * exists) would hit `requireToken`'s `ConfigError` before `fetch` is ever
31
+ * called.
32
+ *
33
+ * **`authenticationVerify` mints a session, the same way `login` does
34
+ * (HITL-5).** A verified passkey assertion is a standalone alternative to a
35
+ * password, not a second factor — so its response is token-bearing, exactly
36
+ * like `console.auth.login`'s. It is a SEPARATE type from `LoginResponse`
37
+ * (`./auth.ts`), not a reuse: the server route is byte-shape-identical to
38
+ * `user-login.ts`'s login body (`id/passkey-login.ts`'s own doc comment) which
39
+ * carries `role`, `tenant` and `emailVerified` on `user` — fields
40
+ * `console.auth`'s `LoginResponse.user` does not declare.
41
+ *
42
+ * **WebAuthn ceremony payloads (`options`/`response`) are opaque JSON, typed
43
+ * as `Record<string, unknown>`, never as `@simplewebauthn/*` types.** This
44
+ * package has no dependency on `@simplewebauthn` (browser or server) and
45
+ * adding one only to type two pass-through fields would be a new dependency
46
+ * for zero behavioural gain — `inputs.touch` for this task explicitly
47
+ * excludes `package.json`. A caller passes the browser's own
48
+ * `PublicKeyCredentialCreationOptionsJSON`/`...RequestOptionsJSON` (from
49
+ * `options`) into `navigator.credentials.create()`/`.get()` (or a helper such
50
+ * as `@simplewebauthn/browser`'s `startRegistration`/`startAuthentication`)
51
+ * and forwards what comes back as `response` — this module never inspects
52
+ * either shape, only relays it.
53
+ *
54
+ * @module
55
+ */
56
+ import { type HttpResponse, type RequestOptions } from "../http.ts";
57
+ /**
58
+ * The slice of `W6WClient` this namespace needs: the transport, and nothing
59
+ * else. Structural rather than a concrete client type, so the namespace stays
60
+ * independently constructible in a test and this module never imports the
61
+ * client back — mirrors `TokensHost` in `./tokens.ts`.
62
+ */
63
+ export interface PasskeysHost {
64
+ /** Perform one request. */
65
+ request<T>(options: RequestOptions): Promise<HttpResponse<T>>;
66
+ }
67
+ /**
68
+ * A stored passkey, as the server exposes it. **Never the public key or the
69
+ * counter** — `packages/server/packages/api/data/passkeys.ts`'s own
70
+ * `WirePasskey`/`toWirePasskey()` state the identical invariant server-side.
71
+ */
72
+ export interface Passkey {
73
+ /** Server-issued id. */
74
+ id: string;
75
+ /** Caller-chosen label (empty string when none was given at registration). */
76
+ label: string;
77
+ /** ISO-8601 timestamp. */
78
+ createdAt: string;
79
+ /** ISO-8601 timestamp of the credential's last successful authentication, or `null`. */
80
+ lastUsedAt: string | null;
81
+ /** WebAuthn transport hints reported at registration (e.g. `"internal"`, `"hybrid"`). */
82
+ transports: string[];
83
+ }
84
+ /**
85
+ * A fresh WebAuthn ceremony challenge — the shared result shape of
86
+ * `POST /me/passkeys/options` (`data/passkeys.ts:118-130`) and
87
+ * `POST /auth/passkey/options` (`id/passkey-login.ts:63-71`). Flat, no
88
+ * envelope key.
89
+ */
90
+ export interface PasskeyCeremonyOptions {
91
+ /**
92
+ * WebAuthn ceremony options, opaque JSON forwarded verbatim to
93
+ * `navigator.credentials.create()`/`.get()` (or a browser WebAuthn helper).
94
+ * This package never inspects its shape — see this module's header.
95
+ */
96
+ options: Record<string, unknown>;
97
+ /** Single-use challenge token. Echo it back on the paired verify call. */
98
+ challengeToken: string;
99
+ }
100
+ /** The body `registrationVerify` sends (`POST /me/passkeys`, `data/passkeys.ts:132-164`). */
101
+ export interface RegistrationVerifyInput {
102
+ /** The token returned by the paired `registrationOptions()` call. */
103
+ challengeToken: string;
104
+ /**
105
+ * The browser's `RegistrationResponseJSON`, opaque JSON — see this
106
+ * module's header.
107
+ */
108
+ response: Record<string, unknown>;
109
+ /** Caller-chosen label for the new passkey. */
110
+ label?: string;
111
+ }
112
+ /** The body `authenticationVerify` sends (`POST /auth/passkey/verify`, `id/passkey-login.ts:73-110`). */
113
+ export interface AuthenticationVerifyInput {
114
+ /** The token returned by the paired `authenticationOptions()` call. */
115
+ challengeToken: string;
116
+ /**
117
+ * The browser's `AuthenticationResponseJSON`, opaque JSON — see this
118
+ * module's header.
119
+ */
120
+ response: Record<string, unknown>;
121
+ }
122
+ /**
123
+ * The user identity `authenticationVerify` mints a session for, as
124
+ * `id/passkey-login.ts` returns it — BYTE-SHAPE IDENTICAL to
125
+ * `console.auth`'s `LoginResponse.user`'s sibling in `user-login.ts`, but
126
+ * carrying more fields (`role`, `tenant`, `emailVerified`), which is why this
127
+ * is a separate type rather than a reuse of `./auth.ts`'s `User`.
128
+ */
129
+ export interface PasskeyUser {
130
+ /** The user's email, or its `userId` when no email is on file. */
131
+ username: string;
132
+ /** Always `"user"` for a passkey login (`id/passkey-login.ts:100`). */
133
+ role: string;
134
+ /** The tenant the session is minted in. */
135
+ tenant: string;
136
+ emailVerified: boolean;
137
+ }
138
+ /**
139
+ * `POST /auth/passkey/verify` → 200 (`id/passkey-login.ts:96-105`). Mints a
140
+ * session exactly like `console.auth.login` does (HITL-5) — a verified
141
+ * passkey assertion is a standalone alternative to a password, not a second
142
+ * factor.
143
+ */
144
+ export interface PasskeyAuthenticationVerifyResponse {
145
+ token: string;
146
+ user: PasskeyUser;
147
+ expiresIn: number;
148
+ }
149
+ /**
150
+ * The `console.passkeys` namespace on a `W6WClient`.
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * // Registration (authenticated).
155
+ * const { options, challengeToken } = await client.console.passkeys.registrationOptions();
156
+ * const response = await startRegistration({ optionsJSON: options }); // e.g. @simplewebauthn/browser
157
+ * const passkey = await client.console.passkeys.registrationVerify({ challengeToken, response });
158
+ *
159
+ * // Login (public — works on a tokenless client).
160
+ * const opts = await client.console.passkeys.authenticationOptions();
161
+ * const assertion = await startAuthentication({ optionsJSON: opts.options });
162
+ * const { token } = await client.console.passkeys.authenticationVerify({
163
+ * challengeToken: opts.challengeToken,
164
+ * response: assertion,
165
+ * });
166
+ * ```
167
+ */
168
+ export declare class PasskeysApi {
169
+ #private;
170
+ /**
171
+ * @param host - The client this namespace issues requests through.
172
+ */
173
+ constructor(host: PasskeysHost);
174
+ /**
175
+ * A fresh registration challenge, scoped to the caller's own identity.
176
+ *
177
+ * AUTHENTICATED — the default `requireAuth` applies.
178
+ *
179
+ * @returns The ceremony options and a single-use challenge token.
180
+ * @throws {ApiError} `400 passkey_not_configured`, `403 passkey_not_eligible`.
181
+ */
182
+ registrationOptions(): Promise<PasskeyCeremonyOptions>;
183
+ /**
184
+ * Verify a registration ceremony and store the credential.
185
+ *
186
+ * AUTHENTICATED — the default `requireAuth` applies.
187
+ *
188
+ * @param input - The challenge token from `registrationOptions()`, the browser's ceremony
189
+ * response, and an optional caller-chosen label.
190
+ * @returns The stored passkey's metadata, unwrapped from the `passkey` envelope.
191
+ * @throws {ApiError} `400 passkey_registration_failed`, `403 passkey_not_eligible`,
192
+ * `409 passkey_already_registered`.
193
+ */
194
+ registrationVerify(input: RegistrationVerifyInput): Promise<Passkey>;
195
+ /**
196
+ * A fresh authentication challenge. No identifier is sent or accepted —
197
+ * discoverable credentials only (P1): the owner is resolved server-side
198
+ * from the assertion itself, never from anything this call sends.
199
+ *
200
+ * PUBLIC — sends no bearer, even on a client that already holds one
201
+ * (`requireAuth: false`). Without it, the login screen (the normal case:
202
+ * no session exists yet) could never call this method at all — a tokenless
203
+ * client would hit `requireToken`'s `ConfigError` before `fetch` is ever
204
+ * called.
205
+ *
206
+ * @returns The ceremony options and a single-use challenge token.
207
+ * @throws {ApiError} `400 passkey_not_configured`.
208
+ */
209
+ authenticationOptions(): Promise<PasskeyCeremonyOptions>;
210
+ /**
211
+ * Verify an authentication (login) ceremony and mint a session — the same
212
+ * way `console.auth.login` does (HITL-5).
213
+ *
214
+ * PUBLIC — sends no bearer, even on a client that already holds one
215
+ * (`requireAuth: false`). Every failure mode past a malformed body is the
216
+ * same `401 passkey_rejected` (P9): unknown credential, revoked credential,
217
+ * wrong kind, bad signature, counter regression, and a spent/invalid
218
+ * challenge are indistinguishable to the caller.
219
+ *
220
+ * @param input - The challenge token from `authenticationOptions()` and the browser's ceremony
221
+ * response.
222
+ * @returns The token, the caller's identity, and the token's lifetime.
223
+ * @throws {ApiError} `401 passkey_rejected` on any verification failure.
224
+ */
225
+ authenticationVerify(input: AuthenticationVerifyInput): Promise<PasskeyAuthenticationVerifyResponse>;
226
+ /**
227
+ * List the caller's own passkeys.
228
+ *
229
+ * AUTHENTICATED — the default `requireAuth` applies.
230
+ *
231
+ * @returns The caller's passkeys, unwrapped from the `passkeys` envelope. Never the empty array
232
+ * collapsed to `undefined` — an empty account gets `[]`.
233
+ */
234
+ list(): Promise<Passkey[]>;
235
+ /**
236
+ * Revoke (delete) one of the caller's own passkeys.
237
+ *
238
+ * AUTHENTICATED — the default `requireAuth` applies.
239
+ *
240
+ * @param id - The passkey id.
241
+ * @returns Nothing: the server answers `204` with no body.
242
+ * @throws {ApiError} `404 passkey_not_found`.
243
+ */
244
+ revoke(id: string): Promise<void>;
245
+ }
246
+ //# sourceMappingURL=passkeys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passkeys.d.ts","sourceRoot":"","sources":["../../../src/console/passkeys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAQ,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAG1E;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,2BAA2B;IAC3B,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/D;AAED;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,wBAAwB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,8EAA8E;IAC9E,KAAK,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,yFAAyF;IACzF,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,0EAA0E;IAC1E,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,6FAA6F;AAC7F,MAAM,WAAW,uBAAuB;IACtC,qEAAqE;IACrE,cAAc,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,yGAAyG;AACzG,MAAM,WAAW,yBAAyB;IACxC,uEAAuE;IACvE,cAAc,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,mCAAmC;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,WAAW,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,WAAW;;IAGtB;;OAEG;gBACS,IAAI,EAAE,YAAY;IAI9B;;;;;;;OAOG;IACG,mBAAmB,IAAI,OAAO,CAAC,sBAAsB,CAAC;IAS5D;;;;;;;;;;OAUG;IACG,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC;IAS1E;;;;;;;;;;;;;OAaG;IACG,qBAAqB,IAAI,OAAO,CAAC,sBAAsB,CAAC;IAU9D;;;;;;;;;;;;;;OAcG;IACG,oBAAoB,CACxB,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,mCAAmC,CAAC;IAU/C;;;;;;;OAOG;IACG,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAKhC;;;;;;;;OAQG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGxC"}
@@ -0,0 +1,192 @@
1
+ /**
2
+ * `client.console.passkeys.*` — WebAuthn passkey management and login for
3
+ * self-serve Studio users (T1.1.5).
4
+ *
5
+ * **Studio-internal, not the published partner contract.** This namespace
6
+ * lives under the `console` subpath export (`@w6w/sdk/console`), excluded from
7
+ * `endpoints.json` and from the root barrel (`mod.ts`) — see `docs/console.md`
8
+ * and HITL-1 in this task's contract. `@w6w/sdk`'s instance-state mechanism
9
+ * pin still applies here exactly as it does to every other namespace
10
+ * (`docs/implementation.md` §MECHANISM PIN — instance state, never globals):
11
+ * this class holds no state of its own beyond the injected host, so two
12
+ * clients in one process never share a credential.
13
+ *
14
+ * **Who this is for (HITL-3).** Passkeys belong to self-serve Studio users
15
+ * only; a partner-tenant user's IdP owns its identity. No eligibility logic
16
+ * lives here — the server enforces it (`PasskeyNotEligibleError`), and this
17
+ * module is a plain transport shim over whatever it decides.
18
+ *
19
+ * **Two routes, four methods, split by who is authenticated.** The management
20
+ * quartet (`registrationOptions`, `registrationVerify`, `list`, `revoke`) is
21
+ * GUARDED, mirroring `packages/server/packages/api/data/passkeys.ts`'s own
22
+ * doc comment ("Registered BELOW the auth guard"). The login pair
23
+ * (`authenticationOptions`, `authenticationVerify`) is PUBLIC, mirroring
24
+ * `packages/server/packages/api/id/passkey-login.ts`'s own doc comment ("BOTH
25
+ * routes are PUBLIC and UNAUTHENTICATED by construction") — discoverable
26
+ * credentials, no identifier in the request body (P1). Each of those two
27
+ * methods passes `requireAuth: false`, the same mechanism
28
+ * `console.auth.login`/`signup`/`checkAccountSlug` rely on: without it a
29
+ * tokenless client (the normal case at the login screen, before any session
30
+ * exists) would hit `requireToken`'s `ConfigError` before `fetch` is ever
31
+ * called.
32
+ *
33
+ * **`authenticationVerify` mints a session, the same way `login` does
34
+ * (HITL-5).** A verified passkey assertion is a standalone alternative to a
35
+ * password, not a second factor — so its response is token-bearing, exactly
36
+ * like `console.auth.login`'s. It is a SEPARATE type from `LoginResponse`
37
+ * (`./auth.ts`), not a reuse: the server route is byte-shape-identical to
38
+ * `user-login.ts`'s login body (`id/passkey-login.ts`'s own doc comment) which
39
+ * carries `role`, `tenant` and `emailVerified` on `user` — fields
40
+ * `console.auth`'s `LoginResponse.user` does not declare.
41
+ *
42
+ * **WebAuthn ceremony payloads (`options`/`response`) are opaque JSON, typed
43
+ * as `Record<string, unknown>`, never as `@simplewebauthn/*` types.** This
44
+ * package has no dependency on `@simplewebauthn` (browser or server) and
45
+ * adding one only to type two pass-through fields would be a new dependency
46
+ * for zero behavioural gain — `inputs.touch` for this task explicitly
47
+ * excludes `package.json`. A caller passes the browser's own
48
+ * `PublicKeyCredentialCreationOptionsJSON`/`...RequestOptionsJSON` (from
49
+ * `options`) into `navigator.credentials.create()`/`.get()` (or a helper such
50
+ * as `@simplewebauthn/browser`'s `startRegistration`/`startAuthentication`)
51
+ * and forwards what comes back as `response` — this module never inspects
52
+ * either shape, only relays it.
53
+ *
54
+ * @module
55
+ */
56
+ import { path } from "../http.js";
57
+ import { unwrap } from "../types.js";
58
+ /**
59
+ * The `console.passkeys` namespace on a `W6WClient`.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * // Registration (authenticated).
64
+ * const { options, challengeToken } = await client.console.passkeys.registrationOptions();
65
+ * const response = await startRegistration({ optionsJSON: options }); // e.g. @simplewebauthn/browser
66
+ * const passkey = await client.console.passkeys.registrationVerify({ challengeToken, response });
67
+ *
68
+ * // Login (public — works on a tokenless client).
69
+ * const opts = await client.console.passkeys.authenticationOptions();
70
+ * const assertion = await startAuthentication({ optionsJSON: opts.options });
71
+ * const { token } = await client.console.passkeys.authenticationVerify({
72
+ * challengeToken: opts.challengeToken,
73
+ * response: assertion,
74
+ * });
75
+ * ```
76
+ */
77
+ export class PasskeysApi {
78
+ #host;
79
+ /**
80
+ * @param host - The client this namespace issues requests through.
81
+ */
82
+ constructor(host) {
83
+ this.#host = host;
84
+ }
85
+ /**
86
+ * A fresh registration challenge, scoped to the caller's own identity.
87
+ *
88
+ * AUTHENTICATED — the default `requireAuth` applies.
89
+ *
90
+ * @returns The ceremony options and a single-use challenge token.
91
+ * @throws {ApiError} `400 passkey_not_configured`, `403 passkey_not_eligible`.
92
+ */
93
+ async registrationOptions() {
94
+ const res = await this.#host.request({
95
+ method: "POST",
96
+ path: "/me/passkeys/options",
97
+ body: {},
98
+ });
99
+ return res.body;
100
+ }
101
+ /**
102
+ * Verify a registration ceremony and store the credential.
103
+ *
104
+ * AUTHENTICATED — the default `requireAuth` applies.
105
+ *
106
+ * @param input - The challenge token from `registrationOptions()`, the browser's ceremony
107
+ * response, and an optional caller-chosen label.
108
+ * @returns The stored passkey's metadata, unwrapped from the `passkey` envelope.
109
+ * @throws {ApiError} `400 passkey_registration_failed`, `403 passkey_not_eligible`,
110
+ * `409 passkey_already_registered`.
111
+ */
112
+ async registrationVerify(input) {
113
+ const res = await this.#host.request({
114
+ method: "POST",
115
+ path: "/me/passkeys",
116
+ body: input,
117
+ });
118
+ return unwrap(res, "passkey");
119
+ }
120
+ /**
121
+ * A fresh authentication challenge. No identifier is sent or accepted —
122
+ * discoverable credentials only (P1): the owner is resolved server-side
123
+ * from the assertion itself, never from anything this call sends.
124
+ *
125
+ * PUBLIC — sends no bearer, even on a client that already holds one
126
+ * (`requireAuth: false`). Without it, the login screen (the normal case:
127
+ * no session exists yet) could never call this method at all — a tokenless
128
+ * client would hit `requireToken`'s `ConfigError` before `fetch` is ever
129
+ * called.
130
+ *
131
+ * @returns The ceremony options and a single-use challenge token.
132
+ * @throws {ApiError} `400 passkey_not_configured`.
133
+ */
134
+ async authenticationOptions() {
135
+ const res = await this.#host.request({
136
+ method: "POST",
137
+ path: "/auth/passkey/options",
138
+ body: {},
139
+ requireAuth: false,
140
+ });
141
+ return res.body;
142
+ }
143
+ /**
144
+ * Verify an authentication (login) ceremony and mint a session — the same
145
+ * way `console.auth.login` does (HITL-5).
146
+ *
147
+ * PUBLIC — sends no bearer, even on a client that already holds one
148
+ * (`requireAuth: false`). Every failure mode past a malformed body is the
149
+ * same `401 passkey_rejected` (P9): unknown credential, revoked credential,
150
+ * wrong kind, bad signature, counter regression, and a spent/invalid
151
+ * challenge are indistinguishable to the caller.
152
+ *
153
+ * @param input - The challenge token from `authenticationOptions()` and the browser's ceremony
154
+ * response.
155
+ * @returns The token, the caller's identity, and the token's lifetime.
156
+ * @throws {ApiError} `401 passkey_rejected` on any verification failure.
157
+ */
158
+ async authenticationVerify(input) {
159
+ const res = await this.#host.request({
160
+ method: "POST",
161
+ path: "/auth/passkey/verify",
162
+ body: input,
163
+ requireAuth: false,
164
+ });
165
+ return res.body;
166
+ }
167
+ /**
168
+ * List the caller's own passkeys.
169
+ *
170
+ * AUTHENTICATED — the default `requireAuth` applies.
171
+ *
172
+ * @returns The caller's passkeys, unwrapped from the `passkeys` envelope. Never the empty array
173
+ * collapsed to `undefined` — an empty account gets `[]`.
174
+ */
175
+ async list() {
176
+ const res = await this.#host.request({ method: "GET", path: "/me/passkeys" });
177
+ return unwrap(res, "passkeys");
178
+ }
179
+ /**
180
+ * Revoke (delete) one of the caller's own passkeys.
181
+ *
182
+ * AUTHENTICATED — the default `requireAuth` applies.
183
+ *
184
+ * @param id - The passkey id.
185
+ * @returns Nothing: the server answers `204` with no body.
186
+ * @throws {ApiError} `404 passkey_not_found`.
187
+ */
188
+ async revoke(id) {
189
+ await this.#host.request({ method: "DELETE", path: path `/me/passkeys/${id}` });
190
+ }
191
+ }
192
+ //# sourceMappingURL=passkeys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passkeys.js","sourceRoot":"","sources":["../../../src/console/passkeys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,EAAqB,IAAI,EAAuB,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAqGrC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,WAAW;IACb,KAAK,CAAe;IAE7B;;OAEG;IACH,YAAY,IAAkB;QAC5B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,mBAAmB;QACvB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAyB;YAC3D,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,sBAAsB;YAC5B,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,kBAAkB,CAAC,KAA8B;QACrD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU;YAC5C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,cAAc;YACpB,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;QACH,OAAO,MAAM,CAAU,GAAG,EAAE,SAAS,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,qBAAqB;QACzB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAyB;YAC3D,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,uBAAuB;YAC7B,IAAI,EAAE,EAAE;YACR,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,oBAAoB,CACxB,KAAgC;QAEhC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAsC;YACxE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,sBAAsB;YAC5B,IAAI,EAAE,KAAK;YACX,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;QACH,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QACvF,OAAO,MAAM,CAAY,GAAG,EAAE,UAAU,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAA,gBAAgB,EAAE,EAAE,EAAE,CAAC,CAAC;IAC1F,CAAC;CACF"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * `client.endpoints.*` — run an Endpoint by the key you gave it.
3
+ *
4
+ * An Endpoint is a callable entry point that dispatches to whatever it targets:
5
+ * an app action, a Function, or a Workflow. Before this namespace existed,
6
+ * calling one meant `client.run({ urn: "ep_…" })` — an opaque id, buried inside
7
+ * an object, for an Endpoint the user named `send-email`. Now:
8
+ *
9
+ * ```ts
10
+ * await client.endpoints.run("send-email", { payload: { to, subject } });
11
+ * ```
12
+ *
13
+ * The name is the FIRST argument, matching `workflows.run` and `functions.run`,
14
+ * so all three runnable kinds read alike.
15
+ *
16
+ * ID OR KEY, one argument: `/endpoints/{idOrKey}/invoke` accepts either, because
17
+ * an id carries a kind prefix (and so an underscore) while a key is kebab-case
18
+ * (which forbids one). No flag, no prefix — pass whichever you have.
19
+ *
20
+ * UNLIKE `functions.run`, THIS RETURNS AN ENVELOPE, and that asymmetry is the
21
+ * honest one: a Function's kind is settled by the method name, but an Endpoint
22
+ * dispatches to one of three things and the caller genuinely does not know which
23
+ * answered. The `kind` discriminant is information here, not ceremony — and the
24
+ * Workflow arm is asynchronous (`202`, a `runId`) where the other two are not.
25
+ */
26
+ import type { ResolvedConfig } from "./config.ts";
27
+ import { type HttpResponse, type RequestOptions } from "./http.ts";
28
+ import type { RunEnvelope } from "./types.ts";
29
+ /**
30
+ * What this namespace needs from the client — the same narrow seam
31
+ * `WorkflowsApi` and `FunctionsApi` take.
32
+ */
33
+ export interface EndpointsHost {
34
+ /** The resolved configuration. */
35
+ readonly config: ResolvedConfig;
36
+ /** Perform one request. */
37
+ request<T>(options: RequestOptions): Promise<HttpResponse<T>>;
38
+ }
39
+ /** Per-call options for `endpoints.run`. */
40
+ export interface EndpointRunOptions {
41
+ /**
42
+ * The Endpoint's input, by input key.
43
+ *
44
+ * Named `payload` for the same reason as `functions.run`: one word across
45
+ * every runnable kind, even though the wire spells this one `input`.
46
+ */
47
+ payload?: Record<string, unknown>;
48
+ }
49
+ /**
50
+ * The `endpoints` namespace on a `W6WClient`.
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * const envelope = await client.endpoints.run("send-email", { payload: { to } });
55
+ * if (envelope.kind === "workflow") console.log(envelope.runId); // async arm
56
+ * ```
57
+ */
58
+ export declare class EndpointsApi {
59
+ #private;
60
+ /**
61
+ * @param host - The client this namespace issues requests through.
62
+ */
63
+ constructor(host: EndpointsHost);
64
+ /**
65
+ * Run one Endpoint; the envelope's `kind` says which arm answered.
66
+ *
67
+ * @param name - The Endpoint's key (`"send-email"`) or its `ep_…` id. Percent-encoded into the path.
68
+ * @param options - `payload`, the Endpoint's input.
69
+ * @returns The `kind`-discriminated envelope, returned exactly as it arrived.
70
+ * @throws {ApiError} `404 unknown_endpoint` when no Endpoint of that name exists for the caller.
71
+ * @throws {ApiError} `bad_response` when a success body carries no string `kind`.
72
+ */
73
+ run(name: string, options?: EndpointRunOptions): Promise<RunEnvelope>;
74
+ }
75
+ //# sourceMappingURL=endpoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../src/endpoints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,KAAK,YAAY,EAAQ,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,2BAA2B;IAC3B,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;CAC/D;AAED,4CAA4C;AAC5C,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;;;;;GAQG;AACH,qBAAa,YAAY;;IAGvB;;OAEG;gBACS,IAAI,EAAE,aAAa;IAI/B;;;;;;;;OAQG;IACG,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC;CAyB5E"}
@@ -0,0 +1,47 @@
1
+ import { ApiError } from "./errors.js";
2
+ import { path } from "./http.js";
3
+ /**
4
+ * The `endpoints` namespace on a `W6WClient`.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * const envelope = await client.endpoints.run("send-email", { payload: { to } });
9
+ * if (envelope.kind === "workflow") console.log(envelope.runId); // async arm
10
+ * ```
11
+ */
12
+ export class EndpointsApi {
13
+ #host;
14
+ /**
15
+ * @param host - The client this namespace issues requests through.
16
+ */
17
+ constructor(host) {
18
+ this.#host = host;
19
+ }
20
+ /**
21
+ * Run one Endpoint; the envelope's `kind` says which arm answered.
22
+ *
23
+ * @param name - The Endpoint's key (`"send-email"`) or its `ep_…` id. Percent-encoded into the path.
24
+ * @param options - `payload`, the Endpoint's input.
25
+ * @returns The `kind`-discriminated envelope, returned exactly as it arrived.
26
+ * @throws {ApiError} `404 unknown_endpoint` when no Endpoint of that name exists for the caller.
27
+ * @throws {ApiError} `bad_response` when a success body carries no string `kind`.
28
+ */
29
+ async run(name, options) {
30
+ const res = await this.#host.request({
31
+ method: "POST",
32
+ path: path `/endpoints/${name}/invoke`,
33
+ body: { input: options?.payload ?? {} },
34
+ });
35
+ const body = res.body;
36
+ // The same guard `run.ts` applies, for the same reason: an object-only
37
+ // check lets `{}` and `[]` through and hands back an envelope whose `kind`
38
+ // is `undefined` at runtime — a lie the compiler cannot catch.
39
+ if (typeof body !== "object" || body === null ||
40
+ typeof body.kind !== "string") {
41
+ throw new ApiError(res.status, "bad_response", `Server returned a ${res.status} with no "kind" in the response body.`, body);
42
+ }
43
+ // Returned as it arrived — an unknown `kind` reaches the caller intact.
44
+ return body;
45
+ }
46
+ }
47
+ //# sourceMappingURL=endpoints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../../src/endpoints.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAqB,IAAI,EAAuB,MAAM,WAAW,CAAC;AAyBzE;;;;;;;;GAQG;AACH,MAAM,OAAO,YAAY;IACd,KAAK,CAAgB;IAE9B;;OAEG;IACH,YAAY,IAAmB;QAC7B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACpB,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,GAAG,CAAC,IAAY,EAAE,OAA4B;QAClD,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAU;YAC5C,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAA,cAAc,IAAI,SAAS;YACrC,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE,EAAE;SACxC,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;QACtB,uEAAuE;QACvE,2EAA2E;QAC3E,+DAA+D;QAC/D,IACE,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;YACzC,OAAQ,IAA2B,CAAC,IAAI,KAAK,QAAQ,EACrD,CAAC;YACD,MAAM,IAAI,QAAQ,CAChB,GAAG,CAAC,MAAM,EACV,cAAc,EACd,qBAAqB,GAAG,CAAC,MAAM,uCAAuC,EACtE,IAAI,CACL,CAAC;QACJ,CAAC;QACD,wEAAwE;QACxE,OAAO,IAAmB,CAAC;IAC7B,CAAC;CACF"}