@apifuse/provider-sdk 2.2.0-beta.61 → 2.2.0-beta.63

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 (258) hide show
  1. package/AUTHORING.md +268 -9
  2. package/CHANGELOG.md +8 -0
  3. package/README.md +1 -0
  4. package/bin/apifuse-check.ts +84 -2
  5. package/bin/apifuse-dev.ts +11 -31
  6. package/bin/apifuse-migrate-deployment.ts +200 -0
  7. package/bin/apifuse-pack-check.ts +11 -4
  8. package/bin/apifuse-pack-types.ts +191 -4
  9. package/bin/apifuse-record.ts +44 -32
  10. package/bin/apifuse-test.ts +3 -1
  11. package/dist/cli/commands.d.ts +1 -1
  12. package/dist/cli/commands.js +11 -0
  13. package/dist/cli/deployment-intent.d.ts +178 -0
  14. package/dist/cli/deployment-intent.js +277 -0
  15. package/dist/cli/migrate-deployment-intent.d.ts +132 -0
  16. package/dist/cli/migrate-deployment-intent.js +1552 -0
  17. package/dist/cli/migrate-provider-shape.d.ts +5 -1
  18. package/dist/cli/migrate-provider-shape.js +4 -2
  19. package/dist/cli/resolver-runtime.d.ts +21 -0
  20. package/dist/cli/resolver-runtime.js +31 -0
  21. package/dist/define.d.ts +3 -0
  22. package/dist/define.js +5 -0
  23. package/dist/dev.d.ts +3 -1
  24. package/dist/dev.js +6 -1
  25. package/dist/engine.d.ts +35 -1
  26. package/dist/engine.js +21 -2
  27. package/dist/error-resolution.d.ts +1 -0
  28. package/dist/error-resolution.js +54 -0
  29. package/dist/errors.d.ts +39 -1
  30. package/dist/errors.js +50 -0
  31. package/dist/handle-meta.d.ts +18 -2
  32. package/dist/handle-meta.js +30 -2
  33. package/dist/handle.d.ts +33 -12
  34. package/dist/handle.js +69 -24
  35. package/dist/i18n/error-messages.d.ts +86 -0
  36. package/dist/i18n/error-messages.js +192 -0
  37. package/dist/i18n/index.d.ts +1 -0
  38. package/dist/i18n/index.js +1 -0
  39. package/dist/i18n/keys.d.ts +12 -0
  40. package/dist/i18n/keys.js +76 -5
  41. package/dist/index.d.ts +10 -2
  42. package/dist/index.js +9 -1
  43. package/dist/lint.d.ts +10 -0
  44. package/dist/lint.js +440 -57
  45. package/dist/provider.d.ts +7 -5
  46. package/dist/provider.js +4 -2
  47. package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
  48. package/dist/runtime/browser-telemetry-binding.js +83 -0
  49. package/dist/runtime/browser-telemetry.d.ts +76 -0
  50. package/dist/runtime/browser-telemetry.js +165 -0
  51. package/dist/runtime/browser.d.ts +3 -0
  52. package/dist/runtime/browser.js +208 -47
  53. package/dist/runtime/cache-telemetry.d.ts +71 -0
  54. package/dist/runtime/cache-telemetry.js +177 -0
  55. package/dist/runtime/cache.js +67 -7
  56. package/dist/runtime/capability-response.d.ts +3 -0
  57. package/dist/runtime/capability-response.js +56 -0
  58. package/dist/runtime/capability-telemetry.d.ts +46 -0
  59. package/dist/runtime/capability-telemetry.js +68 -0
  60. package/dist/runtime/diagnostic-env.d.ts +3 -0
  61. package/dist/runtime/diagnostic-env.js +10 -1
  62. package/dist/runtime/engine-mode.d.ts +74 -0
  63. package/dist/runtime/engine-mode.js +152 -0
  64. package/dist/runtime/handle.js +15 -10
  65. package/dist/runtime/http-telemetry-binding.d.ts +10 -0
  66. package/dist/runtime/http-telemetry-binding.js +152 -0
  67. package/dist/runtime/http-telemetry-guard.d.ts +16 -0
  68. package/dist/runtime/http-telemetry-guard.js +202 -0
  69. package/dist/runtime/http-telemetry.d.ts +104 -0
  70. package/dist/runtime/http-telemetry.js +190 -0
  71. package/dist/runtime/http.d.ts +31 -0
  72. package/dist/runtime/http.js +356 -174
  73. package/dist/runtime/instrumentation.js +92 -13
  74. package/dist/runtime/ocr-telemetry.d.ts +82 -0
  75. package/dist/runtime/ocr-telemetry.js +192 -0
  76. package/dist/runtime/ocr.js +30 -8
  77. package/dist/runtime/request-telemetry.d.ts +2 -0
  78. package/dist/runtime/request-telemetry.js +2 -1
  79. package/dist/runtime/resolver-runtime-options.d.ts +14 -0
  80. package/dist/runtime/resolver-runtime-options.js +33 -0
  81. package/dist/runtime/resolver-shared.d.ts +3 -2
  82. package/dist/runtime/resolver-shared.js +4 -4
  83. package/dist/runtime/resolver-telemetry.d.ts +1 -0
  84. package/dist/runtime/resolver-telemetry.js +1 -1
  85. package/dist/runtime/resolver-vendors/browser.d.ts +2 -0
  86. package/dist/runtime/resolver-vendors/browser.js +46 -0
  87. package/dist/runtime/resolver-vendors/hosts.d.ts +21 -0
  88. package/dist/runtime/resolver-vendors/hosts.js +35 -0
  89. package/dist/runtime/resolver-vendors/hypersolutions.js +2 -2
  90. package/dist/runtime/resolver-vendors/types.d.ts +5 -4
  91. package/dist/runtime/resolver.d.ts +4 -1
  92. package/dist/runtime/resolver.js +46 -13
  93. package/dist/runtime/state-telemetry.d.ts +79 -0
  94. package/dist/runtime/state-telemetry.js +194 -0
  95. package/dist/runtime/state.d.ts +3 -0
  96. package/dist/runtime/state.js +26 -7
  97. package/dist/runtime/stealth-cookies.d.ts +5 -1
  98. package/dist/runtime/stealth-cookies.js +21 -1
  99. package/dist/runtime/stealth-owned-headers.d.ts +26 -0
  100. package/dist/runtime/stealth-owned-headers.js +37 -0
  101. package/dist/runtime/stealth-telemetry.d.ts +92 -0
  102. package/dist/runtime/stealth-telemetry.js +179 -0
  103. package/dist/runtime/stealth.d.ts +4 -1
  104. package/dist/runtime/stealth.js +228 -85
  105. package/dist/runtime/stt-telemetry.d.ts +77 -0
  106. package/dist/runtime/stt-telemetry.js +176 -0
  107. package/dist/runtime/stt.js +15 -6
  108. package/dist/server/error-stack-frames.d.ts +35 -0
  109. package/dist/server/error-stack-frames.js +219 -0
  110. package/dist/server/index.d.ts +9 -0
  111. package/dist/server/index.js +5 -0
  112. package/dist/server/sdk-version.d.ts +3 -0
  113. package/dist/server/sdk-version.js +19 -0
  114. package/dist/server/self-test.js +1 -18
  115. package/dist/server/sensitive-values.d.ts +1 -1
  116. package/dist/server/sensitive-values.js +9 -0
  117. package/dist/server/serve-implementation.d.ts +53 -2
  118. package/dist/server/serve-implementation.js +369 -123
  119. package/dist/server/types.d.ts +1 -0
  120. package/dist/server/types.js +7 -0
  121. package/dist/stateful/stateful-provider-owner-forwarder.js +22 -0
  122. package/dist/stateful/stateful-provider-runtime-context.d.ts +3 -0
  123. package/dist/stateful/stateful-provider-runtime-context.js +1 -0
  124. package/dist/types.d.ts +94 -1
  125. package/package.json +6 -1
  126. package/src/cli/commands.ts +14 -0
  127. package/src/cli/deployment-intent.ts +364 -0
  128. package/src/cli/migrate-deployment-intent.ts +1908 -0
  129. package/src/cli/migrate-provider-shape.ts +10 -4
  130. package/src/cli/resolver-runtime.ts +72 -0
  131. package/src/define.ts +13 -0
  132. package/src/dev.ts +9 -2
  133. package/src/engine.ts +38 -2
  134. package/src/error-resolution.ts +58 -0
  135. package/src/errors.ts +77 -1
  136. package/src/handle-meta.ts +39 -4
  137. package/src/handle.ts +121 -38
  138. package/src/i18n/error-messages.ts +255 -0
  139. package/src/i18n/index.ts +1 -0
  140. package/src/i18n/keys.ts +80 -6
  141. package/src/index.ts +91 -0
  142. package/src/lint.ts +552 -57
  143. package/src/provider.ts +20 -0
  144. package/src/runtime/browser-telemetry-binding.ts +92 -0
  145. package/src/runtime/browser-telemetry.ts +289 -0
  146. package/src/runtime/browser.ts +249 -65
  147. package/src/runtime/cache-telemetry.ts +247 -0
  148. package/src/runtime/cache.ts +68 -17
  149. package/src/runtime/capability-response.ts +53 -0
  150. package/src/runtime/capability-telemetry.ts +101 -0
  151. package/src/runtime/diagnostic-env.ts +11 -1
  152. package/src/runtime/engine-mode.ts +233 -0
  153. package/src/runtime/handle.ts +20 -10
  154. package/src/runtime/http-telemetry-binding.ts +162 -0
  155. package/src/runtime/http-telemetry-guard.ts +208 -0
  156. package/src/runtime/http-telemetry.ts +292 -0
  157. package/src/runtime/http.ts +457 -204
  158. package/src/runtime/instrumentation.ts +105 -16
  159. package/src/runtime/ocr-telemetry.ts +308 -0
  160. package/src/runtime/ocr.ts +109 -74
  161. package/src/runtime/request-telemetry.ts +2 -1
  162. package/src/runtime/resolver-runtime-options.ts +50 -0
  163. package/src/runtime/resolver-shared.ts +9 -4
  164. package/src/runtime/resolver-telemetry.ts +1 -1
  165. package/src/runtime/resolver-vendors/browser.ts +65 -7
  166. package/src/runtime/resolver-vendors/hosts.ts +43 -0
  167. package/src/runtime/resolver-vendors/hypersolutions.ts +2 -2
  168. package/src/runtime/resolver-vendors/types.ts +5 -4
  169. package/src/runtime/resolver.ts +64 -21
  170. package/src/runtime/state-telemetry.ts +298 -0
  171. package/src/runtime/state.ts +46 -45
  172. package/src/runtime/stealth-cookies.ts +24 -1
  173. package/src/runtime/stealth-owned-headers.ts +41 -0
  174. package/src/runtime/stealth-telemetry.ts +304 -0
  175. package/src/runtime/stealth.ts +355 -150
  176. package/src/runtime/stt-telemetry.ts +282 -0
  177. package/src/runtime/stt.ts +93 -71
  178. package/src/server/error-stack-frames.ts +214 -0
  179. package/src/server/index.ts +66 -0
  180. package/src/server/sdk-version.ts +22 -0
  181. package/src/server/self-test.ts +1 -21
  182. package/src/server/sensitive-values.ts +14 -0
  183. package/src/server/serve-implementation.ts +601 -157
  184. package/src/server/types.ts +7 -0
  185. package/src/stateful/stateful-provider-owner-forwarder.ts +23 -0
  186. package/src/stateful/stateful-provider-runtime-context.ts +4 -0
  187. package/src/types.ts +99 -1
  188. package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +0 -6
  189. package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +0 -3
  190. package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +0 -10
  191. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-a.ts.txt +0 -3
  192. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-b.ts.txt +0 -3
  193. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-barrel.ts.txt +0 -2
  194. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-index.ts.txt +0 -3
  195. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-computed.ts.txt +0 -6
  196. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-a.ts.txt +0 -1
  197. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-b.ts.txt +0 -1
  198. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-index.ts.txt +0 -3
  199. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-barrel.ts.txt +0 -7
  200. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-catalog.ts.txt +0 -19
  201. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-docs.ts.txt +0 -6
  202. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-index.ts.txt +0 -3
  203. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-stores.ts.txt +0 -8
  204. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-indirect-config.ts.txt +0 -5
  205. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-nonstatic.ts.txt +0 -4
  206. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-package-index.ts.txt +0 -3
  207. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-index.ts.txt +0 -3
  208. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-leaf.ts.txt +0 -10
  209. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-one.ts.txt +0 -1
  210. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-two.ts.txt +0 -1
  211. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-index.ts.txt +0 -3
  212. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-one.ts.txt +0 -6
  213. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-two.ts.txt +0 -6
  214. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-mixed-index.ts.txt +0 -14
  215. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-registry.ts.txt +0 -3
  216. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-barrel.ts.txt +0 -2
  217. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-index.ts.txt +0 -3
  218. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-leaf.ts.txt +0 -3
  219. package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +0 -8
  220. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-hoisted-array-spread.ts.txt +0 -15
  221. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-imported-array-spread.ts.txt +0 -9
  222. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-kebab-operation-id.ts.txt +0 -17
  223. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +0 -5
  224. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-mixed-array-spread.ts.txt +0 -24
  225. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +0 -16
  226. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-snake-operation-id.ts.txt +0 -21
  227. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-duplicate-provider.ts.txt +0 -11
  228. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-id-unresolved.ts.txt +0 -7
  229. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +0 -3
  230. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-many.ts.txt +0 -18
  231. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-one.ts.txt +0 -13
  232. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +0 -31
  233. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +0 -11
  234. package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +0 -11
  235. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +0 -11
  236. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +0 -21
  237. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +0 -11
  238. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +0 -14
  239. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-en.json +0 -1
  240. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ja.json +0 -1
  241. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ko.json +0 -1
  242. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-existing-operation-namespace-en.json +0 -8
  243. package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +0 -7
  244. package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +0 -6
  245. package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +0 -7
  246. package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +0 -6
  247. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-binding-ambiguous.ts.txt +0 -12
  248. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported-other.ts.txt +0 -7
  249. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported.ts.txt +0 -5
  250. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-key-ambiguous.ts.txt +0 -19
  251. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-shorthand.ts.txt +0 -9
  252. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-typed.ts.txt +0 -11
  253. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-unrelated.ts.txt +0 -13
  254. package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +0 -7
  255. package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +0 -7
  256. package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +0 -15
  257. package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +0 -4
  258. package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +0 -12
