@apifuse/provider-sdk 2.2.0-beta.3 → 2.2.0-beta.5

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 (165) hide show
  1. package/AUTHORING.md +53 -0
  2. package/CHANGELOG.md +8 -0
  3. package/bin/apifuse-check.ts +18 -58
  4. package/bin/apifuse-create.ts +1 -1
  5. package/bin/apifuse-dev.ts +27 -52
  6. package/bin/apifuse-pack-smoke.ts +22 -81
  7. package/bin/apifuse-pack-types.ts +266 -0
  8. package/bin/apifuse-perf.ts +45 -127
  9. package/bin/apifuse-record.ts +23 -61
  10. package/bin/apifuse-submit-check.ts +266 -34
  11. package/bin/apifuse.ts +1 -1
  12. package/bin/submit-check-xml.ts +1 -1
  13. package/dist/auth-turn/index.d.ts +1 -1
  14. package/dist/auth.d.ts +2 -2
  15. package/dist/auth.js +9 -18
  16. package/dist/ceremonies/index.d.ts +1 -1
  17. package/dist/ceremonies/index.js +8 -18
  18. package/dist/config/loader.d.ts +2 -2
  19. package/dist/config/loader.js +19 -42
  20. package/dist/contract-serialization.d.ts +2 -2
  21. package/dist/contract-serialization.js +3 -6
  22. package/dist/contract-types.d.ts +2 -2
  23. package/dist/contract.d.ts +3 -3
  24. package/dist/contract.js +4 -6
  25. package/dist/define.d.ts +8 -1
  26. package/dist/define.js +57 -115
  27. package/dist/dev.d.ts +1 -1
  28. package/dist/dev.js +1 -1
  29. package/dist/errors.d.ts +1 -1
  30. package/dist/errors.js +1 -3
  31. package/dist/i18n/catalog.d.ts +2 -2
  32. package/dist/i18n/catalog.js +4 -10
  33. package/dist/i18n/index.d.ts +2 -2
  34. package/dist/i18n/index.js +2 -2
  35. package/dist/i18n/keys.d.ts +2 -2
  36. package/dist/index.d.ts +43 -42
  37. package/dist/index.js +38 -37
  38. package/dist/lint.js +8 -15
  39. package/dist/provider.d.ts +11 -11
  40. package/dist/provider.js +9 -9
  41. package/dist/public-schema-field-lint.d.ts +1 -1
  42. package/dist/recipes/gov-api.js +1 -1
  43. package/dist/runtime/auth-flow.d.ts +1 -1
  44. package/dist/runtime/auth-flow.js +3 -3
  45. package/dist/runtime/browser.d.ts +1 -1
  46. package/dist/runtime/browser.js +15 -29
  47. package/dist/runtime/cache.d.ts +1 -1
  48. package/dist/runtime/cache.js +4 -8
  49. package/dist/runtime/choice.d.ts +1 -1
  50. package/dist/runtime/choice.js +12 -34
  51. package/dist/runtime/credential.d.ts +1 -1
  52. package/dist/runtime/credential.js +1 -1
  53. package/dist/runtime/env.d.ts +1 -1
  54. package/dist/runtime/executor.d.ts +1 -1
  55. package/dist/runtime/executor.js +2 -2
  56. package/dist/runtime/http.d.ts +2 -2
  57. package/dist/runtime/http.js +5 -5
  58. package/dist/runtime/insights.d.ts +1 -1
  59. package/dist/runtime/insights.js +6 -13
  60. package/dist/runtime/instrumentation.d.ts +2 -2
  61. package/dist/runtime/instrumentation.js +5 -15
  62. package/dist/runtime/keyring.js +1 -1
  63. package/dist/runtime/namespace.js +1 -1
  64. package/dist/runtime/otlp.d.ts +1 -1
  65. package/dist/runtime/perf.d.ts +1 -1
  66. package/dist/runtime/provider.d.ts +1 -1
  67. package/dist/runtime/provider.js +1 -2
  68. package/dist/runtime/proxy-errors.d.ts +1 -1
  69. package/dist/runtime/proxy-errors.js +3 -5
  70. package/dist/runtime/proxy-retry-policy.d.ts +2 -2
  71. package/dist/runtime/proxy-retry-policy.js +2 -2
  72. package/dist/runtime/proxy-telemetry.d.ts +1 -1
  73. package/dist/runtime/proxy-telemetry.js +16 -48
  74. package/dist/runtime/redis.d.ts +1 -1
  75. package/dist/runtime/redis.js +2 -4
  76. package/dist/runtime/request-options.d.ts +1 -1
  77. package/dist/runtime/state.d.ts +2 -2
  78. package/dist/runtime/state.js +3 -3
  79. package/dist/runtime/stealth.d.ts +2 -2
  80. package/dist/runtime/stealth.js +6 -6
  81. package/dist/runtime/stt.d.ts +1 -1
  82. package/dist/runtime/stt.js +11 -15
  83. package/dist/runtime/trace.d.ts +2 -2
  84. package/dist/runtime/trace.js +2 -4
  85. package/dist/runtime/waterfall.d.ts +1 -1
  86. package/dist/schema.d.ts +1 -1
  87. package/dist/schema.js +7 -15
  88. package/dist/serve.d.ts +1 -1
  89. package/dist/serve.js +1 -1
  90. package/dist/server/index.d.ts +7 -7
  91. package/dist/server/index.js +6 -6
  92. package/dist/server/self-test-redaction.d.ts +1 -1
  93. package/dist/server/self-test-redaction.js +1 -1
  94. package/dist/server/self-test.d.ts +104 -3
  95. package/dist/server/self-test.js +673 -115
  96. package/dist/server/serve.d.ts +3 -3
  97. package/dist/server/serve.js +37 -49
  98. package/dist/server/types.js +2 -7
  99. package/dist/stealth/profiles.d.ts +1 -1
  100. package/dist/stealth/profiles.js +5 -14
  101. package/dist/stream.d.ts +1 -1
  102. package/dist/testing/index.d.ts +2 -2
  103. package/dist/testing/index.js +2 -2
  104. package/dist/testing/run.d.ts +1 -1
  105. package/dist/testing/run.js +7 -14
  106. package/dist/types.d.ts +57 -0
  107. package/dist/user-input.d.ts +30 -0
  108. package/dist/user-input.js +66 -0
  109. package/package.json +6 -4
  110. package/src/auth-turn/index.ts +1 -1
  111. package/src/auth.ts +28 -86
  112. package/src/ceremonies/index.ts +24 -78
  113. package/src/config/loader.ts +58 -176
  114. package/src/contract-serialization.ts +5 -11
  115. package/src/contract-types.ts +2 -2
  116. package/src/contract.ts +12 -28
  117. package/src/define.ts +174 -495
  118. package/src/dev.ts +4 -9
  119. package/src/errors.ts +4 -11
  120. package/src/i18n/catalog.ts +10 -32
  121. package/src/i18n/index.ts +2 -2
  122. package/src/i18n/keys.ts +5 -11
  123. package/src/index.ts +44 -42
  124. package/src/lint.ts +89 -159
  125. package/src/provider.ts +12 -11
  126. package/src/public-schema-field-lint.ts +7 -33
  127. package/src/recipes/gov-api.ts +2 -5
  128. package/src/runtime/auth-flow.ts +5 -7
  129. package/src/runtime/browser.ts +64 -187
  130. package/src/runtime/cache.ts +20 -67
  131. package/src/runtime/choice.ts +55 -129
  132. package/src/runtime/credential.ts +2 -2
  133. package/src/runtime/env.ts +1 -1
  134. package/src/runtime/executor.ts +9 -19
  135. package/src/runtime/http.ts +7 -7
  136. package/src/runtime/insights.ts +15 -53
  137. package/src/runtime/instrumentation.ts +19 -58
  138. package/src/runtime/keyring.ts +7 -19
  139. package/src/runtime/namespace.ts +2 -7
  140. package/src/runtime/otlp.ts +12 -23
  141. package/src/runtime/perf.ts +1 -1
  142. package/src/runtime/provider.ts +4 -9
  143. package/src/runtime/proxy-errors.ts +17 -38
  144. package/src/runtime/proxy-retry-policy.ts +3 -3
  145. package/src/runtime/proxy-telemetry.ts +23 -72
  146. package/src/runtime/redis.ts +4 -12
  147. package/src/runtime/request-options.ts +4 -13
  148. package/src/runtime/state.ts +30 -109
  149. package/src/runtime/stealth.ts +8 -8
  150. package/src/runtime/stt.ts +38 -94
  151. package/src/runtime/trace.ts +14 -44
  152. package/src/runtime/waterfall.ts +5 -18
  153. package/src/schema.ts +23 -84
  154. package/src/serve.ts +1 -1
  155. package/src/server/index.ts +12 -7
  156. package/src/server/self-test-redaction.ts +2 -2
  157. package/src/server/self-test.ts +857 -132
  158. package/src/server/serve.ts +89 -238
  159. package/src/server/types.ts +6 -19
  160. package/src/stealth/profiles.ts +10 -26
  161. package/src/stream.ts +8 -19
  162. package/src/testing/index.ts +2 -2
  163. package/src/testing/run.ts +19 -67
  164. package/src/types.ts +58 -0
  165. package/src/user-input.ts +118 -0
