@apifuse/provider-sdk 2.2.0-beta.62 → 2.2.0-beta.64

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 (261) hide show
  1. package/AUTHORING.md +367 -9
  2. package/CHANGELOG.md +8 -0
  3. package/LICENSE +21 -0
  4. package/README.md +1 -0
  5. package/bin/apifuse-check.ts +84 -2
  6. package/bin/apifuse-dev.ts +11 -31
  7. package/bin/apifuse-migrate-deployment.ts +200 -0
  8. package/bin/apifuse-pack-check.ts +11 -4
  9. package/bin/apifuse-pack-types.ts +187 -4
  10. package/bin/apifuse-record.ts +44 -32
  11. package/bin/apifuse-submit-check.ts +9 -5
  12. package/bin/apifuse-test.ts +3 -1
  13. package/dist/cli/commands.d.ts +1 -1
  14. package/dist/cli/commands.js +11 -0
  15. package/dist/cli/deployment-intent.d.ts +178 -0
  16. package/dist/cli/deployment-intent.js +277 -0
  17. package/dist/cli/migrate-deployment-intent.d.ts +132 -0
  18. package/dist/cli/migrate-deployment-intent.js +1552 -0
  19. package/dist/cli/migrate-provider-shape.d.ts +5 -1
  20. package/dist/cli/migrate-provider-shape.js +4 -2
  21. package/dist/cli/resolver-runtime.d.ts +21 -0
  22. package/dist/cli/resolver-runtime.js +31 -0
  23. package/dist/define.d.ts +3 -0
  24. package/dist/define.js +5 -0
  25. package/dist/dev.d.ts +3 -1
  26. package/dist/dev.js +6 -1
  27. package/dist/engine.d.ts +35 -1
  28. package/dist/engine.js +21 -2
  29. package/dist/error-resolution.d.ts +1 -0
  30. package/dist/error-resolution.js +54 -0
  31. package/dist/errors.d.ts +39 -1
  32. package/dist/errors.js +50 -0
  33. package/dist/handle-meta.d.ts +36 -1
  34. package/dist/handle-meta.js +16 -0
  35. package/dist/handle.d.ts +23 -5
  36. package/dist/handle.js +54 -8
  37. package/dist/health-scenario.d.ts +38 -0
  38. package/dist/i18n/error-messages.d.ts +86 -0
  39. package/dist/i18n/error-messages.js +192 -0
  40. package/dist/i18n/index.d.ts +1 -0
  41. package/dist/i18n/index.js +1 -0
  42. package/dist/i18n/keys.d.ts +12 -0
  43. package/dist/i18n/keys.js +76 -5
  44. package/dist/index.d.ts +11 -3
  45. package/dist/index.js +9 -1
  46. package/dist/lint.d.ts +15 -0
  47. package/dist/lint.js +469 -82
  48. package/dist/provider.d.ts +6 -6
  49. package/dist/provider.js +3 -3
  50. package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
  51. package/dist/runtime/browser-telemetry-binding.js +83 -0
  52. package/dist/runtime/browser-telemetry.d.ts +76 -0
  53. package/dist/runtime/browser-telemetry.js +165 -0
  54. package/dist/runtime/browser.d.ts +3 -0
  55. package/dist/runtime/browser.js +208 -47
  56. package/dist/runtime/cache-telemetry.d.ts +71 -0
  57. package/dist/runtime/cache-telemetry.js +177 -0
  58. package/dist/runtime/cache.js +67 -7
  59. package/dist/runtime/capability-response.d.ts +3 -0
  60. package/dist/runtime/capability-response.js +56 -0
  61. package/dist/runtime/capability-telemetry.d.ts +46 -0
  62. package/dist/runtime/capability-telemetry.js +68 -0
  63. package/dist/runtime/diagnostic-env.d.ts +3 -0
  64. package/dist/runtime/diagnostic-env.js +10 -1
  65. package/dist/runtime/engine-mode.d.ts +74 -0
  66. package/dist/runtime/engine-mode.js +152 -0
  67. package/dist/runtime/handle.js +9 -1
  68. package/dist/runtime/http-telemetry-guard.d.ts +10 -0
  69. package/dist/runtime/http-telemetry-guard.js +62 -10
  70. package/dist/runtime/http.js +141 -35
  71. package/dist/runtime/instrumentation.js +92 -13
  72. package/dist/runtime/ocr-telemetry.d.ts +82 -0
  73. package/dist/runtime/ocr-telemetry.js +192 -0
  74. package/dist/runtime/ocr.js +35 -8
  75. package/dist/runtime/request-telemetry.d.ts +2 -0
  76. package/dist/runtime/request-telemetry.js +2 -1
  77. package/dist/runtime/resolver-runtime-options.d.ts +14 -0
  78. package/dist/runtime/resolver-runtime-options.js +33 -0
  79. package/dist/runtime/resolver-shared.d.ts +3 -2
  80. package/dist/runtime/resolver-shared.js +4 -4
  81. package/dist/runtime/resolver-telemetry.d.ts +1 -0
  82. package/dist/runtime/resolver-telemetry.js +1 -1
  83. package/dist/runtime/resolver-vendors/browser.d.ts +2 -0
  84. package/dist/runtime/resolver-vendors/browser.js +46 -0
  85. package/dist/runtime/resolver-vendors/hosts.d.ts +21 -0
  86. package/dist/runtime/resolver-vendors/hosts.js +35 -0
  87. package/dist/runtime/resolver-vendors/hypersolutions.js +2 -2
  88. package/dist/runtime/resolver-vendors/types.d.ts +5 -4
  89. package/dist/runtime/resolver.d.ts +4 -1
  90. package/dist/runtime/resolver.js +46 -13
  91. package/dist/runtime/state-telemetry.d.ts +79 -0
  92. package/dist/runtime/state-telemetry.js +194 -0
  93. package/dist/runtime/state.d.ts +3 -0
  94. package/dist/runtime/state.js +26 -7
  95. package/dist/runtime/stealth-cookies.d.ts +5 -1
  96. package/dist/runtime/stealth-cookies.js +21 -1
  97. package/dist/runtime/stealth-owned-headers.d.ts +26 -0
  98. package/dist/runtime/stealth-owned-headers.js +37 -0
  99. package/dist/runtime/stealth-telemetry.d.ts +92 -0
  100. package/dist/runtime/stealth-telemetry.js +179 -0
  101. package/dist/runtime/stealth.d.ts +4 -1
  102. package/dist/runtime/stealth.js +228 -85
  103. package/dist/runtime/stt-telemetry.d.ts +77 -0
  104. package/dist/runtime/stt-telemetry.js +176 -0
  105. package/dist/runtime/stt.js +15 -6
  106. package/dist/runtime-boundary-lint.d.ts +132 -0
  107. package/dist/runtime-boundary-lint.js +586 -0
  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 +7 -0
  111. package/dist/server/index.js +4 -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 +51 -2
  118. package/dist/server/serve-implementation.js +337 -90
  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 +123 -1
  125. package/dist/typescript-module.d.ts +39 -0
  126. package/dist/typescript-module.js +72 -0
  127. package/package.json +6 -1
  128. package/src/cli/commands.ts +14 -0
  129. package/src/cli/deployment-intent.ts +364 -0
  130. package/src/cli/migrate-deployment-intent.ts +1908 -0
  131. package/src/cli/migrate-provider-shape.ts +10 -4
  132. package/src/cli/resolver-runtime.ts +72 -0
  133. package/src/define.ts +13 -0
  134. package/src/dev.ts +9 -2
  135. package/src/engine.ts +38 -2
  136. package/src/error-resolution.ts +58 -0
  137. package/src/errors.ts +77 -1
  138. package/src/handle-meta.ts +51 -1
  139. package/src/handle.ts +92 -10
  140. package/src/health-scenario.ts +38 -0
  141. package/src/i18n/error-messages.ts +255 -0
  142. package/src/i18n/index.ts +1 -0
  143. package/src/i18n/keys.ts +80 -6
  144. package/src/index.ts +86 -0
  145. package/src/lint.ts +604 -91
  146. package/src/provider.ts +12 -0
  147. package/src/runtime/browser-telemetry-binding.ts +92 -0
  148. package/src/runtime/browser-telemetry.ts +289 -0
  149. package/src/runtime/browser.ts +249 -65
  150. package/src/runtime/cache-telemetry.ts +247 -0
  151. package/src/runtime/cache.ts +68 -17
  152. package/src/runtime/capability-response.ts +53 -0
  153. package/src/runtime/capability-telemetry.ts +101 -0
  154. package/src/runtime/diagnostic-env.ts +11 -1
  155. package/src/runtime/engine-mode.ts +233 -0
  156. package/src/runtime/handle.ts +9 -1
  157. package/src/runtime/http-telemetry-guard.ts +66 -13
  158. package/src/runtime/http.ts +168 -37
  159. package/src/runtime/instrumentation.ts +105 -16
  160. package/src/runtime/ocr-telemetry.ts +308 -0
  161. package/src/runtime/ocr.ts +114 -74
  162. package/src/runtime/request-telemetry.ts +2 -1
  163. package/src/runtime/resolver-runtime-options.ts +50 -0
  164. package/src/runtime/resolver-shared.ts +9 -4
  165. package/src/runtime/resolver-telemetry.ts +1 -1
  166. package/src/runtime/resolver-vendors/browser.ts +65 -7
  167. package/src/runtime/resolver-vendors/hosts.ts +43 -0
  168. package/src/runtime/resolver-vendors/hypersolutions.ts +2 -2
  169. package/src/runtime/resolver-vendors/types.ts +5 -4
  170. package/src/runtime/resolver.ts +64 -21
  171. package/src/runtime/state-telemetry.ts +298 -0
  172. package/src/runtime/state.ts +46 -45
  173. package/src/runtime/stealth-cookies.ts +24 -1
  174. package/src/runtime/stealth-owned-headers.ts +41 -0
  175. package/src/runtime/stealth-telemetry.ts +304 -0
  176. package/src/runtime/stealth.ts +355 -150
  177. package/src/runtime/stt-telemetry.ts +282 -0
  178. package/src/runtime/stt.ts +93 -71
  179. package/src/runtime-boundary-lint.ts +703 -0
  180. package/src/server/error-stack-frames.ts +214 -0
  181. package/src/server/index.ts +53 -0
  182. package/src/server/sdk-version.ts +22 -0
  183. package/src/server/self-test.ts +1 -21
  184. package/src/server/sensitive-values.ts +14 -0
  185. package/src/server/serve-implementation.ts +569 -108
  186. package/src/server/types.ts +7 -0
  187. package/src/stateful/stateful-provider-owner-forwarder.ts +23 -0
  188. package/src/stateful/stateful-provider-runtime-context.ts +4 -0
  189. package/src/types.ts +128 -1
  190. package/src/typescript-module.ts +100 -0
  191. package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +0 -6
  192. package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +0 -3
  193. package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +0 -10
  194. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-a.ts.txt +0 -3
  195. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-b.ts.txt +0 -3
  196. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-barrel.ts.txt +0 -2
  197. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-ambiguous-index.ts.txt +0 -3
  198. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-computed.ts.txt +0 -6
  199. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-a.ts.txt +0 -1
  200. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-b.ts.txt +0 -1
  201. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-cycle-index.ts.txt +0 -3
  202. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-barrel.ts.txt +0 -7
  203. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-catalog.ts.txt +0 -19
  204. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-docs.ts.txt +0 -6
  205. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-index.ts.txt +0 -3
  206. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-daiso-stores.ts.txt +0 -8
  207. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-indirect-config.ts.txt +0 -5
  208. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-nonstatic.ts.txt +0 -4
  209. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-package-index.ts.txt +0 -3
  210. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-index.ts.txt +0 -3
  211. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-leaf.ts.txt +0 -10
  212. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-one.ts.txt +0 -1
  213. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-reexport-two.ts.txt +0 -1
  214. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-index.ts.txt +0 -3
  215. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-one.ts.txt +0 -6
  216. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-composed-two.ts.txt +0 -6
  217. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-mixed-index.ts.txt +0 -14
  218. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-runtime-registry.ts.txt +0 -3
  219. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-barrel.ts.txt +0 -2
  220. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-index.ts.txt +0 -3
  221. package/src/cli/__tests__/fixtures/migrate-operation-declaration/discovery-star-package-leaf.ts.txt +0 -3
  222. package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +0 -8
  223. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-hoisted-array-spread.ts.txt +0 -15
  224. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-imported-array-spread.ts.txt +0 -9
  225. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-kebab-operation-id.ts.txt +0 -17
  226. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +0 -5
  227. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-mixed-array-spread.ts.txt +0 -24
  228. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +0 -16
  229. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-snake-operation-id.ts.txt +0 -21
  230. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-duplicate-provider.ts.txt +0 -11
  231. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-id-unresolved.ts.txt +0 -7
  232. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +0 -3
  233. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-many.ts.txt +0 -18
  234. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-one-to-one.ts.txt +0 -13
  235. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +0 -31
  236. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +0 -11
  237. package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +0 -11
  238. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +0 -11
  239. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +0 -21
  240. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +0 -11
  241. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +0 -14
  242. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-en.json +0 -1
  243. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ja.json +0 -1
  244. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-canonical-ko.json +0 -1
  245. package/src/cli/__tests__/fixtures/migrate-operation-declaration/locale-existing-operation-namespace-en.json +0 -8
  246. package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +0 -7
  247. package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +0 -6
  248. package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +0 -7
  249. package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +0 -6
  250. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-binding-ambiguous.ts.txt +0 -12
  251. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported-other.ts.txt +0 -7
  252. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-imported.ts.txt +0 -5
  253. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-key-ambiguous.ts.txt +0 -19
  254. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-shorthand.ts.txt +0 -9
  255. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-typed.ts.txt +0 -11
  256. package/src/cli/__tests__/fixtures/migrate-operation-declaration/registry-unrelated.ts.txt +0 -13
  257. package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +0 -7
  258. package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +0 -7
  259. package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +0 -15
  260. package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +0 -4
  261. package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +0 -12
