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.
- package/CHANGELOG.md +7 -0
- package/README.md +22 -0
- package/dist/ast/nodes.d.ts +83 -4
- package/dist/ast/nodes.js +14 -0
- package/dist/auth/circuit-breaker.js +7 -6
- package/dist/auth/rate-limiter.d.ts +4 -0
- package/dist/auth/rate-limiter.js +9 -16
- package/dist/cli.d.ts +13 -0
- package/dist/cli.js +84 -4
- package/dist/config/constants.d.ts +141 -0
- package/dist/config/constants.js +128 -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 +88 -0
- package/dist/control/server.js +238 -0
- package/dist/control/types.d.ts +55 -0
- package/dist/control/types.js +7 -0
- package/dist/debug/cli-debugger.d.ts +17 -0
- package/dist/debug/cli-debugger.js +180 -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/index.d.ts +21 -1
- package/dist/index.js +33 -2
- package/dist/interpreter/context.d.ts +14 -0
- package/dist/interpreter/context.js +15 -0
- package/dist/interpreter/evaluator.d.ts +63 -1
- package/dist/interpreter/evaluator.js +186 -39
- package/dist/interpreter/executor.d.ts +70 -14
- package/dist/interpreter/executor.js +503 -174
- package/dist/interpreter/fetch-handler.d.ts +9 -0
- package/dist/interpreter/fetch-handler.js +133 -24
- package/dist/interpreter/http.d.ts +5 -0
- package/dist/interpreter/http.js +26 -12
- package/dist/interpreter/index.d.ts +3 -1
- package/dist/interpreter/index.js +2 -0
- package/dist/interpreter/pagination.d.ts +11 -2
- package/dist/interpreter/pagination.js +95 -31
- 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 +13 -0
- package/dist/interpreter/step-handlers/for-handler.js +71 -4
- 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 +43 -16
- 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 +11 -1
- package/dist/interpreter/step-handlers/store-handler.js +45 -13
- 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 +4 -2
- package/dist/interpreter/step-handlers/webhook-handler.d.ts +3 -0
- package/dist/interpreter/step-handlers/webhook-handler.js +18 -2
- package/dist/interpreter/store-manager.d.ts +46 -0
- package/dist/interpreter/store-manager.js +66 -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/mcp/index.d.ts +11 -0
- package/dist/mcp/index.js +11 -0
- package/dist/mcp/server.d.ts +17 -0
- package/dist/mcp/server.js +451 -0
- package/dist/oas/index.d.ts +2 -0
- package/dist/oas/index.js +1 -0
- package/dist/oas/mock-generator.d.ts +12 -0
- package/dist/oas/mock-generator.js +187 -0
- package/dist/observability/events.d.ts +244 -0
- package/dist/observability/events.js +90 -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 +259 -0
- package/dist/observability/otel.d.ts +135 -0
- package/dist/observability/otel.js +386 -0
- package/dist/parser/action-parser.d.ts +105 -0
- package/dist/parser/action-parser.js +645 -0
- package/dist/parser/expressions.d.ts +13 -0
- package/dist/parser/expressions.js +72 -2
- package/dist/parser/fetch-parser.d.ts +27 -0
- package/dist/parser/fetch-parser.js +269 -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 +14 -0
- package/dist/pause/index.js +11 -0
- package/dist/pause/manager.d.ts +118 -0
- package/dist/pause/manager.js +245 -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 +156 -0
- package/dist/plugin.d.ts +9 -12
- package/dist/plugin.js +10 -13
- package/dist/stores/factory.d.ts +1 -1
- package/dist/stores/factory.js +3 -2
- package/dist/stores/file.d.ts +26 -0
- package/dist/stores/file.js +64 -10
- 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 +11 -0
- package/dist/stores/types.d.ts +17 -0
- package/dist/stores/types.js +12 -0
- package/dist/trace/index.d.ts +16 -0
- package/dist/trace/index.js +12 -0
- package/dist/trace/recorder.d.ts +71 -0
- package/dist/trace/recorder.js +144 -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 +69 -0
- package/dist/trace/store.js +225 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/type-guards.d.ts +58 -0
- package/dist/utils/type-guards.js +92 -0
- package/dist/webhook/server.js +7 -6
- package/package.json +55 -6
- 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,129 +0,0 @@
|
|
|
1
|
-
// Type definitions for the order reconciliation workflow
|
|
2
|
-
// Temporal requires explicit type definitions for all data structures
|
|
3
|
-
|
|
4
|
-
export interface ShopifyOrder {
|
|
5
|
-
id: string;
|
|
6
|
-
customer: {
|
|
7
|
-
email: string;
|
|
8
|
-
first_name: string;
|
|
9
|
-
last_name: string;
|
|
10
|
-
};
|
|
11
|
-
total_price: string;
|
|
12
|
-
currency: string;
|
|
13
|
-
status: string;
|
|
14
|
-
financial_status: string;
|
|
15
|
-
fulfillment_status: string | null;
|
|
16
|
-
created_at: string;
|
|
17
|
-
updated_at: string;
|
|
18
|
-
line_items: Array<{
|
|
19
|
-
id: string;
|
|
20
|
-
title: string;
|
|
21
|
-
quantity: number;
|
|
22
|
-
price: string;
|
|
23
|
-
}>;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface StripePaymentIntent {
|
|
27
|
-
id: string;
|
|
28
|
-
amount: number;
|
|
29
|
-
currency: string;
|
|
30
|
-
status: string;
|
|
31
|
-
payment_method_types: string[];
|
|
32
|
-
metadata: {
|
|
33
|
-
shopify_order_id?: string;
|
|
34
|
-
};
|
|
35
|
-
charges: {
|
|
36
|
-
data: Array<{
|
|
37
|
-
id: string;
|
|
38
|
-
amount: number;
|
|
39
|
-
amount_refunded: number;
|
|
40
|
-
created: number;
|
|
41
|
-
}>;
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface ShipStationShipment {
|
|
46
|
-
shipmentId: number;
|
|
47
|
-
orderNumber: string;
|
|
48
|
-
carrierCode: string;
|
|
49
|
-
trackingNumber: string | null;
|
|
50
|
-
voided: boolean;
|
|
51
|
-
shipDate: string;
|
|
52
|
-
deliveryDate: string | null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface UnifiedOrder {
|
|
56
|
-
order_id: string;
|
|
57
|
-
external_id: string;
|
|
58
|
-
source: string;
|
|
59
|
-
customer_email: string;
|
|
60
|
-
total_amount: number;
|
|
61
|
-
currency: string;
|
|
62
|
-
status: string;
|
|
63
|
-
created_at: Date;
|
|
64
|
-
line_items_count: number;
|
|
65
|
-
payment_status: string;
|
|
66
|
-
fulfillment_status: string;
|
|
67
|
-
synced_at: Date;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export interface UnifiedPayment {
|
|
71
|
-
payment_id: string;
|
|
72
|
-
order_id: string;
|
|
73
|
-
amount: number;
|
|
74
|
-
currency: string;
|
|
75
|
-
status: string;
|
|
76
|
-
method: string;
|
|
77
|
-
captured_at: Date;
|
|
78
|
-
refunded_amount: number;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export interface UnifiedShipment {
|
|
82
|
-
shipment_id: string;
|
|
83
|
-
order_id: string;
|
|
84
|
-
carrier: string;
|
|
85
|
-
tracking_number: string | null;
|
|
86
|
-
status: string;
|
|
87
|
-
shipped_at: Date;
|
|
88
|
-
delivered_at: Date | null;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export interface Discrepancy {
|
|
92
|
-
id: string;
|
|
93
|
-
order_id: string;
|
|
94
|
-
type: DiscrepancyType;
|
|
95
|
-
severity: Severity;
|
|
96
|
-
description: string;
|
|
97
|
-
shopify_value: string | null;
|
|
98
|
-
stripe_value: string | null;
|
|
99
|
-
shipstation_value: string | null;
|
|
100
|
-
detected_at: Date;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export type DiscrepancyType =
|
|
104
|
-
| 'missing_payment'
|
|
105
|
-
| 'amount_mismatch'
|
|
106
|
-
| 'missing_shipment_record'
|
|
107
|
-
| 'refund_status_mismatch';
|
|
108
|
-
|
|
109
|
-
export type Severity = 'low' | 'medium' | 'high' | 'critical';
|
|
110
|
-
|
|
111
|
-
export interface SyncCheckpoint {
|
|
112
|
-
key: string;
|
|
113
|
-
value: string;
|
|
114
|
-
updated_at: Date;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export interface PaginatedResponse<T> {
|
|
118
|
-
data: T[];
|
|
119
|
-
hasMore: boolean;
|
|
120
|
-
nextCursor?: string;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export interface ReconciliationResult {
|
|
124
|
-
ordersProcessed: number;
|
|
125
|
-
paymentsProcessed: number;
|
|
126
|
-
shipmentsProcessed: number;
|
|
127
|
-
discrepanciesFound: number;
|
|
128
|
-
duration: number;
|
|
129
|
-
}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
// Temporal Worker Setup
|
|
2
|
-
// This is infrastructure code that Reqon doesn't require at all
|
|
3
|
-
// Reqon runs as a simple CLI or library - no workers, no server cluster
|
|
4
|
-
|
|
5
|
-
import { NativeConnection, Worker } from '@temporalio/worker';
|
|
6
|
-
import * as activities from '../activities';
|
|
7
|
-
|
|
8
|
-
// Worker configuration
|
|
9
|
-
const TASK_QUEUE = 'order-reconciliation';
|
|
10
|
-
const TEMPORAL_ADDRESS = process.env.TEMPORAL_ADDRESS || 'localhost:7233';
|
|
11
|
-
const TEMPORAL_NAMESPACE = process.env.TEMPORAL_NAMESPACE || 'default';
|
|
12
|
-
|
|
13
|
-
async function run() {
|
|
14
|
-
console.log('Starting Order Reconciliation Worker...');
|
|
15
|
-
console.log(`Connecting to Temporal at ${TEMPORAL_ADDRESS}`);
|
|
16
|
-
console.log(`Namespace: ${TEMPORAL_NAMESPACE}`);
|
|
17
|
-
|
|
18
|
-
// Connect to Temporal server
|
|
19
|
-
const connection = await NativeConnection.connect({
|
|
20
|
-
address: TEMPORAL_ADDRESS,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
// Create worker
|
|
25
|
-
const worker = await Worker.create({
|
|
26
|
-
connection,
|
|
27
|
-
namespace: TEMPORAL_NAMESPACE,
|
|
28
|
-
taskQueue: TASK_QUEUE,
|
|
29
|
-
workflowsPath: require.resolve('../workflows/orderReconciliation'),
|
|
30
|
-
activities,
|
|
31
|
-
// Worker tuning options
|
|
32
|
-
maxConcurrentWorkflowTaskExecutions: 10,
|
|
33
|
-
maxConcurrentActivityTaskExecutions: 20,
|
|
34
|
-
maxCachedWorkflows: 100,
|
|
35
|
-
// Sticky execution options
|
|
36
|
-
stickyQueueScheduleToStartTimeout: '10s',
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
console.log(`Worker listening on task queue: ${TASK_QUEUE}`);
|
|
40
|
-
|
|
41
|
-
// Register shutdown handlers
|
|
42
|
-
const shutdown = async () => {
|
|
43
|
-
console.log('Shutting down worker...');
|
|
44
|
-
await worker.shutdown();
|
|
45
|
-
await connection.close();
|
|
46
|
-
process.exit(0);
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
process.on('SIGINT', shutdown);
|
|
50
|
-
process.on('SIGTERM', shutdown);
|
|
51
|
-
|
|
52
|
-
// Start the worker
|
|
53
|
-
await worker.run();
|
|
54
|
-
} catch (error) {
|
|
55
|
-
console.error('Worker error:', error);
|
|
56
|
-
await connection.close();
|
|
57
|
-
process.exit(1);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
run().catch((err) => {
|
|
62
|
-
console.error('Fatal error:', err);
|
|
63
|
-
process.exit(1);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
/*
|
|
67
|
-
* INFRASTRUCTURE REQUIREMENTS FOR TEMPORAL:
|
|
68
|
-
*
|
|
69
|
-
* 1. Temporal Server Cluster:
|
|
70
|
-
* - Frontend service (gRPC API)
|
|
71
|
-
* - History service (workflow state)
|
|
72
|
-
* - Matching service (task routing)
|
|
73
|
-
* - Worker service (internal tasks)
|
|
74
|
-
*
|
|
75
|
-
* 2. Database:
|
|
76
|
-
* - PostgreSQL, MySQL, or Cassandra
|
|
77
|
-
* - For workflow history and visibility
|
|
78
|
-
*
|
|
79
|
-
* 3. Elasticsearch (optional):
|
|
80
|
-
* - For advanced workflow search
|
|
81
|
-
*
|
|
82
|
-
* 4. Prometheus + Grafana (recommended):
|
|
83
|
-
* - For metrics and monitoring
|
|
84
|
-
*
|
|
85
|
-
* 5. Docker Compose or Kubernetes:
|
|
86
|
-
* - For orchestrating all services
|
|
87
|
-
*
|
|
88
|
-
* Example docker-compose.yml (simplified):
|
|
89
|
-
*
|
|
90
|
-
* version: '3.8'
|
|
91
|
-
* services:
|
|
92
|
-
* postgresql:
|
|
93
|
-
* image: postgres:13
|
|
94
|
-
* environment:
|
|
95
|
-
* POSTGRES_PASSWORD: temporal
|
|
96
|
-
* POSTGRES_USER: temporal
|
|
97
|
-
* POSTGRES_DB: temporal
|
|
98
|
-
*
|
|
99
|
-
* temporal:
|
|
100
|
-
* image: temporalio/auto-setup:latest
|
|
101
|
-
* depends_on:
|
|
102
|
-
* - postgresql
|
|
103
|
-
* environment:
|
|
104
|
-
* - DB=postgresql
|
|
105
|
-
* - DB_PORT=5432
|
|
106
|
-
* - POSTGRES_USER=temporal
|
|
107
|
-
* - POSTGRES_PWD=temporal
|
|
108
|
-
* - POSTGRES_SEEDS=postgresql
|
|
109
|
-
* ports:
|
|
110
|
-
* - "7233:7233"
|
|
111
|
-
*
|
|
112
|
-
* temporal-admin-tools:
|
|
113
|
-
* image: temporalio/admin-tools:latest
|
|
114
|
-
* depends_on:
|
|
115
|
-
* - temporal
|
|
116
|
-
*
|
|
117
|
-
* temporal-ui:
|
|
118
|
-
* image: temporalio/ui:latest
|
|
119
|
-
* depends_on:
|
|
120
|
-
* - temporal
|
|
121
|
-
* ports:
|
|
122
|
-
* - "8080:8080"
|
|
123
|
-
*
|
|
124
|
-
* COMPARE TO REQON:
|
|
125
|
-
*
|
|
126
|
-
* $ reqon reconciliation.vague --auth ./credentials.json
|
|
127
|
-
*
|
|
128
|
-
* That's it. No infrastructure. No workers. No database setup.
|
|
129
|
-
* Just a single command that runs anywhere Node.js is available.
|
|
130
|
-
*/
|
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
// Order Reconciliation Workflow
|
|
2
|
-
// This is the Temporal equivalent of:
|
|
3
|
-
// run SyncShopifyOrders
|
|
4
|
-
// then SyncStripePayments
|
|
5
|
-
// then SyncShipStationShipments
|
|
6
|
-
// then ValidateReconciliation
|
|
7
|
-
//
|
|
8
|
-
// Notice how much ceremony is required compared to Reqon's declarative approach
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
proxyActivities,
|
|
12
|
-
defineQuery,
|
|
13
|
-
defineSignal,
|
|
14
|
-
setHandler,
|
|
15
|
-
condition,
|
|
16
|
-
sleep,
|
|
17
|
-
workflowInfo,
|
|
18
|
-
ApplicationFailure,
|
|
19
|
-
} from '@temporalio/workflow';
|
|
20
|
-
|
|
21
|
-
import type * as shopifyActivities from '../activities/shopify';
|
|
22
|
-
import type * as stripeActivities from '../activities/stripe';
|
|
23
|
-
import type * as shipstationActivities from '../activities/shipstation';
|
|
24
|
-
import type * as validationActivities from '../activities/validation';
|
|
25
|
-
import type * as storageActivities from '../activities/storage';
|
|
26
|
-
|
|
27
|
-
import {
|
|
28
|
-
shopifyActivityOptions,
|
|
29
|
-
stripeActivityOptions,
|
|
30
|
-
shipStationActivityOptions,
|
|
31
|
-
databaseActivityOptions,
|
|
32
|
-
validationActivityOptions,
|
|
33
|
-
} from '../config/retry';
|
|
34
|
-
|
|
35
|
-
import { ReconciliationResult, UnifiedOrder, UnifiedPayment, UnifiedShipment } from '../types';
|
|
36
|
-
|
|
37
|
-
// Proxy activities with their respective retry policies
|
|
38
|
-
const shopify = proxyActivities<typeof shopifyActivities>(shopifyActivityOptions);
|
|
39
|
-
const stripe = proxyActivities<typeof stripeActivities>(stripeActivityOptions);
|
|
40
|
-
const shipstation = proxyActivities<typeof shipstationActivities>(shipStationActivityOptions);
|
|
41
|
-
const validation = proxyActivities<typeof validationActivities>(validationActivityOptions);
|
|
42
|
-
const storage = proxyActivities<typeof storageActivities>(databaseActivityOptions);
|
|
43
|
-
|
|
44
|
-
// Workflow state
|
|
45
|
-
interface WorkflowState {
|
|
46
|
-
status: 'pending' | 'syncing_shopify' | 'syncing_stripe' | 'syncing_shipstation' | 'validating' | 'completed' | 'failed';
|
|
47
|
-
ordersProcessed: number;
|
|
48
|
-
paymentsProcessed: number;
|
|
49
|
-
shipmentsProcessed: number;
|
|
50
|
-
discrepanciesFound: number;
|
|
51
|
-
error?: string;
|
|
52
|
-
startedAt: Date;
|
|
53
|
-
completedAt?: Date;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Define queries to check workflow status
|
|
57
|
-
export const getStatusQuery = defineQuery<WorkflowState>('getStatus');
|
|
58
|
-
|
|
59
|
-
// Define signals to control workflow
|
|
60
|
-
export const cancelSignal = defineSignal('cancel');
|
|
61
|
-
export const pauseSignal = defineSignal('pause');
|
|
62
|
-
export const resumeSignal = defineSignal('resume');
|
|
63
|
-
|
|
64
|
-
// Main workflow
|
|
65
|
-
export async function orderReconciliationWorkflow(): Promise<ReconciliationResult> {
|
|
66
|
-
const startTime = Date.now();
|
|
67
|
-
let cancelled = false;
|
|
68
|
-
let paused = false;
|
|
69
|
-
|
|
70
|
-
// Initialize workflow state
|
|
71
|
-
const state: WorkflowState = {
|
|
72
|
-
status: 'pending',
|
|
73
|
-
ordersProcessed: 0,
|
|
74
|
-
paymentsProcessed: 0,
|
|
75
|
-
shipmentsProcessed: 0,
|
|
76
|
-
discrepanciesFound: 0,
|
|
77
|
-
startedAt: new Date(),
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
// Set up query handler
|
|
81
|
-
setHandler(getStatusQuery, () => state);
|
|
82
|
-
|
|
83
|
-
// Set up signal handlers
|
|
84
|
-
setHandler(cancelSignal, () => {
|
|
85
|
-
cancelled = true;
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
setHandler(pauseSignal, () => {
|
|
89
|
-
paused = true;
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
setHandler(resumeSignal, () => {
|
|
93
|
-
paused = false;
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
// Helper to check for cancellation/pause
|
|
97
|
-
const checkPauseAndCancel = async () => {
|
|
98
|
-
if (cancelled) {
|
|
99
|
-
throw ApplicationFailure.nonRetryable('Workflow cancelled by user');
|
|
100
|
-
}
|
|
101
|
-
while (paused) {
|
|
102
|
-
await condition(() => !paused || cancelled, '1m');
|
|
103
|
-
if (cancelled) {
|
|
104
|
-
throw ApplicationFailure.nonRetryable('Workflow cancelled by user');
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
try {
|
|
110
|
-
// ========================================
|
|
111
|
-
// STEP 1: Sync Shopify Orders
|
|
112
|
-
// ========================================
|
|
113
|
-
state.status = 'syncing_shopify';
|
|
114
|
-
await checkPauseAndCancel();
|
|
115
|
-
|
|
116
|
-
// Get last sync checkpoint
|
|
117
|
-
const shopifyLastSync = await storage.getCheckpoint('shopify_orders_last_sync');
|
|
118
|
-
|
|
119
|
-
// Fetch all orders (with automatic pagination handled in activity)
|
|
120
|
-
const orders = await shopify.fetchAllShopifyOrders(shopifyLastSync);
|
|
121
|
-
|
|
122
|
-
// Store orders
|
|
123
|
-
state.ordersProcessed = await storage.upsertOrders(orders);
|
|
124
|
-
|
|
125
|
-
// Update checkpoint
|
|
126
|
-
await storage.setCheckpoint('shopify_orders_last_sync', new Date().toISOString());
|
|
127
|
-
|
|
128
|
-
console.log(`Synced ${state.ordersProcessed} Shopify orders`);
|
|
129
|
-
|
|
130
|
-
// ========================================
|
|
131
|
-
// STEP 2: Sync Stripe Payments
|
|
132
|
-
// ========================================
|
|
133
|
-
state.status = 'syncing_stripe';
|
|
134
|
-
await checkPauseAndCancel();
|
|
135
|
-
|
|
136
|
-
// Get last sync checkpoint (as Unix timestamp for Stripe)
|
|
137
|
-
const stripeLastSyncStr = await storage.getCheckpoint('stripe_payments_last_sync');
|
|
138
|
-
const stripeLastSync = stripeLastSyncStr
|
|
139
|
-
? Math.floor(new Date(stripeLastSyncStr).getTime() / 1000)
|
|
140
|
-
: null;
|
|
141
|
-
|
|
142
|
-
// Fetch all payments
|
|
143
|
-
const payments = await stripe.fetchAllStripePayments(stripeLastSync);
|
|
144
|
-
|
|
145
|
-
// Store payments
|
|
146
|
-
state.paymentsProcessed = await storage.upsertPayments(payments);
|
|
147
|
-
|
|
148
|
-
// Update checkpoint
|
|
149
|
-
await storage.setCheckpoint('stripe_payments_last_sync', new Date().toISOString());
|
|
150
|
-
|
|
151
|
-
console.log(`Synced ${state.paymentsProcessed} Stripe payments`);
|
|
152
|
-
|
|
153
|
-
// ========================================
|
|
154
|
-
// STEP 3: Sync ShipStation Shipments
|
|
155
|
-
// ========================================
|
|
156
|
-
state.status = 'syncing_shipstation';
|
|
157
|
-
await checkPauseAndCancel();
|
|
158
|
-
|
|
159
|
-
// Get last sync checkpoint
|
|
160
|
-
const shipstationLastSync = await storage.getCheckpoint('shipstation_last_sync');
|
|
161
|
-
|
|
162
|
-
// Fetch all shipments
|
|
163
|
-
const shipments = await shipstation.fetchAllShipStationShipments(shipstationLastSync);
|
|
164
|
-
|
|
165
|
-
// Store shipments
|
|
166
|
-
state.shipmentsProcessed = await storage.upsertShipments(shipments);
|
|
167
|
-
|
|
168
|
-
// Update checkpoint
|
|
169
|
-
await storage.setCheckpoint('shipstation_last_sync', new Date().toISOString());
|
|
170
|
-
|
|
171
|
-
console.log(`Synced ${state.shipmentsProcessed} ShipStation shipments`);
|
|
172
|
-
|
|
173
|
-
// ========================================
|
|
174
|
-
// STEP 4: Validate and Reconcile
|
|
175
|
-
// ========================================
|
|
176
|
-
state.status = 'validating';
|
|
177
|
-
await checkPauseAndCancel();
|
|
178
|
-
|
|
179
|
-
// Get all data for validation
|
|
180
|
-
const allOrders = await storage.getAllOrders();
|
|
181
|
-
const allPayments = await storage.getAllPayments();
|
|
182
|
-
const allShipments = await storage.getAllShipments();
|
|
183
|
-
|
|
184
|
-
// Run all validations
|
|
185
|
-
const validationResult = await validation.runAllValidations(
|
|
186
|
-
allOrders,
|
|
187
|
-
allPayments,
|
|
188
|
-
allShipments
|
|
189
|
-
);
|
|
190
|
-
|
|
191
|
-
// Store discrepancies
|
|
192
|
-
state.discrepanciesFound = await storage.upsertDiscrepancies(
|
|
193
|
-
validationResult.discrepancies
|
|
194
|
-
);
|
|
195
|
-
|
|
196
|
-
console.log(`Found ${state.discrepanciesFound} discrepancies`);
|
|
197
|
-
|
|
198
|
-
// ========================================
|
|
199
|
-
// Complete
|
|
200
|
-
// ========================================
|
|
201
|
-
state.status = 'completed';
|
|
202
|
-
state.completedAt = new Date();
|
|
203
|
-
|
|
204
|
-
const duration = Date.now() - startTime;
|
|
205
|
-
|
|
206
|
-
return {
|
|
207
|
-
ordersProcessed: state.ordersProcessed,
|
|
208
|
-
paymentsProcessed: state.paymentsProcessed,
|
|
209
|
-
shipmentsProcessed: state.shipmentsProcessed,
|
|
210
|
-
discrepanciesFound: state.discrepanciesFound,
|
|
211
|
-
duration,
|
|
212
|
-
};
|
|
213
|
-
} catch (error) {
|
|
214
|
-
state.status = 'failed';
|
|
215
|
-
state.error = error instanceof Error ? error.message : String(error);
|
|
216
|
-
throw error;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Child workflow for parallel sync (alternative approach)
|
|
221
|
-
export async function parallelSyncWorkflow(): Promise<{
|
|
222
|
-
orders: UnifiedOrder[];
|
|
223
|
-
payments: UnifiedPayment[];
|
|
224
|
-
shipments: UnifiedShipment[];
|
|
225
|
-
}> {
|
|
226
|
-
// Get all checkpoints in parallel
|
|
227
|
-
const [shopifyLastSync, stripeLastSyncStr, shipstationLastSync] =
|
|
228
|
-
await Promise.all([
|
|
229
|
-
storage.getCheckpoint('shopify_orders_last_sync'),
|
|
230
|
-
storage.getCheckpoint('stripe_payments_last_sync'),
|
|
231
|
-
storage.getCheckpoint('shipstation_last_sync'),
|
|
232
|
-
]);
|
|
233
|
-
|
|
234
|
-
const stripeLastSync = stripeLastSyncStr
|
|
235
|
-
? Math.floor(new Date(stripeLastSyncStr).getTime() / 1000)
|
|
236
|
-
: null;
|
|
237
|
-
|
|
238
|
-
// Fetch from all sources in parallel
|
|
239
|
-
// Note: This is more efficient but harder to debug than sequential
|
|
240
|
-
const [orders, payments, shipments] = await Promise.all([
|
|
241
|
-
shopify.fetchAllShopifyOrders(shopifyLastSync),
|
|
242
|
-
stripe.fetchAllStripePayments(stripeLastSync),
|
|
243
|
-
shipstation.fetchAllShipStationShipments(shipstationLastSync),
|
|
244
|
-
]);
|
|
245
|
-
|
|
246
|
-
// Store all in parallel
|
|
247
|
-
await Promise.all([
|
|
248
|
-
storage.upsertOrders(orders),
|
|
249
|
-
storage.upsertPayments(payments),
|
|
250
|
-
storage.upsertShipments(shipments),
|
|
251
|
-
]);
|
|
252
|
-
|
|
253
|
-
// Update all checkpoints
|
|
254
|
-
const now = new Date().toISOString();
|
|
255
|
-
await Promise.all([
|
|
256
|
-
storage.setCheckpoint('shopify_orders_last_sync', now),
|
|
257
|
-
storage.setCheckpoint('stripe_payments_last_sync', now),
|
|
258
|
-
storage.setCheckpoint('shipstation_last_sync', now),
|
|
259
|
-
]);
|
|
260
|
-
|
|
261
|
-
return { orders, payments, shipments };
|
|
262
|
-
}
|
package/examples/xero/README.md
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
# Xero Invoice Sync Example
|
|
2
|
-
|
|
3
|
-
Demonstrates a real-world sync pipeline with OAuth2 authentication, pagination, hydration, normalization, and comprehensive error handling.
|
|
4
|
-
|
|
5
|
-
## What it does
|
|
6
|
-
|
|
7
|
-
1. **FetchInvoiceList**: Fetches paginated invoice summaries with error handling
|
|
8
|
-
2. **HydrateInvoices**: Fetches full details for each invoice, handling individual failures
|
|
9
|
-
3. **RefreshToken**: OAuth token refresh (called via `jump` directive on auth errors)
|
|
10
|
-
4. **NormalizeInvoices**: Maps Xero schema to a vendor-agnostic `StandardInvoice` format
|
|
11
|
-
|
|
12
|
-
## Run
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
node dist/cli.js examples/xero/invoices.vague --auth credentials.json --verbose
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
Requires a `credentials.json`:
|
|
19
|
-
```json
|
|
20
|
-
{
|
|
21
|
-
"Xero": {
|
|
22
|
-
"type": "oauth2",
|
|
23
|
-
"accessToken": "your-xero-access-token"
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Features demonstrated
|
|
29
|
-
|
|
30
|
-
### OAuth2 Authentication
|
|
31
|
-
```vague
|
|
32
|
-
source Xero {
|
|
33
|
-
auth: oauth2,
|
|
34
|
-
base: "https://api.xero.com/api.xro/2.0"
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
### Pagination with Until Condition
|
|
39
|
-
```vague
|
|
40
|
-
get "/Invoices" {
|
|
41
|
-
paginate: offset(page, 100),
|
|
42
|
-
until: length(response.Invoices) == 0
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### Schema Overloading with Match Steps
|
|
47
|
-
Handle different API response types declaratively:
|
|
48
|
-
```vague
|
|
49
|
-
match response {
|
|
50
|
-
XeroInvoiceList -> { store response.Invoices -> cache },
|
|
51
|
-
XeroRateLimitError -> retry { maxAttempts: 5, backoff: exponential },
|
|
52
|
-
XeroUnauthorizedError -> jump RefreshToken then retry,
|
|
53
|
-
_ -> abort "Unexpected response"
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Flow Control Directives
|
|
58
|
-
|
|
59
|
-
| Directive | Usage | Description |
|
|
60
|
-
|-----------|-------|-------------|
|
|
61
|
-
| `continue` | `Schema -> continue` | Proceed to next step |
|
|
62
|
-
| `skip` | `Schema -> skip` | Skip remaining steps in action |
|
|
63
|
-
| `abort` | `Schema -> abort "message"` | Halt mission with error |
|
|
64
|
-
| `retry` | `Schema -> retry { ... }` | Retry with backoff config |
|
|
65
|
-
| `queue` | `Schema -> queue target` | Send to dead-letter queue |
|
|
66
|
-
| `jump` | `Schema -> jump Action then retry` | Execute action, then continue |
|
|
67
|
-
|
|
68
|
-
### Partial Record Hydration
|
|
69
|
-
```vague
|
|
70
|
-
store response.Invoices -> invoices_cache {
|
|
71
|
-
key: .InvoiceID,
|
|
72
|
-
partial: true // Mark as needing hydration
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
for invoice in invoices_cache where ._partial == true {
|
|
76
|
-
// Fetch full details
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Match Expressions for Field Mapping
|
|
81
|
-
```vague
|
|
82
|
-
status: match .Status {
|
|
83
|
-
"PAID" => "paid",
|
|
84
|
-
"AUTHORISED" => "approved",
|
|
85
|
-
"SUBMITTED" => "pending",
|
|
86
|
-
_ => "unknown"
|
|
87
|
-
}
|
|
88
|
-
```
|