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

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 +14 -0
  2. package/CHANGELOG.md +4 -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 +26 -21
  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 +3 -3
  95. package/dist/server/self-test.js +3 -3
  96. package/dist/server/serve.d.ts +3 -3
  97. package/dist/server/serve.js +36 -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 +7 -7
  156. package/src/server/self-test-redaction.ts +2 -2
  157. package/src/server/self-test.ts +5 -5
  158. package/src/server/serve.ts +87 -242
  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/lint.ts CHANGED
@@ -1,17 +1,9 @@
1
1
  import type { ZodType } from "zod";
2
2
 
3
- import { lintPublicSchemaFieldNames } from "./public-schema-field-lint";
4
- import {
5
- APIFUSE_DESCRIPTION_KEY_META_KEY,
6
- APIFUSE_SENSITIVE_META_KEY,
7
- } from "./schema";
8
-
9
- type AuthModeLike =
10
- | "none"
11
- | "platform-managed"
12
- | "credentials"
13
- | "oauth2"
14
- | "api-key";
3
+ import { lintPublicSchemaFieldNames } from "./public-schema-field-lint.js";
4
+ import { APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_SENSITIVE_META_KEY } from "./schema.js";
5
+
6
+ type AuthModeLike = "none" | "platform-managed" | "credentials" | "oauth2" | "api-key";
15
7
 
16
8
  type ProviderAuthLike = {
17
9
  mode?: AuthModeLike;
@@ -141,28 +133,19 @@ function hasReusableSecretKeys(keys: readonly string[] | undefined): boolean {
141
133
  }
142
134
 
143
135
  return keys.some((key) =>
144
- /(access_token|refresh_token|password|secret|cookie|session|token|api[_-]?key)/i.test(
145
- key,
146
- ),
136
+ /(access_token|refresh_token|password|secret|cookie|session|token|api[_-]?key)/i.test(key),
147
137
  );
148
138
  }
149
139
 