@@ -40,7 +40,11 @@ export type ProviderShapeKind =
40
40
  | "single-phase-default-export"
41
41
  /** `const p = defineProvider({ ..., operations }); export default p;` */
42
42
  | "single-phase-variable-export"
43
- /** `const p = defineProvider({ ..., operations }); export default { ...p, deployment };` */
43
+ /**
44
+ * `const p = defineProvider({ ..., operations }); export default { ...p, extra };`
45
+ * — extras stay on the spread export; a `deployment` extra is a legacy
46
+ * surface that `apifuse migrate-deployment` hoists into the declaration.
47
+ */
44
48
  | "single-phase-variable-spread-export"
45
49
  /** Already `const b = defineProvider(...); export default b({ operations })` */
46
50
  | "two-phase";
@@ -221,7 +225,7 @@ type ShapeClassification =
221
225
  /** Variable the declaration is currently bound to, when it is bound. */
222
226
  readonly variableName?: string;
223
227
  readonly variableStatement?: TS.VariableStatement;
224
- /** Extra properties on a `{ ...provider, deployment }` default export. */
228
+ /** Extra properties on a `{ ...provider, ...extras }` default export. */
225
229
  readonly spreadExportExtras?: string;
226
230
  }
227
231
  | { readonly status: "skipped"; readonly reason: string };
