@passlock/server 2.1.0 → 2.2.1

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 (45) hide show
  1. package/dist/effect.d.ts +8 -0
  2. package/dist/effect.d.ts.map +1 -1
  3. package/dist/effect.js +8 -0
  4. package/dist/effect.js.map +1 -1
  5. package/dist/errors.d.ts +65 -0
  6. package/dist/errors.d.ts.map +1 -1
  7. package/dist/errors.js +36 -5
  8. package/dist/errors.js.map +1 -1
  9. package/dist/index.d.ts +54 -18
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +52 -16
  12. package/dist/index.js.map +1 -1
  13. package/dist/network.d.ts +3 -3
  14. package/dist/passkey/passkey.d.ts +242 -10
  15. package/dist/passkey/passkey.d.ts.map +1 -1
  16. package/dist/passkey/passkey.js +140 -4
  17. package/dist/passkey/passkey.js.map +1 -1
  18. package/dist/principal/principal.d.ts +45 -1
  19. package/dist/principal/principal.d.ts.map +1 -1
  20. package/dist/principal/principal.js +27 -0
  21. package/dist/principal/principal.js.map +1 -1
  22. package/dist/safe-result.d.ts +33 -0
  23. package/dist/safe-result.d.ts.map +1 -0
  24. package/dist/safe-result.js +35 -0
  25. package/dist/safe-result.js.map +1 -0
  26. package/dist/safe.d.ts +79 -28
  27. package/dist/safe.d.ts.map +1 -1
  28. package/dist/safe.js +82 -28
  29. package/dist/safe.js.map +1 -1
  30. package/dist/schemas/passkey.d.ts +148 -0
  31. package/dist/schemas/passkey.d.ts.map +1 -1
  32. package/dist/schemas/passkey.js +82 -12
  33. package/dist/schemas/passkey.js.map +1 -1
  34. package/dist/schemas/principal.d.ts +50 -0
  35. package/dist/schemas/principal.d.ts.map +1 -1
  36. package/dist/schemas/principal.js +30 -0
  37. package/dist/schemas/principal.js.map +1 -1
  38. package/dist/schemas/signup.d.ts +20 -0
  39. package/dist/schemas/signup.d.ts.map +1 -1
  40. package/dist/schemas/signup.js +10 -0
  41. package/dist/schemas/signup.js.map +1 -1
  42. package/dist/shared.d.ts +18 -0
  43. package/dist/shared.d.ts.map +1 -1
  44. package/dist/shared.js.map +1 -1
  45. package/package.json +6 -6
@@ -1,12 +1,17 @@
1
- import { Effect, type Layer, Stream } from "effect";
1
+ import { Effect, Stream, type Layer } from "effect";
2
2
  import { type NetworkFetch } from "../network.js";
3
3
  import { ForbiddenError, NotFoundError } from "../schemas/index.js";
4
4
  import * as PasskeySchemas from "../schemas/passkey.js";
5
5
  import type { AuthenticatedOptions } from "../shared.js";
6
6
  /**
7
- * WebAuthn specific passkey data
7
+ * WebAuthn-specific credential data stored for a passkey in the Passlock vault.
8
+ *
9
+ * The `id` and `userId` fields are the underlying WebAuthn values, encoded as
10
+ * Base64URL strings.
11
+ *
12
+ * @category Passkeys
8
13
  */