150
- function hasReusableReloginSecretKeys(
151
- keys: readonly string[] | undefined,
152
- ): boolean {
140
+ function hasReusableReloginSecretKeys(keys: readonly string[] | undefined): boolean {
153
141
  if (!keys) {
154
142
  return false;
155
143
  }
156
144
 
157
- return keys.some((key) =>
158
- /(password|passcode|secret|cookie|session)/i.test(key),
159
- );
145
+ return keys.some((key) => /(password|passcode|secret|cookie|session)/i.test(key));
160
146
  }
161
147
 
162
- function getAuthFlowSource(provider: {
163
- auth?: ProviderAuthLike;
164
- authFlowSource?: string;
165
- }): string {
148
+ function getAuthFlowSource(provider: { auth?: ProviderAuthLike; authFlowSource?: string }): string {
166
149
  if (provider.authFlowSource) {
167
150
  return provider.authFlowSource;
168
151
  }
@@ -176,10 +159,7 @@ function getAuthFlowSource(provider: {
176
159
  ];
177
160
 
178
161
  return parts
179
- .filter(
180
- (part): part is (...args: unknown[]) => unknown =>
181
- typeof part === "function",
182
- )
162
+ .filter((part): part is (...args: unknown[]) => unknown => typeof part === "function")
183
163
  .map((part) => part.toString())
184
164
  .join("\n");
185
165
  }
@@ -243,8 +223,7 @@ function lintAuthModel(provider: {
243
223
 
244
224
  if (
245
225
  hasReusableSecretKeys(credentialKeys) &&
246
- (!provider.credential?.storesReusableSecret ||
247
- !provider.credential.justification)
226
+ (!provider.credential?.storesReusableSecret || !provider.credential.justification)
248
227
  ) {
249
228
  diagnostics.push({
250
229
  rule: "credential-reusable-secret",
@@ -257,8 +236,7 @@ function lintAuthModel(provider: {
257
236
  if (
258
237
  typeof provider.auth?.flow?.refresh === "function" &&
259
238
  hasReusableReloginSecretKeys(credentialKeys) &&
260
- (!provider.credential?.storesReusableSecret ||
261
- !provider.credential.justification)
239
+ (!provider.credential?.storesReusableSecret || !provider.credential.justification)
262
240
  ) {
263
241
  diagnostics.push({
264
242
  rule: "auth-refresh-reusable-secret",
@@ -278,10 +256,7 @@ function lintAuthModel(provider: {
278
256
  }
279
257
 
280
258
  const authFlowSource = getAuthFlowSource(provider);
281
- if (
282
- authFlowSource.includes("ctx.context") &&
283
- (provider.context?.keys?.length ?? 0) === 0
284
- ) {
259
+ if (authFlowSource.includes("ctx.context") && (provider.context?.keys?.length ?? 0) === 0) {
285
260
  diagnostics.push({
286
261
  rule: "context-keys-required",
287
262
  level: "warn",
@@ -323,8 +298,7 @@ function isSchemaRecord(value: unknown): value is Record<string, SchemaLike> {
323
298
  }
324
299
 
325
300
  function getObjectShape(schema: SchemaLike): Record<string, SchemaLike> {
326
- const rawShape =
327
- typeof schema.shape === "function" ? schema.shape() : schema.shape;
301
+ const rawShape = typeof schema.shape === "function" ? schema.shape() : schema.shape;
328
302
  if (isSchemaRecord(rawShape)) {
329
303
  return rawShape;
330
304
  }
@@ -344,9 +318,7 @@ function getObjectShape(schema: SchemaLike): Record<string, SchemaLike> {
344
318
  return {};
345
319
  }
346
320
 
347
- function getChildSchemas(
348
- schema: SchemaLike,
349
- ): Array<{ key: string; schema: SchemaLike }> {
321
+ function getChildSchemas(schema: SchemaLike): Array<{ key: string; schema: SchemaLike }> {
350
322
  const seen = new Map<string, SchemaLike>();
351
323
  const def = getSchemaDef(schema);
352
324
 
@@ -450,10 +422,7 @@ function getSchemaMetadata(schema: SchemaLike): Record<string, unknown> {
450
422
  }
451
423
 
452
424
  function getSchemaDescriptionKey(schema: SchemaLike): string | undefined {
453
- const value = Reflect.get(
454
- getSchemaMetadata(schema),
455
- APIFUSE_DESCRIPTION_KEY_META_KEY,
456
- );
425
+ const value = Reflect.get(getSchemaMetadata(schema), APIFUSE_DESCRIPTION_KEY_META_KEY);
457
426
  return typeof value === "string" && value.length > 0 ? value : undefined;
458
427
  }
459
428
 
@@ -597,22 +566,14 @@ function collectSchemaDescriptionKeyDiagnostics(
597
566
  ? `${currentPath}[]`
598
567
  : `${currentPath}.${child.key}`;
599
568
  diagnostics.push(
600
- ...collectSchemaDescriptionKeyDiagnostics(
601
- child.schema,
602
- childPath,
603
- seen,
604
- !isStructuralNode,
605
- ),
569
+ ...collectSchemaDescriptionKeyDiagnostics(child.schema, childPath, seen, !isStructuralNode),
606
570
  );
607
571
  }
608
572
 
609
573
  return diagnostics;
610
574
  }
611
575
 
612
- function isComplexSchema(
613
- schema: unknown,
614
- seen = new Set<SchemaLike>(),
615
- ): boolean {
576
+ function isComplexSchema(schema: unknown, seen = new Set<SchemaLike>()): boolean {
616
577
  if (!isSchema(schema) || seen.has(schema)) {
617
578
  return false;
618
579
  }
@@ -624,10 +585,7 @@ function isComplexSchema(
624
585
  return childChildren.length > 0;
625
586
  });
626
587
 
627
- return (
628
- hasNestedComposite ||
629
- children.some(({ schema: child }) => isComplexSchema(child, seen))
630
- );
588
+ return hasNestedComposite || children.some(({ schema: child }) => isComplexSchema(child, seen));
631
589
  }
632
590
 
633
591
  function hasBidirectionalFixtures(fixtures: unknown): boolean {
@@ -638,16 +596,11 @@ function hasBidirectionalFixtures(fixtures: unknown): boolean {
638
596
  return "request" in fixtures && "response" in fixtures;
639
597
  }
640
598
 
641
- function getOperationSource(operation: {
642
- handler?: unknown;
643
- source?: string;
644
- }): string {
599
+ function getOperationSource(operation: { handler?: unknown; source?: string }): string {
645
600
  if (operation.source) {
646
601
  return operation.source;
647
602
  }
648
- return typeof operation.handler === "function"
649
- ? operation.handler.toString()
650
- : "";
603
+ return typeof operation.handler === "function" ? operation.handler.toString() : "";
651
604
  }
652
605
 
653
606
  function lintStealthTransportUsage(provider: {
@@ -660,22 +613,20 @@ function lintStealthTransportUsage(provider: {
660
613
  }
661
614
 
662
615
  const providerLabel = provider.id ? `Provider "${provider.id}"` : "Provider";
663
- return Object.entries(provider.operations).flatMap(
664
- ([operationKey, operation]) => {
665
- const source = getOperationSource(operation);
666
- if (!/\bctx\.stealth\b/.test(source)) {
667
- return [];
668
- }
669
- return [
670
- {
671
- rule: "stealth-config-required",
672
- level: "error" as const,
673
- field: `operations.${operationKey}`,
674
- message: `${providerLabel} operation "${operationKey}" uses ctx.stealth but provider.stealth is not declared.`,
675
- },
676
- ];
677
- },
678
- );
616
+ return Object.entries(provider.operations).flatMap(([operationKey, operation]) => {
617
+ const source = getOperationSource(operation);
618
+ if (!/\bctx\.stealth\b/.test(source)) {
619
+ return [];
620
+ }
621
+ return [
622
+ {
623
+ rule: "stealth-config-required",
624
+ level: "error" as const,
625
+ field: `operations.${operationKey}`,
626
+ message: `${providerLabel} operation "${operationKey}" uses ctx.stealth but provider.stealth is not declared.`,
627
+ },
628
+ ];
629
+ });
679
630
  }
680
631
 
681
632
  function lintCredentialWriteUsage(provider: {
@@ -685,24 +636,22 @@ function lintCredentialWriteUsage(provider: {
685
636
  return [];
686
637
  }
687
638
 
688
- return Object.entries(provider.operations).flatMap(
689
- ([operationKey, operation]) => {
690
- const source = getOperationSource(operation);
691
- if (!/\bctx\.credential\.(?:set|setMany)\s*\(/.test(source)) {
692
- return [];
693
- }
639
+ return Object.entries(provider.operations).flatMap(([operationKey, operation]) => {
640
+ const source = getOperationSource(operation);
641
+ if (!/\bctx\.credential\.(?:set|setMany)\s*\(/.test(source)) {
642
+ return [];
643
+ }
694
644
 
695
- return [
696
- {
697
- rule: "ctx-credential-write-forbidden-in-handler",
698
- level: "error" as const,
699
- field: `operations.${operationKey}.handler`,
700
- message:
701
- "Operation handlers must not mutate credentials; return refreshed credentials from auth.flow.refresh instead.",
702
- },
703
- ];
704
- },
705
- );
645
+ return [
646
+ {
647
+ rule: "ctx-credential-write-forbidden-in-handler",
648
+ level: "error" as const,
649
+ field: `operations.${operationKey}.handler`,
650
+ message:
651
+ "Operation handlers must not mutate credentials; return refreshed credentials from auth.flow.refresh instead.",
652
+ },
653
+ ];
654
+ });
706
655
  }
707
656
 
708
657
  function lintPlaywrightDirectImports(provider: {
@@ -724,9 +673,7 @@ function lintPlaywrightDirectImports(provider: {
724
673
  });
725
674
  }
726
675
 
727
- for (const [filePath, source] of Object.entries(
728
- provider.providerSourceFiles ?? {},
729
- )) {
676
+ for (const [filePath, source] of Object.entries(provider.providerSourceFiles ?? {})) {
730
677
  if (!importPattern.test(source)) {
731
678
  continue;
732
679
  }
@@ -814,15 +761,11 @@ function lintSelfHostedBrowserPatterns(
814
761
  sources.push({ field: "auth.flow", source: provider.authFlowSource });
815
762
  }
816
763
 
817
- for (const [filePath, source] of Object.entries(
818
- provider.providerSourceFiles ?? {},
819
- )) {
764
+ for (const [filePath, source] of Object.entries(provider.providerSourceFiles ?? {})) {
820
765
  sources.push({ field: `sourceFiles.${filePath}`, source });
821
766
  }
822
767
 
823
- for (const [operationKey, operation] of Object.entries(
824
- provider.operations ?? {},
825
- )) {
768
+ for (const [operationKey, operation] of Object.entries(provider.operations ?? {})) {
826
769
  const source = getOperationSource(operation);
827
770
  if (source) {
828
771
  sources.push({
@@ -865,16 +808,14 @@ export function lintOperation(op: {
865
808
  }): LintDiagnostic[] {
866
809
  const diagnostics: LintDiagnostic[] = [];
867
810
  const description = op.description ?? "";
868
- const hasDescriptionKey =
869
- typeof op.descriptionKey === "string" && op.descriptionKey.length > 0;
811
+ const hasDescriptionKey = typeof op.descriptionKey === "string" && op.descriptionKey.length > 0;
870
812
 
871
813
  if (description.trim().length > 0 && !hasDescriptionKey) {
872
814
  diagnostics.push({
873
815
  rule: "operation-description-raw-prose",
874
816
  level: "error",
875
817
  field: "description",
876
- message:
877
- "Operation description must use descriptionKey instead of raw static prose.",
818
+ message: "Operation description must use descriptionKey instead of raw static prose.",
878
819
  });
879
820
  }
880
821
 
@@ -892,21 +833,16 @@ export function lintOperation(op: {
892
833
  rule: "operation-when-to-use-raw-prose",
893
834
  level: "error",
894
835
  field: "whenToUse",
895
- message:
896
- "Operation whenToUse must use whenToUseKeys instead of raw static prose.",
836
+ message: "Operation whenToUse must use whenToUseKeys instead of raw static prose.",
897
837
  });
898
838
  }
899
839
 
900
- if (
901
- (op.whenNotToUse?.length ?? 0) > 0 &&
902
- !(op.whenNotToUseKeys?.length ?? 0)
903
- ) {
840
+ if ((op.whenNotToUse?.length ?? 0) > 0 && !(op.whenNotToUseKeys?.length ?? 0)) {
904
841
  diagnostics.push({
905
842
  rule: "operation-when-not-to-use-raw-prose",
906
843
  level: "error",
907
844
  field: "whenNotToUse",
908
- message:
909
- "Operation whenNotToUse must use whenNotToUseKeys instead of raw static prose.",
845
+ message: "Operation whenNotToUse must use whenNotToUseKeys instead of raw static prose.",
910
846
  });
911
847
  }
912
848
 
@@ -942,14 +878,11 @@ export function lintOperation(op: {
942
878
  rule: "complex-input-has-examples",
943
879
  level: "warn",
944
880
  field: "inputExamples",
945
- message:
946
- "Complex input schemas should provide at least 2 input examples.",
881
+ message: "Complex input schemas should provide at least 2 input examples.",
947
882
  });
948
883
  }
949
884
 
950
- for (const field of uniqueFields(
951
- collectUnmarkedSensitiveFields(op.input, "input"),
952
- )) {
885
+ for (const field of uniqueFields(collectUnmarkedSensitiveFields(op.input, "input"))) {
953
886
  diagnostics.push({
954
887
  rule: "sensitive-field-unmarked",
955
888
  level: "warn",
@@ -958,9 +891,7 @@ export function lintOperation(op: {
958
891
  });
959
892
  }
960
893
 
961
- for (const field of uniqueFields(
962
- collectUnmarkedSensitiveFields(op.output, "output"),
963
- )) {
894
+ for (const field of uniqueFields(collectUnmarkedSensitiveFields(op.output, "output"))) {
964
895
  diagnostics.push({
965
896
  rule: "sensitive-field-unmarked",
966
897
  level: "warn",
@@ -1044,36 +975,35 @@ export function lintProvider(
1044
975
  }
1045
976
 
1046
977
  diagnostics.push(
1047
- ...Object.entries(provider.operations).flatMap(
1048
- ([operationKey, operation]) =>
1049
- [
1050
- ...lintOperation({
1051
- description: operation.description ?? "",
1052
- descriptionKey: operation.descriptionKey,
1053
- whenToUse: operation.whenToUse,
1054
- whenToUseKeys: operation.whenToUseKeys,
1055
- whenNotToUse: operation.whenNotToUse,
1056
- whenNotToUseKeys: operation.whenNotToUseKeys,
1057
- input: operation.input,
1058
- output: operation.output,
1059
- fixtures: operation.fixtures,
1060
- inputExamples: operation.inputExamples,
1061
- derivations: operation.derivations,
1062
- }),
1063
- ...lintPublicSchemaFieldNames(
1064
- provider.id,
1065
- operationKey,
1066
- operation.input,
1067
- operation.output,
1068
- provider.meta?.contract?.publicSchemaFieldNames === "normalized",
1069
- ),
1070
- ].map((diagnostic) => ({
1071
- ...diagnostic,
1072
- field: diagnostic.field
1073
- ? `operations.${operationKey}.${diagnostic.field}`
1074
- : `operations.${operationKey}`,
1075
- message: `[${operationKey}] ${diagnostic.message}`,
1076
- })),
978
+ ...Object.entries(provider.operations).flatMap(([operationKey, operation]) =>
979
+ [
980
+ ...lintOperation({
981
+ description: operation.description ?? "",
982
+ descriptionKey: operation.descriptionKey,
983
+ whenToUse: operation.whenToUse,
984
+ whenToUseKeys: operation.whenToUseKeys,
985
+ whenNotToUse: operation.whenNotToUse,
986
+ whenNotToUseKeys: operation.whenNotToUseKeys,
987
+ input: operation.input,
988
+ output: operation.output,
989
+ fixtures: operation.fixtures,
990
+ inputExamples: operation.inputExamples,
991
+ derivations: operation.derivations,
992
+ }),
993
+ ...lintPublicSchemaFieldNames(
994
+ provider.id,
995
+ operationKey,
996
+ operation.input,
997
+ operation.output,
998
+ provider.meta?.contract?.publicSchemaFieldNames === "normalized",
999
+ ),
1000
+ ].map((diagnostic) => ({
1001
+ ...diagnostic,
1002
+ field: diagnostic.field
1003
+ ? `operations.${operationKey}.${diagnostic.field}`
1004
+ : `operations.${operationKey}`,
1005
+ message: `[${operationKey}] ${diagnostic.message}`,
1006
+ })),
1077
1007
  ),
1078
1008
  );
1079
1009
 
package/src/provider.ts CHANGED
@@ -3,7 +3,7 @@ export {
3
3
  credentialsAuthChallenge,
4
4
  createAuthFlowHelpers,
5
5
  defineCredentialsAuth,
6
- } from "./auth";
6
+ } from "./auth.js";
7
7
  export type {
8
8
  CredentialsAuthChallengeDefinition,
9
9
  CredentialsAuthChallengeRequest,
@@ -16,8 +16,8 @@ export type {
16
16
  CredentialsAuthLoginResult,
17
17
  DefineCredentialsAuthOptions,
18
18
  DefinedCredentialsAuth,
19
- } from "./auth";
20
- export { createFormCeremony } from "./ceremonies";
19
+ } from "./auth.js";
20
+ export { createFormCeremony } from "./ceremonies/index.js";
21
21
  export {
22
22
  assertFreshProviderChoiceIssuedAt,
23
23
  createProviderChoiceToken,
@@ -25,7 +25,7 @@ export {
25
25
  type ProviderChoiceTokenErrorReason,
26
26
  type ProviderChoiceTokenPayload,
27
27
  parseProviderChoiceToken,
28
- } from "./choice-token";
28
+ } from "./choice-token.js";
29
29
  export {
30
30
  centered,
31
31
  delayed,
@@ -34,7 +34,7 @@ export {
34
34
  defineProvider,
35
35
  defineSmsOtpMatcher,
36
36
  every,
37
- } from "./define";
37
+ } from "./define.js";
38
38
  export {
39
39
  AuthError,
40
40
  isProviderError,
@@ -44,18 +44,18 @@ export {
44
44
  SessionExpiredError,
45
45
  TransportError,
46
46
  ValidationError,
47
- } from "./errors";
47
+ } from "./errors.js";
48
48
  export {
49
49
  getProviderLocalePath,
50
50
  providerLocaleKey,
51
51
  qualifyProviderLocaleKey,
52
- } from "./i18n";
52
+ } from "./i18n/index.js";
53
53
  export {
54
54
  type CreateProviderChoiceContextOptions,
55
55
  createProviderChoiceContext,
56
56
  createTestProviderChoiceContext,
57
57
  PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV,
58
- } from "./runtime/choice";
58
+ } from "./runtime/choice.js";
59
59
  export {
60
60
  APIFUSE_DESCRIPTION_KEY_META_KEY,
61
61
  APIFUSE_REDACTION_MARKER,
@@ -72,7 +72,7 @@ export {
72
72
  type SensitivePath,
73
73
  sensitive,
74
74
  z,
75
- } from "./schema";
75
+ } from "./schema.js";
76
76
  export type {
77
77
  AuthAbortData,
78
78
  AuthAbortRetry,
@@ -115,6 +115,7 @@ export type {
115
115
  ProviderChoiceParseOptions,
116
116
  ProviderContext,
117
117
  ProviderDefinition,
118
+ ProviderDeploymentOverrides,
118
119
  ProviderLocale,
119
120
  ProviderLocaleKey,
120
121
  ProviderLocaleKeyInput,
@@ -133,11 +134,11 @@ export type {
133
134
  StateNamespaceOptions,
134
135
  StateValue,
135
136
  StateWriteOptions,
136
- } from "./types";
137
+ } from "./types.js";
137
138
  export {
138
139
  HttpRetryAfterPolicy,
139
140
  HttpRetryDelayStrategy,
140
141
  HttpRetryJitter,
141
142
  HttpRetryPreset,
142
143
  HttpRetryUnsafeMethodPolicy,
143
- } from "./types";
144
+ } from "./types.js";
@@ -1,6 +1,6 @@
1
1
  import type { ZodType } from "zod";
2
2
 
3
- import type { LintDiagnostic } from "./lint";
3
+ import type { LintDiagnostic } from "./lint.js";
4
4
 
5
5
  type SchemaLike = ZodType & {
6
6
  def?: Record<string, unknown>;
@@ -55,8 +55,7 @@ function isSchemaRecord(value: unknown): value is Record<string, SchemaLike> {
55
55
  }
56
56
 
57
57
  function getObjectShape(schema: SchemaLike): Record<string, SchemaLike> {
58
- const rawShape =
59
- typeof schema.shape === "function" ? schema.shape() : schema.shape;
58
+ const rawShape = typeof schema.shape === "function" ? schema.shape() : schema.shape;
60
59
  if (isSchemaRecord(rawShape)) {
61
60
  return rawShape;
62
61
  }
@@ -69,10 +68,7 @@ function getObjectShape(schema: SchemaLike): Record<string, SchemaLike> {
69
68
  return isSchemaRecord(defShape) ? defShape : {};
70
69
  }
71
70
 
72
- function appendSchemaChildren(
73
- children: SchemaLike[],
74
- value: unknown,
75
- ): SchemaLike[] {
71
+ function appendSchemaChildren(children: SchemaLike[], value: unknown): SchemaLike[] {
76
72
  if (isSchema(value)) {
77
73
  children.push(value);
78
74
  return children;
@@ -183,26 +179,14 @@ function collectPublicSchemaFieldDiagnostics(
183
179
  });
184
180
  }
185
181
  diagnostics.push(
186
- ...collectPublicSchemaFieldDiagnostics(
187
- providerId,
188
- operationId,
189
- child,
190
- fieldPath,
191
- seen,
192
- ),
182
+ ...collectPublicSchemaFieldDiagnostics(providerId, operationId, child, fieldPath, seen),
193
183
  );
194
184
  }
195
185
 
196
186
  for (const child of getTransparentChildSchemas(schema)) {
197
187
  const childPath = schema.element === child ? `${basePath}[]` : basePath;
198
188
  diagnostics.push(
199
- ...collectPublicSchemaFieldDiagnostics(
200
- providerId,
201
- operationId,
202
- child,
203
- childPath,
204
- seen,
205
- ),
189
+ ...collectPublicSchemaFieldDiagnostics(providerId, operationId, child, childPath, seen),
206
190
  );
207
191
  }
208
192
 
@@ -221,17 +205,7 @@ export function lintPublicSchemaFieldNames(
221
205
  }
222
206
 
223
207
  return [
224
- ...collectPublicSchemaFieldDiagnostics(
225
- providerId,
226
- operationId,
227
- input,
228
- "input",
229
- ),
230
- ...collectPublicSchemaFieldDiagnostics(
231
- providerId,
232
- operationId,
233
- output,
234
- "output",
235
- ),
208
+ ...collectPublicSchemaFieldDiagnostics(providerId, operationId, input, "input"),
209
+ ...collectPublicSchemaFieldDiagnostics(providerId, operationId, output, "output"),
236
210
  ];
237
211
  }
@@ -1,4 +1,4 @@
1
- import { unwrapEnvelope } from "../utils/parse";
1
+ import { unwrapEnvelope } from "../utils/parse.js";
2
2
 
3
3
  function getResultCode(raw: unknown): string | undefined {
4
4
  if (!raw || typeof raw !== "object") {
@@ -33,10 +33,7 @@ export function checkResultCode(
33
33
  * Replace placeholder values with null
34
34
  * e.g., nullIfPlaceholder('해당없음', ['해당없음', '-', '']) → null
35
35
  */
36
- export function nullIfPlaceholder(
37
- v: unknown,
38
- patterns: string[],
39
- ): unknown | null {
36
+ export function nullIfPlaceholder(v: unknown, patterns: string[]): unknown | null {
40
37
  if (v === null || v === undefined) {
41
38
  return null;
42
39
  }
@@ -1,5 +1,5 @@
1
- import { ContextAccessError } from "../errors";
2
- import { createAuthFlowHelpers } from "../auth";
1
+ import { ContextAccessError } from "../errors.js";
2
+ import { createAuthFlowHelpers } from "../auth.js";
3
3
  import type {
4
4
  ContextScratchpad,
5
5
  EnvContext,
@@ -7,8 +7,8 @@ import type {
7
7
  HttpClient,
8
8
  StealthClient,
9
9
  SttContext,
10
- } from "../types";
11
- import { createUnsupportedSttClient } from "./stt";
10
+ } from "../types.js";
11
+ import { createUnsupportedSttClient } from "./stt.js";
12
12
 
13
13
  function normalizeAllowedKeys(allowedKeys: string[]): Set<string> {
14
14
  return new Set(allowedKeys.filter((key) => key.trim().length > 0));
@@ -16,9 +16,7 @@ function normalizeAllowedKeys(allowedKeys: string[]): Set<string> {
16
16
 
17
17
  function assertAllowedKey(allowedKeys: Set<string>, key: string): void {
18
18
  if (!allowedKeys.has(key)) {
19
- throw new ContextAccessError(
20
- `Context key "${key}" is not declared in context.keys.`,
21
- );
19
+ throw new ContextAccessError(`Context key "${key}" is not declared in context.keys.`);
22
20
  }
23
21
  }
24
22