package/src/auth.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AuthError, ProviderError } from "./errors";
1
+ import { AuthError, ProviderError } from "./errors.js";
2
2
  import type {
3
3
  AuthAbortData,
4
4
  AuthConfig,
@@ -10,7 +10,7 @@ import type {
10
10
  CredentialDeclaration,
11
11
  FlowContext,
12
12
  ProviderLocaleKeyInput,
13
- } from "./types";
13
+ } from "./types.js";
14
14
 
15
15
  const CREDENTIALS_AUTH_CHALLENGE_CONTEXT_KEY = "__credentialsAuthChallenge";
16
16
  const DEFAULT_COMPLETE_TURN_ID = "auth.complete";
@@ -33,11 +33,7 @@ function isSensitiveAuthDataKey(key: string): boolean {
33
33
  return SENSITIVE_ABORT_DATA_KEY_PATTERN.test(normalizedAuthDataKey(key));
34
34
  }
35
35
 
36
- export type CredentialsAuthFieldType =
37
- | "string"
38
- | "email"
39
- | "password"
40
- | "otp";
36
+ export type CredentialsAuthFieldType = "string" | "email" | "password" | "otp";
41
37
 
42
38
  export interface CredentialsAuthField {
43
39
  type?: CredentialsAuthFieldType;
@@ -138,10 +134,9 @@ function abortData(options: {
138
134
  };
139
135
  }
140
136
 
141
- export function createAuthFlowHelpers(options: {
142
- readonly signal?: AbortSignal;
143
- readonly deadline?: string;
144
- } = {}): AuthFlowTerminalContext {
137
+ export function createAuthFlowHelpers(
138
+ options: { readonly signal?: AbortSignal; readonly deadline?: string } = {},
139
+ ): AuthFlowTerminalContext {
145
140
  return {
146
141
  ...(options.signal ? { signal: options.signal } : {}),
147
142
  ...(options.deadline ? { deadline: options.deadline } : {}),
@@ -156,16 +151,7 @@ export function createAuthFlowHelpers(options: {
156
151
  },
157
152
  };
158
153
  },
159
- abort({
160
- code,
161
- message,
162
- retry,
163
- actionHint,
164
- fieldErrors,
165
- data,
166
- turnId,
167
- expiresAt,
168
- }) {
154
+ abort({ code, message, retry, actionHint, fieldErrors, data, turnId, expiresAt }) {
169
155
  return {
170
156
  kind: "abort",
171
157
  ...authTurnBase({ turnId, defaultTurnId: DEFAULT_ABORT_TURN_ID, expiresAt }),
@@ -190,8 +176,7 @@ export function createAuthFlowHelpers(options: {
190
176
  ...(options.hintKey ? { hintKey: options.hintKey } : {}),
191
177
  ...(options.timing ? { timing: options.timing } : {}),
192
178
  ...(options.data ? { data: options.data } : {}),
193
- expectedInput:
194
- options.expectedInput ?? expectedInputFromFields(options.fields ?? {}),
179
+ expectedInput: options.expectedInput ?? expectedInputFromFields(options.fields ?? {}),
195
180
  };
196
181
  },
197
182
  nextPoll(options = {}) {
@@ -223,9 +208,7 @@ export class AuthAbortError extends AuthError {
223
208
  }
224
209
  }
225
210
 
226
- export interface CredentialsAuthCompleteResult<
227
- TCredentialKeys extends readonly string[],
228
- > {
211
+ export interface CredentialsAuthCompleteResult<TCredentialKeys extends readonly string[]> {
229
212
  credential: CredentialsAuthCredential<TCredentialKeys>;
230
213
  /** Additional non-credential auth-flow data to return alongside credential. */
231
214
  data?: Record<string, unknown>;
@@ -247,9 +230,7 @@ export interface CredentialsAuthChallengeRequest<TChallengeId extends string = s
247
230
  export type CredentialsAuthLoginResult<
248
231
  TCredentialKeys extends readonly string[],
249
232
  TChallengeId extends string = string,
250
- > =
251
- | CredentialsAuthCompleteResult<TCredentialKeys>
252
- | CredentialsAuthChallengeRequest<TChallengeId>;
233
+ > = CredentialsAuthCompleteResult<TCredentialKeys> | CredentialsAuthChallengeRequest<TChallengeId>;
253
234
 
254
235
  export interface CredentialsAuthChallengeDefinition<
255
236
  TFields extends CredentialsAuthFields,
@@ -351,12 +332,8 @@ function expectedInputFromFields(fields: CredentialsAuthFields): Record<string,
351
332
  ...(field.type === "password" ? { format: "password" } : {}),
352
333
  ...(field.type === "otp" ? { format: "otp" } : {}),
353
334
  ...(field.labelKey ? { nameKey: field.labelKey } : {}),
354
- ...(field.descriptionKey
355
- ? { descriptionKey: field.descriptionKey }
356
- : {}),
357
- ...(field.placeholderKey
358
- ? { placeholderKey: field.placeholderKey }
359
- : {}),
335
+ ...(field.descriptionKey ? { descriptionKey: field.descriptionKey } : {}),
336
+ ...(field.placeholderKey ? { placeholderKey: field.placeholderKey } : {}),
360
337
  ...(field.sensitive || field.type === "password" || field.type === "otp"
361
338
  ? { sensitive: true }
362
339
  : {}),
@@ -437,10 +414,7 @@ function getPendingChallenge(ctx: FlowContext): PendingCredentialsAuthChallenge
437
414
  };
438
415
  }
439
416
 
440
- function setPendingChallenge(
441
- ctx: FlowContext,
442
- challenge: PendingCredentialsAuthChallenge,
443
- ): void {
417
+ function setPendingChallenge(ctx: FlowContext, challenge: PendingCredentialsAuthChallenge): void {
444
418
  ctx.context.set(CREDENTIALS_AUTH_CHALLENGE_CONTEXT_KEY, challenge);
445
419
  }
446
420
 
@@ -473,9 +447,7 @@ function retryTurn(
473
447
  turnId: retryTurnId,
474
448
  expectedInput,
475
449
  data: {
476
- fieldErrors: Object.fromEntries(
477
- missing.map((name) => [name, "Required"]),
478
- ),
450
+ fieldErrors: Object.fromEntries(missing.map((name) => [name, "Required"])),
479
451
  fieldErrorKeys: Object.fromEntries(
480
452
  missing.map((name) => [name, "auth.credentials.fieldRequired"]),
481
453
  ),
@@ -499,18 +471,12 @@ function completeTurn<TCredentialKeys extends readonly string[]>(
499
471
  typeof result.credential !== "object" ||
500
472
  Array.isArray(result.credential)
501
473
  ) {
502
- throw new ProviderError(
503
- "Credentials auth login completed without a credential object",
504
- {
505
- code: "credentials_auth_missing_credential",
506
- fix: "Return { credential: { ... } } from defineCredentialsAuth handlers. Gateway persists only auth.flow complete data.credential into the connection.",
507
- },
508
- );
474
+ throw new ProviderError("Credentials auth login completed without a credential object", {
475
+ code: "credentials_auth_missing_credential",
476
+ fix: "Return { credential: { ... } } from defineCredentialsAuth handlers. Gateway persists only auth.flow complete data.credential into the connection.",
477
+ });
509
478
  }
510
- assertCredentialKeys(
511
- credentialKeys,
512
- result.credential as Record<string, unknown>,
513
- );
479
+ assertCredentialKeys(credentialKeys, result.credential as Record<string, unknown>);
514
480
  return {
515
481
  kind: "complete",
516
482
  turnId: result.turnId ?? defaultTurnId,
@@ -523,24 +489,18 @@ function completeTurn<TCredentialKeys extends readonly string[]>(
523
489
  }
524
490
 
525
491
  function challengeTurn(
526
- definition: CredentialsAuthChallengeDefinition<
527
- CredentialsAuthFields,
528
- readonly string[],
529
- string
530
- >,
492
+ definition: CredentialsAuthChallengeDefinition<CredentialsAuthFields, readonly string[], string>,
531
493
  request: CredentialsAuthChallengeRequest<string>,
532
494
  ): AuthTurn {
533
- const expectedInput = definition.fields
534
- ? expectedInputFromFields(definition.fields)
535
- : undefined;
495
+ const expectedInput = definition.fields ? expectedInputFromFields(definition.fields) : undefined;
536
496
  return {
537
497
  kind: expectedInput ? "form" : "pending",
538
498
  turnId: request.turnId ?? definition.turnId ?? `credentials.${request.challengeId}`,
539
499
  ...(request.expiresAt ? { expiresAt: request.expiresAt } : {}),
540
- ...(request.hintKey ?? definition.hintKey
500
+ ...((request.hintKey ?? definition.hintKey)
541
501
  ? { hintKey: request.hintKey ?? definition.hintKey }
542
502
  : {}),
543
- ...(request.timing ?? definition.timing
503
+ ...((request.timing ?? definition.timing)
544
504
  ? { timing: request.timing ?? definition.timing }
545
505
  : {}),
546
506
  ...(expectedInput ? { expectedInput } : {}),
@@ -630,13 +590,7 @@ async function continuePendingChallenge<TCredentialKeys extends readonly string[
630
590
  normalizeInput(definition.fields, rawInput),
631
591
  pending.state,
632
592
  );
633
- return await resolveAuthResult(
634
- ctx,
635
- credentialKeys,
636
- challenges,
637
- result,
638
- completeTurnId,
639
- );
593
+ return await resolveAuthResult(ctx, credentialKeys, challenges, result, completeTurnId);
640
594
  }
641
595
 
642
596
  async function pollPendingChallenge<TCredentialKeys extends readonly string[]>(
@@ -669,13 +623,7 @@ async function pollPendingChallenge<TCredentialKeys extends readonly string[]>(
669
623
  `credentials.${pending.challengeId}.pending`,
670
624
  };
671
625
  }
672
- return await resolveAuthResult(
673
- ctx,
674
- credentialKeys,
675
- challenges,
676
- result,
677
- completeTurnId,
678
- );
626
+ return await resolveAuthResult(ctx, credentialKeys, challenges, result, completeTurnId);
679
627
  }
680
628
 
681
629
  export function defineCredentialsAuth<
@@ -697,7 +645,7 @@ export function defineCredentialsAuth<
697
645
  ): DefinedCredentialsAuth {
698
646
  if (Object.keys(options.fields).length === 0) {
699
647
  throw new ProviderError("defineCredentialsAuth requires at least one field", {
700
- fix: "Pass fields such as { email: { type: \"email\" }, password: { type: \"password\" } }.",
648
+ fix: 'Pass fields such as { email: { type: "email" }, password: { type: "password" } }.',
701
649
  });
702
650
  }
703
651
 
@@ -737,10 +685,7 @@ export function defineCredentialsAuth<
737
685
  return retryTurn(expectedInput, missing, retryTurnId);
738
686
  }
739
687
 
740
- const result = await options.login(
741
- ctx,
742
- normalizeInput(options.fields, rawInput),
743
- );
688
+ const result = await options.login(ctx, normalizeInput(options.fields, rawInput));
744
689
  return await resolveAuthResult(
745
690
  ctx,
746
691
  options.credentialKeys,
@@ -776,10 +721,7 @@ export function defineCredentialsAuth<
776
721
  },
777
722
  context: {
778
723
  keys: Array.from(
779
- new Set([
780
- CREDENTIALS_AUTH_CHALLENGE_CONTEXT_KEY,
781
- ...(options.contextKeys ?? []),
782
- ]),
724
+ new Set([CREDENTIALS_AUTH_CHALLENGE_CONTEXT_KEY, ...(options.contextKeys ?? [])]),
783
725
  ),
784
726
  },
785
727
  };
@@ -2,19 +2,14 @@ import { createHash, randomBytes, randomUUID } from "node:crypto";
2
2
 
3
3
  import Ajv2020 from "ajv/dist/2020.js";
4
4
 
5
- import { AUTH_TURN_SCHEMA, type KnownAuthTurnKind } from "../auth-turn";
5
+ import { AUTH_TURN_SCHEMA, type KnownAuthTurnKind } from "../auth-turn/index.js";
6
6
  import {
7
7
  FlowExpiredError,
8
8
  ProviderSecretError,
9
9
  TurnValidationError,
10
10
  ValidationError,
11
- } from "../errors";
12
- import type {
13
- AuthFlowDefinition,
14
- AuthFlowInputHandler,
15
- AuthTurn,
16
- FlowContext,
17
- } from "../types";
11
+ } from "../errors.js";
12
+ import type { AuthFlowDefinition, AuthFlowInputHandler, AuthTurn, FlowContext } from "../types.js";
18
13
 
19
14
  type TurnKind = KnownAuthTurnKind;
20
15
 
@@ -45,10 +40,7 @@ function ensureRecord(value: unknown): JsonObject {
45
40
  return isRecord(value) ? value : {};
46
41
  }
47
42
 
48
- function createTurn(
49
- kind: TurnKind,
50
- options: Omit<AuthTurn, "kind" | "turnId"> = {},
51
- ): AuthTurn {
43
+ function createTurn(kind: TurnKind, options: Omit<AuthTurn, "kind" | "turnId"> = {}): AuthTurn {
52
44
  return {
53
45
  kind,
54
46
  turnId: randomUUID(),
@@ -69,11 +61,7 @@ function getRequiredEnv(ctx: FlowContext, key: string): string {
69
61
  }
70
62
 
71
63
  function toBase64Url(input: Buffer): string {
72
- return input
73
- .toString("base64")
74
- .replace(/\+/g, "-")
75
- .replace(/\//g, "_")
76
- .replace(/=+$/g, "");
64
+ return input.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
77
65
  }
78
66
 
79
67
  function createCodeVerifier(): string {
@@ -130,10 +118,7 @@ async function runCeremonyHandler(
130
118
  }
131
119
  }
132
120
 
133
- function getString(
134
- input: Record<string, unknown>,
135
- key: string,
136
- ): string | undefined {
121
+ function getString(input: Record<string, unknown>, key: string): string | undefined {
137
122
  const value = input[key];
138
123
  return typeof value === "string" ? value : undefined;
139
124
  }
@@ -142,10 +127,7 @@ function getNestedRecord(ctx: FlowContext, key: string): JsonObject {
142
127
  return ensureRecord(ctx.context.get(key));
143
128
  }
144
129
 
145
- function buildJsonSchemaForm(
146
- expectedInput: JsonObject,
147
- hint: string,
148
- ): AuthTurn {
130
+ function buildJsonSchemaForm(expectedInput: JsonObject, hint: string): AuthTurn {
149
131
  return createTurn("form", {
150
132
  hint,
151
133
  expectedInput: withDeclaredFormFieldOrder(expectedInput),
@@ -160,10 +142,7 @@ function withDeclaredFormFieldOrder(expectedInput: JsonObject): JsonObject {
160
142
  }
161
143
 
162
144
  const existingOrder = expectedInput[FORM_FIELD_ORDER_EXTENSION];
163
- if (
164
- Array.isArray(existingOrder) &&
165
- existingOrder.every((value) => typeof value === "string")
166
- ) {
145
+ if (Array.isArray(existingOrder) && existingOrder.every((value) => typeof value === "string")) {
167
146
  return expectedInput;
168
147
  }
169
148
 
@@ -176,9 +155,7 @@ function withDeclaredFormFieldOrder(expectedInput: JsonObject): JsonObject {
176
155
  export function validateCeremonyOutput(turn: unknown): AuthTurn {
177
156
  if (!validateAuthTurn(turn)) {
178
157
  const detail = validateAuthTurn.errors
179
- ?.map(
180
- (error) => `${error.instancePath || "$"} ${error.message ?? "invalid"}`,
181
- )
158
+ ?.map((error) => `${error.instancePath || "$"} ${error.message ?? "invalid"}`)
182
159
  .join("; ");
183
160
  throw new TurnValidationError(detail || "Invalid AuthTurn output");
184
161
  }
@@ -214,10 +191,7 @@ export function createOAuth2Ceremony(options: {
214
191
  if (options.usePKCE) {
215
192
  const verifier = createCodeVerifier();
216
193
  ctx.context.set(OAUTH2_PKCE_VERIFIER_KEY, verifier);
217
- authorizeUrl.searchParams.set(
218
- "code_challenge",
219
- createCodeChallenge(verifier),
220
- );
194
+ authorizeUrl.searchParams.set("code_challenge", createCodeChallenge(verifier));
221
195
  authorizeUrl.searchParams.set("code_challenge_method", "S256");
222
196
  }
223
197
 
@@ -270,10 +244,7 @@ export function createOAuth2Ceremony(options: {
270
244
  ctx,
271
245
  input,
272
246
  ),
273
- abort: async () =>
274
- validateCeremonyOutput(
275
- createTurn("abort", { hint: "OAuth flow aborted." }),
276
- ),
247
+ abort: async () => validateCeremonyOutput(createTurn("abort", { hint: "OAuth flow aborted." })),
277
248
  };
278
249
  }
279
250
 
@@ -329,26 +300,19 @@ export function createDeviceFlowCeremony(options: {
329
300
  client_id: getRequiredEnv(ctx, options.clientIdEnvKey),
330
301
  ...(options.clientSecretEnvKey
331
302
  ? {
332
- client_secret: getRequiredEnv(
333
- ctx,
334
- options.clientSecretEnvKey,
335
- ),
303
+ client_secret: getRequiredEnv(ctx, options.clientSecretEnvKey),
336
304
  }
337
305
  : {}),
338
306
  });
339
307
  const data = ensureRecord(response.data);
340
308
  const errorCode = getString(data, "error");
341
309
 
342
- if (
343
- errorCode === "authorization_pending" ||
344
- errorCode === "slow_down"
345
- ) {
310
+ if (errorCode === "authorization_pending" || errorCode === "slow_down") {
346
311
  return createTurn("poll", {
347
312
  data,
348
313
  hint: "Authorization pending.",
349
314
  timing: {
350
- suggestedPollIntervalMs:
351
- errorCode === "slow_down" ? 10_000 : 5_000,
315
+ suggestedPollIntervalMs: errorCode === "slow_down" ? 10_000 : 5_000,
352
316
  maxWaitMs: 120_000,
353
317
  },
354
318
  });
@@ -367,9 +331,7 @@ export function createDeviceFlowCeremony(options: {
367
331
  ctx,
368
332
  ),
369
333
  abort: async () =>
370
- validateCeremonyOutput(
371
- createTurn("abort", { hint: "Device flow aborted." }),
372
- ),
334
+ validateCeremonyOutput(createTurn("abort", { hint: "Device flow aborted." })),
373
335
  };
374
336
  }
375
337
 
@@ -437,9 +399,7 @@ export function createWebAuthnCeremony(options: {
437
399
  input,
438
400
  ),
439
401
  abort: async () =>
440
- validateCeremonyOutput(
441
- createTurn("abort", { hint: "WebAuthn ceremony aborted." }),
442
- ),
402
+ validateCeremonyOutput(createTurn("abort", { hint: "WebAuthn ceremony aborted." })),
443
403
  };
444
404
  }
445
405
 
@@ -526,9 +486,7 @@ export function createMagicLinkCeremony(options: {
526
486
  ctx,
527
487
  ),
528
488
  abort: async () =>
529
- validateCeremonyOutput(
530
- createTurn("abort", { hint: "Magic link flow aborted." }),
531
- ),
489
+ validateCeremonyOutput(createTurn("abort", { hint: "Magic link flow aborted." })),
532
490
  };
533
491
  }
534
492
 
@@ -548,7 +506,7 @@ export function createFormCeremony(options: {
548
506
  continue: (ctx, input = {}) =>
549
507
  runCeremonyHandler(
550
508
  async () => {
551
- const { prevalidate } = await import("../runtime/prevalidate");
509
+ const { prevalidate } = await import("../runtime/prevalidate.js");
552
510
  const result = prevalidate(options.schema, input);
553
511
  if (!result.valid) {
554
512
  throw new ValidationError("Form input failed validation.", {
@@ -558,9 +516,7 @@ export function createFormCeremony(options: {
558
516
 
559
517
  return createTurn("complete", {
560
518
  data: {
561
- credential: options.mapCredential
562
- ? options.mapCredential(input)
563
- : input,
519
+ credential: options.mapCredential ? options.mapCredential(input) : input,
564
520
  },
565
521
  hint: "Form completed.",
566
522
  });
@@ -570,15 +526,11 @@ export function createFormCeremony(options: {
570
526
  input,
571
527
  ),
572
528
  abort: async () =>
573
- validateCeremonyOutput(
574
- createTurn("abort", { hint: "Form ceremony aborted." }),
575
- ),
529
+ validateCeremonyOutput(createTurn("abort", { hint: "Form ceremony aborted." })),
576
530
  };
577
531
  }
578
532
 
579
- export function combineCeremonies(
580
- ...ceremonies: AuthFlowDefinition[]
581
- ): AuthFlowDefinition {
533
+ export function combineCeremonies(...ceremonies: AuthFlowDefinition[]): AuthFlowDefinition {
582
534
  function getStage(ctx: FlowContext): number {
583
535
  const rawStage = ctx.context.get(COMBINED_STAGE_KEY);
584
536
  return typeof rawStage === "number" ? rawStage : 0;
@@ -630,9 +582,7 @@ export function combineCeremonies(
630
582
  async () => {
631
583
  const current = ceremonies[getStage(ctx)];
632
584
  if (!current?.poll) {
633
- throw new ValidationError(
634
- "Current ceremony does not support polling.",
635
- );
585
+ throw new ValidationError("Current ceremony does not support polling.");
636
586
  }
637
587
  return await current.poll(ctx);
638
588
  },
@@ -680,9 +630,7 @@ export function createSwitchCeremony(options: {
680
630
  async () => {
681
631
  const storedChoice = ctx.context.get(SWITCH_SELECTION_KEY);
682
632
  const choice =
683
- typeof storedChoice === "string"
684
- ? storedChoice
685
- : getString(input, "choice");
633
+ typeof storedChoice === "string" ? storedChoice : getString(input, "choice");
686
634
 
687
635
  if (!choice || !options.choices[choice]) {
688
636
  throw new ValidationError("A valid choice is required.");
@@ -710,9 +658,7 @@ export function createSwitchCeremony(options: {
710
658
 
711
659
  const ceremony = options.choices[choice];
712
660
  if (!ceremony?.poll) {
713
- throw new ValidationError(
714
- "Selected ceremony does not support polling.",
715
- );
661
+ throw new ValidationError("Selected ceremony does not support polling.");
716
662
  }
717
663
 
718
664
  return await ceremony.poll(ctx);