@wenathlan/saddle 1.8.17 → 2.0.2

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 (1005) hide show
  1. package/Dockerfile +1339 -0
  2. package/README.md +68 -22
  3. package/alternatives.ts +1218 -0
  4. package/biome.json +153 -0
  5. package/boards.json +1517 -0
  6. package/compute.ts +3144 -0
  7. package/cores.json +1801 -0
  8. package/dist/acquisition.d.ts +359 -0
  9. package/dist/acquisition.d.ts.map +1 -0
  10. package/dist/acquisition.js +629 -0
  11. package/dist/acquisition.js.map +1 -0
  12. package/dist/alternatives.d.ts +509 -0
  13. package/dist/alternatives.d.ts.map +1 -0
  14. package/dist/alternatives.js +951 -0
  15. package/dist/alternatives.js.map +1 -0
  16. package/dist/automation.d.ts +426 -0
  17. package/dist/automation.d.ts.map +1 -0
  18. package/dist/automation.js +561 -0
  19. package/dist/automation.js.map +1 -0
  20. package/dist/browser.d.ts +562 -0
  21. package/dist/browser.d.ts.map +1 -0
  22. package/dist/browser.js +1057 -0
  23. package/dist/browser.js.map +1 -0
  24. package/dist/capacitor.config.d.ts +13 -0
  25. package/dist/capacitor.config.d.ts.map +1 -0
  26. package/dist/capacitor.config.js +26 -0
  27. package/dist/capacitor.config.js.map +1 -0
  28. package/dist/cli.d.ts +17 -0
  29. package/dist/cli.d.ts.map +1 -0
  30. package/dist/cli.js +111 -0
  31. package/dist/cli.js.map +1 -0
  32. package/dist/communication.d.ts +192 -0
  33. package/dist/communication.d.ts.map +1 -0
  34. package/dist/communication.js +418 -0
  35. package/dist/communication.js.map +1 -0
  36. package/dist/compute.d.ts +1161 -0
  37. package/dist/compute.d.ts.map +1 -0
  38. package/dist/compute.js +2273 -0
  39. package/dist/compute.js.map +1 -0
  40. package/dist/distribution.d.ts +529 -0
  41. package/dist/distribution.d.ts.map +1 -0
  42. package/dist/distribution.js +811 -0
  43. package/dist/distribution.js.map +1 -0
  44. package/dist/execution.d.ts +530 -0
  45. package/dist/execution.d.ts.map +1 -0
  46. package/dist/execution.js +761 -0
  47. package/dist/execution.js.map +1 -0
  48. package/dist/format.d.ts +19 -0
  49. package/dist/format.d.ts.map +1 -0
  50. package/dist/format.js +60 -0
  51. package/dist/format.js.map +1 -0
  52. package/dist/foundation.d.ts +176 -0
  53. package/dist/foundation.d.ts.map +1 -0
  54. package/dist/foundation.js +309 -0
  55. package/dist/foundation.js.map +1 -0
  56. package/dist/index.d.ts +733 -122
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +1018 -122
  59. package/dist/index.js.map +1 -1
  60. package/dist/integration.d.ts +236 -0
  61. package/dist/integration.d.ts.map +1 -0
  62. package/dist/integration.js +236 -0
  63. package/dist/integration.js.map +1 -0
  64. package/dist/intelligence.d.ts +94 -0
  65. package/dist/intelligence.d.ts.map +1 -0
  66. package/dist/intelligence.js +145 -0
  67. package/dist/intelligence.js.map +1 -0
  68. package/dist/isolation.d.ts +129 -0
  69. package/dist/isolation.d.ts.map +1 -0
  70. package/dist/isolation.js +96 -0
  71. package/dist/isolation.js.map +1 -0
  72. package/dist/media.d.ts +344 -0
  73. package/dist/media.d.ts.map +1 -0
  74. package/dist/media.js +986 -0
  75. package/dist/media.js.map +1 -0
  76. package/dist/modes.d.ts +359 -0
  77. package/dist/modes.d.ts.map +1 -0
  78. package/dist/modes.js +134 -0
  79. package/dist/modes.js.map +1 -0
  80. package/dist/{library/public.d.ts → operations.d.ts} +15 -1
  81. package/dist/operations.d.ts.map +1 -0
  82. package/dist/{library/public.js → operations.js} +18 -7
  83. package/dist/operations.js.map +1 -0
  84. package/dist/orchestrator.d.ts +1339 -0
  85. package/dist/orchestrator.d.ts.map +1 -0
  86. package/dist/orchestrator.js +4308 -0
  87. package/dist/orchestrator.js.map +1 -0
  88. package/dist/performance.d.ts +416 -0
  89. package/dist/performance.d.ts.map +1 -0
  90. package/dist/performance.js +827 -0
  91. package/dist/performance.js.map +1 -0
  92. package/dist/quantum.d.ts +810 -0
  93. package/dist/quantum.d.ts.map +1 -0
  94. package/dist/quantum.js +2073 -0
  95. package/dist/quantum.js.map +1 -0
  96. package/dist/render.d.ts +381 -0
  97. package/dist/render.d.ts.map +1 -0
  98. package/dist/render.js +1073 -0
  99. package/dist/render.js.map +1 -0
  100. package/dist/scheduler.d.ts +596 -0
  101. package/dist/scheduler.d.ts.map +1 -0
  102. package/dist/scheduler.js +1259 -0
  103. package/dist/scheduler.js.map +1 -0
  104. package/dist/security.d.ts +501 -0
  105. package/dist/security.d.ts.map +1 -0
  106. package/dist/security.js +1170 -0
  107. package/dist/security.js.map +1 -0
  108. package/dist/server.d.ts +21 -0
  109. package/dist/server.d.ts.map +1 -0
  110. package/dist/{server/node.js → server.js} +16 -2
  111. package/dist/server.js.map +1 -0
  112. package/dist/tiers.d.ts +1002 -0
  113. package/dist/tiers.d.ts.map +1 -0
  114. package/dist/tiers.js +2165 -0
  115. package/dist/tiers.js.map +1 -0
  116. package/dist/virtual.d.ts +641 -0
  117. package/dist/virtual.d.ts.map +1 -0
  118. package/dist/virtual.js +1285 -0
  119. package/dist/virtual.js.map +1 -0
  120. package/dist/virtualcpu.d.ts +316 -0
  121. package/dist/virtualcpu.d.ts.map +1 -0
  122. package/dist/virtualcpu.js +1180 -0
  123. package/dist/virtualcpu.js.map +1 -0
  124. package/dist/virtualgpu.d.ts +345 -0
  125. package/dist/virtualgpu.d.ts.map +1 -0
  126. package/dist/virtualgpu.js +1000 -0
  127. package/dist/virtualgpu.js.map +1 -0
  128. package/dist/virtualization.d.ts +607 -0
  129. package/dist/virtualization.d.ts.map +1 -0
  130. package/dist/virtualization.js +1187 -0
  131. package/dist/virtualization.js.map +1 -0
  132. package/dist/virtualmemory.d.ts +818 -0
  133. package/dist/virtualmemory.d.ts.map +1 -0
  134. package/dist/virtualmemory.js +1796 -0
  135. package/dist/virtualmemory.js.map +1 -0
  136. package/dist/webscrape.d.ts +720 -0
  137. package/dist/webscrape.d.ts.map +1 -0
  138. package/dist/webscrape.js +2697 -0
  139. package/dist/webscrape.js.map +1 -0
  140. package/docker.config +769 -0
  141. package/docs/CONVERSA.txt +1523 -0
  142. package/docs/alternatives.md +499 -0
  143. package/docs/architecture-1.8.19.md +76 -0
  144. package/docs/architecture-1.8.19.mmd +33 -0
  145. package/docs/architecture-1.8.19.png +0 -0
  146. package/docs/architecture.md +355 -0
  147. package/docs/artifactavailability.md +6 -0
  148. package/docs/brancharchive-2026-08-18.md +18 -0
  149. package/docs/browser.md +7 -0
  150. package/docs/consolidation.md +70 -0
  151. package/docs/e2ugh-engine.md +528 -0
  152. package/{dist/examples/localjob.js → docs/example-localjob.ts} +3 -3
  153. package/{dist/examples/publicapi.js → docs/example-publicapi.ts} +2 -2
  154. package/docs/hardware.md +342 -0
  155. package/docs/optimization.md +126 -0
  156. package/docs/performance.md +499 -0
  157. package/docs/planning.1.8.18.md +94 -0
  158. package/docs/planning.1.8.19.md +49 -0
  159. package/docs/releasenotes-1.8.17.md +6 -0
  160. package/docs/releasenotes-1.8.18.md +32 -0
  161. package/docs/releasenotes-1.8.19.md +35 -0
  162. package/docs/research-1.8.18-isolation.md +43 -0
  163. package/docs/research-1.8.19-virtual-browser.md +27 -0
  164. package/docs/saddle.archive.1.8.17.tar.gz.gpg +0 -0
  165. package/docs/security.md +454 -0
  166. package/docs/todo-1.8.16.md +56 -1
  167. package/docs/todo-1.8.18.md +164 -0
  168. package/docs/todo-1.8.19.md +241 -0
  169. package/docs/viability.md +777 -0
  170. package/docs/virtualization.md +335 -0
  171. package/docs/web-duplicatecleanup.md +9 -0
  172. package/docs/web-ideas.md +106 -0
  173. package/docs/workflowimprovements-2026-08-19.md +70 -0
  174. package/gpumonitor.cpp +1543 -0
  175. package/gpus.json +2408 -0
  176. package/index.ts +1478 -0
  177. package/media.ts +1337 -0
  178. package/mttg.config +1549 -0
  179. package/orchestrator.ts +5462 -0
  180. package/package.json +304 -55
  181. package/passage.config +1331 -0
  182. package/performance.ts +1049 -0
  183. package/processors.json +2217 -0
  184. package/qemu.config +1062 -0
  185. package/qemubridge.py +1340 -0
  186. package/quantum.ts +2393 -0
  187. package/render.ts +1325 -0
  188. package/scheduler.ts +1600 -0
  189. package/security.ts +1449 -0
  190. package/tiers.ts +2871 -0
  191. package/tsconfig.json +29 -0
  192. package/virtualcpu.ts +1273 -0
  193. package/virtualgpu.ts +1181 -0
  194. package/virtualhardware.c +1011 -0
  195. package/virtualhardware.json +739 -0
  196. package/virtualization.ts +1628 -0
  197. package/virtualizationcore.cpp +4635 -0
  198. package/virtualmemory.ts +2303 -0
  199. package/vm.config.json +1910 -0
  200. package/{extension → web/extension}/manifest.json +1 -1
  201. package/web/readme.md +382 -0
  202. package/web/tsconfig.json +25 -0
  203. package/dist/adapters/forge.d.ts +0 -17
  204. package/dist/adapters/forge.d.ts.map +0 -1
  205. package/dist/adapters/forge.js +0 -19
  206. package/dist/adapters/forge.js.map +0 -1
  207. package/dist/adapters/forgejo.d.ts +0 -49
  208. package/dist/adapters/forgejo.d.ts.map +0 -1
  209. package/dist/adapters/forgejo.js +0 -8
  210. package/dist/adapters/forgejo.js.map +0 -1
  211. package/dist/adapters/github.d.ts +0 -12
  212. package/dist/adapters/github.d.ts.map +0 -1
  213. package/dist/adapters/github.js +0 -20
  214. package/dist/adapters/github.js.map +0 -1
  215. package/dist/adapters/gitlab.d.ts +0 -17
  216. package/dist/adapters/gitlab.d.ts.map +0 -1
  217. package/dist/adapters/gitlab.js +0 -10
  218. package/dist/adapters/gitlab.js.map +0 -1
  219. package/dist/adapters/huggingface.d.ts +0 -17
  220. package/dist/adapters/huggingface.d.ts.map +0 -1
  221. package/dist/adapters/huggingface.js +0 -6
  222. package/dist/adapters/huggingface.js.map +0 -1
  223. package/dist/adapters/socket.d.ts +0 -11
  224. package/dist/adapters/socket.d.ts.map +0 -1
  225. package/dist/adapters/socket.js +0 -17
  226. package/dist/adapters/socket.js.map +0 -1
  227. package/dist/adapters/transport.d.ts +0 -7
  228. package/dist/adapters/transport.d.ts.map +0 -1
  229. package/dist/adapters/transport.js +0 -36
  230. package/dist/adapters/transport.js.map +0 -1
  231. package/dist/ai/chunk.d.ts +0 -2
  232. package/dist/ai/chunk.d.ts.map +0 -1
  233. package/dist/ai/chunk.js +0 -36
  234. package/dist/ai/chunk.js.map +0 -1
  235. package/dist/ai/llmstxt.d.ts +0 -6
  236. package/dist/ai/llmstxt.d.ts.map +0 -1
  237. package/dist/ai/llmstxt.js +0 -12
  238. package/dist/ai/llmstxt.js.map +0 -1
  239. package/dist/ai/provenance.d.ts +0 -22
  240. package/dist/ai/provenance.d.ts.map +0 -1
  241. package/dist/ai/provenance.js +0 -25
  242. package/dist/ai/provenance.js.map +0 -1
  243. package/dist/ai/rag.d.ts +0 -26
  244. package/dist/ai/rag.d.ts.map +0 -1
  245. package/dist/ai/rag.js +0 -22
  246. package/dist/ai/rag.js.map +0 -1
  247. package/dist/ai/tokens.d.ts +0 -15
  248. package/dist/ai/tokens.d.ts.map +0 -1
  249. package/dist/ai/tokens.js +0 -9
  250. package/dist/ai/tokens.js.map +0 -1
  251. package/dist/api/auth.d.ts +0 -16
  252. package/dist/api/auth.d.ts.map +0 -1
  253. package/dist/api/auth.js +0 -19
  254. package/dist/api/auth.js.map +0 -1
  255. package/dist/api/contracts.d.ts +0 -28
  256. package/dist/api/contracts.d.ts.map +0 -1
  257. package/dist/api/contracts.js +0 -14
  258. package/dist/api/contracts.js.map +0 -1
  259. package/dist/api/control.d.ts +0 -10
  260. package/dist/api/control.d.ts.map +0 -1
  261. package/dist/api/control.js +0 -35
  262. package/dist/api/control.js.map +0 -1
  263. package/dist/api/http.d.ts +0 -7
  264. package/dist/api/http.d.ts.map +0 -1
  265. package/dist/api/http.js +0 -12
  266. package/dist/api/http.js.map +0 -1
  267. package/dist/api/rate.d.ts +0 -28
  268. package/dist/api/rate.d.ts.map +0 -1
  269. package/dist/api/rate.js +0 -36
  270. package/dist/api/rate.js.map +0 -1
  271. package/dist/api/security.d.ts +0 -12
  272. package/dist/api/security.d.ts.map +0 -1
  273. package/dist/api/security.js +0 -56
  274. package/dist/api/security.js.map +0 -1
  275. package/dist/api/service.d.ts +0 -5
  276. package/dist/api/service.d.ts.map +0 -1
  277. package/dist/api/service.js +0 -70
  278. package/dist/api/service.js.map +0 -1
  279. package/dist/apps/registry.d.ts +0 -33
  280. package/dist/apps/registry.d.ts.map +0 -1
  281. package/dist/apps/registry.js +0 -24
  282. package/dist/apps/registry.js.map +0 -1
  283. package/dist/binary/archive.d.ts +0 -27
  284. package/dist/binary/archive.d.ts.map +0 -1
  285. package/dist/binary/archive.js +0 -46
  286. package/dist/binary/archive.js.map +0 -1
  287. package/dist/binary/build.d.ts +0 -29
  288. package/dist/binary/build.d.ts.map +0 -1
  289. package/dist/binary/build.js +0 -17
  290. package/dist/binary/build.js.map +0 -1
  291. package/dist/binary/transform.d.ts +0 -70
  292. package/dist/binary/transform.d.ts.map +0 -1
  293. package/dist/binary/transform.js +0 -105
  294. package/dist/binary/transform.js.map +0 -1
  295. package/dist/bot/adapter.d.ts +0 -5
  296. package/dist/bot/adapter.d.ts.map +0 -1
  297. package/dist/bot/adapter.js +0 -11
  298. package/dist/bot/adapter.js.map +0 -1
  299. package/dist/bot/bot.d.ts +0 -28
  300. package/dist/bot/bot.d.ts.map +0 -1
  301. package/dist/bot/bot.js +0 -52
  302. package/dist/bot/bot.js.map +0 -1
  303. package/dist/bot/commands.d.ts +0 -8
  304. package/dist/bot/commands.d.ts.map +0 -1
  305. package/dist/bot/commands.js +0 -19
  306. package/dist/bot/commands.js.map +0 -1
  307. package/dist/bot/permissions.d.ts +0 -13
  308. package/dist/bot/permissions.d.ts.map +0 -1
  309. package/dist/bot/permissions.js +0 -16
  310. package/dist/bot/permissions.js.map +0 -1
  311. package/dist/browser/actions.d.ts +0 -33
  312. package/dist/browser/actions.d.ts.map +0 -1
  313. package/dist/browser/actions.js +0 -44
  314. package/dist/browser/actions.js.map +0 -1
  315. package/dist/browser/agent.d.ts +0 -21
  316. package/dist/browser/agent.d.ts.map +0 -1
  317. package/dist/browser/agent.js +0 -13
  318. package/dist/browser/agent.js.map +0 -1
  319. package/dist/browser/context.d.ts +0 -43
  320. package/dist/browser/context.d.ts.map +0 -1
  321. package/dist/browser/context.js +0 -54
  322. package/dist/browser/context.js.map +0 -1
  323. package/dist/browser/fingerprint.d.ts +0 -4
  324. package/dist/browser/fingerprint.d.ts.map +0 -1
  325. package/dist/browser/fingerprint.js +0 -12
  326. package/dist/browser/fingerprint.js.map +0 -1
  327. package/dist/browser/index.d.ts +0 -11
  328. package/dist/browser/index.d.ts.map +0 -1
  329. package/dist/browser/index.js +0 -11
  330. package/dist/browser/index.js.map +0 -1
  331. package/dist/browser/playwright.d.ts +0 -11
  332. package/dist/browser/playwright.d.ts.map +0 -1
  333. package/dist/browser/playwright.js +0 -24
  334. package/dist/browser/playwright.js.map +0 -1
  335. package/dist/browser/recorder.d.ts +0 -21
  336. package/dist/browser/recorder.d.ts.map +0 -1
  337. package/dist/browser/recorder.js +0 -58
  338. package/dist/browser/recorder.js.map +0 -1
  339. package/dist/browser/session.d.ts +0 -14
  340. package/dist/browser/session.d.ts.map +0 -1
  341. package/dist/browser/session.js +0 -21
  342. package/dist/browser/session.js.map +0 -1
  343. package/dist/browser/snapshot.d.ts +0 -69
  344. package/dist/browser/snapshot.d.ts.map +0 -1
  345. package/dist/browser/snapshot.js +0 -133
  346. package/dist/browser/snapshot.js.map +0 -1
  347. package/dist/captcha/contract.d.ts +0 -35
  348. package/dist/captcha/contract.d.ts.map +0 -1
  349. package/dist/captcha/contract.js +0 -17
  350. package/dist/captcha/contract.js.map +0 -1
  351. package/dist/captcha/evidence.d.ts +0 -10
  352. package/dist/captcha/evidence.d.ts.map +0 -1
  353. package/dist/captcha/evidence.js +0 -9
  354. package/dist/captcha/evidence.js.map +0 -1
  355. package/dist/captcha/guard.d.ts +0 -23
  356. package/dist/captcha/guard.d.ts.map +0 -1
  357. package/dist/captcha/guard.js +0 -12
  358. package/dist/captcha/guard.js.map +0 -1
  359. package/dist/cli/main.d.ts +0 -4
  360. package/dist/cli/main.d.ts.map +0 -1
  361. package/dist/cli/main.js +0 -46
  362. package/dist/cli/main.js.map +0 -1
  363. package/dist/core/errors.d.ts +0 -84
  364. package/dist/core/errors.d.ts.map +0 -1
  365. package/dist/core/errors.js +0 -54
  366. package/dist/core/errors.js.map +0 -1
  367. package/dist/core/events.d.ts +0 -9
  368. package/dist/core/events.d.ts.map +0 -1
  369. package/dist/core/events.js +0 -21
  370. package/dist/core/events.js.map +0 -1
  371. package/dist/core/hash.d.ts +0 -10
  372. package/dist/core/hash.d.ts.map +0 -1
  373. package/dist/core/hash.js +0 -82
  374. package/dist/core/hash.js.map +0 -1
  375. package/dist/core/ids.d.ts +0 -10
  376. package/dist/core/ids.d.ts.map +0 -1
  377. package/dist/core/ids.js +0 -15
  378. package/dist/core/ids.js.map +0 -1
  379. package/dist/delivery/manifest.d.ts +0 -35
  380. package/dist/delivery/manifest.d.ts.map +0 -1
  381. package/dist/delivery/manifest.js +0 -68
  382. package/dist/delivery/manifest.js.map +0 -1
  383. package/dist/deploy/index.d.ts +0 -6
  384. package/dist/deploy/index.d.ts.map +0 -1
  385. package/dist/deploy/index.js +0 -6
  386. package/dist/deploy/index.js.map +0 -1
  387. package/dist/dispatch/resumable.d.ts +0 -102
  388. package/dist/dispatch/resumable.d.ts.map +0 -1
  389. package/dist/dispatch/resumable.js +0 -64
  390. package/dist/dispatch/resumable.js.map +0 -1
  391. package/dist/dispatch/workflow.d.ts +0 -6
  392. package/dist/dispatch/workflow.d.ts.map +0 -1
  393. package/dist/dispatch/workflow.js +0 -37
  394. package/dist/dispatch/workflow.js.map +0 -1
  395. package/dist/domain/artifacts.d.ts +0 -12
  396. package/dist/domain/artifacts.d.ts.map +0 -1
  397. package/dist/domain/artifacts.js +0 -14
  398. package/dist/domain/artifacts.js.map +0 -1
  399. package/dist/domain/jobs.d.ts +0 -12
  400. package/dist/domain/jobs.d.ts.map +0 -1
  401. package/dist/domain/jobs.js +0 -20
  402. package/dist/domain/jobs.js.map +0 -1
  403. package/dist/domain/providers.d.ts +0 -10
  404. package/dist/domain/providers.d.ts.map +0 -1
  405. package/dist/domain/providers.js +0 -8
  406. package/dist/domain/providers.js.map +0 -1
  407. package/dist/domain/runtime.d.ts +0 -14
  408. package/dist/domain/runtime.d.ts.map +0 -1
  409. package/dist/domain/runtime.js +0 -10
  410. package/dist/domain/runtime.js.map +0 -1
  411. package/dist/domain/sessions.d.ts +0 -12
  412. package/dist/domain/sessions.d.ts.map +0 -1
  413. package/dist/domain/sessions.js +0 -57
  414. package/dist/domain/sessions.js.map +0 -1
  415. package/dist/examples/localjob.d.ts +0 -2
  416. package/dist/examples/localjob.d.ts.map +0 -1
  417. package/dist/examples/localjob.js.map +0 -1
  418. package/dist/examples/publicapi.d.ts +0 -2
  419. package/dist/examples/publicapi.d.ts.map +0 -1
  420. package/dist/examples/publicapi.js.map +0 -1
  421. package/dist/extension/build.d.ts +0 -9
  422. package/dist/extension/build.d.ts.map +0 -1
  423. package/dist/extension/build.js +0 -85
  424. package/dist/extension/build.js.map +0 -1
  425. package/dist/extension/content.d.ts +0 -6
  426. package/dist/extension/content.d.ts.map +0 -1
  427. package/dist/extension/content.js +0 -135
  428. package/dist/extension/content.js.map +0 -1
  429. package/dist/extension/index.d.ts +0 -7
  430. package/dist/extension/index.d.ts.map +0 -1
  431. package/dist/extension/index.js +0 -7
  432. package/dist/extension/index.js.map +0 -1
  433. package/dist/extension/pagebridge.d.ts +0 -6
  434. package/dist/extension/pagebridge.d.ts.map +0 -1
  435. package/dist/extension/pagebridge.js +0 -42
  436. package/dist/extension/pagebridge.js.map +0 -1
  437. package/dist/extension/permissions.d.ts +0 -26
  438. package/dist/extension/permissions.d.ts.map +0 -1
  439. package/dist/extension/permissions.js +0 -28
  440. package/dist/extension/permissions.js.map +0 -1
  441. package/dist/extension/popup.d.ts +0 -5
  442. package/dist/extension/popup.d.ts.map +0 -1
  443. package/dist/extension/popup.js +0 -26
  444. package/dist/extension/popup.js.map +0 -1
  445. package/dist/extension/protocol.d.ts +0 -58
  446. package/dist/extension/protocol.d.ts.map +0 -1
  447. package/dist/extension/protocol.js +0 -101
  448. package/dist/extension/protocol.js.map +0 -1
  449. package/dist/extension/serviceworker.d.ts +0 -25
  450. package/dist/extension/serviceworker.d.ts.map +0 -1
  451. package/dist/extension/serviceworker.js +0 -102
  452. package/dist/extension/serviceworker.js.map +0 -1
  453. package/dist/extension/worker.d.ts +0 -28
  454. package/dist/extension/worker.d.ts.map +0 -1
  455. package/dist/extension/worker.js +0 -22
  456. package/dist/extension/worker.js.map +0 -1
  457. package/dist/format/check.d.ts +0 -8
  458. package/dist/format/check.d.ts.map +0 -1
  459. package/dist/format/check.js +0 -38
  460. package/dist/format/check.js.map +0 -1
  461. package/dist/library/public.d.ts.map +0 -1
  462. package/dist/library/public.js.map +0 -1
  463. package/dist/mcp/browser.d.ts +0 -9
  464. package/dist/mcp/browser.d.ts.map +0 -1
  465. package/dist/mcp/browser.js +0 -13
  466. package/dist/mcp/browser.js.map +0 -1
  467. package/dist/mcp/server.d.ts +0 -35
  468. package/dist/mcp/server.d.ts.map +0 -1
  469. package/dist/mcp/server.js +0 -40
  470. package/dist/mcp/server.js.map +0 -1
  471. package/dist/mcp/transport.d.ts +0 -7
  472. package/dist/mcp/transport.d.ts.map +0 -1
  473. package/dist/mcp/transport.js +0 -17
  474. package/dist/mcp/transport.js.map +0 -1
  475. package/dist/memory/bridge.d.ts +0 -14
  476. package/dist/memory/bridge.d.ts.map +0 -1
  477. package/dist/memory/bridge.js +0 -16
  478. package/dist/memory/bridge.js.map +0 -1
  479. package/dist/memory/engine.d.ts +0 -38
  480. package/dist/memory/engine.d.ts.map +0 -1
  481. package/dist/memory/engine.js +0 -109
  482. package/dist/memory/engine.js.map +0 -1
  483. package/dist/memory/modes.d.ts +0 -43
  484. package/dist/memory/modes.d.ts.map +0 -1
  485. package/dist/memory/modes.js +0 -66
  486. package/dist/memory/modes.js.map +0 -1
  487. package/dist/memory/objects.d.ts +0 -21
  488. package/dist/memory/objects.d.ts.map +0 -1
  489. package/dist/memory/objects.js +0 -20
  490. package/dist/memory/objects.js.map +0 -1
  491. package/dist/memory/planner.d.ts +0 -66
  492. package/dist/memory/planner.d.ts.map +0 -1
  493. package/dist/memory/planner.js +0 -108
  494. package/dist/memory/planner.js.map +0 -1
  495. package/dist/memory/targets.d.ts +0 -78
  496. package/dist/memory/targets.d.ts.map +0 -1
  497. package/dist/memory/targets.js +0 -29
  498. package/dist/memory/targets.js.map +0 -1
  499. package/dist/memory/transforms.d.ts +0 -19
  500. package/dist/memory/transforms.d.ts.map +0 -1
  501. package/dist/memory/transforms.js +0 -14
  502. package/dist/memory/transforms.js.map +0 -1
  503. package/dist/modes/matrix.d.ts +0 -23
  504. package/dist/modes/matrix.d.ts.map +0 -1
  505. package/dist/modes/matrix.js +0 -18
  506. package/dist/modes/matrix.js.map +0 -1
  507. package/dist/modes/modes.d.ts +0 -33
  508. package/dist/modes/modes.d.ts.map +0 -1
  509. package/dist/modes/modes.js +0 -15
  510. package/dist/modes/modes.js.map +0 -1
  511. package/dist/modes/resolve.d.ts +0 -96
  512. package/dist/modes/resolve.d.ts.map +0 -1
  513. package/dist/modes/resolve.js +0 -48
  514. package/dist/modes/resolve.js.map +0 -1
  515. package/dist/observability/metrics.d.ts +0 -14
  516. package/dist/observability/metrics.d.ts.map +0 -1
  517. package/dist/observability/metrics.js +0 -18
  518. package/dist/observability/metrics.js.map +0 -1
  519. package/dist/packager/manifest.d.ts +0 -66
  520. package/dist/packager/manifest.d.ts.map +0 -1
  521. package/dist/packager/manifest.js +0 -94
  522. package/dist/packager/manifest.js.map +0 -1
  523. package/dist/packager/publish.d.ts +0 -51
  524. package/dist/packager/publish.d.ts.map +0 -1
  525. package/dist/packager/publish.js +0 -18
  526. package/dist/packager/publish.js.map +0 -1
  527. package/dist/packager/targetcli.d.ts +0 -7
  528. package/dist/packager/targetcli.d.ts.map +0 -1
  529. package/dist/packager/targetcli.js +0 -22
  530. package/dist/packager/targetcli.js.map +0 -1
  531. package/dist/persistence/adapter.d.ts +0 -5
  532. package/dist/persistence/adapter.d.ts.map +0 -1
  533. package/dist/persistence/adapter.js +0 -11
  534. package/dist/persistence/adapter.js.map +0 -1
  535. package/dist/persistence/drizzle.d.ts +0 -2
  536. package/dist/persistence/drizzle.d.ts.map +0 -1
  537. package/dist/persistence/drizzle.js +0 -12
  538. package/dist/persistence/drizzle.js.map +0 -1
  539. package/dist/persistence/memory.d.ts +0 -2
  540. package/dist/persistence/memory.d.ts.map +0 -1
  541. package/dist/persistence/memory.js +0 -27
  542. package/dist/persistence/memory.js.map +0 -1
  543. package/dist/persistence/migrations.d.ts +0 -19
  544. package/dist/persistence/migrations.d.ts.map +0 -1
  545. package/dist/persistence/migrations.js +0 -13
  546. package/dist/persistence/migrations.js.map +0 -1
  547. package/dist/persistence/prisma.d.ts +0 -2
  548. package/dist/persistence/prisma.d.ts.map +0 -1
  549. package/dist/persistence/prisma.js +0 -25
  550. package/dist/persistence/prisma.js.map +0 -1
  551. package/dist/persistence/schema.d.ts +0 -63
  552. package/dist/persistence/schema.d.ts.map +0 -1
  553. package/dist/persistence/schema.js +0 -28
  554. package/dist/persistence/schema.js.map +0 -1
  555. package/dist/persistence/sql.d.ts +0 -3
  556. package/dist/persistence/sql.d.ts.map +0 -1
  557. package/dist/persistence/sql.js +0 -37
  558. package/dist/persistence/sql.js.map +0 -1
  559. package/dist/protocol/blocks.d.ts +0 -10
  560. package/dist/protocol/blocks.d.ts.map +0 -1
  561. package/dist/protocol/blocks.js +0 -26
  562. package/dist/protocol/blocks.js.map +0 -1
  563. package/dist/protocol/json.d.ts +0 -6
  564. package/dist/protocol/json.d.ts.map +0 -1
  565. package/dist/protocol/json.js +0 -6
  566. package/dist/protocol/json.js.map +0 -1
  567. package/dist/protocol/ndjson.d.ts +0 -3
  568. package/dist/protocol/ndjson.d.ts.map +0 -1
  569. package/dist/protocol/ndjson.js +0 -20
  570. package/dist/protocol/ndjson.js.map +0 -1
  571. package/dist/protocol/sse.d.ts +0 -7
  572. package/dist/protocol/sse.d.ts.map +0 -1
  573. package/dist/protocol/sse.js +0 -25
  574. package/dist/protocol/sse.js.map +0 -1
  575. package/dist/proxy/pool.d.ts +0 -9
  576. package/dist/proxy/pool.d.ts.map +0 -1
  577. package/dist/proxy/pool.js +0 -27
  578. package/dist/proxy/pool.js.map +0 -1
  579. package/dist/queue/idempotency.d.ts +0 -10
  580. package/dist/queue/idempotency.d.ts.map +0 -1
  581. package/dist/queue/idempotency.js +0 -13
  582. package/dist/queue/idempotency.js.map +0 -1
  583. package/dist/queue/persistent.d.ts +0 -14
  584. package/dist/queue/persistent.d.ts.map +0 -1
  585. package/dist/queue/persistent.js +0 -66
  586. package/dist/queue/persistent.js.map +0 -1
  587. package/dist/queue/queue.d.ts +0 -7
  588. package/dist/queue/queue.d.ts.map +0 -1
  589. package/dist/queue/queue.js +0 -55
  590. package/dist/queue/queue.js.map +0 -1
  591. package/dist/queue/saga.d.ts +0 -5
  592. package/dist/queue/saga.d.ts.map +0 -1
  593. package/dist/queue/saga.js +0 -20
  594. package/dist/queue/saga.js.map +0 -1
  595. package/dist/release/assets.d.ts +0 -144
  596. package/dist/release/assets.d.ts.map +0 -1
  597. package/dist/release/assets.js +0 -157
  598. package/dist/release/assets.js.map +0 -1
  599. package/dist/release/evidence.d.ts +0 -92
  600. package/dist/release/evidence.d.ts.map +0 -1
  601. package/dist/release/evidence.js +0 -148
  602. package/dist/release/evidence.js.map +0 -1
  603. package/dist/release/verify.d.ts +0 -12
  604. package/dist/release/verify.d.ts.map +0 -1
  605. package/dist/release/verify.js +0 -112
  606. package/dist/release/verify.js.map +0 -1
  607. package/dist/runners/chain.d.ts +0 -125
  608. package/dist/runners/chain.d.ts.map +0 -1
  609. package/dist/runners/chain.js +0 -95
  610. package/dist/runners/chain.js.map +0 -1
  611. package/dist/runners/health.d.ts +0 -36
  612. package/dist/runners/health.d.ts.map +0 -1
  613. package/dist/runners/health.js +0 -26
  614. package/dist/runners/health.js.map +0 -1
  615. package/dist/runners/heartbeat.d.ts +0 -23
  616. package/dist/runners/heartbeat.d.ts.map +0 -1
  617. package/dist/runners/heartbeat.js +0 -29
  618. package/dist/runners/heartbeat.js.map +0 -1
  619. package/dist/runners/inprocess.d.ts +0 -17
  620. package/dist/runners/inprocess.d.ts.map +0 -1
  621. package/dist/runners/inprocess.js +0 -20
  622. package/dist/runners/inprocess.js.map +0 -1
  623. package/dist/runners/scheduler.d.ts +0 -5
  624. package/dist/runners/scheduler.d.ts.map +0 -1
  625. package/dist/runners/scheduler.js +0 -19
  626. package/dist/runners/scheduler.js.map +0 -1
  627. package/dist/runtime/abort.d.ts +0 -8
  628. package/dist/runtime/abort.d.ts.map +0 -1
  629. package/dist/runtime/abort.js +0 -13
  630. package/dist/runtime/abort.js.map +0 -1
  631. package/dist/runtime/compatibility.d.ts +0 -37
  632. package/dist/runtime/compatibility.d.ts.map +0 -1
  633. package/dist/runtime/compatibility.js +0 -10
  634. package/dist/runtime/compatibility.js.map +0 -1
  635. package/dist/runtime/detect.d.ts +0 -13
  636. package/dist/runtime/detect.d.ts.map +0 -1
  637. package/dist/runtime/detect.js +0 -18
  638. package/dist/runtime/detect.js.map +0 -1
  639. package/dist/runtime/engine.d.ts +0 -20
  640. package/dist/runtime/engine.d.ts.map +0 -1
  641. package/dist/runtime/engine.js +0 -61
  642. package/dist/runtime/engine.js.map +0 -1
  643. package/dist/runtime/retry.d.ts +0 -19
  644. package/dist/runtime/retry.d.ts.map +0 -1
  645. package/dist/runtime/retry.js +0 -54
  646. package/dist/runtime/retry.js.map +0 -1
  647. package/dist/runtime/worker.d.ts +0 -10
  648. package/dist/runtime/worker.d.ts.map +0 -1
  649. package/dist/runtime/worker.js +0 -25
  650. package/dist/runtime/worker.js.map +0 -1
  651. package/dist/scrape/cache.d.ts +0 -45
  652. package/dist/scrape/cache.d.ts.map +0 -1
  653. package/dist/scrape/cache.js +0 -45
  654. package/dist/scrape/cache.js.map +0 -1
  655. package/dist/scrape/crawl.d.ts +0 -47
  656. package/dist/scrape/crawl.d.ts.map +0 -1
  657. package/dist/scrape/crawl.js +0 -114
  658. package/dist/scrape/crawl.js.map +0 -1
  659. package/dist/scrape/extract.d.ts +0 -63
  660. package/dist/scrape/extract.d.ts.map +0 -1
  661. package/dist/scrape/extract.js +0 -47
  662. package/dist/scrape/extract.js.map +0 -1
  663. package/dist/scrape/normalize.d.ts +0 -52
  664. package/dist/scrape/normalize.d.ts.map +0 -1
  665. package/dist/scrape/normalize.js +0 -102
  666. package/dist/scrape/normalize.js.map +0 -1
  667. package/dist/scrape/robots.d.ts +0 -37
  668. package/dist/scrape/robots.d.ts.map +0 -1
  669. package/dist/scrape/robots.js +0 -71
  670. package/dist/scrape/robots.js.map +0 -1
  671. package/dist/scrape/schema.d.ts +0 -23
  672. package/dist/scrape/schema.d.ts.map +0 -1
  673. package/dist/scrape/schema.js +0 -92
  674. package/dist/scrape/schema.js.map +0 -1
  675. package/dist/scrape/scraper.d.ts +0 -6
  676. package/dist/scrape/scraper.d.ts.map +0 -1
  677. package/dist/scrape/scraper.js +0 -46
  678. package/dist/scrape/scraper.js.map +0 -1
  679. package/dist/scrape/semantic.d.ts +0 -25
  680. package/dist/scrape/semantic.d.ts.map +0 -1
  681. package/dist/scrape/semantic.js +0 -27
  682. package/dist/scrape/semantic.js.map +0 -1
  683. package/dist/server/node.d.ts +0 -7
  684. package/dist/server/node.d.ts.map +0 -1
  685. package/dist/server/node.js.map +0 -1
  686. package/dist/sessions/file.d.ts +0 -25
  687. package/dist/sessions/file.d.ts.map +0 -1
  688. package/dist/sessions/file.js +0 -13
  689. package/dist/sessions/file.js.map +0 -1
  690. package/dist/sessions/replay.d.ts +0 -9
  691. package/dist/sessions/replay.d.ts.map +0 -1
  692. package/dist/sessions/replay.js +0 -70
  693. package/dist/sessions/replay.js.map +0 -1
  694. package/dist/sessions/store.d.ts +0 -25
  695. package/dist/sessions/store.d.ts.map +0 -1
  696. package/dist/sessions/store.js +0 -13
  697. package/dist/sessions/store.js.map +0 -1
  698. package/dist/storage/adapter.d.ts +0 -5
  699. package/dist/storage/adapter.d.ts.map +0 -1
  700. package/dist/storage/adapter.js +0 -11
  701. package/dist/storage/adapter.js.map +0 -1
  702. package/dist/storage/cache.d.ts +0 -23
  703. package/dist/storage/cache.d.ts.map +0 -1
  704. package/dist/storage/cache.js +0 -79
  705. package/dist/storage/cache.js.map +0 -1
  706. package/dist/storage/checksum.d.ts +0 -3
  707. package/dist/storage/checksum.d.ts.map +0 -1
  708. package/dist/storage/checksum.js +0 -19
  709. package/dist/storage/checksum.js.map +0 -1
  710. package/dist/storage/chunked.d.ts +0 -21
  711. package/dist/storage/chunked.d.ts.map +0 -1
  712. package/dist/storage/chunked.js +0 -67
  713. package/dist/storage/chunked.js.map +0 -1
  714. package/dist/storage/content.d.ts +0 -24
  715. package/dist/storage/content.d.ts.map +0 -1
  716. package/dist/storage/content.js +0 -44
  717. package/dist/storage/content.js.map +0 -1
  718. package/dist/storage/filehosting.d.ts +0 -2
  719. package/dist/storage/filehosting.d.ts.map +0 -1
  720. package/dist/storage/filehosting.js +0 -24
  721. package/dist/storage/filehosting.js.map +0 -1
  722. package/dist/storage/githubcontents.d.ts +0 -2
  723. package/dist/storage/githubcontents.d.ts.map +0 -1
  724. package/dist/storage/githubcontents.js +0 -29
  725. package/dist/storage/githubcontents.js.map +0 -1
  726. package/dist/storage/index.d.ts +0 -12
  727. package/dist/storage/index.d.ts.map +0 -1
  728. package/dist/storage/index.js +0 -12
  729. package/dist/storage/index.js.map +0 -1
  730. package/dist/storage/local.d.ts +0 -2
  731. package/dist/storage/local.d.ts.map +0 -1
  732. package/dist/storage/local.js +0 -72
  733. package/dist/storage/local.js.map +0 -1
  734. package/dist/storage/memory.d.ts +0 -6
  735. package/dist/storage/memory.d.ts.map +0 -1
  736. package/dist/storage/memory.js +0 -36
  737. package/dist/storage/memory.js.map +0 -1
  738. package/dist/storage/pool.d.ts +0 -95
  739. package/dist/storage/pool.d.ts.map +0 -1
  740. package/dist/storage/pool.js +0 -202
  741. package/dist/storage/pool.js.map +0 -1
  742. package/dist/storage/s3compatible.d.ts +0 -3
  743. package/dist/storage/s3compatible.d.ts.map +0 -1
  744. package/dist/storage/s3compatible.js +0 -70
  745. package/dist/storage/s3compatible.js.map +0 -1
  746. package/dist/storage/sync.d.ts +0 -47
  747. package/dist/storage/sync.d.ts.map +0 -1
  748. package/dist/storage/sync.js +0 -75
  749. package/dist/storage/sync.js.map +0 -1
  750. package/dist/surfaces/adapters.d.ts +0 -97
  751. package/dist/surfaces/adapters.d.ts.map +0 -1
  752. package/dist/surfaces/adapters.js +0 -50
  753. package/dist/surfaces/adapters.js.map +0 -1
  754. package/dist/surfaces/controls.d.ts +0 -18
  755. package/dist/surfaces/controls.d.ts.map +0 -1
  756. package/dist/surfaces/controls.js +0 -45
  757. package/dist/surfaces/controls.js.map +0 -1
  758. package/dist/surfaces/manifest.d.ts +0 -68
  759. package/dist/surfaces/manifest.d.ts.map +0 -1
  760. package/dist/surfaces/manifest.js +0 -42
  761. package/dist/surfaces/manifest.js.map +0 -1
  762. package/dist/surfaces/n8n.d.ts +0 -25
  763. package/dist/surfaces/n8n.d.ts.map +0 -1
  764. package/dist/surfaces/n8n.js +0 -31
  765. package/dist/surfaces/n8n.js.map +0 -1
  766. package/dist/surfaces/operations.d.ts +0 -32
  767. package/dist/surfaces/operations.d.ts.map +0 -1
  768. package/dist/surfaces/operations.js +0 -53
  769. package/dist/surfaces/operations.js.map +0 -1
  770. package/dist/surfaces/requirements.d.ts +0 -29
  771. package/dist/surfaces/requirements.d.ts.map +0 -1
  772. package/dist/surfaces/requirements.js +0 -50
  773. package/dist/surfaces/requirements.js.map +0 -1
  774. package/dist/surfaces/targets.d.ts +0 -196
  775. package/dist/surfaces/targets.d.ts.map +0 -1
  776. package/dist/surfaces/targets.js +0 -27
  777. package/dist/surfaces/targets.js.map +0 -1
  778. package/dist/webhook/delivery.d.ts +0 -18
  779. package/dist/webhook/delivery.d.ts.map +0 -1
  780. package/dist/webhook/delivery.js +0 -36
  781. package/dist/webhook/delivery.js.map +0 -1
  782. package/dist/webhook/receiver.d.ts +0 -26
  783. package/dist/webhook/receiver.d.ts.map +0 -1
  784. package/dist/webhook/receiver.js +0 -24
  785. package/dist/webhook/receiver.js.map +0 -1
  786. package/dist/webhook/signature.d.ts +0 -3
  787. package/dist/webhook/signature.d.ts.map +0 -1
  788. package/dist/webhook/signature.js +0 -7
  789. package/dist/webhook/signature.js.map +0 -1
  790. package/dist/workflow/manifest.d.ts +0 -22
  791. package/dist/workflow/manifest.d.ts.map +0 -1
  792. package/dist/workflow/manifest.js +0 -21
  793. package/dist/workflow/manifest.js.map +0 -1
  794. package/dist/workflow/registry.d.ts +0 -7
  795. package/dist/workflow/registry.d.ts.map +0 -1
  796. package/dist/workflow/registry.js +0 -18
  797. package/dist/workflow/registry.js.map +0 -1
  798. package/dist/workflow/templates.d.ts +0 -6
  799. package/dist/workflow/templates.d.ts.map +0 -1
  800. package/dist/workflow/templates.js +0 -18
  801. package/dist/workflow/templates.js.map +0 -1
  802. package/dist/workflow/triggers.d.ts +0 -64
  803. package/dist/workflow/triggers.d.ts.map +0 -1
  804. package/dist/workflow/triggers.js +0 -99
  805. package/dist/workflow/triggers.js.map +0 -1
  806. package/docs/logs/.gitkeep +0 -0
  807. package/docs/plans/00.index.md +0 -50
  808. package/docs/plans/01.architecture.md +0 -86
  809. package/docs/plans/02.research.computer.use.md +0 -58
  810. package/docs/plans/03.research.captcha.bypass.md +0 -68
  811. package/docs/plans/04.research.sandbox.ai.md +0 -52
  812. package/docs/plans/05.capture.platform.md +0 -57
  813. package/docs/plans/06.dependencies.md +0 -97
  814. package/docs/plans/07.captcha.test.page.md +0 -41
  815. package/docs/plans/08.production.infra.md +0 -70
  816. package/docs/plans/09.database.schema.md +0 -121
  817. package/docs/plans/10.cloudinary.storage.md +0 -57
  818. package/docs/plans/11.movement.logs.json.md +0 -72
  819. package/docs/plans/12.research.atlas.agent.browser.md +0 -79
  820. package/docs/plans/13.research.anti.detection.md +0 -898
  821. package/docs/plans/14.research.proxy.md +0 -1495
  822. package/docs/plans/15.research.retry.rate.limit.md +0 -1958
  823. package/docs/plans/16.research.crawling.md +0 -1417
  824. package/docs/plans/17.research.caching.md +0 -1610
  825. package/docs/plans/18.research.content.extraction.md +0 -1952
  826. package/docs/plans/19.research.errors.events.md +0 -1523
  827. package/docs/plans/20.research.zod.validation.md +0 -1350
  828. package/docs/plans/21.research.batch.concurrency.md +0 -1888
  829. package/docs/plans/22.research.universal.runtime.md +0 -944
  830. package/docs/plans/23.research.ai.integration.md +0 -1465
  831. package/docs/plans/24.research.memory.persistence.md +0 -1979
  832. package/docs/plans/25.research.server.api.md +0 -342
  833. package/docs/plans/26.research.compilation.md +0 -249
  834. package/docs/plans/27.research.html.parsing.md +0 -251
  835. package/docs/plans/28.action.plan.md +0 -50
  836. package/docs/plans/29.api.reference.md +0 -174
  837. package/docs/plans/30.architecture.plan.md +0 -94
  838. package/docs/plans/31.auditoria.dados.md +0 -163
  839. package/docs/plans/32.bots.automacao.computacional.md +0 -214
  840. package/docs/plans/33.bots.codigo.revisao.md +0 -220
  841. package/docs/plans/34.bots.seguranca.cicd.md +0 -366
  842. package/docs/plans/35.comparativo.concorrencia.md +0 -464
  843. package/docs/plans/36.computational.memory.md +0 -340
  844. package/docs/plans/37.deploystrategy.md +0 -394
  845. package/docs/plans/38.flow.md +0 -155
  846. package/docs/plans/39.multi.platform.bot.md +0 -252
  847. package/docs/plans/40.npm.publish.md +0 -250
  848. package/docs/plans/41.o.que.falta.md +0 -407
  849. package/docs/plans/42.pesquisa.concorrencia.md +0 -721
  850. package/docs/plans/43.plan.universal.architecture.md +0 -496
  851. package/docs/plans/44.reference.md +0 -100
  852. package/docs/plans/45.robotarchitecture.md +0 -237
  853. package/docs/plans/46.scdnintegration.md +0 -284
  854. package/docs/plans/47.multiforge.readme.md +0 -129
  855. package/docs/plans/48.theory.v4.repo.os.md +0 -152
  856. package/docs/plans/49.third.party.infra.md +0 -12
  857. package/docs/plans/50.file.as.compute.md +0 -39
  858. package/docs/plans/51.architecture.virtual.processor.md +0 -80
  859. package/docs/plans/52.manifesto.v8.md +0 -11
  860. package/docs/plans/58.cdn.list.md +0 -23
  861. package/docs/plans/59.sql.frameworks.md +0 -33
  862. package/docs/plans/60.sql.thirdparty.md +0 -26
  863. package/docs/plans/61.objective.multiforge.md +0 -63
  864. package/docs/plans/62.huggingface.upload.md +0 -26
  865. package/docs/plans/63.kaggle.upload.md +0 -24
  866. package/docs/plans/64.npm.storage.md +0 -30
  867. package/docs/plans/65.rclone.terabox.md +0 -32
  868. package/docs/plans/66.buckets.and.models.todo.md +0 -14
  869. package/docs/plans/67.database.todo.md +0 -13
  870. package/docs/plans/68.deploy.packages.todo.md +0 -12
  871. package/docs/plans/69.report.human.operator.md +0 -133
  872. package/docs/plans/70.report.brain2qwerty.ems.md +0 -135
  873. package/docs/plans/71.report.hd.infinito.vram.md +0 -155
  874. package/docs/plans/72.plan.hd.infinito.node.md +0 -146
  875. package/docs/plans/73.plan.scifi.repos.md +0 -125
  876. package/docs/plans/74.000.manifesto.v8.flat.2..md +0 -11
  877. package/docs/plans/README.md +0 -489
  878. package/docs/plans/aggregate_platforms.mjs +0 -146
  879. package/docs/plans/examplesession.json +0 -36
  880. package/docs/plans/missing-facts.md +0 -192
  881. package/docs/plans/models.md +0 -64
  882. package/docs/plans/organize.cjs +0 -270
  883. package/docs/plans/platforms.md +0 -2887
  884. package/docs/plans/sites.md +0 -31322
  885. package/docs/sources/farm.py +0 -117
  886. package/docs/sources/html/saddle1.html +0 -132
  887. package/docs/sources/html/saddle2.html +0 -157
  888. package/docs/sources/html/saddle3.html +0 -119
  889. package/docs/sources/html/saddle4.html +0 -144
  890. package/docs/sources/html/saddle5.html +0 -72
  891. package/docs/sources/html/saddle6.html +0 -171
  892. package/docs/sources/html/saddle7.html +0 -236
  893. package/docs/sources/saddle.ts +0 -74
  894. package/docs/sources/schema.prisma +0 -88
  895. package/docs/sources/script.sh +0 -64
  896. package/docs/sources/workflows.yml +0 -458
  897. package/docs/talks1/_body.txt +0 -14
  898. package/docs/talks1/_index.md +0 -15
  899. package/docs/talks1/_screenshot.png +0 -0
  900. package/docs/talks1/assistant-01.md +0 -5
  901. package/docs/talks1/assistant-02.md +0 -5
  902. package/docs/talks1/assistant-03.md +0 -531
  903. package/docs/talks1/assistant-04.md +0 -26
  904. package/docs/talks1/assistant-05.md +0 -774
  905. package/docs/talks1/assistant-06.md +0 -1718
  906. package/docs/talks1/scrape-share.cjs +0 -185
  907. package/docs/talks1/scrape-share.ts +0 -183
  908. package/docs/talks1/user-01.md +0 -3
  909. package/docs/talks1/user-02.md +0 -3
  910. package/docs/talks1/user-03.md +0 -88
  911. package/docs/talks1/user-04.md +0 -3
  912. package/docs/talks1/user-05.md +0 -3
  913. package/docs/talks1/user-06.md +0 -88
  914. package/docs/talks1/user-07.md +0 -88
  915. package/docs/talks2/_body.txt +0 -14
  916. package/docs/talks2/_index.md +0 -16
  917. package/docs/talks2/_screenshot.png +0 -0
  918. package/docs/talks2/assistant-01.md +0 -5
  919. package/docs/talks2/assistant-02.md +0 -5
  920. package/docs/talks2/assistant-03.md +0 -424
  921. package/docs/talks2/assistant-04.md +0 -598
  922. package/docs/talks2/assistant-05.md +0 -1280
  923. package/docs/talks2/assistant-06.md +0 -1227
  924. package/docs/talks2/assistant-07.md +0 -1252
  925. package/docs/talks2/user-01.md +0 -3
  926. package/docs/talks2/user-02.md +0 -3
  927. package/docs/talks2/user-03.md +0 -88
  928. package/docs/talks2/user-04.md +0 -88
  929. package/docs/talks2/user-05.md +0 -88
  930. package/docs/talks2/user-06.md +0 -88
  931. package/docs/talks2/user-07.md +0 -3
  932. package/docs/talks3/_body.txt +0 -467
  933. package/docs/talks3/_index.md +0 -10
  934. package/docs/talks3/_screenshot.png +0 -0
  935. package/docs/talks3/assistant-01.md +0 -417
  936. package/docs/talks3/assistant-02.md +0 -417
  937. package/docs/talks3/assistant-03.md +0 -29
  938. package/docs/talks3/assistant-04.md +0 -727
  939. package/docs/talks3/user-01.md +0 -88
  940. package/docs/talks3/user-02.md +0 -88
  941. package/docs/talks3/user-03.md +0 -3
  942. package/docs/talks3/user-04.md +0 -3
  943. package/docs/talks4/_body.txt +0 -14
  944. package/docs/talks4/_index.md +0 -12
  945. package/docs/talks4/_screenshot.png +0 -0
  946. package/docs/talks4/assistant-01.md +0 -5
  947. package/docs/talks4/assistant-02.md +0 -5
  948. package/docs/talks4/assistant-03.md +0 -35
  949. package/docs/talks4/assistant-04.md +0 -512
  950. package/docs/talks4/assistant-05.md +0 -599
  951. package/docs/talks4/user-01.md +0 -3
  952. package/docs/talks4/user-02.md +0 -3
  953. package/docs/talks4/user-03.md +0 -88
  954. package/docs/talks4/user-04.md +0 -88
  955. package/docs/talks4/user-05.md +0 -7
  956. package/docs/talks5/_body.txt +0 -14
  957. package/docs/talks5/_index.md +0 -13
  958. package/docs/talks5/_screenshot.png +0 -0
  959. package/docs/talks5/assistant-01.md +0 -5
  960. package/docs/talks5/assistant-02.md +0 -5
  961. package/docs/talks5/assistant-03.md +0 -690
  962. package/docs/talks5/assistant-04.md +0 -758
  963. package/docs/talks5/assistant-05.md +0 -974
  964. package/docs/talks5/user-01.md +0 -3
  965. package/docs/talks5/user-02.md +0 -3
  966. package/docs/talks5/user-03.md +0 -105
  967. package/docs/talks5/user-04.md +0 -105
  968. package/docs/talks5/user-05.md +0 -63
  969. package/docs/talks5/user-06.md +0 -105
  970. package/docs/talks6/_body.txt +0 -14
  971. package/docs/talks6/_index.md +0 -9
  972. package/docs/talks6/_screenshot.png +0 -0
  973. package/docs/talks6/assistant-01.md +0 -5
  974. package/docs/talks6/assistant-02.md +0 -5
  975. package/docs/talks6/assistant-03.md +0 -1499
  976. package/docs/talks6/user-01.md +0 -3
  977. package/docs/talks6/user-02.md +0 -3
  978. package/docs/talks6/user-03.md +0 -88
  979. package/docs/talks6/user-04.md +0 -88
  980. package/docs/talks7/_body.txt +0 -14
  981. package/docs/talks7/_index.md +0 -10
  982. package/docs/talks7/_screenshot.png +0 -0
  983. package/docs/talks7/assistant-01.md +0 -5
  984. package/docs/talks7/assistant-02.md +0 -5
  985. package/docs/talks7/assistant-03.md +0 -523
  986. package/docs/talks7/assistant-04.md +0 -617
  987. package/docs/talks7/user-01.md +0 -3
  988. package/docs/talks7/user-02.md +0 -3
  989. package/docs/talks7/user-03.md +0 -105
  990. package/docs/talks7/user-04.md +0 -67
  991. package/docs/talks8/conversa1.txt +0 -1322
  992. package/docs/talks8/conversa2.txt +0 -237
  993. package/docs/talks9/Beyond the Obvious_ 50 Plataformas Auto-Hospedadas de Forja de C/303/263digo para Al/303/251m de Gitea e GitLab.md" +0 -174
  994. package/docs/talks9/De NPM a Multi-Linguagem_ Uma Arquitetura T/303/251cnica para a Execu/303/247/303/243o Integrada de C/303/263digo no Ecossistema Node.js.md" +0 -59
  995. package/docs/talks9/De NPM a VMs Virtuais_ Uma An/303/241lise Arquitet/303/264nica para a Realiza/303/247/303/243o do Ciclo de Vida do Projeto SADDLE.md" +0 -91
  996. package/docs/talks9/Mapeamento da Engrenagem Computacional_ Uma Arquitetura para Execu/303/247/303/243o Isolada e Persist/303/252ncia em Ambientes Distribu/303/255dos.md" +0 -116
  997. package/docs/talks9/O Cen/303/241rio Pr/303/241tico do SADDLE_ Uma An/303/241lise de Viabilidade e Modelo de Ciclo de Vida Integrado.md" +0 -128
  998. package/docs/talks9/README (2).md +0 -489
  999. package/docs/talks9/README.md +0 -198
  1000. package/docs/talks9/Viabilidade do Saddle_ Uma An/303/241lise T/303/251cnica da Transforma/303/247/303/243o de Armazenamento Remoto em Mem/303/263ria Computacional.md" +0 -80
  1001. package/docs/talks9/conversa.txt +0 -544
  1002. package/docs/talks9/other (2).md +0 -39
  1003. package/docs/talks9/other.md +0 -57
  1004. package/docs/talks9/outro.txt +0 -24
  1005. /package/{extension/README.md → docs/extension.md} +0 -0
