@apifuse/provider-sdk 2.2.0-beta.7 → 2.2.0-beta.70

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 (478) hide show
  1. package/AUTHORING.md +943 -51
  2. package/CHANGELOG.md +273 -1
  3. package/LICENSE +21 -0
  4. package/README.md +117 -29
  5. package/SUBMISSION.md +3 -2
  6. package/bin/apifuse-check.ts +293 -13
  7. package/bin/apifuse-dev.ts +42 -19
  8. package/bin/apifuse-migrate-deployment.ts +200 -0
  9. package/bin/apifuse-migrate-operation-declaration.ts +55 -0
  10. package/bin/apifuse-migrate-shape.ts +202 -0
  11. package/bin/apifuse-pack-check.ts +19 -6
  12. package/bin/apifuse-pack-smoke.ts +57 -2
  13. package/bin/apifuse-pack-types.ts +736 -38
  14. package/bin/apifuse-perf.ts +59 -23
  15. package/bin/apifuse-record.ts +923 -94
  16. package/bin/apifuse-submit-check.ts +2313 -281
  17. package/bin/apifuse-test.ts +3 -1
  18. package/bin/submit-check-delimited-text.ts +50 -0
  19. package/dist/auth-turn/index.d.ts +3 -3
  20. package/dist/auth-turn/index.js +1 -1
  21. package/dist/auth.d.ts +14 -0
  22. package/dist/auth.js +67 -0
  23. package/dist/ceremonies/index.d.ts +16 -0
  24. package/dist/ceremonies/index.js +141 -36
  25. package/dist/cli/commands.d.ts +1 -1
  26. package/dist/cli/commands.js +30 -0
  27. package/dist/cli/create.d.ts +1 -1
  28. package/dist/cli/create.js +8 -2
  29. package/dist/cli/deployment-intent.d.ts +178 -0
  30. package/dist/cli/deployment-intent.js +277 -0
  31. package/dist/cli/local-connection.d.ts +111 -0
  32. package/dist/cli/local-connection.js +151 -0
  33. package/dist/cli/migrate-deployment-intent.d.ts +132 -0
  34. package/dist/cli/migrate-deployment-intent.js +1552 -0
  35. package/dist/cli/migrate-operation-declaration.d.ts +70 -0
  36. package/dist/cli/migrate-operation-declaration.js +2206 -0
  37. package/dist/cli/migrate-operation-shape.d.ts +44 -0
  38. package/dist/cli/migrate-operation-shape.js +113 -0
  39. package/dist/cli/migrate-provider-shape.d.ts +56 -0
  40. package/dist/cli/migrate-provider-shape.js +580 -0
  41. package/dist/cli/resolver-runtime.d.ts +21 -0
  42. package/dist/cli/resolver-runtime.js +31 -0
  43. package/dist/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
  44. package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
  45. package/dist/cli/templates/provider/README.md.tpl +41 -19
  46. package/dist/cli/templates/provider/index.ts.tpl +6 -3
  47. package/dist/cli/templates/provider/operations/ping.ts.tpl +4 -1
  48. package/dist/cli/templates/provider/provider.json.tpl +6 -0
  49. package/dist/config/loader.d.ts +202 -16
  50. package/dist/config/loader.js +491 -141
  51. package/dist/contract-serialization.js +4 -8
  52. package/dist/contract-types.d.ts +12 -5
  53. package/dist/contract.js +24 -10
  54. package/dist/declaration-validation.d.ts +34 -0
  55. package/dist/declaration-validation.js +305 -0
  56. package/dist/define.d.ts +71 -29
  57. package/dist/define.js +807 -69
  58. package/dist/dev.d.ts +5 -0
  59. package/dist/dev.js +8 -1
  60. package/dist/engine.d.ts +129 -0
  61. package/dist/engine.js +209 -0
  62. package/dist/error-observability.d.ts +7 -0
  63. package/dist/error-observability.js +61 -0
  64. package/dist/error-resolution.d.ts +18 -0
  65. package/dist/error-resolution.js +243 -0
  66. package/dist/errors.d.ts +74 -0
  67. package/dist/errors.js +99 -0
  68. package/dist/fixture-sanitization.d.ts +28 -0
  69. package/dist/fixture-sanitization.js +371 -0
  70. package/dist/handle-meta.d.ts +90 -0
  71. package/dist/handle-meta.js +73 -0
  72. package/dist/handle.d.ts +226 -0
  73. package/dist/handle.js +345 -0
  74. package/dist/health-scenario.d.ts +1901 -0
  75. package/dist/health-scenario.js +653 -0
  76. package/dist/i18n/catalog.js +21 -1
  77. package/dist/i18n/error-messages.d.ts +86 -0
  78. package/dist/i18n/error-messages.js +192 -0
  79. package/dist/i18n/index.d.ts +1 -0
  80. package/dist/i18n/index.js +1 -0
  81. package/dist/i18n/keys.d.ts +12 -0
  82. package/dist/i18n/keys.js +76 -5
  83. package/dist/i18n/operation-locale-namespace.d.ts +2 -0
  84. package/dist/i18n/operation-locale-namespace.js +7 -0
  85. package/dist/index.d.ts +40 -15
  86. package/dist/index.js +29 -11
  87. package/dist/lint.d.ts +43 -11
  88. package/dist/lint.js +2512 -177
  89. package/dist/native-address.d.ts +43 -0
  90. package/dist/native-address.js +281 -0
  91. package/dist/native-egress-policy.d.ts +31 -0
  92. package/dist/native-egress-policy.js +288 -0
  93. package/dist/observability.d.ts +5 -2
  94. package/dist/observability.js +48 -1
  95. package/dist/provider.d.ts +18 -8
  96. package/dist/provider.js +11 -6
  97. package/dist/runtime/auth-flow.d.ts +6 -1
  98. package/dist/runtime/auth-flow.js +8 -0
  99. package/dist/runtime/bounded-expiring-map.d.ts +21 -0
  100. package/dist/runtime/bounded-expiring-map.js +64 -0
  101. package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
  102. package/dist/runtime/browser-telemetry-binding.js +83 -0
  103. package/dist/runtime/browser-telemetry.d.ts +76 -0
  104. package/dist/runtime/browser-telemetry.js +165 -0
  105. package/dist/runtime/browser.d.ts +4 -0
  106. package/dist/runtime/browser.js +688 -83
  107. package/dist/runtime/cache-telemetry.d.ts +71 -0
  108. package/dist/runtime/cache-telemetry.js +177 -0
  109. package/dist/runtime/cache.d.ts +3 -0
  110. package/dist/runtime/cache.js +245 -23
  111. package/dist/runtime/capability-response.d.ts +3 -0
  112. package/dist/runtime/capability-response.js +56 -0
  113. package/dist/runtime/capability-telemetry.d.ts +46 -0
  114. package/dist/runtime/capability-telemetry.js +68 -0
  115. package/dist/runtime/chrome149-header-order.d.ts +58 -0
  116. package/dist/runtime/chrome149-header-order.js +289 -0
  117. package/dist/runtime/diagnostic-env-values.d.ts +5 -0
  118. package/dist/runtime/diagnostic-env-values.js +57 -0
  119. package/dist/runtime/diagnostic-env.d.ts +14 -0
  120. package/dist/runtime/diagnostic-env.js +44 -0
  121. package/dist/runtime/diagnostic-redactor.d.ts +54 -0
  122. package/dist/runtime/diagnostic-redactor.js +571 -0
  123. package/dist/runtime/egress-lease.d.ts +65 -0
  124. package/dist/runtime/egress-lease.js +236 -0
  125. package/dist/runtime/engine-mode.d.ts +74 -0
  126. package/dist/runtime/engine-mode.js +152 -0
  127. package/dist/runtime/env.js +14 -1
  128. package/dist/runtime/executor.d.ts +3 -2
  129. package/dist/runtime/executor.js +23 -26
  130. package/dist/runtime/handle-wordlist.d.ts +43 -0
  131. package/dist/runtime/handle-wordlist.js +256 -0
  132. package/dist/runtime/handle.d.ts +71 -0
  133. package/dist/runtime/handle.js +908 -0
  134. package/dist/runtime/http-telemetry-binding.d.ts +10 -0
  135. package/dist/runtime/http-telemetry-binding.js +152 -0
  136. package/dist/runtime/http-telemetry-guard.d.ts +16 -0
  137. package/dist/runtime/http-telemetry-guard.js +202 -0
  138. package/dist/runtime/http-telemetry.d.ts +104 -0
  139. package/dist/runtime/http-telemetry.js +190 -0
  140. package/dist/runtime/http.d.ts +34 -0
  141. package/dist/runtime/http.js +680 -121
  142. package/dist/runtime/insights.js +2 -2
  143. package/dist/runtime/instrumentation.d.ts +2 -2
  144. package/dist/runtime/instrumentation.js +462 -19
  145. package/dist/runtime/native-network-errors.d.ts +33 -0
  146. package/dist/runtime/native-network-errors.js +69 -0
  147. package/dist/runtime/native-network.d.ts +105 -0
  148. package/dist/runtime/native-network.js +1433 -0
  149. package/dist/runtime/native-telemetry.d.ts +142 -0
  150. package/dist/runtime/native-telemetry.js +231 -0
  151. package/dist/runtime/ocr-telemetry.d.ts +82 -0
  152. package/dist/runtime/ocr-telemetry.js +192 -0
  153. package/dist/runtime/ocr.d.ts +29 -0
  154. package/dist/runtime/ocr.js +468 -0
  155. package/dist/runtime/otlp.d.ts +71 -2
  156. package/dist/runtime/otlp.js +398 -16
  157. package/dist/runtime/provider.d.ts +7 -0
  158. package/dist/runtime/provider.js +14 -0
  159. package/dist/runtime/proxy-errors.js +6 -2
  160. package/dist/runtime/proxy-nodemaven.d.ts +56 -0
  161. package/dist/runtime/proxy-nodemaven.js +147 -0
  162. package/dist/runtime/proxy-retry-policy.d.ts +4 -1
  163. package/dist/runtime/proxy-retry-policy.js +11 -2
  164. package/dist/runtime/proxy-telemetry.d.ts +133 -3
  165. package/dist/runtime/proxy-telemetry.js +218 -70
  166. package/dist/runtime/redirect-hop-headers.d.ts +19 -0
  167. package/dist/runtime/redirect-hop-headers.js +58 -0
  168. package/dist/runtime/redirects.d.ts +61 -0
  169. package/dist/runtime/redirects.js +149 -0
  170. package/dist/runtime/redis.d.ts +1 -1
  171. package/dist/runtime/redis.js +4 -2
  172. package/dist/runtime/request-options.d.ts +75 -1
  173. package/dist/runtime/request-options.js +588 -0
  174. package/dist/runtime/request-telemetry.d.ts +70 -0
  175. package/dist/runtime/request-telemetry.js +229 -0
  176. package/dist/runtime/resolver-config.d.ts +13 -0
  177. package/dist/runtime/resolver-config.js +14 -0
  178. package/dist/runtime/resolver-public.d.ts +3 -0
  179. package/dist/runtime/resolver-public.js +1 -0
  180. package/dist/runtime/resolver-runtime-options.d.ts +14 -0
  181. package/dist/runtime/resolver-runtime-options.js +33 -0
  182. package/dist/runtime/resolver-shared.d.ts +24 -0
  183. package/dist/runtime/resolver-shared.js +69 -0
  184. package/dist/runtime/resolver-span-attributes.d.ts +34 -0
  185. package/dist/runtime/resolver-span-attributes.js +93 -0
  186. package/dist/runtime/resolver-telemetry.d.ts +135 -0
  187. package/dist/runtime/resolver-telemetry.js +204 -0
  188. package/dist/runtime/resolver-usage.d.ts +32 -0
  189. package/dist/runtime/resolver-usage.js +54 -0
  190. package/dist/runtime/resolver-vendors/bindings.d.ts +53 -0
  191. package/dist/runtime/resolver-vendors/bindings.js +45 -0
  192. package/dist/runtime/resolver-vendors/browser.d.ts +24 -0
  193. package/dist/runtime/resolver-vendors/browser.js +423 -0
  194. package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
  195. package/dist/runtime/resolver-vendors/capsolver.js +544 -0
  196. package/dist/runtime/resolver-vendors/hosts.d.ts +23 -0
  197. package/dist/runtime/resolver-vendors/hosts.js +68 -0
  198. package/dist/runtime/resolver-vendors/hypersolutions.d.ts +27 -0
  199. package/dist/runtime/resolver-vendors/hypersolutions.js +369 -0
  200. package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
  201. package/dist/runtime/resolver-vendors/twocaptcha.js +425 -0
  202. package/dist/runtime/resolver-vendors/types.d.ts +125 -0
  203. package/dist/runtime/resolver-vendors/types.js +106 -0
  204. package/dist/runtime/resolver.d.ts +79 -0
  205. package/dist/runtime/resolver.js +1094 -0
  206. package/dist/runtime/state-telemetry.d.ts +79 -0
  207. package/dist/runtime/state-telemetry.js +194 -0
  208. package/dist/runtime/state.d.ts +10 -1
  209. package/dist/runtime/state.js +322 -82
  210. package/dist/runtime/stealth-akamai-sbsd.d.ts +54 -0
  211. package/dist/runtime/stealth-akamai-sbsd.js +142 -0
  212. package/dist/runtime/stealth-cookies.d.ts +24 -0
  213. package/dist/runtime/stealth-cookies.js +131 -0
  214. package/dist/runtime/stealth-owned-headers.d.ts +39 -0
  215. package/dist/runtime/stealth-owned-headers.js +57 -0
  216. package/dist/runtime/stealth-telemetry.d.ts +92 -0
  217. package/dist/runtime/stealth-telemetry.js +179 -0
  218. package/dist/runtime/stealth.d.ts +45 -6
  219. package/dist/runtime/stealth.js +1775 -320
  220. package/dist/runtime/stt-telemetry.d.ts +77 -0
  221. package/dist/runtime/stt-telemetry.js +176 -0
  222. package/dist/runtime/stt.js +18 -19
  223. package/dist/runtime/timeout.d.ts +5 -0
  224. package/dist/runtime/timeout.js +12 -0
  225. package/dist/runtime/trace-config.d.ts +12 -0
  226. package/dist/runtime/trace-config.js +62 -0
  227. package/dist/runtime/trace.d.ts +17 -0
  228. package/dist/runtime/trace.js +176 -25
  229. package/dist/runtime-boundary-lint.d.ts +137 -0
  230. package/dist/runtime-boundary-lint.js +590 -0
  231. package/dist/schema.d.ts +20 -0
  232. package/dist/schema.js +72 -2
  233. package/dist/serve.d.ts +1 -1
  234. package/dist/serve.js +1 -1
  235. package/dist/server/error-observability.d.ts +1 -0
  236. package/dist/server/error-observability.js +1 -0
  237. package/dist/server/error-stack-frames.d.ts +35 -0
  238. package/dist/server/error-stack-frames.js +219 -0
  239. package/dist/server/index.d.ts +21 -2
  240. package/dist/server/index.js +11 -2
  241. package/dist/server/runtime-diagnostics.d.ts +165 -0
  242. package/dist/server/runtime-diagnostics.js +360 -0
  243. package/dist/server/sdk-version.d.ts +3 -0
  244. package/dist/server/sdk-version.js +19 -0
  245. package/dist/server/self-test-input-tokens.d.ts +2 -1
  246. package/dist/server/self-test-input-tokens.js +18 -14
  247. package/dist/server/self-test-redaction.js +8 -33
  248. package/dist/server/self-test.d.ts +18 -3
  249. package/dist/server/self-test.js +139 -76
  250. package/dist/server/sensitive-values.d.ts +26 -0
  251. package/dist/server/sensitive-values.js +137 -0
  252. package/dist/server/serve-implementation.d.ts +285 -0
  253. package/dist/server/serve-implementation.js +3172 -0
  254. package/dist/server/serve.d.ts +1 -75
  255. package/dist/server/serve.js +1 -1170
  256. package/dist/server/state-backend-report.d.ts +70 -0
  257. package/dist/server/state-backend-report.js +113 -0
  258. package/dist/server/trace-output.d.ts +7 -0
  259. package/dist/server/trace-output.js +111 -0
  260. package/dist/server/types.d.ts +37 -5
  261. package/dist/server/types.js +34 -1
  262. package/dist/stateful/errors.d.ts +19 -0
  263. package/dist/stateful/errors.js +24 -0
  264. package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
  265. package/dist/stateful/http-provider-event-emitter.js +237 -0
  266. package/dist/stateful/http-session-owner-registry.d.ts +44 -0
  267. package/dist/stateful/http-session-owner-registry.js +210 -0
  268. package/dist/stateful/index.d.ts +18 -0
  269. package/dist/stateful/index.js +18 -0
  270. package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
  271. package/dist/stateful/provider-event-delivery-failures.js +43 -0
  272. package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
  273. package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
  274. package/dist/stateful/provider-event-pipeline.d.ts +50 -0
  275. package/dist/stateful/provider-event-pipeline.js +1 -0
  276. package/dist/stateful/provider-events.d.ts +101 -0
  277. package/dist/stateful/provider-events.js +289 -0
  278. package/dist/stateful/session-key.d.ts +15 -0
  279. package/dist/stateful/session-key.js +86 -0
  280. package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
  281. package/dist/stateful/stateful-provider-adapter-context.js +42 -0
  282. package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
  283. package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
  284. package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
  285. package/dist/stateful/stateful-provider-adapter.js +287 -0
  286. package/dist/stateful/stateful-provider-observability.d.ts +62 -0
  287. package/dist/stateful/stateful-provider-observability.js +161 -0
  288. package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
  289. package/dist/stateful/stateful-provider-owner-forwarder.js +237 -0
  290. package/dist/stateful/stateful-provider-runtime-context.d.ts +35 -0
  291. package/dist/stateful/stateful-provider-runtime-context.js +61 -0
  292. package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
  293. package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
  294. package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
  295. package/dist/stateful/stateful-provider-session-routing.js +345 -0
  296. package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
  297. package/dist/stateful/stateful-provider-session-runtime.js +245 -0
  298. package/dist/stateful-signing.d.ts +18 -0
  299. package/dist/stateful-signing.js +27 -0
  300. package/dist/stealth/profiles.d.ts +15 -4
  301. package/dist/stealth/profiles.js +169 -211
  302. package/dist/stream-evidence.d.ts +74 -0
  303. package/dist/stream-evidence.js +785 -0
  304. package/dist/stream.js +7 -1
  305. package/dist/testing/index.d.ts +2 -1
  306. package/dist/testing/index.js +2 -1
  307. package/dist/testing/run.d.ts +32 -2
  308. package/dist/testing/run.js +509 -25
  309. package/dist/trace-sanitization.d.ts +6 -0
  310. package/dist/trace-sanitization.js +68 -0
  311. package/dist/types.d.ts +899 -210
  312. package/dist/types.js +1 -0
  313. package/dist/typescript-module.d.ts +39 -0
  314. package/dist/typescript-module.js +72 -0
  315. package/package.json +52 -6
  316. package/src/auth-turn/index.ts +1 -1
  317. package/src/auth.ts +118 -0
  318. package/src/ceremonies/index.ts +189 -46
  319. package/src/cli/commands.ts +37 -0
  320. package/src/cli/create.ts +8 -2
  321. package/src/cli/deployment-intent.ts +364 -0
  322. package/src/cli/local-connection.ts +221 -0
  323. package/src/cli/migrate-deployment-intent.ts +1908 -0
  324. package/src/cli/migrate-operation-declaration.ts +3026 -0
  325. package/src/cli/migrate-operation-shape.ts +184 -0
  326. package/src/cli/migrate-provider-shape.ts +778 -0
  327. package/src/cli/resolver-runtime.ts +72 -0
  328. package/src/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
  329. package/src/cli/templates/provider/Dockerfile.tpl +1 -1
  330. package/src/cli/templates/provider/README.md.tpl +41 -19
  331. package/src/cli/templates/provider/index.ts.tpl +6 -3
  332. package/src/cli/templates/provider/operations/ping.ts.tpl +4 -1
  333. package/src/cli/templates/provider/provider.json.tpl +6 -0
  334. package/src/config/loader.ts +774 -181
  335. package/src/contract-serialization.ts +5 -7
  336. package/src/contract-types.ts +12 -5
  337. package/src/contract.ts +24 -10
  338. package/src/declaration-validation.ts +376 -0
  339. package/src/define.ts +1105 -131
  340. package/src/dev.ts +13 -1
  341. package/src/engine.ts +390 -0
  342. package/src/error-observability.ts +64 -0
  343. package/src/error-resolution.ts +269 -0
  344. package/src/errors.ts +157 -0
  345. package/src/fixture-sanitization.ts +422 -0
  346. package/src/handle-meta.ts +143 -0
  347. package/src/handle.ts +694 -0
  348. package/src/health-scenario.ts +960 -0
  349. package/src/i18n/catalog.ts +23 -1
  350. package/src/i18n/error-messages.ts +255 -0
  351. package/src/i18n/index.ts +1 -0
  352. package/src/i18n/keys.ts +80 -6
  353. package/src/i18n/operation-locale-namespace.ts +10 -0
  354. package/src/index.ts +390 -23
  355. package/src/lint.ts +2975 -234
  356. package/src/native-address.ts +340 -0
  357. package/src/native-egress-policy.ts +358 -0
  358. package/src/observability.ts +51 -1
  359. package/src/provider.ts +207 -27
  360. package/src/runtime/auth-flow.ts +15 -0
  361. package/src/runtime/bounded-expiring-map.ts +67 -0
  362. package/src/runtime/browser-telemetry-binding.ts +92 -0
  363. package/src/runtime/browser-telemetry.ts +289 -0
  364. package/src/runtime/browser.ts +882 -99
  365. package/src/runtime/cache-telemetry.ts +247 -0
  366. package/src/runtime/cache.ts +258 -22
  367. package/src/runtime/capability-response.ts +53 -0
  368. package/src/runtime/capability-telemetry.ts +101 -0
  369. package/src/runtime/chrome149-header-order.ts +330 -0
  370. package/src/runtime/diagnostic-env-values.ts +56 -0
  371. package/src/runtime/diagnostic-env.ts +65 -0
  372. package/src/runtime/diagnostic-redactor.ts +668 -0
  373. package/src/runtime/egress-lease.ts +341 -0
  374. package/src/runtime/engine-mode.ts +233 -0
  375. package/src/runtime/env.ts +15 -1
  376. package/src/runtime/executor.ts +39 -32
  377. package/src/runtime/handle-wordlist.ts +266 -0
  378. package/src/runtime/handle.ts +1180 -0
  379. package/src/runtime/http-telemetry-binding.ts +162 -0
  380. package/src/runtime/http-telemetry-guard.ts +208 -0
  381. package/src/runtime/http-telemetry.ts +292 -0
  382. package/src/runtime/http.ts +896 -150
  383. package/src/runtime/insights.ts +2 -2
  384. package/src/runtime/instrumentation.ts +628 -28
  385. package/src/runtime/native-network-errors.ts +99 -0
  386. package/src/runtime/native-network.ts +1853 -0
  387. package/src/runtime/native-telemetry.ts +366 -0
  388. package/src/runtime/ocr-telemetry.ts +308 -0
  389. package/src/runtime/ocr.ts +564 -0
  390. package/src/runtime/otlp.ts +468 -21
  391. package/src/runtime/provider.ts +15 -0
  392. package/src/runtime/proxy-errors.ts +12 -4
  393. package/src/runtime/proxy-nodemaven.ts +222 -0
  394. package/src/runtime/proxy-retry-policy.ts +12 -1
  395. package/src/runtime/proxy-telemetry.ts +358 -103
  396. package/src/runtime/redirect-hop-headers.ts +71 -0
  397. package/src/runtime/redirects.ts +215 -0
  398. package/src/runtime/redis.ts +7 -2
  399. package/src/runtime/request-options.ts +728 -1
  400. package/src/runtime/request-telemetry.ts +375 -0
  401. package/src/runtime/resolver-config.ts +18 -0
  402. package/src/runtime/resolver-public.ts +44 -0
  403. package/src/runtime/resolver-runtime-options.ts +50 -0
  404. package/src/runtime/resolver-shared.ts +113 -0
  405. package/src/runtime/resolver-span-attributes.ts +139 -0
  406. package/src/runtime/resolver-telemetry.ts +362 -0
  407. package/src/runtime/resolver-usage.ts +99 -0
  408. package/src/runtime/resolver-vendors/bindings.ts +61 -0
  409. package/src/runtime/resolver-vendors/browser.ts +591 -0
  410. package/src/runtime/resolver-vendors/capsolver.ts +727 -0
  411. package/src/runtime/resolver-vendors/hosts.ts +81 -0
  412. package/src/runtime/resolver-vendors/hypersolutions.ts +480 -0
  413. package/src/runtime/resolver-vendors/twocaptcha.ts +555 -0
  414. package/src/runtime/resolver-vendors/types.ts +261 -0
  415. package/src/runtime/resolver.ts +1543 -0
  416. package/src/runtime/state-telemetry.ts +298 -0
  417. package/src/runtime/state.ts +435 -89
  418. package/src/runtime/stealth-akamai-sbsd.ts +207 -0
  419. package/src/runtime/stealth-cookies.ts +155 -0
  420. package/src/runtime/stealth-owned-headers.ts +67 -0
  421. package/src/runtime/stealth-telemetry.ts +309 -0
  422. package/src/runtime/stealth.ts +2275 -372
  423. package/src/runtime/stt-telemetry.ts +282 -0
  424. package/src/runtime/stt.ts +96 -91
  425. package/src/runtime/timeout.ts +18 -0
  426. package/src/runtime/trace-config.ts +78 -0
  427. package/src/runtime/trace.ts +257 -35
  428. package/src/runtime-boundary-lint.ts +707 -0
  429. package/src/schema.ts +80 -2
  430. package/src/serve.ts +6 -1
  431. package/src/server/error-observability.ts +1 -0
  432. package/src/server/error-stack-frames.ts +214 -0
  433. package/src/server/index.ts +184 -2
  434. package/src/server/runtime-diagnostics.ts +522 -0
  435. package/src/server/sdk-version.ts +22 -0
  436. package/src/server/self-test-input-tokens.ts +29 -14
  437. package/src/server/self-test-redaction.ts +10 -40
  438. package/src/server/self-test.ts +205 -89
  439. package/src/server/sensitive-values.ts +211 -0
  440. package/src/server/serve-implementation.ts +4596 -0
  441. package/src/server/serve.ts +1 -1685
  442. package/src/server/state-backend-report.ts +185 -0
  443. package/src/server/trace-output.ts +189 -0
  444. package/src/server/types.ts +34 -1
  445. package/src/stateful/README.md +146 -0
  446. package/src/stateful/errors.ts +35 -0
  447. package/src/stateful/http-provider-event-emitter.ts +314 -0
  448. package/src/stateful/http-session-owner-registry.ts +306 -0
  449. package/src/stateful/index.ts +18 -0
  450. package/src/stateful/provider-event-delivery-failures.ts +80 -0
  451. package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
  452. package/src/stateful/provider-event-pipeline.ts +61 -0
  453. package/src/stateful/provider-events.ts +462 -0
  454. package/src/stateful/session-key.ts +111 -0
  455. package/src/stateful/stateful-provider-adapter-context.ts +59 -0
  456. package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
  457. package/src/stateful/stateful-provider-adapter.ts +562 -0
  458. package/src/stateful/stateful-provider-observability.ts +261 -0
  459. package/src/stateful/stateful-provider-owner-forwarder.ts +310 -0
  460. package/src/stateful/stateful-provider-runtime-context.ts +96 -0
  461. package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
  462. package/src/stateful/stateful-provider-session-routing.ts +546 -0
  463. package/src/stateful/stateful-provider-session-runtime.ts +403 -0
  464. package/src/stateful-signing.ts +46 -0
  465. package/src/stealth/profiles.ts +212 -231
  466. package/src/stream-evidence.ts +988 -0
  467. package/src/stream.ts +8 -1
  468. package/src/testing/index.ts +10 -1
  469. package/src/testing/run.ts +685 -19
  470. package/src/trace-sanitization.ts +110 -0
  471. package/src/types.ts +1014 -273
  472. package/src/typescript-module.ts +100 -0
  473. package/dist/choice-token.d.ts +0 -24
  474. package/dist/choice-token.js +0 -74
  475. package/dist/runtime/choice.d.ts +0 -15
  476. package/dist/runtime/choice.js +0 -413
  477. package/src/choice-token.ts +0 -165
  478. package/src/runtime/choice.ts +0 -686