9
- export type Credential = {
14
+ export type PasskeyCredential = {
10
15
  id: string;
11
16
  userId: string;
12
17
  username: string;
@@ -31,13 +36,15 @@ export type Credential = {
31
36
  *
32
37
  * We've also included links to icons (SVG) so you can give your users
33
38
  * a quick visual indication.
39
+ *
40
+ * @category Passkeys
34
41
  */
35
42
  export type Platform = {
36
43
  name?: string | undefined;
37
44
  icon?: string | undefined;
38
45
  };
39
46
  /**
40
- * The server-side component of a passkey
47
+ * The server-side representation of a passkey stored in the Passlock vault.
41
48
  *
42
49
  * @category Passkeys
43
50
  */
@@ -52,13 +59,23 @@ export type Passkey = {
52
59
  */
53
60
  userId?: string | undefined;
54
61
  enabled: boolean;
55
- credential: Credential;
62
+ credential: PasskeyCredential;
56
63
  platform?: Platform | undefined;
57
64
  lastUsed?: number | undefined;
58
65
  createdAt: number;
59
66
  updatedAt: number;
60
67
  };
68
+ /**
69
+ * Type guard for {@link Passkey}.
70
+ *
71
+ * @category Passkeys
72
+ */
61
73
  export declare const isPasskey: (payload: unknown) => payload is Passkey;
74
+ /**
75
+ * Compact passkey payload returned by list operations.
76
+ *
77
+ * @category Passkeys
78
+ */
62
79
  export type PasskeySummary = {
63
80
  readonly _tag: "PasskeySummary";
64
81
  readonly id: string;
@@ -71,20 +88,73 @@ export type PasskeySummary = {
71
88
  readonly lastUsed?: number | undefined;
72
89
  readonly createdAt: number;
73
90
  };
91
+ /**
92
+ * Type guard for {@link PasskeySummary}.
93
+ *
94
+ * @category Passkeys
95
+ */
74
96
  export declare const isPasskeySummary: (payload: unknown) => payload is PasskeySummary;
97
+ /**
98
+ * Result payload returned when passkeys are updated in bulk for a user.
99
+ *
100
+ * @category Passkeys
101
+ */
75
102
  export type UpdatedPasskeys = {
76
103
  _tag: "UpdatedPasskeys";
77
104
  updated: ReadonlyArray<Passkey>;
78
105
  };
106
+ /**
107
+ * Type guard for {@link UpdatedPasskeys}.
108
+ *
109
+ * @category Passkeys
110
+ */
79
111
  export declare const isUpdatedPasskeys: (payload: unknown) => payload is UpdatedPasskeys;
112
+ /**
113
+ * Credential identifiers returned by passkey deletion operations.
114
+ *
115
+ * @category Passkeys
116
+ */
117
+ export type Credential = {
118
+ credentialId: string;
119
+ userId: string;
120
+ rpId: string;
121
+ };
122
+ /**
123
+ * Result payload returned when all passkeys for a user have been deleted.
124
+ *
125
+ * @category Passkeys
126
+ */
127
+ export type DeletedPasskeys = {
128
+ _tag: "DeletedPasskeys";
129
+ deleted: ReadonlyArray<Credential>;
130
+ };
131
+ /**
132
+ * Type guard for {@link DeletedPasskeys}.
133
+ *
134
+ * @category Passkeys
135
+ */
136
+ export declare const isDeletedPasskeys: (payload: unknown) => payload is DeletedPasskeys;
137
+ /**
138
+ * A single page of passkey summaries returned by {@link listPasskeys}.
139
+ *
140
+ * @category Passkeys
141
+ */
80
142
  export type FindAllPasskeys = {
81
143
  readonly _tag: "FindAllPasskeys";
82
144
  readonly cursor: string | null;
83
145
  readonly records: ReadonlyArray<PasskeySummary>;
84
146
  };
85
147
  export declare const isFindAllPasskeys: (payload: unknown) => payload is FindAllPasskeys;
86
- export type UpdatedPasskeyUsernames = {
87
- _tag: "UpdatedPasskeyUsernames";
148
+ /**
149
+ * Client-facing credential update payload returned by
150
+ * {@link updatePasskeyUsernames}.
151
+ *
152
+ * Each entry describes one credential to update on the user's device.
153
+ *
154
+ * @category Passkeys
155
+ */
156
+ export type UpdatedCredentials = {
157
+ _tag: "UpdatedCredentials";
88
158
  credentials: ReadonlyArray<{
89
159
  rpId: string;
90
160
  userId: string;
@@ -92,41 +162,203 @@ export type UpdatedPasskeyUsernames = {
92
162
  displayName: string;
93
163
  }>;
94
164
  };
95
- export declare const isUpdatedPasskeyUsernames: (payload: unknown) => payload is UpdatedPasskeyUsernames;
165
+ /**
166
+ * Narrow an unknown value to an `UpdatedCredentials`-tagged payload.
167
+ *
168
+ * @category Passkeys
169
+ */
170
+ export declare const isUpdatedUserDetails: (payload: unknown) => payload is UpdatedCredentials;
171
+ /**
172
+ * Options for fetching a single passkey.
173
+ *
174
+ * @category Passkeys
175
+ */
96
176
  export interface GetPasskeyOptions extends AuthenticatedOptions {
177
+ /**
178
+ * Identifier of the passkey to fetch.
179
+ */
97
180
  passkeyId: string;
98
181
  }
182
+ /**
183
+ * Fetch a single passkey from the Passlock vault.
184
+ *
185
+ * @param options Request options including the passkey identifier.
186
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
187
+ * @returns An Effect that succeeds with the requested passkey.
188
+ *
189
+ * @category Passkeys
190
+ */
99
191
  export declare const getPasskey: (options: GetPasskeyOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<Passkey, NotFoundError | ForbiddenError>;
192
+ /**
193
+ * Options for deleting a single passkey.
194
+ *
195
+ * @category Passkeys
196
+ */
100
197
  export interface DeletePasskeyOptions extends AuthenticatedOptions {
198
+ /**
199
+ * Identifier of the passkey to delete.
200
+ */
101
201
  passkeyId: string;
102
202
  }
203
+ /**
204
+ * Delete a single passkey from the Passlock vault.
205
+ *
206
+ * This only removes the server-side record. It does not remove the passkey
207
+ * from the user's device.
208
+ *
209
+ * @param options Request options including the passkey identifier.
210
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
211
+ * @returns An Effect that succeeds with the deleted passkey.
212
+ *
213
+ * @category Passkeys
214
+ */
103
215
  export declare const deletePasskey: (options: DeletePasskeyOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<Passkey, NotFoundError | ForbiddenError>;
104
216
  /**
217
+ * Options for assigning a custom user ID to a single passkey.
218
+ *
105
219
  * @category Passkeys
106
220
  */
107
221
  export interface AssignUserOptions extends AuthenticatedOptions {
222
+ /**
223
+ * Identifier of the passkey to update.
224
+ */
108
225
  passkeyId: string;
109
226
  /**
110
227
  * Custom User ID to align with your own systems
111
228
  */
112
229
  userId: string;
113
230
  }
231
+ /**
232
+ * Assign a custom user ID to a single passkey.
233
+ *
234
+ * This updates Passlock's mapping for the passkey. It does not change the
235
+ * underlying WebAuthn credential's `userId`.
236
+ *
237
+ * @param options Request options including the passkey identifier and custom user ID.
238
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
239
+ * @returns An Effect that succeeds with the updated passkey.
240
+ *
241
+ * @category Passkeys
242
+ */
114
243
  export declare const assignUser: (options: AssignUserOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<Passkey, NotFoundError | ForbiddenError>;
244
+ /**
245
+ * Options for updating a single passkey's metadata.
246
+ *
247
+ * @category Passkeys
248
+ */
115
249
  export interface UpdatePasskeyOptions extends AuthenticatedOptions {
250
+ /**
251
+ * Identifier of the passkey to update.
252
+ */
116
253
  passkeyId: string;
254
+ /**
255
+ * Custom user ID to associate with the passkey.
256
+ */
117
257
  userId?: string;
258
+ /**
259
+ * Username metadata stored alongside the passkey.
260
+ */
118
261
  username?: string;
119
262
  }
263
+ /**
264
+ * Update a single passkey's custom user ID and/or username metadata.
265
+ *
266
+ * @param options Request options including the passkey identifier and fields to update.
267
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
268
+ * @returns An Effect that succeeds with the updated passkey.
269
+ *
270
+ * @category Passkeys
271
+ */
120
272
  export declare const updatePasskey: (options: UpdatePasskeyOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<Passkey, NotFoundError | ForbiddenError>;
121
- export interface UpdatePasskeyUsernamesOptions extends AuthenticatedOptions {
273
+ /**
274
+ * Options for deleting all passkeys belonging to a user.
275
+ *
276
+ * @category Passkeys
277
+ */
278
+ export interface DeleteUserPasskeysOptions extends AuthenticatedOptions {
279
+ /**
280
+ * Custom user ID whose passkeys should be deleted.
281
+ */
282
+ userId: string;
283
+ }
284
+ /**
285
+ * Delete all passkeys associated with a custom user ID.
286
+ *
287
+ * The resulting `deleted` credentials can be passed to
288
+ * `@passlock/client` to remove the corresponding passkeys from the user's
289
+ * device.
290
+ *
291
+ * @param options Request options including the custom user ID.
292
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
293
+ * @returns An Effect that succeeds with the deleted credential identifiers.
294
+ *
295
+ * @category Passkeys
296
+ */
297
+ export declare const deleteUserPasskeys: (options: DeleteUserPasskeysOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<DeletedPasskeys, NotFoundError | ForbiddenError>;
298
+ /**
299
+ * Options for updating the username and display name for all passkeys that
300
+ * share a custom user ID.
301
+ *
302
+ * @category Passkeys
303
+ */
304
+ export interface UpdateUsernamesOptions extends AuthenticatedOptions {
305
+ /**
306
+ * Custom user ID whose passkeys should be updated.
307
+ */
122
308
  userId: string;
309
+ /**
310
+ * Username to write back to each stored passkey.
311
+ */
123
312
  username: string;
313
+ /**
314
+ * Optional display name to return for client-side credential updates.
315
+ *
316
+ * When omitted, the returned credentials use `username` as the display name.
317
+ */
124
318
  displayName?: string;
125
319
  }
126
- export declare const updatePasskeyUsernames: (options: UpdatePasskeyUsernamesOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<UpdatedPasskeyUsernames, NotFoundError | ForbiddenError>;
320
+ /**
321
+ * Update the username metadata for all passkeys belonging to a custom user ID.
322
+ *
323
+ * The resulting payload is designed to be passed to
324
+ * `@passlock/client` so matching device credentials can be updated.
325
+ *
326
+ * @param options Request options including the custom user ID and username metadata.
327
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
328
+ * @returns An Effect that succeeds with one credential update per updated passkey.
329
+ *
330
+ * @category Passkeys
331
+ */
332
+ export declare const updatePasskeyUsernames: (options: UpdateUsernamesOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<UpdatedCredentials, NotFoundError | ForbiddenError>;
333
+ /**
334
+ * Stream every passkey summary for a tenancy across all result pages.
335
+ *
336
+ * @param options Request options used for each paginated request.
337
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
338
+ * @returns A stream of passkey summaries.
339
+ *
340
+ * @category Passkeys
341
+ */
127
342
  export declare const listPasskeysStream: (options: AuthenticatedOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Stream.Stream<PasskeySummary, ForbiddenError>;
343
+ /**
344
+ * Options for listing passkeys.
345
+ *
346
+ * @category Passkeys
347
+ */
128
348
  export interface ListPasskeyOptions extends AuthenticatedOptions {
349
+ /**
350
+ * Pagination cursor returned from a previous {@link listPasskeys} call.
351
+ */
129
352
  cursor?: string;
130
353
  }
354
+ /**
355
+ * Fetch a single page of passkey summaries for a tenancy.
356
+ *
357
+ * @param options Request options including an optional pagination cursor.
358
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
359
+ * @returns An Effect that succeeds with one page of passkey summaries.
360
+ *
361
+ * @category Passkeys
362
+ */
131
363
  export declare const listPasskeys: (options: ListPasskeyOptions, fetchLayer?: Layer.Layer<NetworkFetch>) => Effect.Effect<FindAllPasskeys, ForbiddenError>;
132
364
  //# sourceMappingURL=passkey.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"passkey.d.ts","sourceRoot":"","sources":["../../src/passkey/passkey.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"passkey.d.ts","sourceRoot":"","sources":["../../src/passkey/passkey.ts"],"names":[],"mappings":"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"}
@@ -2,11 +2,37 @@ import { Array, Chunk, Effect, Match, Option, pipe, Schema, Stream, } from "effe
2
2
  import { fetchNetwork, matchStatus, NetworkFetchLive, } from "../network.js";
3
3
  import { FindAllPasskeys as FindAllPasskeysSchema, ForbiddenError, NotFoundError, } from "../schemas/index.js";
4
4
  import * as PasskeySchemas from "../schemas/passkey.js";
5
+ /**
6
+ * Type guard for {@link Passkey}.
7
+ *
8
+ * @category Passkeys
9
+ */
5
10
  export const isPasskey = (payload) => Schema.is(PasskeySchemas.Passkey)(payload);
11
+ /**
12
+ * Type guard for {@link PasskeySummary}.
13
+ *
14
+ * @category Passkeys
15
+ */
6
16
  export const isPasskeySummary = (payload) => Schema.is(PasskeySchemas.PasskeySummary)(payload);
17
+ /**
18
+ * Type guard for {@link UpdatedPasskeys}.
19
+ *
20
+ * @category Passkeys
21
+ */
7
22
  export const isUpdatedPasskeys = (payload) => Schema.is(PasskeySchemas.UpdatedPasskeys)(payload);
23
+ /**
24
+ * Type guard for {@link DeletedPasskeys}.
25
+ *
26
+ * @category Passkeys
27
+ */
28
+ export const isDeletedPasskeys = (payload) => Schema.is(PasskeySchemas.DeletedPasskeys)(payload);
8
29
  export const isFindAllPasskeys = (payload) => Schema.is(PasskeySchemas.FindAllPasskeys)(payload);
9
- export const isUpdatedPasskeyUsernames = (payload) => {
30
+ /**
31
+ * Narrow an unknown value to an `UpdatedCredentials`-tagged payload.
32
+ *
33
+ * @category Passkeys
34
+ */
35
+ export const isUpdatedUserDetails = (payload) => {
10
36
  if (typeof payload !== "object")
11
37
  return false;
12
38
  if (payload === null)
@@ -15,15 +41,24 @@ export const isUpdatedPasskeyUsernames = (payload) => {
15
41
  return false;
16
42
  if (typeof payload._tag !== "string")
17
43
  return false;
18
- if (payload._tag !== "UpdatedPasskeyUsernames")
44
+ if (payload._tag !== "UpdatedCredentials")
19
45
  return false;
20
46
  return true;
21
47
  };
22
- /* END UpdatedPasskeyUsernames */
48
+ /* END UpdatedUserDetails */
23
49
  const authorizationHeaders = (apiKey) => ({
24
50
  authorization: `Bearer ${apiKey}`,
25
51
  });
26
52
  const decodeResponseJson = (response, schema) => pipe(response.json, Effect.flatMap(Schema.decodeUnknown(schema)));
53
+ /**
54
+ * Fetch a single passkey from the Passlock vault.
55
+ *
56
+ * @param options Request options including the passkey identifier.
57
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
58
+ * @returns An Effect that succeeds with the requested passkey.
59
+ *
60
+ * @category Passkeys
61
+ */
27
62
  export const getPasskey = (options, fetchLayer = NetworkFetchLive) => pipe(Effect.gen(function* () {
28
63
  const baseUrl = options.endpoint ?? "https://api.passlock.dev";
29
64
  const { tenancyId, passkeyId } = options;
@@ -42,6 +77,18 @@ export const getPasskey = (options, fetchLayer = NetworkFetchLive) => pipe(Effec
42
77
  "@error/NetworkResponse": (err) => Effect.die(err),
43
78
  ParseError: (err) => Effect.die(err),
44
79
  }), Effect.provide(fetchLayer));
80
+ /**
81
+ * Delete a single passkey from the Passlock vault.
82
+ *
83
+ * This only removes the server-side record. It does not remove the passkey
84
+ * from the user's device.
85
+ *
86
+ * @param options Request options including the passkey identifier.
87
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
88
+ * @returns An Effect that succeeds with the deleted passkey.
89
+ *
90
+ * @category Passkeys
91
+ */
45
92
  export const deletePasskey = (options, fetchLayer = NetworkFetchLive) => pipe(Effect.gen(function* () {
46
93
  const baseUrl = options.endpoint ?? "https://api.passlock.dev";
47
94
  const { tenancyId, passkeyId } = options;
@@ -61,6 +108,18 @@ export const deletePasskey = (options, fetchLayer = NetworkFetchLive) => pipe(Ef
61
108
  ParseError: (err) => Effect.die(err),
62
109
  }), Effect.provide(fetchLayer));
63
110
  // TODO reuse updatePasskey
111
+ /**
112
+ * Assign a custom user ID to a single passkey.
113
+ *
114
+ * This updates Passlock's mapping for the passkey. It does not change the
115
+ * underlying WebAuthn credential's `userId`.
116
+ *
117
+ * @param options Request options including the passkey identifier and custom user ID.
118
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
119
+ * @returns An Effect that succeeds with the updated passkey.
120
+ *
121
+ * @category Passkeys
122
+ */
64
123
  export const assignUser = (options, fetchLayer = NetworkFetchLive) => pipe(Effect.gen(function* () {
65
124
  const baseUrl = options.endpoint ?? "https://api.passlock.dev";
66
125
  const { userId, passkeyId } = options;
@@ -80,6 +139,15 @@ export const assignUser = (options, fetchLayer = NetworkFetchLive) => pipe(Effec
80
139
  "@error/NetworkResponse": (err) => Effect.die(err),
81
140
  ParseError: (err) => Effect.die(err),
82
141
  }), Effect.provide(fetchLayer));
142
+ /**
143
+ * Update a single passkey's custom user ID and/or username metadata.
144
+ *
145
+ * @param options Request options including the passkey identifier and fields to update.
146
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
147
+ * @returns An Effect that succeeds with the updated passkey.
148
+ *
149
+ * @category Passkeys
150
+ */
83
151
  export const updatePasskey = (options, fetchLayer = NetworkFetchLive) => pipe(Effect.gen(function* () {
84
152
  const baseUrl = options.endpoint ?? "https://api.passlock.dev";
85
153
  const { userId, passkeyId, username } = options;
@@ -118,6 +186,56 @@ const updateUserPasskeys = (options, fetchLayer = NetworkFetchLive) => pipe(Effe
118
186
  "@error/NetworkResponse": (err) => Effect.die(err),
119
187
  ParseError: (err) => Effect.die(err),
120
188
  }), Effect.provide(fetchLayer));
189
+ /**
190
+ * Delete all passkeys associated with a custom user ID.
191
+ *
192
+ * The resulting `deleted` credentials can be passed to
193
+ * `@passlock/client` to remove the corresponding passkeys from the user's
194
+ * device.
195
+ *
196
+ * @param options Request options including the custom user ID.
197
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
198
+ * @returns An Effect that succeeds with the deleted credential identifiers.
199
+ *
200
+ * @category Passkeys
201
+ */
202
+ export const deleteUserPasskeys = (options, fetchLayer = NetworkFetchLive) => pipe(Effect.gen(function* () {
203
+ const baseUrl = options.endpoint ?? "https://api.passlock.dev";
204
+ const { tenancyId, userId } = options;
205
+ const url = new URL(`/${tenancyId}/users/${userId}/passkeys/`, baseUrl);
206
+ const response = yield* fetchNetwork(url, "delete", { userId }, {
207
+ headers: authorizationHeaders(options.apiKey),
208
+ });
209
+ const encoded = yield* matchStatus(response, {
210
+ "2xx": (res) => decodeResponseJson(res, PasskeySchemas.DeletedPasskeysResponse),
211
+ orElse: (res) => decodeResponseJson(res, Schema.Union(NotFoundError, ForbiddenError)),
212
+ });
213
+ return yield* pipe(Match.value(encoded), Match.tag("DeletedPasskeys", (result) => Effect.succeed({
214
+ _tag: "DeletedPasskeys",
215
+ deleted: result.deleted.map((passkey) => ({
216
+ credentialId: passkey.credential.id,
217
+ userId: passkey.credential.userId,
218
+ rpId: passkey.credential.rpId,
219
+ })),
220
+ })), Match.tag("@error/NotFound", (err) => Effect.fail(err)), Match.tag("@error/Forbidden", (err) => Effect.fail(err)), Match.exhaustive);
221
+ }), Effect.catchTags({
222
+ "@error/NetworkPayload": (err) => Effect.die(err),
223
+ "@error/NetworkRequest": (err) => Effect.die(err),
224
+ "@error/NetworkResponse": (err) => Effect.die(err),
225
+ ParseError: (err) => Effect.die(err),
226
+ }), Effect.provide(fetchLayer));
227
+ /**
228
+ * Update the username metadata for all passkeys belonging to a custom user ID.
229
+ *
230
+ * The resulting payload is designed to be passed to
231
+ * `@passlock/client` so matching device credentials can be updated.
232
+ *
233
+ * @param options Request options including the custom user ID and username metadata.
234
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
235
+ * @returns An Effect that succeeds with one credential update per updated passkey.
236
+ *
237
+ * @category Passkeys
238
+ */
121
239
  export const updatePasskeyUsernames = (options, fetchLayer = NetworkFetchLive) => pipe(updateUserPasskeys(options, fetchLayer), Effect.map((result) => result.updated), Effect.map(Array.map((passkey) => {
122
240
  return {
123
241
  rpId: passkey.credential.rpId,
@@ -126,14 +244,32 @@ export const updatePasskeyUsernames = (options, fetchLayer = NetworkFetchLive) =
126
244
  displayName: options.displayName ?? passkey.credential.username,
127
245
  };
128
246
  })), Effect.map((credentials) => ({
129
- _tag: "UpdatedPasskeyUsernames",
247
+ _tag: "UpdatedCredentials",
130
248
  credentials,
131
249
  })));
132
250
  /* List Passkeys */
251
+ /**
252
+ * Stream every passkey summary for a tenancy across all result pages.
253
+ *
254
+ * @param options Request options used for each paginated request.
255
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
256
+ * @returns A stream of passkey summaries.
257
+ *
258
+ * @category Passkeys
259
+ */
133
260
  export const listPasskeysStream = (options, fetchLayer = NetworkFetchLive) => pipe(Stream.paginateChunkEffect(null, (cursor) => pipe(listPasskeys(cursor ? { ...options, cursor } : options, fetchLayer), Effect.map((result) => [
134
261
  Chunk.fromIterable(result.records),
135
262
  Option.fromNullable(result.cursor),
136
263
  ]))));
264
+ /**
265
+ * Fetch a single page of passkey summaries for a tenancy.
266
+ *
267
+ * @param options Request options including an optional pagination cursor.
268
+ * @param fetchLayer Optional fetch service override for testing or custom runtimes.
269
+ * @returns An Effect that succeeds with one page of passkey summaries.
270
+ *
271
+ * @category Passkeys
272
+ */
137
273
  export const listPasskeys = (options, fetchLayer = NetworkFetchLive) => pipe(Effect.gen(function* () {
138
274
  const baseUrl = options.endpoint ?? "https://api.passlock.dev";
139
275
  const { tenancyId } = options;