reqon-dsl 0.2.0 → 0.4.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/CHANGELOG.md +7 -0
- package/README.md +45 -3
- package/dist/ast/nodes.d.ts +91 -4
- package/dist/ast/nodes.js +14 -0
- package/dist/auth/circuit-breaker.d.ts +11 -0
- package/dist/auth/circuit-breaker.js +90 -18
- package/dist/auth/credentials.d.ts +6 -1
- package/dist/auth/credentials.js +12 -4
- package/dist/auth/oauth2-provider.js +13 -3
- package/dist/auth/rate-limiter.d.ts +12 -1
- package/dist/auth/rate-limiter.js +39 -26
- package/dist/auth/token-store.js +8 -1
- package/dist/cli.d.ts +24 -1
- package/dist/cli.js +149 -10
- package/dist/config/constants.d.ts +152 -0
- package/dist/config/constants.js +139 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.js +4 -0
- package/dist/control/index.d.ts +2 -0
- package/dist/control/index.js +1 -0
- package/dist/control/server.d.ts +105 -0
- package/dist/control/server.js +315 -0
- package/dist/control/types.d.ts +61 -0
- package/dist/control/types.js +7 -0
- package/dist/debug/cli-debugger.d.ts +17 -0
- package/dist/debug/cli-debugger.js +185 -0
- package/dist/debug/controller.d.ts +94 -0
- package/dist/debug/controller.js +45 -0
- package/dist/debug/index.d.ts +6 -0
- package/dist/debug/index.js +5 -0
- package/dist/errors/index.d.ts +67 -0
- package/dist/errors/index.js +89 -1
- package/dist/execution/index.d.ts +1 -1
- package/dist/execution/state.d.ts +24 -0
- package/dist/execution/store.js +2 -2
- package/dist/execution-log/events.d.ts +125 -0
- package/dist/execution-log/events.js +17 -0
- package/dist/execution-log/fold.d.ts +38 -0
- package/dist/execution-log/fold.js +54 -0
- package/dist/execution-log/index.d.ts +18 -0
- package/dist/execution-log/index.js +6 -0
- package/dist/execution-log/postgres-store.d.ts +36 -0
- package/dist/execution-log/postgres-store.js +108 -0
- package/dist/execution-log/resume.d.ts +11 -0
- package/dist/execution-log/resume.js +5 -0
- package/dist/execution-log/sqlite-store.d.ts +16 -0
- package/dist/execution-log/sqlite-store.js +101 -0
- package/dist/execution-log/store.d.ts +72 -0
- package/dist/execution-log/store.js +182 -0
- package/dist/index.d.ts +23 -2
- package/dist/index.js +35 -3
- package/dist/interpreter/context.d.ts +29 -0
- package/dist/interpreter/context.js +18 -0
- package/dist/interpreter/evaluator.d.ts +63 -1
- package/dist/interpreter/evaluator.js +219 -42
- package/dist/interpreter/executor.d.ts +132 -14
- package/dist/interpreter/executor.js +883 -178
- package/dist/interpreter/fetch-handler.d.ts +48 -1
- package/dist/interpreter/fetch-handler.js +216 -38
- package/dist/interpreter/http.d.ts +34 -0
- package/dist/interpreter/http.js +203 -28
- package/dist/interpreter/index.d.ts +5 -3
- package/dist/interpreter/index.js +4 -2
- package/dist/interpreter/pagination.d.ts +12 -3
- package/dist/interpreter/pagination.js +102 -32
- package/dist/interpreter/signals.d.ts +8 -0
- package/dist/interpreter/signals.js +12 -0
- package/dist/interpreter/source-manager.d.ts +75 -0
- package/dist/interpreter/source-manager.js +157 -0
- package/dist/interpreter/step-handlers/apply-handler.d.ts +29 -0
- package/dist/interpreter/step-handlers/apply-handler.js +79 -0
- package/dist/interpreter/step-handlers/for-handler.d.ts +16 -0
- package/dist/interpreter/step-handlers/for-handler.js +89 -7
- package/dist/interpreter/step-handlers/index.d.ts +4 -2
- package/dist/interpreter/step-handlers/index.js +4 -2
- package/dist/interpreter/step-handlers/match-handler.d.ts +9 -0
- package/dist/interpreter/step-handlers/match-handler.js +47 -17
- package/dist/interpreter/step-handlers/pause-handler.d.ts +52 -0
- package/dist/interpreter/step-handlers/pause-handler.js +87 -0
- package/dist/interpreter/step-handlers/store-handler.d.ts +17 -1
- package/dist/interpreter/step-handlers/store-handler.js +61 -20
- package/dist/interpreter/step-handlers/types.d.ts +3 -0
- package/dist/interpreter/step-handlers/validate-handler.d.ts +2 -1
- package/dist/interpreter/step-handlers/validate-handler.js +7 -2
- package/dist/interpreter/step-handlers/webhook-handler.d.ts +4 -0
- package/dist/interpreter/step-handlers/webhook-handler.js +31 -5
- package/dist/interpreter/store-manager.d.ts +46 -0
- package/dist/interpreter/store-manager.js +70 -0
- package/dist/lexer/index.d.ts +11 -4
- package/dist/lexer/index.js +11 -4
- package/dist/lexer/tokens.d.ts +17 -1
- package/dist/lexer/tokens.js +36 -0
- package/dist/loader/index.js +5 -8
- package/dist/mcp/index.d.ts +11 -0
- package/dist/mcp/index.js +11 -0
- package/dist/mcp/sandbox.d.ts +41 -0
- package/dist/mcp/sandbox.js +76 -0
- package/dist/mcp/server.d.ts +17 -0
- package/dist/mcp/server.js +504 -0
- package/dist/oas/index.d.ts +2 -0
- package/dist/oas/index.js +1 -0
- package/dist/oas/loader.d.ts +13 -1
- package/dist/oas/loader.js +25 -3
- package/dist/oas/mock-generator.d.ts +12 -0
- package/dist/oas/mock-generator.js +196 -0
- package/dist/oas/validator.js +45 -5
- package/dist/observability/events.d.ts +248 -0
- package/dist/observability/events.js +85 -0
- package/dist/observability/index.d.ts +15 -0
- package/dist/observability/index.js +12 -0
- package/dist/observability/logger.d.ts +106 -0
- package/dist/observability/logger.js +266 -0
- package/dist/observability/otel.d.ts +143 -0
- package/dist/observability/otel.js +421 -0
- package/dist/parser/action-parser.d.ts +105 -0
- package/dist/parser/action-parser.js +645 -0
- package/dist/parser/base.d.ts +7 -0
- package/dist/parser/base.js +11 -0
- package/dist/parser/expressions.d.ts +14 -0
- package/dist/parser/expressions.js +89 -6
- package/dist/parser/fetch-parser.d.ts +27 -0
- package/dist/parser/fetch-parser.js +280 -0
- package/dist/parser/index.d.ts +17 -0
- package/dist/parser/index.js +17 -0
- package/dist/parser/parser.d.ts +44 -46
- package/dist/parser/parser.js +122 -1070
- package/dist/parser/pipeline-parser.d.ts +12 -0
- package/dist/parser/pipeline-parser.js +52 -0
- package/dist/parser/schedule-parser.d.ts +7 -0
- package/dist/parser/schedule-parser.js +137 -0
- package/dist/parser/source-parser.d.ts +9 -0
- package/dist/parser/source-parser.js +151 -0
- package/dist/pause/index.d.ts +15 -0
- package/dist/pause/index.js +12 -0
- package/dist/pause/log-store.d.ts +33 -0
- package/dist/pause/log-store.js +98 -0
- package/dist/pause/manager.d.ts +130 -0
- package/dist/pause/manager.js +294 -0
- package/dist/pause/state.d.ts +93 -0
- package/dist/pause/state.js +103 -0
- package/dist/pause/store.d.ts +61 -0
- package/dist/pause/store.js +158 -0
- package/dist/plugin.d.ts +9 -12
- package/dist/plugin.js +10 -13
- package/dist/scheduler/cron-parser.d.ts +10 -3
- package/dist/scheduler/cron-parser.js +227 -48
- package/dist/scheduler/scheduler.js +56 -22
- package/dist/stores/factory.d.ts +7 -1
- package/dist/stores/factory.js +14 -3
- package/dist/stores/file.d.ts +26 -0
- package/dist/stores/file.js +67 -21
- package/dist/stores/index.d.ts +16 -1
- package/dist/stores/index.js +16 -1
- package/dist/stores/memory.d.ts +4 -0
- package/dist/stores/memory.js +8 -6
- package/dist/stores/postgrest.d.ts +28 -0
- package/dist/stores/postgrest.js +84 -37
- package/dist/stores/types.d.ts +17 -0
- package/dist/stores/types.js +12 -0
- package/dist/sync/index.d.ts +3 -2
- package/dist/sync/index.js +2 -1
- package/dist/sync/log-store.d.ts +30 -0
- package/dist/sync/log-store.js +45 -0
- package/dist/sync/store.js +1 -1
- package/dist/trace/index.d.ts +18 -0
- package/dist/trace/index.js +13 -0
- package/dist/trace/log-view.d.ts +57 -0
- package/dist/trace/log-view.js +76 -0
- package/dist/trace/recorder.d.ts +75 -0
- package/dist/trace/recorder.js +157 -0
- package/dist/trace/replay.d.ts +132 -0
- package/dist/trace/replay.js +264 -0
- package/dist/trace/state.d.ts +102 -0
- package/dist/trace/state.js +86 -0
- package/dist/trace/store.d.ts +75 -0
- package/dist/trace/store.js +250 -0
- package/dist/utils/deep-merge.d.ts +10 -0
- package/dist/utils/deep-merge.js +23 -0
- package/dist/utils/file.d.ts +13 -4
- package/dist/utils/file.js +70 -12
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.js +2 -1
- package/dist/utils/long-timeout.d.ts +19 -0
- package/dist/utils/long-timeout.js +33 -0
- package/dist/utils/path.d.ts +22 -1
- package/dist/utils/path.js +46 -1
- package/dist/utils/redact.d.ts +22 -0
- package/dist/utils/redact.js +42 -0
- package/dist/utils/type-guards.d.ts +58 -0
- package/dist/utils/type-guards.js +92 -0
- package/dist/webhook/server.d.ts +9 -0
- package/dist/webhook/server.js +122 -36
- package/dist/webhook/types.d.ts +9 -1
- package/package.json +76 -9
- package/.claude/settings.local.json +0 -31
- package/.claude/skills/api-integration.md +0 -125
- package/.claude/skills/database-schema.md +0 -51
- package/.claude/skills/dsl-design.md +0 -80
- package/.claude/skills/property-testing.md +0 -143
- package/.claude/skills/reqon/SKILL.md +0 -44
- package/.claude/skills/reqon/references/examples.md +0 -206
- package/.claude/skills/reqon/references/syntax.md +0 -263
- package/.claude/skills/vscode-extension.md +0 -113
- package/.github/dependabot.yml +0 -32
- package/.github/pull_request_template.md +0 -21
- package/.github/workflows/ci.yml +0 -174
- package/.github/workflows/release.yml +0 -73
- package/CLAUDE.md +0 -72
- package/CONTRIBUTING.md +0 -161
- package/TODO.md +0 -51
- package/dist/auth/auth.test.d.ts +0 -1
- package/dist/auth/auth.test.js +0 -255
- package/dist/errors/errors.test.d.ts +0 -1
- package/dist/errors/errors.test.js +0 -165
- package/dist/execution/execution.test.d.ts +0 -1
- package/dist/execution/execution.test.js +0 -246
- package/dist/integration.test.d.ts +0 -1
- package/dist/integration.test.js +0 -168
- package/dist/interpreter/evaluator.test.d.ts +0 -1
- package/dist/interpreter/evaluator.test.js +0 -512
- package/dist/interpreter/http.test.d.ts +0 -1
- package/dist/interpreter/http.test.js +0 -299
- package/dist/interpreter/progress.test.d.ts +0 -1
- package/dist/interpreter/progress.test.js +0 -216
- package/dist/interpreter/schema-matcher.test.d.ts +0 -1
- package/dist/interpreter/schema-matcher.test.js +0 -122
- package/dist/lexer/lexer.d.ts +0 -24
- package/dist/lexer/lexer.js +0 -264
- package/dist/lexer/lexer.test.d.ts +0 -1
- package/dist/lexer/lexer.test.js +0 -259
- package/dist/loader/loader.test.d.ts +0 -1
- package/dist/loader/loader.test.js +0 -287
- package/dist/oas/oas.test.d.ts +0 -1
- package/dist/oas/oas.test.js +0 -218
- package/dist/parser/expressions.test.d.ts +0 -1
- package/dist/parser/expressions.test.js +0 -378
- package/dist/parser/match.test.d.ts +0 -1
- package/dist/parser/match.test.js +0 -254
- package/dist/parser/parser.test.d.ts +0 -1
- package/dist/parser/parser.test.js +0 -333
- package/dist/parser/schedule.test.d.ts +0 -1
- package/dist/parser/schedule.test.js +0 -241
- package/dist/scheduler/cron-parser.test.d.ts +0 -1
- package/dist/scheduler/cron-parser.test.js +0 -188
- package/dist/stores/file.test.d.ts +0 -1
- package/dist/stores/file.test.js +0 -165
- package/dist/stores/memory.test.d.ts +0 -1
- package/dist/stores/memory.test.js +0 -157
- package/dist/stores/stores.test.d.ts +0 -1
- package/dist/stores/stores.test.js +0 -158
- package/dist/sync/sync.test.d.ts +0 -1
- package/dist/sync/sync.test.js +0 -221
- package/docusaurus/README.md +0 -41
- package/docusaurus/docs/advanced/execution-state.md +0 -283
- package/docusaurus/docs/advanced/extending-reqon.md +0 -388
- package/docusaurus/docs/advanced/multi-file-missions.md +0 -250
- package/docusaurus/docs/advanced/parallel-execution.md +0 -353
- package/docusaurus/docs/api-reference.md +0 -443
- package/docusaurus/docs/authentication/api-key.md +0 -339
- package/docusaurus/docs/authentication/basic.md +0 -276
- package/docusaurus/docs/authentication/bearer.md +0 -282
- package/docusaurus/docs/authentication/oauth2.md +0 -317
- package/docusaurus/docs/authentication/overview.md +0 -251
- package/docusaurus/docs/cli.md +0 -229
- package/docusaurus/docs/core-concepts/actions.md +0 -286
- package/docusaurus/docs/core-concepts/missions.md +0 -264
- package/docusaurus/docs/core-concepts/schemas.md +0 -353
- package/docusaurus/docs/core-concepts/sources.md +0 -339
- package/docusaurus/docs/core-concepts/stores.md +0 -332
- package/docusaurus/docs/dsl-syntax/expressions.md +0 -361
- package/docusaurus/docs/dsl-syntax/fetch.md +0 -293
- package/docusaurus/docs/dsl-syntax/for-loops.md +0 -324
- package/docusaurus/docs/dsl-syntax/map.md +0 -345
- package/docusaurus/docs/dsl-syntax/match.md +0 -387
- package/docusaurus/docs/dsl-syntax/pipelines.md +0 -397
- package/docusaurus/docs/dsl-syntax/validate.md +0 -401
- package/docusaurus/docs/error-handling/dead-letter-queues.md +0 -399
- package/docusaurus/docs/error-handling/flow-control.md +0 -337
- package/docusaurus/docs/error-handling/retry-strategies.md +0 -368
- package/docusaurus/docs/examples.md +0 -488
- package/docusaurus/docs/getting-started.md +0 -256
- package/docusaurus/docs/http/circuit-breaker.md +0 -401
- package/docusaurus/docs/http/incremental-sync.md +0 -394
- package/docusaurus/docs/http/pagination.md +0 -361
- package/docusaurus/docs/http/rate-limiting.md +0 -383
- package/docusaurus/docs/http/requests.md +0 -328
- package/docusaurus/docs/http/retry.md +0 -402
- package/docusaurus/docs/intro.md +0 -90
- package/docusaurus/docs/openapi/loading-specs.md +0 -305
- package/docusaurus/docs/openapi/operation-calls.md +0 -314
- package/docusaurus/docs/openapi/overview.md +0 -212
- package/docusaurus/docs/openapi/response-validation.md +0 -344
- package/docusaurus/docs/scheduling/cron.md +0 -305
- package/docusaurus/docs/scheduling/daemon-mode.md +0 -317
- package/docusaurus/docs/scheduling/intervals.md +0 -289
- package/docusaurus/docs/scheduling/overview.md +0 -231
- package/docusaurus/docs/stores/custom-adapters.md +0 -376
- package/docusaurus/docs/stores/file.md +0 -236
- package/docusaurus/docs/stores/memory.md +0 -193
- package/docusaurus/docs/stores/overview.md +0 -274
- package/docusaurus/docs/stores/postgrest.md +0 -316
- package/docusaurus/docusaurus.config.ts +0 -148
- package/docusaurus/package-lock.json +0 -18029
- package/docusaurus/package.json +0 -47
- package/docusaurus/sidebars.ts +0 -155
- package/docusaurus/src/components/HomepageFeatures/index.tsx +0 -105
- package/docusaurus/src/components/HomepageFeatures/styles.module.css +0 -12
- package/docusaurus/src/css/custom.css +0 -169
- package/docusaurus/src/pages/index.module.css +0 -48
- package/docusaurus/src/pages/index.tsx +0 -110
- package/docusaurus/src/pages/markdown-page.md +0 -7
- 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 +0 -10
- package/docusaurus/static/img/undraw_docusaurus_mountain.svg +0 -171
- package/docusaurus/static/img/undraw_docusaurus_react.svg +0 -170
- package/docusaurus/static/img/undraw_docusaurus_tree.svg +0 -40
- package/docusaurus/tsconfig.json +0 -8
- package/examples/README.md +0 -112
- package/examples/error-handling/README.md +0 -150
- package/examples/error-handling/payment-processor.vague +0 -287
- package/examples/github-sync/README.md +0 -74
- package/examples/github-sync/fetch-issues.vague +0 -47
- package/examples/github-sync/fetch-prs.vague +0 -40
- package/examples/github-sync/mission.vague +0 -101
- package/examples/github-sync/normalize.vague +0 -70
- package/examples/jsonplaceholder/README.md +0 -28
- package/examples/jsonplaceholder/posts.vague +0 -48
- package/examples/petstore/README.md +0 -35
- package/examples/petstore/openapi.yaml +0 -97
- package/examples/petstore/sync.vague +0 -52
- package/examples/temporal-comparison/README.md +0 -297
- package/examples/temporal-comparison/reconciliation.vague +0 -355
- package/examples/temporal-comparison/temporal/activities/index.ts +0 -8
- package/examples/temporal-comparison/temporal/activities/shipstation.ts +0 -225
- package/examples/temporal-comparison/temporal/activities/shopify.ts +0 -257
- package/examples/temporal-comparison/temporal/activities/storage.ts +0 -198
- package/examples/temporal-comparison/temporal/activities/stripe.ts +0 -169
- package/examples/temporal-comparison/temporal/activities/validation.ts +0 -205
- package/examples/temporal-comparison/temporal/client/schedule.ts +0 -218
- package/examples/temporal-comparison/temporal/config/retry.ts +0 -63
- package/examples/temporal-comparison/temporal/types/index.ts +0 -129
- package/examples/temporal-comparison/temporal/workers/main.ts +0 -130
- package/examples/temporal-comparison/temporal/workflows/orderReconciliation.ts +0 -262
- package/examples/xero/README.md +0 -88
- package/examples/xero/invoices.vague +0 -189
- package/src/api-integration.test.ts +0 -954
- package/src/ast/index.ts +0 -1
- package/src/ast/nodes.ts +0 -310
- package/src/auth/auth.test.ts +0 -326
- package/src/auth/circuit-breaker.test.ts +0 -390
- package/src/auth/circuit-breaker.ts +0 -379
- package/src/auth/credentials.test.ts +0 -273
- package/src/auth/credentials.ts +0 -246
- package/src/auth/index.ts +0 -40
- package/src/auth/oauth2-provider.ts +0 -177
- package/src/auth/rate-limiter.ts +0 -459
- package/src/auth/token-store.ts +0 -177
- package/src/auth/types.ts +0 -159
- package/src/benchmark/e2e.bench.ts +0 -288
- package/src/benchmark/evaluator.bench.ts +0 -331
- package/src/benchmark/fixtures.ts +0 -295
- package/src/benchmark/index.ts +0 -108
- package/src/benchmark/lexer.bench.ts +0 -69
- package/src/benchmark/parser.bench.ts +0 -103
- package/src/benchmark/resilience.bench.ts +0 -193
- package/src/benchmark/store.bench.ts +0 -147
- package/src/benchmark/utils.ts +0 -230
- package/src/cli.ts +0 -313
- package/src/errors/errors.test.ts +0 -234
- package/src/errors/index.ts +0 -223
- package/src/execution/execution.test.ts +0 -307
- package/src/execution/index.ts +0 -21
- package/src/execution/state.ts +0 -207
- package/src/execution/store.ts +0 -188
- package/src/index.ts +0 -169
- package/src/integration.test.ts +0 -192
- package/src/interpreter/context.ts +0 -57
- package/src/interpreter/evaluator.test.ts +0 -796
- package/src/interpreter/evaluator.ts +0 -245
- package/src/interpreter/executor.ts +0 -946
- package/src/interpreter/fetch-handler.ts +0 -302
- package/src/interpreter/http.test.ts +0 -423
- package/src/interpreter/http.ts +0 -308
- package/src/interpreter/index.ts +0 -32
- package/src/interpreter/pagination.ts +0 -207
- package/src/interpreter/progress.test.ts +0 -276
- package/src/interpreter/schema-matcher.test.ts +0 -160
- package/src/interpreter/schema-matcher.ts +0 -168
- package/src/interpreter/signals.ts +0 -73
- package/src/interpreter/step-handlers/for-handler.ts +0 -65
- package/src/interpreter/step-handlers/index.ts +0 -17
- package/src/interpreter/step-handlers/map-handler.ts +0 -24
- package/src/interpreter/step-handlers/match-handler.ts +0 -101
- package/src/interpreter/step-handlers/store-handler.ts +0 -78
- package/src/interpreter/step-handlers/types.ts +0 -17
- package/src/interpreter/step-handlers/validate-handler.ts +0 -30
- package/src/interpreter/step-handlers/webhook-handler.ts +0 -142
- package/src/lexer/index.ts +0 -18
- package/src/lexer/lexer.test.ts +0 -316
- package/src/lexer/tokens.ts +0 -179
- package/src/loader/index.ts +0 -288
- package/src/loader/loader.test.ts +0 -360
- package/src/oas/index.ts +0 -4
- package/src/oas/loader.ts +0 -126
- package/src/oas/oas.test.ts +0 -254
- package/src/oas/validator.ts +0 -299
- package/src/parser/base.ts +0 -124
- package/src/parser/expressions.test.ts +0 -525
- package/src/parser/expressions.ts +0 -314
- package/src/parser/index.ts +0 -3
- package/src/parser/match.test.ts +0 -296
- package/src/parser/parser.test.ts +0 -739
- package/src/parser/parser.ts +0 -1469
- package/src/parser/schedule.test.ts +0 -287
- package/src/parser/webhook.test.ts +0 -248
- package/src/plugin.ts +0 -83
- package/src/scheduler/cron-parser.test.ts +0 -236
- package/src/scheduler/cron-parser.ts +0 -236
- package/src/scheduler/index.ts +0 -10
- package/src/scheduler/scheduler.ts +0 -443
- package/src/scheduler/types.ts +0 -71
- package/src/stores/factory.ts +0 -104
- package/src/stores/file.test.ts +0 -276
- package/src/stores/file.ts +0 -211
- package/src/stores/index.ts +0 -6
- package/src/stores/memory.test.ts +0 -238
- package/src/stores/memory.ts +0 -63
- package/src/stores/postgrest.test.ts +0 -488
- package/src/stores/postgrest.ts +0 -263
- package/src/stores/stores.test.ts +0 -197
- package/src/stores/types.ts +0 -58
- package/src/sync/index.ts +0 -16
- package/src/sync/state.ts +0 -126
- package/src/sync/store.ts +0 -139
- package/src/sync/sync.test.ts +0 -271
- package/src/utils/async.ts +0 -10
- package/src/utils/file.ts +0 -106
- package/src/utils/index.ts +0 -14
- package/src/utils/logger.ts +0 -53
- package/src/utils/path.ts +0 -47
- package/src/webhook/index.ts +0 -15
- package/src/webhook/server.test.ts +0 -253
- package/src/webhook/server.ts +0 -389
- package/src/webhook/store.ts +0 -239
- package/src/webhook/types.ts +0 -93
- package/tsconfig.json +0 -17
- package/vitest.config.ts +0 -39
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import { sleep } from '../utils/async.js';
|
|
2
|
-
|
|
3
|
-
const DEFAULT_MAX_STALE_AGE_MS = 60 * 60 * 1000;
|
|
4
|
-
/** Cleanup interval (default: 5 minutes) */
|
|
5
|
-
const CLEANUP_INTERVAL_MS = 5 * 60 * 1000;
|
|
6
|
-
/** Max number of entries before forced cleanup */
|
|
7
|
-
const MAX_ENTRIES_BEFORE_CLEANUP = 1000;
|
|
2
|
+
import { RATE_LIMIT_DEFAULTS } from '../config/index.js';
|
|
8
3
|
const DEFAULT_CONFIG = {
|
|
9
|
-
strategy:
|
|
10
|
-
maxWait:
|
|
11
|
-
notifyAt:
|
|
12
|
-
fallbackRpm:
|
|
4
|
+
strategy: RATE_LIMIT_DEFAULTS.STRATEGY,
|
|
5
|
+
maxWait: RATE_LIMIT_DEFAULTS.MAX_WAIT_SECONDS,
|
|
6
|
+
notifyAt: RATE_LIMIT_DEFAULTS.NOTIFY_AT_SECONDS,
|
|
7
|
+
fallbackRpm: RATE_LIMIT_DEFAULTS.FALLBACK_RPM,
|
|
13
8
|
};
|
|
14
9
|
/**
|
|
15
10
|
* Rate limit timeout error - thrown when maxWait is exceeded
|
|
@@ -44,8 +39,6 @@ export class RateLimitError extends Error {
|
|
|
44
39
|
* Adaptive rate limiter that learns from response headers
|
|
45
40
|
* Supports pause, throttle, and fail strategies
|
|
46
41
|
*/
|
|
47
|
-
/** Number of responses between cleanup checks */
|
|
48
|
-
const CLEANUP_CHECK_INTERVAL = 100;
|
|
49
42
|
export class AdaptiveRateLimiter {
|
|
50
43
|
defaultConfig;
|
|
51
44
|
state = new Map();
|
|
@@ -56,29 +49,37 @@ export class AdaptiveRateLimiter {
|
|
|
56
49
|
responsesSinceCleanup = 0;
|
|
57
50
|
constructor(defaultConfig = {}, options = {}) {
|
|
58
51
|
this.defaultConfig = defaultConfig;
|
|
59
|
-
this.maxStaleAgeMs = options.maxStaleAgeMs ??
|
|
52
|
+
this.maxStaleAgeMs = options.maxStaleAgeMs ?? RATE_LIMIT_DEFAULTS.MAX_STALE_AGE_MS;
|
|
60
53
|
}
|
|
61
54
|
/**
|
|
62
|
-
* Clean up stale entries from the state map to prevent memory leaks
|
|
55
|
+
* Clean up stale entries from the state map to prevent memory leaks.
|
|
56
|
+
*
|
|
57
|
+
* Eviction is driven by `lastRequestAt`, not `resetAt`. Most of the leak came
|
|
58
|
+
* from keys whose API sends no reset header: `resetAt` is never set, so the
|
|
59
|
+
* old reset-passed condition could never fire and those keys lived forever.
|
|
60
|
+
* Now any key idle longer than the stale threshold is evicted regardless of
|
|
61
|
+
* `resetAt`, except while an active `retryAfter` backoff is still pending
|
|
62
|
+
* (that state must survive so we keep honouring the 429).
|
|
63
63
|
*/
|
|
64
64
|
cleanup() {
|
|
65
65
|
const now = Date.now();
|
|
66
66
|
// Skip if cleanup was done recently and we're under the entry limit
|
|
67
|
-
if (now - this.lastCleanup < CLEANUP_INTERVAL_MS &&
|
|
68
|
-
this.state.size < MAX_ENTRIES_BEFORE_CLEANUP) {
|
|
67
|
+
if (now - this.lastCleanup < RATE_LIMIT_DEFAULTS.CLEANUP_INTERVAL_MS &&
|
|
68
|
+
this.state.size < RATE_LIMIT_DEFAULTS.MAX_ENTRIES_BEFORE_CLEANUP) {
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
71
|
this.lastCleanup = now;
|
|
72
72
|
const nowDate = new Date(now);
|
|
73
73
|
const staleThreshold = new Date(now - this.maxStaleAgeMs);
|
|
74
74
|
for (const [key, state] of this.state) {
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
75
|
+
// A pending retry-after backoff must never be evicted out from under us.
|
|
76
|
+
const isRetryPending = state.retryAfter !== undefined && state.retryAfter >= nowDate;
|
|
77
|
+
if (isRetryPending)
|
|
78
|
+
continue;
|
|
79
|
+
// Stale if the last request is older than the threshold, or if no request
|
|
80
|
+
// was ever recorded for this key.
|
|
81
|
+
const isStale = !state.lastRequestAt || state.lastRequestAt < staleThreshold;
|
|
82
|
+
if (isStale) {
|
|
82
83
|
this.state.delete(key);
|
|
83
84
|
}
|
|
84
85
|
}
|
|
@@ -258,9 +259,18 @@ export class AdaptiveRateLimiter {
|
|
|
258
259
|
}
|
|
259
260
|
state.lastRequestAt = now;
|
|
260
261
|
this.state.set(key, state);
|
|
261
|
-
//
|
|
262
|
+
// Trigger a stale-entry sweep every N responses. The sweep itself is rate-
|
|
263
|
+
// limited by CLEANUP_INTERVAL_MS / MAX_ENTRIES_BEFORE_CLEANUP inside
|
|
264
|
+
// cleanup(), so this counter only decides how often we *consider* sweeping.
|
|
265
|
+
//
|
|
266
|
+
// TODO: this limiter is purely reactive — it learns limits from response
|
|
267
|
+
// headers after the fact. Add proactive in-flight token accounting (track
|
|
268
|
+
// tokens consumed by requests that have been issued but not yet returned a
|
|
269
|
+
// response) so concurrent callers can't collectively blow past the limit
|
|
270
|
+
// between header updates. That is a larger redesign; the eviction leak fix
|
|
271
|
+
// above is independent of it.
|
|
262
272
|
this.responsesSinceCleanup++;
|
|
263
|
-
if (this.responsesSinceCleanup >= CLEANUP_CHECK_INTERVAL) {
|
|
273
|
+
if (this.responsesSinceCleanup >= RATE_LIMIT_DEFAULTS.CLEANUP_CHECK_INTERVAL) {
|
|
264
274
|
this.responsesSinceCleanup = 0;
|
|
265
275
|
this.cleanup();
|
|
266
276
|
}
|
|
@@ -273,7 +283,10 @@ export class AdaptiveRateLimiter {
|
|
|
273
283
|
return { isLimited: false };
|
|
274
284
|
}
|
|
275
285
|
const isLimited = (state.retryAfter && state.retryAfter > now) ||
|
|
276
|
-
(state.remaining !== undefined &&
|
|
286
|
+
(state.remaining !== undefined &&
|
|
287
|
+
state.remaining <= 0 &&
|
|
288
|
+
state.resetAt &&
|
|
289
|
+
state.resetAt > now);
|
|
277
290
|
let resetInSeconds;
|
|
278
291
|
if (isLimited && state.resetAt) {
|
|
279
292
|
resetInSeconds = Math.ceil((state.resetAt.getTime() - now.getTime()) / 1000);
|
package/dist/auth/token-store.js
CHANGED
|
@@ -103,7 +103,14 @@ export class FileTokenStore {
|
|
|
103
103
|
for (const [key, value] of this.cache) {
|
|
104
104
|
data[key] = value;
|
|
105
105
|
}
|
|
106
|
-
|
|
106
|
+
// Owner-only (0o600): the file holds OAuth tokens and must not be
|
|
107
|
+
// world-readable. `mode` only applies on creation, so chmod an existing
|
|
108
|
+
// file too (in case it was created before this fix or under a loose umask).
|
|
109
|
+
await fs.writeFile(this.filePath, JSON.stringify(data, null, 2), {
|
|
110
|
+
encoding: 'utf-8',
|
|
111
|
+
mode: 0o600,
|
|
112
|
+
});
|
|
113
|
+
await fs.chmod(this.filePath, 0o600).catch(() => { });
|
|
107
114
|
}
|
|
108
115
|
async get(connectionId) {
|
|
109
116
|
const map = await this.load();
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,2 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* ---
|
|
4
|
+
* purpose: CLI entry point - parses args and runs missions
|
|
5
|
+
* inputs:
|
|
6
|
+
* - file.reqon or folder path
|
|
7
|
+
* - --dry-run, --verbose, --auth, --env, --output, --daemon, --webhook, --debug
|
|
8
|
+
* related:
|
|
9
|
+
* - ./index.ts - library APIs used by CLI
|
|
10
|
+
* - ./scheduler/index.ts - daemon mode scheduling
|
|
11
|
+
* - ./webhook/index.ts - webhook server for wait steps
|
|
12
|
+
* - ./debug/cli-debugger.ts - interactive debugging
|
|
13
|
+
* ---
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Load and resolve an --auth credentials file, turning low-level fs/JSON
|
|
17
|
+
* failures into clean, user-facing messages instead of raw stack traces.
|
|
18
|
+
*/
|
|
19
|
+
export declare function loadAuthFile(rawPath: string): Promise<Record<string, unknown>>;
|
|
20
|
+
/**
|
|
21
|
+
* Print an error in a clean, user-facing form (no stack trace). ReqonErrors
|
|
22
|
+
* get their rich source-context formatting; everything else gets a one-line
|
|
23
|
+
* message.
|
|
24
|
+
*/
|
|
25
|
+
export declare function reportFatalError(error: unknown): void;
|
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,70 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ---
|
|
4
|
+
* purpose: CLI entry point - parses args and runs missions
|
|
5
|
+
* inputs:
|
|
6
|
+
* - file.reqon or folder path
|
|
7
|
+
* - --dry-run, --verbose, --auth, --env, --output, --daemon, --webhook, --debug
|
|
8
|
+
* related:
|
|
9
|
+
* - ./index.ts - library APIs used by CLI
|
|
10
|
+
* - ./scheduler/index.ts - daemon mode scheduling
|
|
11
|
+
* - ./webhook/index.ts - webhook server for wait steps
|
|
12
|
+
* - ./debug/cli-debugger.ts - interactive debugging
|
|
13
|
+
* ---
|
|
14
|
+
*/
|
|
2
15
|
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
3
16
|
import { resolve, dirname } from 'node:path';
|
|
17
|
+
import { pathToFileURL } from 'node:url';
|
|
4
18
|
import { fromPath, Scheduler, loadMission } from './index.js';
|
|
5
19
|
import { ReqonError } from './errors/index.js';
|
|
6
20
|
import { loadEnv, loadCredentials } from './auth/credentials.js';
|
|
7
21
|
import { WebhookServer } from './webhook/index.js';
|
|
22
|
+
import { ControlServer } from './control/index.js';
|
|
23
|
+
/**
|
|
24
|
+
* Load and resolve an --auth credentials file, turning low-level fs/JSON
|
|
25
|
+
* failures into clean, user-facing messages instead of raw stack traces.
|
|
26
|
+
*/
|
|
27
|
+
export async function loadAuthFile(rawPath) {
|
|
28
|
+
const authPath = resolve(rawPath);
|
|
29
|
+
let authContent;
|
|
30
|
+
try {
|
|
31
|
+
authContent = await readFile(authPath, 'utf-8');
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
if (err.code === 'ENOENT') {
|
|
35
|
+
throw new Error(`auth file not found: ${authPath}`);
|
|
36
|
+
}
|
|
37
|
+
if (err.code === 'EISDIR') {
|
|
38
|
+
throw new Error(`auth path is a directory, not a file: ${authPath}`);
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`could not read auth file ${authPath}: ${err.message}`);
|
|
41
|
+
}
|
|
42
|
+
let rawAuth;
|
|
43
|
+
try {
|
|
44
|
+
rawAuth = JSON.parse(authContent);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
throw new Error(`auth file is not valid JSON: ${authPath}`);
|
|
48
|
+
}
|
|
49
|
+
// Resolve env var references in the auth config
|
|
50
|
+
return loadCredentials(rawAuth);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Print an error in a clean, user-facing form (no stack trace). ReqonErrors
|
|
54
|
+
* get their rich source-context formatting; everything else gets a one-line
|
|
55
|
+
* message.
|
|
56
|
+
*/
|
|
57
|
+
export function reportFatalError(error) {
|
|
58
|
+
if (error instanceof ReqonError) {
|
|
59
|
+
console.error(error.format());
|
|
60
|
+
}
|
|
61
|
+
else if (error instanceof Error) {
|
|
62
|
+
console.error(`Error: ${error.message}`);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
console.error(`Error: ${String(error)}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
8
68
|
async function main() {
|
|
9
69
|
const args = process.argv.slice(2);
|
|
10
70
|
if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
|
|
@@ -17,6 +77,7 @@ Usage:
|
|
|
17
77
|
Options:
|
|
18
78
|
--dry-run Run without making actual HTTP requests
|
|
19
79
|
--verbose Enable verbose logging
|
|
80
|
+
--dev Development mode: let sql/nosql stores fall back to local JSON files
|
|
20
81
|
--auth <file> JSON file with auth credentials (supports env var interpolation)
|
|
21
82
|
--env <file> Path to .env file (default: .env in current directory)
|
|
22
83
|
--output <path> Export stores to JSON (file or directory)
|
|
@@ -25,6 +86,10 @@ Options:
|
|
|
25
86
|
--webhook Enable webhook server for 'wait' steps
|
|
26
87
|
--webhook-port <n> Port for webhook server (default: 3000)
|
|
27
88
|
--webhook-url <url> Base URL for webhook endpoints (default: http://localhost:3000)
|
|
89
|
+
--control Enable control server for pause/resume and status queries
|
|
90
|
+
--control-port <n> Port for control server (default: 3001)
|
|
91
|
+
--debug Enable step-through debugging
|
|
92
|
+
--resume <id> Resume a paused or failed execution by ID
|
|
28
93
|
--help, -h Show this help message
|
|
29
94
|
|
|
30
95
|
Environment Variables:
|
|
@@ -44,15 +109,27 @@ Examples:
|
|
|
44
109
|
reqon sync-invoices.reqon --output ./output.json
|
|
45
110
|
reqon sync-invoices.reqon --daemon --verbose
|
|
46
111
|
reqon sync-invoices.reqon --webhook --webhook-port 8080 --verbose
|
|
112
|
+
reqon sync-invoices.reqon --control --verbose # enable control server
|
|
113
|
+
reqon sync-invoices.reqon --resume exec_abc123 # resume paused execution
|
|
114
|
+
|
|
115
|
+
Control Server:
|
|
116
|
+
When --control is enabled, the server exposes these endpoints:
|
|
117
|
+
POST /pause Request graceful pause at next safe point
|
|
118
|
+
POST /resume Clear pause request
|
|
119
|
+
GET /status Get current execution state and progress
|
|
120
|
+
GET /health Health check
|
|
47
121
|
`);
|
|
48
122
|
process.exit(0);
|
|
49
123
|
}
|
|
50
124
|
const filePath = args[0];
|
|
51
125
|
const dryRun = args.includes('--dry-run');
|
|
52
126
|
const verbose = args.includes('--verbose');
|
|
127
|
+
const devMode = args.includes('--dev');
|
|
53
128
|
const daemon = args.includes('--daemon');
|
|
54
129
|
const once = args.includes('--once');
|
|
55
130
|
const webhookEnabled = args.includes('--webhook');
|
|
131
|
+
const debugEnabled = args.includes('--debug');
|
|
132
|
+
const controlEnabled = args.includes('--control');
|
|
56
133
|
// Parse webhook options
|
|
57
134
|
let webhookPort = 3000;
|
|
58
135
|
const webhookPortIndex = args.indexOf('--webhook-port');
|
|
@@ -64,6 +141,18 @@ Examples:
|
|
|
64
141
|
if (webhookUrlIndex !== -1 && args[webhookUrlIndex + 1]) {
|
|
65
142
|
webhookUrl = args[webhookUrlIndex + 1];
|
|
66
143
|
}
|
|
144
|
+
// Parse control server options
|
|
145
|
+
let controlPort = 3001;
|
|
146
|
+
const controlPortIndex = args.indexOf('--control-port');
|
|
147
|
+
if (controlPortIndex !== -1 && args[controlPortIndex + 1]) {
|
|
148
|
+
controlPort = parseInt(args[controlPortIndex + 1], 10);
|
|
149
|
+
}
|
|
150
|
+
// Parse resume option
|
|
151
|
+
let resumeFrom;
|
|
152
|
+
const resumeIndex = args.indexOf('--resume');
|
|
153
|
+
if (resumeIndex !== -1 && args[resumeIndex + 1]) {
|
|
154
|
+
resumeFrom = args[resumeIndex + 1];
|
|
155
|
+
}
|
|
67
156
|
// Load .env file(s)
|
|
68
157
|
let envFile;
|
|
69
158
|
const envIndex = args.indexOf('--env');
|
|
@@ -78,11 +167,7 @@ Examples:
|
|
|
78
167
|
let auth;
|
|
79
168
|
const authIndex = args.indexOf('--auth');
|
|
80
169
|
if (authIndex !== -1 && args[authIndex + 1]) {
|
|
81
|
-
|
|
82
|
-
const authContent = await readFile(authPath, 'utf-8');
|
|
83
|
-
const rawAuth = JSON.parse(authContent);
|
|
84
|
-
// Resolve env var references in the auth config
|
|
85
|
-
auth = loadCredentials(rawAuth);
|
|
170
|
+
auth = await loadAuthFile(args[authIndex + 1]);
|
|
86
171
|
}
|
|
87
172
|
let outputPath;
|
|
88
173
|
const outputIndex = args.indexOf('--output');
|
|
@@ -112,14 +197,44 @@ Examples:
|
|
|
112
197
|
await webhookServer.start();
|
|
113
198
|
console.log(`Webhook server started on port ${webhookPort}`);
|
|
114
199
|
}
|
|
200
|
+
// Start control server if enabled
|
|
201
|
+
let controlServer;
|
|
202
|
+
if (controlEnabled) {
|
|
203
|
+
controlServer = new ControlServer({ port: controlPort, verbose });
|
|
204
|
+
await controlServer.start();
|
|
205
|
+
console.log(`Control server started on port ${controlPort}`);
|
|
206
|
+
console.log(` POST http://localhost:${controlPort}/pause - request pause`);
|
|
207
|
+
console.log(` GET http://localhost:${controlPort}/status - check status`);
|
|
208
|
+
}
|
|
209
|
+
// Initialize debug controller if enabled
|
|
210
|
+
let debugController;
|
|
211
|
+
if (debugEnabled) {
|
|
212
|
+
const { CLIDebugger } = await import('./debug/cli-debugger.js');
|
|
213
|
+
debugController = new CLIDebugger();
|
|
214
|
+
console.log('Debug mode enabled. Commands: c(ontinue), s(tep), si(step-into), so(step-over), q(uit)');
|
|
215
|
+
console.log('Type "help" at the debug prompt for more commands.\n');
|
|
216
|
+
}
|
|
115
217
|
try {
|
|
116
218
|
const result = await fromPath(filePath, {
|
|
117
219
|
dryRun,
|
|
118
220
|
verbose,
|
|
221
|
+
developmentMode: devMode,
|
|
119
222
|
auth: auth,
|
|
120
223
|
webhookServer,
|
|
224
|
+
debugController,
|
|
225
|
+
controlServer,
|
|
226
|
+
resumeFrom,
|
|
121
227
|
});
|
|
122
|
-
if
|
|
228
|
+
// Check if execution was paused
|
|
229
|
+
const isPaused = result.state?.status === 'paused';
|
|
230
|
+
if (isPaused) {
|
|
231
|
+
console.log(`\n⏸ Mission paused`);
|
|
232
|
+
console.log(` Duration: ${result.duration}ms`);
|
|
233
|
+
console.log(` Actions run: ${result.actionsRun.join(' → ')}`);
|
|
234
|
+
console.log(` Execution ID: ${result.executionId}`);
|
|
235
|
+
console.log(`\n To resume: reqon ${filePath} --resume ${result.executionId}`);
|
|
236
|
+
}
|
|
237
|
+
else if (result.success) {
|
|
123
238
|
console.log(`\n✓ Mission completed successfully`);
|
|
124
239
|
console.log(` Duration: ${result.duration}ms`);
|
|
125
240
|
console.log(` Actions run: ${result.actionsRun.join(' → ')}`);
|
|
@@ -127,7 +242,7 @@ Examples:
|
|
|
127
242
|
const storeData = {};
|
|
128
243
|
for (const [name, store] of result.stores) {
|
|
129
244
|
const items = await store.list();
|
|
130
|
-
console.log(` Store "${name}": ${items.length} items`);
|
|
245
|
+
console.log(` Store "${name}": ${items.length} ${items.length === 1 ? 'item' : 'items'}`);
|
|
131
246
|
storeData[name] = items;
|
|
132
247
|
}
|
|
133
248
|
// Export to JSON if requested
|
|
@@ -142,6 +257,10 @@ Examples:
|
|
|
142
257
|
for (const error of result.errors) {
|
|
143
258
|
console.error(` [${error.action}/${error.step}] ${error.message}`);
|
|
144
259
|
}
|
|
260
|
+
if (result.executionId) {
|
|
261
|
+
console.log(`\n Execution ID: ${result.executionId}`);
|
|
262
|
+
console.log(` To resume: reqon ${filePath} --resume ${result.executionId}`);
|
|
263
|
+
}
|
|
145
264
|
process.exit(1);
|
|
146
265
|
}
|
|
147
266
|
}
|
|
@@ -159,16 +278,22 @@ Examples:
|
|
|
159
278
|
if (webhookServer) {
|
|
160
279
|
await webhookServer.stop();
|
|
161
280
|
}
|
|
281
|
+
// Stop control server if it was started
|
|
282
|
+
if (controlServer) {
|
|
283
|
+
await controlServer.stop();
|
|
284
|
+
}
|
|
285
|
+
// Close debug controller if it was started
|
|
286
|
+
if (debugController?.close) {
|
|
287
|
+
debugController.close();
|
|
288
|
+
}
|
|
162
289
|
}
|
|
163
290
|
}
|
|
164
291
|
async function runDaemon(filePath, options) {
|
|
165
292
|
const absolutePath = resolve(filePath);
|
|
166
293
|
let program;
|
|
167
|
-
let baseDir;
|
|
168
294
|
try {
|
|
169
295
|
const result = await loadMission(absolutePath);
|
|
170
296
|
program = result.program;
|
|
171
|
-
baseDir = result.baseDir;
|
|
172
297
|
}
|
|
173
298
|
catch (error) {
|
|
174
299
|
if (error instanceof ReqonError) {
|
|
@@ -267,4 +392,18 @@ async function runDaemon(filePath, options) {
|
|
|
267
392
|
function formatTime(date) {
|
|
268
393
|
return date.toISOString().replace('T', ' ').substring(0, 19);
|
|
269
394
|
}
|
|
270
|
-
|
|
395
|
+
// Only auto-run when invoked directly as the CLI entry point, so the module can
|
|
396
|
+
// be imported in tests without executing main() against the test runner's argv.
|
|
397
|
+
const isMain = typeof process.argv[1] === 'string' && import.meta.url === pathToFileURL(process.argv[1]).href;
|
|
398
|
+
if (isMain) {
|
|
399
|
+
// A rejected promise anywhere (including outside main's try/catch) should
|
|
400
|
+
// surface as a clean message and a non-zero exit, never a raw stack trace.
|
|
401
|
+
process.on('unhandledRejection', (reason) => {
|
|
402
|
+
reportFatalError(reason);
|
|
403
|
+
process.exit(1);
|
|
404
|
+
});
|
|
405
|
+
main().catch((error) => {
|
|
406
|
+
reportFatalError(error);
|
|
407
|
+
process.exit(1);
|
|
408
|
+
});
|
|
409
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized Configuration Constants
|
|
3
|
+
*
|
|
4
|
+
* This module contains all default values and configuration constants used
|
|
5
|
+
* throughout the Reqon framework. Centralizing these values makes it easier
|
|
6
|
+
* to understand, tune, and override defaults.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Default retry configuration for HTTP requests
|
|
10
|
+
*/
|
|
11
|
+
export declare const HTTP_RETRY_DEFAULTS: {
|
|
12
|
+
/** Maximum number of retry attempts */
|
|
13
|
+
readonly MAX_ATTEMPTS: 3;
|
|
14
|
+
/** Initial delay between retries in milliseconds */
|
|
15
|
+
readonly INITIAL_DELAY_MS: 1000;
|
|
16
|
+
/** Maximum delay between retries in milliseconds */
|
|
17
|
+
readonly MAX_DELAY_MS: 30000;
|
|
18
|
+
/** Backoff strategy: 'exponential', 'linear', or 'constant' */
|
|
19
|
+
readonly BACKOFF: "exponential";
|
|
20
|
+
/** Per-attempt request timeout in milliseconds (aborts a hung request) */
|
|
21
|
+
readonly TIMEOUT_MS: 30000;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Default HTTP headers
|
|
25
|
+
*/
|
|
26
|
+
export declare const HTTP_DEFAULT_HEADERS: {
|
|
27
|
+
readonly CONTENT_TYPE: "application/json";
|
|
28
|
+
readonly ACCEPT: "application/json";
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Default rate limiter configuration
|
|
32
|
+
*/
|
|
33
|
+
export declare const RATE_LIMIT_DEFAULTS: {
|
|
34
|
+
/** Default strategy when rate limited: 'pause', 'throttle', or 'fail' */
|
|
35
|
+
readonly STRATEGY: "pause";
|
|
36
|
+
/** Maximum wait time in seconds before timing out */
|
|
37
|
+
readonly MAX_WAIT_SECONDS: 300;
|
|
38
|
+
/** Seconds before starting to notify about ongoing waits */
|
|
39
|
+
readonly NOTIFY_AT_SECONDS: 10;
|
|
40
|
+
/** Fallback requests per minute when no rate limit info available */
|
|
41
|
+
readonly FALLBACK_RPM: 60;
|
|
42
|
+
/** Maximum age for stale rate limit entries (1 hour in ms) */
|
|
43
|
+
readonly MAX_STALE_AGE_MS: number;
|
|
44
|
+
/** Cleanup interval for stale entries (5 minutes in ms) */
|
|
45
|
+
readonly CLEANUP_INTERVAL_MS: number;
|
|
46
|
+
/** Number of responses between cleanup checks */
|
|
47
|
+
readonly CLEANUP_CHECK_INTERVAL: 100;
|
|
48
|
+
/** Maximum entries before forced cleanup */
|
|
49
|
+
readonly MAX_ENTRIES_BEFORE_CLEANUP: 1000;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Default circuit breaker configuration
|
|
53
|
+
*/
|
|
54
|
+
export declare const CIRCUIT_BREAKER_DEFAULTS: {
|
|
55
|
+
/** Number of failures before opening circuit */
|
|
56
|
+
readonly FAILURE_THRESHOLD: 5;
|
|
57
|
+
/** Time in milliseconds before attempting recovery */
|
|
58
|
+
readonly RESET_TIMEOUT_MS: 30000;
|
|
59
|
+
/** Number of successful requests in half-open to close circuit */
|
|
60
|
+
readonly SUCCESS_THRESHOLD: 2;
|
|
61
|
+
/** Time window in milliseconds for counting failures */
|
|
62
|
+
readonly FAILURE_WINDOW_MS: 60000;
|
|
63
|
+
/** HTTP status codes to count as failures */
|
|
64
|
+
readonly FAILURE_STATUS_CODES: readonly number[];
|
|
65
|
+
/** Whether to count network errors as failures */
|
|
66
|
+
readonly COUNT_NETWORK_ERRORS: true;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Default webhook server configuration
|
|
70
|
+
*/
|
|
71
|
+
export declare const WEBHOOK_DEFAULTS: {
|
|
72
|
+
/** Default port for webhook server */
|
|
73
|
+
readonly PORT: 3000;
|
|
74
|
+
/** Default host binding — loopback only; opt into 0.0.0.0 explicitly. */
|
|
75
|
+
readonly HOST: "127.0.0.1";
|
|
76
|
+
/** Default timeout for wait steps (5 minutes in ms) */
|
|
77
|
+
readonly DEFAULT_TIMEOUT_MS: 300000;
|
|
78
|
+
/** Cleanup interval for expired registrations (1 minute in ms) */
|
|
79
|
+
readonly CLEANUP_INTERVAL_MS: 60000;
|
|
80
|
+
/** Maximum accepted request body size in bytes (1 MiB) */
|
|
81
|
+
readonly MAX_BODY_BYTES: number;
|
|
82
|
+
/** Idle socket timeout in ms; drops slow-drip connections */
|
|
83
|
+
readonly SOCKET_TIMEOUT_MS: 30000;
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Default store configuration
|
|
87
|
+
*/
|
|
88
|
+
export declare const STORE_DEFAULTS: {
|
|
89
|
+
/** Default base directory for file stores */
|
|
90
|
+
readonly DATA_DIR: ".reqon-data";
|
|
91
|
+
/** Default subdirectory for executions */
|
|
92
|
+
readonly EXECUTIONS_DIR: "executions";
|
|
93
|
+
/** Default subdirectory for sync state */
|
|
94
|
+
readonly SYNC_DIR: "sync";
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Default scheduler configuration
|
|
98
|
+
*/
|
|
99
|
+
export declare const SCHEDULER_DEFAULTS: {
|
|
100
|
+
/** Default retry configuration for failed scheduled missions */
|
|
101
|
+
readonly MAX_RETRIES: 3;
|
|
102
|
+
/** Default delay between retries in seconds */
|
|
103
|
+
readonly RETRY_DELAY_SECONDS: 60;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Default execution configuration
|
|
107
|
+
*/
|
|
108
|
+
export declare const EXECUTION_DEFAULTS: {
|
|
109
|
+
/**
|
|
110
|
+
* Whether development mode is enabled by default. When true, sql/nosql
|
|
111
|
+
* stores fall back to local JSON files; default false so a mission that
|
|
112
|
+
* declares `store sql`/`nosql` errors loudly instead of silently writing
|
|
113
|
+
* to disk.
|
|
114
|
+
*/
|
|
115
|
+
readonly DEVELOPMENT_MODE: false;
|
|
116
|
+
/** Whether to persist execution state by default */
|
|
117
|
+
readonly PERSIST_STATE: false;
|
|
118
|
+
};
|
|
119
|
+
/** Type for rate limit strategy */
|
|
120
|
+
export type RateLimitStrategy = 'pause' | 'throttle' | 'fail';
|
|
121
|
+
/** Type for retry backoff strategy */
|
|
122
|
+
export type BackoffStrategy = 'exponential' | 'linear' | 'constant';
|
|
123
|
+
/**
|
|
124
|
+
* Merged configuration type utilities
|
|
125
|
+
*/
|
|
126
|
+
export type HttpRetryConfig = {
|
|
127
|
+
maxAttempts?: number;
|
|
128
|
+
initialDelay?: number;
|
|
129
|
+
maxDelay?: number;
|
|
130
|
+
backoff?: BackoffStrategy;
|
|
131
|
+
};
|
|
132
|
+
export type RateLimitConfig = {
|
|
133
|
+
strategy?: RateLimitStrategy;
|
|
134
|
+
maxWait?: number;
|
|
135
|
+
notifyAt?: number;
|
|
136
|
+
fallbackRpm?: number;
|
|
137
|
+
};
|
|
138
|
+
export type CircuitBreakerConfig = {
|
|
139
|
+
failureThreshold?: number;
|
|
140
|
+
resetTimeout?: number;
|
|
141
|
+
successThreshold?: number;
|
|
142
|
+
failureWindow?: number;
|
|
143
|
+
failureStatusCodes?: number[];
|
|
144
|
+
countNetworkErrors?: boolean;
|
|
145
|
+
};
|
|
146
|
+
export type WebhookConfig = {
|
|
147
|
+
port?: number;
|
|
148
|
+
host?: string;
|
|
149
|
+
baseUrl?: string;
|
|
150
|
+
defaultTimeout?: number;
|
|
151
|
+
verbose?: boolean;
|
|
152
|
+
};
|