@@ -1,6 +1,11 @@
1
- import { isSessionExpiredError, ProviderError, SessionExpiredError } from "../errors.js";
1
+ import {
2
+ isValidationError,
3
+ ProviderError,
4
+ ValidationError,
5
+ } from "../errors.js";
6
+ import { z } from "zod";
2
7
  import { parseSchema } from "../schema.js";
3
- import type { ProviderContext, ProviderDefinition } from "../types.js";
8
+ import type { EnvContext, ProviderDefinition } from "../types.js";
4
9
  import { assertRequiredSecretsPresent } from "./secrets.js";
5
10
 
6
11
  export function isStreamingOperation(provider: ProviderDefinition, operationId: string): boolean {
@@ -19,18 +24,24 @@ export function isStreamingOperation(provider: ProviderDefinition, operationId:
19
24
  *
20
25
  * @see openspec/provider-sdk/03-sdk-core.md §3.6
21
26
  */
22
- export async function executeOperation(
23
- provider: ProviderDefinition,
24
- operationId: string,
25
- ctx: ProviderContext,
27
+ export async function executeOperation<
28
+ const TProvider extends ProviderDefinition,
29
+ const TOperationId extends keyof TProvider["operations"] & string,
30
+ >(
31
+ provider: TProvider,
32
+ operationId: TOperationId,
33
+ ctx: NoInfer<Parameters<TProvider["operations"][TOperationId]["handler"]>[0]>,
26
34
  input: unknown,
27
- _options?: { skipAuth?: boolean },
35
+ _options?: { skipAuth?: boolean; env?: EnvContext },
28
36
  ): Promise<unknown> {
29
37
  const operation = provider.operations[operationId];
30
38
 
31
39
  if (!operation) {
32
40
  throw new ProviderError(`Unknown operation: ${provider.id}/${operationId}`, {
33
41
  code: "NOT_FOUND",
42
+ // No upstream was asked: keep the registered NOT_FOUND code from
43
+ // attributing this to one.
44
+ category: "provider_error",
34
45
  fix: `Valid operations: ${Object.keys(provider.operations).join(", ")}`,
35
46
  });
36
47
  }
@@ -40,7 +51,12 @@ export async function executeOperation(
40
51
  // handler, so every invocation path (serve /v1, self-test probes, perf,
41
52
  // record) fails with the same structured MISSING_SECRET error instead of a
42
53
  // handler-specific crash. Providers must not re-check presence locally.
43
- assertRequiredSecretsPresent(provider, ctx.env);
54
+ if (provider.secrets?.some((secret) => secret.required === true)) {
55
+ assertRequiredSecretsPresent(
56
+ provider,
57
+ _options?.env ?? ("env" in ctx ? ctx.env : { get: () => undefined }),
58
+ );
59
+ }
44
60
 
45
61
  const validatedInput = await parseSchema(
46
62
  operation.input,
@@ -53,33 +69,24 @@ export async function executeOperation(
53
69
  Promise.resolve(operation.handler(ctx, validatedInput)),
54
70
  );
55
71
 
56
- let result: unknown;
57
- try {
58
- result = await execute();
59
- } catch (error) {
60
- // Session expiry is renewed by Credential Service via the /auth/refresh
61
- // route, NOT in-process here: this executor cannot mutate ctx.credential,
62
- // so an in-process retry would just repeat the call with the same stale
63
- // credential (and risk repeating partial side-effects). Instead we surface
64
- // the expiry so Credential Service refreshes and re-drives the operation
65
- // with a fresh credential. `retryOnAuthRefresh` declares that this
66
- // operation is safe to re-drive after refresh, which we signal by marking
67
- // the surfaced error retryable; non-idempotent operations (the default)
68
- // stay non-retryable so they are not auto-re-driven. See design.md §4.3 D3.
69
- // Use the branded guard, not `instanceof`: a handler loaded through a
70
- // duplicate/published SDK module can throw a correctly branded
71
- // SessionExpiredError whose constructor identity differs from this
72
- // executor's, which `instanceof` would miss — dropping the retryable
73
- // upgrade and stranding an operation that opted into auth refresh.
74
- if (isSessionExpiredError(error) && operation.retryOnAuthRefresh) {
75
- throw new SessionExpiredError(error.message, { retryable: true });
76
- }
77
- throw error;
78
- }
72
+ const result: unknown = await execute();
79
73
 
80
74
  if (isStreamingOperation(provider, operationId)) {
81
75
  return result;
82
76
  }
83
77
 
84
- return parseSchema(operation.output, result, `operations.${operationId}.output`);
78
+ try {
79
+ return await parseSchema(operation.output, result, `operations.${operationId}.output`);
80
+ } catch (cause) {
81
+ if (!(cause instanceof z.ZodError) && !isValidationError(cause)) {
82
+ throw cause;
83
+ }
84
+ throw new ValidationError(`Operation handler output failed schema validation.`, {
85
+ code: "OUTPUT_VALIDATION_FAILED",
86
+ category: "output_validation",
87
+ retryable: false,
88
+ zodError: isValidationError(cause) ? cause.zodError : cause,
89
+ ...(cause instanceof Error ? { cause } : {}),
90
+ });
91
+ }
85
92
  }
@@ -0,0 +1,266 @@
1
+ /**
2
+ * Official EFF Short Wordlist #2, embedded unchanged from:
3
+ * https://www.eff.org/files/2016/09/08/eff_short_wordlist_2_0.txt
4
+ *
5
+ * The source's dice-roll column is intentionally omitted; word order is preserved.
6
+ */
7
+ const EFF_SHORT_WORDLIST_2_TEXT = `
8
+ aardvark abandoned abbreviate abdomen abhorrence abiding abnormal abrasion absorbing abundant abyss
9
+ academy accountant acetone achiness acid acoustics acquire acrobat actress acuteness aerosol
10
+ aesthetic affidavit afloat afraid aftershave again agency aggressor aghast agitate agnostic
11
+ agonizing agreeing aidless aimlessly ajar alarmclock albatross alchemy alfalfa algae aliens
12
+ alkaline almanac alongside alphabet already also altitude aluminum always amazingly ambulance
13
+ amendment amiable ammunition amnesty amoeba amplifier amuser anagram anchor android anesthesia
14
+ angelfish animal anklet announcer anonymous answer antelope anxiety anyplace aorta apartment apnea
15
+ apostrophe apple apricot aquamarine arachnid arbitrate ardently arena argument aristocrat armchair
16
+ aromatic arrowhead arsonist artichoke asbestos ascend aseptic ashamed asinine asleep asocial
17
+ asparagus astronaut asymmetric atlas atmosphere atom atrocious attic atypical auctioneer auditorium
18
+ augmented auspicious automobile auxiliary avalanche avenue aviator avocado awareness awhile awkward
19
+ awning awoke axially azalea babbling backpack badass bagpipe bakery balancing bamboo banana
20
+ barracuda basket bathrobe bazooka blade blender blimp blouse blurred boatyard bobcat body bogusness
21
+ bohemian boiler bonnet boots borough bossiness bottle bouquet boxlike breath briefcase broom
22
+ brushes bubblegum buckle buddhist buffalo bullfrog bunny busboy buzzard cabin cactus cadillac
23
+ cafeteria cage cahoots cajoling cakewalk calculator camera canister capsule carrot cashew cathedral
24
+ caucasian caviar ceasefire cedar celery cement census ceramics cesspool chalkboard cheesecake
25
+ chimney chlorine chopsticks chrome chute cilantro cinnamon circle cityscape civilian clay clergyman
26
+ clipboard clock clubhouse coathanger cobweb coconut codeword coexistent coffeecake cognitive
27
+ cohabitate collarbone computer confetti copier cornea cosmetics cotton couch coverless coyote
28
+ coziness crawfish crewmember crib croissant crumble crystal cubical cucumber cuddly cufflink
29
+ cuisine culprit cup curry cushion cuticle cybernetic cyclist cylinder cymbal cynicism cypress
30
+ cytoplasm dachshund daffodil dagger dairy dalmatian dandelion dartboard dastardly datebook daughter
31
+ dawn daytime dazzler dealer debris decal dedicate deepness defrost degree dehydrator deliverer
32
+ democrat dentist deodorant depot deranged desktop detergent device dexterity diamond dibs
33
+ dictionary diffuser digit dilated dimple dinnerware dioxide diploma directory dishcloth ditto
34
+ dividers dizziness doctor dodge doll dominoes donut doorstep dorsal double downstairs dozed
35
+ drainpipe dresser driftwood droppings drum dryer dubiously duckling duffel dugout dumpster duplex
36
+ durable dustpan dutiful duvet dwarfism dwelling dwindling dynamite dyslexia eagerness earlobe easel
37
+ eavesdrop ebook eccentric echoless eclipse ecosystem ecstasy edged editor educator eelworm eerie
38
+ effects eggnog egomaniac ejection elastic elbow elderly elephant elfishly eliminator elk elliptical
39
+ elongated elsewhere elusive elves emancipate embroidery emcee emerald emission emoticon emperor
40
+ emulate enactment enchilada endorphin energy enforcer engine enhance enigmatic enjoyably enlarged
41
+ enormous enquirer enrollment ensemble entryway enunciate envoy enzyme epidemic equipment erasable
42
+ ergonomic erratic eruption escalator eskimo esophagus espresso essay estrogen etching eternal
43
+ ethics etiquette eucalyptus eulogy euphemism euthanize evacuation evergreen evidence evolution exam
44
+ excerpt exerciser exfoliate exhale exist exorcist explode exquisite exterior exuberant fabric
45
+ factory faded failsafe falcon family fanfare fasten faucet favorite feasibly february federal
46
+ feedback feigned feline femur fence ferret festival fettuccine feudalist feverish fiberglass
47
+ fictitious fiddle figurine fillet finalist fiscally fixture flashlight fleshiness flight florist
48
+ flypaper foamless focus foggy folksong fondue footpath fossil fountain fox fragment freeway fridge
49
+ frosting fruit fryingpan gadget gainfully gallstone gamekeeper gangway garlic gaslight gathering
50
+ gauntlet gearbox gecko gem generator geographer gerbil gesture getaway geyser ghoulishly gibberish
51
+ giddiness giftshop gigabyte gimmick giraffe giveaway gizmo glasses gleeful glisten glove glucose
52
+ glycerin gnarly gnomish goatskin goggles goldfish gong gooey gorgeous gosling gothic gourmet
53
+ governor grape greyhound grill groundhog grumbling guacamole guerrilla guitar gullible gumdrop
54
+ gurgling gusto gutless gymnast gynecology gyration habitat hacking haggard haiku halogen hamburger
55
+ handgun happiness hardhat hastily hatchling haughty hazelnut headband hedgehog hefty heinously
56
+ helmet hemoglobin henceforth herbs hesitation hexagon hubcap huddling huff hugeness hullabaloo
57
+ human hunter hurricane hushing hyacinth hybrid hydrant hygienist hypnotist ibuprofen icepack icing
58
+ iconic identical idiocy idly igloo ignition iguana illuminate imaging imbecile imitator immigrant
59
+ imprint iodine ionosphere ipad iphone iridescent irksome iron irrigation island isotope issueless
60
+ italicize itemizer itinerary itunes ivory jabbering jackrabbit jaguar jailhouse jalapeno jamboree
61
+ janitor jarring jasmine jaundice jawbreaker jaywalker jazz jealous jeep jelly jeopardize jersey
62
+ jetski jezebel jiffy jigsaw jingling jobholder jockstrap jogging john joinable jokingly journal
63
+ jovial joystick jubilant judiciary juggle juice jujitsu jukebox jumpiness junkyard juror justifying
64
+ juvenile kabob kamikaze kangaroo karate kayak keepsake kennel kerosene ketchup khaki kickstand
65
+ kilogram kimono kingdom kiosk kissing kite kleenex knapsack kneecap knickers koala krypton
66
+ laboratory ladder lakefront lantern laptop laryngitis lasagna latch laundry lavender laxative
67
+ lazybones lecturer leftover leggings leisure lemon length leopard leprechaun lettuce leukemia
68
+ levers lewdness liability library licorice lifeboat lightbulb likewise lilac limousine lint lioness
69
+ lipstick liquid listless litter liverwurst lizard llama luau lubricant lucidity ludicrous luggage
70
+ lukewarm lullaby lumberjack lunchbox luridness luscious luxurious lyrics macaroni maestro magazine
71
+ mahogany maimed majority makeover malformed mammal mango mapmaker marbles massager matchstick
72
+ maverick maximum mayonnaise moaning mobilize moccasin modify moisture molecule momentum monastery
73
+ moonshine mortuary mosquito motorcycle mousetrap movie mower mozzarella muckiness mudflow mugshot
74
+ mule mummy mundane muppet mural mustard mutation myriad myspace myth nail namesake nanosecond
75
+ napkin narrator nastiness natives nautically navigate nearest nebula nectar nefarious negotiator
76
+ neither nemesis neoliberal nephew nervously nest netting neuron nevermore nextdoor nicotine niece
77
+ nimbleness nintendo nirvana nuclear nugget nuisance nullify numbing nuptials nursery nutcracker
78
+ nylon oasis oat obediently obituary object obliterate obnoxious observer obtain obvious occupation
79
+ oceanic octopus ocular office oftentimes oiliness ointment older olympics omissible omnivorous
80
+ oncoming onion onlooker onstage onward onyx oomph opaquely opera opium opossum opponent optical
81
+ opulently oscillator osmosis ostrich otherwise ought outhouse ovation oven owlish oxford oxidize
82
+ oxygen oyster ozone pacemaker padlock pageant pajamas palm pamphlet pantyhose paprika parakeet
83
+ passport patio pauper pavement payphone pebble peculiarly pedometer pegboard pelican penguin peony
84
+ pepperoni peroxide pesticide petroleum pewter pharmacy pheasant phonebook phrasing physician plank
85
+ pledge plotted plug plywood pneumonia podiatrist poetic pogo poison poking policeman poncho popcorn
86
+ porcupine postcard poultry powerboat prairie pretzel princess propeller prune pry pseudo psychopath
87
+ publisher pucker pueblo pulley pumpkin punchbowl puppy purse pushup putt puzzle pyramid python
88
+ quarters quesadilla quilt quote racoon radish ragweed railroad rampantly rancidity rarity raspberry
89
+ ravishing rearrange rebuilt receipt reentry refinery register rehydrate reimburse rejoicing
90
+ rekindle relic remote renovator reopen reporter request rerun reservoir retriever reunion revolver
91
+ rewrite rhapsody rhetoric rhino rhubarb rhyme ribbon riches ridden rigidness rimmed riptide riskily
92
+ ritzy riverboat roamer robe rocket romancer ropelike rotisserie roundtable royal rubber rudderless
93
+ rugby ruined rulebook rummage running rupture rustproof sabotage sacrifice saddlebag saffron
94
+ sainthood saltshaker samurai sandworm sapphire sardine sassy satchel sauna savage saxophone scarf
95
+ scenario schoolbook scientist scooter scrapbook sculpture scythe secretary sedative segregator
96
+ seismology selected semicolon senator septum sequence serpent sesame settler severely shack shelf
97
+ shirt shovel shrimp shuttle shyness siamese sibling siesta silicon simmering singles sisterhood
98
+ sitcom sixfold sizable skateboard skeleton skies skulk skylight slapping sled slingshot sloth
99
+ slumbering smartphone smelliness smitten smokestack smudge snapshot sneezing sniff snowsuit
100
+ snugness speakers sphinx spider splashing sponge sprout spur spyglass squirrel statue steamboat
101
+ stingray stopwatch strawberry student stylus suave subway suction suds suffocate sugar suitcase
102
+ sulphur superstore surfer sushi swan sweatshirt swimwear sword sycamore syllable symphony synagogue
103
+ syringes systemize tablespoon taco tadpole taekwondo tagalong takeout tallness tamale tanned
104
+ tapestry tarantula tastebud tattoo tavern thaw theater thimble thorn throat thumb thwarting tiara
105
+ tidbit tiebreaker tiger timid tinsel tiptoeing tirade tissue tractor tree tripod trousers trucks
106
+ tryout tubeless tuesday tugboat tulip tumbleweed tupperware turtle tusk tutorial tuxedo tweezers
107
+ twins tyrannical ultrasound umbrella umpire unarmored unbuttoned uncle underwear unevenness
108
+ unflavored ungloved unhinge unicycle unjustly unknown unlocking unmarked unnoticed unopened unpaved
109
+ unquenched unroll unscrewing untied unusual unveiled unwrinkled unyielding unzip upbeat upcountry
110
+ update upfront upgrade upholstery upkeep upload uppercut upright upstairs uptown upwind uranium
111
+ urban urchin urethane urgent urologist username usher utensil utility utmost utopia utterance
112
+ vacuum vagrancy valuables vanquished vaporizer varied vaseline vegetable vehicle velcro vendor
113
+ vertebrae vestibule veteran vexingly vicinity videogame viewfinder vigilante village vinegar violin
114
+ viperfish virus visor vitamins vivacious vixen vocalist vogue voicemail volleyball voucher voyage
115
+ vulnerable waffle wagon wakeup walrus wanderer wasp water waving wheat whisper wholesaler wick
116
+ widow wielder wifeless wikipedia wildcat windmill wipeout wired wishbone wizardry wobbliness
117
+ wolverine womb woolworker workbasket wound wrangle wreckage wristwatch wrongdoing xerox xylophone
118
+ yacht yahoo yard yearbook yesterday yiddish yield yo-yo yodel yogurt yuppie zealot zebra zeppelin
119
+ zestfully zigzagged zillion zipping zirconium zodiac zombie zookeeper zucchini
120
+ `;
121
+
122
+ export const HANDLE_WORDLIST_SIZE = 1_296;
123
+ export const HANDLE_WORD_ENTROPY_BITS = Math.log2(HANDLE_WORDLIST_SIZE);
124
+ /**
125
+ * Bound handles live under `state.forConnection(connectionId)`: another
126
+ * connection cannot address them at all, so no guessing analysis applies. The
127
+ * only requirement is uniqueness among live handles of one connection
128
+ * (1,296^2 = 1.68M keys, CAS-if-absent with retries), which two words satisfy.
129
+ */
130
+ export const BOUND_HANDLE_WORD_COUNT = 2;
131
+ /** Public handles are addressable by anyone; ADR 0006 §2 guessing numbers apply. */
132
+ export const PUBLIC_HANDLE_WORD_COUNT = 4;
133
+ /** Used when a public kind declares `strength: "high"` or its ttl exceeds one hour. */
134
+ export const HIGH_PUBLIC_HANDLE_WORD_COUNT = 5;
135
+ export const PUBLIC_HANDLE_ENTROPY_BITS = PUBLIC_HANDLE_WORD_COUNT * HANDLE_WORD_ENTROPY_BITS;
136
+ export const HIGH_PUBLIC_HANDLE_ENTROPY_BITS =
137
+ HIGH_PUBLIC_HANDLE_WORD_COUNT * HANDLE_WORD_ENTROPY_BITS;
138
+
139
+ export const EFF_SHORT_WORDLIST_2: readonly string[] = Object.freeze(
140
+ EFF_SHORT_WORDLIST_2_TEXT.trim().split(/\s+/),
141
+ );
142
+
143
+ const EFF_SHORT_WORD_SET: ReadonlySet<string> = new Set(EFF_SHORT_WORDLIST_2);
144
+
145
+ /**
146
+ * Words the runtime may issue. The handle grammar joins words with `-`, so the
147
+ * one hyphenated official entry (`yo-yo`) would fuse with the separator and is
148
+ * never issued. The official list itself stays embedded unchanged.
149
+ */
150
+ export const ISSUABLE_HANDLE_WORDS: readonly string[] = Object.freeze(
151
+ EFF_SHORT_WORDLIST_2.filter((word) => !word.includes("-")),
152
+ );
153
+
154
+ export function handleWordAt(index: number): string {
155
+ const word = EFF_SHORT_WORDLIST_2[index];
156
+ if (word === undefined) {
157
+ throw new RangeError(`Handle word index is out of range: ${index}`);
158
+ }
159
+ return word;
160
+ }
161
+
162
+ export function isHandleWord(value: string): boolean {
163
+ return EFF_SHORT_WORD_SET.has(value);
164
+ }
165
+
166
+ /**
167
+ * Symmetric-deletion index (SymSpell, max distance 1). Two strings at
168
+ * Levenshtein distance <= 1 always share a form reachable by deleting at most
169
+ * one character from each side, so a lookup of the query and its one-deletion
170
+ * variants yields every candidate; a real distance check then removes the false
171
+ * positives (e.g. transpositions). ~10k entries, O(len) per lookup.
172
+ */
173
+ /** Shortest and longest words in the list (3 and 10 for the official list). */
174
+ export const MIN_HANDLE_WORD_LENGTH: number = Math.min(
175
+ ...EFF_SHORT_WORDLIST_2.map((word) => word.length),
176
+ );
177
+ export const MAX_HANDLE_WORD_LENGTH: number = Math.max(
178
+ ...EFF_SHORT_WORDLIST_2.map((word) => word.length),
179
+ );
180
+
181
+ const DELETION_INDEX: ReadonlyMap<string, readonly string[]> = (() => {
182
+ const index = new Map<string, string[]>();
183
+ const add = (form: string, word: string): void => {
184
+ const bucket = index.get(form);
185
+ if (bucket === undefined) index.set(form, [word]);
186
+ else if (!bucket.includes(word)) bucket.push(word);
187
+ };
188
+ for (const word of EFF_SHORT_WORDLIST_2) {
189
+ add(word, word);
190
+ for (const variant of oneDeletionVariants(word)) add(variant, word);
191
+ }
192
+ return index;
193
+ })();
194
+
195
+ function oneDeletionVariants(value: string): string[] {
196
+ const variants: string[] = [];
197
+ for (let position = 0; position < value.length; position += 1) {
198
+ variants.push(value.slice(0, position) + value.slice(position + 1));
199
+ }
200
+ return variants;
201
+ }
202
+
203
+ /** True when Levenshtein distance between `left` and `right` is at most 1. */
204
+ function withinEditDistanceOne(left: string, right: string): boolean {
205
+ if (left === right) return true;
206
+ const lengthDelta = left.length - right.length;
207
+ if (lengthDelta > 1 || lengthDelta < -1) return false;
208
+ if (lengthDelta === 0) {
209
+ let mismatches = 0;
210
+ for (let position = 0; position < left.length; position += 1) {
211
+ if (left[position] !== right[position]) {
212
+ mismatches += 1;
213
+ if (mismatches > 1) return false;
214
+ }
215
+ }
216
+ return true;
217
+ }
218
+ const longer = lengthDelta > 0 ? left : right;
219
+ const shorter = lengthDelta > 0 ? right : left;
220
+ let longIndex = 0;
221
+ let shortIndex = 0;
222
+ let skipped = false;
223
+ while (shortIndex < shorter.length) {
224
+ if (longer[longIndex] === shorter[shortIndex]) {
225
+ longIndex += 1;
226
+ shortIndex += 1;
227
+ continue;
228
+ }
229
+ if (skipped) return false;
230
+ skipped = true;
231
+ longIndex += 1;
232
+ }
233
+ return true;
234
+ }
235
+
236
+ /**
237
+ * Resolves one handle segment to a wordlist entry: the exact word, or the
238
+ * unique word at edit distance <= `maxDistance`. Returns null when no word or
239
+ * more than one word qualifies. The official list has pairwise edit distance
240
+ * >= 3, so at distance 1 every non-null answer is unique; the uniqueness check
241
+ * is kept as a guard so a wordlist change cannot silently make normalization
242
+ * map one input onto two different canonical handles.
243
+ */
244
+ export function findHandleWordWithinDistance(segment: string, maxDistance: 1): string | null {
245
+ if (segment.length === 0) return null;
246
+ if (EFF_SHORT_WORD_SET.has(segment)) return segment;
247
+ if (maxDistance !== 1) return null;
248
+ // A segment that is more than one character shorter or longer than every
249
+ // word cannot be within distance 1 of any word. Rejecting it here also bounds
250
+ // the variant generation below (which is O(len²) in memory) against
251
+ // client-supplied garbage of arbitrary length.
252
+ if (
253
+ segment.length < MIN_HANDLE_WORD_LENGTH - maxDistance ||
254
+ segment.length > MAX_HANDLE_WORD_LENGTH + maxDistance
255
+ ) {
256
+ return null;
257
+ }
258
+ const matches = new Set<string>();
259
+ for (const form of [segment, ...oneDeletionVariants(segment)]) {
260
+ for (const candidate of DELETION_INDEX.get(form) ?? []) {
261
+ if (withinEditDistanceOne(segment, candidate)) matches.add(candidate);
262
+ }
263
+ }
264
+ if (matches.size !== 1) return null;
265
+ return matches.values().next().value ?? null;
266
+ }