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,332 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
sidebar_position: 4
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Stores
|
|
6
|
-
|
|
7
|
-
A **Store** is a named data persistence target. Stores allow you to save, retrieve, update, and query data during mission execution.
|
|
8
|
-
|
|
9
|
-
## Basic Syntax
|
|
10
|
-
|
|
11
|
-
```vague
|
|
12
|
-
store storeName: adapter("identifier")
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Available Adapters
|
|
16
|
-
|
|
17
|
-
| Adapter | Description | Use Case |
|
|
18
|
-
|---------|-------------|----------|
|
|
19
|
-
| `memory` | In-memory storage | Testing, temporary data |
|
|
20
|
-
| `file` | JSON file storage | Local development, small datasets |
|
|
21
|
-
| `sql` | SQL database | Production with PostgreSQL/MySQL |
|
|
22
|
-
| `nosql` | NoSQL database | Production with MongoDB/DynamoDB |
|
|
23
|
-
|
|
24
|
-
## Memory Store
|
|
25
|
-
|
|
26
|
-
In-memory storage that doesn't persist between runs:
|
|
27
|
-
|
|
28
|
-
```vague
|
|
29
|
-
store cache: memory("cache")
|
|
30
|
-
store tempData: memory("temp")
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Best for:
|
|
34
|
-
- Testing
|
|
35
|
-
- Temporary processing data
|
|
36
|
-
- Intermediate results
|
|
37
|
-
|
|
38
|
-
## File Store
|
|
39
|
-
|
|
40
|
-
JSON file storage in the `.vague-data` directory:
|
|
41
|
-
|
|
42
|
-
```vague
|
|
43
|
-
store customers: file("customers")
|
|
44
|
-
store orders: file("orders")
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Creates files like:
|
|
48
|
-
```
|
|
49
|
-
.vague-data/
|
|
50
|
-
├── customers.json
|
|
51
|
-
└── orders.json
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Best for:
|
|
55
|
-
- Local development
|
|
56
|
-
- Small to medium datasets
|
|
57
|
-
- Simple persistence without database setup
|
|
58
|
-
|
|
59
|
-
## SQL Store
|
|
60
|
-
|
|
61
|
-
SQL database storage via PostgREST or direct connection:
|
|
62
|
-
|
|
63
|
-
```vague
|
|
64
|
-
store customers: sql("customers_table")
|
|
65
|
-
store orders: sql("orders")
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Requires configuration:
|
|
69
|
-
|
|
70
|
-
```json
|
|
71
|
-
{
|
|
72
|
-
"stores": {
|
|
73
|
-
"sql": {
|
|
74
|
-
"type": "postgrest",
|
|
75
|
-
"url": "https://your-project.supabase.co/rest/v1",
|
|
76
|
-
"apiKey": "your-anon-key"
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
See [PostgREST Store](../stores/postgrest) for details.
|
|
83
|
-
|
|
84
|
-
## NoSQL Store
|
|
85
|
-
|
|
86
|
-
NoSQL database storage:
|
|
87
|
-
|
|
88
|
-
```vague
|
|
89
|
-
store events: nosql("events_collection")
|
|
90
|
-
store logs: nosql("activity_logs")
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
Currently falls back to file storage in development. Full MongoDB/DynamoDB support planned.
|
|
94
|
-
|
|
95
|
-
## Store Operations
|
|
96
|
-
|
|
97
|
-
### Writing Data
|
|
98
|
-
|
|
99
|
-
```vague
|
|
100
|
-
action SaveData {
|
|
101
|
-
get "/users"
|
|
102
|
-
|
|
103
|
-
// Store entire response
|
|
104
|
-
store response -> users
|
|
105
|
-
|
|
106
|
-
// Store with key for indexed access
|
|
107
|
-
store response -> users { key: .id }
|
|
108
|
-
|
|
109
|
-
// Store nested data
|
|
110
|
-
store response.data.items -> items { key: .itemId }
|
|
111
|
-
}
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### Key Option
|
|
115
|
-
|
|
116
|
-
The `key` option specifies which field to use as the unique identifier:
|
|
117
|
-
|
|
118
|
-
```vague
|
|
119
|
-
store response -> users { key: .id }
|
|
120
|
-
store response -> users { key: .email }
|
|
121
|
-
store response -> users { key: concat(.orgId, "-", .userId) }
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
### Upsert Mode
|
|
125
|
-
|
|
126
|
-
Insert or update based on key:
|
|
127
|
-
|
|
128
|
-
```vague
|
|
129
|
-
store response -> users {
|
|
130
|
-
key: .id,
|
|
131
|
-
upsert: true
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Partial Updates
|
|
136
|
-
|
|
137
|
-
Update only provided fields:
|
|
138
|
-
|
|
139
|
-
```vague
|
|
140
|
-
store response -> users {
|
|
141
|
-
key: .id,
|
|
142
|
-
partial: true
|
|
143
|
-
}
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## Reading From Stores
|
|
147
|
-
|
|
148
|
-
Stores are available as variables in actions:
|
|
149
|
-
|
|
150
|
-
```vague
|
|
151
|
-
action ProcessStoredData {
|
|
152
|
-
// Iterate over store contents
|
|
153
|
-
for user in users {
|
|
154
|
-
// Access user data
|
|
155
|
-
get "/orders" { params: { userId: user.id } }
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// With filtering
|
|
159
|
-
for user in users where .status == "active" {
|
|
160
|
-
// Process active users only
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
## Store Interface
|
|
166
|
-
|
|
167
|
-
Stores implement this interface:
|
|
168
|
-
|
|
169
|
-
```typescript
|
|
170
|
-
interface StoreAdapter {
|
|
171
|
-
// Get single record by key
|
|
172
|
-
get(key: string): Promise<Record | null>
|
|
173
|
-
|
|
174
|
-
// Set record with key
|
|
175
|
-
set(key: string, value: Record): Promise<void>
|
|
176
|
-
|
|
177
|
-
// Update record (partial)
|
|
178
|
-
update(key: string, partial: Record): Promise<void>
|
|
179
|
-
|
|
180
|
-
// Delete record
|
|
181
|
-
delete(key: string): Promise<void>
|
|
182
|
-
|
|
183
|
-
// List all records with optional filter
|
|
184
|
-
list(filter?: FilterOptions): Promise<Record[]>
|
|
185
|
-
|
|
186
|
-
// Clear all records
|
|
187
|
-
clear(): Promise<void>
|
|
188
|
-
}
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
## Filtering Store Data
|
|
192
|
-
|
|
193
|
-
Use `where` clauses when iterating:
|
|
194
|
-
|
|
195
|
-
```vague
|
|
196
|
-
action ProcessFiltered {
|
|
197
|
-
// Status filter
|
|
198
|
-
for order in orders where .status == "pending" {
|
|
199
|
-
// Process pending orders
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Multiple conditions
|
|
203
|
-
for user in users where .active == true and .role == "admin" {
|
|
204
|
-
// Process active admins
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// Comparison
|
|
208
|
-
for product in products where .price > 100 {
|
|
209
|
-
// Process expensive products
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
## Store Aggregations
|
|
215
|
-
|
|
216
|
-
Access store metadata:
|
|
217
|
-
|
|
218
|
-
```vague
|
|
219
|
-
action CheckStore {
|
|
220
|
-
// Get count
|
|
221
|
-
validate {
|
|
222
|
-
assume length(users) > 0
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Check if empty
|
|
226
|
-
match users {
|
|
227
|
-
[] -> abort "No users found",
|
|
228
|
-
_ -> continue
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
## Cross-Store Operations
|
|
234
|
-
|
|
235
|
-
Reference multiple stores:
|
|
236
|
-
|
|
237
|
-
```vague
|
|
238
|
-
action Reconcile {
|
|
239
|
-
for order in orders {
|
|
240
|
-
// Look up related customer
|
|
241
|
-
for customer in customers where .id == order.customerId {
|
|
242
|
-
map order -> EnrichedOrder {
|
|
243
|
-
id: order.id,
|
|
244
|
-
amount: order.amount,
|
|
245
|
-
customerName: customer.name,
|
|
246
|
-
customerEmail: customer.email
|
|
247
|
-
}
|
|
248
|
-
store order -> enrichedOrders { key: .id }
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
## Best Practices
|
|
255
|
-
|
|
256
|
-
### Use Appropriate Adapters
|
|
257
|
-
|
|
258
|
-
```vague
|
|
259
|
-
// Development
|
|
260
|
-
store data: file("data")
|
|
261
|
-
|
|
262
|
-
// Production
|
|
263
|
-
store data: sql("data_table")
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### Always Specify Keys
|
|
267
|
-
|
|
268
|
-
```vague
|
|
269
|
-
// Good: explicit key
|
|
270
|
-
store response -> users { key: .id }
|
|
271
|
-
|
|
272
|
-
// Avoid: no key (uses auto-generated)
|
|
273
|
-
store response -> users
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
### Use Upsert for Sync Operations
|
|
277
|
-
|
|
278
|
-
```vague
|
|
279
|
-
action IncrementalSync {
|
|
280
|
-
get "/users" { since: lastSync }
|
|
281
|
-
|
|
282
|
-
for user in response {
|
|
283
|
-
store user -> users { key: .id, upsert: true }
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
### Clean Up Temporary Stores
|
|
289
|
-
|
|
290
|
-
```vague
|
|
291
|
-
mission CleanPipeline {
|
|
292
|
-
store temp: memory("temp")
|
|
293
|
-
|
|
294
|
-
action Process {
|
|
295
|
-
// Use temp store
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// Temp store is automatically cleaned when mission ends
|
|
299
|
-
}
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
### Use Descriptive Store Names
|
|
303
|
-
|
|
304
|
-
```vague
|
|
305
|
-
// Good
|
|
306
|
-
store activeCustomers: file("active-customers")
|
|
307
|
-
store pendingOrders: file("pending-orders")
|
|
308
|
-
store syncedInvoices: file("synced-invoices")
|
|
309
|
-
|
|
310
|
-
// Avoid
|
|
311
|
-
store data: file("data")
|
|
312
|
-
store temp: file("temp")
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
## Exporting Store Data
|
|
316
|
-
|
|
317
|
-
Use the CLI to export stores after execution:
|
|
318
|
-
|
|
319
|
-
```bash
|
|
320
|
-
reqon mission.vague --output ./exports/
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
Or programmatically:
|
|
324
|
-
|
|
325
|
-
```typescript
|
|
326
|
-
const result = await execute(source);
|
|
327
|
-
|
|
328
|
-
for (const [name, store] of result.stores) {
|
|
329
|
-
const data = await store.list();
|
|
330
|
-
fs.writeFileSync(`${name}.json`, JSON.stringify(data, null, 2));
|
|
331
|
-
}
|
|
332
|
-
```
|
|
@@ -1,361 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
sidebar_position: 7
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Expressions
|
|
6
|
-
|
|
7
|
-
Reqon uses the Vague expression language for data manipulation. This page covers the most common expressions; for complete documentation, see the [Vague documentation](https://github.com/mcclowes/vague).
|
|
8
|
-
|
|
9
|
-
## Literals
|
|
10
|
-
|
|
11
|
-
```vague
|
|
12
|
-
// Numbers
|
|
13
|
-
42
|
|
14
|
-
3.14
|
|
15
|
-
-100
|
|
16
|
-
|
|
17
|
-
// Strings
|
|
18
|
-
"hello world"
|
|
19
|
-
'single quotes also work'
|
|
20
|
-
|
|
21
|
-
// Booleans
|
|
22
|
-
true
|
|
23
|
-
false
|
|
24
|
-
|
|
25
|
-
// Null
|
|
26
|
-
null
|
|
27
|
-
|
|
28
|
-
// Arrays
|
|
29
|
-
[1, 2, 3]
|
|
30
|
-
["a", "b", "c"]
|
|
31
|
-
|
|
32
|
-
// Objects
|
|
33
|
-
{ key: "value", nested: { a: 1 } }
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Property Access
|
|
37
|
-
|
|
38
|
-
```vague
|
|
39
|
-
// Dot notation
|
|
40
|
-
.name
|
|
41
|
-
.address.city
|
|
42
|
-
.items[0].name
|
|
43
|
-
|
|
44
|
-
// Within context
|
|
45
|
-
user.name
|
|
46
|
-
response.data.items
|
|
47
|
-
|
|
48
|
-
// Array indexing
|
|
49
|
-
.items[0]
|
|
50
|
-
.items[length(.items) - 1]
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Operators
|
|
54
|
-
|
|
55
|
-
### Arithmetic
|
|
56
|
-
|
|
57
|
-
```vague
|
|
58
|
-
1 + 2 // 3
|
|
59
|
-
10 - 3 // 7
|
|
60
|
-
4 * 5 // 20
|
|
61
|
-
20 / 4 // 5
|
|
62
|
-
10 % 3 // 1 (modulo)
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### Comparison
|
|
66
|
-
|
|
67
|
-
```vague
|
|
68
|
-
.a == .b // equality
|
|
69
|
-
.a != .b // inequality
|
|
70
|
-
.a > .b // greater than
|
|
71
|
-
.a >= .b // greater or equal
|
|
72
|
-
.a < .b // less than
|
|
73
|
-
.a <= .b // less or equal
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### Logical
|
|
77
|
-
|
|
78
|
-
```vague
|
|
79
|
-
.a and .b // logical AND
|
|
80
|
-
.a or .b // logical OR
|
|
81
|
-
not .a // logical NOT
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### String
|
|
85
|
-
|
|
86
|
-
```vague
|
|
87
|
-
.first + " " + .last // concatenation
|
|
88
|
-
.email contains "@" // contains check
|
|
89
|
-
.name startsWith "Dr." // prefix check
|
|
90
|
-
.file endsWith ".pdf" // suffix check
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
## Conditional Expressions
|
|
94
|
-
|
|
95
|
-
### If-Then-Else
|
|
96
|
-
|
|
97
|
-
```vague
|
|
98
|
-
if .active then "Active" else "Inactive"
|
|
99
|
-
|
|
100
|
-
if .age >= 18 then "Adult"
|
|
101
|
-
else if .age >= 13 then "Teen"
|
|
102
|
-
else "Child"
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### Ternary Style
|
|
106
|
-
|
|
107
|
-
```vague
|
|
108
|
-
.status == "active" ? "Yes" : "No"
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
### Null Coalescing
|
|
112
|
-
|
|
113
|
-
```vague
|
|
114
|
-
.name or "Unknown"
|
|
115
|
-
.email or .backup_email or "no-email@example.com"
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
## String Functions
|
|
119
|
-
|
|
120
|
-
```vague
|
|
121
|
-
// Length
|
|
122
|
-
length("hello") // 5
|
|
123
|
-
|
|
124
|
-
// Case conversion
|
|
125
|
-
lowercase("HELLO") // "hello"
|
|
126
|
-
uppercase("hello") // "HELLO"
|
|
127
|
-
|
|
128
|
-
// Substring
|
|
129
|
-
substring("hello", 0, 2) // "he"
|
|
130
|
-
substring("hello", 2) // "llo"
|
|
131
|
-
|
|
132
|
-
// Split and join
|
|
133
|
-
split("a,b,c", ",") // ["a", "b", "c"]
|
|
134
|
-
join(["a", "b"], "-") // "a-b"
|
|
135
|
-
|
|
136
|
-
// Trim
|
|
137
|
-
trim(" hello ") // "hello"
|
|
138
|
-
trimStart(" hello") // "hello"
|
|
139
|
-
trimEnd("hello ") // "hello"
|
|
140
|
-
|
|
141
|
-
// Replace
|
|
142
|
-
replace("hello", "l", "L") // "heLLo"
|
|
143
|
-
|
|
144
|
-
// Concatenation
|
|
145
|
-
concat("Hello", " ", "World") // "Hello World"
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## Array Functions
|
|
149
|
-
|
|
150
|
-
```vague
|
|
151
|
-
// Length
|
|
152
|
-
length([1, 2, 3]) // 3
|
|
153
|
-
|
|
154
|
-
// Access
|
|
155
|
-
first([1, 2, 3]) // 1
|
|
156
|
-
last([1, 2, 3]) // 3
|
|
157
|
-
|
|
158
|
-
// Check contents
|
|
159
|
-
includes([1, 2, 3], 2) // true
|
|
160
|
-
isEmpty([]) // true
|
|
161
|
-
|
|
162
|
-
// Transform
|
|
163
|
-
map([1, 2, 3], x => x * 2) // [2, 4, 6]
|
|
164
|
-
filter([1, 2, 3], x => x > 1) // [2, 3]
|
|
165
|
-
reduce([1, 2, 3], (a, b) => a + b, 0) // 6
|
|
166
|
-
|
|
167
|
-
// Aggregate
|
|
168
|
-
sum([1, 2, 3]) // 6
|
|
169
|
-
min([1, 2, 3]) // 1
|
|
170
|
-
max([1, 2, 3]) // 3
|
|
171
|
-
avg([1, 2, 3]) // 2
|
|
172
|
-
|
|
173
|
-
// Combine
|
|
174
|
-
concat([1, 2], [3, 4]) // [1, 2, 3, 4]
|
|
175
|
-
flatten([[1, 2], [3]]) // [1, 2, 3]
|
|
176
|
-
unique([1, 1, 2, 2]) // [1, 2]
|
|
177
|
-
|
|
178
|
-
// Sort
|
|
179
|
-
sort([3, 1, 2]) // [1, 2, 3]
|
|
180
|
-
sortBy(items, .name) // sorted by name field
|
|
181
|
-
|
|
182
|
-
// Find
|
|
183
|
-
find(items, .id == "123") // first match
|
|
184
|
-
findIndex(items, .id == "123") // index of first match
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
## Object Functions
|
|
188
|
-
|
|
189
|
-
```vague
|
|
190
|
-
// Get keys/values
|
|
191
|
-
keys({ a: 1, b: 2 }) // ["a", "b"]
|
|
192
|
-
values({ a: 1, b: 2 }) // [1, 2]
|
|
193
|
-
entries({ a: 1 }) // [["a", 1]]
|
|
194
|
-
|
|
195
|
-
// Check
|
|
196
|
-
hasKey({ a: 1 }, "a") // true
|
|
197
|
-
|
|
198
|
-
// Transform
|
|
199
|
-
pick({ a: 1, b: 2 }, ["a"]) // { a: 1 }
|
|
200
|
-
omit({ a: 1, b: 2 }, ["b"]) // { a: 1 }
|
|
201
|
-
merge({ a: 1 }, { b: 2 }) // { a: 1, b: 2 }
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
## Numeric Functions
|
|
205
|
-
|
|
206
|
-
```vague
|
|
207
|
-
// Rounding
|
|
208
|
-
round(3.7) // 4
|
|
209
|
-
round(3.14159, 2) // 3.14
|
|
210
|
-
floor(3.7) // 3
|
|
211
|
-
ceil(3.2) // 4
|
|
212
|
-
|
|
213
|
-
// Math
|
|
214
|
-
abs(-5) // 5
|
|
215
|
-
min(1, 2, 3) // 1
|
|
216
|
-
max(1, 2, 3) // 3
|
|
217
|
-
pow(2, 3) // 8
|
|
218
|
-
sqrt(16) // 4
|
|
219
|
-
|
|
220
|
-
// Conversion
|
|
221
|
-
toNumber("42") // 42
|
|
222
|
-
toString(42) // "42"
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
## Date Functions
|
|
226
|
-
|
|
227
|
-
```vague
|
|
228
|
-
// Current time
|
|
229
|
-
now()
|
|
230
|
-
|
|
231
|
-
// Parsing
|
|
232
|
-
parseDate("2024-01-20")
|
|
233
|
-
parseDate("2024-01-20T10:30:00Z")
|
|
234
|
-
|
|
235
|
-
// Formatting
|
|
236
|
-
formatDate(now(), "YYYY-MM-DD")
|
|
237
|
-
formatDate(now(), "MMM D, YYYY")
|
|
238
|
-
|
|
239
|
-
// Components
|
|
240
|
-
year(now()) // 2024
|
|
241
|
-
month(now()) // 1-12
|
|
242
|
-
day(now()) // 1-31
|
|
243
|
-
hour(now()) // 0-23
|
|
244
|
-
minute(now()) // 0-59
|
|
245
|
-
|
|
246
|
-
// Manipulation
|
|
247
|
-
addDays(now(), 7)
|
|
248
|
-
addMonths(now(), 1)
|
|
249
|
-
subtractDays(now(), 30)
|
|
250
|
-
|
|
251
|
-
// Comparison
|
|
252
|
-
diffDays(date1, date2)
|
|
253
|
-
isBefore(date1, date2)
|
|
254
|
-
isAfter(date1, date2)
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
## Type Functions
|
|
258
|
-
|
|
259
|
-
```vague
|
|
260
|
-
// Type checking
|
|
261
|
-
.value is string
|
|
262
|
-
.value is number
|
|
263
|
-
.value is boolean
|
|
264
|
-
.value is array
|
|
265
|
-
.value is object
|
|
266
|
-
.value is null
|
|
267
|
-
|
|
268
|
-
// Type conversion
|
|
269
|
-
toString(123) // "123"
|
|
270
|
-
toNumber("42") // 42
|
|
271
|
-
toBoolean(1) // true
|
|
272
|
-
toArray("a") // ["a"]
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
## Environment Variables
|
|
276
|
-
|
|
277
|
-
```vague
|
|
278
|
-
env("API_KEY")
|
|
279
|
-
env("BASE_URL")
|
|
280
|
-
env("DEBUG") == "true"
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
## Pattern Matching in Expressions
|
|
284
|
-
|
|
285
|
-
```vague
|
|
286
|
-
match .status {
|
|
287
|
-
"active" => "Active User",
|
|
288
|
-
"pending" => "Pending Approval",
|
|
289
|
-
"inactive" => "Deactivated",
|
|
290
|
-
_ => "Unknown Status"
|
|
291
|
-
}
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
## Complex Expression Examples
|
|
295
|
-
|
|
296
|
-
### Data Transformation
|
|
297
|
-
|
|
298
|
-
```vague
|
|
299
|
-
map user -> Output {
|
|
300
|
-
fullName: concat(.firstName, " ", .lastName),
|
|
301
|
-
email: lowercase(.email),
|
|
302
|
-
age: year(now()) - year(.birthDate),
|
|
303
|
-
isAdult: year(now()) - year(.birthDate) >= 18,
|
|
304
|
-
displayName: if .nickname then .nickname else .firstName,
|
|
305
|
-
initials: concat(
|
|
306
|
-
substring(.firstName, 0, 1),
|
|
307
|
-
substring(.lastName, 0, 1)
|
|
308
|
-
)
|
|
309
|
-
}
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
### Aggregation
|
|
313
|
-
|
|
314
|
-
```vague
|
|
315
|
-
map orders -> Summary {
|
|
316
|
-
totalOrders: length(orders),
|
|
317
|
-
totalRevenue: sum(orders.map(.total)),
|
|
318
|
-
avgOrderValue: sum(orders.map(.total)) / length(orders),
|
|
319
|
-
maxOrder: max(orders.map(.total)),
|
|
320
|
-
pendingCount: length(filter(orders, .status == "pending")),
|
|
321
|
-
completedRate: length(filter(orders, .status == "completed")) / length(orders) * 100
|
|
322
|
-
}
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
### Conditional Logic
|
|
326
|
-
|
|
327
|
-
```vague
|
|
328
|
-
map order -> PricedOrder {
|
|
329
|
-
...order,
|
|
330
|
-
discount: match .customerTier {
|
|
331
|
-
"gold" => 0.20,
|
|
332
|
-
"silver" => 0.10,
|
|
333
|
-
"bronze" => 0.05,
|
|
334
|
-
_ => 0
|
|
335
|
-
},
|
|
336
|
-
discountedTotal: .total * (1 - match .customerTier {
|
|
337
|
-
"gold" => 0.20,
|
|
338
|
-
"silver" => 0.10,
|
|
339
|
-
"bronze" => 0.05,
|
|
340
|
-
_ => 0
|
|
341
|
-
}),
|
|
342
|
-
shippingFee: if .total > 100 then 0 else 9.99,
|
|
343
|
-
finalTotal: .total * (1 - if .customerTier == "gold" then 0.20 else 0) +
|
|
344
|
-
(if .total > 100 then 0 else 9.99)
|
|
345
|
-
}
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
### Validation Conditions
|
|
349
|
-
|
|
350
|
-
```vague
|
|
351
|
-
validate order {
|
|
352
|
-
assume .id is string,
|
|
353
|
-
assume length(.items) > 0,
|
|
354
|
-
assume sum(.items.map(.quantity)) > 0,
|
|
355
|
-
assume .total == sum(.items.map(.price * .quantity)),
|
|
356
|
-
assume .createdAt <= now(),
|
|
357
|
-
assume .shippingDate == null or .shippingDate >= .createdAt
|
|
358
|
-
}
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
For the complete expression language reference, visit the [Vague documentation](https://github.com/mcclowes/vague).
|