@@ -38,6 +38,7 @@ export declare const OperationRequestSchema: z.ZodObject<{
38
38
  metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
39
39
  externalRef: z.ZodString;
40
40
  }, z.core.$strip>>;
41
+ tenantId: z.ZodOptional<z.ZodString>;
41
42
  headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
42
43
  trace: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
43
44
  }, z.core.$strip>;
@@ -21,6 +21,13 @@ export const OperationRequestSchema = z.object({
21
21
  input: z.record(z.string(), z.unknown()),
22
22
  connectionId: z.string().optional(),
23
23
  connection: OperationConnectionSchema.optional(),
24
+ /**
25
+ * Gateway-asserted principal scope: the organization id for customer
26
+ * subjects, the service-account id for platform service accounts. Absent
27
+ * on direct calls and self-test. Trusted exactly like `connectionId`; it is
28
+ * never derived from caller headers or `input`.
29
+ */
30
+ tenantId: z.string().optional(),
24
31
  headers: z.record(z.string(), z.string()).optional(),
25
32
  trace: z.record(z.string(), z.string()).optional(),
26
33
  });
@@ -145,6 +145,7 @@ function buildForwardingEnvelope(input) {
145
145
  requestId: input.request.requestId,
146
146
  input: input.request.input,
147
147
  connection: metadata.connection,
148
+ ...(metadata.tenantId ? { tenantId: metadata.tenantId } : {}),
148
149
  headers: sanitizeForwardedHeaders(metadata.headers),
149
150
  ...(metadata.trace ? { trace: metadata.trace } : {}),
150
151
  },