@@ -1,1350 +0,0 @@
1
- # Pesquisa: Zod Schema Validation para TypeScript (2026)
2
-
3
- ## Sumário
4
-
5
- 1. [Zod v4: O que mudou](#1-zod-v4-o-que-mudou)
6
- 2. [Runtime Validation of Scraping Options](#2-runtime-validation-of-scraping-options)
7
- 3. [Creating Zod Schemas for Core Types](#3-creating-zod-schemas-for-core-types)
8
- 4. [API Input Validation Middleware](#4-api-input-validation-middleware)
9
- 5. [CLI Validation with z.coerce](#5-cli-validation-with-zcoerce)
10
- 6. [Deriving TypeScript Types](#6-deriving-typescript-types)
11
- 7. [Best Practices](#7-best-practices)
12
- 8. [Response Validation Pattern](#8-response-validation-pattern)
13
- 9. [JSON Schema Generation](#9-json-schema-generation)
14
- 10. [Complete Code Examples](#10-complete-code-examples)
15
-
16
- ---
17
-
18
- ## 1. Zod v4: O que mudou
19
-
20
- ### Performance Improvements
21
-
22
- Zod v4 (released 2025-2026) brings major improvements:
23
-
24
- | Metric | Zod v3 | Zod v4 | Improvement |
25
- |--------|--------|--------|-------------|
26
- | Parse speed | ~1x | ~14x | 14x faster |
27
- | Bundle size | ~60KB | ~26KB | 2.3x smaller |
28
- | Type inference | Good | Excellent | Better DX |
29
- | Error messages | Basic | Rich | More helpful |
30
-
31
- ### Key New Features
32
-
33
- ```typescript
34
- import { z } from 'zod/v4';
35
-
36
- // 1. z.strictObject — rejects unknown keys at runtime
37
- const strictConfig = z.strictObject({
38
- url: z.string().url(),
39
- maxRetries: z.number().int().positive(),
40
- // Unknown keys throw ZodError
41
- });
42
-
43
- // 2. .prefault() — default values computed lazily
44
- const options = z.object({
45
- concurrency: z.number().default(5),
46
- timeout: z.number().default(30_000),
47
- userAgent: z.string().prefault(() => `Bot/${Math.random().toString(36)}`),
48
- });
49
-
50
- // 3. z.interface() — proper interface-like semantics
51
- const IScrapeResult = z.interface({
52
- url: z.string(),
53
- title: z.string(),
54
- links: z.array(z.string()),
55
- });
56
-
57
- // 4. Improved error messages
58
- const schema = z.string().email();
59
- schema.parse('not-an-email');
60
- // v3: "Invalid email"
61
- // v4: "Invalid email: expected string matching email format, received 'not-an-email'"
62
-
63
- // 5. Pattern matching
64
- const result = z.union([z.string(), z.number()]).safeParse(true);
65
- // v4 gives better error: "Invalid input: expected string | number, received boolean"
66
- ```
67
-
68
- ### Migration from v3 to v4
69
-
70
- ```typescript
71
- // v3
72
- import { z } from 'zod';
73
- const schema = z.object({ name: z.string() });
74
-
75
- // v4 (drop-in with import path change)
76
- import { z } from 'zod/v4';
77
- const schema = z.object({ name: z.string() });
78
-
79
- // For backwards compatibility
80
- import { z } from 'zod';
81
- // Zod v4 is backwards compatible with v3 API
82
- // But v4 has new features only available with 'zod/v4'
83
- ```
84
-
85
- ---
86
-
87
- ## 2. Runtime Validation of Scraping Options
88
-
89
- ### Why Runtime Validation?
90
-
91
- TypeScript types are erased at compile time. If your scraper receives options from:
92
- - CLI arguments (strings)
93
- - API requests (JSON)
94
- - Config files (YAML/JSON)
95
- - Environment variables (strings)
96
-
97
- ...you need runtime validation to ensure they match your expected types.
98
-
99
- ### Core Scraping Options Schema
100
-
101
- ```typescript
102
- import { z } from 'zod';
103
-
104
- // Enum-like unions
105
- const HttpMethod = z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);
106
- const ProxyType = z.enum(['http', 'https', 'socks5']);
107
- const BrowserType = z.enum(['chromium', 'firefox', 'webkit']);
108
-
109
- // URL with custom validation
110
- const SafeUrl = z.string()
111
- .url()
112
- .refine(
113
- (url) => {
114
- try {
115
- const parsed = new URL(url);
116
- return ['http:', 'https:'].includes(parsed.protocol);
117
- } catch {
118
- return false;
119
- }
120
- },
121
- { message: 'URL must use http or https protocol' }
122
- );
123
-
124
- // Proxy configuration
125
- const ProxyConfig = z.object({
126
- url: z.string().url(),
127
- username: z.string().optional(),
128
- password: z.string().optional(),
129
- type: ProxyType.default('http'),
130
- }).strict();
131
-
132
- // Header map
133
- const Headers = z.record(z.string(), z.string()).default({
134
- 'Accept': 'text/html,application/xhtml+xml',
135
- 'Accept-Language': 'en-US,en;q=0.9',
136
- });
137
-
138
- // Selector with timeout
139
- const SelectorConfig = z.object({
140
- selector: z.string().min(1),
141
- timeout: z.number().int().positive().default(5000),
142
- optional: z.boolean().default(false),
143
- });
144
-
145
- // Main scrape options — the most important schema
146
- const ScrapeOptions = z.object({
147
- // Target
148
- url: SafeUrl,
149
- method: HttpMethod.default('GET'),
150
- headers: Headers,
151
-
152
- // Browser settings
153
- browser: BrowserType.default('chromium'),
154
- headless: z.boolean().default(true),
155
- viewport: z.object({
156
- width: z.number().int().min(320).max(7680).default(1920),
157
- height: z.number().int().min(240).max(4320).default(1080),
158
- }).default({}),
159
-
160
- // Timing
161
- timeout: z.number().int().positive().default(30_000),
162
- waitForSelector: SelectorConfig.optional(),
163
- waitAfterLoad: z.number().int().min(0).default(0),
164
-
165
- // Retry
166
- maxRetries: z.number().int().min(0).max(10).default(3),
167
- retryDelay: z.number().int().min(0).default(1000),
168
- retryBackoff: z.enum(['linear', 'exponential']).default('exponential'),
169
-
170
- // Proxy
171
- proxy: ProxyConfig.optional(),
172
-
173
- // Extraction
174
- selectors: z.record(z.string(), SelectorConfig).optional(),
175
- evaluatePage: z.string().optional(), // Serialized function
176
-
177
- // Session
178
- sessionId: z.string().uuid().optional(),
179
- cookies: z.array(z.object({
180
- name: z.string(),
181
- value: z.string(),
182
- domain: z.string().optional(),
183
- path: z.string().default('/'),
184
- })).optional(),
185
-
186
- // Rate limiting
187
- maxConcurrency: z.number().int().min(1).max(100).default(5),
188
- requestsPerSecond: z.number().positive().optional(),
189
- delayBetweenRequests: z.number().int().min(0).optional(),
190
-
191
- // Output
192
- format: z.enum(['html', 'text', 'json', 'screenshot']).default('html'),
193
- screenshotFullPage: z.boolean().default(false),
194
- }).strict();
195
-
196
- // Cross-field refinements
197
- const ScrapeOptionsWithRefinements = ScrapeOptions.refine(
198
- (opts) => {
199
- // If using screenshot, must be in headless mode or have specific format
200
- if (opts.screenshotFullPage && opts.format !== 'screenshot') {
201
- return false;
202
- }
203
- return true;
204
- },
205
- {
206
- message: 'screenshotFullPage requires format="screenshot"',
207
- path: ['screenshotFullPage'],
208
- }
209
- ).refine(
210
- (opts) => {
211
- // requestsPerSecond and delayBetweenRequests are mutually exclusive
212
- if (opts.requestsPerSecond && opts.delayBetweenRequests) {
213
- return false;
214
- }
215
- return true;
216
- },
217
- {
218
- message: 'Cannot set both requestsPerSecond and delayBetweenRequests',
219
- path: ['requestsPerSecond'],
220
- }
221
- );
222
- ```
223
-
224
- ### Browser Agent Config Schema
225
-
226
- ```typescript
227
- const BrowserAgentConfig = z.object({
228
- // Browser management
229
- browserPool: z.object({
230
- minBrowsers: z.number().int().min(1).default(1),
231
- maxBrowsers: z.number().int().min(1).max(20).default(5),
232
- maxPagesPerBrowser: z.number().int().min(1).max(50).default(10),
233
- idleTimeout: z.number().int().min(1000).default(60_000),
234
- launchTimeout: z.number().int().min(1000).default(30_000),
235
- }).default({}),
236
-
237
- // Session management
238
- sessions: z.object({
239
- maxSessions: z.number().int().min(1).default(100),
240
- sessionTimeout: z.number().int().min(60_000).default(3_600_000),
241
- rotateOnBlock: z.boolean().default(true),
242
- cookiePersistence: z.boolean().default(true),
243
- }).default({}),
244
-
245
- // Anti-detection
246
- stealth: z.object({
247
- enabled: z.boolean().default(true),
248
- randomizeViewport: z.boolean().default(true),
249
- randomizeTiming: z.boolean().default(true),
250
- minDelay: z.number().int().min(0).default(500),
251
- maxDelay: z.number().int().min(0).default(2000),
252
- humanizeMouse: z.boolean().default(true),
253
- }).default({}),
254
-
255
- // Plugin system
256
- plugins: z.array(z.object({
257
- name: z.string(),
258
- enabled: z.boolean().default(true),
259
- config: z.record(z.unknown()).default({}),
260
- })).default([]),
261
-
262
- // Error handling
263
- errorHandling: z.object({
264
- maxConsecutiveErrors: z.number().int().min(1).default(5),
265
- circuitBreakerThreshold: z.number().min(0).max(1).default(0.5),
266
- circuitBreakerResetTimeout: z.number().int().min(1000).default(60_000),
267
- onCriticalError: z.enum(['stop', 'skip', 'restart']).default('stop'),
268
- }).default({}),
269
-
270
- // Logging
271
- logging: z.object({
272
- level: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
273
- requestLogging: z.boolean().default(true),
274
- errorLogging: z.boolean().default(true),
275
- }).default({}),
276
- }).strict();
277
- ```
278
-
279
- ---
280
-
281
- ## 3. Creating Zod Schemas for Core Types
282
-
283
- ### Data Extraction Schema
284
-
285
- ```typescript
286
- // Schema for scraped data
287
- const ScrapedItem = z.object({
288
- url: z.string().url(),
289
- title: z.string(),
290
- description: z.string().optional(),
291
- content: z.string().optional(),
292
- links: z.array(z.string().url()).default([]),
293
- images: z.array(z.object({
294
- src: z.string().url(),
295
- alt: z.string().default(''),
296
- })).default([]),
297
- metadata: z.record(z.string(), z.unknown()).default({}),
298
- scrapedAt: z.string().datetime().default(() => new Date().toISOString()),
299
- });
300
-
301
- // Schema for structured data extraction
302
- const ExtractionRule = z.object({
303
- name: z.string().min(1),
304
- selector: z.string().min(1),
305
- type: z.enum(['text', 'html', 'attribute', 'list', 'count']),
306
- attribute: z.string().optional(), // For type='attribute'
307
- multiple: z.boolean().default(false),
308
- required: z.boolean().default(true),
309
- transform: z.enum(['string', 'number', 'boolean', 'date', 'json']).optional(),
310
- default: z.unknown().optional(),
311
- }).refine(
312
- (rule) => rule.type === 'attribute' ? !!rule.attribute : true,
313
- { message: 'attribute name required when type="attribute"', path: ['attribute'] }
314
- );
315
-
316
- const ExtractionConfig = z.object({
317
- items: z.string().min(1), // Container selector
318
- rules: z.array(ExtractionRule).min(1),
319
- pagination: z.object({
320
- nextSelector: z.string().min(1),
321
- maxPages: z.number().int().min(1).default(10),
322
- waitForLoad: z.number().int().min(0).default(2000),
323
- }).optional(),
324
- }).strict();
325
- ```
326
-
327
- ### Queue and Job Schema
328
-
329
- ```typescript
330
- const JobPriority = z.enum(['critical', 'high', 'normal', 'low']);
331
-
332
- const ScrapeJob = z.object({
333
- id: z.string().uuid().default(() => crypto.randomUUID()),
334
- url: z.string().url(),
335
- priority: JobPriority.default('normal'),
336
- options: ScrapeOptions.partial().default({}),
337
- metadata: z.record(z.unknown()).default({}),
338
- createdAt: z.string().datetime().default(() => new Date().toISOString()),
339
- attempts: z.number().int().min(0).default(0),
340
- maxAttempts: z.number().int().min(1).default(3),
341
- status: z.enum(['pending', 'running', 'completed', 'failed', 'cancelled']).default('pending'),
342
- }).strict();
343
-
344
- const BatchConfig = z.object({
345
- jobs: z.array(ScrapeJob).min(1).max(10_000),
346
- concurrency: z.number().int().min(1).max(100).default(10),
347
- rateLimit: z.object({
348
- requestsPerSecond: z.number().positive(),
349
- burstSize: z.number().int().positive().default(5),
350
- }).optional(),
351
- deadline: z.string().datetime().optional(),
352
- onProgress: z.function().optional(), // Can't validate functions with Zod
353
- }).strict();
354
- ```
355
-
356
- ---
357
-
358
- ## 4. API Input Validation Middleware
359
-
360
- ### Express/Hono/Fastify Pattern
361
-
362
- ```typescript
363
- import { z } from 'zod';
364
- import type { ZodSchema, ZodError } from 'zod';
365
- import type { Request, Response, NextFunction } from 'express';
366
-
367
- // Generic validation middleware
368
- function validate<T extends ZodSchema>(
369
- schema: T,
370
- source: 'body' | 'query' | 'params' = 'body'
371
- ) {
372
- return (req: Request, res: Response, next: NextFunction) => {
373
- const result = schema.safeParse(req[source]);
374
-
375
- if (!result.success) {
376
- const errors = formatZodError(result.error);
377
- return res.status(400).json({
378
- error: 'Validation failed',
379
- details: errors,
380
- });
381
- }
382
-
383
- // Replace with validated/transformed data
384
- (req as any)[source] = result.data;
385
- next();
386
- };
387
- }
388
-
389
- // Format ZodError into a readable structure
390
- function formatZodError(error: ZodError): Array<{
391
- path: string;
392
- message: string;
393
- code: string;
394
- }> {
395
- return error.issues.map((issue) => ({
396
- path: issue.path.join('.'),
397
- message: issue.message,
398
- code: issue.code,
399
- }));
400
- }
401
-
402
- // Usage with Express
403
- import express from 'express';
404
-
405
- const app = express();
406
- app.use(express.json());
407
-
408
- // POST /api/scrape — validates body
409
- app.post(
410
- '/api/scrape',
411
- validate(ScrapeOptions),
412
- async (req, res) => {
413
- // req.body is now typed as ScrapeOptions (validated)
414
- const result = await scrape(req.body);
415
- res.json(result);
416
- }
417
- );
418
-
419
- // GET /api/jobs/:id — validates params
420
- app.get(
421
- '/api/jobs/:id',
422
- validate(z.object({ id: z.string().uuid() }), 'params'),
423
- async (req, res) => {
424
- // req.params.id is validated as UUID
425
- const job = await getJob(req.params.id);
426
- res.json(job);
427
- }
428
- );
429
-
430
- // GET /api/jobs — validates query
431
- app.get(
432
- '/api/jobs',
433
- validate(
434
- z.object({
435
- page: z.coerce.number().int().min(1).default(1),
436
- limit: z.coerce.number().int().min(1).max(100).default(20),
437
- status: z.enum(['pending', 'running', 'completed', 'failed']).optional(),
438
- }),
439
- 'query'
440
- ),
441
- async (req, res) => {
442
- // req.query is validated and coerced
443
- const jobs = await listJobs(req.query);
444
- res.json(jobs);
445
- }
446
- );
447
- ```
448
-
449
- ### Hono-Specific Pattern
450
-
451
- ```typescript
452
- import { Hono } from 'hono';
453
- import { zValidator } from '@hono/zod-validator';
454
-
455
- const app = new Hono();
456
-
457
- // Hono has built-in Zod validator
458
- app.post(
459
- '/api/scrape',
460
- zValidator('json', ScrapeOptions, (result, c) => {
461
- if (!result.success) {
462
- return c.json({ error: result.error.issues }, 400);
463
- }
464
- }),
465
- async (c) => {
466
- const body = c.req.valid('json');
467
- // body is fully typed and validated
468
- const result = await scrape(body);
469
- return c.json(result);
470
- }
471
- );
472
- ```
473
-
474
- ### Fastify Pattern
475
-
476
- ```typescript
477
- import Fastify from 'fastify';
478
- import { Type } from '@sinclair/typebox';
479
- import { Value } from '@sinclair/typebox';
480
-
481
- // Or use Zod with fastify-type-provider-zod
482
- import { ZodTypeProvider } from 'fastify-type-provider-zod';
483
- import { z } from 'zod';
484
-
485
- const fastify = Fastify().withTypeProvider<ZodTypeProvider>();
486
-
487
- fastify.post('/api/scrape', {
488
- schema: {
489
- body: ScrapeOptions,
490
- response: {
491
- 200: z.object({
492
- success: z.boolean(),
493
- data: ScrapedItem,
494
- }),
495
- },
496
- },
497
- }, async (request, reply) => {
498
- // request.body is typed
499
- const result = await scrape(request.body);
500
- return { success: true, data: result };
501
- });
502
- ```
503
-
504
- ---
505
-
506
- ## 5. CLI Validation with z.coerce
507
-
508
- ### The Problem
509
-
510
- CLI arguments are always strings. `z.coerce` converts them to the correct type during validation.
511
-
512
- ```typescript
513
- import { z } from 'zod';
514
-
515
- // CLI argument schema
516
- const CliOptions = z.object({
517
- // String arguments (no coercion needed)
518
- url: z.string().url('Invalid URL'),
519
- output: z.string().default('./output'),
520
-
521
- // Coerced number arguments
522
- concurrency: z.coerce.number()
523
- .int()
524
- .min(1, 'Concurrency must be at least 1')
525
- .max(100, 'Concurrency cannot exceed 100')
526
- .default(5),
527
-
528
- timeout: z.coerce.number()
529
- .int()
530
- .min(1000, 'Timeout must be at least 1000ms')
531
- .default(30_000),
532
-
533
- maxRetries: z.coerce.number()
534
- .int()
535
- .min(0)
536
- .max(10)
537
- .default(3),
538
-
539
- // Coerced boolean arguments
540
- headless: z.coerce.boolean().default(true),
541
- verbose: z.coerce.boolean().default(false),
542
- followRedirects: z.coerce.boolean().default(true),
543
-
544
- // Enum arguments
545
- browser: z.enum(['chromium', 'firefox', 'webkit']).default('chromium'),
546
- format: z.enum(['json', 'csv', 'html']).default('json'),
547
-
548
- // Date coercion
549
- since: z.coerce.date().optional(),
550
-
551
- // Array arguments (comma-separated)
552
- urls: z.string().transform((val) => val.split(',').map(u => u.trim())),
553
- }).strict();
554
-
555
- // Parse CLI args
556
- function parseCliArgs(argv: string[]): z.infer<typeof CliOptions> {
557
- // Simple arg parser (use commander/yargs in production)
558
- const args: Record<string, string> = {};
559
-
560
- for (let i = 2; i < argv.length; i++) {
561
- const arg = argv[i];
562
- if (arg.startsWith('--')) {
563
- const [key, value] = arg.slice(2).split('=');
564
- args[key] = value ?? argv[++i] ?? 'true';
565
- }
566
- }
567
-
568
- const result = CliOptions.safeParse(args);
569
-
570
- if (!result.success) {
571
- console.error('Invalid arguments:');
572
- for (const issue of result.error.issues) {
573
- console.error(` --${issue.path.join('.')}: ${issue.message}`);
574
- }
575
- process.exit(1);
576
- }
577
-
578
- return result.data;
579
- }
580
-
581
- // Usage
582
- const options = parseCliArgs(process.argv);
583
- console.log(`Scraping ${options.url} with ${options.concurrency} concurrent requests`);
584
- ```
585
-
586
- ### Commander.js Integration
587
-
588
- ```typescript
589
- import { Command } from 'commander';
590
- import { z } from 'zod';
591
-
592
- const program = new Command();
593
-
594
- const scrapeSchema = z.object({
595
- url: z.string().url(),
596
- concurrency: z.coerce.number().int().min(1).max(100).default(5),
597
- timeout: z.coerce.number().int().min(1000).default(30_000),
598
- headless: z.coerce.boolean().default(true),
599
- browser: z.enum(['chromium', 'firefox', 'webkit']).default('chromium'),
600
- output: z.string().default('./output'),
601
- verbose: z.coerce.boolean().default(false),
602
- });
603
-
604
- program
605
- .name('scraper')
606
- .description('Web scraper CLI')
607
- .version('1.0.0')
608
- .argument('<url>', 'URL to scrape')
609
- .option('-c, --concurrency <number>', 'Concurrent requests', '5')
610
- .option('-t, --timeout <number>', 'Request timeout in ms', '30000')
611
- .option('--no-headless', 'Run browser in headed mode')
612
- .option('-b, --browser <type>', 'Browser type', 'chromium')
613
- .option('-o, --output <dir>', 'Output directory', './output')
614
- .option('-v, --verbose', 'Verbose output')
615
- .action(async (url, opts) => {
616
- const result = scrapeSchema.safeParse({ url, ...opts });
617
-
618
- if (!result.success) {
619
- console.error('Validation error:');
620
- result.error.issues.forEach(i => {
621
- console.error(` ${i.path.join('.')}: ${i.message}`);
622
- });
623
- process.exit(1);
624
- }
625
-
626
- await runScraper(result.data);
627
- });
628
-
629
- program.parse();
630
- ```
631
-
632
- ---
633
-
634
- ## 6. Deriving TypeScript Types
635
-
636
- ### The z.infer Pattern
637
-
638
- Zod schemas are the source of truth. TypeScript types are derived from them — never the other way around.
639
-
640
- ```typescript
641
- import { z } from 'zod';
642
-
643
- // Define the schema
644
- const ScrapeOptions = z.object({
645
- url: z.string().url(),
646
- concurrency: z.number().int().default(5),
647
- headless: z.boolean().default(true),
648
- proxy: z.object({
649
- url: z.string().url(),
650
- username: z.string().optional(),
651
- }).optional(),
652
- });
653
-
654
- // Derive the TypeScript type
655
- type ScrapeOptions = z.infer<typeof ScrapeOptions>;
656
- // {
657
- // url: string;
658
- // concurrency: number;
659
- // headless: boolean;
660
- // proxy?: { url: string; username?: string } | undefined;
661
- // }
662
-
663
- // For input (before defaults are applied)
664
- type ScrapeOptionsInput = z.input<typeof ScrapeOptions>;
665
- // { url: string; concurrency?: number; headless?: boolean; proxy?: ... }
666
-
667
- // For output (after defaults, transforms, refinements)
668
- type ScrapeOptionsOutput = z.output<typeof ScrapeOptions>;
669
- // { url: string; concurrency: number; headless: boolean; proxy?: ... }
670
- ```
671
-
672
- ### Extracting Types from Complex Schemas
673
-
674
- ```typescript
675
- const ScrapedItem = z.object({
676
- url: z.string().url(),
677
- title: z.string(),
678
- data: z.record(z.string(), z.unknown()),
679
- tags: z.array(z.string()),
680
- metadata: z.object({
681
- scrapedAt: z.string().datetime(),
682
- duration: z.number(),
683
- status: z.enum(['success', 'partial', 'failed']),
684
- }),
685
- });
686
-
687
- // Full type
688
- type ScrapedItem = z.infer<typeof ScrapedItem>;
689
-
690
- // Partial type (all optional)
691
- const PartialScrapedItem = ScrapedItem.partial();
692
- type PartialScrapedItem = z.infer<typeof PartialScrapedItem>;
693
-
694
- // Pick specific fields
695
- const ScrapedItemSummary = ScrapedItem.pick({
696
- url: true,
697
- title: true,
698
- metadata: true,
699
- });
700
- type ScrapedItemSummary = z.infer<typeof ScrapedItemSummary>;
701
-
702
- // Omit specific fields
703
- const ScrapedItemData = ScrapedItem.omit({ metadata: true });
704
- type ScrapedItemData = z.infer<typeof ScrapedItemData>;
705
-
706
- // Extend with additional fields
707
- const ExtendedItem = ScrapedItem.extend({
708
- screenshot: z.string().optional(),
709
- pdf: z.string().optional(),
710
- });
711
- type ExtendedItem = z.infer<typeof ExtendedItem>;
712
- ```
713
-
714
- ### Utility Types from Zod
715
-
716
- ```typescript
717
- // Make specific fields required
718
- const RequiredConfig = BrowserAgentConfig.required({
719
- browserPool: true,
720
- sessions: true,
721
- });
722
-
723
- // Deep partial (recursive)
724
- const DeepPartialScrapeOptions = ScrapeOptions.deepPartial();
725
- type DeepPartialScrapeOptions = z.infer<typeof DeepPartialScrapeOptions>;
726
-
727
- // Brand types for nominal typing
728
- const UserId = z.string().uuid().brand<'UserId'>();
729
- type UserId = z.infer<typeof UserId>;
730
-
731
- function getUser(id: UserId) { /* ... */ }
732
-
733
- // ✅ Works
734
- const id = UserId.parse('550e8400-e29b-41d4-a716-446655440000');
735
- getUser(id);
736
-
737
- // ❌ Compile error — can't pass random string
738
- getUser('550e8400-e29b-41d4-a716-446655440000');
739
- ```
740
-
741
- ---
742
-
743
- ## 7. Best Practices
744
-
745
- ### Validate at Boundaries, Trust Internally
746
-
747
- ```typescript
748
- // ❌ BAD: Validating everywhere
749
- function processItem(item: ScrapedItem) {
750
- const validated = ScrapedItem.parse(item); // Unnecessary!
751
- return validated.title;
752
- }
753
-
754
- // ✅ GOOD: Validate once at the boundary
755
- async function scrapeAndProcess(url: string): Promise<ProcessedItem> {
756
- // Boundary: incoming data from external source
757
- const html = await fetch(url).then(r => r.text());
758
- const raw = extractData(html); // Returns unknown
759
-
760
- // Validate once
761
- const item = ScrapedItem.parse(raw);
762
-
763
- // Trust internally — no more validation needed
764
- return processItem(item);
765
- }
766
-
767
- function processItem(item: ScrapedItem): ProcessedItem {
768
- // item is guaranteed to be ScrapedItem
769
- return { title: item.title.toUpperCase() };
770
- }
771
- ```
772
-
773
- ### Use safeParse at Boundaries
774
-
775
- ```typescript
776
- // For operations that shouldn't throw
777
- function tryParseScrapeOptions(input: unknown): ScrapeOptions | null {
778
- const result = ScrapeOptions.safeParse(input);
779
- if (result.success) {
780
- return result.data;
781
- }
782
- console.error('Invalid options:', result.error.format());
783
- return null;
784
- }
785
-
786
- // For API responses
787
- async function fetchAndValidate<T extends z.ZodSchema>(
788
- url: string,
789
- schema: T
790
- ): Promise<z.infer<T>> {
791
- const res = await fetch(url);
792
- const json = await res.json();
793
-
794
- const result = schema.safeParse(json);
795
- if (!result.success) {
796
- throw new ScraperError('Invalid API response', {
797
- code: 'RESPONSE_VALIDATION_FAILED',
798
- metadata: { url, errors: result.error.issues },
799
- });
800
- }
801
-
802
- return result.data;
803
- }
804
- ```
805
-
806
- ### Compose Schemas
807
-
808
- ```typescript
809
- // Build complex schemas from simple ones
810
- const BaseEntity = z.object({
811
- id: z.string().uuid(),
812
- createdAt: z.string().datetime(),
813
- updatedAt: z.string().datetime(),
814
- });
815
-
816
- const ScrapedPage = BaseEntity.extend({
817
- url: z.string().url(),
818
- title: z.string(),
819
- content: z.string(),
820
- links: z.array(z.string().url()),
821
- });
822
-
823
- const ScrapedProduct = BaseEntity.extend({
824
- url: z.string().url(),
825
- name: z.string(),
826
- price: z.number().positive(),
827
- inStock: z.boolean(),
828
- images: z.array(z.string().url()),
829
- });
830
-
831
- // Discriminated union for different scraped types
832
- const ScrapedEntity = z.discriminatedUnion('type', [
833
- ScrapedPage.extend({ type: z.literal('page') }),
834
- ScrapedProduct.extend({ type: z.literal('product') }),
835
- ]);
836
- ```
837
-
838
- ---
839
-
840
- ## 8. Response Validation Pattern
841
-
842
- ### Validating External API Responses
843
-
844
- ```typescript
845
- import { z } from 'zod';
846
-
847
- // Schema for a specific API
848
- const ExternalApiResponse = z.object({
849
- status: z.enum(['ok', 'error']),
850
- data: z.object({
851
- results: z.array(z.object({
852
- id: z.number(),
853
- title: z.string(),
854
- body: z.string(),
855
- })),
856
- total: z.number(),
857
- page: z.number(),
858
- }).optional(),
859
- error: z.string().optional(),
860
- }).refine(
861
- (res) => res.status === 'ok' ? !!res.data : !!res.error,
862
- { message: 'Response must have data when status is ok, or error when status is error' }
863
- );
864
-
865
- async function fetchExternalData(query: string) {
866
- const res = await fetch(`https://api.example.com/search?q=${query}`);
867
- const json = await res.json();
868
-
869
- const result = ExternalApiResponse.safeParse(json);
870
-
871
- if (!result.success) {
872
- // Log the raw response for debugging
873
- console.error('Unexpected API response format:', json);
874
- throw new ScraperError('External API returned unexpected format', {
875
- code: 'RESPONSE_VALIDATION_FAILED',
876
- metadata: {
877
- issues: result.error.issues,
878
- rawResponse: json,
879
- },
880
- });
881
- }
882
-
883
- if (result.data.status === 'error') {
884
- throw new ScraperError(`External API error: ${result.data.error}`, {
885
- code: 'EXTERNAL_API_ERROR',
886
- });
887
- }
888
-
889
- return result.data.data!;
890
- }
891
- ```
892
-
893
- ### Validating Scraped HTML Structure
894
-
895
- ```typescript
896
- // After extracting data from HTML, validate the structure
897
- const HtmlExtractedData = z.object({
898
- title: z.string().min(1),
899
- price: z.string().transform((val) => {
900
- const num = parseFloat(val.replace(/[^0-9.]/g, ''));
901
- if (isNaN(num)) throw new Error(`Invalid price: ${val}`);
902
- return num;
903
- }),
904
- rating: z.string().transform((val) => {
905
- const num = parseFloat(val);
906
- if (num < 0 || num > 5) throw new Error(`Rating out of range: ${val}`);
907
- return num;
908
- }),
909
- reviewCount: z.string().transform((val) => {
910
- const num = parseInt(val.replace(/[^0-9]/g, ''), 10);
911
- if (isNaN(num)) throw new Error(`Invalid review count: ${val}`);
912
- return num;
913
- }),
914
- images: z.array(z.string().url()),
915
- inStock: z.string().transform((val) => {
916
- const lower = val.toLowerCase();
917
- return lower.includes('in stock') || lower.includes('available');
918
- }),
919
- });
920
-
921
- // Transform and validate in one step
922
- function parseProductPage(html: string): z.infer<typeof HtmlExtractedData> {
923
- const raw = extractFromHtml(html); // Returns unknown
924
- return HtmlExtractedData.parse(raw); // Throws on invalid data
925
- }
926
- ```
927
-
928
- ---
929
-
930
- ## 9. JSON Schema Generation
931
-
932
- ### Zod v4: z.toJSONSchema
933
-
934
- ```typescript
935
- import { z } from 'zod/v4';
936
-
937
- const ScrapeOptions = z.object({
938
- url: z.string().url(),
939
- concurrency: z.number().int().min(1).max(100).default(5),
940
- headless: z.boolean().default(true),
941
- browser: z.enum(['chromium', 'firefox', 'webkit']).default('chromium'),
942
- proxy: z.object({
943
- url: z.string().url(),
944
- type: z.enum(['http', 'https', 'socks5']).default('http'),
945
- }).optional(),
946
- selectors: z.record(z.string(), z.object({
947
- selector: z.string(),
948
- type: z.enum(['text', 'html', 'attribute']),
949
- })).optional(),
950
- });
951
-
952
- // Generate JSON Schema
953
- const jsonSchema = z.toJSONSchema(ScrapeOptions);
954
-
955
- console.log(JSON.stringify(jsonSchema, null, 2));
956
- // Output:
957
- // {
958
- // "type": "object",
959
- // "properties": {
960
- // "url": { "type": "string", "format": "uri" },
961
- // "concurrency": { "type": "integer", "minimum": 1, "maximum": 100, "default": 5 },
962
- // "headless": { "type": "boolean", "default": true },
963
- // "browser": { "type": "string", "enum": ["chromium", "firefox", "webkit"], "default": "chromium" },
964
- // "proxy": {
965
- // "type": "object",
966
- // "properties": {
967
- // "url": { "type": "string", "format": "uri" },
968
- // "type": { "type": "string", "enum": ["http", "https", "socks5"], "default": "http" }
969
- // },
970
- // "required": ["url"]
971
- // },
972
- // "selectors": {
973
- // "type": "object",
974
- // "additionalProperties": {
975
- // "type": "object",
976
- // "properties": {
977
- // "selector": { "type": "string" },
978
- // "type": { "type": "string", "enum": ["text", "html", "attribute"] }
979
- // },
980
- // "required": ["selector", "type"]
981
- // }
982
- // }
983
- // },
984
- // "required": ["url"],
985
- // "additionalProperties": false
986
- // }
987
- ```
988
-
989
- ### Use Cases for JSON Schema
990
-
991
- ```typescript
992
- // 1. Generate OpenAPI docs
993
- import { z } from 'zod/v4';
994
-
995
- const apiSchema = z.object({
996
- body: ScrapeOptions,
997
- response: z.object({
998
- success: z.boolean(),
999
- data: ScrapedItem,
1000
- }),
1001
- });
1002
-
1003
- const jsonSchema = z.toJSONSchema(apiSchema);
1004
- // Use with swagger-ui or redoc
1005
-
1006
- // 2. Generate VS Code settings schema
1007
- const VsCodeSettings = z.object({
1008
- 'scraper.defaultBrowser': z.enum(['chromium', 'firefox', 'webkit']),
1009
- 'scraper.concurrency': z.number().int().min(1).max(100),
1010
- 'scraper.outputDir': z.string(),
1011
- });
1012
-
1013
- const vscodeSchema = z.toJSONSchema(VsCodeSettings);
1014
- // Write to .vscode/settings.schema.json
1015
-
1016
- // 3. Validate config files at runtime
1017
- const configSchema = z.object({
1018
- targets: z.array(z.object({
1019
- url: z.string().url(),
1020
- schedule: z.string(), // cron expression
1021
- })),
1022
- global: BrowserAgentConfig,
1023
- });
1024
-
1025
- // Load and validate config
1026
- const configPath = path.resolve('scraper.config.json');
1027
- const configJson = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
1028
- const config = configSchema.parse(configJson);
1029
-
1030
- // 4. Client-side form validation
1031
- // Use JSON Schema to generate form fields in React/Vue
1032
- const formSchema = z.toJSONSchema(ScrapeOptions);
1033
- // Pass to react-jsonschema-form or similar
1034
- ```
1035
-
1036
- ### OpenAPI Integration
1037
-
1038
- ```typescript
1039
- import { z } from 'zod/v4';
1040
- import { createDocument } from 'zod-openapi';
1041
-
1042
- const app = z.object({
1043
- openapi: z.literal('3.1.0'),
1044
- info: z.object({
1045
- title: 'Scraper API',
1046
- version: z.string(),
1047
- }),
1048
- paths: z.record(z.string(), z.object({
1049
- post: z.object({
1050
- requestBody: z.object({
1051
- content: z.record(z.string(), z.object({
1052
- schema: z.toJSONSchema(ScrapeOptions),
1053
- })),
1054
- }),
1055
- responses: z.record(z.string(), z.object({
1056
- description: z.string(),
1057
- content: z.record(z.string(), z.object({
1058
- schema: z.toJSONSchema(ScrapedItem),
1059
- })),
1060
- })),
1061
- }),
1062
- })),
1063
- });
1064
-
1065
- // Generate OpenAPI spec
1066
- const spec = app.parse({
1067
- openapi: '3.1.0',
1068
- info: { title: 'Scraper API', version: '1.0.0' },
1069
- paths: {
1070
- '/api/scrape': {
1071
- post: {
1072
- requestBody: {
1073
- content: {
1074
- 'application/json': {
1075
- schema: z.toJSONSchema(ScrapeOptions),
1076
- },
1077
- },
1078
- },
1079
- responses: {
1080
- '200': {
1081
- description: 'Success',
1082
- content: {
1083
- 'application/json': {
1084
- schema: z.toJSONSchema(ScrapedItem),
1085
- },
1086
- },
1087
- },
1088
- },
1089
- },
1090
- },
1091
- },
1092
- });
1093
- ```
1094
-
1095
- ---
1096
-
1097
- ## 10. Complete Code Examples
1098
-
1099
- ### Full Scraper Config Validation System
1100
-
1101
- ```typescript
1102
- import { z } from 'zod';
1103
-
1104
- // ============================================
1105
- // Schema Definitions
1106
- // ============================================
1107
-
1108
- const UrlSchema = z.string().url().refine(
1109
- (url) => {
1110
- try {
1111
- const parsed = new URL(url);
1112
- return ['http:', 'https:'].includes(parsed.protocol);
1113
- } catch {
1114
- return false;
1115
- }
1116
- },
1117
- { message: 'URL must use http or https protocol' }
1118
- );
1119
-
1120
- const ProxySchema = z.object({
1121
- url: UrlSchema,
1122
- username: z.string().optional(),
1123
- password: z.string().optional(),
1124
- type: z.enum(['http', 'https', 'socks5']).default('http'),
1125
- }).strict();
1126
-
1127
- const SelectorSchema = z.object({
1128
- selector: z.string().min(1, 'Selector cannot be empty'),
1129
- timeout: z.number().int().min(100).max(60_000).default(5000),
1130
- optional: z.boolean().default(false),
1131
- waitForVisible: z.boolean().default(false),
1132
- }).strict();
1133
-
1134
- const ScrapeOptionsSchema = z.object({
1135
- url: UrlSchema,
1136
- method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']).default('GET'),
1137
- headers: z.record(z.string(), z.string()).default({
1138
- 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9',
1139
- 'Accept-Language': 'en-US,en;q=0.9',
1140
- }),
1141
- body: z.union([z.string(), z.record(z.unknown())]).optional(),
1142
- browser: z.enum(['chromium', 'firefox', 'webkit']).default('chromium'),
1143
- headless: z.boolean().default(true),
1144
- viewport: z.object({
1145
- width: z.number().int().min(320).max(7680).default(1920),
1146
- height: z.number().int().min(240).max(4320).default(1080),
1147
- }).default({}),
1148
- timeout: z.number().int().min(1000).max(300_000).default(30_000),
1149
- waitForSelector: SelectorSchema.optional(),
1150
- waitAfterLoad: z.number().int().min(0).max(60_000).default(0),
1151
- maxRetries: z.number().int().min(0).max(10).default(3),
1152
- retryDelay: z.number().int().min(0).max(60_000).default(1000),
1153
- retryBackoff: z.enum(['linear', 'exponential']).default('exponential'),
1154
- proxy: ProxySchema.optional(),
1155
- selectors: z.record(z.string(), SelectorSchema).optional(),
1156
- sessionId: z.string().uuid().optional(),
1157
- cookies: z.array(z.object({
1158
- name: z.string(),
1159
- value: z.string(),
1160
- domain: z.string().optional(),
1161
- path: z.string().default('/'),
1162
- })).optional(),
1163
- maxConcurrency: z.number().int().min(1).max(100).default(5),
1164
- requestsPerSecond: z.number().positive().optional(),
1165
- delayBetweenRequests: z.number().int().min(0).max(60_000).optional(),
1166
- format: z.enum(['html', 'text', 'json', 'screenshot']).default('html'),
1167
- screenshotFullPage: z.boolean().default(false),
1168
- }).strict()
1169
- .refine(
1170
- (opts) => !(opts.requestsPerSecond && opts.delayBetweenRequests),
1171
- { message: 'Cannot set both requestsPerSecond and delayBetweenRequests' }
1172
- )
1173
- .refine(
1174
- (opts) => opts.screenshotFullPage ? opts.format === 'screenshot' : true,
1175
- { message: 'screenshotFullPage requires format="screenshot"' }
1176
- );
1177
-
1178
- const BatchConfigSchema = z.object({
1179
- urls: z.array(UrlSchema).min(1).max(10_000),
1180
- defaultOptions: ScrapeOptionsSchema.partial().default({}),
1181
- concurrency: z.number().int().min(1).max(100).default(10),
1182
- rateLimit: z.object({
1183
- requestsPerSecond: z.number().positive(),
1184
- burstSize: z.number().int().positive().default(5),
1185
- }).optional(),
1186
- deadline: z.string().datetime().optional(),
1187
- onProgress: z.function().optional(),
1188
- }).strict();
1189
-
1190
- const BrowserAgentConfigSchema = z.object({
1191
- browserPool: z.object({
1192
- minBrowsers: z.number().int().min(1).default(1),
1193
- maxBrowsers: z.number().int().min(1).max(20).default(5),
1194
- maxPagesPerBrowser: z.number().int().min(1).max(50).default(10),
1195
- idleTimeout: z.number().int().min(1000).default(60_000),
1196
- launchTimeout: z.number().int().min(1000).default(30_000),
1197
- }).default({}),
1198
- sessions: z.object({
1199
- maxSessions: z.number().int().min(1).default(100),
1200
- sessionTimeout: z.number().int().min(60_000).default(3_600_000),
1201
- rotateOnBlock: z.boolean().default(true),
1202
- }).default({}),
1203
- stealth: z.object({
1204
- enabled: z.boolean().default(true),
1205
- randomizeViewport: z.boolean().default(true),
1206
- randomizeTiming: z.boolean().default(true),
1207
- minDelay: z.number().int().min(0).default(500),
1208
- maxDelay: z.number().int().min(0).default(2000),
1209
- }).default({}),
1210
- errorHandling: z.object({
1211
- maxConsecutiveErrors: z.number().int().min(1).default(5),
1212
- circuitBreakerThreshold: z.number().min(0).max(1).default(0.5),
1213
- circuitBreakerResetTimeout: z.number().int().min(1000).default(60_000),
1214
- }).default({}),
1215
- }).strict();
1216
-
1217
- // ============================================
1218
- // Validation Utility
1219
- // ============================================
1220
-
1221
- class ValidationError extends Error {
1222
- public readonly issues: z.ZodIssue[];
1223
-
1224
- constructor(error: z.ZodError) {
1225
- const message = error.issues
1226
- .map(i => `${i.path.join('.')}: ${i.message}`)
1227
- .join('\n');
1228
- super(`Validation failed:\n${message}`);
1229
- this.name = 'ValidationError';
1230
- this.issues = error.issues;
1231
- }
1232
-
1233
- toJSON() {
1234
- return {
1235
- name: this.name,
1236
- message: this.message,
1237
- issues: this.issues.map(i => ({
1238
- path: i.path.join('.'),
1239
- message: i.message,
1240
- code: i.code,
1241
- })),
1242
- };
1243
- }
1244
- }
1245
-
1246
- function validate<T extends z.ZodSchema>(schema: T, data: unknown): z.infer<T> {
1247
- const result = schema.safeParse(data);
1248
- if (!result.success) {
1249
- throw new ValidationError(result.error);
1250
- }
1251
- return result.data;
1252
- }
1253
-
1254
- // ============================================
1255
- // Usage
1256
- // ============================================
1257
-
1258
- // Single URL scrape
1259
- const options = validate(ScrapeOptionsSchema, {
1260
- url: 'https://example.com',
1261
- concurrency: 3,
1262
- proxy: {
1263
- url: 'http://proxy.example.com:8080',
1264
- type: 'http',
1265
- },
1266
- });
1267
-
1268
- // Batch scrape
1269
- const batch = validate(BatchConfigSchema, {
1270
- urls: [
1271
- 'https://example.com/page1',
1272
- 'https://example.com/page2',
1273
- 'https://example.com/page3',
1274
- ],
1275
- concurrency: 5,
1276
- defaultOptions: {
1277
- headless: true,
1278
- maxRetries: 3,
1279
- },
1280
- });
1281
-
1282
- // Browser agent config
1283
- const agentConfig = validate(BrowserAgentConfigSchema, {
1284
- browserPool: {
1285
- maxBrowsers: 3,
1286
- maxPagesPerBrowser: 15,
1287
- },
1288
- stealth: {
1289
- enabled: true,
1290
- randomizeTiming: true,
1291
- },
1292
- });
1293
-
1294
- // CLI args validation
1295
- const cliOptions = validate(
1296
- z.object({
1297
- url: z.string().url(),
1298
- concurrency: z.coerce.number().int().min(1).max(100).default(5),
1299
- headless: z.coerce.boolean().default(true),
1300
- verbose: z.coerce.boolean().default(false),
1301
- }),
1302
- {
1303
- url: process.argv[2],
1304
- concurrency: process.argv[3],
1305
- headless: process.argv[4],
1306
- verbose: process.argv[5],
1307
- }
1308
- );
1309
-
1310
- // API request validation (Express middleware)
1311
- function validateBody<T extends z.ZodSchema>(schema: T) {
1312
- return (req: any, res: any, next: any) => {
1313
- const result = schema.safeParse(req.body);
1314
- if (!result.success) {
1315
- return res.status(400).json({
1316
- error: 'Validation failed',
1317
- details: result.error.issues.map(i => ({
1318
- path: i.path.join('.'),
1319
- message: i.message,
1320
- })),
1321
- });
1322
- }
1323
- req.body = result.data;
1324
- next();
1325
- };
1326
- }
1327
-
1328
- // app.post('/api/scrape', validateBody(ScrapeOptionsSchema), handler);
1329
- ```
1330
-
1331
- ---
1332
-
1333
- ## Summary: Quick Reference
1334
-
1335
- | Task | Zod API | Example |
1336
- |------|---------|---------|
1337
- | Basic object | `z.object({...})` | `z.object({ url: z.string() })` |
1338
- | String URL | `z.string().url()` | Validates URL format |
1339
- | Number with bounds | `z.number().min().max()` | `z.number().int().min(1).max(100)` |
1340
- | Enum | `z.enum([...])` | `z.enum(['a', 'b', 'c'])` |
1341
- | Default values | `.default(value)` | `z.number().default(5)` |
1342
- | Optional | `.optional()` | `z.string().optional()` |
1343
- | Coerce from string | `z.coerce.number()` | CLI arguments |
1344
- | Transform | `.transform(fn)` | Parse string to Date |
1345
- | Refine | `.refine(fn, msg)` | Cross-field validation |
1346
- | Discriminated union | `z.discriminatedUnion()` | Different response types |
1347
- | Strict object | `z.strictObject()` | Reject unknown keys |
1348
- | Derive TS type | `z.infer<typeof schema>` | Type from schema |
1349
- | Safe parse | `.safeParse(data)` | Returns result, no throw |
1350
- | Generate JSON Schema | `z.toJSONSchema()` | v4 only |