@qlever-llc/trellis 0.10.22 → 0.11.0-rc.1
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/esm/auth/mod.d.ts +1 -1
- package/esm/auth/mod.d.ts.map +1 -1
- package/esm/auth/mod.js +1 -1
- package/esm/auth/protocol.d.ts +55 -0
- package/esm/auth/protocol.d.ts.map +1 -1
- package/esm/browser.d.ts +3 -3
- package/esm/browser.d.ts.map +1 -1
- package/esm/browser.js +1 -1
- package/esm/client_connect.d.ts +12 -3
- package/esm/client_connect.d.ts.map +1 -1
- package/esm/client_connect.js +112 -7
- package/esm/codec.d.ts +7 -6
- package/esm/codec.d.ts.map +1 -1
- package/esm/codec.js +125 -6
- package/esm/contract_support/canonical.d.ts +3 -0
- package/esm/contract_support/canonical.d.ts.map +1 -1
- package/esm/contract_support/canonical.js +3 -0
- package/esm/contract_support/mod.d.ts +125 -10
- package/esm/contract_support/mod.d.ts.map +1 -1
- package/esm/contract_support/mod.js +159 -5
- package/esm/contract_support/protocol.d.ts +92 -7
- package/esm/contract_support/protocol.d.ts.map +1 -1
- package/esm/contract_support/protocol.js +41 -7
- package/esm/contract_support/runtime.d.ts +4 -1
- package/esm/contract_support/runtime.d.ts.map +1 -1
- package/esm/errors/SchemaValidationError.d.ts +49 -0
- package/esm/errors/SchemaValidationError.d.ts.map +1 -0
- package/esm/errors/SchemaValidationError.js +67 -0
- package/esm/errors/index.d.ts +38 -9
- package/esm/errors/index.d.ts.map +1 -1
- package/esm/errors/index.js +16 -0
- package/esm/generated-sdk/auth/api.d.ts +33 -605
- package/esm/generated-sdk/auth/api.d.ts.map +1 -1
- package/esm/generated-sdk/auth/api.js +6 -1
- package/esm/generated-sdk/auth/client.d.ts +129 -134
- package/esm/generated-sdk/auth/client.d.ts.map +1 -1
- package/esm/generated-sdk/auth/contract.d.ts +2 -601
- package/esm/generated-sdk/auth/contract.d.ts.map +1 -1
- package/esm/generated-sdk/auth/contract.js +310 -93
- package/esm/generated-sdk/auth/mod.d.ts +1 -1
- package/esm/generated-sdk/auth/mod.d.ts.map +1 -1
- package/esm/generated-sdk/auth/owned_api.d.ts +88 -86
- package/esm/generated-sdk/auth/owned_api.d.ts.map +1 -1
- package/esm/generated-sdk/auth/owned_api.js +6 -0
- package/esm/generated-sdk/auth/schemas.d.ts +284 -136
- package/esm/generated-sdk/auth/schemas.d.ts.map +1 -1
- package/esm/generated-sdk/auth/schemas.js +231 -92
- package/esm/generated-sdk/auth/types.d.ts +565 -89
- package/esm/generated-sdk/auth/types.d.ts.map +1 -1
- package/esm/generated-sdk/auth/types.js +1 -1
- package/esm/generated-sdk/health/api.d.ts +29 -18
- package/esm/generated-sdk/health/api.d.ts.map +1 -1
- package/esm/generated-sdk/health/client.d.ts +7 -21
- package/esm/generated-sdk/health/client.d.ts.map +1 -1
- package/esm/generated-sdk/health/contract.d.ts +2 -15
- package/esm/generated-sdk/health/contract.d.ts.map +1 -1
- package/esm/generated-sdk/health/contract.js +2 -10
- package/esm/generated-sdk/health/mod.d.ts +1 -1
- package/esm/generated-sdk/health/mod.d.ts.map +1 -1
- package/esm/generated-sdk/health/owned_api.d.ts +2 -2
- package/esm/generated-sdk/health/schemas.d.ts +1 -14
- package/esm/generated-sdk/health/schemas.d.ts.map +1 -1
- package/esm/generated-sdk/health/schemas.js +1 -9
- package/esm/generated-sdk/health/types.d.ts +10 -5
- package/esm/generated-sdk/health/types.d.ts.map +1 -1
- package/esm/generated-sdk/health/types.js +1 -2
- package/esm/generated-sdk/jobs/api.d.ts +29 -109
- package/esm/generated-sdk/jobs/api.d.ts.map +1 -1
- package/esm/generated-sdk/jobs/client.d.ts +21 -33
- package/esm/generated-sdk/jobs/client.d.ts.map +1 -1
- package/esm/generated-sdk/jobs/contract.d.ts +2 -106
- package/esm/generated-sdk/jobs/contract.d.ts.map +1 -1
- package/esm/generated-sdk/jobs/contract.js +268 -1
- package/esm/generated-sdk/jobs/mod.d.ts +1 -1
- package/esm/generated-sdk/jobs/mod.d.ts.map +1 -1
- package/esm/generated-sdk/jobs/owned_api.d.ts +22 -9
- package/esm/generated-sdk/jobs/owned_api.d.ts.map +1 -1
- package/esm/generated-sdk/jobs/owned_api.js +20 -1
- package/esm/generated-sdk/jobs/schemas.d.ts +437 -0
- package/esm/generated-sdk/jobs/schemas.d.ts.map +1 -1
- package/esm/generated-sdk/jobs/schemas.js +211 -0
- package/esm/generated-sdk/jobs/types.d.ts +195 -12
- package/esm/generated-sdk/jobs/types.d.ts.map +1 -1
- package/esm/generated-sdk/jobs/types.js +1 -1
- package/esm/generated-sdk/state/api.d.ts +29 -68
- package/esm/generated-sdk/state/api.d.ts.map +1 -1
- package/esm/generated-sdk/state/client.d.ts +17 -31
- package/esm/generated-sdk/state/client.d.ts.map +1 -1
- package/esm/generated-sdk/state/contract.d.ts +1 -64
- package/esm/generated-sdk/state/contract.d.ts.map +1 -1
- package/esm/generated-sdk/state/mod.d.ts +1 -1
- package/esm/generated-sdk/state/mod.d.ts.map +1 -1
- package/esm/generated-sdk/state/owned_api.d.ts +7 -7
- package/esm/generated-sdk/state/types.d.ts +52 -9
- package/esm/generated-sdk/state/types.d.ts.map +1 -1
- package/esm/generated-sdk/trellis-core/api.d.ts +33 -45
- package/esm/generated-sdk/trellis-core/api.d.ts.map +1 -1
- package/esm/generated-sdk/trellis-core/api.js +6 -1
- package/esm/generated-sdk/trellis-core/client.d.ts +31 -20
- package/esm/generated-sdk/trellis-core/client.d.ts.map +1 -1
- package/esm/generated-sdk/trellis-core/contract.d.ts +2 -41
- package/esm/generated-sdk/trellis-core/contract.d.ts.map +1 -1
- package/esm/generated-sdk/trellis-core/contract.js +91 -1
- package/esm/generated-sdk/trellis-core/mod.d.ts +1 -1
- package/esm/generated-sdk/trellis-core/mod.d.ts.map +1 -1
- package/esm/generated-sdk/trellis-core/owned_api.d.ts +4 -4
- package/esm/generated-sdk/trellis-core/schemas.d.ts +113 -0
- package/esm/generated-sdk/trellis-core/schemas.d.ts.map +1 -1
- package/esm/generated-sdk/trellis-core/schemas.js +81 -0
- package/esm/generated-sdk/trellis-core/types.d.ts +54 -7
- package/esm/generated-sdk/trellis-core/types.d.ts.map +1 -1
- package/esm/generated-sdk/trellis-core/types.js +1 -1
- package/esm/health.d.ts +1 -1
- package/esm/health.d.ts.map +1 -1
- package/esm/health.js +1 -1
- package/esm/index.d.ts +4 -4
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +2 -2
- package/esm/jobs.d.ts +69 -3
- package/esm/jobs.d.ts.map +1 -1
- package/esm/jobs.js +92 -3
- package/esm/server/health.d.ts +2 -6
- package/esm/server/health.d.ts.map +1 -1
- package/esm/server/health_schemas.d.ts +0 -8
- package/esm/server/health_schemas.d.ts.map +1 -1
- package/esm/server/health_schemas.js +0 -5
- package/esm/server/internal_jobs/bindings.d.ts +11 -0
- package/esm/server/internal_jobs/bindings.d.ts.map +1 -1
- package/esm/server/internal_jobs/job-manager.d.ts +58 -2
- package/esm/server/internal_jobs/job-manager.d.ts.map +1 -1
- package/esm/server/internal_jobs/job-manager.js +429 -55
- package/esm/server/internal_jobs/key-coordinator.d.ts +269 -0
- package/esm/server/internal_jobs/key-coordinator.d.ts.map +1 -0
- package/esm/server/internal_jobs/key-coordinator.js +677 -0
- package/esm/server/internal_jobs/projection.d.ts.map +1 -1
- package/esm/server/internal_jobs/projection.js +2 -0
- package/esm/server/internal_jobs/runtime-worker.d.ts +5 -1
- package/esm/server/internal_jobs/runtime-worker.d.ts.map +1 -1
- package/esm/server/internal_jobs/runtime-worker.js +14 -2
- package/esm/server/internal_jobs/types.d.ts +5 -5
- package/esm/server/internal_jobs/types.d.ts.map +1 -1
- package/esm/server/internal_jobs/types.js +6 -0
- package/esm/server/runtime.d.ts.map +1 -1
- package/esm/server/service.d.ts +81 -112
- package/esm/server/service.d.ts.map +1 -1
- package/esm/server/service.js +372 -130
- package/esm/server.d.ts +3 -3
- package/esm/server.d.ts.map +1 -1
- package/esm/service/deno.d.ts +1 -1
- package/esm/service/deno.d.ts.map +1 -1
- package/esm/service/drizzle.d.ts +52 -0
- package/esm/service/drizzle.d.ts.map +1 -0
- package/esm/service/drizzle.js +108 -0
- package/esm/service/mod.d.ts +3 -3
- package/esm/service/mod.d.ts.map +1 -1
- package/esm/service/mod.js +2 -2
- package/esm/service/node.d.ts +1 -1
- package/esm/service/node.d.ts.map +1 -1
- package/esm/service/outbox_inbox.d.ts +76 -22
- package/esm/service/outbox_inbox.d.ts.map +1 -1
- package/esm/service/outbox_inbox.js +231 -70
- package/esm/telemetry/metrics.d.ts +55 -0
- package/esm/telemetry/metrics.d.ts.map +1 -1
- package/esm/telemetry/metrics.js +86 -0
- package/esm/telemetry/mod.d.ts +2 -1
- package/esm/telemetry/mod.d.ts.map +1 -1
- package/esm/telemetry/mod.js +1 -1
- package/esm/trellis.d.ts +62 -30
- package/esm/trellis.d.ts.map +1 -1
- package/esm/trellis.js +125 -42
- package/package.json +14 -2
- package/script/auth/mod.d.ts +1 -1
- package/script/auth/mod.d.ts.map +1 -1
- package/script/auth/mod.js +11 -4
- package/script/auth/protocol.d.ts +55 -0
- package/script/auth/protocol.d.ts.map +1 -1
- package/script/browser.d.ts +3 -3
- package/script/browser.d.ts.map +1 -1
- package/script/browser.js +3 -2
- package/script/client_connect.d.ts +12 -3
- package/script/client_connect.d.ts.map +1 -1
- package/script/client_connect.js +111 -6
- package/script/codec.d.ts +7 -6
- package/script/codec.d.ts.map +1 -1
- package/script/codec.js +124 -5
- package/script/contract_support/canonical.d.ts +3 -0
- package/script/contract_support/canonical.d.ts.map +1 -1
- package/script/contract_support/canonical.js +3 -0
- package/script/contract_support/mod.d.ts +125 -10
- package/script/contract_support/mod.d.ts.map +1 -1
- package/script/contract_support/mod.js +165 -5
- package/script/contract_support/protocol.d.ts +92 -7
- package/script/contract_support/protocol.d.ts.map +1 -1
- package/script/contract_support/protocol.js +42 -8
- package/script/contract_support/runtime.d.ts +4 -1
- package/script/contract_support/runtime.d.ts.map +1 -1
- package/script/errors/SchemaValidationError.d.ts +49 -0
- package/script/errors/SchemaValidationError.d.ts.map +1 -0
- package/script/errors/SchemaValidationError.js +74 -0
- package/script/errors/index.d.ts +38 -9
- package/script/errors/index.d.ts.map +1 -1
- package/script/errors/index.js +20 -1
- package/script/generated-sdk/auth/api.d.ts +33 -605
- package/script/generated-sdk/auth/api.d.ts.map +1 -1
- package/script/generated-sdk/auth/api.js +6 -1
- package/script/generated-sdk/auth/client.d.ts +129 -134
- package/script/generated-sdk/auth/client.d.ts.map +1 -1
- package/script/generated-sdk/auth/contract.d.ts +2 -601
- package/script/generated-sdk/auth/contract.d.ts.map +1 -1
- package/script/generated-sdk/auth/contract.js +310 -93
- package/script/generated-sdk/auth/mod.d.ts +1 -1
- package/script/generated-sdk/auth/mod.d.ts.map +1 -1
- package/script/generated-sdk/auth/owned_api.d.ts +88 -86
- package/script/generated-sdk/auth/owned_api.d.ts.map +1 -1
- package/script/generated-sdk/auth/owned_api.js +6 -0
- package/script/generated-sdk/auth/schemas.d.ts +284 -136
- package/script/generated-sdk/auth/schemas.d.ts.map +1 -1
- package/script/generated-sdk/auth/schemas.js +231 -92
- package/script/generated-sdk/auth/types.d.ts +565 -89
- package/script/generated-sdk/auth/types.d.ts.map +1 -1
- package/script/generated-sdk/auth/types.js +1 -1
- package/script/generated-sdk/health/api.d.ts +29 -18
- package/script/generated-sdk/health/api.d.ts.map +1 -1
- package/script/generated-sdk/health/client.d.ts +7 -21
- package/script/generated-sdk/health/client.d.ts.map +1 -1
- package/script/generated-sdk/health/contract.d.ts +2 -15
- package/script/generated-sdk/health/contract.d.ts.map +1 -1
- package/script/generated-sdk/health/contract.js +2 -10
- package/script/generated-sdk/health/mod.d.ts +1 -1
- package/script/generated-sdk/health/mod.d.ts.map +1 -1
- package/script/generated-sdk/health/owned_api.d.ts +2 -2
- package/script/generated-sdk/health/schemas.d.ts +1 -14
- package/script/generated-sdk/health/schemas.d.ts.map +1 -1
- package/script/generated-sdk/health/schemas.js +1 -9
- package/script/generated-sdk/health/types.d.ts +10 -5
- package/script/generated-sdk/health/types.d.ts.map +1 -1
- package/script/generated-sdk/health/types.js +1 -2
- package/script/generated-sdk/jobs/api.d.ts +29 -109
- package/script/generated-sdk/jobs/api.d.ts.map +1 -1
- package/script/generated-sdk/jobs/client.d.ts +21 -33
- package/script/generated-sdk/jobs/client.d.ts.map +1 -1
- package/script/generated-sdk/jobs/contract.d.ts +2 -106
- package/script/generated-sdk/jobs/contract.d.ts.map +1 -1
- package/script/generated-sdk/jobs/contract.js +268 -1
- package/script/generated-sdk/jobs/mod.d.ts +1 -1
- package/script/generated-sdk/jobs/mod.d.ts.map +1 -1
- package/script/generated-sdk/jobs/owned_api.d.ts +22 -9
- package/script/generated-sdk/jobs/owned_api.d.ts.map +1 -1
- package/script/generated-sdk/jobs/owned_api.js +19 -0
- package/script/generated-sdk/jobs/schemas.d.ts +437 -0
- package/script/generated-sdk/jobs/schemas.d.ts.map +1 -1
- package/script/generated-sdk/jobs/schemas.js +212 -1
- package/script/generated-sdk/jobs/types.d.ts +195 -12
- package/script/generated-sdk/jobs/types.d.ts.map +1 -1
- package/script/generated-sdk/jobs/types.js +1 -1
- package/script/generated-sdk/state/api.d.ts +29 -68
- package/script/generated-sdk/state/api.d.ts.map +1 -1
- package/script/generated-sdk/state/client.d.ts +17 -31
- package/script/generated-sdk/state/client.d.ts.map +1 -1
- package/script/generated-sdk/state/contract.d.ts +1 -64
- package/script/generated-sdk/state/contract.d.ts.map +1 -1
- package/script/generated-sdk/state/mod.d.ts +1 -1
- package/script/generated-sdk/state/mod.d.ts.map +1 -1
- package/script/generated-sdk/state/owned_api.d.ts +7 -7
- package/script/generated-sdk/state/types.d.ts +52 -9
- package/script/generated-sdk/state/types.d.ts.map +1 -1
- package/script/generated-sdk/trellis-core/api.d.ts +33 -45
- package/script/generated-sdk/trellis-core/api.d.ts.map +1 -1
- package/script/generated-sdk/trellis-core/api.js +6 -1
- package/script/generated-sdk/trellis-core/client.d.ts +31 -20
- package/script/generated-sdk/trellis-core/client.d.ts.map +1 -1
- package/script/generated-sdk/trellis-core/contract.d.ts +2 -41
- package/script/generated-sdk/trellis-core/contract.d.ts.map +1 -1
- package/script/generated-sdk/trellis-core/contract.js +91 -1
- package/script/generated-sdk/trellis-core/mod.d.ts +1 -1
- package/script/generated-sdk/trellis-core/mod.d.ts.map +1 -1
- package/script/generated-sdk/trellis-core/owned_api.d.ts +4 -4
- package/script/generated-sdk/trellis-core/schemas.d.ts +113 -0
- package/script/generated-sdk/trellis-core/schemas.d.ts.map +1 -1
- package/script/generated-sdk/trellis-core/schemas.js +81 -0
- package/script/generated-sdk/trellis-core/types.d.ts +54 -7
- package/script/generated-sdk/trellis-core/types.d.ts.map +1 -1
- package/script/generated-sdk/trellis-core/types.js +1 -1
- package/script/health.d.ts +1 -1
- package/script/health.d.ts.map +1 -1
- package/script/health.js +1 -2
- package/script/index.d.ts +4 -4
- package/script/index.d.ts.map +1 -1
- package/script/index.js +2 -2
- package/script/jobs.d.ts +69 -3
- package/script/jobs.d.ts.map +1 -1
- package/script/jobs.js +93 -3
- package/script/server/health.d.ts +2 -6
- package/script/server/health.d.ts.map +1 -1
- package/script/server/health_schemas.d.ts +0 -8
- package/script/server/health_schemas.d.ts.map +1 -1
- package/script/server/health_schemas.js +1 -6
- package/script/server/internal_jobs/bindings.d.ts +11 -0
- package/script/server/internal_jobs/bindings.d.ts.map +1 -1
- package/script/server/internal_jobs/job-manager.d.ts +58 -2
- package/script/server/internal_jobs/job-manager.d.ts.map +1 -1
- package/script/server/internal_jobs/job-manager.js +429 -54
- package/script/server/internal_jobs/key-coordinator.d.ts +269 -0
- package/script/server/internal_jobs/key-coordinator.d.ts.map +1 -0
- package/script/server/internal_jobs/key-coordinator.js +690 -0
- package/script/server/internal_jobs/projection.d.ts.map +1 -1
- package/script/server/internal_jobs/projection.js +2 -0
- package/script/server/internal_jobs/runtime-worker.d.ts +5 -1
- package/script/server/internal_jobs/runtime-worker.d.ts.map +1 -1
- package/script/server/internal_jobs/runtime-worker.js +14 -2
- package/script/server/internal_jobs/types.d.ts +5 -5
- package/script/server/internal_jobs/types.d.ts.map +1 -1
- package/script/server/internal_jobs/types.js +6 -0
- package/script/server/runtime.d.ts.map +1 -1
- package/script/server/service.d.ts +81 -112
- package/script/server/service.d.ts.map +1 -1
- package/script/server/service.js +369 -127
- package/script/server.d.ts +3 -3
- package/script/server.d.ts.map +1 -1
- package/script/service/deno.d.ts +1 -1
- package/script/service/deno.d.ts.map +1 -1
- package/script/service/drizzle.d.ts +52 -0
- package/script/service/drizzle.d.ts.map +1 -0
- package/script/service/drizzle.js +113 -0
- package/script/service/mod.d.ts +3 -3
- package/script/service/mod.d.ts.map +1 -1
- package/script/service/mod.js +4 -3
- package/script/service/node.d.ts +1 -1
- package/script/service/node.d.ts.map +1 -1
- package/script/service/outbox_inbox.d.ts +76 -22
- package/script/service/outbox_inbox.d.ts.map +1 -1
- package/script/service/outbox_inbox.js +233 -70
- package/script/telemetry/metrics.d.ts +55 -0
- package/script/telemetry/metrics.d.ts.map +1 -1
- package/script/telemetry/metrics.js +88 -0
- package/script/telemetry/mod.d.ts +2 -1
- package/script/telemetry/mod.d.ts.map +1 -1
- package/script/telemetry/mod.js +3 -1
- package/script/trellis.d.ts +62 -30
- package/script/trellis.d.ts.map +1 -1
- package/script/trellis.js +124 -41
- package/src/auth/mod.ts +7 -0
- package/src/browser.ts +5 -7
- package/src/client_connect.ts +200 -12
- package/src/codec.ts +186 -11
- package/src/contract_support/canonical.ts +3 -0
- package/src/contract_support/mod.ts +380 -9
- package/src/contract_support/protocol.ts +57 -10
- package/src/contract_support/runtime.ts +7 -0
- package/src/errors/SchemaValidationError.ts +67 -0
- package/src/errors/index.ts +28 -0
- package/src/health.ts +0 -1
- package/src/index.ts +7 -8
- package/src/jobs.ts +138 -1
- package/src/sdk/_generated/auth/api.ts +38 -7
- package/src/sdk/_generated/auth/client.ts +168 -530
- package/src/sdk/_generated/auth/contract.ts +310 -93
- package/src/sdk/_generated/auth/mod.ts +0 -1
- package/src/sdk/_generated/auth/owned_api.ts +92 -86
- package/src/sdk/_generated/auth/schemas.ts +231 -92
- package/src/sdk/_generated/auth/types.ts +1069 -273
- package/src/sdk/_generated/core/api.ts +38 -7
- package/src/sdk/_generated/core/client.ts +47 -73
- package/src/sdk/_generated/core/contract.ts +91 -1
- package/src/sdk/_generated/core/mod.ts +0 -1
- package/src/sdk/_generated/core/owned_api.ts +4 -4
- package/src/sdk/_generated/core/schemas.ts +81 -0
- package/src/sdk/_generated/core/types.ts +79 -15
- package/src/sdk/_generated/health/api.ts +29 -5
- package/src/sdk/_generated/health/client.ts +11 -58
- package/src/sdk/_generated/health/contract.ts +2 -10
- package/src/sdk/_generated/health/mod.ts +0 -1
- package/src/sdk/_generated/health/owned_api.ts +2 -2
- package/src/sdk/_generated/health/schemas.ts +1 -9
- package/src/sdk/_generated/health/types.ts +23 -2
- package/src/sdk/_generated/jobs/api.ts +29 -5
- package/src/sdk/_generated/jobs/client.ts +25 -109
- package/src/sdk/_generated/jobs/contract.ts +269 -1
- package/src/sdk/_generated/jobs/mod.ts +0 -1
- package/src/sdk/_generated/jobs/owned_api.ts +30 -9
- package/src/sdk/_generated/jobs/schemas.ts +213 -0
- package/src/sdk/_generated/jobs/types.ts +252 -18
- package/src/sdk/_generated/state/api.ts +29 -5
- package/src/sdk/_generated/state/client.ts +18 -95
- package/src/sdk/_generated/state/mod.ts +0 -1
- package/src/sdk/_generated/state/owned_api.ts +7 -7
- package/src/sdk/_generated/state/types.ts +91 -15
- package/src/server/health.ts +2 -6
- package/src/server/health_schemas.ts +0 -6
- package/src/server/internal_jobs/bindings.ts +11 -0
- package/src/server/internal_jobs/job-manager.ts +553 -24
- package/src/server/internal_jobs/key-coordinator.ts +1080 -0
- package/src/server/internal_jobs/projection.ts +2 -0
- package/src/server/internal_jobs/runtime-worker.ts +17 -1
- package/src/server/internal_jobs/types.ts +6 -0
- package/src/server/runtime.ts +4 -0
- package/src/server/service.ts +645 -625
- package/src/server.ts +14 -7
- package/src/service/deno.ts +0 -5
- package/src/service/drizzle.ts +184 -0
- package/src/service/mod.ts +17 -7
- package/src/service/node.ts +0 -5
- package/src/service/outbox_inbox.ts +354 -88
- package/src/telemetry/metrics.ts +198 -1
- package/src/telemetry/mod.ts +6 -0
- package/src/trellis.ts +286 -105
package/src/client_connect.ts
CHANGED
|
@@ -49,7 +49,12 @@ import {
|
|
|
49
49
|
type TrellisOpts,
|
|
50
50
|
} from "./trellis.js";
|
|
51
51
|
import { TransportError } from "./errors/index.js";
|
|
52
|
-
import {
|
|
52
|
+
import {
|
|
53
|
+
AsyncResult,
|
|
54
|
+
BaseError,
|
|
55
|
+
Result,
|
|
56
|
+
UnexpectedError,
|
|
57
|
+
} from "@qlever-llc/result";
|
|
53
58
|
import { type StaticDecode, Type } from "typebox";
|
|
54
59
|
import { Value } from "typebox/value";
|
|
55
60
|
import {
|
|
@@ -62,6 +67,7 @@ import {
|
|
|
62
67
|
observeNatsTrellisConnection,
|
|
63
68
|
type TrellisConnection,
|
|
64
69
|
} from "./connection.js";
|
|
70
|
+
import { recordTrellisDuration } from "./telemetry/mod.js";
|
|
65
71
|
|
|
66
72
|
type ClientContract<
|
|
67
73
|
TApi extends TrellisAPI = TrellisAPI,
|
|
@@ -116,13 +122,19 @@ function createConnectedClient(args: {
|
|
|
116
122
|
|
|
117
123
|
function clientConnectResult<T>(
|
|
118
124
|
promise: Promise<T>,
|
|
119
|
-
): AsyncResult<T, TransportError | UnexpectedError> {
|
|
125
|
+
): AsyncResult<T, TransportError | UnexpectedError | ClientAuthHandledError> {
|
|
120
126
|
return AsyncResult.from(
|
|
121
127
|
promise.then(
|
|
122
|
-
(value): Result<
|
|
123
|
-
|
|
128
|
+
(value): Result<
|
|
129
|
+
T,
|
|
130
|
+
TransportError | UnexpectedError | ClientAuthHandledError
|
|
131
|
+
> => Result.ok(value),
|
|
132
|
+
(
|
|
133
|
+
cause,
|
|
134
|
+
): Result<T, TransportError | UnexpectedError | ClientAuthHandledError> =>
|
|
124
135
|
Result.err(
|
|
125
|
-
cause instanceof TransportError
|
|
136
|
+
cause instanceof TransportError ||
|
|
137
|
+
cause instanceof ClientAuthHandledError
|
|
126
138
|
? cause
|
|
127
139
|
: new UnexpectedError({ cause }),
|
|
128
140
|
),
|
|
@@ -166,13 +178,27 @@ export type ClientAuthContinuation =
|
|
|
166
178
|
| { status: "handled" }
|
|
167
179
|
| void;
|
|
168
180
|
|
|
181
|
+
export type ClientAuthHandledErrorData = {
|
|
182
|
+
id: string;
|
|
183
|
+
type: "ClientAuthHandledError";
|
|
184
|
+
message: string;
|
|
185
|
+
context?: Record<string, unknown>;
|
|
186
|
+
traceId?: string;
|
|
187
|
+
};
|
|
188
|
+
|
|
169
189
|
/**
|
|
170
190
|
* Error raised when client authentication was delegated to caller-owned routing.
|
|
171
191
|
*/
|
|
172
|
-
export class ClientAuthHandledError
|
|
192
|
+
export class ClientAuthHandledError
|
|
193
|
+
extends BaseError<ClientAuthHandledErrorData> {
|
|
194
|
+
override readonly name = "ClientAuthHandledError" as const;
|
|
195
|
+
|
|
173
196
|
constructor() {
|
|
174
197
|
super("Client authentication was handled by the caller");
|
|
175
|
-
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
override toSerializable(): ClientAuthHandledErrorData {
|
|
201
|
+
return this.baseSerializable() as ClientAuthHandledErrorData;
|
|
176
202
|
}
|
|
177
203
|
}
|
|
178
204
|
|
|
@@ -532,6 +558,7 @@ async function bindClientFlow(args: {
|
|
|
532
558
|
flowId: string;
|
|
533
559
|
sig: string;
|
|
534
560
|
}): Promise<void> {
|
|
561
|
+
const startedAt = performance.now();
|
|
535
562
|
const response = await fetch(
|
|
536
563
|
`${args.trellisUrl}/auth/flow/${encodeURIComponent(args.flowId)}/bind`,
|
|
537
564
|
{
|
|
@@ -596,6 +623,15 @@ async function bindClientFlow(args: {
|
|
|
596
623
|
},
|
|
597
624
|
});
|
|
598
625
|
}
|
|
626
|
+
recordTrellisDuration(
|
|
627
|
+
"trellis.connect.duration",
|
|
628
|
+
performance.now() - startedAt,
|
|
629
|
+
{
|
|
630
|
+
phase: "bootstrap",
|
|
631
|
+
participantKind: "client",
|
|
632
|
+
outcome: "ok",
|
|
633
|
+
},
|
|
634
|
+
);
|
|
599
635
|
}
|
|
600
636
|
|
|
601
637
|
async function fetchClientBootstrap(args: {
|
|
@@ -604,6 +640,7 @@ async function fetchClientBootstrap(args: {
|
|
|
604
640
|
bootstrapSig: string;
|
|
605
641
|
iat: number;
|
|
606
642
|
}): Promise<ClientBootstrapAttemptResponse> {
|
|
643
|
+
const startedAt = performance.now();
|
|
607
644
|
const response = await fetch(`${args.trellisUrl}/bootstrap/client`, {
|
|
608
645
|
method: "POST",
|
|
609
646
|
headers: { "Content-Type": "application/json" },
|
|
@@ -639,12 +676,39 @@ async function fetchClientBootstrap(args: {
|
|
|
639
676
|
}
|
|
640
677
|
|
|
641
678
|
if (Value.Check(ClientBootstrapReadySchema, payload)) {
|
|
679
|
+
recordTrellisDuration(
|
|
680
|
+
"trellis.connect.duration",
|
|
681
|
+
performance.now() - startedAt,
|
|
682
|
+
{
|
|
683
|
+
phase: "bootstrap",
|
|
684
|
+
participantKind: "client",
|
|
685
|
+
outcome: "ok",
|
|
686
|
+
},
|
|
687
|
+
);
|
|
642
688
|
return payload;
|
|
643
689
|
}
|
|
644
690
|
if (Value.Check(ClientBootstrapAuthRequiredSchema, payload)) {
|
|
691
|
+
recordTrellisDuration(
|
|
692
|
+
"trellis.connect.duration",
|
|
693
|
+
performance.now() - startedAt,
|
|
694
|
+
{
|
|
695
|
+
phase: "bootstrap",
|
|
696
|
+
participantKind: "client",
|
|
697
|
+
outcome: "ok",
|
|
698
|
+
},
|
|
699
|
+
);
|
|
645
700
|
return payload;
|
|
646
701
|
}
|
|
647
702
|
if (Value.Check(ClientBootstrapNotReadySchema, payload)) {
|
|
703
|
+
recordTrellisDuration(
|
|
704
|
+
"trellis.connect.duration",
|
|
705
|
+
performance.now() - startedAt,
|
|
706
|
+
{
|
|
707
|
+
phase: "bootstrap",
|
|
708
|
+
participantKind: "client",
|
|
709
|
+
outcome: "ok",
|
|
710
|
+
},
|
|
711
|
+
);
|
|
648
712
|
return payload;
|
|
649
713
|
}
|
|
650
714
|
|
|
@@ -678,6 +742,7 @@ async function fetchClientBootstrapWithRetry(args: {
|
|
|
678
742
|
offsetState: ClockOffsetState;
|
|
679
743
|
}): Promise<ClientBootstrapResponse> {
|
|
680
744
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
745
|
+
const attemptStartedAt = performance.now();
|
|
681
746
|
const requestStartedAtMs = args.deps.now();
|
|
682
747
|
const iat = correctedIatSeconds(
|
|
683
748
|
requestStartedAtMs,
|
|
@@ -690,6 +755,15 @@ async function fetchClientBootstrapWithRetry(args: {
|
|
|
690
755
|
bootstrapSig: await args.identity.bootstrapSig(iat),
|
|
691
756
|
});
|
|
692
757
|
const responseReceivedAtMs = args.deps.now();
|
|
758
|
+
recordTrellisDuration(
|
|
759
|
+
"trellis.connect.duration",
|
|
760
|
+
performance.now() - attemptStartedAt,
|
|
761
|
+
{
|
|
762
|
+
phase: "bootstrap",
|
|
763
|
+
participantKind: "client",
|
|
764
|
+
outcome: "ok",
|
|
765
|
+
},
|
|
766
|
+
);
|
|
693
767
|
|
|
694
768
|
updateClockOffsetFromServer({
|
|
695
769
|
offsetState: args.offsetState,
|
|
@@ -941,6 +1015,7 @@ async function buildSessionKeyLoginUrl(args: {
|
|
|
941
1015
|
}): Promise<
|
|
942
1016
|
{ status: "bound" } | { status: "flow_started"; loginUrl: string }
|
|
943
1017
|
> {
|
|
1018
|
+
const startedAt = performance.now();
|
|
944
1019
|
const context = authRequestContextRecord(args.context);
|
|
945
1020
|
let response = await fetch(`${args.trellisUrl}/auth/requests`, {
|
|
946
1021
|
method: "POST",
|
|
@@ -955,6 +1030,15 @@ async function buildSessionKeyLoginUrl(args: {
|
|
|
955
1030
|
}),
|
|
956
1031
|
});
|
|
957
1032
|
if (await authStartNeedsManifest(response)) {
|
|
1033
|
+
recordTrellisDuration(
|
|
1034
|
+
"trellis.connect.duration",
|
|
1035
|
+
performance.now() - startedAt,
|
|
1036
|
+
{
|
|
1037
|
+
phase: "bootstrap",
|
|
1038
|
+
participantKind: "client",
|
|
1039
|
+
outcome: "ok",
|
|
1040
|
+
},
|
|
1041
|
+
);
|
|
958
1042
|
response = await fetch(`${args.trellisUrl}/auth/requests`, {
|
|
959
1043
|
method: "POST",
|
|
960
1044
|
headers: { "Content-Type": "application/json" },
|
|
@@ -991,6 +1075,15 @@ async function buildSessionKeyLoginUrl(args: {
|
|
|
991
1075
|
(payload as { status?: unknown }).status === "flow_started" &&
|
|
992
1076
|
typeof (payload as { loginUrl?: unknown }).loginUrl === "string"
|
|
993
1077
|
) {
|
|
1078
|
+
recordTrellisDuration(
|
|
1079
|
+
"trellis.connect.duration",
|
|
1080
|
+
performance.now() - startedAt,
|
|
1081
|
+
{
|
|
1082
|
+
phase: "bootstrap",
|
|
1083
|
+
participantKind: "client",
|
|
1084
|
+
outcome: "ok",
|
|
1085
|
+
},
|
|
1086
|
+
);
|
|
994
1087
|
return {
|
|
995
1088
|
status: "flow_started",
|
|
996
1089
|
loginUrl: (payload as { loginUrl: string }).loginUrl,
|
|
@@ -1000,6 +1093,15 @@ async function buildSessionKeyLoginUrl(args: {
|
|
|
1000
1093
|
payload && typeof payload === "object" &&
|
|
1001
1094
|
(payload as { status?: unknown }).status === "bound"
|
|
1002
1095
|
) {
|
|
1096
|
+
recordTrellisDuration(
|
|
1097
|
+
"trellis.connect.duration",
|
|
1098
|
+
performance.now() - startedAt,
|
|
1099
|
+
{
|
|
1100
|
+
phase: "bootstrap",
|
|
1101
|
+
participantKind: "client",
|
|
1102
|
+
outcome: "ok",
|
|
1103
|
+
},
|
|
1104
|
+
);
|
|
1003
1105
|
return { status: "bound" };
|
|
1004
1106
|
}
|
|
1005
1107
|
throw createTransportError({
|
|
@@ -1039,6 +1141,7 @@ export async function connectClientWithDeps<
|
|
|
1039
1141
|
args: ClientConnectArgsFor<TContract>,
|
|
1040
1142
|
deps: ClientConnectDeps,
|
|
1041
1143
|
): Promise<Trellis<TrellisAPI, "client", RuntimeStateStores>> {
|
|
1144
|
+
const totalStartedAt = performance.now();
|
|
1042
1145
|
const trellisUrl = normalizeTrellisUrl(args.trellisUrl);
|
|
1043
1146
|
const identity = await resolveClientIdentity(args.auth);
|
|
1044
1147
|
const currentUrl = args.auth?.mode === "session_key"
|
|
@@ -1082,6 +1185,7 @@ export async function connectClientWithDeps<
|
|
|
1082
1185
|
}
|
|
1083
1186
|
}
|
|
1084
1187
|
|
|
1188
|
+
const initialBootstrapStartedAt = performance.now();
|
|
1085
1189
|
const initialBootstrap = await fetchClientBootstrapWithRetry({
|
|
1086
1190
|
trellisUrl,
|
|
1087
1191
|
sessionKey: identity.sessionKey,
|
|
@@ -1089,11 +1193,30 @@ export async function connectClientWithDeps<
|
|
|
1089
1193
|
deps,
|
|
1090
1194
|
offsetState,
|
|
1091
1195
|
});
|
|
1196
|
+
recordTrellisDuration(
|
|
1197
|
+
"trellis.connect.duration",
|
|
1198
|
+
performance.now() - initialBootstrapStartedAt,
|
|
1199
|
+
{
|
|
1200
|
+
phase: "bootstrap",
|
|
1201
|
+
participantKind: "client",
|
|
1202
|
+
outcome: "ok",
|
|
1203
|
+
},
|
|
1204
|
+
);
|
|
1092
1205
|
|
|
1206
|
+
const authStartedAt = performance.now();
|
|
1093
1207
|
const bootstrap = needsReauth(initialBootstrap) ||
|
|
1094
1208
|
!bootstrapTargetsRequestedContract(initialBootstrap, args)
|
|
1095
1209
|
? await resolveAuthRequired(args, identity, currentUrl, deps, offsetState)
|
|
1096
1210
|
: initialBootstrap;
|
|
1211
|
+
recordTrellisDuration(
|
|
1212
|
+
"trellis.connect.duration",
|
|
1213
|
+
performance.now() - authStartedAt,
|
|
1214
|
+
{
|
|
1215
|
+
phase: "auth_resolution",
|
|
1216
|
+
participantKind: "client",
|
|
1217
|
+
outcome: "ok",
|
|
1218
|
+
},
|
|
1219
|
+
);
|
|
1097
1220
|
|
|
1098
1221
|
if (bootstrap.status !== "ready") {
|
|
1099
1222
|
if (bootstrap.status === "not_ready") {
|
|
@@ -1189,6 +1312,7 @@ export async function connectClientWithDeps<
|
|
|
1189
1312
|
});
|
|
1190
1313
|
let nc: NatsConnection;
|
|
1191
1314
|
try {
|
|
1315
|
+
const natsStartedAt = performance.now();
|
|
1192
1316
|
nc = await transport.connect({
|
|
1193
1317
|
servers: selectClientRuntimeTransportServers(
|
|
1194
1318
|
bootstrap.connectInfo.transports,
|
|
@@ -1197,6 +1321,15 @@ export async function connectClientWithDeps<
|
|
|
1197
1321
|
inboxPrefix: bootstrap.connectInfo.transport.inboxPrefix,
|
|
1198
1322
|
authenticator: runtimeAuth.authenticators,
|
|
1199
1323
|
});
|
|
1324
|
+
recordTrellisDuration(
|
|
1325
|
+
"trellis.connect.duration",
|
|
1326
|
+
performance.now() - natsStartedAt,
|
|
1327
|
+
{
|
|
1328
|
+
phase: "nats_connect",
|
|
1329
|
+
participantKind: "client",
|
|
1330
|
+
outcome: "ok",
|
|
1331
|
+
},
|
|
1332
|
+
);
|
|
1200
1333
|
} catch (error) {
|
|
1201
1334
|
runtimeAuth.stop();
|
|
1202
1335
|
throw createTransportError({
|
|
@@ -1241,7 +1374,7 @@ export async function connectClientWithDeps<
|
|
|
1241
1374
|
TrellisAPI
|
|
1242
1375
|
>["state"];
|
|
1243
1376
|
|
|
1244
|
-
|
|
1377
|
+
const client = createConnectedClient({
|
|
1245
1378
|
name: clientOpts.name ?? "client",
|
|
1246
1379
|
nc,
|
|
1247
1380
|
connection,
|
|
@@ -1257,6 +1390,16 @@ export async function connectClientWithDeps<
|
|
|
1257
1390
|
onSessionNotFound: handleSessionNotFound,
|
|
1258
1391
|
},
|
|
1259
1392
|
});
|
|
1393
|
+
recordTrellisDuration(
|
|
1394
|
+
"trellis.connect.duration",
|
|
1395
|
+
performance.now() - totalStartedAt,
|
|
1396
|
+
{
|
|
1397
|
+
phase: "total",
|
|
1398
|
+
participantKind: "client",
|
|
1399
|
+
outcome: "ok",
|
|
1400
|
+
},
|
|
1401
|
+
);
|
|
1402
|
+
return client;
|
|
1260
1403
|
}
|
|
1261
1404
|
|
|
1262
1405
|
async function resolveAuthRequired<
|
|
@@ -1315,40 +1458,82 @@ async function resolveAuthRequired<
|
|
|
1315
1458
|
});
|
|
1316
1459
|
|
|
1317
1460
|
if (authStart.status === "bound") {
|
|
1318
|
-
|
|
1461
|
+
const bootstrapStartedAt = performance.now();
|
|
1462
|
+
const bootstrap = await fetchClientBootstrapWithRetry({
|
|
1319
1463
|
trellisUrl: normalizeTrellisUrl(args.trellisUrl),
|
|
1320
1464
|
sessionKey: identity.sessionKey,
|
|
1321
1465
|
identity,
|
|
1322
1466
|
deps,
|
|
1323
1467
|
offsetState,
|
|
1324
1468
|
});
|
|
1469
|
+
recordTrellisDuration(
|
|
1470
|
+
"trellis.connect.duration",
|
|
1471
|
+
performance.now() - bootstrapStartedAt,
|
|
1472
|
+
{
|
|
1473
|
+
phase: "bootstrap",
|
|
1474
|
+
participantKind: "client",
|
|
1475
|
+
outcome: "ok",
|
|
1476
|
+
},
|
|
1477
|
+
);
|
|
1478
|
+
return bootstrap;
|
|
1325
1479
|
}
|
|
1326
1480
|
|
|
1327
1481
|
const loginUrl = authStart.loginUrl;
|
|
1328
1482
|
|
|
1483
|
+
const continuationStartedAt = performance.now();
|
|
1329
1484
|
const continuation = await args.onAuthRequired?.({
|
|
1330
1485
|
loginUrl,
|
|
1331
1486
|
sessionKey: identity.sessionKey,
|
|
1332
1487
|
mode: identity.mode,
|
|
1333
1488
|
});
|
|
1489
|
+
recordTrellisDuration(
|
|
1490
|
+
"trellis.connect.duration",
|
|
1491
|
+
performance.now() - continuationStartedAt,
|
|
1492
|
+
{
|
|
1493
|
+
phase: "bootstrap",
|
|
1494
|
+
participantKind: "client",
|
|
1495
|
+
outcome: "ok",
|
|
1496
|
+
},
|
|
1497
|
+
);
|
|
1334
1498
|
if (continuation && continuation.status === "handled") {
|
|
1335
1499
|
throw new ClientAuthHandledError();
|
|
1336
1500
|
}
|
|
1337
1501
|
|
|
1338
1502
|
if (continuation && continuation.status === "bound") {
|
|
1503
|
+
const bindStartedAt = performance.now();
|
|
1339
1504
|
await bindClientFlow({
|
|
1340
1505
|
trellisUrl: normalizeTrellisUrl(args.trellisUrl),
|
|
1341
1506
|
sessionKey: identity.sessionKey,
|
|
1342
1507
|
flowId: continuation.flowId,
|
|
1343
1508
|
sig: await identity.bindFlowSig(continuation.flowId),
|
|
1344
1509
|
});
|
|
1345
|
-
|
|
1510
|
+
recordTrellisDuration(
|
|
1511
|
+
"trellis.connect.duration",
|
|
1512
|
+
performance.now() - bindStartedAt,
|
|
1513
|
+
{
|
|
1514
|
+
phase: "bootstrap",
|
|
1515
|
+
participantKind: "client",
|
|
1516
|
+
outcome: "ok",
|
|
1517
|
+
},
|
|
1518
|
+
);
|
|
1519
|
+
const bootstrapStartedAt = performance.now();
|
|
1520
|
+
const bootstrap = await fetchClientBootstrapWithRetry({
|
|
1346
1521
|
trellisUrl: normalizeTrellisUrl(args.trellisUrl),
|
|
1347
1522
|
sessionKey: identity.sessionKey,
|
|
1348
1523
|
identity,
|
|
1349
1524
|
deps,
|
|
1350
1525
|
offsetState,
|
|
1351
1526
|
});
|
|
1527
|
+
recordTrellisDuration(
|
|
1528
|
+
"trellis.connect.duration",
|
|
1529
|
+
performance.now() - bootstrapStartedAt,
|
|
1530
|
+
{
|
|
1531
|
+
phase: "bootstrap",
|
|
1532
|
+
participantKind: "client",
|
|
1533
|
+
outcome: "ok",
|
|
1534
|
+
},
|
|
1535
|
+
);
|
|
1536
|
+
return bootstrap;
|
|
1352
1537
|
}
|
|
1353
1538
|
|
|
1354
1539
|
if (isBrowserRuntime()) {
|
|
@@ -1370,11 +1555,14 @@ export class TrellisClient {
|
|
|
1370
1555
|
ConnectedTrellisClient<
|
|
1371
1556
|
TContract & { API: { trellis: ApiForClientContract<TContract> } }
|
|
1372
1557
|
>,
|
|
1373
|
-
TransportError | UnexpectedError
|
|
1558
|
+
TransportError | UnexpectedError | ClientAuthHandledError
|
|
1374
1559
|
>;
|
|
1375
1560
|
static connect(
|
|
1376
1561
|
args: TrellisClientConnectArgs,
|
|
1377
|
-
): AsyncResult<
|
|
1562
|
+
): AsyncResult<
|
|
1563
|
+
unknown,
|
|
1564
|
+
TransportError | UnexpectedError | ClientAuthHandledError
|
|
1565
|
+
> {
|
|
1378
1566
|
return clientConnectResult(connectClientWithDeps(args, defaultDeps));
|
|
1379
1567
|
}
|
|
1380
1568
|
}
|
package/src/codec.ts
CHANGED
|
@@ -6,7 +6,17 @@ import {
|
|
|
6
6
|
import { Result } from "@qlever-llc/result";
|
|
7
7
|
import type { StaticDecode, TSchema } from "typebox";
|
|
8
8
|
import { EncodeError, ParseError, Value } from "typebox/value";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
SchemaValidationError,
|
|
11
|
+
UnexpectedError,
|
|
12
|
+
ValidationError,
|
|
13
|
+
} from "./errors/index.js";
|
|
14
|
+
import type { SchemaValidationIssue } from "./errors/SchemaValidationError.js";
|
|
15
|
+
import type { TLocalizedValidationError } from "typebox/error";
|
|
16
|
+
import type {
|
|
17
|
+
TrellisValidationExtension,
|
|
18
|
+
TrellisValidationIssueHint,
|
|
19
|
+
} from "./contract_support/mod.js";
|
|
10
20
|
|
|
11
21
|
export type JsonValue =
|
|
12
22
|
| string
|
|
@@ -18,6 +28,164 @@ export type JsonValue =
|
|
|
18
28
|
[key: string]: JsonValue;
|
|
19
29
|
};
|
|
20
30
|
|
|
31
|
+
const X_TRELLIS_VALIDATION = "x-trellis-validation";
|
|
32
|
+
|
|
33
|
+
function readTrellisValidationExtension(
|
|
34
|
+
schema: unknown,
|
|
35
|
+
): TrellisValidationExtension | undefined {
|
|
36
|
+
if (schema === null || schema === undefined || typeof schema !== "object") {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
const ext = (schema as Record<string, unknown>)[X_TRELLIS_VALIDATION];
|
|
40
|
+
if (ext === null || ext === undefined || typeof ext !== "object") {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
return ext as TrellisValidationExtension;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function resolveSchemaNode(
|
|
47
|
+
root: unknown,
|
|
48
|
+
schemaPath: string,
|
|
49
|
+
): unknown | undefined {
|
|
50
|
+
if (!schemaPath.startsWith("#/")) {
|
|
51
|
+
if (schemaPath === "#") return root;
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
const parts = schemaPath.slice(2).split("/").map(decodeURIComponent);
|
|
55
|
+
let current = root;
|
|
56
|
+
for (const part of parts) {
|
|
57
|
+
if (
|
|
58
|
+
current === null || current === undefined || typeof current !== "object"
|
|
59
|
+
) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
current = (current as Record<string, unknown>)[part];
|
|
63
|
+
}
|
|
64
|
+
return current;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function resolveRequiredErrorNode(
|
|
68
|
+
root: unknown,
|
|
69
|
+
error: TLocalizedValidationError,
|
|
70
|
+
): unknown | undefined {
|
|
71
|
+
const params = error.params as Record<string, unknown> | undefined;
|
|
72
|
+
const missingProperty = (
|
|
73
|
+
params?.missingProperty ??
|
|
74
|
+
(params?.requiredProperties as string[] | undefined)?.[0]
|
|
75
|
+
) as string | undefined;
|
|
76
|
+
if (!missingProperty) return undefined;
|
|
77
|
+
|
|
78
|
+
const objNode = resolveSchemaNode(root, error.schemaPath);
|
|
79
|
+
if (!objNode || typeof objNode !== "object") return undefined;
|
|
80
|
+
|
|
81
|
+
const properties = (objNode as Record<string, unknown>).properties;
|
|
82
|
+
if (!properties || typeof properties !== "object") return undefined;
|
|
83
|
+
|
|
84
|
+
return (properties as Record<string, unknown>)[missingProperty];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const ALLOWED_HINT_KEYWORDS = new Set([
|
|
88
|
+
"required",
|
|
89
|
+
"minItems",
|
|
90
|
+
"maxItems",
|
|
91
|
+
"minLength",
|
|
92
|
+
"maxLength",
|
|
93
|
+
"minimum",
|
|
94
|
+
"maximum",
|
|
95
|
+
"exclusiveMinimum",
|
|
96
|
+
"exclusiveMaximum",
|
|
97
|
+
"pattern",
|
|
98
|
+
"format",
|
|
99
|
+
"enum",
|
|
100
|
+
"const",
|
|
101
|
+
]);
|
|
102
|
+
|
|
103
|
+
function keywordAllowsHint(keyword: string): boolean {
|
|
104
|
+
return ALLOWED_HINT_KEYWORDS.has(keyword);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function typeboxIssueToPath(error: TLocalizedValidationError): string {
|
|
108
|
+
if (error.keyword === "required") {
|
|
109
|
+
const params = error.params as Record<string, unknown> | undefined;
|
|
110
|
+
const missingProperty = (
|
|
111
|
+
params?.missingProperty ??
|
|
112
|
+
(params?.requiredProperties as string[] | undefined)?.[0]
|
|
113
|
+
) as string | undefined;
|
|
114
|
+
if (missingProperty) {
|
|
115
|
+
return error.instancePath
|
|
116
|
+
? `${error.instancePath}/${missingProperty}`
|
|
117
|
+
: `/${missingProperty}`;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return error.instancePath || error.schemaPath;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function collectValidationIssues(
|
|
124
|
+
root: unknown,
|
|
125
|
+
errors: Iterable<TLocalizedValidationError>,
|
|
126
|
+
): {
|
|
127
|
+
annotated: SchemaValidationIssue[];
|
|
128
|
+
unannotated: TLocalizedValidationError[];
|
|
129
|
+
} {
|
|
130
|
+
const annotated: SchemaValidationIssue[] = [];
|
|
131
|
+
const unannotated: TLocalizedValidationError[] = [];
|
|
132
|
+
|
|
133
|
+
for (const error of [...errors]) {
|
|
134
|
+
const schemaNode = error.keyword === "required"
|
|
135
|
+
? resolveRequiredErrorNode(root, error)
|
|
136
|
+
: resolveSchemaNode(root, error.schemaPath);
|
|
137
|
+
|
|
138
|
+
const extension = schemaNode !== undefined
|
|
139
|
+
? readTrellisValidationExtension(schemaNode)
|
|
140
|
+
: undefined;
|
|
141
|
+
|
|
142
|
+
if (
|
|
143
|
+
extension !== undefined &&
|
|
144
|
+
keywordAllowsHint(error.keyword) &&
|
|
145
|
+
extension.issues?.[error.keyword] !== undefined
|
|
146
|
+
) {
|
|
147
|
+
const hint = extension.issues[error.keyword]!;
|
|
148
|
+
if (hint.code !== undefined) {
|
|
149
|
+
annotated.push({
|
|
150
|
+
path: typeboxIssueToPath(error),
|
|
151
|
+
schemaPath: error.schemaPath,
|
|
152
|
+
keyword: error.keyword,
|
|
153
|
+
code: hint.code,
|
|
154
|
+
message: hint.message || error.message,
|
|
155
|
+
label: hint.label ?? extension.label,
|
|
156
|
+
note: hint.note ?? extension.note,
|
|
157
|
+
i18nKey: hint.i18nKey,
|
|
158
|
+
severity: hint.severity ?? "error",
|
|
159
|
+
params: error.params as Record<string, unknown>,
|
|
160
|
+
});
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
unannotated.push(error);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return { annotated, unannotated };
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function buildValidationError(
|
|
172
|
+
schema: unknown,
|
|
173
|
+
data: unknown,
|
|
174
|
+
errors: Iterable<TLocalizedValidationError>,
|
|
175
|
+
cause: ParseError | EncodeError,
|
|
176
|
+
): SchemaValidationError | ValidationError {
|
|
177
|
+
const { annotated, unannotated } = collectValidationIssues(schema, errors);
|
|
178
|
+
if (annotated.length > 0 && unannotated.length === 0) {
|
|
179
|
+
return new SchemaValidationError({ issues: annotated, cause });
|
|
180
|
+
}
|
|
181
|
+
return new ValidationError({
|
|
182
|
+
errors: unannotated.length > 0
|
|
183
|
+
? unannotated
|
|
184
|
+
: annotated.map((i) => ({ path: i.path, message: i.message })),
|
|
185
|
+
cause,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
21
189
|
function parseWithSchema(schema: TSchema, data: JsonValue): unknown {
|
|
22
190
|
return Value.Parse(schema, data);
|
|
23
191
|
}
|
|
@@ -29,13 +197,16 @@ function encodeWithSchema(schema: TSchema, data: unknown): string {
|
|
|
29
197
|
export function parse<T extends TSchema>(
|
|
30
198
|
schema: T,
|
|
31
199
|
data: JsonValue,
|
|
32
|
-
): Result<
|
|
200
|
+
): Result<
|
|
201
|
+
StaticDecode<T>,
|
|
202
|
+
SchemaValidationError | ValidationError | UnexpectedError
|
|
203
|
+
> {
|
|
33
204
|
try {
|
|
34
205
|
return Result.ok(parseWithSchema(schema, data) as StaticDecode<T>);
|
|
35
206
|
} catch (cause) {
|
|
36
207
|
if (cause instanceof ParseError) {
|
|
37
208
|
const errors = Value.Errors(schema, data);
|
|
38
|
-
return Result.err(
|
|
209
|
+
return Result.err(buildValidationError(schema, data, errors, cause));
|
|
39
210
|
}
|
|
40
211
|
return Result.err(new UnexpectedError({ cause }));
|
|
41
212
|
}
|
|
@@ -44,7 +215,10 @@ export function parse<T extends TSchema>(
|
|
|
44
215
|
export function parseSchema<S extends SchemaLike>(
|
|
45
216
|
schema: S,
|
|
46
217
|
data: JsonValue,
|
|
47
|
-
): Result<
|
|
218
|
+
): Result<
|
|
219
|
+
InferSchemaType<S>,
|
|
220
|
+
SchemaValidationError | ValidationError | UnexpectedError
|
|
221
|
+
> {
|
|
48
222
|
const raw = unwrapSchema(schema);
|
|
49
223
|
try {
|
|
50
224
|
return Result.ok(
|
|
@@ -53,23 +227,24 @@ export function parseSchema<S extends SchemaLike>(
|
|
|
53
227
|
} catch (cause) {
|
|
54
228
|
if (cause instanceof ParseError) {
|
|
55
229
|
const errors = Value.Errors(raw as TSchema, data);
|
|
56
|
-
return Result.err(
|
|
230
|
+
return Result.err(buildValidationError(raw, data, errors, cause));
|
|
57
231
|
}
|
|
58
232
|
return Result.err(new UnexpectedError({ cause }));
|
|
59
233
|
}
|
|
60
234
|
}
|
|
61
235
|
|
|
236
|
+
/** Parses unknown JSON-compatible data with an arbitrary Trellis schema. */
|
|
62
237
|
export function parseUnknownSchema(
|
|
63
238
|
schema: SchemaLike,
|
|
64
239
|
data: JsonValue,
|
|
65
|
-
): Result<unknown, ValidationError | UnexpectedError> {
|
|
240
|
+
): Result<unknown, SchemaValidationError | ValidationError | UnexpectedError> {
|
|
66
241
|
const raw = unwrapSchema(schema);
|
|
67
242
|
try {
|
|
68
243
|
return Result.ok(parseWithSchema(raw as TSchema, data));
|
|
69
244
|
} catch (cause) {
|
|
70
245
|
if (cause instanceof ParseError) {
|
|
71
246
|
const errors = Value.Errors(raw as TSchema, data);
|
|
72
|
-
return Result.err(
|
|
247
|
+
return Result.err(buildValidationError(raw, data, errors, cause));
|
|
73
248
|
}
|
|
74
249
|
return Result.err(new UnexpectedError({ cause }));
|
|
75
250
|
}
|
|
@@ -78,13 +253,13 @@ export function parseUnknownSchema(
|
|
|
78
253
|
export function encode<T extends TSchema>(
|
|
79
254
|
schema: T,
|
|
80
255
|
data: unknown,
|
|
81
|
-
): Result<string, ValidationError | UnexpectedError> {
|
|
256
|
+
): Result<string, SchemaValidationError | ValidationError | UnexpectedError> {
|
|
82
257
|
try {
|
|
83
258
|
return Result.ok(encodeWithSchema(schema, data));
|
|
84
259
|
} catch (cause) {
|
|
85
260
|
if (cause instanceof EncodeError) {
|
|
86
261
|
const errors = Value.Errors(schema, data);
|
|
87
|
-
return Result.err(
|
|
262
|
+
return Result.err(buildValidationError(schema, data, errors, cause));
|
|
88
263
|
}
|
|
89
264
|
return Result.err(new UnexpectedError({ cause }));
|
|
90
265
|
}
|
|
@@ -93,14 +268,14 @@ export function encode<T extends TSchema>(
|
|
|
93
268
|
export function encodeSchema(
|
|
94
269
|
schema: SchemaLike,
|
|
95
270
|
data: unknown,
|
|
96
|
-
): Result<string, ValidationError | UnexpectedError> {
|
|
271
|
+
): Result<string, SchemaValidationError | ValidationError | UnexpectedError> {
|
|
97
272
|
const raw = unwrapSchema(schema);
|
|
98
273
|
try {
|
|
99
274
|
return Result.ok(encodeWithSchema(raw as TSchema, data));
|
|
100
275
|
} catch (cause) {
|
|
101
276
|
if (cause instanceof EncodeError) {
|
|
102
277
|
const errors = Value.Errors(raw as TSchema, data);
|
|
103
|
-
return Result.err(
|
|
278
|
+
return Result.err(buildValidationError(raw, data, errors, cause));
|
|
104
279
|
}
|
|
105
280
|
return Result.err(new UnexpectedError({ cause }));
|
|
106
281
|
}
|