@@ -160,12 +161,33 @@ function forwardedMetadata(request) {
160
161
  }
161
162
  const operationRequest = forwardingContext.operationRequest;
162
163
  const connection = OperationConnectionSchema.parse(operationRequest?.connection);
164
+ const tenantId = forwardedTenantId(operationRequest?.tenantId);
163
165
  return {
164
166
  connection,
167
+ ...(tenantId !== undefined ? { tenantId } : {}),
165
168
  ...(operationRequest?.headers ? { headers: operationRequest.headers } : {}),
166
169
  ...(operationRequest?.trace ? { trace: operationRequest.trace } : {}),
167
170
  };
168
171
  }
172
+ /**
173
+ * The runtime context is consumer-supplied and typed `unknown`, and only its
174
+ * `requestId` is guarded on read. A malformed principal scope must fail at the
175
+ * source with a forwarding error — the owner would otherwise reject the whole
176
+ * forwarded operation, and dropping it silently would downgrade a per-principal
177
+ * policy to the shared scope. `""` is not a principal (same rule as ids on the
178
+ * ingress envelope), so it is absent rather than invalid.
179
+ */
180
+ function forwardedTenantId(value) {
181
+ if (value === undefined || value === "")
182
+ return undefined;
183
+ if (typeof value !== "string") {
184
+ throw new StatefulOwnerForwardingError({
185
+ code: "STATEFUL_FORWARDING_CONTEXT_INVALID",
186
+ message: "Stateful operation forwarding requires a string tenantId when it is present.",
187
+ });
188
+ }
189
+ return value;
190
+ }
169
191
  function sanitizeForwardedHeaders(headers) {
170
192
  if (!headers)
171
193
  return {};
@@ -5,6 +5,8 @@ export interface StatefulForwardingRuntimeContext {
5
5
  readonly operationRequest?: {
6
6
  readonly requestId: string;
7
7
  readonly connection?: unknown;
8
+ /** Gateway-asserted principal scope; forwarded verbatim to the owner pod. */
9
+ readonly tenantId?: string;
8
10
  readonly headers?: Record<string, string>;
9
11
  readonly trace?: Record<string, string>;
10
12
  };
@@ -24,6 +26,7 @@ export declare function withStatefulLocalProviderContext(providerContext: unknow
24
26
  export declare function statefulForwardingContextFromProviderRequest(request: {
25
27
  readonly requestId: string;
26
28
  readonly connection?: unknown;
29
+ readonly tenantId?: string;
27
30
  readonly headers?: Record<string, string>;
28
31
  readonly trace?: Record<string, string>;
29
32
  }): StatefulForwardingRuntimeContext;
@@ -16,6 +16,7 @@ export function statefulForwardingContextFromProviderRequest(request) {
16
16
  operationRequest: {
17
17
  requestId: request.requestId,
18
18
  ...(request.connection !== undefined ? { connection: request.connection } : {}),
19
+ ...(request.tenantId ? { tenantId: request.tenantId } : {}),
19
20
  ...(request.headers ? { headers: request.headers } : {}),
20
21
  ...(request.trace ? { trace: request.trace } : {}),
21
22
  },
package/dist/types.d.ts CHANGED
@@ -198,6 +198,25 @@ export interface OcrCaptchaResult {
198
198
  readonly model: string;
199
199
  }
200
200
  export interface OcrContext {
201
+ /**
202
+ * Whether this context is backed by a configured OCR backend.
203
+ *
204
+ * The SDK owns this verdict: clients built by `createOcrClientFromEnv` for a
205
+ * configured backend report `true`; the unsupported/error clients handed to
206
+ * undeclared or misconfigured providers report `false`. Providers branch on
207
+ * this flag (for example, "require manual CAPTCHA input") instead of probing
208
+ * the engine-owned `APIFUSE__OCR__*` environment names themselves.
209
+ *
210
+ * `true` promises a configured backend, not a successful call: upstream
211
+ * failures still surface as errors from `recognize` / `extractCaptchaText`.
212
+ *
213
+ * Implementations must expose this as an own enumerable data property (not a
214
+ * getter or prototype member) so that wrappers which spread the context, such
215
+ * as `bindOcrTelemetry`, preserve it. Custom `OcrContext` overrides passed to
216
+ * `serve({ ocr })`, `createFlowContext({ ocr })`, or test contexts must set it
217
+ * explicitly.
218
+ */
219
+ readonly available: boolean;
201
220
  recognize(request: OcrRecognizeRequest): Promise<OcrResult>;
202
221
  extractCaptchaText(image: OcrImageInput, options?: OcrCaptchaOptions): Promise<OcrCaptchaResult>;
203
222
  }
@@ -670,6 +689,16 @@ export type HealthCheckCase<TInput = unknown, TOutput = unknown> = {
670
689
  *
671
690
  * MUST NOT access scheduler, recorder, or any runtime type — pure data
672
691
  * + lambda only.
692
+ *
693
+ * NOTE: a closure cannot cross the registry's serialization boundary, so
694
+ * the platform health monitor cannot execute this hook — it runs a case's
695
+ * serialized `scenario` and nothing else. A case that carries only
696
+ * `assertions` is still published as a probe, but its outcome is
697
+ * permanently `unknown` / `monitoring_unavailable`, so the operation
698
+ * reads as monitored while nothing is being checked. This hook runs only
699
+ * in the provider runtime's own self-test
700
+ * (`/internal/health/self-test`). Express anything that must be
701
+ * monitored in production as a `scenario`.
673
702
  */
674
703
  assertions: (ctx: HealthCheckAssertionContext<TOutput>) => void | Promise<void> | HealthCheckCaseResult | Promise<HealthCheckCaseResult>;
675
704
  /** Declarative scenarios replace the imperative preparation and assertion hooks. */
@@ -782,8 +811,17 @@ export type ProviderErrorStatus = (typeof VALID_OPERATION_ERROR_STATUSES)[number
782
811
  export interface OperationErrorCode {
783
812
  code: string;
784
813
  status?: ProviderErrorStatus;
814
+ /** Developer-facing English prose for docs and MCP tool text. Never localized. */
785
815
  description: string;
786
816
  retryable?: boolean;
817
+ /**
818
+ * Locale catalog key for the client-facing `message` of every error thrown
819
+ * with this `code`. A throw site's own `messageKey` wins; when neither is
820
+ * present the SDK derives `errors.<code>.message`.
821
+ */
822
+ messageKey?: ProviderLocaleKeyInput;
823
+ /** Locale catalog key for the client-facing `fix`. Derived default: `errors.<code>.fix`. */
824
+ fixKey?: ProviderLocaleKeyInput;
787
825
  }
788
826
  export type StealthPlatform = "macos" | "windows" | "linux" | "android" | "ios";
789
827
  export type StealthBrowser = "chrome" | "firefox" | "safari";
@@ -1039,8 +1077,44 @@ export interface HttpRetrySummary {
1039
1077
  lastErrorCode?: string;
1040
1078
  lastStatus?: number;
1041
1079
  }
1080
+ /** Per-attempt input for a `RequestOptions.headers` factory. */
1081
+ export interface HttpAttemptContext {
1082
+ /**
1083
+ * 1-based number of this request build: the first request is `1`, its first
1084
+ * retry `2`. Only attempts that reach header resolution count; a failed
1085
+ * proxy allocation or a skipped duplicate proxy offset builds no request
1086
+ * and is not numbered.
1087
+ */
1088
+ attempt: number;
1089
+ /**
1090
+ * Resolved request URL: `baseUrl` + path + `params` + `sensitiveParams`.
1091
+ * It is the exact URL the attempt is issued against, so bind signature
1092
+ * targets to it rather than to a URL the caller rebuilds. Strip the query
1093
+ * and fragment for fields that are defined without them — RFC 9449 §4.2
1094
+ * requires that of DPoP `htu`. It carries any sensitive query values, so
1095
+ * never log it and never copy it verbatim into a signed field that a
1096
+ * verifier logs.
1097
+ */
1098
+ url: string;
1099
+ /** Normalized upper-case HTTP method of the request. */
1100
+ method: Uppercase<HttpMethod>;
1101
+ }
1102
+ /**
1103
+ * Builds the request headers for one issued attempt. Managed retry calls it
1104
+ * again for every retry, so request-bound single-use proofs (DPoP `jti`,
1105
+ * HTTP message signatures, HMAC nonces) can be re-minted instead of replayed.
1106
+ * A throw is raised as a non-retryable `TransportError` with code
1107
+ * `http_header_factory_failed`.
1108
+ */
1109
+ export type HttpHeadersFactory = (attempt: HttpAttemptContext) => Record<string, string> | Promise<Record<string, string>>;
1042
1110
  export interface RequestOptions {
1043
- headers?: Record<string, string>;
1111
+ /**
1112
+ * Request headers, or a factory resolved once per issued attempt (see
1113
+ * `HttpHeadersFactory`). The factory runs after proxy resolution, before the
1114
+ * first redirect hop of that attempt; redirect hops reuse the attempt's
1115
+ * headers. `ctx.stealth` declares its own header option and is not affected.
1116
+ */
1117
+ headers?: Record<string, string> | HttpHeadersFactory;
1044
1118
  params?: RequestParams;
1045
1119
  /**
1046
1120
  * Query parameters whose values contain credentials or other secret material.
@@ -1048,7 +1122,23 @@ export interface RequestOptions {
1048
1122
  */
1049
1123
  sensitiveParams?: Record<string, string>;
1050
1124
  proxy?: string;
1125
+ /**
1126
+ * Per-attempt timeout for the response-header phase. It is disarmed once a
1127
+ * successful response's headers arrive, so it never bounds consumption of
1128
+ * that body — on the buffered path as well as on streams; use `signal` for
1129
+ * that. A non-2xx body the transport discards on the caller's behalf is
1130
+ * still drained under this deadline, so a wedged error body cannot hang the
1131
+ * attempt.
1132
+ */
1051
1133
  timeout?: number;
1134
+ /**
1135
+ * Cancels this request only — its retries, its backoff sleep and its
1136
+ * response-body consumption — leaving the client's other in-flight requests
1137
+ * untouched. Merged with the client-level `signal`, so a rejection reads as
1138
+ * `transport_cancelled` either way; inspect `signal.reason` to tell a
1139
+ * per-request abort from a fleet-wide one.
1140
+ */
1141
+ signal?: AbortSignal;
1052
1142
  /**
1053
1143
  * Defaults to true. Set to false when callers need to inspect upstream
1054
1144
  * non-2xx bodies themselves instead of converting them to TransportError.
@@ -1073,6 +1163,13 @@ export interface HttpRedirectPolicy {
1073
1163
  export type HttpRedirectFailureReason = Exclude<RedirectRunReason, "completed">;
1074
1164
  export type HttpMethod = "HEAD" | "head" | "GET" | "get" | "POST" | "post" | "PUT" | "put" | "DELETE" | "delete" | "OPTIONS" | "options" | "TRACE" | "trace" | "PATCH" | "patch";
1075
1165
  export interface StealthFetchOptions extends Omit<RequestOptions, "redirectPolicy" | "headers"> {
1166
+ /**
1167
+ * Not supported by the stealth transport, which observes only the
1168
+ * client-level `signal` passed to `createStealthClient`. Typed as `never` so
1169
+ * a per-request signal fails to compile instead of being silently ignored;
1170
+ * threading one through the stealth session is a separate change.
1171
+ */
1172
+ signal?: never;
1076
1173
  /**
1077
1174
  * Defaults to true. Set to false when callers need to inspect upstream
1078
1175
  * non-2xx bodies themselves instead of converting them to TransportError.
@@ -1659,6 +1756,16 @@ export interface CredentialContext {
1659
1756
  }
1660
1757
  export interface ProviderRequestContext {
1661
1758
  connectionId?: string;
1759
+ /**
1760
+ * Gateway-asserted principal scope of the operation request: the
1761
+ * organization id for customer subjects, the service-account id for
1762
+ * platform service accounts. `undefined` on direct calls and self-test
1763
+ * (unlike `FlowContext.tenantId`, which is coerced to `""`); an empty
1764
+ * string on the wire is normalised to `undefined` like `connectionId`.
1765
+ * Key per-principal policy (quota, fairness, correlation) for
1766
+ * connectionless operations on it. It does not scope `ctx.state`.
1767
+ */
1768
+ tenantId?: string;
1662
1769
  headers: Record<string, string>;
1663
1770
  }
1664
1771
  export interface ContextScratchpad {
@@ -1915,10 +2022,17 @@ export interface AuthConfig {
1915
2022
  proxied?: ProxiedOAuthConfig;
1916
2023
  flow?: AuthFlowDefinition;
1917
2024
  }
2025
+ /** Who provisions a declared secret: the platform (`apifuse`) or the provider author (`contributor`). */
2026
+ export type ProviderSecretIssuer = "apifuse" | "contributor";
1918
2027
  export interface ProviderSecretDeclaration {
1919
2028
  name: string;
1920
2029
  description?: string;
1921
2030
  required?: boolean;
2031
+ /**
2032
+ * Optional today; ADR-0011 D3 makes it required once every deployed provider
2033
+ * declares it. Metadata only: it does not change which secrets are projected.
2034
+ */
2035
+ issuer?: ProviderSecretIssuer;
1922
2036
  }
1923
2037
  export interface CredentialDeclaration {
1924
2038
  keys: string[];
@@ -2000,6 +2114,14 @@ export interface OperationDefinition<TInput extends SchemaLike = SchemaLike, TOu
2000
2114
  * optional. Note that the deployment `runtime` axis
2001
2115
  * (`shared`/`dedicated`/`browser`) is distinct from the provider execution
2002
2116
  * `runtime` (`standard`/`shared`/`browser`).
2117
+ *
2118
+ * This key is the ONLY authored deployment surface. Declare it inside the
2119
+ * `defineProvider({...})` literal, not on a spread default export and not
2120
+ * in a standalone `deploy.ts` (legacy; `apifuse migrate-deployment` hoists
2121
+ * and deletes it). Write only what differs from the runtime profile —
2122
+ * shared `25m/128Mi`, browser `200m/256Mi`, `language: "typescript"`,
2123
+ * `replicas: 1`, HPA enabled 1-1 at 70% CPU — so most providers declare
2124
+ * nothing and `apifuse check` warns on restated defaults.
2003
2125
  */
2004
2126
  export interface ProviderDeploymentOverrides {
2005
2127
  runtime?: "shared" | "dedicated" | "browser";
@@ -0,0 +1,39 @@
1
+ /** The TypeScript compiler API surface the source-level lint rules parse with. */
2
+ export type TypeScriptModule = typeof import("typescript");
3
+ /**
4
+ * What a caller hands over as a compiler module. Typed structurally so the
5
+ * option does not depend on which `typescript` package the caller's own type
6
+ * resolution lands on: under a `typescript@7` pin `typeof import("typescript")`
7
+ * is the native shell's version module, not the compiler API. The members are
8
+ * optional for the same reason — the shell has none of them — and
9
+ * `isTypeScriptCompilerModule` decides at runtime whether the module can parse.
10
+ */
11
+ export type TypeScriptCompilerModuleLike = {
12
+ readonly createSourceFile?: (...parameters: never[]) => unknown;
13
+ readonly ScriptTarget?: object;
14
+ readonly version?: string;
15
+ };
16
+ /**
17
+ * Package specifiers that may carry the compiler API, in resolution order.
18
+ *
19
+ * `typescript@7` (the Go-native toolchain) resolves but its JavaScript entry
20
+ * exports only `version`/`getExePath` — no `createSourceFile`, so the lint
21
+ * rules cannot parse with it. The compiler API of that generation is published
22
+ * as `@typescript/typescript6`, which is what a `typescript@7` dependency tree
23
+ * (for example the APIFuse monorepo root) installs alongside the shell.
24
+ */
25
+ export declare const TYPESCRIPT_COMPILER_MODULE_SPECIFIERS: readonly ["typescript", "@typescript/typescript6"];
26
+ /**
27
+ * True when `candidate` is a loaded module that exposes the parser the lint
28
+ * rules need. Internal (narrows to the `typescript` module type, which is not
29
+ * part of the package surface); `lintRuntimeBoundarySources` applies it to the
30
+ * caller-supplied option.
31
+ */
32
+ export declare function isTypeScriptCompilerModule(candidate: unknown): candidate is TypeScriptModule;
33
+ /**
34
+ * Resolve the compiler API through `load`, trying each specifier in order and
35
+ * accepting the first module that exposes `createSourceFile`. Exposed for the
36
+ * tests; production code uses `getTypeScript()`.
37
+ */
38
+ export declare function loadTypeScriptModule(load: (specifier: string) => unknown, specifiers?: readonly string[]): TypeScriptModule;
39
+ export declare function getTypeScript(): TypeScriptModule;
@@ -0,0 +1,72 @@
1
+ import { createRequire } from "node:module";
2
+ const requireModule = createRequire(import.meta.url);
3
+ /**
4
+ * Package specifiers that may carry the compiler API, in resolution order.
5
+ *
6
+ * `typescript@7` (the Go-native toolchain) resolves but its JavaScript entry
7
+ * exports only `version`/`getExePath` — no `createSourceFile`, so the lint
8
+ * rules cannot parse with it. The compiler API of that generation is published
9
+ * as `@typescript/typescript6`, which is what a `typescript@7` dependency tree
10
+ * (for example the APIFuse monorepo root) installs alongside the shell.
11
+ */
12
+ export const TYPESCRIPT_COMPILER_MODULE_SPECIFIERS = [
13
+ "typescript",
14
+ "@typescript/typescript6",
15
+ ];
16
+ /**
17
+ * True when `candidate` is a loaded module that exposes the parser the lint
18
+ * rules need. Internal (narrows to the `typescript` module type, which is not
19
+ * part of the package surface); `lintRuntimeBoundarySources` applies it to the
20
+ * caller-supplied option.
21
+ */
22
+ export function isTypeScriptCompilerModule(candidate) {
23
+ return (typeof candidate === "object" &&
24
+ candidate !== null &&
25
+ typeof candidate.createSourceFile === "function" &&
26
+ typeof candidate.ScriptTarget === "object");
27
+ }
28
+ function describeCandidate(candidate) {
29
+ if (typeof candidate === "object" && candidate !== null) {
30
+ const version = candidate.version;
31
+ if (typeof version === "string")
32
+ return `resolved ${version} without a compiler API`;
33
+ }
34
+ return "resolved without a compiler API";
35
+ }
36
+ /**
37
+ * Resolve the compiler API through `load`, trying each specifier in order and
38
+ * accepting the first module that exposes `createSourceFile`. Exposed for the
39
+ * tests; production code uses `getTypeScript()`.
40
+ */
41
+ export function loadTypeScriptModule(load, specifiers = TYPESCRIPT_COMPILER_MODULE_SPECIFIERS) {
42
+ const attempts = [];
43
+ for (const specifier of specifiers) {
44
+ let candidate;
45
+ try {
46
+ candidate = load(specifier);
47
+ }
48
+ catch {
49
+ attempts.push(`${specifier}: not resolvable`);
50
+ continue;
51
+ }
52
+ if (isTypeScriptCompilerModule(candidate))
53
+ return candidate;
54
+ attempts.push(`${specifier}: ${describeCandidate(candidate)}`);
55
+ }
56
+ throw new Error(`The provider source lint needs the TypeScript compiler API (createSourceFile) and none of the resolvable packages provide it — ${attempts.join("; ")}. Install typescript 6.x as a devDependency, or @typescript/typescript6 next to a typescript 7 toolchain, in the dependency tree that installs @apifuse/provider-sdk.`);
57
+ }
58
+ /**
59
+ * Lazily loaded TypeScript compiler API shared by the source-level lint rules.
60
+ *
61
+ * `typeof import(...)` keeps the type without emitting a static import: the
62
+ * typescript package is a devDependency of the SDK and only the CLI and the
63
+ * lint rules need it at runtime, which the typescript-import-boundary test
64
+ * enforces for production sources. Resolution starts at the installed SDK, so
65
+ * the caller's dependency tree must provide one of
66
+ * `TYPESCRIPT_COMPILER_MODULE_SPECIFIERS`.
67
+ */
68
+ let typeScriptModule;
69
+ export function getTypeScript() {
70
+ typeScriptModule ??= loadTypeScriptModule(requireModule);
71
+ return typeScriptModule;
72
+ }
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.2.0-beta.62",
2
+ "version": "2.2.0-beta.64",
3
3
  "name": "@apifuse/provider-sdk",
4
4
  "private": false,
5
5
  "type": "module",
@@ -15,9 +15,14 @@
15
15
  "src",
16
16
  "!src/__tests__",
17
17
  "!src/__tests__/**",
18
+ "!src/**/__tests__",
19
+ "!src/**/__tests__/**",
18
20
  "!src/**/*.test.ts",
21
+ "!src/**/*.spec.ts",
19
22
  "!src/index.test.ts",
20
23
  "bin",
24
+ "!bin/__tests__",
25
+ "!bin/__tests__/**",
21
26
  "README.md",
22
27
  "AUTHORING.md",
23
28
  "CHANGELOG.md",
@@ -5,6 +5,7 @@ export type ApifuseCommandName =
5
5
  | "sync-assets"
6
6
  | "migrate-shape"
7
7
  | "migrate-operation-declaration"
8
+ | "migrate-deployment"
8
9
  | "submit-check"
9
10
  | "bounty-check"
10
11
  | "record"
@@ -76,6 +77,18 @@ export const COMMAND_MANIFEST: Record<
76
77
  ],
77
78
  modulePath: "./apifuse-migrate-operation-declaration",
78
79
  },
80
+ "migrate-deployment": {
81
+ name: "migrate-deployment",
82
+ summary:
83
+ "Retire a legacy deploy.ts: hoist its non-default values into the defineProvider() deployment key and delete the file.",
84
+ usage:
85
+ "apifuse migrate-deployment [path] [--check] [--json] [--drop-codeowners-lock]",
86
+ examples: [
87
+ "apifuse migrate-deployment .",
88
+ "apifuse migrate-deployment . --check --json",
89
+ ],
90
+ modulePath: "./apifuse-migrate-deployment",
91
+ },
79
92
  "submit-check": {
80
93
  name: "submit-check",
81
94
  summary:
@@ -136,6 +149,7 @@ export const COMMAND_ORDER: ApifuseCommandName[] = [
136
149
  "sync-assets",
137
150
  "migrate-shape",
138
151
  "migrate-operation-declaration",
152
+ "migrate-deployment",
139
153
  "submit-check",
140
154
  "record",
141
155
  "test",