reqon-dsl 0.2.0 → 0.3.0

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 (396) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +22 -0
  3. package/dist/ast/nodes.d.ts +83 -4
  4. package/dist/ast/nodes.js +14 -0
  5. package/dist/auth/circuit-breaker.js +7 -6
  6. package/dist/auth/rate-limiter.d.ts +4 -0
  7. package/dist/auth/rate-limiter.js +9 -16
  8. package/dist/cli.d.ts +13 -0
  9. package/dist/cli.js +84 -4
  10. package/dist/config/constants.d.ts +141 -0
  11. package/dist/config/constants.js +128 -0
  12. package/dist/config/index.d.ts +4 -0
  13. package/dist/config/index.js +4 -0
  14. package/dist/control/index.d.ts +2 -0
  15. package/dist/control/index.js +1 -0
  16. package/dist/control/server.d.ts +88 -0
  17. package/dist/control/server.js +238 -0
  18. package/dist/control/types.d.ts +55 -0
  19. package/dist/control/types.js +7 -0
  20. package/dist/debug/cli-debugger.d.ts +17 -0
  21. package/dist/debug/cli-debugger.js +180 -0
  22. package/dist/debug/controller.d.ts +94 -0
  23. package/dist/debug/controller.js +45 -0
  24. package/dist/debug/index.d.ts +6 -0
  25. package/dist/debug/index.js +5 -0
  26. package/dist/errors/index.d.ts +67 -0
  27. package/dist/errors/index.js +89 -1
  28. package/dist/execution/index.d.ts +1 -1
  29. package/dist/execution/state.d.ts +24 -0
  30. package/dist/index.d.ts +21 -1
  31. package/dist/index.js +33 -2
  32. package/dist/interpreter/context.d.ts +14 -0
  33. package/dist/interpreter/context.js +15 -0
  34. package/dist/interpreter/evaluator.d.ts +63 -1
  35. package/dist/interpreter/evaluator.js +186 -39
  36. package/dist/interpreter/executor.d.ts +70 -14
  37. package/dist/interpreter/executor.js +503 -174
  38. package/dist/interpreter/fetch-handler.d.ts +9 -0
  39. package/dist/interpreter/fetch-handler.js +133 -24
  40. package/dist/interpreter/http.d.ts +5 -0
  41. package/dist/interpreter/http.js +26 -12
  42. package/dist/interpreter/index.d.ts +3 -1
  43. package/dist/interpreter/index.js +2 -0
  44. package/dist/interpreter/pagination.d.ts +11 -2
  45. package/dist/interpreter/pagination.js +95 -31
  46. package/dist/interpreter/signals.d.ts +8 -0
  47. package/dist/interpreter/signals.js +12 -0
  48. package/dist/interpreter/source-manager.d.ts +75 -0
  49. package/dist/interpreter/source-manager.js +157 -0
  50. package/dist/interpreter/step-handlers/apply-handler.d.ts +29 -0
  51. package/dist/interpreter/step-handlers/apply-handler.js +79 -0
  52. package/dist/interpreter/step-handlers/for-handler.d.ts +13 -0
  53. package/dist/interpreter/step-handlers/for-handler.js +71 -4
  54. package/dist/interpreter/step-handlers/index.d.ts +4 -2
  55. package/dist/interpreter/step-handlers/index.js +4 -2
  56. package/dist/interpreter/step-handlers/match-handler.d.ts +9 -0
  57. package/dist/interpreter/step-handlers/match-handler.js +43 -16
  58. package/dist/interpreter/step-handlers/pause-handler.d.ts +52 -0
  59. package/dist/interpreter/step-handlers/pause-handler.js +87 -0
  60. package/dist/interpreter/step-handlers/store-handler.d.ts +11 -1
  61. package/dist/interpreter/step-handlers/store-handler.js +45 -13
  62. package/dist/interpreter/step-handlers/types.d.ts +3 -0
  63. package/dist/interpreter/step-handlers/validate-handler.d.ts +2 -1
  64. package/dist/interpreter/step-handlers/validate-handler.js +4 -2
  65. package/dist/interpreter/step-handlers/webhook-handler.d.ts +3 -0
  66. package/dist/interpreter/step-handlers/webhook-handler.js +18 -2
  67. package/dist/interpreter/store-manager.d.ts +46 -0
  68. package/dist/interpreter/store-manager.js +66 -0
  69. package/dist/lexer/index.d.ts +11 -4
  70. package/dist/lexer/index.js +11 -4
  71. package/dist/lexer/tokens.d.ts +17 -1
  72. package/dist/lexer/tokens.js +36 -0
  73. package/dist/mcp/index.d.ts +11 -0
  74. package/dist/mcp/index.js +11 -0
  75. package/dist/mcp/server.d.ts +17 -0
  76. package/dist/mcp/server.js +451 -0
  77. package/dist/oas/index.d.ts +2 -0
  78. package/dist/oas/index.js +1 -0
  79. package/dist/oas/mock-generator.d.ts +12 -0
  80. package/dist/oas/mock-generator.js +187 -0
  81. package/dist/observability/events.d.ts +244 -0
  82. package/dist/observability/events.js +90 -0
  83. package/dist/observability/index.d.ts +15 -0
  84. package/dist/observability/index.js +12 -0
  85. package/dist/observability/logger.d.ts +106 -0
  86. package/dist/observability/logger.js +259 -0
  87. package/dist/observability/otel.d.ts +135 -0
  88. package/dist/observability/otel.js +386 -0
  89. package/dist/parser/action-parser.d.ts +105 -0
  90. package/dist/parser/action-parser.js +645 -0
  91. package/dist/parser/expressions.d.ts +13 -0
  92. package/dist/parser/expressions.js +72 -2
  93. package/dist/parser/fetch-parser.d.ts +27 -0
  94. package/dist/parser/fetch-parser.js +269 -0
  95. package/dist/parser/index.d.ts +17 -0
  96. package/dist/parser/index.js +17 -0
  97. package/dist/parser/parser.d.ts +44 -46
  98. package/dist/parser/parser.js +122 -1070
  99. package/dist/parser/pipeline-parser.d.ts +12 -0
  100. package/dist/parser/pipeline-parser.js +52 -0
  101. package/dist/parser/schedule-parser.d.ts +7 -0
  102. package/dist/parser/schedule-parser.js +137 -0
  103. package/dist/parser/source-parser.d.ts +9 -0
  104. package/dist/parser/source-parser.js +151 -0
  105. package/dist/pause/index.d.ts +14 -0
  106. package/dist/pause/index.js +11 -0
  107. package/dist/pause/manager.d.ts +118 -0
  108. package/dist/pause/manager.js +245 -0
  109. package/dist/pause/state.d.ts +93 -0
  110. package/dist/pause/state.js +103 -0
  111. package/dist/pause/store.d.ts +61 -0
  112. package/dist/pause/store.js +156 -0
  113. package/dist/plugin.d.ts +9 -12
  114. package/dist/plugin.js +10 -13
  115. package/dist/stores/factory.d.ts +1 -1
  116. package/dist/stores/factory.js +3 -2
  117. package/dist/stores/file.d.ts +26 -0
  118. package/dist/stores/file.js +64 -10
  119. package/dist/stores/index.d.ts +16 -1
  120. package/dist/stores/index.js +16 -1
  121. package/dist/stores/memory.d.ts +4 -0
  122. package/dist/stores/memory.js +11 -0
  123. package/dist/stores/types.d.ts +17 -0
  124. package/dist/stores/types.js +12 -0
  125. package/dist/trace/index.d.ts +16 -0
  126. package/dist/trace/index.js +12 -0
  127. package/dist/trace/recorder.d.ts +71 -0
  128. package/dist/trace/recorder.js +144 -0
  129. package/dist/trace/replay.d.ts +132 -0
  130. package/dist/trace/replay.js +264 -0
  131. package/dist/trace/state.d.ts +102 -0
  132. package/dist/trace/state.js +86 -0
  133. package/dist/trace/store.d.ts +69 -0
  134. package/dist/trace/store.js +225 -0
  135. package/dist/utils/index.d.ts +1 -0
  136. package/dist/utils/index.js +1 -0
  137. package/dist/utils/type-guards.d.ts +58 -0
  138. package/dist/utils/type-guards.js +92 -0
  139. package/dist/webhook/server.js +7 -6
  140. package/package.json +55 -6
  141. package/.claude/settings.local.json +0 -31
  142. package/.claude/skills/api-integration.md +0 -125
  143. package/.claude/skills/database-schema.md +0 -51
  144. package/.claude/skills/dsl-design.md +0 -80
  145. package/.claude/skills/property-testing.md +0 -143
  146. package/.claude/skills/reqon/SKILL.md +0 -44
  147. package/.claude/skills/reqon/references/examples.md +0 -206
  148. package/.claude/skills/reqon/references/syntax.md +0 -263
  149. package/.claude/skills/vscode-extension.md +0 -113
  150. package/.github/dependabot.yml +0 -32
  151. package/.github/pull_request_template.md +0 -21
  152. package/.github/workflows/ci.yml +0 -174
  153. package/.github/workflows/release.yml +0 -73
  154. package/CLAUDE.md +0 -72
  155. package/CONTRIBUTING.md +0 -161
  156. package/TODO.md +0 -51
  157. package/dist/auth/auth.test.d.ts +0 -1
  158. package/dist/auth/auth.test.js +0 -255
  159. package/dist/errors/errors.test.d.ts +0 -1
  160. package/dist/errors/errors.test.js +0 -165
  161. package/dist/execution/execution.test.d.ts +0 -1
  162. package/dist/execution/execution.test.js +0 -246
  163. package/dist/integration.test.d.ts +0 -1
  164. package/dist/integration.test.js +0 -168
  165. package/dist/interpreter/evaluator.test.d.ts +0 -1
  166. package/dist/interpreter/evaluator.test.js +0 -512
  167. package/dist/interpreter/http.test.d.ts +0 -1
  168. package/dist/interpreter/http.test.js +0 -299
  169. package/dist/interpreter/progress.test.d.ts +0 -1
  170. package/dist/interpreter/progress.test.js +0 -216
  171. package/dist/interpreter/schema-matcher.test.d.ts +0 -1
  172. package/dist/interpreter/schema-matcher.test.js +0 -122
  173. package/dist/lexer/lexer.d.ts +0 -24
  174. package/dist/lexer/lexer.js +0 -264
  175. package/dist/lexer/lexer.test.d.ts +0 -1
  176. package/dist/lexer/lexer.test.js +0 -259
  177. package/dist/loader/loader.test.d.ts +0 -1
  178. package/dist/loader/loader.test.js +0 -287
  179. package/dist/oas/oas.test.d.ts +0 -1
  180. package/dist/oas/oas.test.js +0 -218
  181. package/dist/parser/expressions.test.d.ts +0 -1
  182. package/dist/parser/expressions.test.js +0 -378
  183. package/dist/parser/match.test.d.ts +0 -1
  184. package/dist/parser/match.test.js +0 -254
  185. package/dist/parser/parser.test.d.ts +0 -1
  186. package/dist/parser/parser.test.js +0 -333
  187. package/dist/parser/schedule.test.d.ts +0 -1
  188. package/dist/parser/schedule.test.js +0 -241
  189. package/dist/scheduler/cron-parser.test.d.ts +0 -1
  190. package/dist/scheduler/cron-parser.test.js +0 -188
  191. package/dist/stores/file.test.d.ts +0 -1
  192. package/dist/stores/file.test.js +0 -165
  193. package/dist/stores/memory.test.d.ts +0 -1
  194. package/dist/stores/memory.test.js +0 -157
  195. package/dist/stores/stores.test.d.ts +0 -1
  196. package/dist/stores/stores.test.js +0 -158
  197. package/dist/sync/sync.test.d.ts +0 -1
  198. package/dist/sync/sync.test.js +0 -221
  199. package/docusaurus/README.md +0 -41
  200. package/docusaurus/docs/advanced/execution-state.md +0 -283
  201. package/docusaurus/docs/advanced/extending-reqon.md +0 -388
  202. package/docusaurus/docs/advanced/multi-file-missions.md +0 -250
  203. package/docusaurus/docs/advanced/parallel-execution.md +0 -353
  204. package/docusaurus/docs/api-reference.md +0 -443
  205. package/docusaurus/docs/authentication/api-key.md +0 -339
  206. package/docusaurus/docs/authentication/basic.md +0 -276
  207. package/docusaurus/docs/authentication/bearer.md +0 -282
  208. package/docusaurus/docs/authentication/oauth2.md +0 -317
  209. package/docusaurus/docs/authentication/overview.md +0 -251
  210. package/docusaurus/docs/cli.md +0 -229
  211. package/docusaurus/docs/core-concepts/actions.md +0 -286
  212. package/docusaurus/docs/core-concepts/missions.md +0 -264
  213. package/docusaurus/docs/core-concepts/schemas.md +0 -353
  214. package/docusaurus/docs/core-concepts/sources.md +0 -339
  215. package/docusaurus/docs/core-concepts/stores.md +0 -332
  216. package/docusaurus/docs/dsl-syntax/expressions.md +0 -361
  217. package/docusaurus/docs/dsl-syntax/fetch.md +0 -293
  218. package/docusaurus/docs/dsl-syntax/for-loops.md +0 -324
  219. package/docusaurus/docs/dsl-syntax/map.md +0 -345
  220. package/docusaurus/docs/dsl-syntax/match.md +0 -387
  221. package/docusaurus/docs/dsl-syntax/pipelines.md +0 -397
  222. package/docusaurus/docs/dsl-syntax/validate.md +0 -401
  223. package/docusaurus/docs/error-handling/dead-letter-queues.md +0 -399
  224. package/docusaurus/docs/error-handling/flow-control.md +0 -337
  225. package/docusaurus/docs/error-handling/retry-strategies.md +0 -368
  226. package/docusaurus/docs/examples.md +0 -488
  227. package/docusaurus/docs/getting-started.md +0 -256
  228. package/docusaurus/docs/http/circuit-breaker.md +0 -401
  229. package/docusaurus/docs/http/incremental-sync.md +0 -394
  230. package/docusaurus/docs/http/pagination.md +0 -361
  231. package/docusaurus/docs/http/rate-limiting.md +0 -383
  232. package/docusaurus/docs/http/requests.md +0 -328
  233. package/docusaurus/docs/http/retry.md +0 -402
  234. package/docusaurus/docs/intro.md +0 -90
  235. package/docusaurus/docs/openapi/loading-specs.md +0 -305
  236. package/docusaurus/docs/openapi/operation-calls.md +0 -314
  237. package/docusaurus/docs/openapi/overview.md +0 -212
  238. package/docusaurus/docs/openapi/response-validation.md +0 -344
  239. package/docusaurus/docs/scheduling/cron.md +0 -305
  240. package/docusaurus/docs/scheduling/daemon-mode.md +0 -317
  241. package/docusaurus/docs/scheduling/intervals.md +0 -289
  242. package/docusaurus/docs/scheduling/overview.md +0 -231
  243. package/docusaurus/docs/stores/custom-adapters.md +0 -376
  244. package/docusaurus/docs/stores/file.md +0 -236
  245. package/docusaurus/docs/stores/memory.md +0 -193
  246. package/docusaurus/docs/stores/overview.md +0 -274
  247. package/docusaurus/docs/stores/postgrest.md +0 -316
  248. package/docusaurus/docusaurus.config.ts +0 -148
  249. package/docusaurus/package-lock.json +0 -18029
  250. package/docusaurus/package.json +0 -47
  251. package/docusaurus/sidebars.ts +0 -155
  252. package/docusaurus/src/components/HomepageFeatures/index.tsx +0 -105
  253. package/docusaurus/src/components/HomepageFeatures/styles.module.css +0 -12
  254. package/docusaurus/src/css/custom.css +0 -169
  255. package/docusaurus/src/pages/index.module.css +0 -48
  256. package/docusaurus/src/pages/index.tsx +0 -110
  257. package/docusaurus/src/pages/markdown-page.md +0 -7
  258. package/docusaurus/static/.nojekyll +0 -0
  259. package/docusaurus/static/img/docusaurus-social-card.jpg +0 -0
  260. package/docusaurus/static/img/docusaurus.png +0 -0
  261. package/docusaurus/static/img/favicon.ico +0 -0
  262. package/docusaurus/static/img/logo.svg +0 -10
  263. package/docusaurus/static/img/undraw_docusaurus_mountain.svg +0 -171
  264. package/docusaurus/static/img/undraw_docusaurus_react.svg +0 -170
  265. package/docusaurus/static/img/undraw_docusaurus_tree.svg +0 -40
  266. package/docusaurus/tsconfig.json +0 -8
  267. package/examples/README.md +0 -112
  268. package/examples/error-handling/README.md +0 -150
  269. package/examples/error-handling/payment-processor.vague +0 -287
  270. package/examples/github-sync/README.md +0 -74
  271. package/examples/github-sync/fetch-issues.vague +0 -47
  272. package/examples/github-sync/fetch-prs.vague +0 -40
  273. package/examples/github-sync/mission.vague +0 -101
  274. package/examples/github-sync/normalize.vague +0 -70
  275. package/examples/jsonplaceholder/README.md +0 -28
  276. package/examples/jsonplaceholder/posts.vague +0 -48
  277. package/examples/petstore/README.md +0 -35
  278. package/examples/petstore/openapi.yaml +0 -97
  279. package/examples/petstore/sync.vague +0 -52
  280. package/examples/temporal-comparison/README.md +0 -297
  281. package/examples/temporal-comparison/reconciliation.vague +0 -355
  282. package/examples/temporal-comparison/temporal/activities/index.ts +0 -8
  283. package/examples/temporal-comparison/temporal/activities/shipstation.ts +0 -225
  284. package/examples/temporal-comparison/temporal/activities/shopify.ts +0 -257
  285. package/examples/temporal-comparison/temporal/activities/storage.ts +0 -198
  286. package/examples/temporal-comparison/temporal/activities/stripe.ts +0 -169
  287. package/examples/temporal-comparison/temporal/activities/validation.ts +0 -205
  288. package/examples/temporal-comparison/temporal/client/schedule.ts +0 -218
  289. package/examples/temporal-comparison/temporal/config/retry.ts +0 -63
  290. package/examples/temporal-comparison/temporal/types/index.ts +0 -129
  291. package/examples/temporal-comparison/temporal/workers/main.ts +0 -130
  292. package/examples/temporal-comparison/temporal/workflows/orderReconciliation.ts +0 -262
  293. package/examples/xero/README.md +0 -88
  294. package/examples/xero/invoices.vague +0 -189
  295. package/src/api-integration.test.ts +0 -954
  296. package/src/ast/index.ts +0 -1
  297. package/src/ast/nodes.ts +0 -310
  298. package/src/auth/auth.test.ts +0 -326
  299. package/src/auth/circuit-breaker.test.ts +0 -390
  300. package/src/auth/circuit-breaker.ts +0 -379
  301. package/src/auth/credentials.test.ts +0 -273
  302. package/src/auth/credentials.ts +0 -246
  303. package/src/auth/index.ts +0 -40
  304. package/src/auth/oauth2-provider.ts +0 -177
  305. package/src/auth/rate-limiter.ts +0 -459
  306. package/src/auth/token-store.ts +0 -177
  307. package/src/auth/types.ts +0 -159
  308. package/src/benchmark/e2e.bench.ts +0 -288
  309. package/src/benchmark/evaluator.bench.ts +0 -331
  310. package/src/benchmark/fixtures.ts +0 -295
  311. package/src/benchmark/index.ts +0 -108
  312. package/src/benchmark/lexer.bench.ts +0 -69
  313. package/src/benchmark/parser.bench.ts +0 -103
  314. package/src/benchmark/resilience.bench.ts +0 -193
  315. package/src/benchmark/store.bench.ts +0 -147
  316. package/src/benchmark/utils.ts +0 -230
  317. package/src/cli.ts +0 -313
  318. package/src/errors/errors.test.ts +0 -234
  319. package/src/errors/index.ts +0 -223
  320. package/src/execution/execution.test.ts +0 -307
  321. package/src/execution/index.ts +0 -21
  322. package/src/execution/state.ts +0 -207
  323. package/src/execution/store.ts +0 -188
  324. package/src/index.ts +0 -169
  325. package/src/integration.test.ts +0 -192
  326. package/src/interpreter/context.ts +0 -57
  327. package/src/interpreter/evaluator.test.ts +0 -796
  328. package/src/interpreter/evaluator.ts +0 -245
  329. package/src/interpreter/executor.ts +0 -946
  330. package/src/interpreter/fetch-handler.ts +0 -302
  331. package/src/interpreter/http.test.ts +0 -423
  332. package/src/interpreter/http.ts +0 -308
  333. package/src/interpreter/index.ts +0 -32
  334. package/src/interpreter/pagination.ts +0 -207
  335. package/src/interpreter/progress.test.ts +0 -276
  336. package/src/interpreter/schema-matcher.test.ts +0 -160
  337. package/src/interpreter/schema-matcher.ts +0 -168
  338. package/src/interpreter/signals.ts +0 -73
  339. package/src/interpreter/step-handlers/for-handler.ts +0 -65
  340. package/src/interpreter/step-handlers/index.ts +0 -17
  341. package/src/interpreter/step-handlers/map-handler.ts +0 -24
  342. package/src/interpreter/step-handlers/match-handler.ts +0 -101
  343. package/src/interpreter/step-handlers/store-handler.ts +0 -78
  344. package/src/interpreter/step-handlers/types.ts +0 -17
  345. package/src/interpreter/step-handlers/validate-handler.ts +0 -30
  346. package/src/interpreter/step-handlers/webhook-handler.ts +0 -142
  347. package/src/lexer/index.ts +0 -18
  348. package/src/lexer/lexer.test.ts +0 -316
  349. package/src/lexer/tokens.ts +0 -179
  350. package/src/loader/index.ts +0 -288
  351. package/src/loader/loader.test.ts +0 -360
  352. package/src/oas/index.ts +0 -4
  353. package/src/oas/loader.ts +0 -126
  354. package/src/oas/oas.test.ts +0 -254
  355. package/src/oas/validator.ts +0 -299
  356. package/src/parser/base.ts +0 -124
  357. package/src/parser/expressions.test.ts +0 -525
  358. package/src/parser/expressions.ts +0 -314
  359. package/src/parser/index.ts +0 -3
  360. package/src/parser/match.test.ts +0 -296
  361. package/src/parser/parser.test.ts +0 -739
  362. package/src/parser/parser.ts +0 -1469
  363. package/src/parser/schedule.test.ts +0 -287
  364. package/src/parser/webhook.test.ts +0 -248
  365. package/src/plugin.ts +0 -83
  366. package/src/scheduler/cron-parser.test.ts +0 -236
  367. package/src/scheduler/cron-parser.ts +0 -236
  368. package/src/scheduler/index.ts +0 -10
  369. package/src/scheduler/scheduler.ts +0 -443
  370. package/src/scheduler/types.ts +0 -71
  371. package/src/stores/factory.ts +0 -104
  372. package/src/stores/file.test.ts +0 -276
  373. package/src/stores/file.ts +0 -211
  374. package/src/stores/index.ts +0 -6
  375. package/src/stores/memory.test.ts +0 -238
  376. package/src/stores/memory.ts +0 -63
  377. package/src/stores/postgrest.test.ts +0 -488
  378. package/src/stores/postgrest.ts +0 -263
  379. package/src/stores/stores.test.ts +0 -197
  380. package/src/stores/types.ts +0 -58
  381. package/src/sync/index.ts +0 -16
  382. package/src/sync/state.ts +0 -126
  383. package/src/sync/store.ts +0 -139
  384. package/src/sync/sync.test.ts +0 -271
  385. package/src/utils/async.ts +0 -10
  386. package/src/utils/file.ts +0 -106
  387. package/src/utils/index.ts +0 -14
  388. package/src/utils/logger.ts +0 -53
  389. package/src/utils/path.ts +0 -47
  390. package/src/webhook/index.ts +0 -15
  391. package/src/webhook/server.test.ts +0 -253
  392. package/src/webhook/server.ts +0 -389
  393. package/src/webhook/store.ts +0 -239
  394. package/src/webhook/types.ts +0 -93
  395. package/tsconfig.json +0 -17
  396. package/vitest.config.ts +0 -39
