reqon-dsl 0.2.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.
- package/.claude/settings.local.json +31 -0
- package/.claude/skills/api-integration.md +125 -0
- package/.claude/skills/database-schema.md +51 -0
- package/.claude/skills/dsl-design.md +80 -0
- package/.claude/skills/property-testing.md +143 -0
- package/.claude/skills/reqon/SKILL.md +44 -0
- package/.claude/skills/reqon/references/examples.md +206 -0
- package/.claude/skills/reqon/references/syntax.md +263 -0
- package/.claude/skills/vscode-extension.md +113 -0
- package/.github/dependabot.yml +32 -0
- package/.github/pull_request_template.md +21 -0
- package/.github/workflows/ci.yml +174 -0
- package/.github/workflows/release.yml +73 -0
- package/CLAUDE.md +72 -0
- package/CONTRIBUTING.md +161 -0
- package/README.md +235 -0
- package/TODO.md +51 -0
- package/dist/ast/index.d.ts +1 -0
- package/dist/ast/index.js +1 -0
- package/dist/ast/nodes.d.ts +237 -0
- package/dist/ast/nodes.js +12 -0
- package/dist/auth/auth.test.d.ts +1 -0
- package/dist/auth/auth.test.js +255 -0
- package/dist/auth/circuit-breaker.d.ts +115 -0
- package/dist/auth/circuit-breaker.js +267 -0
- package/dist/auth/credentials.d.ts +91 -0
- package/dist/auth/credentials.js +169 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.js +8 -0
- package/dist/auth/oauth2-provider.d.ts +41 -0
- package/dist/auth/oauth2-provider.js +131 -0
- package/dist/auth/rate-limiter.d.ts +61 -0
- package/dist/auth/rate-limiter.js +380 -0
- package/dist/auth/token-store.d.ts +30 -0
- package/dist/auth/token-store.js +148 -0
- package/dist/auth/types.d.ts +142 -0
- package/dist/auth/types.js +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +270 -0
- package/dist/errors/errors.test.d.ts +1 -0
- package/dist/errors/errors.test.js +165 -0
- package/dist/errors/index.d.ts +83 -0
- package/dist/errors/index.js +159 -0
- package/dist/execution/execution.test.d.ts +1 -0
- package/dist/execution/execution.test.js +246 -0
- package/dist/execution/index.d.ts +4 -0
- package/dist/execution/index.js +2 -0
- package/dist/execution/state.d.ts +136 -0
- package/dist/execution/state.js +82 -0
- package/dist/execution/store.d.ts +52 -0
- package/dist/execution/store.js +120 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +57 -0
- package/dist/integration.test.d.ts +1 -0
- package/dist/integration.test.js +168 -0
- package/dist/interpreter/context.d.ts +15 -0
- package/dist/interpreter/context.js +29 -0
- package/dist/interpreter/evaluator.d.ts +5 -0
- package/dist/interpreter/evaluator.js +223 -0
- package/dist/interpreter/evaluator.test.d.ts +1 -0
- package/dist/interpreter/evaluator.test.js +512 -0
- package/dist/interpreter/executor.d.ts +131 -0
- package/dist/interpreter/executor.js +663 -0
- package/dist/interpreter/fetch-handler.d.ts +43 -0
- package/dist/interpreter/fetch-handler.js +203 -0
- package/dist/interpreter/http.d.ts +57 -0
- package/dist/interpreter/http.js +210 -0
- package/dist/interpreter/http.test.d.ts +1 -0
- package/dist/interpreter/http.test.js +299 -0
- package/dist/interpreter/index.d.ts +7 -0
- package/dist/interpreter/index.js +7 -0
- package/dist/interpreter/pagination.d.ts +63 -0
- package/dist/interpreter/pagination.js +155 -0
- package/dist/interpreter/progress.test.d.ts +1 -0
- package/dist/interpreter/progress.test.js +216 -0
- package/dist/interpreter/schema-matcher.d.ts +16 -0
- package/dist/interpreter/schema-matcher.js +136 -0
- package/dist/interpreter/schema-matcher.test.d.ts +1 -0
- package/dist/interpreter/schema-matcher.test.js +122 -0
- package/dist/interpreter/signals.d.ts +57 -0
- package/dist/interpreter/signals.js +73 -0
- package/dist/interpreter/step-handlers/for-handler.d.ts +17 -0
- package/dist/interpreter/step-handlers/for-handler.js +51 -0
- package/dist/interpreter/step-handlers/index.d.ts +8 -0
- package/dist/interpreter/step-handlers/index.js +8 -0
- package/dist/interpreter/step-handlers/map-handler.d.ts +10 -0
- package/dist/interpreter/step-handlers/map-handler.js +20 -0
- package/dist/interpreter/step-handlers/match-handler.d.ts +27 -0
- package/dist/interpreter/step-handlers/match-handler.js +61 -0
- package/dist/interpreter/step-handlers/store-handler.d.ts +13 -0
- package/dist/interpreter/step-handlers/store-handler.js +66 -0
- package/dist/interpreter/step-handlers/types.d.ts +15 -0
- package/dist/interpreter/step-handlers/types.js +1 -0
- package/dist/interpreter/step-handlers/validate-handler.d.ts +10 -0
- package/dist/interpreter/step-handlers/validate-handler.js +26 -0
- package/dist/interpreter/step-handlers/webhook-handler.d.ts +36 -0
- package/dist/interpreter/step-handlers/webhook-handler.js +104 -0
- package/dist/lexer/index.d.ts +10 -0
- package/dist/lexer/index.js +12 -0
- package/dist/lexer/lexer.d.ts +24 -0
- package/dist/lexer/lexer.js +264 -0
- package/dist/lexer/lexer.test.d.ts +1 -0
- package/dist/lexer/lexer.test.js +259 -0
- package/dist/lexer/tokens.d.ts +69 -0
- package/dist/lexer/tokens.js +146 -0
- package/dist/loader/index.d.ts +36 -0
- package/dist/loader/index.js +220 -0
- package/dist/loader/loader.test.d.ts +1 -0
- package/dist/loader/loader.test.js +287 -0
- package/dist/oas/index.d.ts +4 -0
- package/dist/oas/index.js +2 -0
- package/dist/oas/loader.d.ts +21 -0
- package/dist/oas/loader.js +82 -0
- package/dist/oas/oas.test.d.ts +1 -0
- package/dist/oas/oas.test.js +218 -0
- package/dist/oas/validator.d.ts +12 -0
- package/dist/oas/validator.js +227 -0
- package/dist/parser/base.d.ts +33 -0
- package/dist/parser/base.js +97 -0
- package/dist/parser/expressions.d.ts +27 -0
- package/dist/parser/expressions.js +248 -0
- package/dist/parser/expressions.test.d.ts +1 -0
- package/dist/parser/expressions.test.js +378 -0
- package/dist/parser/index.d.ts +3 -0
- package/dist/parser/index.js +3 -0
- package/dist/parser/match.test.d.ts +1 -0
- package/dist/parser/match.test.js +254 -0
- package/dist/parser/parser.d.ts +68 -0
- package/dist/parser/parser.js +1229 -0
- package/dist/parser/parser.test.d.ts +1 -0
- package/dist/parser/parser.test.js +333 -0
- package/dist/parser/schedule.test.d.ts +1 -0
- package/dist/parser/schedule.test.js +241 -0
- package/dist/plugin.d.ts +35 -0
- package/dist/plugin.js +68 -0
- package/dist/scheduler/cron-parser.d.ts +32 -0
- package/dist/scheduler/cron-parser.js +198 -0
- package/dist/scheduler/cron-parser.test.d.ts +1 -0
- package/dist/scheduler/cron-parser.test.js +188 -0
- package/dist/scheduler/index.d.ts +3 -0
- package/dist/scheduler/index.js +2 -0
- package/dist/scheduler/scheduler.d.ts +81 -0
- package/dist/scheduler/scheduler.js +376 -0
- package/dist/scheduler/types.d.ts +65 -0
- package/dist/scheduler/types.js +1 -0
- package/dist/stores/factory.d.ts +36 -0
- package/dist/stores/factory.js +73 -0
- package/dist/stores/file.d.ts +60 -0
- package/dist/stores/file.js +173 -0
- package/dist/stores/file.test.d.ts +1 -0
- package/dist/stores/file.test.js +165 -0
- package/dist/stores/index.d.ts +6 -0
- package/dist/stores/index.js +5 -0
- package/dist/stores/memory.d.ts +19 -0
- package/dist/stores/memory.js +51 -0
- package/dist/stores/memory.test.d.ts +1 -0
- package/dist/stores/memory.test.js +157 -0
- package/dist/stores/postgrest.d.ts +55 -0
- package/dist/stores/postgrest.js +217 -0
- package/dist/stores/stores.test.d.ts +1 -0
- package/dist/stores/stores.test.js +158 -0
- package/dist/stores/types.d.ts +31 -0
- package/dist/stores/types.js +26 -0
- package/dist/sync/index.d.ts +4 -0
- package/dist/sync/index.js +2 -0
- package/dist/sync/state.d.ts +69 -0
- package/dist/sync/state.js +66 -0
- package/dist/sync/store.d.ts +49 -0
- package/dist/sync/store.js +93 -0
- package/dist/sync/sync.test.d.ts +1 -0
- package/dist/sync/sync.test.js +221 -0
- package/dist/utils/async.d.ts +7 -0
- package/dist/utils/async.js +9 -0
- package/dist/utils/file.d.ts +38 -0
- package/dist/utils/file.js +92 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/logger.d.ts +34 -0
- package/dist/utils/logger.js +39 -0
- package/dist/utils/path.d.ts +12 -0
- package/dist/utils/path.js +41 -0
- package/dist/webhook/index.d.ts +8 -0
- package/dist/webhook/index.js +7 -0
- package/dist/webhook/server.d.ts +84 -0
- package/dist/webhook/server.js +319 -0
- package/dist/webhook/store.d.ts +67 -0
- package/dist/webhook/store.js +193 -0
- package/dist/webhook/types.d.ts +88 -0
- package/dist/webhook/types.js +6 -0
- package/docusaurus/README.md +41 -0
- package/docusaurus/docs/advanced/execution-state.md +283 -0
- package/docusaurus/docs/advanced/extending-reqon.md +388 -0
- package/docusaurus/docs/advanced/multi-file-missions.md +250 -0
- package/docusaurus/docs/advanced/parallel-execution.md +353 -0
- package/docusaurus/docs/api-reference.md +443 -0
- package/docusaurus/docs/authentication/api-key.md +339 -0
- package/docusaurus/docs/authentication/basic.md +276 -0
- package/docusaurus/docs/authentication/bearer.md +282 -0
- package/docusaurus/docs/authentication/oauth2.md +317 -0
- package/docusaurus/docs/authentication/overview.md +251 -0
- package/docusaurus/docs/cli.md +229 -0
- package/docusaurus/docs/core-concepts/actions.md +286 -0
- package/docusaurus/docs/core-concepts/missions.md +264 -0
- package/docusaurus/docs/core-concepts/schemas.md +353 -0
- package/docusaurus/docs/core-concepts/sources.md +339 -0
- package/docusaurus/docs/core-concepts/stores.md +332 -0
- package/docusaurus/docs/dsl-syntax/expressions.md +361 -0
- package/docusaurus/docs/dsl-syntax/fetch.md +293 -0
- package/docusaurus/docs/dsl-syntax/for-loops.md +324 -0
- package/docusaurus/docs/dsl-syntax/map.md +345 -0
- package/docusaurus/docs/dsl-syntax/match.md +387 -0
- package/docusaurus/docs/dsl-syntax/pipelines.md +397 -0
- package/docusaurus/docs/dsl-syntax/validate.md +401 -0
- package/docusaurus/docs/error-handling/dead-letter-queues.md +399 -0
- package/docusaurus/docs/error-handling/flow-control.md +337 -0
- package/docusaurus/docs/error-handling/retry-strategies.md +368 -0
- package/docusaurus/docs/examples.md +488 -0
- package/docusaurus/docs/getting-started.md +256 -0
- package/docusaurus/docs/http/circuit-breaker.md +401 -0
- package/docusaurus/docs/http/incremental-sync.md +394 -0
- package/docusaurus/docs/http/pagination.md +361 -0
- package/docusaurus/docs/http/rate-limiting.md +383 -0
- package/docusaurus/docs/http/requests.md +328 -0
- package/docusaurus/docs/http/retry.md +402 -0
- package/docusaurus/docs/intro.md +90 -0
- package/docusaurus/docs/openapi/loading-specs.md +305 -0
- package/docusaurus/docs/openapi/operation-calls.md +314 -0
- package/docusaurus/docs/openapi/overview.md +212 -0
- package/docusaurus/docs/openapi/response-validation.md +344 -0
- package/docusaurus/docs/scheduling/cron.md +305 -0
- package/docusaurus/docs/scheduling/daemon-mode.md +317 -0
- package/docusaurus/docs/scheduling/intervals.md +289 -0
- package/docusaurus/docs/scheduling/overview.md +231 -0
- package/docusaurus/docs/stores/custom-adapters.md +376 -0
- package/docusaurus/docs/stores/file.md +236 -0
- package/docusaurus/docs/stores/memory.md +193 -0
- package/docusaurus/docs/stores/overview.md +274 -0
- package/docusaurus/docs/stores/postgrest.md +316 -0
- package/docusaurus/docusaurus.config.ts +148 -0
- package/docusaurus/package-lock.json +18029 -0
- package/docusaurus/package.json +47 -0
- package/docusaurus/sidebars.ts +155 -0
- package/docusaurus/src/components/HomepageFeatures/index.tsx +105 -0
- package/docusaurus/src/components/HomepageFeatures/styles.module.css +12 -0
- package/docusaurus/src/css/custom.css +169 -0
- package/docusaurus/src/pages/index.module.css +48 -0
- package/docusaurus/src/pages/index.tsx +110 -0
- package/docusaurus/src/pages/markdown-page.md +7 -0
- package/docusaurus/static/.nojekyll +0 -0
- package/docusaurus/static/img/docusaurus-social-card.jpg +0 -0
- package/docusaurus/static/img/docusaurus.png +0 -0
- package/docusaurus/static/img/favicon.ico +0 -0
- package/docusaurus/static/img/logo.svg +10 -0
- package/docusaurus/static/img/undraw_docusaurus_mountain.svg +171 -0
- package/docusaurus/static/img/undraw_docusaurus_react.svg +170 -0
- package/docusaurus/static/img/undraw_docusaurus_tree.svg +40 -0
- package/docusaurus/tsconfig.json +8 -0
- package/examples/README.md +112 -0
- package/examples/error-handling/README.md +150 -0
- package/examples/error-handling/payment-processor.vague +287 -0
- package/examples/github-sync/README.md +74 -0
- package/examples/github-sync/fetch-issues.vague +47 -0
- package/examples/github-sync/fetch-prs.vague +40 -0
- package/examples/github-sync/mission.vague +101 -0
- package/examples/github-sync/normalize.vague +70 -0
- package/examples/jsonplaceholder/README.md +28 -0
- package/examples/jsonplaceholder/posts.vague +48 -0
- package/examples/petstore/README.md +35 -0
- package/examples/petstore/openapi.yaml +97 -0
- package/examples/petstore/sync.vague +52 -0
- package/examples/temporal-comparison/README.md +297 -0
- package/examples/temporal-comparison/reconciliation.vague +355 -0
- package/examples/temporal-comparison/temporal/activities/index.ts +8 -0
- package/examples/temporal-comparison/temporal/activities/shipstation.ts +225 -0
- package/examples/temporal-comparison/temporal/activities/shopify.ts +257 -0
- package/examples/temporal-comparison/temporal/activities/storage.ts +198 -0
- package/examples/temporal-comparison/temporal/activities/stripe.ts +169 -0
- package/examples/temporal-comparison/temporal/activities/validation.ts +205 -0
- package/examples/temporal-comparison/temporal/client/schedule.ts +218 -0
- package/examples/temporal-comparison/temporal/config/retry.ts +63 -0
- package/examples/temporal-comparison/temporal/types/index.ts +129 -0
- package/examples/temporal-comparison/temporal/workers/main.ts +130 -0
- package/examples/temporal-comparison/temporal/workflows/orderReconciliation.ts +262 -0
- package/examples/xero/README.md +88 -0
- package/examples/xero/invoices.vague +189 -0
- package/package.json +40 -0
- package/src/api-integration.test.ts +954 -0
- package/src/ast/index.ts +1 -0
- package/src/ast/nodes.ts +310 -0
- package/src/auth/auth.test.ts +326 -0
- package/src/auth/circuit-breaker.test.ts +390 -0
- package/src/auth/circuit-breaker.ts +379 -0
- package/src/auth/credentials.test.ts +273 -0
- package/src/auth/credentials.ts +246 -0
- package/src/auth/index.ts +40 -0
- package/src/auth/oauth2-provider.ts +177 -0
- package/src/auth/rate-limiter.ts +459 -0
- package/src/auth/token-store.ts +177 -0
- package/src/auth/types.ts +159 -0
- package/src/benchmark/e2e.bench.ts +288 -0
- package/src/benchmark/evaluator.bench.ts +331 -0
- package/src/benchmark/fixtures.ts +295 -0
- package/src/benchmark/index.ts +108 -0
- package/src/benchmark/lexer.bench.ts +69 -0
- package/src/benchmark/parser.bench.ts +103 -0
- package/src/benchmark/resilience.bench.ts +193 -0
- package/src/benchmark/store.bench.ts +147 -0
- package/src/benchmark/utils.ts +230 -0
- package/src/cli.ts +313 -0
- package/src/errors/errors.test.ts +234 -0
- package/src/errors/index.ts +223 -0
- package/src/execution/execution.test.ts +307 -0
- package/src/execution/index.ts +21 -0
- package/src/execution/state.ts +207 -0
- package/src/execution/store.ts +188 -0
- package/src/index.ts +169 -0
- package/src/integration.test.ts +192 -0
- package/src/interpreter/context.ts +57 -0
- package/src/interpreter/evaluator.test.ts +796 -0
- package/src/interpreter/evaluator.ts +245 -0
- package/src/interpreter/executor.ts +946 -0
- package/src/interpreter/fetch-handler.ts +302 -0
- package/src/interpreter/http.test.ts +423 -0
- package/src/interpreter/http.ts +308 -0
- package/src/interpreter/index.ts +32 -0
- package/src/interpreter/pagination.ts +207 -0
- package/src/interpreter/progress.test.ts +276 -0
- package/src/interpreter/schema-matcher.test.ts +160 -0
- package/src/interpreter/schema-matcher.ts +168 -0
- package/src/interpreter/signals.ts +73 -0
- package/src/interpreter/step-handlers/for-handler.ts +65 -0
- package/src/interpreter/step-handlers/index.ts +17 -0
- package/src/interpreter/step-handlers/map-handler.ts +24 -0
- package/src/interpreter/step-handlers/match-handler.ts +101 -0
- package/src/interpreter/step-handlers/store-handler.ts +78 -0
- package/src/interpreter/step-handlers/types.ts +17 -0
- package/src/interpreter/step-handlers/validate-handler.ts +30 -0
- package/src/interpreter/step-handlers/webhook-handler.ts +142 -0
- package/src/lexer/index.ts +18 -0
- package/src/lexer/lexer.test.ts +316 -0
- package/src/lexer/tokens.ts +179 -0
- package/src/loader/index.ts +288 -0
- package/src/loader/loader.test.ts +360 -0
- package/src/oas/index.ts +4 -0
- package/src/oas/loader.ts +126 -0
- package/src/oas/oas.test.ts +254 -0
- package/src/oas/validator.ts +299 -0
- package/src/parser/base.ts +124 -0
- package/src/parser/expressions.test.ts +525 -0
- package/src/parser/expressions.ts +314 -0
- package/src/parser/index.ts +3 -0
- package/src/parser/match.test.ts +296 -0
- package/src/parser/parser.test.ts +739 -0
- package/src/parser/parser.ts +1469 -0
- package/src/parser/schedule.test.ts +287 -0
- package/src/parser/webhook.test.ts +248 -0
- package/src/plugin.ts +83 -0
- package/src/scheduler/cron-parser.test.ts +236 -0
- package/src/scheduler/cron-parser.ts +236 -0
- package/src/scheduler/index.ts +10 -0
- package/src/scheduler/scheduler.ts +443 -0
- package/src/scheduler/types.ts +71 -0
- package/src/stores/factory.ts +104 -0
- package/src/stores/file.test.ts +276 -0
- package/src/stores/file.ts +211 -0
- package/src/stores/index.ts +6 -0
- package/src/stores/memory.test.ts +238 -0
- package/src/stores/memory.ts +63 -0
- package/src/stores/postgrest.test.ts +488 -0
- package/src/stores/postgrest.ts +263 -0
- package/src/stores/stores.test.ts +197 -0
- package/src/stores/types.ts +58 -0
- package/src/sync/index.ts +16 -0
- package/src/sync/state.ts +126 -0
- package/src/sync/store.ts +139 -0
- package/src/sync/sync.test.ts +271 -0
- package/src/utils/async.ts +10 -0
- package/src/utils/file.ts +106 -0
- package/src/utils/index.ts +14 -0
- package/src/utils/logger.ts +53 -0
- package/src/utils/path.ts +47 -0
- package/src/webhook/index.ts +15 -0
- package/src/webhook/server.test.ts +253 -0
- package/src/webhook/server.ts +389 -0
- package/src/webhook/store.ts +239 -0
- package/src/webhook/types.ts +93 -0
- package/tsconfig.json +17 -0
- package/vitest.config.ts +39 -0
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
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/README.md
ADDED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Reqon
|
|
2
|
+
|
|
3
|
+
A declarative DSL for fetch, map, validate pipelines - built on [Vague](https://github.com/mcclowes/vague).
|
|
4
|
+
|
|
5
|
+
## What is Reqon?
|
|
6
|
+
|
|
7
|
+
Reqon lets you define data synchronization pipelines in a readable, declarative language. Think of it like Temporal.io, but with a focus on API data fetching and transformation.
|
|
8
|
+
|
|
9
|
+
## Example
|
|
10
|
+
|
|
11
|
+
```vague
|
|
12
|
+
mission SyncXeroInvoices {
|
|
13
|
+
source Xero {
|
|
14
|
+
auth: oauth2,
|
|
15
|
+
base: "https://api.xero.com/api.xro/2.0"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
store invoices: memory("invoices")
|
|
19
|
+
store normalized: memory("normalized")
|
|
20
|
+
|
|
21
|
+
action FetchInvoices {
|
|
22
|
+
get "/Invoices" {
|
|
23
|
+
paginate: offset(page, 100),
|
|
24
|
+
until: length(response.Invoices) == 0
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
store response.Invoices -> invoices {
|
|
28
|
+
key: .InvoiceID,
|
|
29
|
+
partial: true
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
action NormalizeInvoices {
|
|
34
|
+
for invoice in invoices {
|
|
35
|
+
map invoice -> StandardInvoice {
|
|
36
|
+
id: .InvoiceID,
|
|
37
|
+
amount: .Total,
|
|
38
|
+
status: match .Status {
|
|
39
|
+
"PAID" => "paid",
|
|
40
|
+
"AUTHORISED" => "approved",
|
|
41
|
+
_ => "pending"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
validate response {
|
|
46
|
+
assume .amount >= 0
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
store response -> normalized { key: .id }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
run FetchInvoices then NormalizeInvoices
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm install reqon
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Usage
|
|
64
|
+
|
|
65
|
+
### CLI
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
reqon sync-invoices.vague --verbose
|
|
69
|
+
reqon sync-invoices.vague --auth ./credentials.json
|
|
70
|
+
reqon sync-invoices.vague --dry-run
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Programmatic
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { parse, execute } from 'reqon';
|
|
77
|
+
|
|
78
|
+
const program = parse(`
|
|
79
|
+
mission Test {
|
|
80
|
+
source API { auth: bearer, base: "https://api.example.com" }
|
|
81
|
+
store items: memory("items")
|
|
82
|
+
action Fetch {
|
|
83
|
+
get "/items"
|
|
84
|
+
store response -> items { key: .id }
|
|
85
|
+
}
|
|
86
|
+
run Fetch
|
|
87
|
+
}
|
|
88
|
+
`);
|
|
89
|
+
|
|
90
|
+
const result = await execute(source, {
|
|
91
|
+
auth: { API: { type: 'bearer', token: 'your-token' } }
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
console.log(result.stores.get('items').list());
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## DSL Reference
|
|
98
|
+
|
|
99
|
+
### Sources
|
|
100
|
+
|
|
101
|
+
Sources can be defined with explicit base URLs or by referencing an OpenAPI spec:
|
|
102
|
+
|
|
103
|
+
```vague
|
|
104
|
+
// Traditional: explicit base URL
|
|
105
|
+
source Name {
|
|
106
|
+
auth: oauth2 | bearer | basic | api_key,
|
|
107
|
+
base: "https://api.example.com"
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// OAS-based: load from OpenAPI spec (base URL derived from spec)
|
|
111
|
+
source Petstore from "./petstore-openapi.yaml" {
|
|
112
|
+
auth: bearer,
|
|
113
|
+
validateResponses: true // Optional: validate responses against OAS schema
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Stores
|
|
118
|
+
|
|
119
|
+
```vague
|
|
120
|
+
store name: memory("collection")
|
|
121
|
+
store name: sql("table_name")
|
|
122
|
+
store name: nosql("collection")
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Actions
|
|
126
|
+
|
|
127
|
+
```vague
|
|
128
|
+
action Name {
|
|
129
|
+
// Steps: get/post/put/patch/delete, call, for, map, validate, store
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### HTTP Requests
|
|
134
|
+
|
|
135
|
+
Two styles are supported:
|
|
136
|
+
|
|
137
|
+
```vague
|
|
138
|
+
// Traditional: explicit HTTP method and path
|
|
139
|
+
get "/path" {
|
|
140
|
+
paginate: offset(page, 100),
|
|
141
|
+
until: response.items.length == 0,
|
|
142
|
+
retry: { maxAttempts: 3, backoff: exponential }
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// OAS-based: reference by Source.operationId
|
|
146
|
+
call Petstore.listPets {
|
|
147
|
+
paginate: cursor(cursor, 20, "nextCursor"),
|
|
148
|
+
until: response.pets.length == 0
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
When using OAS-based `call`, the HTTP method and path are resolved from the OpenAPI spec automatically.
|
|
153
|
+
|
|
154
|
+
### Iteration
|
|
155
|
+
|
|
156
|
+
```vague
|
|
157
|
+
for item in collection where .status == "pending" {
|
|
158
|
+
// nested steps
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Mapping
|
|
163
|
+
|
|
164
|
+
```vague
|
|
165
|
+
map source -> TargetSchema {
|
|
166
|
+
field: .sourceField,
|
|
167
|
+
computed: .price * .quantity,
|
|
168
|
+
status: match .state {
|
|
169
|
+
"A" => "active",
|
|
170
|
+
_ => "unknown"
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Validation
|
|
176
|
+
|
|
177
|
+
```vague
|
|
178
|
+
validate target {
|
|
179
|
+
assume .amount > 0,
|
|
180
|
+
assume .date >= .createdAt
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Pipeline
|
|
185
|
+
|
|
186
|
+
```vague
|
|
187
|
+
// Sequential execution
|
|
188
|
+
run Step1 then Step2 then Step3
|
|
189
|
+
|
|
190
|
+
// Parallel execution with brackets
|
|
191
|
+
run [Step1, Step2] then Step3 // Step1 and Step2 run in parallel, then Step3
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## OpenAPI Integration
|
|
195
|
+
|
|
196
|
+
Reqon can consume OpenAPI specs directly, eliminating the need for handwritten SDK code:
|
|
197
|
+
|
|
198
|
+
```vague
|
|
199
|
+
mission SyncPets {
|
|
200
|
+
// Load API definition from OpenAPI spec
|
|
201
|
+
source Petstore from "./petstore.yaml" {
|
|
202
|
+
auth: bearer,
|
|
203
|
+
validateResponses: true
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
store pets: memory("pets")
|
|
207
|
+
|
|
208
|
+
action FetchPets {
|
|
209
|
+
// Use operationId from spec - method and path are resolved automatically
|
|
210
|
+
call Petstore.listPets
|
|
211
|
+
|
|
212
|
+
store response.pets -> pets { key: .id }
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
run FetchPets
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Benefits:
|
|
220
|
+
- **No SDK required** - The OpenAPI spec *is* the SDK
|
|
221
|
+
- **Always up-to-date** - Spec changes are picked up automatically
|
|
222
|
+
- **Response validation** - Validate API responses against the spec's schemas
|
|
223
|
+
- **Auto-discovery** - Base URLs, paths, and methods come from the spec
|
|
224
|
+
|
|
225
|
+
## Development
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
npm run build # Compile TypeScript
|
|
229
|
+
npm run test:run # Run tests
|
|
230
|
+
npm run dev # Watch mode
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## License
|
|
234
|
+
|
|
235
|
+
ISC
|
package/TODO.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
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**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './nodes.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './nodes.js';
|