@apifuse/provider-sdk 2.2.0-beta.2 → 2.2.0-beta.21

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 (291) hide show
  1. package/AUTHORING.md +487 -0
  2. package/CHANGELOG.md +90 -0
  3. package/README.md +49 -3
  4. package/SUBMISSION.md +1 -1
  5. package/bin/apifuse-check.ts +44 -59
  6. package/bin/apifuse-create.ts +1 -1
  7. package/bin/apifuse-dev.ts +27 -52
  8. package/bin/apifuse-pack-check.ts +14 -0
  9. package/bin/apifuse-pack-smoke.ts +36 -81
  10. package/bin/apifuse-pack-types.ts +305 -0
  11. package/bin/apifuse-perf.ts +45 -127
  12. package/bin/apifuse-record.ts +659 -111
  13. package/bin/apifuse-submit-check.ts +546 -48
  14. package/bin/apifuse-sync-assets.ts +117 -0
  15. package/bin/apifuse.ts +1 -1
  16. package/bin/submit-check-delimited-text.ts +50 -0
  17. package/bin/submit-check-xml-semantics.ts +204 -0
  18. package/bin/submit-check-xml.ts +134 -0
  19. package/dist/auth-turn/index.d.ts +3 -3
  20. package/dist/auth.d.ts +2 -2
  21. package/dist/auth.js +9 -18
  22. package/dist/ceremonies/index.d.ts +9 -1
  23. package/dist/ceremonies/index.js +65 -18
  24. package/dist/cli/commands.d.ts +1 -1
  25. package/dist/cli/commands.js +8 -0
  26. package/dist/cli/create.d.ts +3 -0
  27. package/dist/cli/create.js +34 -35
  28. package/dist/cli/prompt-assets.d.ts +80 -0
  29. package/dist/cli/prompt-assets.js +743 -0
  30. package/dist/cli/templates/provider/AGENTS.md.tpl +17 -8
  31. package/dist/config/loader.d.ts +176 -8
  32. package/dist/config/loader.js +424 -95
  33. package/dist/contract-serialization.d.ts +2 -2
  34. package/dist/contract-serialization.js +3 -6
  35. package/dist/contract-types.d.ts +2 -2
  36. package/dist/contract.d.ts +3 -3
  37. package/dist/contract.js +4 -6
  38. package/dist/define.d.ts +9 -1
  39. package/dist/define.js +304 -119
  40. package/dist/dev.d.ts +1 -1
  41. package/dist/dev.js +1 -1
  42. package/dist/error-resolution.d.ts +2 -0
  43. package/dist/error-resolution.js +90 -0
  44. package/dist/errors.d.ts +22 -1
  45. package/dist/errors.js +88 -0
  46. package/dist/fixture-sanitization.d.ts +26 -0
  47. package/dist/fixture-sanitization.js +216 -0
  48. package/dist/i18n/catalog.d.ts +2 -2
  49. package/dist/i18n/catalog.js +4 -10
  50. package/dist/i18n/index.d.ts +2 -2
  51. package/dist/i18n/index.js +2 -2
  52. package/dist/i18n/keys.d.ts +2 -2
  53. package/dist/index.d.ts +46 -42
  54. package/dist/index.js +41 -37
  55. package/dist/lint.d.ts +1 -1
  56. package/dist/lint.js +8 -15
  57. package/dist/native-address.d.ts +43 -0
  58. package/dist/native-address.js +281 -0
  59. package/dist/native-egress-policy.d.ts +31 -0
  60. package/dist/native-egress-policy.js +288 -0
  61. package/dist/observability.d.ts +5 -2
  62. package/dist/observability.js +48 -1
  63. package/dist/provider.d.ts +12 -11
  64. package/dist/provider.js +10 -9
  65. package/dist/public-schema-field-lint.d.ts +1 -1
  66. package/dist/recipes/gov-api.js +1 -1
  67. package/dist/runtime/auth-flow.d.ts +2 -1
  68. package/dist/runtime/auth-flow.js +4 -3
  69. package/dist/runtime/browser.d.ts +1 -1
  70. package/dist/runtime/browser.js +15 -29
  71. package/dist/runtime/cache.d.ts +1 -1
  72. package/dist/runtime/cache.js +4 -8
  73. package/dist/runtime/choice.d.ts +1 -1
  74. package/dist/runtime/choice.js +31 -35
  75. package/dist/runtime/credential.d.ts +1 -1
  76. package/dist/runtime/credential.js +1 -1
  77. package/dist/runtime/env.d.ts +1 -1
  78. package/dist/runtime/executor.d.ts +1 -1
  79. package/dist/runtime/executor.js +31 -4
  80. package/dist/runtime/http.d.ts +2 -2
  81. package/dist/runtime/http.js +387 -47
  82. package/dist/runtime/insights.d.ts +1 -1
  83. package/dist/runtime/insights.js +6 -13
  84. package/dist/runtime/instrumentation.d.ts +2 -2
  85. package/dist/runtime/instrumentation.js +345 -22
  86. package/dist/runtime/keyring.js +1 -1
  87. package/dist/runtime/namespace.js +1 -1
  88. package/dist/runtime/native-network.d.ts +127 -0
  89. package/dist/runtime/native-network.js +1298 -0
  90. package/dist/runtime/otlp.d.ts +1 -1
  91. package/dist/runtime/perf.d.ts +1 -1
  92. package/dist/runtime/provider.d.ts +1 -1
  93. package/dist/runtime/provider.js +1 -2
  94. package/dist/runtime/proxy-errors.d.ts +1 -1
  95. package/dist/runtime/proxy-errors.js +9 -7
  96. package/dist/runtime/proxy-nodemaven.d.ts +56 -0
  97. package/dist/runtime/proxy-nodemaven.js +146 -0
  98. package/dist/runtime/proxy-retry-policy.d.ts +2 -2
  99. package/dist/runtime/proxy-retry-policy.js +2 -2
  100. package/dist/runtime/proxy-telemetry.d.ts +2 -1
  101. package/dist/runtime/proxy-telemetry.js +55 -52
  102. package/dist/runtime/redirects.d.ts +29 -0
  103. package/dist/runtime/redirects.js +36 -0
  104. package/dist/runtime/redis.d.ts +1 -1
  105. package/dist/runtime/redis.js +2 -4
  106. package/dist/runtime/request-options.d.ts +68 -1
  107. package/dist/runtime/request-options.js +548 -0
  108. package/dist/runtime/secrets.d.ts +27 -0
  109. package/dist/runtime/secrets.js +51 -0
  110. package/dist/runtime/state.d.ts +2 -2
  111. package/dist/runtime/state.js +238 -26
  112. package/dist/runtime/stealth.d.ts +5 -3
  113. package/dist/runtime/stealth.js +423 -143
  114. package/dist/runtime/stt.d.ts +1 -1
  115. package/dist/runtime/stt.js +11 -15
  116. package/dist/runtime/trace.d.ts +2 -2
  117. package/dist/runtime/trace.js +2 -4
  118. package/dist/runtime/waterfall.d.ts +1 -1
  119. package/dist/schema.d.ts +1 -1
  120. package/dist/schema.js +7 -15
  121. package/dist/serve.d.ts +1 -1
  122. package/dist/serve.js +1 -1
  123. package/dist/server/index.d.ts +7 -7
  124. package/dist/server/index.js +6 -6
  125. package/dist/server/self-test-input-tokens.d.ts +2 -1
  126. package/dist/server/self-test-input-tokens.js +18 -14
  127. package/dist/server/self-test-redaction.d.ts +1 -1
  128. package/dist/server/self-test-redaction.js +1 -1
  129. package/dist/server/self-test.d.ts +104 -3
  130. package/dist/server/self-test.js +673 -115
  131. package/dist/server/serve.d.ts +116 -4
  132. package/dist/server/serve.js +799 -128
  133. package/dist/server/types.d.ts +34 -9
  134. package/dist/server/types.js +8 -1
  135. package/dist/stateful/errors.d.ts +14 -0
  136. package/dist/stateful/errors.js +14 -0
  137. package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
  138. package/dist/stateful/http-provider-event-emitter.js +237 -0
  139. package/dist/stateful/http-session-owner-registry.d.ts +44 -0
  140. package/dist/stateful/http-session-owner-registry.js +210 -0
  141. package/dist/stateful/index.d.ts +18 -0
  142. package/dist/stateful/index.js +18 -0
  143. package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
  144. package/dist/stateful/provider-event-delivery-failures.js +43 -0
  145. package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
  146. package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
  147. package/dist/stateful/provider-event-pipeline.d.ts +50 -0
  148. package/dist/stateful/provider-event-pipeline.js +1 -0
  149. package/dist/stateful/provider-events.d.ts +101 -0
  150. package/dist/stateful/provider-events.js +289 -0
  151. package/dist/stateful/session-key.d.ts +15 -0
  152. package/dist/stateful/session-key.js +86 -0
  153. package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
  154. package/dist/stateful/stateful-provider-adapter-context.js +42 -0
  155. package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
  156. package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
  157. package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
  158. package/dist/stateful/stateful-provider-adapter.js +287 -0
  159. package/dist/stateful/stateful-provider-observability.d.ts +62 -0
  160. package/dist/stateful/stateful-provider-observability.js +161 -0
  161. package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
  162. package/dist/stateful/stateful-provider-owner-forwarder.js +215 -0
  163. package/dist/stateful/stateful-provider-runtime-context.d.ts +32 -0
  164. package/dist/stateful/stateful-provider-runtime-context.js +60 -0
  165. package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
  166. package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
  167. package/dist/stateful/stateful-provider-session-routing.d.ts +71 -0
  168. package/dist/stateful/stateful-provider-session-routing.js +353 -0
  169. package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
  170. package/dist/stateful/stateful-provider-session-runtime.js +245 -0
  171. package/dist/stateful-signing.d.ts +18 -0
  172. package/dist/stateful-signing.js +27 -0
  173. package/dist/stealth/profiles.d.ts +1 -1
  174. package/dist/stealth/profiles.js +5 -14
  175. package/dist/stream-evidence.d.ts +74 -0
  176. package/dist/stream-evidence.js +785 -0
  177. package/dist/stream.d.ts +1 -1
  178. package/dist/testing/index.d.ts +2 -2
  179. package/dist/testing/index.js +2 -2
  180. package/dist/testing/run.d.ts +32 -2
  181. package/dist/testing/run.js +478 -28
  182. package/dist/types.d.ts +342 -14
  183. package/dist/types.js +1 -0
  184. package/dist/user-input.d.ts +30 -0
  185. package/dist/user-input.js +66 -0
  186. package/package.json +16 -5
  187. package/src/auth-turn/index.ts +1 -1
  188. package/src/auth.ts +28 -86
  189. package/src/ceremonies/index.ts +103 -78
  190. package/src/cli/commands.ts +10 -0
  191. package/src/cli/create.ts +42 -35
  192. package/src/cli/prompt-assets.ts +865 -0
  193. package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
  194. package/src/config/loader.ts +652 -204
  195. package/src/contract-serialization.ts +5 -11
  196. package/src/contract-types.ts +2 -2
  197. package/src/contract.ts +12 -28
  198. package/src/define.ts +499 -498
  199. package/src/dev.ts +4 -9
  200. package/src/error-resolution.ts +91 -0
  201. package/src/errors.ts +110 -5
  202. package/src/fixture-sanitization.ts +247 -0
  203. package/src/i18n/catalog.ts +10 -32
  204. package/src/i18n/index.ts +2 -2
  205. package/src/i18n/keys.ts +5 -11
  206. package/src/index.ts +112 -42
  207. package/src/lint.ts +88 -152
  208. package/src/native-address.ts +340 -0
  209. package/src/native-egress-policy.ts +358 -0
  210. package/src/observability.ts +51 -1
  211. package/src/provider.ts +66 -11
  212. package/src/public-schema-field-lint.ts +7 -33
  213. package/src/recipes/gov-api.ts +2 -5
  214. package/src/runtime/auth-flow.ts +7 -7
  215. package/src/runtime/browser.ts +64 -187
  216. package/src/runtime/cache.ts +20 -67
  217. package/src/runtime/choice.ts +79 -132
  218. package/src/runtime/credential.ts +2 -2
  219. package/src/runtime/env.ts +1 -1
  220. package/src/runtime/executor.ts +43 -20
  221. package/src/runtime/http.ts +494 -57
  222. package/src/runtime/insights.ts +15 -53
  223. package/src/runtime/instrumentation.ts +495 -66
  224. package/src/runtime/keyring.ts +7 -19
  225. package/src/runtime/namespace.ts +2 -7
  226. package/src/runtime/native-network.ts +1686 -0
  227. package/src/runtime/otlp.ts +12 -23
  228. package/src/runtime/perf.ts +1 -1
  229. package/src/runtime/provider.ts +4 -9
  230. package/src/runtime/proxy-errors.ts +29 -42
  231. package/src/runtime/proxy-nodemaven.ts +221 -0
  232. package/src/runtime/proxy-retry-policy.ts +3 -3
  233. package/src/runtime/proxy-telemetry.ts +79 -77
  234. package/src/runtime/redirects.ts +66 -0
  235. package/src/runtime/redis.ts +4 -12
  236. package/src/runtime/request-options.ts +679 -9
  237. package/src/runtime/secrets.ts +64 -0
  238. package/src/runtime/state.ts +353 -133
  239. package/src/runtime/stealth.ts +505 -154
  240. package/src/runtime/stt.ts +38 -94
  241. package/src/runtime/trace.ts +14 -44
  242. package/src/runtime/waterfall.ts +5 -18
  243. package/src/schema.ts +23 -84
  244. package/src/serve.ts +1 -1
  245. package/src/server/index.ts +29 -7
  246. package/src/server/self-test-input-tokens.ts +29 -14
  247. package/src/server/self-test-redaction.ts +2 -2
  248. package/src/server/self-test.ts +857 -132
  249. package/src/server/serve.ts +1151 -328
  250. package/src/server/types.ts +12 -13
  251. package/src/stateful/README.md +146 -0
  252. package/src/stateful/errors.ts +23 -0
  253. package/src/stateful/http-provider-event-emitter.ts +314 -0
  254. package/src/stateful/http-session-owner-registry.ts +306 -0
  255. package/src/stateful/index.ts +18 -0
  256. package/src/stateful/provider-event-delivery-failures.ts +80 -0
  257. package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
  258. package/src/stateful/provider-event-pipeline.ts +61 -0
  259. package/src/stateful/provider-events.ts +462 -0
  260. package/src/stateful/session-key.ts +111 -0
  261. package/src/stateful/stateful-provider-adapter-context.ts +59 -0
  262. package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
  263. package/src/stateful/stateful-provider-adapter.ts +562 -0
  264. package/src/stateful/stateful-provider-observability.ts +261 -0
  265. package/src/stateful/stateful-provider-owner-forwarder.ts +287 -0
  266. package/src/stateful/stateful-provider-runtime-context.ts +92 -0
  267. package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
  268. package/src/stateful/stateful-provider-session-routing.ts +555 -0
  269. package/src/stateful/stateful-provider-session-runtime.ts +403 -0
  270. package/src/stateful-signing.ts +46 -0
  271. package/src/stealth/profiles.ts +10 -26
  272. package/src/stream-evidence.ts +988 -0
  273. package/src/stream.ts +8 -19
  274. package/src/testing/index.ts +10 -2
  275. package/src/testing/run.ts +653 -74
  276. package/src/types.ts +408 -28
  277. package/src/user-input.ts +118 -0
  278. package/dist/cli/templates/provider/CLAUDE.md.tpl +0 -1
  279. package/src/cli/templates/provider/CLAUDE.md.tpl +0 -1
  280. /package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  281. /package/dist/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  282. /package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  283. /package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  284. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  285. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
  286. /package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  287. /package/src/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  288. /package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  289. /package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  290. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  291. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