package/CLAUDE.md DELETED
@@ -1,72 +0,0 @@
1
- # Reqon
2
-
3
- A declarative DSL framework for fetch, map, validate pipelines - built on [Vague](https://github.com/mcclowes/vague).
4
-
5
- ## Architecture
6
-
7
- - **Vague** is the DSL layer (lexer, parser, expression syntax)
8
- - **Reqon** is the runtime/framework extending Vague with execution semantics
9
-
10
- ## Project Structure
11
-
12
- ```
13
- src/
14
- ├── ast/ # Extended AST nodes (missions, actions, steps)
15
- ├── auth/ # Rate limiting and authentication providers
16
- ├── errors/ # Structured error classes (ParseError, RuntimeError, etc.)
17
- ├── execution/ # Execution state management and persistence
18
- ├── interpreter/ # Runtime execution
19
- │ ├── context.ts # Execution context (stores, variables)
20
- │ ├── evaluator.ts # Expression evaluation
21
- │ ├── executor.ts # Mission/action execution
22
- │ ├── fetch-handler.ts # HTTP fetch with sync checkpoints
23
- │ ├── pagination.ts # Pagination strategies (offset, page, cursor)
24
- │ └── http.ts # HTTP client with retry/backoff
25
- ├── lexer/ # Reqon keywords (uses Vague's lexer via plugin)
26
- ├── oas/ # OpenAPI spec integration
27
- ├── parser/ # Parser for mission/action/fetch/store syntax
28
- ├── scheduler/ # Cron scheduling for missions
29
- ├── stores/ # Store adapters (memory, file, extensible to SQL/NoSQL)
30
- ├── sync/ # Incremental sync checkpointing
31
- ├── utils/ # Shared utilities (sleep, path traversal, logger)
32
- ├── index.ts # Main exports
33
- └── cli.ts # CLI entry point
34
- ```
35
-
36
- ## Commands
37
-
38
- ```bash
39
- npm run build # Compile TypeScript
40
- npm run test # Run tests in watch mode
41
- npm run test:run # Run tests once
42
- npm run dev # Watch mode compilation
43
- ```
44
-
45
- ## DSL Syntax
46
-
47
- Key constructs:
48
- - `mission` - Pipeline definition
49
- - `source` - API source with auth (oauth2, bearer, basic, api_key), or from OAS spec
50
- - `store` - Storage target (memory, file, sql, nosql)
51
- - `action` - Discrete pipeline step
52
- - `fetch` - HTTP request with optional pagination/retry, or OAS operationId reference
53
- - `for...in...where` - Iteration with filtering
54
- - `map...->` - Schema transformation
55
- - `validate` - Constraint checking with `assume`
56
- - `run...then` - Pipeline sequencing (supports `run [A, B] then C` for parallel)
57
- - `match` - Pattern matching (from Vague)
58
- - `since: lastSync` - Incremental sync with checkpointing
59
-
60
- ## Code Conventions
61
-
62
- - TypeScript with strict mode
63
- - Vitest for testing
64
- - Test files alongside implementation (`*.test.ts`)
65
- - Vague dependency via local file link (`file:../vague`)
66
-
67
- ## Key Decisions
68
-
69
- 1. **Extends Vague**: Reqon uses Vague's lexer (via plugin system) and expression syntax; parser extends Vague's token types
70
- 2. **Keyword conflicts**: Parser explicitly handles Reqon keywords (key, partial, upsert, page, etc.) when they appear in option contexts
71
- 3. **`response` identifier**: Special-cased in evaluator to reference `ctx.response`
72
- 4. **Store adapters**: Interface-based design for pluggable storage backends
package/CONTRIBUTING.md DELETED
@@ -1,161 +0,0 @@
1
- # Contributing to Reqon
2
-
3
- Thank you for your interest in contributing to Reqon! This guide will help you get started.
4
-
5
- ## Getting Started
6
-
7
- ### Prerequisites
8
-
9
- - Node.js 18 or higher
10
- - npm
11
- - [Vague](https://github.com/mcclowes/vague) cloned as a sibling directory (required for local development)
12
-
13
- ### Setup
14
-
15
- 1. Clone the repository:
16
- ```bash
17
- git clone https://github.com/mcclowes/reqon.git
18
- cd reqon
19
- ```
20
-
21
- 2. Clone Vague as a sibling directory:
22
- ```bash
23
- cd ..
24
- git clone https://github.com/mcclowes/vague.git
25
- cd reqon
26
- ```
27
-
28
- 3. Install dependencies:
29
- ```bash
30
- npm install
31
- ```
32
-
33
- 4. Build the project:
34
- ```bash
35
- npm run build
36
- ```
37
-
38
- 5. Run tests to verify setup:
39
- ```bash
40
- npm run test:run
41
- ```
42
-
43
- ## Development Workflow
44
-
45
- ### Available Scripts
46
-
47
- | Command | Description |
48
- |---------|-------------|
49
- | `npm run build` | Compile TypeScript to `dist/` |
50
- | `npm run dev` | Watch mode compilation |
51
- | `npm run test` | Run tests in watch mode |
52
- | `npm run test:run` | Run tests once |
53
- | `npm run test:coverage` | Run tests with coverage report |
54
-
55
- ### Project Structure
56
-
57
- ```
58
- src/
59
- ├── ast/ # Extended AST nodes (missions, actions, steps)
60
- ├── auth/ # Rate limiting and authentication providers
61
- ├── errors/ # Structured error classes
62
- ├── execution/ # Execution state management and persistence
63
- ├── interpreter/ # Runtime execution (context, evaluator, executor)
64
- ├── lexer/ # Reqon keywords (uses Vague's lexer via plugin)
65
- ├── oas/ # OpenAPI spec integration
66
- ├── parser/ # Parser for mission/action/fetch/store syntax
67
- ├── scheduler/ # Cron scheduling for missions
68
- ├── stores/ # Store adapters (memory, file, postgrest)
69
- ├── sync/ # Incremental sync checkpointing
70
- ├── utils/ # Shared utilities
71
- ├── index.ts # Main exports
72
- └── cli.ts # CLI entry point
73
- ```
74
-
75
- ## Code Conventions
76
-
77
- ### TypeScript
78
-
79
- - Strict mode is enabled
80
- - Use explicit types for function parameters and return values
81
- - Prefer `interface` over `type` for object shapes
82
-
83
- ### Testing
84
-
85
- - Tests use [Vitest](https://vitest.dev/)
86
- - Test files are co-located with implementation: `feature.ts` → `feature.test.ts`
87
- - Write tests for new functionality
88
- - Ensure existing tests pass before submitting
89
-
90
- Example test structure:
91
- ```typescript
92
- import { describe, it, expect } from 'vitest';
93
-
94
- describe('FeatureName', () => {
95
- it('should do something specific', () => {
96
- // Arrange
97
- // Act
98
- // Assert
99
- expect(result).toBe(expected);
100
- });
101
- });
102
- ```
103
-
104
- ### Architecture
105
-
106
- Reqon extends [Vague](https://github.com/mcclowes/vague), which provides the core DSL layer (lexer, parser, expression syntax). Reqon adds:
107
-
108
- - Mission/action/step AST nodes
109
- - HTTP fetch with pagination and retry
110
- - Store adapters for persistence
111
- - Execution context and runtime
112
-
113
- When adding features:
114
- - Extend Vague's lexer/parser if adding new expression syntax
115
- - Add new step types in `src/ast/` and handle them in `src/interpreter/executor.ts`
116
- - New store backends implement the `StoreAdapter` interface in `src/stores/`
117
-
118
- ## Submitting Changes
119
-
120
- ### Pull Requests
121
-
122
- 1. Fork the repository
123
- 2. Create a feature branch from `main`
124
- 3. Make your changes
125
- 4. Ensure tests pass: `npm run test:run`
126
- 5. Ensure the build succeeds: `npm run build`
127
- 6. Submit a pull request
128
-
129
- ### Commit Messages
130
-
131
- Write clear, concise commit messages that describe what changed and why:
132
-
133
- ```
134
- Add cursor-based pagination support
135
-
136
- - Implement cursor pagination strategy in pagination.ts
137
- - Add cursor option to fetch step parser
138
- - Add tests for cursor pagination
139
- ```
140
-
141
- ### Code Review
142
-
143
- All submissions require review. We aim to provide feedback within a few days.
144
-
145
- ## Reporting Issues
146
-
147
- When reporting bugs, please include:
148
-
149
- - Reqon version
150
- - Node.js version
151
- - Minimal reproduction case (ideally a `.vague` snippet)
152
- - Expected vs actual behavior
153
- - Error messages and stack traces
154
-
155
- ## Questions?
156
-
157
- Open an issue for questions about contributing or the codebase architecture.
158
-
159
- ## License
160
-
161
- By contributing, you agree that your contributions will be licensed under the ISC License.
package/TODO.md DELETED
@@ -1,51 +0,0 @@
1
- # TODO
2
-
3
- ## Core Features
4
-
5
- - [x] **State persistence** - Durable execution state for resumable missions with checkpointing
6
- - [x] **Incremental sync** - `since: lastSync` parameter for "only fetch changed since last run"
7
- - [ ] **Idempotency** - Upsert semantics and conflict resolution strategies
8
- - [x] **Schema overloading** - `match response { Schema1 -> ..., Schema2 -> ... }` - auto-fork based on response shape matching
9
- - [x] **Error handling via match** - Flow control directives (continue, skip, abort, retry, queue, jump) in match arms
10
- - [x] **Multi-file missions** - Split actions into separate files within a folder (mission.vague + action files)
11
- - [x] **Vague plugin system** - Extended Vague with runtime-extensible keywords and statement parsers; Reqon exports a plugin for Vague integration
12
-
13
- ## Store Adapters
14
-
15
- - [x] **File adapter** - JSON file-based storage in `.reqon-data/` for local development
16
- - [ ] **SQL adapter** - PostgreSQL/MySQL store implementation
17
- - [ ] **NoSQL adapter** - MongoDB/DynamoDB store implementation
18
-
19
- ## API Integration
20
-
21
- - [x] **OpenAPI integration** - Load sources from OAS, resolve operationIds, validate responses
22
- - [x] **Rate limiting** - Adaptive rate limiter, parses X-RateLimit-* headers, respects Retry-After, supports pause/throttle/fail strategies with callbacks
23
- - [x] **OAuth2 flow** - Token store interface, auto-refresh before expiry, 401 retry with refresh
24
- - [ ] **Connection registry** - Multi-tenant token management with proactive refresh
25
-
26
- ## DSL Enhancements
27
-
28
- - [x] **`is` type checking** - `assume .items is array` syntax
29
- - [x] **Parallel execution** - `run [Step1, Step2] then Step3` (bracket syntax for parallel stages)
30
- - [x] **Conditional actions** - `run Step1 then Step2 if condition` (already implemented in parser)
31
- - [x] **Variables/let bindings** - Reusable values within missions
32
- - [x] **Schema definitions** - Full Vague schema support with validation and matching
33
-
34
- ## Developer Experience
35
-
36
- - [x] **Better error messages** - Line numbers, column, source context with pointer in parse/lexer/runtime errors
37
- - [ ] **VS Code extension** - Syntax highlighting and LSP for `.vague` files
38
- - [ ] **Debug mode** - Step-through execution with state inspection
39
- - [ ] **Dry run improvements** - Mock responses based on schema
40
-
41
- ## Testing
42
-
43
- - [ ] **Integration tests with real APIs** - Xero sandbox, etc.
44
- - [ ] **Property-based testing** - Fuzzing the parser
45
- - [ ] **Benchmark suite** - Performance testing for large datasets
46
-
47
- ## Documentation
48
-
49
- - [ ] **More examples** - QuickBooks, Stripe, Shopify integrations
50
- - [ ] **Architecture docs** - How Reqon extends Vague
51
- - [ ] **Contributing guide**
@@ -1 +0,0 @@
1
- export {};
@@ -1,255 +0,0 @@
1
- import { describe, it, expect, beforeEach, vi } from 'vitest';
2
- import { AdaptiveRateLimiter, parseRateLimitHeaders, RateLimitError, RateLimitTimeoutError, } from './rate-limiter.js';
3
- import { InMemoryTokenStore } from './token-store.js';
4
- describe('parseRateLimitHeaders', () => {
5
- it('parses X-RateLimit headers', () => {
6
- const headers = {
7
- 'X-RateLimit-Limit': '100',
8
- 'X-RateLimit-Remaining': '42',
9
- 'X-RateLimit-Reset': '1700000000',
10
- };
11
- const info = parseRateLimitHeaders(headers);
12
- expect(info.limit).toBe(100);
13
- expect(info.remaining).toBe(42);
14
- expect(info.resetAt).toBeInstanceOf(Date);
15
- expect(info.resetAt?.getTime()).toBe(1700000000 * 1000);
16
- });
17
- it('parses lowercase ratelimit headers', () => {
18
- const headers = {
19
- 'ratelimit-limit': '60',
20
- 'ratelimit-remaining': '5',
21
- };
22
- const info = parseRateLimitHeaders(headers);
23
- expect(info.limit).toBe(60);
24
- expect(info.remaining).toBe(5);
25
- });
26
- it('parses Retry-After header (seconds)', () => {
27
- const headers = {
28
- 'Retry-After': '30',
29
- };
30
- const info = parseRateLimitHeaders(headers);
31
- expect(info.retryAfter).toBe(30);
32
- });
33
- it('handles missing headers gracefully', () => {
34
- const info = parseRateLimitHeaders({});
35
- expect(info.limit).toBeUndefined();
36
- expect(info.remaining).toBeUndefined();
37
- expect(info.resetAt).toBeUndefined();
38
- expect(info.retryAfter).toBeUndefined();
39
- });
40
- });
41
- describe('AdaptiveRateLimiter', () => {
42
- let limiter;
43
- beforeEach(() => {
44
- limiter = new AdaptiveRateLimiter();
45
- });
46
- it('allows requests when no limits recorded', async () => {
47
- const canProceed = await limiter.canProceed('TestAPI');
48
- expect(canProceed).toBe(true);
49
- });
50
- it('blocks requests when remaining is 0', async () => {
51
- const futureReset = new Date(Date.now() + 60000);
52
- limiter.recordResponse('TestAPI', {
53
- remaining: 0,
54
- limit: 100,
55
- resetAt: futureReset,
56
- });
57
- const canProceed = await limiter.canProceed('TestAPI');
58
- expect(canProceed).toBe(false);
59
- });
60
- it('allows requests after reset time passes', async () => {
61
- const pastReset = new Date(Date.now() - 1000);
62
- limiter.recordResponse('TestAPI', {
63
- remaining: 0,
64
- limit: 100,
65
- resetAt: pastReset,
66
- });
67
- const canProceed = await limiter.canProceed('TestAPI');
68
- expect(canProceed).toBe(true);
69
- });
70
- it('blocks during retry-after period', async () => {
71
- limiter.recordResponse('TestAPI', {
72
- retryAfter: 60, // 60 seconds
73
- });
74
- const canProceed = await limiter.canProceed('TestAPI');
75
- expect(canProceed).toBe(false);
76
- });
77
- it('tracks limits per source', async () => {
78
- limiter.recordResponse('API1', { remaining: 0, resetAt: new Date(Date.now() + 60000) });
79
- limiter.recordResponse('API2', { remaining: 50, limit: 100 });
80
- expect(await limiter.canProceed('API1')).toBe(false);
81
- expect(await limiter.canProceed('API2')).toBe(true);
82
- });
83
- it('tracks limits per endpoint within source', async () => {
84
- limiter.recordResponse('API', { remaining: 0, resetAt: new Date(Date.now() + 60000) }, '/invoices');
85
- limiter.recordResponse('API', { remaining: 50, limit: 100 }, '/contacts');
86
- expect(await limiter.canProceed('API', '/invoices')).toBe(false);
87
- expect(await limiter.canProceed('API', '/contacts')).toBe(true);
88
- });
89
- it('provides accurate status', () => {
90
- limiter.recordResponse('TestAPI', {
91
- remaining: 42,
92
- limit: 100,
93
- resetAt: new Date(Date.now() + 60000),
94
- });
95
- const status = limiter.getStatus('TestAPI');
96
- expect(status.remaining).toBe(42);
97
- expect(status.limit).toBe(100);
98
- expect(status.isLimited).toBe(false);
99
- });
100
- describe('fail strategy', () => {
101
- it('throws RateLimitError immediately when rate limited', async () => {
102
- limiter.configure('FailAPI', { strategy: 'fail' });
103
- limiter.recordResponse('FailAPI', {
104
- remaining: 0,
105
- resetAt: new Date(Date.now() + 60000),
106
- });
107
- await expect(limiter.waitForCapacity('FailAPI')).rejects.toThrow(RateLimitError);
108
- });
109
- it('includes reset time in error', async () => {
110
- limiter.configure('FailAPI', { strategy: 'fail' });
111
- const resetAt = new Date(Date.now() + 60000);
112
- limiter.recordResponse('FailAPI', { remaining: 0, resetAt });
113
- try {
114
- await limiter.waitForCapacity('FailAPI');
115
- expect.fail('Should have thrown');
116
- }
117
- catch (error) {
118
- expect(error).toBeInstanceOf(RateLimitError);
119
- expect(error.resetAt).toEqual(resetAt);
120
- }
121
- });
122
- });
123
- describe('pause strategy', () => {
124
- it('throws RateLimitTimeoutError when maxWait exceeded', async () => {
125
- limiter.configure('PauseAPI', { strategy: 'pause', maxWait: 1 });
126
- limiter.recordResponse('PauseAPI', {
127
- remaining: 0,
128
- resetAt: new Date(Date.now() + 60000), // 60s in future
129
- });
130
- await expect(limiter.waitForCapacity('PauseAPI')).rejects.toThrow(RateLimitTimeoutError);
131
- });
132
- it('proceeds after reset time passes', async () => {
133
- limiter.configure('PauseAPI', { strategy: 'pause', maxWait: 5 });
134
- // Reset in 50ms
135
- limiter.recordResponse('PauseAPI', {
136
- remaining: 0,
137
- resetAt: new Date(Date.now() + 50),
138
- });
139
- // Should complete without throwing
140
- await limiter.waitForCapacity('PauseAPI');
141
- });
142
- });
143
- describe('throttle strategy', () => {
144
- it('calculates delay based on remaining requests and reset time', () => {
145
- limiter.configure('ThrottleAPI', { strategy: 'throttle' });
146
- limiter.recordResponse('ThrottleAPI', {
147
- remaining: 10,
148
- limit: 100,
149
- resetAt: new Date(Date.now() + 10000), // 10s left
150
- });
151
- const delay = limiter.getThrottleDelay('ThrottleAPI');
152
- // 10s / 10 remaining = 1s per request = 1000ms
153
- expect(delay).toBeGreaterThanOrEqual(900);
154
- expect(delay).toBeLessThanOrEqual(1100);
155
- });
156
- it('returns 0 delay when not in throttle mode', () => {
157
- limiter.configure('PauseAPI', { strategy: 'pause' });
158
- limiter.recordResponse('PauseAPI', { remaining: 10, limit: 100 });
159
- const delay = limiter.getThrottleDelay('PauseAPI');
160
- expect(delay).toBe(0);
161
- });
162
- it('uses fallback RPM when no rate limit headers', () => {
163
- limiter.configure('FallbackAPI', { strategy: 'throttle', fallbackRpm: 60 });
164
- limiter.recordResponse('FallbackAPI', {}); // No rate limit info
165
- const delay = limiter.getThrottleDelay('FallbackAPI');
166
- // 60 RPM = 1 per second = 1000ms intervals
167
- expect(delay).toBeLessThanOrEqual(1000);
168
- });
169
- });
170
- describe('callbacks', () => {
171
- it('calls onRateLimited when rate limited', async () => {
172
- const onRateLimited = vi.fn();
173
- limiter.setCallbacks({ onRateLimited });
174
- // Use maxWait of 10s so it doesn't timeout immediately (wait is only 50ms)
175
- limiter.configure('CallbackAPI', { strategy: 'pause', maxWait: 10 });
176
- limiter.recordResponse('CallbackAPI', {
177
- remaining: 0,
178
- resetAt: new Date(Date.now() + 50), // Resets in 50ms
179
- });
180
- await limiter.waitForCapacity('CallbackAPI');
181
- expect(onRateLimited).toHaveBeenCalledTimes(1);
182
- expect(onRateLimited).toHaveBeenCalledWith(expect.objectContaining({
183
- source: 'CallbackAPI',
184
- strategy: 'pause',
185
- }));
186
- });
187
- it('calls onResumed after waiting completes', async () => {
188
- const onResumed = vi.fn();
189
- limiter.setCallbacks({ onResumed });
190
- limiter.configure('ResumeAPI', { strategy: 'pause', maxWait: 5 });
191
- // Reset in 50ms
192
- limiter.recordResponse('ResumeAPI', {
193
- remaining: 0,
194
- resetAt: new Date(Date.now() + 50),
195
- });
196
- await limiter.waitForCapacity('ResumeAPI');
197
- expect(onResumed).toHaveBeenCalledTimes(1);
198
- expect(onResumed).toHaveBeenCalledWith(expect.objectContaining({
199
- source: 'ResumeAPI',
200
- }));
201
- });
202
- });
203
- });
204
- describe('InMemoryTokenStore', () => {
205
- let store;
206
- beforeEach(() => {
207
- store = new InMemoryTokenStore();
208
- });
209
- it('stores and retrieves tokens', async () => {
210
- const tokens = {
211
- accessToken: 'access123',
212
- refreshToken: 'refresh456',
213
- expiresAt: new Date(Date.now() + 3600000),
214
- };
215
- await store.set('connection-1', tokens);
216
- const retrieved = await store.get('connection-1');
217
- expect(retrieved?.accessToken).toBe('access123');
218
- expect(retrieved?.refreshToken).toBe('refresh456');
219
- });
220
- it('returns null for unknown connections', async () => {
221
- const result = await store.get('unknown');
222
- expect(result).toBeNull();
223
- });
224
- it('deletes tokens', async () => {
225
- await store.set('connection-1', { accessToken: 'test' });
226
- await store.delete('connection-1');
227
- const result = await store.get('connection-1');
228
- expect(result).toBeNull();
229
- });
230
- it('lists all connections', async () => {
231
- await store.set('conn-1', { accessToken: 'a' });
232
- await store.set('conn-2', { accessToken: 'b' });
233
- await store.set('conn-3', { accessToken: 'c' });
234
- const connections = await store.list();
235
- expect(connections).toHaveLength(3);
236
- expect(connections).toContain('conn-1');
237
- expect(connections).toContain('conn-2');
238
- expect(connections).toContain('conn-3');
239
- });
240
- it('identifies tokens needing refresh', async () => {
241
- // Token expiring in 10 seconds (within 5 min buffer)
242
- await store.set('expiring-soon', {
243
- accessToken: 'test',
244
- expiresAt: new Date(Date.now() + 10000),
245
- });
246
- // Token not expiring soon
247
- await store.set('valid', {
248
- accessToken: 'test',
249
- expiresAt: new Date(Date.now() + 3600000),
250
- });
251
- const needsRefresh = await store.getTokensNeedingRefresh(300);
252
- expect(needsRefresh).toContain('expiring-soon');
253
- expect(needsRefresh).not.toContain('valid');
254
- });
255
- });
@@ -1 +0,0 @@
1
- export {};