@@ -360,7 +364,7 @@ function defaultExportCallsBuilder(
360
364
  * resolves to a builder-call result. Covers the three migrated layouts —
361
365
  * `export default buildProvider({...})`, an intermediate
362
366
  * `const provider = buildProvider({...}); export default provider;`, and the
363
- * spread export `export default { ...provider, deployment }` over such a
367
+ * spread export `export default { ...provider, ...extras }` over such a
364
368
  * binding. Without the latter two, re-running the transform on its own
365
369
  * spread-shape output reports "ambiguous" instead of "unchanged", which
366
370
  * breaks idempotency for repeated fan-out runs.
@@ -549,7 +553,9 @@ function rewriteDefaultExport(
549
553
  }
550
554
 
551
555
  // Spread export: re-introduce the provider binding so the extra properties
552
- // (currently `deployment`) still spread over a built provider.
556
+ // (e.g. `healthAccountSeedInputs`, or a legacy `deployment` that
557
+ // `apifuse migrate-deployment` later hoists) still spread over a built
558
+ // provider.
553
559
  const providerName = shape.variableName ?? "provider";
554
560
  const extras = shape.spreadExportExtras ?? "";
555
561
  const rebuilt =
@@ -0,0 +1,72 @@
1
+ import {
2
+ compileProcessDiagnosticSensitiveValues,
3
+ createDiagnosticRedactor,
4
+ } from "../runtime/diagnostic-redactor.js";
5
+ import {
6
+ createResolverClientFromEnv,
7
+ createUnsupportedResolverClient,
8
+ } from "../runtime/resolver.js";
9
+ import {
10
+ createResolverRuntimeOptions,
11
+ resolveNativeProxyPolicy,
12
+ } from "../runtime/resolver-runtime-options.js";
13
+ import { ResolverTelemetryCollector } from "../runtime/resolver-telemetry.js";
14
+ import { collectStaticDiagnosticSensitiveValues } from "../server/sensitive-values.js";
15
+ import { getStealthProfile } from "../stealth/profiles.js";
16
+ import type { ProviderCache, ProviderDefinition, ResolverContext } from "../types.js";
17
+
18
+ export interface CliResolverRuntime {
19
+ readonly resolver: ResolverContext;
20
+ /** Per-context sink; `toLogPayload()` is the `resolver` sibling of the server request log. */
21
+ readonly resolverTelemetry: ResolverTelemetryCollector;
22
+ /**
23
+ * Extend the collector's redaction with values learned after construction (request-scoped
24
+ * `sensitiveParams` the recorder captures); the collector redacts at record time, before it
25
+ * truncates, so values must be registered before the vendor call that may echo them.
26
+ */
27
+ readonly registerSensitiveValues: (values: readonly string[]) => void;
28
+ }
29
+
30
+ /**
31
+ * Resolver chain for the CLI helper contexts (`apifuse record`, the `apifuse dev` helper), built
32
+ * like a server request scope: engine-owned solver keys, the CDP pool URL, and the resolver
33
+ * timeout come from the process environment, the runtime options come from the shared builder,
34
+ * and every vendor invocation lands in a collector redacted with the provider's static sensitive
35
+ * inventory. A CLI context has no server-owned identity scope and no proxy telemetry.
36
+ */
37
+ export function createCliResolverRuntime(
38
+ provider: ProviderDefinition,
39
+ cache: ProviderCache,
40
+ ): CliResolverRuntime {
41
+ const sensitiveValues = createDiagnosticRedactor(
42
+ [],
43
+ compileProcessDiagnosticSensitiveValues(collectStaticDiagnosticSensitiveValues(provider)),
44
+ );
45
+ const resolverTelemetry = new ResolverTelemetryCollector({ redact: sensitiveValues.redact });
46
+ const registerSensitiveValues = (values: readonly string[]) => sensitiveValues.add(values);
47
+ if (!provider.resolver) {
48
+ return {
49
+ resolver: createUnsupportedResolverClient("Provider does not declare resolver capability"),
50
+ resolverTelemetry,
51
+ registerSensitiveValues,
52
+ };
53
+ }
54
+ const stealthProfile = provider.stealth ? getStealthProfile(provider.stealth) : undefined;
55
+ return {
56
+ resolver: createResolverClientFromEnv(
57
+ provider.resolver,
58
+ process.env,
59
+ createResolverRuntimeOptions(
60
+ provider,
61
+ cache,
62
+ undefined,
63
+ resolveNativeProxyPolicy(provider),
64
+ { upstream: { proxy: provider.proxy } },
65
+ stealthProfile,
66
+ resolverTelemetry,
67
+ ),
68
+ ),
69
+ resolverTelemetry,
70
+ registerSensitiveValues,
71
+ };
72
+ }
package/src/define.ts CHANGED
@@ -587,6 +587,9 @@ export interface ProviderDeclaration {
587
587
  * provider definition. The SDK types this field but does not deep-validate
588
588
  * it — the APIFuse registry builder owns deployment validation and
589
589
  * resolves omitted fields against the runtime deployment profiles.
590
+ *
591
+ * This is the only authored deployment surface (no standalone
592
+ * `deploy.ts`); declare only the fields that differ from the profile.
590
593
  */
591
594
  deployment?: ProviderDeploymentOverrides;
592
595
  /** Declares the HTTP capability binding. A bare object states use without configuration. */
@@ -949,6 +952,16 @@ function validateProviderProxy(config: {
949
952
  secrets?: ProviderSecretDeclaration[];
950
953
  }): void {
951
954
  for (const secret of config.secrets ?? []) {
955
+ if (
956
+ secret.issuer !== undefined &&
957
+ secret.issuer !== "apifuse" &&
958
+ secret.issuer !== "contributor"
959
+ ) {
960
+ throw new ValidationError(
961
+ `Provider "${config.id}" secret "${secret.name}" has invalid issuer "${String(secret.issuer)}"`,
962
+ { fix: `Set issuer to "apifuse" or "contributor", or omit it.` },
963
+ );
964
+ }
952
965
  const engineName = engineOwnedResolverCredentialTarget(secret.name);
953
966
  if (engineName !== undefined) {
954
967
  throw new ValidationError(
package/src/dev.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { serve } from "./server/serve.js";
2
- import type { ProviderEngine } from "./engine.js";
2
+ import type { ProviderEngine, ProviderEngineMode } from "./engine.js";
3
3
  import type { ProviderDefinition } from "./types.js";
4
4
 
5
5
  export interface DevServerOptions {
@@ -7,6 +7,8 @@ export interface DevServerOptions {
7
7
  sessionDbPath?: string;
8
8
  /** Override the default in-process engine attachment. */
9
9
  engine?: ProviderEngine;
10
+ /** Explicit engine mode; `APIFUSE__ENGINE__MODE` outranks it when both are set. */
11
+ engineMode?: ProviderEngineMode;
10
12
  }
11
13
 
12
14
  export function createDevServer(
@@ -19,7 +21,12 @@ export function createDevServer(
19
21
  start: () => {
20
22
  // Local development has no Redis by default; handles (ADR-0012) need a
21
23
  // state backend, so fall back to memory state when none is configured.
22
- void serve(provider, { port, engine: options?.engine, allowMemoryStateFallback: true });
24
+ void serve(provider, {
25
+ port,
26
+ engine: options?.engine,
27
+ engineMode: options?.engineMode,
28
+ allowMemoryStateFallback: true,
29
+ });
23
30
  console.log(
24
31
  `[apifuse dev] ${provider.id}@${provider.version} running at http://localhost:${port}`,
25
32
  );
package/src/engine.ts CHANGED
@@ -38,6 +38,27 @@ import type {
38
38
  /** Versioned envelope protocol used by out-of-process engine transports. */
39
39
  export const PROVIDER_ENGINE_PROTOCOL_VERSION = "provider-engine.v1" as const;
40
40
 
41
+ /**
42
+ * Environment variable that selects how a provider process attaches its capability
43
+ * bindings. Engine-owned by prefix (`APIFUSE__ENGINE__*`): never declarable as a
44
+ * provider secret and never projected into `ctx.env`.
45
+ *
46
+ * Values are trimmed and case-folded; absent or blank means "unset". An
47
+ * unrecognized value is reported on the `provider_engine_mode` boot event and
48
+ * ignored — a deployment-authored typo must never turn into CrashLoopBackOff.
49
+ */
50
+ export const PROVIDER_ENGINE_MODE_ENV = "APIFUSE__ENGINE__MODE";
51
+
52
+ /**
53
+ * How a provider process attaches its capability bindings: `"in-process"` today,
54
+ * `"remote"` for the authenticated engine (ADR-0011).
55
+ *
56
+ * The union is intentionally open so further lanes (for example a provider hosted
57
+ * inside the engine) can be named without a breaking change. Unknown values are
58
+ * rejected at runtime, not by the type.
59
+ */
60
+ export type ProviderEngineMode = "in-process" | "remote" | (string & {});
61
+
41
62
  /** Credential names owned by the engine and forbidden in provider declarations. */
42
63
  export const ENGINE_OWNED_PROXY_CREDENTIAL_ENV_NAMES = [
43
64
  "APIFUSE__PROXY__SMARTPROXY_APP_KEY",
@@ -262,6 +283,12 @@ export interface ProviderEngineAttachmentInput {
262
283
 
263
284
  /** Attachment boundary shared by in-process development and remote RPC bridges. */
264
285
  export interface ProviderEngine {
286
+ /**
287
+ * Which attachment this engine performs. Lets the server report a truthful
288
+ * mode at boot and compare an explicit engine object against a requested
289
+ * `engineMode`; omit for opaque host engines (reported as `custom`).
290
+ */
291
+ readonly kind?: ProviderEngineMode;
265
292
  attach<TDeclaration extends object = Record<string, unknown>>(
266
293
  input: ProviderEngineAttachmentInput,
267
294
  ): ProviderContext<TDeclaration>;
@@ -348,7 +375,16 @@ function attachInProcess<TDeclaration extends object>(
348
375
  }) as ProviderContext<TDeclaration>;
349
376
  }
350
377
 
351
- /** Local engine attachment; deployed bridges implement the same interface with RPC clients. */
378
+ /**
379
+ * Local engine attachment; deployed bridges implement the same interface with RPC clients.
380
+ *
381
+ * ADR-0011 makes the authenticated remote engine the only attachment, so this one
382
+ * is scheduled for removal — but not deprecated yet: the remote client ships in a
383
+ * later release, and deprecating the only working constructor before its
384
+ * replacement exists would flag every current caller with no fix available. Until
385
+ * then it stays the default, and the server reports each in-process boot as
386
+ * `provider_engine_mode` with `deprecated: true`.
387
+ */
352
388
  export function createInProcessProviderEngine(): ProviderEngine {
353
- return { attach: attachInProcess };
389
+ return { kind: "in-process", attach: attachInProcess };
354
390
  }
@@ -20,6 +20,14 @@ export const SDK_OWNED_PROVIDER_ERROR_CODES = new Set([
20
20
  "refresh_not_supported",
21
21
  "RUNTIME_UNSUPPORTED",
22
22
  "PROVIDER_STATE_UNSUPPORTED",
23
+ // Engine attachment (ADR-0011). Registered here so an engine failure is served
24
+ // as a known SDK code instead of raising a false
25
+ // `unregistered_provider_error_code` signal on a 500.
26
+ "PROVIDER_ENGINE_AUTHENTICATION_FAILED",
27
+ "PROVIDER_ENGINE_PROTOCOL_VERSION_MISMATCH",
28
+ "PROVIDER_ENGINE_UNAVAILABLE",
29
+ "PROVIDER_ENGINE_MODE_UNSUPPORTED",
30
+ "PROVIDER_EGRESS_DENIED",
23
31
  "HANDLE_INVALID",
24
32
  "HANDLE_NOT_FOUND",
25
33
  "HANDLE_EXPIRED",
@@ -59,6 +67,7 @@ export const SDK_OWNED_PROVIDER_ERROR_CODES = new Set([
59
67
  "http_redirect_missing_location",
60
68
  "http_redirect_loop",
61
69
  "transport_invalid_url",
70
+ "http_header_factory_failed",
62
71
  "EGRESS_LEASE_INVALID",
63
72
  "EGRESS_LEASE_BINDING_INVALID",
64
73
  "EGRESS_LEASE_KEY_MISSING",
@@ -86,6 +95,7 @@ export const SDK_OWNED_PROVIDER_ERROR_CODES = new Set([
86
95
  "STATEFUL_FORWARDING_OWNER_FENCE_INVALID",
87
96
  "STATEFUL_FORWARDING_REQUEST_FAILED",
88
97
  "STATEFUL_FORWARDING_CONTEXT_MISSING",
98
+ "STATEFUL_FORWARDING_CONTEXT_INVALID",
89
99
  "STATEFUL_FORWARDING_BAD_RESPONSE",
90
100
  "STATEFUL_INTERNAL_EXECUTOR_NOT_CONFIGURED",
91
101
  "STATEFUL_FILE_FORWARDING_UNSUPPORTED",
@@ -149,9 +159,57 @@ export const SDK_STATUS_MAPPED_PROVIDER_ERROR_CODES: ReadonlyMap<string, Provide
149
159
  ["HANDLE_BUSY", 409],
150
160
  ["UPSTREAM_ERROR", 502],
151
161
  ["BLOCKED", 502],
162
+ // Fleet-consensus provider codes. These are thrown by provider code, not
163
+ // by the SDK, so they are registered here (status mapping) and not in
164
+ // SDK_RUNTIME_OWNED_ERROR_CODES: an operation-declared status still wins,
165
+ // exactly as it does for UPSTREAM_ERROR and BLOCKED above. Registering
166
+ // them stops the fleet from re-declaring the same three rows on every
167
+ // operation, and stops an undeclared throw from being served as 500.
168
+ //
169
+ // A platform-managed upstream service key the upstream refuses. With
170
+ // `auth.mode: "platform-managed"` the caller holds no credential, so 401
171
+ // ("re-authenticate") tells the caller to do something it cannot do, and
172
+ // 502 ("upstream is sick") promises a recovery that will never come. It is
173
+ // a deployment/config defect — the same class as MISSING_SECRET above,
174
+ // which is already an explicit 400 for that reason.
175
+ ["UPSTREAM_AUTH_ERROR", 400],
176
+ // The upstream changed its response shape and the provider cannot
177
+ // normalize it. 502 because the fault is upstream of us, non-retryable
178
+ // because a retry returns the same broken payload.
179
+ ["UPSTREAM_SCHEMA_ERROR", 502],
180
+ // Caller-side bad input rejected by the provider. The minority spellings
181
+ // (INVALID_INPUT / VALIDATION_ERROR / BAD_REQUEST) are deliberately not
182
+ // registered: they migrate to this spelling on the contract track, and
183
+ // registering them here would freeze the divergence.
184
+ ["INVALID_REQUEST", 400],
152
185
  ["OCR_UNAVAILABLE", 503],
153
186
  ["UNSUPPORTED_OCR_BACKEND", 503],
154
187
  ["STT_UNAVAILABLE", 503],
155
188
  ["UNSUPPORTED_STT_BACKEND", 503],
156
189
  ["STATEFUL_FORWARDING_REPLAY_CACHE_FULL", 503],
190
+ // The engine is reachable-in-principle but not now: retryable, so the
191
+ // caller may retry once the engine recovers. Authentication, protocol
192
+ // mismatch, an unsupported mode and denied egress stay unmapped (500) and
193
+ // non-retryable: they are deployment or provider faults that no caller
194
+ // retry can clear, and a retryable 5xx there would turn one bad rollout
195
+ // into gateway-driven load.
196
+ ["PROVIDER_ENGINE_UNAVAILABLE", 503],
157
197
  ]);
198
+
199
+ // Canonical retryability for the fleet-consensus codes registered above.
200
+ //
201
+ // Runtime retryability still resolves as `instance option ?? declared ??
202
+ // false`, so this map changes no served response: an undeclared throw already
203
+ // defaults to false, which is what every entry here says. It exists so the
204
+ // authoring lint can tell a provider that its declared `retryable` contradicts
205
+ // the registered meaning of the code, instead of the fleet quietly shipping two
206
+ // answers for the same code. Only codes whose retryability was fixed as part of
207
+ // registration belong here — do not backfill opinions the SDK never made.
208
+ export const SDK_CANONICAL_ERROR_CODE_RETRYABILITY: ReadonlyMap<string, boolean> = new Map<
209
+ string,
210
+ boolean
211
+ >([
212
+ ["UPSTREAM_AUTH_ERROR", false],
213
+ ["UPSTREAM_SCHEMA_ERROR", false],
214
+ ["INVALID_REQUEST", false],
215
+ ]);
package/src/errors.ts CHANGED
@@ -1,5 +1,6 @@
1
+ import type { ProviderErrorMessageParams } from "./i18n/error-messages.js";
1
2
  import type { ProviderErrorCategory } from "./observability.js";
2
- import type { HttpRedirectFailureReason } from "./types.js";
3
+ import type { HttpRedirectFailureReason, ProviderLocaleKeyInput } from "./types.js";
3
4
 
4
5
  // Versioned, cross-realm brands. `Symbol.for` resolves to the same symbol in
5
6
  // any copy/entrypoint of this SDK major version, so an error created by a
@@ -49,6 +50,25 @@ export type ProviderErrorOptions = {
49
50
  retryable?: boolean;
50
51
  /** Provider-authored, bounded metadata safe for operational logs and error headers. */
51
52
  observability?: ProviderErrorObservability;
53
+ /**
54
+ * Locale catalog key for the client-facing `message`, e.g.
55
+ * `"errors.upstreamSchema.message"`. Resolved at serve time against the
56
+ * provider's `locales/{en,ko,ja}.json` with the caller's `Accept-Language`,
57
+ * falling back to `en` and then to the positional `message`.
58
+ *
59
+ * The positional `message` stays English: it is what `error.message`, cause
60
+ * frames, logs and OTLP attributes carry. Only the response envelope is
61
+ * localized.
62
+ */
63
+ messageKey?: ProviderLocaleKeyInput;
64
+ /** Locale catalog key for the client-facing `fix`. Same resolution as {@link ProviderErrorOptions.messageKey}. */
65
+ fixKey?: ProviderLocaleKeyInput;
66
+ /**
67
+ * Values substituted into `{name}` placeholders of the resolved text.
68
+ * Strings and finite numbers only; string values are scrubbed and length
69
+ * capped before substitution because upstream text routinely lands here.
70
+ */
71
+ params?: ProviderErrorMessageParams;
52
72
  };
53
73
 
54
74
  /**
@@ -98,6 +118,62 @@ export class SDKError extends ProviderError {
98
118
  }
99
119
  }
100
120
 
121
+ /** Raised when the remote provider engine speaks an incompatible protocol version. */
122
+ export class ProviderEngineProtocolVersionError extends SDKError {
123
+ constructor(
124
+ public readonly receivedVersion: unknown,
125
+ public readonly expectedVersion: string,
126
+ ) {
127
+ super(
128
+ `Provider engine protocol version mismatch: expected ${expectedVersion}, received ${String(receivedVersion)}`,
129
+ {
130
+ code: "PROVIDER_ENGINE_PROTOCOL_VERSION_MISMATCH",
131
+ details: { receivedVersion, expectedVersion },
132
+ fix: "Update @apifuse/provider-sdk or use a compatible APIFuse provider engine.",
133
+ },
134
+ );
135
+ this.name = "ProviderEngineProtocolVersionError";
136
+ }
137
+ }
138
+
139
+ /** Raised when the remote provider engine rejects a workspace API key. */
140
+ export class ProviderEngineAuthenticationError extends SDKError {
141
+ constructor(message = "Provider engine authentication failed", options?: ProviderErrorOptions) {
142
+ super(message, {
143
+ code: "PROVIDER_ENGINE_AUTHENTICATION_FAILED",
144
+ fix: "Set APIFUSE__ENGINE__API_KEY to the workspace API key from your APIFuse bounty dashboard.",
145
+ ...options,
146
+ });
147
+ this.name = "ProviderEngineAuthenticationError";
148
+ }
149
+ }
150
+
151
+ /** Raised when the remote engine cannot be reached. There is no local fallback. */
152
+ export class ProviderEngineUnavailableError extends SDKError {
153
+ constructor(message = "The remote APIFuse provider engine is unavailable", cause?: Error) {
154
+ super(message, {
155
+ code: "PROVIDER_ENGINE_UNAVAILABLE",
156
+ retryable: true,
157
+ fix: "Check network access and the provider engine endpoint, then retry.",
158
+ ...(cause ? { cause } : {}),
159
+ });
160
+ this.name = "ProviderEngineUnavailableError";
161
+ }
162
+ }
163
+
164
+ /** Raised when the engine refuses egress outside the workspace's pinned allowlist. */
165
+ export class ProviderEgressDeniedError extends ProviderError {
166
+ constructor(message: string, details?: unknown) {
167
+ super(message, {
168
+ code: "PROVIDER_EGRESS_DENIED",
169
+ retryable: false,
170
+ details,
171
+ fix: "Use a host in the provider's pinned allowedHosts declaration, or request a trusted pin update.",
172
+ });
173
+ this.name = "ProviderEgressDeniedError";
174
+ }
175
+ }
176
+
101
177
  /** Raised when persisted stealth cookies use a store version this SDK cannot read. */
102
178
  export class StealthCookieStoreVersionError extends SDKError {
103
179
  constructor(public readonly version: unknown) {
@@ -12,12 +12,19 @@ export const APIFUSE_HANDLE_META_KEY = "x-apifuse-handle" as const;
12
12
  export type HandleKindType = "cursor" | "draft";
13
13
  export type HandleAccess = "bound" | "public";
14
14
 
15
+ /**
16
+ * Operation key(s) that issue a handle. A single string is the common case; a
17
+ * list names every operation whose output carries the field (for example
18
+ * `search-address` and `reverse-geocode` both issuing `location_token`).
19
+ */
20
+ export type HandleIssuedBy = string | readonly string[];
21
+
15
22
  /** Value stored under {@link APIFUSE_HANDLE_META_KEY} on a handle field. */
16
23
  export interface HandleFieldMeta {
17
24
  readonly kind: string;
18
25
  readonly type: HandleKindType;
19
26
  readonly fieldName: string;
20
- readonly issuedBy?: string;
27
+ readonly issuedBy?: HandleIssuedBy;
21
28
  }
22
29
 
23
30
  /**
@@ -30,12 +37,39 @@ export interface HandleKindDeclaration {
30
37
  readonly type: HandleKindType;
31
38
  readonly fieldName: string;
32
39
  readonly access: HandleAccess;
33
- readonly issuedBy?: string;
40
+ readonly issuedBy?: HandleIssuedBy;
34
41
  }
35
42
 
36
43
  /** Kind names are lowercase letters only so they never fuse with the word body. */
37
44
  export const HANDLE_KIND_NAME_PATTERN = /^[a-z]{2,12}$/;
38
45
 
46
+ /** True for a single operation key or a non-empty list of operation keys. */
47
+ export function isHandleIssuedBy(value: unknown): value is HandleIssuedBy {
48
+ if (typeof value === "string") return true;
49
+ return (
50
+ Array.isArray(value) && value.length > 0 && value.every((entry) => typeof entry === "string")
51
+ );
52
+ }
53
+
54
+ /** Normalizes `issuedBy` to a list of operation keys (empty when undefined). */
55
+ export function handleIssuerList(issuedBy: HandleIssuedBy | undefined): readonly string[] {
56
+ if (issuedBy === undefined) return [];
57
+ return typeof issuedBy === "string" ? [issuedBy] : issuedBy;
58
+ }
59
+
60
+ /**
61
+ * Renders the issuing operation(s) as inline code for error and description
62
+ * text: `` `a` ``, `` `a` or `b` ``, `` `a`, `b`, or `c` ``. Undefined when no
63
+ * issuer is declared.
64
+ */
65
+ export function formatHandleIssuers(issuedBy: HandleIssuedBy | undefined): string | undefined {
66
+ const issuers = handleIssuerList(issuedBy).map((operation) => `\`${operation}\``);
67
+ if (issuers.length === 0) return undefined;
68
+ if (issuers.length === 1) return issuers[0];
69
+ if (issuers.length === 2) return `${issuers[0]} or ${issuers[1]}`;
70
+ return `${issuers.slice(0, -1).join(", ")}, or ${issuers[issuers.length - 1]}`;
71
+ }
72
+
39
73
  export function isHandleFieldMeta(value: unknown): value is HandleFieldMeta {
40
74
  if (typeof value !== "object" || value === null) return false;
41
75
  const record = value as Record<string, unknown>;
@@ -43,7 +77,7 @@ export function isHandleFieldMeta(value: unknown): value is HandleFieldMeta {
43
77
  typeof record.kind === "string" &&
44
78
  (record.type === "cursor" || record.type === "draft") &&
45
79
  typeof record.fieldName === "string" &&
46
- (record.issuedBy === undefined || typeof record.issuedBy === "string")
80
+ (record.issuedBy === undefined || isHandleIssuedBy(record.issuedBy))
47
81
  );
48
82
  }
49
83
 
@@ -53,6 +87,7 @@ export function isHandleFieldMeta(value: unknown): value is HandleFieldMeta {
53
87
  * provider override re-enters the localization rules.
54
88
  */
55
89
  export function handleFieldDescription(meta: Pick<HandleFieldMeta, "issuedBy">): string {
56
- const origin = meta.issuedBy ? ` issued by \`${meta.issuedBy}\`` : "";
90
+ const issuers = formatHandleIssuers(meta.issuedBy);
91
+ const origin = issuers ? ` issued by ${issuers}` : "";
57
92
  return `Opaque handle${origin}. Copy it exactly as returned; do not edit or shorten it.`;
58
93
  }