reqon-dsl 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +31 -0
- package/.claude/skills/api-integration.md +125 -0
- package/.claude/skills/database-schema.md +51 -0
- package/.claude/skills/dsl-design.md +80 -0
- package/.claude/skills/property-testing.md +143 -0
- package/.claude/skills/reqon/SKILL.md +44 -0
- package/.claude/skills/reqon/references/examples.md +206 -0
- package/.claude/skills/reqon/references/syntax.md +263 -0
- package/.claude/skills/vscode-extension.md +113 -0
- package/.github/dependabot.yml +32 -0
- package/.github/pull_request_template.md +21 -0
- package/.github/workflows/ci.yml +174 -0
- package/.github/workflows/release.yml +73 -0
- package/CLAUDE.md +72 -0
- package/CONTRIBUTING.md +161 -0
- package/README.md +235 -0
- package/TODO.md +51 -0
- package/dist/ast/index.d.ts +1 -0
- package/dist/ast/index.js +1 -0
- package/dist/ast/nodes.d.ts +237 -0
- package/dist/ast/nodes.js +12 -0
- package/dist/auth/auth.test.d.ts +1 -0
- package/dist/auth/auth.test.js +255 -0
- package/dist/auth/circuit-breaker.d.ts +115 -0
- package/dist/auth/circuit-breaker.js +267 -0
- package/dist/auth/credentials.d.ts +91 -0
- package/dist/auth/credentials.js +169 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.js +8 -0
- package/dist/auth/oauth2-provider.d.ts +41 -0
- package/dist/auth/oauth2-provider.js +131 -0
- package/dist/auth/rate-limiter.d.ts +61 -0
- package/dist/auth/rate-limiter.js +380 -0
- package/dist/auth/token-store.d.ts +30 -0
- package/dist/auth/token-store.js +148 -0
- package/dist/auth/types.d.ts +142 -0
- package/dist/auth/types.js +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +270 -0
- package/dist/errors/errors.test.d.ts +1 -0
- package/dist/errors/errors.test.js +165 -0
- package/dist/errors/index.d.ts +83 -0
- package/dist/errors/index.js +159 -0
- package/dist/execution/execution.test.d.ts +1 -0
- package/dist/execution/execution.test.js +246 -0
- package/dist/execution/index.d.ts +4 -0
- package/dist/execution/index.js +2 -0
- package/dist/execution/state.d.ts +136 -0
- package/dist/execution/state.js +82 -0
- package/dist/execution/store.d.ts +52 -0
- package/dist/execution/store.js +120 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +57 -0
- package/dist/integration.test.d.ts +1 -0
- package/dist/integration.test.js +168 -0
- package/dist/interpreter/context.d.ts +15 -0
- package/dist/interpreter/context.js +29 -0
- package/dist/interpreter/evaluator.d.ts +5 -0
- package/dist/interpreter/evaluator.js +223 -0
- package/dist/interpreter/evaluator.test.d.ts +1 -0
- package/dist/interpreter/evaluator.test.js +512 -0
- package/dist/interpreter/executor.d.ts +131 -0
- package/dist/interpreter/executor.js +663 -0
- package/dist/interpreter/fetch-handler.d.ts +43 -0
- package/dist/interpreter/fetch-handler.js +203 -0
- package/dist/interpreter/http.d.ts +57 -0
- package/dist/interpreter/http.js +210 -0
- package/dist/interpreter/http.test.d.ts +1 -0
- package/dist/interpreter/http.test.js +299 -0
- package/dist/interpreter/index.d.ts +7 -0
- package/dist/interpreter/index.js +7 -0
- package/dist/interpreter/pagination.d.ts +63 -0
- package/dist/interpreter/pagination.js +155 -0
- package/dist/interpreter/progress.test.d.ts +1 -0
- package/dist/interpreter/progress.test.js +216 -0
- package/dist/interpreter/schema-matcher.d.ts +16 -0
- package/dist/interpreter/schema-matcher.js +136 -0
- package/dist/interpreter/schema-matcher.test.d.ts +1 -0
- package/dist/interpreter/schema-matcher.test.js +122 -0
- package/dist/interpreter/signals.d.ts +57 -0
- package/dist/interpreter/signals.js +73 -0
- package/dist/interpreter/step-handlers/for-handler.d.ts +17 -0
- package/dist/interpreter/step-handlers/for-handler.js +51 -0
- package/dist/interpreter/step-handlers/index.d.ts +8 -0
- package/dist/interpreter/step-handlers/index.js +8 -0
- package/dist/interpreter/step-handlers/map-handler.d.ts +10 -0
- package/dist/interpreter/step-handlers/map-handler.js +20 -0
- package/dist/interpreter/step-handlers/match-handler.d.ts +27 -0
- package/dist/interpreter/step-handlers/match-handler.js +61 -0
- package/dist/interpreter/step-handlers/store-handler.d.ts +13 -0
- package/dist/interpreter/step-handlers/store-handler.js +66 -0
- package/dist/interpreter/step-handlers/types.d.ts +15 -0
- package/dist/interpreter/step-handlers/types.js +1 -0
- package/dist/interpreter/step-handlers/validate-handler.d.ts +10 -0
- package/dist/interpreter/step-handlers/validate-handler.js +26 -0
- package/dist/interpreter/step-handlers/webhook-handler.d.ts +36 -0
- package/dist/interpreter/step-handlers/webhook-handler.js +104 -0
- package/dist/lexer/index.d.ts +10 -0
- package/dist/lexer/index.js +12 -0
- package/dist/lexer/lexer.d.ts +24 -0
- package/dist/lexer/lexer.js +264 -0
- package/dist/lexer/lexer.test.d.ts +1 -0
- package/dist/lexer/lexer.test.js +259 -0
- package/dist/lexer/tokens.d.ts +69 -0
- package/dist/lexer/tokens.js +146 -0
- package/dist/loader/index.d.ts +36 -0
- package/dist/loader/index.js +220 -0
- package/dist/loader/loader.test.d.ts +1 -0
- package/dist/loader/loader.test.js +287 -0
- package/dist/oas/index.d.ts +4 -0
- package/dist/oas/index.js +2 -0
- package/dist/oas/loader.d.ts +21 -0
- package/dist/oas/loader.js +82 -0
- package/dist/oas/oas.test.d.ts +1 -0
- package/dist/oas/oas.test.js +218 -0
- package/dist/oas/validator.d.ts +12 -0
- package/dist/oas/validator.js +227 -0
- package/dist/parser/base.d.ts +33 -0
- package/dist/parser/base.js +97 -0
- package/dist/parser/expressions.d.ts +27 -0
- package/dist/parser/expressions.js +248 -0
- package/dist/parser/expressions.test.d.ts +1 -0
- package/dist/parser/expressions.test.js +378 -0
- package/dist/parser/index.d.ts +3 -0
- package/dist/parser/index.js +3 -0
- package/dist/parser/match.test.d.ts +1 -0
- package/dist/parser/match.test.js +254 -0
- package/dist/parser/parser.d.ts +68 -0
- package/dist/parser/parser.js +1229 -0
- package/dist/parser/parser.test.d.ts +1 -0
- package/dist/parser/parser.test.js +333 -0
- package/dist/parser/schedule.test.d.ts +1 -0
- package/dist/parser/schedule.test.js +241 -0
- package/dist/plugin.d.ts +35 -0
- package/dist/plugin.js +68 -0
- package/dist/scheduler/cron-parser.d.ts +32 -0
- package/dist/scheduler/cron-parser.js +198 -0
- package/dist/scheduler/cron-parser.test.d.ts +1 -0
- package/dist/scheduler/cron-parser.test.js +188 -0
- package/dist/scheduler/index.d.ts +3 -0
- package/dist/scheduler/index.js +2 -0
- package/dist/scheduler/scheduler.d.ts +81 -0
- package/dist/scheduler/scheduler.js +376 -0
- package/dist/scheduler/types.d.ts +65 -0
- package/dist/scheduler/types.js +1 -0
- package/dist/stores/factory.d.ts +36 -0
- package/dist/stores/factory.js +73 -0
- package/dist/stores/file.d.ts +60 -0
- package/dist/stores/file.js +173 -0
- package/dist/stores/file.test.d.ts +1 -0
- package/dist/stores/file.test.js +165 -0
- package/dist/stores/index.d.ts +6 -0
- package/dist/stores/index.js +5 -0
- package/dist/stores/memory.d.ts +19 -0
- package/dist/stores/memory.js +51 -0
- package/dist/stores/memory.test.d.ts +1 -0
- package/dist/stores/memory.test.js +157 -0
- package/dist/stores/postgrest.d.ts +55 -0
- package/dist/stores/postgrest.js +217 -0
- package/dist/stores/stores.test.d.ts +1 -0
- package/dist/stores/stores.test.js +158 -0
- package/dist/stores/types.d.ts +31 -0
- package/dist/stores/types.js +26 -0
- package/dist/sync/index.d.ts +4 -0
- package/dist/sync/index.js +2 -0
- package/dist/sync/state.d.ts +69 -0
- package/dist/sync/state.js +66 -0
- package/dist/sync/store.d.ts +49 -0
- package/dist/sync/store.js +93 -0
- package/dist/sync/sync.test.d.ts +1 -0
- package/dist/sync/sync.test.js +221 -0
- package/dist/utils/async.d.ts +7 -0
- package/dist/utils/async.js +9 -0
- package/dist/utils/file.d.ts +38 -0
- package/dist/utils/file.js +92 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/logger.d.ts +34 -0
- package/dist/utils/logger.js +39 -0
- package/dist/utils/path.d.ts +12 -0
- package/dist/utils/path.js +41 -0
- package/dist/webhook/index.d.ts +8 -0
- package/dist/webhook/index.js +7 -0
- package/dist/webhook/server.d.ts +84 -0
- package/dist/webhook/server.js +319 -0
- package/dist/webhook/store.d.ts +67 -0
- package/dist/webhook/store.js +193 -0
- package/dist/webhook/types.d.ts +88 -0
- package/dist/webhook/types.js +6 -0
- package/docusaurus/README.md +41 -0
- package/docusaurus/docs/advanced/execution-state.md +283 -0
- package/docusaurus/docs/advanced/extending-reqon.md +388 -0
- package/docusaurus/docs/advanced/multi-file-missions.md +250 -0
- package/docusaurus/docs/advanced/parallel-execution.md +353 -0
- package/docusaurus/docs/api-reference.md +443 -0
- package/docusaurus/docs/authentication/api-key.md +339 -0
- package/docusaurus/docs/authentication/basic.md +276 -0
- package/docusaurus/docs/authentication/bearer.md +282 -0
- package/docusaurus/docs/authentication/oauth2.md +317 -0
- package/docusaurus/docs/authentication/overview.md +251 -0
- package/docusaurus/docs/cli.md +229 -0
- package/docusaurus/docs/core-concepts/actions.md +286 -0
- package/docusaurus/docs/core-concepts/missions.md +264 -0
- package/docusaurus/docs/core-concepts/schemas.md +353 -0
- package/docusaurus/docs/core-concepts/sources.md +339 -0
- package/docusaurus/docs/core-concepts/stores.md +332 -0
- package/docusaurus/docs/dsl-syntax/expressions.md +361 -0
- package/docusaurus/docs/dsl-syntax/fetch.md +293 -0
- package/docusaurus/docs/dsl-syntax/for-loops.md +324 -0
- package/docusaurus/docs/dsl-syntax/map.md +345 -0
- package/docusaurus/docs/dsl-syntax/match.md +387 -0
- package/docusaurus/docs/dsl-syntax/pipelines.md +397 -0
- package/docusaurus/docs/dsl-syntax/validate.md +401 -0
- package/docusaurus/docs/error-handling/dead-letter-queues.md +399 -0
- package/docusaurus/docs/error-handling/flow-control.md +337 -0
- package/docusaurus/docs/error-handling/retry-strategies.md +368 -0
- package/docusaurus/docs/examples.md +488 -0
- package/docusaurus/docs/getting-started.md +256 -0
- package/docusaurus/docs/http/circuit-breaker.md +401 -0
- package/docusaurus/docs/http/incremental-sync.md +394 -0
- package/docusaurus/docs/http/pagination.md +361 -0
- package/docusaurus/docs/http/rate-limiting.md +383 -0
- package/docusaurus/docs/http/requests.md +328 -0
- package/docusaurus/docs/http/retry.md +402 -0
- package/docusaurus/docs/intro.md +90 -0
- package/docusaurus/docs/openapi/loading-specs.md +305 -0
- package/docusaurus/docs/openapi/operation-calls.md +314 -0
- package/docusaurus/docs/openapi/overview.md +212 -0
- package/docusaurus/docs/openapi/response-validation.md +344 -0
- package/docusaurus/docs/scheduling/cron.md +305 -0
- package/docusaurus/docs/scheduling/daemon-mode.md +317 -0
- package/docusaurus/docs/scheduling/intervals.md +289 -0
- package/docusaurus/docs/scheduling/overview.md +231 -0
- package/docusaurus/docs/stores/custom-adapters.md +376 -0
- package/docusaurus/docs/stores/file.md +236 -0
- package/docusaurus/docs/stores/memory.md +193 -0
- package/docusaurus/docs/stores/overview.md +274 -0
- package/docusaurus/docs/stores/postgrest.md +316 -0
- package/docusaurus/docusaurus.config.ts +148 -0
- package/docusaurus/package-lock.json +18029 -0
- package/docusaurus/package.json +47 -0
- package/docusaurus/sidebars.ts +155 -0
- package/docusaurus/src/components/HomepageFeatures/index.tsx +105 -0
- package/docusaurus/src/components/HomepageFeatures/styles.module.css +12 -0
- package/docusaurus/src/css/custom.css +169 -0
- package/docusaurus/src/pages/index.module.css +48 -0
- package/docusaurus/src/pages/index.tsx +110 -0
- package/docusaurus/src/pages/markdown-page.md +7 -0
- package/docusaurus/static/.nojekyll +0 -0
- package/docusaurus/static/img/docusaurus-social-card.jpg +0 -0
- package/docusaurus/static/img/docusaurus.png +0 -0
- package/docusaurus/static/img/favicon.ico +0 -0
- package/docusaurus/static/img/logo.svg +10 -0
- package/docusaurus/static/img/undraw_docusaurus_mountain.svg +171 -0
- package/docusaurus/static/img/undraw_docusaurus_react.svg +170 -0
- package/docusaurus/static/img/undraw_docusaurus_tree.svg +40 -0
- package/docusaurus/tsconfig.json +8 -0
- package/examples/README.md +112 -0
- package/examples/error-handling/README.md +150 -0
- package/examples/error-handling/payment-processor.vague +287 -0
- package/examples/github-sync/README.md +74 -0
- package/examples/github-sync/fetch-issues.vague +47 -0
- package/examples/github-sync/fetch-prs.vague +40 -0
- package/examples/github-sync/mission.vague +101 -0
- package/examples/github-sync/normalize.vague +70 -0
- package/examples/jsonplaceholder/README.md +28 -0
- package/examples/jsonplaceholder/posts.vague +48 -0
- package/examples/petstore/README.md +35 -0
- package/examples/petstore/openapi.yaml +97 -0
- package/examples/petstore/sync.vague +52 -0
- package/examples/temporal-comparison/README.md +297 -0
- package/examples/temporal-comparison/reconciliation.vague +355 -0
- package/examples/temporal-comparison/temporal/activities/index.ts +8 -0
- package/examples/temporal-comparison/temporal/activities/shipstation.ts +225 -0
- package/examples/temporal-comparison/temporal/activities/shopify.ts +257 -0
- package/examples/temporal-comparison/temporal/activities/storage.ts +198 -0
- package/examples/temporal-comparison/temporal/activities/stripe.ts +169 -0
- package/examples/temporal-comparison/temporal/activities/validation.ts +205 -0
- package/examples/temporal-comparison/temporal/client/schedule.ts +218 -0
- package/examples/temporal-comparison/temporal/config/retry.ts +63 -0
- package/examples/temporal-comparison/temporal/types/index.ts +129 -0
- package/examples/temporal-comparison/temporal/workers/main.ts +130 -0
- package/examples/temporal-comparison/temporal/workflows/orderReconciliation.ts +262 -0
- package/examples/xero/README.md +88 -0
- package/examples/xero/invoices.vague +189 -0
- package/package.json +40 -0
- package/src/api-integration.test.ts +954 -0
- package/src/ast/index.ts +1 -0
- package/src/ast/nodes.ts +310 -0
- package/src/auth/auth.test.ts +326 -0
- package/src/auth/circuit-breaker.test.ts +390 -0
- package/src/auth/circuit-breaker.ts +379 -0
- package/src/auth/credentials.test.ts +273 -0
- package/src/auth/credentials.ts +246 -0
- package/src/auth/index.ts +40 -0
- package/src/auth/oauth2-provider.ts +177 -0
- package/src/auth/rate-limiter.ts +459 -0
- package/src/auth/token-store.ts +177 -0
- package/src/auth/types.ts +159 -0
- package/src/benchmark/e2e.bench.ts +288 -0
- package/src/benchmark/evaluator.bench.ts +331 -0
- package/src/benchmark/fixtures.ts +295 -0
- package/src/benchmark/index.ts +108 -0
- package/src/benchmark/lexer.bench.ts +69 -0
- package/src/benchmark/parser.bench.ts +103 -0
- package/src/benchmark/resilience.bench.ts +193 -0
- package/src/benchmark/store.bench.ts +147 -0
- package/src/benchmark/utils.ts +230 -0
- package/src/cli.ts +313 -0
- package/src/errors/errors.test.ts +234 -0
- package/src/errors/index.ts +223 -0
- package/src/execution/execution.test.ts +307 -0
- package/src/execution/index.ts +21 -0
- package/src/execution/state.ts +207 -0
- package/src/execution/store.ts +188 -0
- package/src/index.ts +169 -0
- package/src/integration.test.ts +192 -0
- package/src/interpreter/context.ts +57 -0
- package/src/interpreter/evaluator.test.ts +796 -0
- package/src/interpreter/evaluator.ts +245 -0
- package/src/interpreter/executor.ts +946 -0
- package/src/interpreter/fetch-handler.ts +302 -0
- package/src/interpreter/http.test.ts +423 -0
- package/src/interpreter/http.ts +308 -0
- package/src/interpreter/index.ts +32 -0
- package/src/interpreter/pagination.ts +207 -0
- package/src/interpreter/progress.test.ts +276 -0
- package/src/interpreter/schema-matcher.test.ts +160 -0
- package/src/interpreter/schema-matcher.ts +168 -0
- package/src/interpreter/signals.ts +73 -0
- package/src/interpreter/step-handlers/for-handler.ts +65 -0
- package/src/interpreter/step-handlers/index.ts +17 -0
- package/src/interpreter/step-handlers/map-handler.ts +24 -0
- package/src/interpreter/step-handlers/match-handler.ts +101 -0
- package/src/interpreter/step-handlers/store-handler.ts +78 -0
- package/src/interpreter/step-handlers/types.ts +17 -0
- package/src/interpreter/step-handlers/validate-handler.ts +30 -0
- package/src/interpreter/step-handlers/webhook-handler.ts +142 -0
- package/src/lexer/index.ts +18 -0
- package/src/lexer/lexer.test.ts +316 -0
- package/src/lexer/tokens.ts +179 -0
- package/src/loader/index.ts +288 -0
- package/src/loader/loader.test.ts +360 -0
- package/src/oas/index.ts +4 -0
- package/src/oas/loader.ts +126 -0
- package/src/oas/oas.test.ts +254 -0
- package/src/oas/validator.ts +299 -0
- package/src/parser/base.ts +124 -0
- package/src/parser/expressions.test.ts +525 -0
- package/src/parser/expressions.ts +314 -0
- package/src/parser/index.ts +3 -0
- package/src/parser/match.test.ts +296 -0
- package/src/parser/parser.test.ts +739 -0
- package/src/parser/parser.ts +1469 -0
- package/src/parser/schedule.test.ts +287 -0
- package/src/parser/webhook.test.ts +248 -0
- package/src/plugin.ts +83 -0
- package/src/scheduler/cron-parser.test.ts +236 -0
- package/src/scheduler/cron-parser.ts +236 -0
- package/src/scheduler/index.ts +10 -0
- package/src/scheduler/scheduler.ts +443 -0
- package/src/scheduler/types.ts +71 -0
- package/src/stores/factory.ts +104 -0
- package/src/stores/file.test.ts +276 -0
- package/src/stores/file.ts +211 -0
- package/src/stores/index.ts +6 -0
- package/src/stores/memory.test.ts +238 -0
- package/src/stores/memory.ts +63 -0
- package/src/stores/postgrest.test.ts +488 -0
- package/src/stores/postgrest.ts +263 -0
- package/src/stores/stores.test.ts +197 -0
- package/src/stores/types.ts +58 -0
- package/src/sync/index.ts +16 -0
- package/src/sync/state.ts +126 -0
- package/src/sync/store.ts +139 -0
- package/src/sync/sync.test.ts +271 -0
- package/src/utils/async.ts +10 -0
- package/src/utils/file.ts +106 -0
- package/src/utils/index.ts +14 -0
- package/src/utils/logger.ts +53 -0
- package/src/utils/path.ts +47 -0
- package/src/webhook/index.ts +15 -0
- package/src/webhook/server.test.ts +253 -0
- package/src/webhook/server.ts +389 -0
- package/src/webhook/store.ts +239 -0
- package/src/webhook/types.ts +93 -0
- package/tsconfig.json +17 -0
- package/vitest.config.ts +39 -0
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_position: 4
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Validation
|
|
6
|
+
|
|
7
|
+
Validate steps check data constraints before processing or storing. They help ensure data quality and catch issues early.
|
|
8
|
+
|
|
9
|
+
## Basic Syntax
|
|
10
|
+
|
|
11
|
+
```vague
|
|
12
|
+
validate target {
|
|
13
|
+
assume constraint1,
|
|
14
|
+
assume constraint2
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Simple Validation
|
|
19
|
+
|
|
20
|
+
```vague
|
|
21
|
+
action ValidateUsers {
|
|
22
|
+
get "/users"
|
|
23
|
+
|
|
24
|
+
for user in response.users {
|
|
25
|
+
validate user {
|
|
26
|
+
assume .id is string,
|
|
27
|
+
assume length(.name) > 0,
|
|
28
|
+
assume .email contains "@"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
store user -> users { key: .id }
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Constraint Types
|
|
37
|
+
|
|
38
|
+
### Type Checking
|
|
39
|
+
|
|
40
|
+
```vague
|
|
41
|
+
validate data {
|
|
42
|
+
assume .id is string,
|
|
43
|
+
assume .count is number,
|
|
44
|
+
assume .active is boolean,
|
|
45
|
+
assume .tags is array,
|
|
46
|
+
assume .metadata is object,
|
|
47
|
+
assume .deletedAt is null
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Existence Checks
|
|
52
|
+
|
|
53
|
+
```vague
|
|
54
|
+
validate data {
|
|
55
|
+
assume .id != null,
|
|
56
|
+
assume .name != null,
|
|
57
|
+
assume .email != null
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### String Constraints
|
|
62
|
+
|
|
63
|
+
```vague
|
|
64
|
+
validate user {
|
|
65
|
+
assume length(.name) > 0,
|
|
66
|
+
assume length(.name) < 100,
|
|
67
|
+
assume .email contains "@",
|
|
68
|
+
assume .phone startsWith "+",
|
|
69
|
+
assume .country endsWith "A"
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Numeric Constraints
|
|
74
|
+
|
|
75
|
+
```vague
|
|
76
|
+
validate order {
|
|
77
|
+
assume .quantity > 0,
|
|
78
|
+
assume .price >= 0,
|
|
79
|
+
assume .discount >= 0 and .discount <= 100,
|
|
80
|
+
assume .total == .price * .quantity
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Array Constraints
|
|
85
|
+
|
|
86
|
+
```vague
|
|
87
|
+
validate response {
|
|
88
|
+
assume length(.items) > 0,
|
|
89
|
+
assume length(.items) <= 100
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Comparison
|
|
94
|
+
|
|
95
|
+
```vague
|
|
96
|
+
validate event {
|
|
97
|
+
assume .endDate >= .startDate,
|
|
98
|
+
assume .createdAt <= now()
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Complex Constraints
|
|
103
|
+
|
|
104
|
+
### Logical Operators
|
|
105
|
+
|
|
106
|
+
```vague
|
|
107
|
+
validate user {
|
|
108
|
+
assume .status == "active" or .status == "pending",
|
|
109
|
+
assume .age >= 18 and .age <= 120,
|
|
110
|
+
assume not (.status == "banned")
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Conditional Validation
|
|
115
|
+
|
|
116
|
+
```vague
|
|
117
|
+
validate order {
|
|
118
|
+
// If discount is present, it must be valid
|
|
119
|
+
assume .discount == null or (.discount >= 0 and .discount <= 50),
|
|
120
|
+
|
|
121
|
+
// If status is shipped, must have tracking
|
|
122
|
+
assume .status != "shipped" or .trackingNumber != null
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Validation Responses
|
|
127
|
+
|
|
128
|
+
### Warnings vs Errors
|
|
129
|
+
|
|
130
|
+
By default, failed validations are warnings and don't stop execution:
|
|
131
|
+
|
|
132
|
+
```vague
|
|
133
|
+
validate user {
|
|
134
|
+
assume length(.name) > 0 // Warning if fails
|
|
135
|
+
}
|
|
136
|
+
// Execution continues even if validation fails
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Strict Validation
|
|
140
|
+
|
|
141
|
+
Combine with match for strict validation:
|
|
142
|
+
|
|
143
|
+
```vague
|
|
144
|
+
action StrictValidation {
|
|
145
|
+
get "/users"
|
|
146
|
+
|
|
147
|
+
for user in response.users {
|
|
148
|
+
validate user {
|
|
149
|
+
assume .id is string,
|
|
150
|
+
assume .email contains "@"
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
match user {
|
|
154
|
+
{ id: null } -> skip,
|
|
155
|
+
{ email: null } -> skip,
|
|
156
|
+
_ -> store user -> users { key: .id }
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Validating Nested Data
|
|
163
|
+
|
|
164
|
+
```vague
|
|
165
|
+
validate order {
|
|
166
|
+
assume .id is string,
|
|
167
|
+
assume .customer.id is string,
|
|
168
|
+
assume .customer.email contains "@",
|
|
169
|
+
assume length(.items) > 0,
|
|
170
|
+
assume .items[0].quantity > 0
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Validating Arrays
|
|
175
|
+
|
|
176
|
+
```vague
|
|
177
|
+
action ValidateAllItems {
|
|
178
|
+
get "/orders"
|
|
179
|
+
|
|
180
|
+
for order in response.orders {
|
|
181
|
+
// Validate order-level
|
|
182
|
+
validate order {
|
|
183
|
+
assume .id is string,
|
|
184
|
+
assume .total > 0
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Validate each item
|
|
188
|
+
for item in order.items {
|
|
189
|
+
validate item {
|
|
190
|
+
assume .productId is string,
|
|
191
|
+
assume .quantity > 0,
|
|
192
|
+
assume .price >= 0
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Custom Validation Messages
|
|
200
|
+
|
|
201
|
+
Use match for custom error handling:
|
|
202
|
+
|
|
203
|
+
```vague
|
|
204
|
+
action ValidateWithMessages {
|
|
205
|
+
get "/users"
|
|
206
|
+
|
|
207
|
+
for user in response.users {
|
|
208
|
+
match user {
|
|
209
|
+
{ email: null } -> {
|
|
210
|
+
store { userId: user.id, error: "Missing email" } -> validationErrors
|
|
211
|
+
skip
|
|
212
|
+
},
|
|
213
|
+
{ age: a } where a < 18 -> {
|
|
214
|
+
store { userId: user.id, error: "User under 18" } -> validationErrors
|
|
215
|
+
skip
|
|
216
|
+
},
|
|
217
|
+
_ -> continue
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
store user -> validUsers { key: .id }
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Validation Before Store
|
|
226
|
+
|
|
227
|
+
Always validate before storing:
|
|
228
|
+
|
|
229
|
+
```vague
|
|
230
|
+
action SafeStore {
|
|
231
|
+
get "/data"
|
|
232
|
+
|
|
233
|
+
for item in response.data {
|
|
234
|
+
validate item {
|
|
235
|
+
assume .id is string,
|
|
236
|
+
assume .value is number
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Only store if valid
|
|
240
|
+
match item {
|
|
241
|
+
{ id: null } -> skip,
|
|
242
|
+
{ value: null } -> skip,
|
|
243
|
+
_ -> store item -> data { key: .id }
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Validation Schemas
|
|
250
|
+
|
|
251
|
+
Use schemas for reusable validation:
|
|
252
|
+
|
|
253
|
+
```vague
|
|
254
|
+
schema ValidUser {
|
|
255
|
+
id: string,
|
|
256
|
+
name: string,
|
|
257
|
+
email: string
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
action ValidateAgainstSchema {
|
|
261
|
+
get "/users"
|
|
262
|
+
|
|
263
|
+
for user in response.users {
|
|
264
|
+
match user {
|
|
265
|
+
ValidUser -> store user -> users { key: .id },
|
|
266
|
+
_ -> store user -> invalidUsers { key: .id }
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Built-in Validation Functions
|
|
273
|
+
|
|
274
|
+
```vague
|
|
275
|
+
validate data {
|
|
276
|
+
// String functions
|
|
277
|
+
assume length(.name) > 0,
|
|
278
|
+
assume .email contains "@",
|
|
279
|
+
assume lowercase(.status) == "active",
|
|
280
|
+
|
|
281
|
+
// Numeric functions
|
|
282
|
+
assume abs(.balance) < 10000,
|
|
283
|
+
assume round(.price, 2) == .price,
|
|
284
|
+
|
|
285
|
+
// Array functions
|
|
286
|
+
assume length(.items) > 0,
|
|
287
|
+
assume includes(.roles, "user"),
|
|
288
|
+
|
|
289
|
+
// Date functions
|
|
290
|
+
assume .createdAt <= now(),
|
|
291
|
+
assume .expiresAt > now()
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
## Complete Example
|
|
296
|
+
|
|
297
|
+
```vague
|
|
298
|
+
mission DataValidation {
|
|
299
|
+
source API { auth: bearer, base: "https://api.example.com" }
|
|
300
|
+
|
|
301
|
+
store validOrders: file("valid-orders")
|
|
302
|
+
store invalidOrders: file("invalid-orders")
|
|
303
|
+
store validationErrors: file("validation-errors")
|
|
304
|
+
|
|
305
|
+
schema ValidOrder {
|
|
306
|
+
id: string,
|
|
307
|
+
customerId: string,
|
|
308
|
+
items: array,
|
|
309
|
+
total: number
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
action ValidateOrders {
|
|
313
|
+
get "/orders"
|
|
314
|
+
|
|
315
|
+
for order in response.orders {
|
|
316
|
+
// Type validation
|
|
317
|
+
validate order {
|
|
318
|
+
assume .id is string,
|
|
319
|
+
assume .customerId is string,
|
|
320
|
+
assume .items is array,
|
|
321
|
+
assume .total is number
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Business rule validation
|
|
325
|
+
validate order {
|
|
326
|
+
assume length(.items) > 0,
|
|
327
|
+
assume .total > 0,
|
|
328
|
+
assume .total == sum(.items.map(.price * .quantity)),
|
|
329
|
+
assume .status == "pending" or .status == "confirmed"
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Route based on validation
|
|
333
|
+
match order {
|
|
334
|
+
ValidOrder where .total > 0 and length(.items) > 0 -> {
|
|
335
|
+
store order -> validOrders { key: .id }
|
|
336
|
+
},
|
|
337
|
+
_ -> {
|
|
338
|
+
store {
|
|
339
|
+
orderId: order.id,
|
|
340
|
+
order: order,
|
|
341
|
+
reason: "Failed validation"
|
|
342
|
+
} -> invalidOrders { key: order.id }
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
run ValidateOrders
|
|
349
|
+
}
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## Best Practices
|
|
353
|
+
|
|
354
|
+
### Validate Early
|
|
355
|
+
|
|
356
|
+
```vague
|
|
357
|
+
action Process {
|
|
358
|
+
get "/data"
|
|
359
|
+
|
|
360
|
+
// Validate immediately after fetch
|
|
361
|
+
validate response {
|
|
362
|
+
assume .data is array,
|
|
363
|
+
assume length(.data) > 0
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Then process
|
|
367
|
+
for item in response.data { }
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Use Specific Constraints
|
|
372
|
+
|
|
373
|
+
```vague
|
|
374
|
+
// Good: specific constraints
|
|
375
|
+
validate user {
|
|
376
|
+
assume .email contains "@",
|
|
377
|
+
assume length(.email) > 5,
|
|
378
|
+
assume .email endsWith ".com" or .email endsWith ".org"
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Avoid: too loose
|
|
382
|
+
validate user {
|
|
383
|
+
assume .email is string
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Log Validation Failures
|
|
388
|
+
|
|
389
|
+
```vague
|
|
390
|
+
action ValidateWithLogging {
|
|
391
|
+
for item in items {
|
|
392
|
+
match item {
|
|
393
|
+
{ id: null } -> {
|
|
394
|
+
store { itemId: "unknown", field: "id", error: "Missing" } -> errors
|
|
395
|
+
skip
|
|
396
|
+
},
|
|
397
|
+
_ -> continue
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
```
|