package/src/lint.ts CHANGED
@@ -1,16 +1,14 @@
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";
3
+ import { lintPublicSchemaFieldNames } from "./public-schema-field-lint.js";
4
+ import { APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_SENSITIVE_META_KEY } from "./schema.js";
8
5
 
9
6
  type AuthModeLike =
10
7
  | "none"
11
8
  | "platform-managed"
12
9
  | "credentials"
13
10
  | "oauth2"
11
+ | "oauth2_proxied"
14
12
  | "api-key";
15
13
 
16
14
  type ProviderAuthLike = {
@@ -141,28 +139,19 @@ function hasReusableSecretKeys(keys: readonly string[] | undefined): boolean {
141
139
  }
142
140
 
143
141
  return keys.some((key) =>
144
- /(access_token|refresh_token|password|secret|cookie|session|token|api[_-]?key)/i.test(
145
- key,
146
- ),
142
+ /(access_token|refresh_token|password|secret|cookie|session|token|api[_-]?key)/i.test(key),
147
143
  );
148
144
  }
149
145
 
150
- function hasReusableReloginSecretKeys(
151
- keys: readonly string[] | undefined,
152
- ): boolean {
146
+ function hasReusableReloginSecretKeys(keys: readonly string[] | undefined): boolean {
153
147
  if (!keys) {
154
148
  return false;
155
149
  }
156
150
 
157
- return keys.some((key) =>
158
- /(password|passcode|secret|cookie|session)/i.test(key),
159
- );
151
+ return keys.some((key) => /(password|passcode|secret|cookie|session)/i.test(key));
160
152
  }
161
153
 
162
- function getAuthFlowSource(provider: {
163
- auth?: ProviderAuthLike;
164
- authFlowSource?: string;
165
- }): string {
154
+ function getAuthFlowSource(provider: { auth?: ProviderAuthLike; authFlowSource?: string }): string {
166
155
  if (provider.authFlowSource) {
167
156
  return provider.authFlowSource;
168
157
  }
@@ -176,10 +165,7 @@ function getAuthFlowSource(provider: {
176
165
  ];
177
166
 
178
167
  return parts
179
- .filter(
180
- (part): part is (...args: unknown[]) => unknown =>
181
- typeof part === "function",
182
- )
168
+ .filter((part): part is (...args: unknown[]) => unknown => typeof part === "function")
183
169
  .map((part) => part.toString())
184
170
  .join("\n");
185
171
  }
@@ -243,8 +229,7 @@ function lintAuthModel(provider: {
243
229
 
244
230
  if (
245
231
  hasReusableSecretKeys(credentialKeys) &&
246
- (!provider.credential?.storesReusableSecret ||
247
- !provider.credential.justification)
232
+ (!provider.credential?.storesReusableSecret || !provider.credential.justification)
248
233
  ) {
249
234
  diagnostics.push({
250
235
  rule: "credential-reusable-secret",
@@ -257,8 +242,7 @@ function lintAuthModel(provider: {
257
242
  if (
258
243
  typeof provider.auth?.flow?.refresh === "function" &&
259
244
  hasReusableReloginSecretKeys(credentialKeys) &&
260
- (!provider.credential?.storesReusableSecret ||
261
- !provider.credential.justification)
245
+ (!provider.credential?.storesReusableSecret || !provider.credential.justification)
262
246
  ) {
263
247
  diagnostics.push({
264
248
  rule: "auth-refresh-reusable-secret",
@@ -278,10 +262,7 @@ function lintAuthModel(provider: {
278
262
  }
279
263
 
280
264
  const authFlowSource = getAuthFlowSource(provider);
281
- if (
282
- authFlowSource.includes("ctx.context") &&
283
- (provider.context?.keys?.length ?? 0) === 0
284
- ) {
265
+ if (authFlowSource.includes("ctx.context") && (provider.context?.keys?.length ?? 0) === 0) {
285
266
  diagnostics.push({
286
267
  rule: "context-keys-required",
287
268
  level: "warn",
@@ -323,8 +304,7 @@ function isSchemaRecord(value: unknown): value is Record<string, SchemaLike> {
323
304
  }
324
305
 
325
306
  function getObjectShape(schema: SchemaLike): Record<string, SchemaLike> {
326
- const rawShape =
327
- typeof schema.shape === "function" ? schema.shape() : schema.shape;
307
+ const rawShape = typeof schema.shape === "function" ? schema.shape() : schema.shape;
328
308
  if (isSchemaRecord(rawShape)) {
329
309
  return rawShape;
330
310
  }
@@ -344,9 +324,7 @@ function getObjectShape(schema: SchemaLike): Record<string, SchemaLike> {
344
324
  return {};
345
325
  }
346
326
 
347
- function getChildSchemas(
348
- schema: SchemaLike,
349
- ): Array<{ key: string; schema: SchemaLike }> {
327
+ function getChildSchemas(schema: SchemaLike): Array<{ key: string; schema: SchemaLike }> {
350
328
  const seen = new Map<string, SchemaLike>();
351
329
  const def = getSchemaDef(schema);
352
330
 
@@ -450,10 +428,7 @@ function getSchemaMetadata(schema: SchemaLike): Record<string, unknown> {
450
428
  }
451
429
 
452
430
  function getSchemaDescriptionKey(schema: SchemaLike): string | undefined {
453
- const value = Reflect.get(
454
- getSchemaMetadata(schema),
455
- APIFUSE_DESCRIPTION_KEY_META_KEY,
456
- );
431
+ const value = Reflect.get(getSchemaMetadata(schema), APIFUSE_DESCRIPTION_KEY_META_KEY);
457
432
  return typeof value === "string" && value.length > 0 ? value : undefined;
458
433
  }
459
434
 
@@ -597,22 +572,14 @@ function collectSchemaDescriptionKeyDiagnostics(
597
572
  ? `${currentPath}[]`
598
573
  : `${currentPath}.${child.key}`;
599
574
  diagnostics.push(
600
- ...collectSchemaDescriptionKeyDiagnostics(
601
- child.schema,
602
- childPath,
603
- seen,
604
- !isStructuralNode,
605
- ),
575
+ ...collectSchemaDescriptionKeyDiagnostics(child.schema, childPath, seen, !isStructuralNode),
606
576
  );
607
577
  }
608
578
 
609
579
  return diagnostics;
610
580
  }
611
581
 
612
- function isComplexSchema(
613
- schema: unknown,
614
- seen = new Set<SchemaLike>(),
615
- ): boolean {
582
+ function isComplexSchema(schema: unknown, seen = new Set<SchemaLike>()): boolean {
616
583
  if (!isSchema(schema) || seen.has(schema)) {
617
584
  return false;
618
585
  }
@@ -624,10 +591,7 @@ function isComplexSchema(
624
591
  return childChildren.length > 0;
625
592
  });
626
593
 
627
- return (
628
- hasNestedComposite ||
629
- children.some(({ schema: child }) => isComplexSchema(child, seen))
630
- );
594
+ return hasNestedComposite || children.some(({ schema: child }) => isComplexSchema(child, seen));
631
595
  }
632
596
 
633
597
  function hasBidirectionalFixtures(fixtures: unknown): boolean {
@@ -638,16 +602,11 @@ function hasBidirectionalFixtures(fixtures: unknown): boolean {
638
602
  return "request" in fixtures && "response" in fixtures;
639
603
  }
640
604
 
641
- function getOperationSource(operation: {
642
- handler?: unknown;
643
- source?: string;
644
- }): string {
605
+ function getOperationSource(operation: { handler?: unknown; source?: string }): string {
645
606
  if (operation.source) {
646
607
  return operation.source;
647
608
  }
648
- return typeof operation.handler === "function"
649
- ? operation.handler.toString()
650
- : "";
609
+ return typeof operation.handler === "function" ? operation.handler.toString() : "";
651
610
  }
652
611
 
653
612
  function lintStealthTransportUsage(provider: {
@@ -660,22 +619,20 @@ function lintStealthTransportUsage(provider: {
660
619
  }
661
620
 
662
621
  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
- );
622
+ return Object.entries(provider.operations).flatMap(([operationKey, operation]) => {
623
+ const source = getOperationSource(operation);
624
+ if (!/\bctx\.stealth\b/.test(source)) {
625
+ return [];
626
+ }
627
+ return [
628
+ {
629
+ rule: "stealth-config-required",
630
+ level: "error" as const,
631
+ field: `operations.${operationKey}`,
632
+ message: `${providerLabel} operation "${operationKey}" uses ctx.stealth but provider.stealth is not declared.`,
633
+ },
634
+ ];
635
+ });
679
636
  }
680
637
 
681
638
  function lintCredentialWriteUsage(provider: {
@@ -685,24 +642,22 @@ function lintCredentialWriteUsage(provider: {
685
642
  return [];
686
643
  }
687
644
 
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
- }
645
+ return Object.entries(provider.operations).flatMap(([operationKey, operation]) => {
646
+ const source = getOperationSource(operation);
647
+ if (!/\bctx\.credential\.(?:set|setMany)\s*\(/.test(source)) {
648
+ return [];
649
+ }
694
650
 
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
- );
651
+ return [
652
+ {
653
+ rule: "ctx-credential-write-forbidden-in-handler",
654
+ level: "error" as const,
655
+ field: `operations.${operationKey}.handler`,
656
+ message:
657
+ "Operation handlers must not mutate credentials; return refreshed credentials from auth.flow.refresh instead.",
658
+ },
659
+ ];
660
+ });
706
661
  }
707
662
 
708
663
  function lintPlaywrightDirectImports(provider: {
@@ -724,9 +679,7 @@ function lintPlaywrightDirectImports(provider: {
724
679
  });
725
680
  }
726
681
 
727
- for (const [filePath, source] of Object.entries(
728
- provider.providerSourceFiles ?? {},
729
- )) {
682
+ for (const [filePath, source] of Object.entries(provider.providerSourceFiles ?? {})) {
730
683
  if (!importPattern.test(source)) {
731
684
  continue;
732
685
  }
@@ -814,15 +767,11 @@ function lintSelfHostedBrowserPatterns(
814
767
  sources.push({ field: "auth.flow", source: provider.authFlowSource });
815
768
  }
816
769
 
817
- for (const [filePath, source] of Object.entries(
818
- provider.providerSourceFiles ?? {},
819
- )) {
770
+ for (const [filePath, source] of Object.entries(provider.providerSourceFiles ?? {})) {
820
771
  sources.push({ field: `sourceFiles.${filePath}`, source });
821
772
  }
822
773
 
823
- for (const [operationKey, operation] of Object.entries(
824
- provider.operations ?? {},
825
- )) {
774
+ for (const [operationKey, operation] of Object.entries(provider.operations ?? {})) {
826
775
  const source = getOperationSource(operation);
827
776
  if (source) {
828
777
  sources.push({
@@ -865,16 +814,14 @@ export function lintOperation(op: {
865
814
  }): LintDiagnostic[] {
866
815
  const diagnostics: LintDiagnostic[] = [];
867
816
  const description = op.description ?? "";
868
- const hasDescriptionKey =
869
- typeof op.descriptionKey === "string" && op.descriptionKey.length > 0;
817
+ const hasDescriptionKey = typeof op.descriptionKey === "string" && op.descriptionKey.length > 0;
870
818
 
871
819
  if (description.trim().length > 0 && !hasDescriptionKey) {
872
820
  diagnostics.push({
873
821
  rule: "operation-description-raw-prose",
874
822
  level: "error",
875
823
  field: "description",
876
- message:
877
- "Operation description must use descriptionKey instead of raw static prose.",
824
+ message: "Operation description must use descriptionKey instead of raw static prose.",
878
825
  });
879
826
  }
880
827
 
@@ -892,21 +839,16 @@ export function lintOperation(op: {
892
839
  rule: "operation-when-to-use-raw-prose",
893
840
  level: "error",
894
841
  field: "whenToUse",
895
- message:
896
- "Operation whenToUse must use whenToUseKeys instead of raw static prose.",
842
+ message: "Operation whenToUse must use whenToUseKeys instead of raw static prose.",
897
843
  });
898
844
  }
899
845
 
900
- if (
901
- (op.whenNotToUse?.length ?? 0) > 0 &&
902
- !(op.whenNotToUseKeys?.length ?? 0)
903
- ) {
846
+ if ((op.whenNotToUse?.length ?? 0) > 0 && !(op.whenNotToUseKeys?.length ?? 0)) {
904
847
  diagnostics.push({
905
848
  rule: "operation-when-not-to-use-raw-prose",
906
849
  level: "error",
907
850
  field: "whenNotToUse",
908
- message:
909
- "Operation whenNotToUse must use whenNotToUseKeys instead of raw static prose.",
851
+ message: "Operation whenNotToUse must use whenNotToUseKeys instead of raw static prose.",
910
852
  });
911
853
  }
912
854
 
@@ -942,14 +884,11 @@ export function lintOperation(op: {
942
884
  rule: "complex-input-has-examples",
943
885
  level: "warn",
944
886
  field: "inputExamples",
945
- message:
946
- "Complex input schemas should provide at least 2 input examples.",
887
+ message: "Complex input schemas should provide at least 2 input examples.",
947
888
  });
948
889
  }
949
890
 
950
- for (const field of uniqueFields(
951
- collectUnmarkedSensitiveFields(op.input, "input"),
952
- )) {
891
+ for (const field of uniqueFields(collectUnmarkedSensitiveFields(op.input, "input"))) {
953
892
  diagnostics.push({
954
893
  rule: "sensitive-field-unmarked",
955
894
  level: "warn",
@@ -958,9 +897,7 @@ export function lintOperation(op: {
958
897
  });
959
898
  }
960
899
 
961
- for (const field of uniqueFields(
962
- collectUnmarkedSensitiveFields(op.output, "output"),
963
- )) {
900
+ for (const field of uniqueFields(collectUnmarkedSensitiveFields(op.output, "output"))) {
964
901
  diagnostics.push({
965
902
  rule: "sensitive-field-unmarked",
966
903
  level: "warn",
@@ -1044,36 +981,35 @@ export function lintProvider(
1044
981
  }
1045
982
 
1046
983
  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
- })),
984
+ ...Object.entries(provider.operations).flatMap(([operationKey, operation]) =>
985
+ [
986
+ ...lintOperation({
987
+ description: operation.description ?? "",
988
+ descriptionKey: operation.descriptionKey,
989
+ whenToUse: operation.whenToUse,
990
+ whenToUseKeys: operation.whenToUseKeys,
991
+ whenNotToUse: operation.whenNotToUse,
992
+ whenNotToUseKeys: operation.whenNotToUseKeys,
993
+ input: operation.input,
994
+ output: operation.output,
995
+ fixtures: operation.fixtures,
996
+ inputExamples: operation.inputExamples,
997
+ derivations: operation.derivations,
998
+ }),
999
+ ...lintPublicSchemaFieldNames(
1000
+ provider.id,
1001
+ operationKey,
1002
+ operation.input,
1003
+ operation.output,
1004
+ provider.meta?.contract?.publicSchemaFieldNames === "normalized",
1005
+ ),
1006
+ ].map((diagnostic) => ({
1007
+ ...diagnostic,
1008
+ field: diagnostic.field
1009
+ ? `operations.${operationKey}.${diagnostic.field}`
1010
+ : `operations.${operationKey}`,
1011
+ message: `[${operationKey}] ${diagnostic.message}`,
1012
+ })),
1077
1013
  ),
1078
1014
  );
1079
1015