@sixb/core 0.1.12 → 0.1.14
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/dist/actions/index.d.ts +2 -2
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +28 -26
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/read-facade.d.ts +14 -16
- package/dist/actions/read-facade.d.ts.map +1 -1
- package/dist/actions/request.d.ts.map +1 -1
- package/dist/actions/run-dispatch.d.ts +2 -0
- package/dist/actions/run-dispatch.d.ts.map +1 -1
- package/dist/actions/types/context.d.ts +18 -31
- package/dist/actions/types/context.d.ts.map +1 -1
- package/dist/actions/types/params.d.ts +2 -1
- package/dist/actions/types/params.d.ts.map +1 -1
- package/dist/actions/worker.js +1 -1
- package/dist/agents/index.js +41 -39
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/streams/index.js +2 -2
- package/dist/agents/streams/internal.js +2 -2
- package/dist/assert-never.d.ts +6 -0
- package/dist/assert-never.d.ts.map +1 -0
- package/dist/auth/client-address.d.ts +3 -0
- package/dist/auth/client-address.d.ts.map +1 -0
- package/dist/auth/csrf.d.ts +5 -1
- package/dist/auth/csrf.d.ts.map +1 -1
- package/dist/auth/errors.d.ts +12 -0
- package/dist/auth/errors.d.ts.map +1 -1
- package/dist/auth/index.d.ts +4 -3
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +16 -8
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/runtime.d.ts +58 -41
- package/dist/auth/runtime.d.ts.map +1 -1
- package/dist/auth/session-cache.d.ts +10 -3
- package/dist/auth/session-cache.d.ts.map +1 -1
- package/dist/auth/sessions.d.ts +12 -0
- package/dist/auth/sessions.d.ts.map +1 -1
- package/dist/auth/strategy.d.ts +2 -0
- package/dist/auth/strategy.d.ts.map +1 -1
- package/dist/auth/strategy.js +4 -2
- package/dist/auth/strategy.js.map +1 -1
- package/dist/auth/types.d.ts +16 -15
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/authorization/index.js +3 -3
- package/dist/bootstrap/index.d.ts +1 -1
- package/dist/bootstrap/index.d.ts.map +1 -1
- package/dist/bootstrap/index.js +45 -43
- package/dist/bootstrap/index.js.map +1 -1
- package/dist/bootstrap/ontology-type-manifest.d.ts +8 -0
- package/dist/bootstrap/ontology-type-manifest.d.ts.map +1 -1
- package/dist/{chunk-m7cx05vp.js → chunk-00pfcqh4.js} +126 -59
- package/dist/{chunk-m7cx05vp.js.map → chunk-00pfcqh4.js.map} +13 -12
- package/dist/{chunk-nzsy3xrp.js → chunk-16jenmzw.js} +69 -44
- package/dist/{chunk-nzsy3xrp.js.map → chunk-16jenmzw.js.map} +7 -7
- package/dist/{chunk-y3ev53cq.js → chunk-2fv8sajb.js} +2 -2
- package/dist/{chunk-q5gz3g2j.js → chunk-2jntasmh.js} +13 -16
- package/dist/{chunk-q5gz3g2j.js.map → chunk-2jntasmh.js.map} +3 -3
- package/dist/chunk-3a338wrp.js +191 -0
- package/dist/chunk-3a338wrp.js.map +11 -0
- package/dist/{chunk-ybhz3j9g.js → chunk-3fpgxpsq.js} +104 -148
- package/dist/{chunk-ybhz3j9g.js.map → chunk-3fpgxpsq.js.map} +7 -8
- package/dist/{chunk-eyjzgav0.js → chunk-3nx8vj5a.js} +6 -4
- package/dist/chunk-3nx8vj5a.js.map +12 -0
- package/dist/{chunk-5tetw4hn.js → chunk-4tnrzqqh.js} +1 -1
- package/dist/{chunk-3ghw2t5q.js → chunk-4ypbe95r.js} +10 -16
- package/dist/chunk-4ypbe95r.js.map +10 -0
- package/dist/{chunk-2cxv584m.js → chunk-6rzb1g6h.js} +358 -248
- package/dist/chunk-6rzb1g6h.js.map +44 -0
- package/dist/{chunk-7zgecwy1.js → chunk-6x0pqh32.js} +12 -1
- package/dist/{chunk-7zgecwy1.js.map → chunk-6x0pqh32.js.map} +3 -3
- package/dist/{chunk-6ma8dvzc.js → chunk-728fp090.js} +49 -42
- package/dist/chunk-728fp090.js.map +15 -0
- package/dist/chunk-96yw3pwd.js.map +2 -2
- package/dist/{chunk-4k53sm9e.js → chunk-a0073121.js} +59 -59
- package/dist/{chunk-4k53sm9e.js.map → chunk-a0073121.js.map} +5 -5
- package/dist/{chunk-y1ahv8b7.js → chunk-bdhfn0ww.js} +1 -1
- package/dist/{chunk-kept9cdd.js → chunk-bxx3ms5t.js} +1 -1
- package/dist/{chunk-xtfryrfb.js → chunk-cbn96bve.js} +2 -2
- package/dist/{chunk-vsg0g7h9.js → chunk-d8yes9yx.js} +304 -45
- package/dist/chunk-d8yes9yx.js.map +20 -0
- package/dist/{chunk-vpxss818.js → chunk-drz59ve0.js} +9 -8
- package/dist/chunk-drz59ve0.js.map +10 -0
- package/dist/{chunk-7c2g3sz9.js → chunk-dsfw1bdr.js} +5 -5
- package/dist/{chunk-7c2g3sz9.js.map → chunk-dsfw1bdr.js.map} +1 -1
- package/dist/{chunk-qm535afa.js → chunk-dv4ct8mp.js} +66 -24
- package/dist/chunk-dv4ct8mp.js.map +15 -0
- package/dist/{chunk-t7dzd1tm.js → chunk-e2c5yxfe.js} +2 -2
- package/dist/{chunk-p6r1ex7t.js → chunk-ffwvdgk1.js} +5 -13
- package/dist/chunk-ffwvdgk1.js.map +10 -0
- package/dist/{chunk-tg4g4zh0.js → chunk-gct3m1da.js} +9 -9
- package/dist/{chunk-tg4g4zh0.js.map → chunk-gct3m1da.js.map} +3 -3
- package/dist/chunk-h89wz928.js +42 -0
- package/dist/chunk-h89wz928.js.map +10 -0
- package/dist/{chunk-b768c93y.js → chunk-hj0n3c2p.js} +83 -28
- package/dist/{chunk-b768c93y.js.map → chunk-hj0n3c2p.js.map} +5 -5
- package/dist/{chunk-hkw8rykk.js → chunk-ht4a7mjg.js} +74 -4
- package/dist/chunk-ht4a7mjg.js.map +15 -0
- package/dist/{chunk-7qnvhtcd.js → chunk-hxgj4kzd.js} +17 -17
- package/dist/{chunk-7qnvhtcd.js.map → chunk-hxgj4kzd.js.map} +5 -5
- package/dist/{chunk-bg2bs62d.js → chunk-jfdggg1p.js} +5 -5
- package/dist/{chunk-f06sf7rr.js → chunk-k4kkp58d.js} +18 -5
- package/dist/chunk-k4kkp58d.js.map +11 -0
- package/dist/{chunk-e1f1sqba.js → chunk-kxea54yg.js} +3 -3
- package/dist/{chunk-2h63nrde.js → chunk-ky7zpbtt.js} +5 -7
- package/dist/{chunk-2h63nrde.js.map → chunk-ky7zpbtt.js.map} +3 -4
- package/dist/chunk-m4ehq95f.js +9 -0
- package/dist/chunk-m4ehq95f.js.map +10 -0
- package/dist/{chunk-0mza4xb2.js → chunk-m8zkvep1.js} +2 -2
- package/dist/{chunk-xn686q2e.js → chunk-ma1mhh7w.js} +75 -57
- package/dist/{chunk-xn686q2e.js.map → chunk-ma1mhh7w.js.map} +3 -3
- package/dist/{chunk-yxb4c62x.js → chunk-mr60an99.js} +3 -2
- package/dist/{chunk-yxb4c62x.js.map → chunk-mr60an99.js.map} +3 -3
- package/dist/{chunk-g50nxqs5.js → chunk-pvgpckm1.js} +63 -20
- package/dist/chunk-pvgpckm1.js.map +20 -0
- package/dist/{chunk-jjwhy3rs.js → chunk-q2xghyft.js} +5 -5
- package/dist/chunk-rdghfsss.js.map +2 -2
- package/dist/{chunk-bbaa1fet.js → chunk-rzcjp5m2.js} +7 -3
- package/dist/chunk-rzcjp5m2.js.map +25 -0
- package/dist/{chunk-hzw7yv5g.js → chunk-rzkr70gr.js} +5 -1
- package/dist/{chunk-hzw7yv5g.js.map → chunk-rzkr70gr.js.map} +3 -3
- package/dist/{chunk-axndsymr.js → chunk-tw03bsmb.js} +2 -2
- package/dist/{chunk-axndsymr.js.map → chunk-tw03bsmb.js.map} +3 -3
- package/dist/{chunk-y0v18c2j.js → chunk-vef6qa14.js} +2 -2
- package/dist/{chunk-gzt6v1ja.js → chunk-vn3yh259.js} +1 -1
- package/dist/{chunk-sfypc7mk.js → chunk-wn7mznxc.js} +4 -4
- package/dist/{chunk-r5zythxp.js → chunk-wnxabtn4.js} +7 -7
- package/dist/{chunk-4ph94nhd.js → chunk-ww185kt6.js} +2 -2
- package/dist/{chunk-3h7ctayx.js → chunk-xgptywp0.js} +4 -3
- package/dist/chunk-xgptywp0.js.map +11 -0
- package/dist/{chunk-gswwr35f.js → chunk-y487ywrv.js} +4 -4
- package/dist/{chunk-bet1rb9h.js → chunk-y6vnvayj.js} +1 -1
- package/dist/{chunk-x9tmx3fc.js → chunk-ypj2wqtj.js} +3 -6
- package/dist/{chunk-x9tmx3fc.js.map → chunk-ypj2wqtj.js.map} +4 -4
- package/dist/{chunk-3bnt2wna.js → chunk-yvf2jqj8.js} +1 -1
- package/dist/{chunk-g2gezsg5.js → chunk-z9h698s8.js} +1 -1
- package/dist/{chunk-wjffn5m4.js → chunk-zdkcdshk.js} +3 -36
- package/dist/{chunk-wjffn5m4.js.map → chunk-zdkcdshk.js.map} +3 -4
- package/dist/{chunk-bfjv1adk.js → chunk-znw0zvy4.js} +1 -1
- package/dist/edits/types.d.ts +19 -19
- package/dist/edits/types.d.ts.map +1 -1
- package/dist/error-reporting/internal.js +3 -3
- package/dist/errors/catalog.d.ts +4 -0
- package/dist/errors/catalog.d.ts.map +1 -1
- package/dist/errors/internal.js +1 -1
- package/dist/events/envelope.d.ts +0 -12
- package/dist/events/envelope.d.ts.map +1 -1
- package/dist/events/index.d.ts +1 -1
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +3 -3
- package/dist/events/service.d.ts +1 -2
- package/dist/events/service.d.ts.map +1 -1
- package/dist/events/toStoredEvent.d.ts +1 -2
- package/dist/events/toStoredEvent.d.ts.map +1 -1
- package/dist/events/types/index.d.ts +2 -1
- package/dist/events/types/index.d.ts.map +1 -1
- package/dist/execution/agent.d.ts +1 -2
- package/dist/execution/agent.d.ts.map +1 -1
- package/dist/execution/agent.js +39 -37
- package/dist/execution/agent.js.map +1 -1
- package/dist/execution/authorized-object-reader.d.ts.map +1 -1
- package/dist/execution/primitive.d.ts +1 -2
- package/dist/execution/primitive.d.ts.map +1 -1
- package/dist/execution/primitive.js +38 -36
- package/dist/execution/primitive.js.map +3 -3
- package/dist/execution/request.d.ts +1 -2
- package/dist/execution/request.d.ts.map +1 -1
- package/dist/execution/request.js +39 -37
- package/dist/execution/request.js.map +3 -3
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +56 -50
- package/dist/index.js.map +1 -1
- package/dist/maintenance/ontology-maintenance.d.ts +11 -1
- package/dist/maintenance/ontology-maintenance.d.ts.map +1 -1
- package/dist/materialization/errors.d.ts +3 -1
- package/dist/materialization/errors.d.ts.map +1 -1
- package/dist/materialization/events.d.ts +27 -2
- package/dist/materialization/events.d.ts.map +1 -1
- package/dist/materializer/edits/commit.d.ts.map +1 -1
- package/dist/materializer/edits/operations.d.ts +2 -1
- package/dist/materializer/edits/operations.d.ts.map +1 -1
- package/dist/materializer/edits/plan.d.ts +2 -2
- package/dist/materializer/edits/plan.d.ts.map +1 -1
- package/dist/materializer/edits/user-refs.d.ts +30 -0
- package/dist/materializer/edits/user-refs.d.ts.map +1 -0
- package/dist/materializer/effective/build-events.d.ts +2 -2
- package/dist/materializer/effective/build-events.d.ts.map +1 -1
- package/dist/materializer/execution/scope.d.ts +11 -3
- package/dist/materializer/execution/scope.d.ts.map +1 -1
- package/dist/materializer/index.js +23 -21
- package/dist/materializer/index.js.map +1 -1
- package/dist/materializer/projections/replacement-plan.d.ts +2 -0
- package/dist/materializer/projections/replacement-plan.d.ts.map +1 -1
- package/dist/materializer/telemetry/plan.d.ts +2 -2
- package/dist/materializer/telemetry/plan.d.ts.map +1 -1
- package/dist/models/execution/index.js +23 -21
- package/dist/models/execution/index.js.map +1 -1
- package/dist/models/index.js +1 -1
- package/dist/objects/execution.d.ts +21 -27
- package/dist/objects/execution.d.ts.map +1 -1
- package/dist/objects/index.js +28 -26
- package/dist/objects/index.js.map +1 -1
- package/dist/objects/query/executor.d.ts.map +1 -1
- package/dist/objects/query/index.js +27 -25
- package/dist/objects/query/index.js.map +1 -1
- package/dist/objects/query/ir.d.ts +8 -1
- package/dist/objects/query/ir.d.ts.map +1 -1
- package/dist/objects/query/scalar-values.d.ts.map +1 -1
- package/dist/objects/query/validate.d.ts.map +1 -1
- package/dist/objects/sdk/object-handle.d.ts +1 -2
- package/dist/objects/sdk/object-handle.d.ts.map +1 -1
- package/dist/objects/sdk/object-set.d.ts +2 -3
- package/dist/objects/sdk/object-set.d.ts.map +1 -1
- package/dist/objects/sdk/query-builder.d.ts +8 -10
- package/dist/objects/sdk/query-builder.d.ts.map +1 -1
- package/dist/objects/sdk/telemetry-channel.d.ts +1 -2
- package/dist/objects/sdk/telemetry-channel.d.ts.map +1 -1
- package/dist/objects/sdk/where.d.ts +2 -3
- package/dist/objects/sdk/where.d.ts.map +1 -1
- package/dist/ontology/builders.d.ts +11 -10
- package/dist/ontology/builders.d.ts.map +1 -1
- package/dist/ontology/index.d.ts +4 -2
- package/dist/ontology/index.d.ts.map +1 -1
- package/dist/ontology/index.js +6 -4
- package/dist/ontology/index.js.map +1 -1
- package/dist/ontology/inference/index.d.ts +34 -22
- package/dist/ontology/inference/index.d.ts.map +1 -1
- package/dist/ontology/internal.d.ts +1 -0
- package/dist/ontology/internal.d.ts.map +1 -1
- package/dist/ontology/internal.js +9 -7
- package/dist/ontology/internal.js.map +1 -1
- package/dist/ontology/primitives.d.ts +38 -0
- package/dist/ontology/primitives.d.ts.map +1 -0
- package/dist/ontology/query-capabilities.d.ts +38 -0
- package/dist/ontology/query-capabilities.d.ts.map +1 -0
- package/dist/ontology/refs.d.ts +23 -2
- package/dist/ontology/refs.d.ts.map +1 -1
- package/dist/ontology/registered.d.ts +16 -0
- package/dist/ontology/registered.d.ts.map +1 -0
- package/dist/ontology/registry.d.ts.map +1 -1
- package/dist/ontology/tokens.d.ts +35 -1
- package/dist/ontology/tokens.d.ts.map +1 -1
- package/dist/ontology/types.d.ts +18 -4
- package/dist/ontology/types.d.ts.map +1 -1
- package/dist/ontology/user-ref.d.ts +35 -0
- package/dist/ontology/user-ref.d.ts.map +1 -0
- package/dist/ontology/validation/definition.d.ts.map +1 -1
- package/dist/ontology/validation/index.d.ts +1 -1
- package/dist/ontology/validation/index.d.ts.map +1 -1
- package/dist/ontology/validation/normalize.d.ts.map +1 -1
- package/dist/ontology/validation/properties.d.ts +6 -1
- package/dist/ontology/validation/properties.d.ts.map +1 -1
- package/dist/ontology/validation/query.d.ts.map +1 -1
- package/dist/ontology/validation/schema.d.ts.map +1 -1
- package/dist/pipelines/index.js +26 -24
- package/dist/pipelines/index.js.map +1 -1
- package/dist/predicates/types.d.ts +53 -3
- package/dist/predicates/types.d.ts.map +1 -1
- package/dist/projections/builders.d.ts +19 -1
- package/dist/projections/builders.d.ts.map +1 -1
- package/dist/projections/internal.js +23 -21
- package/dist/projections/internal.js.map +1 -1
- package/dist/projections/validation.d.ts.map +1 -1
- package/dist/query.js +2 -2
- package/dist/queues/in-memory.d.ts +1 -1
- package/dist/queues/in-memory.d.ts.map +1 -1
- package/dist/runtime/create.d.ts +1 -1
- package/dist/runtime/create.d.ts.map +1 -1
- package/dist/runtime/host.d.ts +5 -5
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/internal.js +27 -25
- package/dist/runtime/internal.js.map +1 -1
- package/dist/runtime/sixb.d.ts +5 -5
- package/dist/runtime/sixb.d.ts.map +1 -1
- package/dist/runtime/types.d.ts +171 -188
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/sandboxes/index.js +5 -5
- package/dist/sandboxes/sandbox.d.ts +4 -1
- package/dist/sandboxes/sandbox.d.ts.map +1 -1
- package/dist/shared/params/types.d.ts +4 -3
- package/dist/shared/params/types.d.ts.map +1 -1
- package/dist/shared/params/user-refs.d.ts +19 -0
- package/dist/shared/params/user-refs.d.ts.map +1 -0
- package/dist/shares/compiler.d.ts.map +1 -1
- package/dist/shares/internal.js +24 -22
- package/dist/shares/internal.js.map +2 -2
- package/dist/storage/action-runs/failure.js +2 -2
- package/dist/storage/action-runs/types.d.ts +1 -1
- package/dist/storage/action-runs/types.d.ts.map +1 -1
- package/dist/storage/agents/provider.js +1 -1
- package/dist/storage/ai-limits/enforcement.js +2 -2
- package/dist/storage/auth/errors.d.ts +1 -1
- package/dist/storage/auth/errors.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/access-tokens.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/auth-storage.d.ts +2 -1
- package/dist/storage/auth/in-memory/auth-storage.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/device-authorizations.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/sessions.d.ts +8 -1
- package/dist/storage/auth/in-memory/sessions.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/shared.d.ts.map +1 -1
- package/dist/storage/auth/index.d.ts +1 -1
- package/dist/storage/auth/index.d.ts.map +1 -1
- package/dist/storage/auth/types.d.ts +77 -20
- package/dist/storage/auth/types.d.ts.map +1 -1
- package/dist/storage/connector-connections/provider.js +1 -1
- package/dist/storage/executions/provider.js +1 -1
- package/dist/storage/file-upload-sessions/in-memory.d.ts +9 -18
- package/dist/storage/file-upload-sessions/in-memory.d.ts.map +1 -1
- package/dist/storage/file-upload-sessions/index.d.ts +1 -1
- package/dist/storage/file-upload-sessions/index.d.ts.map +1 -1
- package/dist/storage/file-upload-sessions/provider.d.ts +52 -0
- package/dist/storage/file-upload-sessions/provider.d.ts.map +1 -0
- package/dist/storage/file-upload-sessions/provider.js +24 -0
- package/dist/storage/file-upload-sessions/provider.js.map +9 -0
- package/dist/storage/file-upload-sessions/types.d.ts +19 -1
- package/dist/storage/file-upload-sessions/types.d.ts.map +1 -1
- package/dist/storage/file-upload-sessions/utils.d.ts +8 -2
- package/dist/storage/file-upload-sessions/utils.d.ts.map +1 -1
- package/dist/storage/index.d.ts +3 -3
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +29 -25
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/internal.js +11 -9
- package/dist/storage/internal.js.map +1 -1
- package/dist/storage/objects/in-memory/query.d.ts.map +1 -1
- package/dist/storage/ontology/commits.d.ts +6 -2
- package/dist/storage/ontology/commits.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/provider-work.d.ts.map +1 -1
- package/dist/storage/ontology/provider.d.ts +14 -1
- package/dist/storage/ontology/provider.d.ts.map +1 -1
- package/dist/storage/ontology/provider.js +8 -2
- package/dist/storage/ontology/provider.js.map +1 -1
- package/dist/storage/operation-scope.d.ts.map +1 -1
- package/dist/storage/operation-scope.js +1 -1
- package/dist/storage/projection-runs/provider.js +2 -2
- package/dist/storage/types.d.ts +1 -1
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/workflow-interventions/index.d.ts +1 -1
- package/dist/storage/workflow-interventions/index.d.ts.map +1 -1
- package/dist/storage/workflow-interventions/types.d.ts +5 -8
- package/dist/storage/workflow-interventions/types.d.ts.map +1 -1
- package/dist/storage/workflow-runs/provider.js +8 -8
- package/dist/syncs/index.js +27 -25
- package/dist/syncs/index.js.map +1 -1
- package/dist/testing/action-execution.d.ts +4 -0
- package/dist/testing/action-execution.d.ts.map +1 -1
- package/dist/testing/auth-storage-contract.d.ts.map +1 -1
- package/dist/testing/execution.d.ts +1 -2
- package/dist/testing/execution.d.ts.map +1 -1
- package/dist/testing/file-upload-session-storage-contract.d.ts +12 -0
- package/dist/testing/file-upload-session-storage-contract.d.ts.map +1 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +2035 -1358
- package/dist/testing/index.js.map +15 -13
- package/dist/testing/materializer-storage-contract.d.ts.map +1 -1
- package/dist/testing/object-query-contract.d.ts.map +1 -1
- package/dist/testing/ontology-contract-fixture.d.ts +8 -0
- package/dist/testing/ontology-contract-fixture.d.ts.map +1 -1
- package/dist/testing/ontology-storage-contract.d.ts.map +1 -1
- package/dist/testing/sandboxes-contract.d.ts.map +1 -1
- package/dist/testing/workflow-intervention-storage-contract.d.ts +8 -0
- package/dist/testing/workflow-intervention-storage-contract.d.ts.map +1 -0
- package/dist/webhooks/internal.js +24 -22
- package/dist/webhooks/internal.js.map +2 -2
- package/dist/webhooks/types.d.ts +2 -2
- package/dist/webhooks/types.d.ts.map +1 -1
- package/dist/workers/index.js +1 -1
- package/dist/workflows/index.js +42 -40
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/run-dispatch.d.ts.map +1 -1
- package/dist/workflows/types.d.ts +2 -2
- package/dist/workflows/types.d.ts.map +1 -1
- package/package.json +7 -1
- package/src/actions/index.ts +0 -3
- package/src/actions/read-facade.ts +102 -62
- package/src/actions/request.ts +13 -0
- package/src/actions/run-dispatch.ts +3 -0
- package/src/actions/types/context.ts +17 -65
- package/src/actions/types/params.ts +2 -1
- package/src/agents/authority.ts +1 -1
- package/src/assert-never.ts +7 -0
- package/src/auth/client-address.ts +12 -0
- package/src/auth/csrf.ts +14 -5
- package/src/auth/errors.ts +23 -0
- package/src/auth/index.ts +4 -3
- package/src/auth/runtime.ts +353 -297
- package/src/auth/session-cache.ts +18 -6
- package/src/auth/sessions.ts +30 -0
- package/src/auth/strategy.ts +2 -0
- package/src/auth/types.ts +15 -17
- package/src/bootstrap/index.ts +1 -0
- package/src/bootstrap/ontology-type-manifest.ts +112 -60
- package/src/edits/types.ts +47 -63
- package/src/errors/catalog.ts +4 -0
- package/src/events/envelope.ts +0 -13
- package/src/events/index.ts +1 -1
- package/src/events/service.ts +1 -11
- package/src/events/toStoredEvent.ts +1 -3
- package/src/events/types/index.ts +1 -1
- package/src/execution/agent.ts +1 -2
- package/src/execution/authorized-object-reader.ts +5 -7
- package/src/execution/primitive.ts +1 -2
- package/src/execution/request.ts +1 -2
- package/src/index.ts +8 -7
- package/src/maintenance/ontology-maintenance.ts +77 -1
- package/src/materialization/errors.ts +2 -0
- package/src/materialization/events.ts +27 -2
- package/src/materializer/README.md +2 -0
- package/src/materializer/edits/commit.ts +21 -12
- package/src/materializer/edits/operations.ts +32 -4
- package/src/materializer/edits/plan.ts +4 -5
- package/src/materializer/edits/user-refs.ts +115 -0
- package/src/materializer/effective/build-events.ts +4 -5
- package/src/materializer/execution/scope.ts +40 -7
- package/src/materializer/projections/replace.ts +2 -0
- package/src/materializer/projections/replacement-plan.ts +4 -0
- package/src/materializer/telemetry/append.ts +4 -12
- package/src/materializer/telemetry/plan.ts +4 -5
- package/src/objects/execution.ts +33 -62
- package/src/objects/query/executor.ts +12 -3
- package/src/objects/query/ir.ts +7 -0
- package/src/objects/query/planner.ts +1 -0
- package/src/objects/query/scalar-values.ts +19 -0
- package/src/objects/query/validate.ts +55 -44
- package/src/objects/sdk/object-handle.ts +8 -8
- package/src/objects/sdk/object-set.ts +8 -15
- package/src/objects/sdk/query-builder.ts +59 -71
- package/src/objects/sdk/telemetry-channel.ts +6 -7
- package/src/objects/sdk/where.ts +6 -13
- package/src/ontology/builders.ts +15 -11
- package/src/ontology/index.ts +4 -0
- package/src/ontology/inference/index.ts +56 -36
- package/src/ontology/internal.ts +1 -0
- package/src/ontology/json-schema.ts +12 -0
- package/src/ontology/primitives.ts +91 -0
- package/src/ontology/query-capabilities.ts +136 -0
- package/src/ontology/refs.ts +33 -6
- package/src/ontology/registered.ts +22 -0
- package/src/ontology/registry.ts +6 -3
- package/src/ontology/tokens.ts +41 -2
- package/src/ontology/types.ts +19 -3
- package/src/ontology/user-ref.ts +120 -0
- package/src/ontology/validation/definition.ts +2 -13
- package/src/ontology/validation/index.ts +1 -0
- package/src/ontology/validation/normalize.ts +39 -3
- package/src/ontology/validation/properties.ts +95 -19
- package/src/ontology/validation/query.ts +11 -42
- package/src/ontology/validation/schema.ts +16 -0
- package/src/predicates/types.ts +43 -33
- package/src/projections/builders.ts +24 -3
- package/src/projections/validation.ts +15 -1
- package/src/runtime/create.ts +2 -2
- package/src/runtime/host.ts +10 -12
- package/src/runtime/index.ts +3 -2
- package/src/runtime/sixb.ts +13 -23
- package/src/runtime/types.ts +277 -479
- package/src/sandboxes/sandbox.ts +4 -1
- package/src/shared/params/types.ts +4 -3
- package/src/shared/params/user-refs.ts +48 -0
- package/src/shares/compiler.ts +6 -16
- package/src/storage/action-runs/types.ts +1 -0
- package/src/storage/auth/errors.ts +0 -1
- package/src/storage/auth/in-memory/access-tokens.ts +5 -2
- package/src/storage/auth/in-memory/auth-storage.ts +49 -73
- package/src/storage/auth/in-memory/device-authorizations.ts +0 -2
- package/src/storage/auth/in-memory/sessions.ts +69 -1
- package/src/storage/auth/in-memory/shared.ts +13 -7
- package/src/storage/auth/index.ts +2 -1
- package/src/storage/auth/types.ts +72 -20
- package/src/storage/executions/validation.ts +1 -1
- package/src/storage/file-upload-sessions/in-memory.ts +64 -113
- package/src/storage/file-upload-sessions/index.ts +1 -0
- package/src/storage/file-upload-sessions/provider.ts +258 -0
- package/src/storage/file-upload-sessions/types.ts +20 -1
- package/src/storage/file-upload-sessions/utils.ts +25 -9
- package/src/storage/index.ts +3 -2
- package/src/storage/objects/in-memory/query.ts +13 -3
- package/src/storage/ontology/commits.ts +6 -2
- package/src/storage/ontology/in-memory/materializations.ts +6 -34
- package/src/storage/ontology/provider-header-validation.ts +57 -0
- package/src/storage/ontology/provider-work.ts +15 -3
- package/src/storage/ontology/provider.ts +59 -1
- package/src/storage/operation-scope.ts +1 -0
- package/src/storage/types.ts +0 -1
- package/src/storage/workflow-interventions/index.ts +0 -1
- package/src/storage/workflow-interventions/types.ts +5 -9
- package/src/testing/action-execution.ts +13 -3
- package/src/testing/auth-storage-contract.ts +253 -192
- package/src/testing/execution-storage-contract.ts +1 -2
- package/src/testing/execution.ts +4 -7
- package/src/testing/file-upload-session-storage-contract.ts +335 -0
- package/src/testing/index.ts +8 -0
- package/src/testing/materializer-storage-contract.ts +86 -4
- package/src/testing/object-query-contract.ts +121 -2
- package/src/testing/ontology-contract-fixture.ts +23 -3
- package/src/testing/ontology-storage-contract.ts +58 -0
- package/src/testing/sandboxes-contract.ts +27 -0
- package/src/testing/workflow-intervention-storage-contract.ts +203 -0
- package/src/webhooks/types.ts +2 -2
- package/src/workflows/run-dispatch.ts +12 -1
- package/src/workflows/snapshot.ts +16 -7
- package/src/workflows/types.ts +2 -2
- package/dist/chunk-2cxv584m.js.map +0 -43
- package/dist/chunk-3ghw2t5q.js.map +0 -10
- package/dist/chunk-3h7ctayx.js.map +0 -11
- package/dist/chunk-6ma8dvzc.js.map +0 -15
- package/dist/chunk-bbaa1fet.js.map +0 -25
- package/dist/chunk-eyjzgav0.js.map +0 -12
- package/dist/chunk-f06sf7rr.js.map +0 -11
- package/dist/chunk-g50nxqs5.js.map +0 -18
- package/dist/chunk-hkw8rykk.js.map +0 -15
- package/dist/chunk-p6r1ex7t.js.map +0 -10
- package/dist/chunk-qm535afa.js.map +0 -15
- package/dist/chunk-vpxss818.js.map +0 -10
- package/dist/chunk-vsg0g7h9.js.map +0 -17
- /package/dist/{chunk-y3ev53cq.js.map → chunk-2fv8sajb.js.map} +0 -0
- /package/dist/{chunk-5tetw4hn.js.map → chunk-4tnrzqqh.js.map} +0 -0
- /package/dist/{chunk-y1ahv8b7.js.map → chunk-bdhfn0ww.js.map} +0 -0
- /package/dist/{chunk-kept9cdd.js.map → chunk-bxx3ms5t.js.map} +0 -0
- /package/dist/{chunk-xtfryrfb.js.map → chunk-cbn96bve.js.map} +0 -0
- /package/dist/{chunk-t7dzd1tm.js.map → chunk-e2c5yxfe.js.map} +0 -0
- /package/dist/{chunk-bg2bs62d.js.map → chunk-jfdggg1p.js.map} +0 -0
- /package/dist/{chunk-e1f1sqba.js.map → chunk-kxea54yg.js.map} +0 -0
- /package/dist/{chunk-0mza4xb2.js.map → chunk-m8zkvep1.js.map} +0 -0
- /package/dist/{chunk-jjwhy3rs.js.map → chunk-q2xghyft.js.map} +0 -0
- /package/dist/{chunk-y0v18c2j.js.map → chunk-vef6qa14.js.map} +0 -0
- /package/dist/{chunk-gzt6v1ja.js.map → chunk-vn3yh259.js.map} +0 -0
- /package/dist/{chunk-sfypc7mk.js.map → chunk-wn7mznxc.js.map} +0 -0
- /package/dist/{chunk-r5zythxp.js.map → chunk-wnxabtn4.js.map} +0 -0
- /package/dist/{chunk-4ph94nhd.js.map → chunk-ww185kt6.js.map} +0 -0
- /package/dist/{chunk-gswwr35f.js.map → chunk-y487ywrv.js.map} +0 -0
- /package/dist/{chunk-bet1rb9h.js.map → chunk-y6vnvayj.js.map} +0 -0
- /package/dist/{chunk-3bnt2wna.js.map → chunk-yvf2jqj8.js.map} +0 -0
- /package/dist/{chunk-g2gezsg5.js.map → chunk-z9h698s8.js.map} +0 -0
- /package/dist/{chunk-bfjv1adk.js.map → chunk-znw0zvy4.js.map} +0 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test"
|
|
2
|
+
import type { Principal } from "../auth"
|
|
3
|
+
import type { BlobUploadSession, FileRef, SignedBlobUploadPart } from "../blob-storage"
|
|
4
|
+
import {
|
|
5
|
+
type CreateFileUploadSessionInput,
|
|
6
|
+
DEFAULT_FILE_UPLOAD_TERMINAL_SESSION_TTL_MS,
|
|
7
|
+
type FileUploadSessionStore,
|
|
8
|
+
} from "../storage/file-upload-sessions"
|
|
9
|
+
|
|
10
|
+
export interface FileUploadSessionStorageContractSuiteOptions<
|
|
11
|
+
TStorage extends FileUploadSessionStore = FileUploadSessionStore,
|
|
12
|
+
> {
|
|
13
|
+
readonly createStorage: () => TStorage | Promise<TStorage>
|
|
14
|
+
readonly cleanup?: (storage: TStorage) => void | Promise<void>
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const HOUR_MS = 60 * 60 * 1000
|
|
18
|
+
const projectId = "file-upload-contract"
|
|
19
|
+
const principal: Principal = { type: "user", id: "usr_contract" }
|
|
20
|
+
const fileRef: FileRef = {
|
|
21
|
+
blobId: `blob_${"a".repeat(64)}`,
|
|
22
|
+
digest: `sha256:${"a".repeat(64)}`,
|
|
23
|
+
sizeBytes: 3,
|
|
24
|
+
fileName: "report.pdf",
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Provider-neutral lifecycle, retention, and abandoned-upload contract for file upload
|
|
29
|
+
* sessions. Stores read their own clock, so fixtures place `expiresAt` relative to the
|
|
30
|
+
* real time instead of controlling it.
|
|
31
|
+
*/
|
|
32
|
+
export function runFileUploadSessionStorageContractSuite<TStorage extends FileUploadSessionStore>(
|
|
33
|
+
label: string,
|
|
34
|
+
options: FileUploadSessionStorageContractSuiteOptions<TStorage>
|
|
35
|
+
): void {
|
|
36
|
+
const withStorage = async (run: (storage: TStorage) => Promise<void>): Promise<void> => {
|
|
37
|
+
const storage = await options.createStorage()
|
|
38
|
+
try {
|
|
39
|
+
await run(storage)
|
|
40
|
+
} finally {
|
|
41
|
+
await options.cleanup?.(storage)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
describe(label, () => {
|
|
46
|
+
test("round-trips every field, including provider fields it does not know", async () => {
|
|
47
|
+
await withStorage(async (storage) => {
|
|
48
|
+
// Provider-specific session fields must survive the JSON round-trip.
|
|
49
|
+
const providerUpload = { ...multipart("upload_roundtrip"), partReceipt: "etag" as const }
|
|
50
|
+
const input = sessionInput("upload_roundtrip", {
|
|
51
|
+
fileName: "report.pdf",
|
|
52
|
+
mediaType: "application/pdf",
|
|
53
|
+
logicalPath: "reports/q3.pdf",
|
|
54
|
+
expectedSizeBytes: 3,
|
|
55
|
+
expectedDigest: fileRef.digest,
|
|
56
|
+
providerUpload,
|
|
57
|
+
})
|
|
58
|
+
const created = await storage.create(input)
|
|
59
|
+
|
|
60
|
+
expect(created).toMatchObject({ status: "pending", principal })
|
|
61
|
+
const read = await storage.getForPrincipal("upload_roundtrip", principal)
|
|
62
|
+
expect(read).toEqual(created)
|
|
63
|
+
expect(read.providerUpload?.expiresAt).toBeInstanceOf(Date)
|
|
64
|
+
expect(read.providerUpload).toMatchObject({ partReceipt: "etag" })
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test("hides a session from other principals and unknown ids", async () => {
|
|
69
|
+
await withStorage(async (storage) => {
|
|
70
|
+
await storage.create(sessionInput("upload_private"))
|
|
71
|
+
|
|
72
|
+
await expect(
|
|
73
|
+
storage.getForPrincipal("upload_private", { type: "user", id: "usr_other" })
|
|
74
|
+
).rejects.toMatchObject({ reason: "not_found" })
|
|
75
|
+
await expect(storage.getForPrincipal("upload_missing", principal)).rejects.toMatchObject({
|
|
76
|
+
reason: "not_found",
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
test("rejects a duplicate id", async () => {
|
|
82
|
+
await withStorage(async (storage) => {
|
|
83
|
+
await storage.create(sessionInput("upload_duplicate"))
|
|
84
|
+
await expect(storage.create(sessionInput("upload_duplicate"))).rejects.toThrow(
|
|
85
|
+
"already exists"
|
|
86
|
+
)
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
test("keeps signed parts unique and ordered by part number", async () => {
|
|
91
|
+
await withStorage(async (storage) => {
|
|
92
|
+
await storage.create(
|
|
93
|
+
sessionInput("upload_parts", { providerUpload: multipart("upload_parts") })
|
|
94
|
+
)
|
|
95
|
+
// Insertion order differs from sorted order at every step, so dropping the sort fails.
|
|
96
|
+
await storage.addSignedPart("upload_parts", signedPart(3))
|
|
97
|
+
await storage.addSignedPart("upload_parts", signedPart(1))
|
|
98
|
+
await storage.addSignedPart("upload_parts", signedPart(2))
|
|
99
|
+
const updated = await storage.addSignedPart("upload_parts", signedPart(2, "replaced"))
|
|
100
|
+
|
|
101
|
+
expect(updated.signedParts.map((part) => [part.partNumber, part.url])).toEqual([
|
|
102
|
+
[1, "https://blob.test/part-1"],
|
|
103
|
+
[2, "https://blob.test/part-2-replaced"],
|
|
104
|
+
[3, "https://blob.test/part-3"],
|
|
105
|
+
])
|
|
106
|
+
const read = await storage.getForPrincipal("upload_parts", principal)
|
|
107
|
+
expect(read.signedParts).toEqual(updated.signedParts)
|
|
108
|
+
expect(read.signedParts[0]?.expiresAt).toBeInstanceOf(Date)
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
test("does not lose a part signed concurrently with another", async () => {
|
|
113
|
+
await withStorage(async (storage) => {
|
|
114
|
+
await storage.create(
|
|
115
|
+
sessionInput("upload_race", { providerUpload: multipart("upload_race") })
|
|
116
|
+
)
|
|
117
|
+
await Promise.all(
|
|
118
|
+
[1, 2, 3, 4, 5].map((n) => storage.addSignedPart("upload_race", signedPart(n)))
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
const read = await storage.getForPrincipal("upload_race", principal)
|
|
122
|
+
expect(read.signedParts.map((part) => part.partNumber)).toEqual([1, 2, 3, 4, 5])
|
|
123
|
+
})
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
test("moves through markUploaded to one terminal state", async () => {
|
|
127
|
+
await withStorage(async (storage) => {
|
|
128
|
+
await storage.create(sessionInput("upload_done"))
|
|
129
|
+
const uploaded = await storage.markUploaded("upload_done", fileRef)
|
|
130
|
+
expect(uploaded).toMatchObject({ status: "pending", fileRef })
|
|
131
|
+
|
|
132
|
+
const completed = await storage.complete("upload_done", fileRef)
|
|
133
|
+
expect(completed.status).toBe("completed")
|
|
134
|
+
expect(completed.completedAt).toBeInstanceOf(Date)
|
|
135
|
+
await expect(storage.complete("upload_done", fileRef)).rejects.toMatchObject({
|
|
136
|
+
reason: "already_completed",
|
|
137
|
+
})
|
|
138
|
+
await expect(storage.abort("upload_done")).rejects.toMatchObject({
|
|
139
|
+
reason: "already_completed",
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
await storage.create(sessionInput("upload_cancelled"))
|
|
143
|
+
expect((await storage.abort("upload_cancelled")).status).toBe("aborted")
|
|
144
|
+
await expect(storage.abort("upload_cancelled")).rejects.toMatchObject({
|
|
145
|
+
reason: "already_aborted",
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
test("checks expiry at the gate only, so a request that passed it can finish", async () => {
|
|
151
|
+
await withStorage(async (storage) => {
|
|
152
|
+
// Provider uploads keep both rows unreapable while pending.
|
|
153
|
+
for (const id of ["upload_late", "upload_abort_late"]) {
|
|
154
|
+
await storage.create(
|
|
155
|
+
sessionInput(id, { expiresAt: ago(HOUR_MS), providerUpload: multipart(id) })
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
await expect(storage.getForPrincipal("upload_late", principal)).rejects.toMatchObject({
|
|
160
|
+
reason: "expired",
|
|
161
|
+
})
|
|
162
|
+
// Transitions run after slow blob I/O that began before `expiresAt`.
|
|
163
|
+
await storage.addSignedPart("upload_late", signedPart(1))
|
|
164
|
+
await storage.markUploaded("upload_late", fileRef)
|
|
165
|
+
expect((await storage.complete("upload_late", fileRef)).status).toBe("completed")
|
|
166
|
+
expect((await storage.abort("upload_abort_late")).status).toBe("aborted")
|
|
167
|
+
})
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
test("lists abandoned sessions for one project only", async () => {
|
|
171
|
+
await withStorage(async (storage) => {
|
|
172
|
+
await storage.create(
|
|
173
|
+
sessionInput("upload_ours", {
|
|
174
|
+
expiresAt: ago(HOUR_MS),
|
|
175
|
+
providerUpload: multipart("ours"),
|
|
176
|
+
})
|
|
177
|
+
)
|
|
178
|
+
await storage.create(
|
|
179
|
+
sessionInput("upload_theirs", {
|
|
180
|
+
projectId: "other-project",
|
|
181
|
+
expiresAt: ago(HOUR_MS),
|
|
182
|
+
providerUpload: multipart("theirs"),
|
|
183
|
+
})
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
const ids = (await storage.listAbandoned({ projectId, now: new Date(), limit: 10 })).map(
|
|
187
|
+
(session) => session.id
|
|
188
|
+
)
|
|
189
|
+
expect(ids).toEqual(["upload_ours"])
|
|
190
|
+
})
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
test("never deletes an abandoned session, on read or on cleanup", async () => {
|
|
194
|
+
await withStorage(async (storage) => {
|
|
195
|
+
await storage.create(
|
|
196
|
+
sessionInput("upload_abandoned", {
|
|
197
|
+
expiresAt: ago(HOUR_MS),
|
|
198
|
+
providerUpload: multipart("upload_abandoned"),
|
|
199
|
+
})
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
// Reading an expired session must not delete it: nothing would abort its provider upload.
|
|
203
|
+
await expect(storage.getForPrincipal("upload_abandoned", principal)).rejects.toMatchObject({
|
|
204
|
+
reason: "expired",
|
|
205
|
+
})
|
|
206
|
+
expect(await storage.cleanupExpired(later(HOUR_MS))).toBe(0)
|
|
207
|
+
expect(
|
|
208
|
+
(await storage.listAbandoned({ projectId, now: new Date(), limit: 10 })).map(
|
|
209
|
+
(session) => session.id
|
|
210
|
+
)
|
|
211
|
+
).toEqual(["upload_abandoned"])
|
|
212
|
+
})
|
|
213
|
+
})
|
|
214
|
+
|
|
215
|
+
test("lists only abandoned sessions, oldest expiry first, within the limit", async () => {
|
|
216
|
+
await withStorage(async (storage) => {
|
|
217
|
+
await storage.create(
|
|
218
|
+
sessionInput("upload_newer", { expiresAt: ago(HOUR_MS), providerUpload: multipart("n") })
|
|
219
|
+
)
|
|
220
|
+
await storage.create(
|
|
221
|
+
sessionInput("upload_older", {
|
|
222
|
+
expiresAt: ago(2 * HOUR_MS),
|
|
223
|
+
providerUpload: multipart("o"),
|
|
224
|
+
})
|
|
225
|
+
)
|
|
226
|
+
await storage.create(sessionInput("upload_live", { providerUpload: multipart("live") }))
|
|
227
|
+
await storage.create(sessionInput("upload_server", { expiresAt: ago(HOUR_MS) }))
|
|
228
|
+
await storage.create(
|
|
229
|
+
sessionInput("upload_aborted", {
|
|
230
|
+
expiresAt: ago(HOUR_MS),
|
|
231
|
+
providerUpload: multipart("a"),
|
|
232
|
+
})
|
|
233
|
+
)
|
|
234
|
+
await storage.abort("upload_aborted")
|
|
235
|
+
|
|
236
|
+
const ids = async (limit: number) =>
|
|
237
|
+
(await storage.listAbandoned({ projectId, now: new Date(), limit })).map(
|
|
238
|
+
(session) => session.id
|
|
239
|
+
)
|
|
240
|
+
expect(await ids(10)).toEqual(["upload_older", "upload_newer"])
|
|
241
|
+
expect(await ids(1)).toEqual(["upload_older"])
|
|
242
|
+
const [oldest] = await storage.listAbandoned({ projectId, now: new Date(), limit: 1 })
|
|
243
|
+
expect(oldest?.providerUpload?.expiresAt).toBeInstanceOf(Date)
|
|
244
|
+
await expect(
|
|
245
|
+
storage.listAbandoned({ projectId, now: new Date(), limit: 0 })
|
|
246
|
+
).rejects.toThrow("positive integer")
|
|
247
|
+
})
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
test("reaps expired sessions without a provider upload and terminal ones after their TTL", async () => {
|
|
251
|
+
await withStorage(async (storage) => {
|
|
252
|
+
await storage.create(sessionInput("upload_live"))
|
|
253
|
+
await storage.create(sessionInput("upload_finished"))
|
|
254
|
+
await storage.complete("upload_finished", fileRef)
|
|
255
|
+
// Created last: a store may reap opportunistically on `create`.
|
|
256
|
+
await storage.create(sessionInput("upload_expired", { expiresAt: ago(HOUR_MS) }))
|
|
257
|
+
|
|
258
|
+
expect(await storage.cleanupExpired(new Date())).toBe(1)
|
|
259
|
+
await expect(storage.getForPrincipal("upload_expired", principal)).rejects.toMatchObject({
|
|
260
|
+
reason: "not_found",
|
|
261
|
+
})
|
|
262
|
+
// A completed session outlives its expiry so a retried `complete` stays idempotent.
|
|
263
|
+
expect((await storage.getForPrincipal("upload_finished", principal)).status).toBe(
|
|
264
|
+
"completed"
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
expect(
|
|
268
|
+
await storage.cleanupExpired(later(DEFAULT_FILE_UPLOAD_TERMINAL_SESSION_TTL_MS + 60_000))
|
|
269
|
+
).toBe(1)
|
|
270
|
+
await expect(storage.getForPrincipal("upload_finished", principal)).rejects.toMatchObject({
|
|
271
|
+
reason: "not_found",
|
|
272
|
+
})
|
|
273
|
+
expect((await storage.getForPrincipal("upload_live", principal)).status).toBe("pending")
|
|
274
|
+
})
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
test("reaps an abandoned session once it has been aborted", async () => {
|
|
278
|
+
await withStorage(async (storage) => {
|
|
279
|
+
await storage.create(
|
|
280
|
+
sessionInput("upload_swept", { expiresAt: ago(HOUR_MS), providerUpload: multipart("s") })
|
|
281
|
+
)
|
|
282
|
+
await storage.abort("upload_swept")
|
|
283
|
+
|
|
284
|
+
expect(await storage.listAbandoned({ projectId, now: new Date(), limit: 10 })).toEqual([])
|
|
285
|
+
expect(await storage.cleanupExpired(new Date())).toBe(0)
|
|
286
|
+
expect(
|
|
287
|
+
await storage.cleanupExpired(later(DEFAULT_FILE_UPLOAD_TERMINAL_SESSION_TTL_MS + 60_000))
|
|
288
|
+
).toBe(1)
|
|
289
|
+
})
|
|
290
|
+
})
|
|
291
|
+
})
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function sessionInput(
|
|
295
|
+
id: string,
|
|
296
|
+
overrides: Partial<CreateFileUploadSessionInput> = {}
|
|
297
|
+
): CreateFileUploadSessionInput {
|
|
298
|
+
return {
|
|
299
|
+
id,
|
|
300
|
+
projectId,
|
|
301
|
+
principal,
|
|
302
|
+
strategy: overrides.providerUpload?.strategy ?? "server",
|
|
303
|
+
expiresAt: later(HOUR_MS),
|
|
304
|
+
...overrides,
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function multipart(uploadId: string): BlobUploadSession {
|
|
309
|
+
return {
|
|
310
|
+
strategy: "multipart",
|
|
311
|
+
uploadId,
|
|
312
|
+
partSizeBytes: 5 * 1024 * 1024,
|
|
313
|
+
expiresAt: later(HOUR_MS),
|
|
314
|
+
stagingKey: `staging/${uploadId}`,
|
|
315
|
+
providerUploadId: `provider-${uploadId}`,
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
function signedPart(partNumber: number, suffix?: string): SignedBlobUploadPart {
|
|
320
|
+
return {
|
|
321
|
+
partNumber,
|
|
322
|
+
method: "PUT",
|
|
323
|
+
url: `https://blob.test/part-${partNumber}${suffix ? `-${suffix}` : ""}`,
|
|
324
|
+
headers: {},
|
|
325
|
+
expiresAt: later(HOUR_MS),
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function ago(ms: number): Date {
|
|
330
|
+
return new Date(Date.now() - ms)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function later(ms: number): Date {
|
|
334
|
+
return new Date(Date.now() + ms)
|
|
335
|
+
}
|
package/src/testing/index.ts
CHANGED
|
@@ -59,6 +59,10 @@ export {
|
|
|
59
59
|
type ExecutionStorageContractSuiteOptions,
|
|
60
60
|
runExecutionStorageContractSuite,
|
|
61
61
|
} from "./execution-storage-contract"
|
|
62
|
+
export {
|
|
63
|
+
type FileUploadSessionStorageContractSuiteOptions,
|
|
64
|
+
runFileUploadSessionStorageContractSuite,
|
|
65
|
+
} from "./file-upload-session-storage-contract"
|
|
62
66
|
export { runLakeChangesContractSuite } from "./lake-changes-contract"
|
|
63
67
|
export {
|
|
64
68
|
type LakeMergeStorageContractSuiteOptions,
|
|
@@ -151,3 +155,7 @@ export {
|
|
|
151
155
|
createTestAutomaticWorkflowExecution,
|
|
152
156
|
createTestWorkflowExecution,
|
|
153
157
|
} from "./workflow-execution"
|
|
158
|
+
export {
|
|
159
|
+
runWorkflowInterventionStorageContractSuite,
|
|
160
|
+
type WorkflowInterventionStorageContractSuiteOptions,
|
|
161
|
+
} from "./workflow-intervention-storage-contract"
|
|
@@ -13,7 +13,11 @@ import {
|
|
|
13
13
|
import type { TrustedPrimitiveRef } from "../execution"
|
|
14
14
|
import { restoreTrustedPrimitiveExecutionScope } from "../execution/durable"
|
|
15
15
|
import { createTestingScope } from "../execution/scopes"
|
|
16
|
-
import type {
|
|
16
|
+
import type {
|
|
17
|
+
ExpectedLinkRevision,
|
|
18
|
+
ExpectedObjectRevision,
|
|
19
|
+
OntologyMaterializer,
|
|
20
|
+
} from "../materializer"
|
|
17
21
|
import {
|
|
18
22
|
createLinkScopeFingerprint,
|
|
19
23
|
createOntologyMaterializer,
|
|
@@ -747,6 +751,84 @@ export function runMaterializerStorageContractSuite<TStorage extends Storage>(
|
|
|
747
751
|
}
|
|
748
752
|
})
|
|
749
753
|
|
|
754
|
+
test(`${name} rejects stale object and link expectations as expectation conflicts`, async () => {
|
|
755
|
+
// Action runs report exactly this conflict kind as `action.read_conflict`. Throw a stale
|
|
756
|
+
// expectation as another kind from any provider and this fails for that provider.
|
|
757
|
+
const createdStorage = await provider.createStorage()
|
|
758
|
+
const storage = requireContractStorage(createdStorage)
|
|
759
|
+
const runtimeMaterializer = createOntologyMaterializer({
|
|
760
|
+
projectId: "materializer-storage-contract",
|
|
761
|
+
ontology,
|
|
762
|
+
projections,
|
|
763
|
+
storage,
|
|
764
|
+
dependencies: { clock: () => new Date("2026-02-01T12:00:00.000Z") },
|
|
765
|
+
}).withScope(runtimeScope())
|
|
766
|
+
const device = { objectTypeId: Device.id, primaryId: "device" }
|
|
767
|
+
const peerLink = {
|
|
768
|
+
source: device,
|
|
769
|
+
linkId: "peers",
|
|
770
|
+
target: { objectTypeId: Device.id, primaryId: "peer" },
|
|
771
|
+
}
|
|
772
|
+
const commitExpecting = (
|
|
773
|
+
requestId: string,
|
|
774
|
+
expected: {
|
|
775
|
+
readonly expectedObjects: readonly ExpectedObjectRevision[]
|
|
776
|
+
readonly expectedLinks: readonly ExpectedLinkRevision[]
|
|
777
|
+
}
|
|
778
|
+
) =>
|
|
779
|
+
runtimeMaterializer.edits.commit({
|
|
780
|
+
mode: "atomic",
|
|
781
|
+
source: { kind: "runtime", requestId },
|
|
782
|
+
operations: [
|
|
783
|
+
{
|
|
784
|
+
id: "rename",
|
|
785
|
+
kind: "object.patch",
|
|
786
|
+
ref: device,
|
|
787
|
+
set: { name: requestId },
|
|
788
|
+
unset: [],
|
|
789
|
+
reset: [],
|
|
790
|
+
},
|
|
791
|
+
],
|
|
792
|
+
...expected,
|
|
793
|
+
expectedLinkScopes: [],
|
|
794
|
+
})
|
|
795
|
+
|
|
796
|
+
try {
|
|
797
|
+
await runtimeMaterializer.edits.commit({
|
|
798
|
+
mode: "atomic",
|
|
799
|
+
source: { kind: "runtime", requestId: "expectation-setup" },
|
|
800
|
+
operations: [
|
|
801
|
+
{ id: "device", kind: "object.create", ref: device, properties: { name: "device" } },
|
|
802
|
+
{
|
|
803
|
+
id: "peer",
|
|
804
|
+
kind: "object.create",
|
|
805
|
+
ref: peerLink.target,
|
|
806
|
+
properties: { name: "peer" },
|
|
807
|
+
},
|
|
808
|
+
{ id: "link", kind: "link.upsert", ref: peerLink },
|
|
809
|
+
],
|
|
810
|
+
expectedObjects: [],
|
|
811
|
+
expectedLinks: [],
|
|
812
|
+
expectedLinkScopes: [],
|
|
813
|
+
})
|
|
814
|
+
|
|
815
|
+
await expect(
|
|
816
|
+
commitExpecting("stale-object", {
|
|
817
|
+
expectedObjects: [{ ref: device, exists: false }],
|
|
818
|
+
expectedLinks: [],
|
|
819
|
+
})
|
|
820
|
+
).rejects.toMatchObject({ kind: "expectation" })
|
|
821
|
+
await expect(
|
|
822
|
+
commitExpecting("stale-link", {
|
|
823
|
+
expectedObjects: [],
|
|
824
|
+
expectedLinks: [{ ref: peerLink, exists: false }],
|
|
825
|
+
})
|
|
826
|
+
).rejects.toMatchObject({ kind: "expectation" })
|
|
827
|
+
} finally {
|
|
828
|
+
await provider.cleanup?.(createdStorage)
|
|
829
|
+
}
|
|
830
|
+
})
|
|
831
|
+
|
|
750
832
|
test(`${name} fences projected cardinality-many link scopes by fingerprint`, async () => {
|
|
751
833
|
const createdStorage = await provider.createStorage()
|
|
752
834
|
const storage = requireContractStorage(createdStorage)
|
|
@@ -886,9 +968,9 @@ export function runMaterializerStorageContractSuite<TStorage extends Storage>(
|
|
|
886
968
|
expectedLinkScopes: [],
|
|
887
969
|
})
|
|
888
970
|
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
)
|
|
971
|
+
const stale = commitObservation("stale-many-scope-action", "must not commit")
|
|
972
|
+
await expect(stale).rejects.toThrow("Expected link scope changed")
|
|
973
|
+
await expect(stale).rejects.toMatchObject({ kind: "expectation" })
|
|
892
974
|
expect(
|
|
893
975
|
await storage.objects.getByPrimaryId({
|
|
894
976
|
projectId: "materializer-storage-contract",
|
|
@@ -10,10 +10,11 @@ import {
|
|
|
10
10
|
normalizeObjectQuery,
|
|
11
11
|
type ObjectQuery,
|
|
12
12
|
ObjectQueryPlanningError,
|
|
13
|
+
type ObjectQueryPredicate,
|
|
13
14
|
planObjectQuery,
|
|
14
15
|
validateObjectQuery,
|
|
15
16
|
} from "../objects/query"
|
|
16
|
-
import { defineObjectType, link, OntologyRegistry, prop, stringEnum } from "../ontology"
|
|
17
|
+
import { defineObjectType, link, OntologyRegistry, prop, ref, stringEnum } from "../ontology"
|
|
17
18
|
import type { ObjectStorage, QueryObjectsResult } from "../storage/objects"
|
|
18
19
|
import type { Storage } from "../storage/types"
|
|
19
20
|
import {
|
|
@@ -133,8 +134,29 @@ const DefaultTextChild = defineObjectType({
|
|
|
133
134
|
search: { defaultText: ["alias"] },
|
|
134
135
|
})
|
|
135
136
|
|
|
137
|
+
const Task = defineObjectType({
|
|
138
|
+
id: "ContractTask",
|
|
139
|
+
name: "Contract Task",
|
|
140
|
+
properties: [
|
|
141
|
+
prop("id", "string", {
|
|
142
|
+
required: true,
|
|
143
|
+
primary: true,
|
|
144
|
+
query: { searchable: true, sortable: true },
|
|
145
|
+
}),
|
|
146
|
+
prop("assignee", ref.user(), {
|
|
147
|
+
nullable: true,
|
|
148
|
+
query: { searchable: true, filterable: true, facet: true },
|
|
149
|
+
}),
|
|
150
|
+
prop(
|
|
151
|
+
"reviewers",
|
|
152
|
+
{ type: "array", items: ref.user() },
|
|
153
|
+
{ query: { searchable: true, filterable: true } }
|
|
154
|
+
),
|
|
155
|
+
],
|
|
156
|
+
})
|
|
157
|
+
|
|
136
158
|
export const objectQueryContractOntology = new OntologyRegistry({
|
|
137
|
-
sources: [Room, Device, Zone, Asset, LaptopAsset, DefaultTextBase, DefaultTextChild],
|
|
159
|
+
sources: [Room, Device, Zone, Asset, LaptopAsset, DefaultTextBase, DefaultTextChild, Task],
|
|
138
160
|
})
|
|
139
161
|
|
|
140
162
|
/**
|
|
@@ -151,6 +173,7 @@ export function runObjectQueryProviderContractSuite<TStorage extends Storage>(
|
|
|
151
173
|
): void {
|
|
152
174
|
const withStorage = async (
|
|
153
175
|
body: (context: {
|
|
176
|
+
readonly storage: TStorage
|
|
154
177
|
readonly objects: TStorage["objects"]
|
|
155
178
|
readonly fixture: MaterializerTestFixture
|
|
156
179
|
}) => Promise<void>
|
|
@@ -158,6 +181,7 @@ export function runObjectQueryProviderContractSuite<TStorage extends Storage>(
|
|
|
158
181
|
const storage = await options.createStorage()
|
|
159
182
|
try {
|
|
160
183
|
await body({
|
|
184
|
+
storage,
|
|
161
185
|
objects: storage.objects,
|
|
162
186
|
fixture: createMaterializerTestFixture({
|
|
163
187
|
projectId,
|
|
@@ -835,6 +859,101 @@ export function runObjectQueryProviderContractSuite<TStorage extends Storage>(
|
|
|
835
859
|
})
|
|
836
860
|
})
|
|
837
861
|
|
|
862
|
+
test("matches user references on type and id, and groups facets by user", async () => {
|
|
863
|
+
await withStorage(async ({ storage: complete, objects: storage, fixture }) => {
|
|
864
|
+
const auth = complete.auth
|
|
865
|
+
if (!auth) throw new Error("The object query contract requires auth storage.")
|
|
866
|
+
for (const id of ["usr_alice", "usr_bob", "usr_carol"]) {
|
|
867
|
+
await auth.users.create({ projectId, id, email: `${id}@example.com` })
|
|
868
|
+
}
|
|
869
|
+
const alice = { type: "user", id: "usr_alice" }
|
|
870
|
+
const bob = { type: "user", id: "usr_bob" }
|
|
871
|
+
const carol = { type: "user", id: "usr_carol" }
|
|
872
|
+
await fixture.seed({
|
|
873
|
+
objects: [
|
|
874
|
+
objectSeed(Task.id, "t1", { assignee: alice, reviewers: [bob] }),
|
|
875
|
+
objectSeed(Task.id, "t2", { assignee: alice, reviewers: [bob, carol] }),
|
|
876
|
+
objectSeed(Task.id, "t3", { assignee: alice, reviewers: [] }),
|
|
877
|
+
objectSeed(Task.id, "t4", { assignee: bob, reviewers: [alice] }),
|
|
878
|
+
objectSeed(Task.id, "t5", { assignee: bob, reviewers: [carol] }),
|
|
879
|
+
objectSeed(Task.id, "t6", { assignee: null, reviewers: [] }),
|
|
880
|
+
objectSeed(Task.id, "t7", { reviewers: [] }),
|
|
881
|
+
],
|
|
882
|
+
})
|
|
883
|
+
|
|
884
|
+
const ids = async (predicate: ObjectQueryPredicate) => {
|
|
885
|
+
const result = await executeObjectQuery(
|
|
886
|
+
{
|
|
887
|
+
projectId,
|
|
888
|
+
query: {
|
|
889
|
+
kind: "sort",
|
|
890
|
+
fields: [{ kind: "property", propertyId: "id" }],
|
|
891
|
+
input: {
|
|
892
|
+
kind: "filter",
|
|
893
|
+
predicate,
|
|
894
|
+
input: { kind: "start", objectTypeId: Task.id },
|
|
895
|
+
},
|
|
896
|
+
},
|
|
897
|
+
},
|
|
898
|
+
{ ontology: objectQueryContractOntology, storage }
|
|
899
|
+
)
|
|
900
|
+
expect(result.plan.mode).toBe("pushdown")
|
|
901
|
+
return result.objects.map((object) => object.primaryId)
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
expect(await ids({ op: "eq", propertyId: "assignee", value: alice })).toEqual([
|
|
905
|
+
"t1",
|
|
906
|
+
"t2",
|
|
907
|
+
"t3",
|
|
908
|
+
])
|
|
909
|
+
// Field order is not part of the value.
|
|
910
|
+
expect(
|
|
911
|
+
await ids({ op: "eq", propertyId: "assignee", value: { id: "usr_alice", type: "user" } })
|
|
912
|
+
).toEqual(["t1", "t2", "t3"])
|
|
913
|
+
expect(await ids({ op: "neq", propertyId: "assignee", value: alice })).toEqual([
|
|
914
|
+
"t4",
|
|
915
|
+
"t5",
|
|
916
|
+
"t6",
|
|
917
|
+
"t7",
|
|
918
|
+
])
|
|
919
|
+
expect(await ids({ op: "in", propertyId: "assignee", values: [bob, null] })).toEqual([
|
|
920
|
+
"t4",
|
|
921
|
+
"t5",
|
|
922
|
+
"t6",
|
|
923
|
+
])
|
|
924
|
+
expect(await ids({ op: "exists", propertyId: "assignee", value: false })).toEqual(["t7"])
|
|
925
|
+
expect(await ids({ op: "contains", propertyId: "reviewers", value: bob })).toEqual([
|
|
926
|
+
"t1",
|
|
927
|
+
"t2",
|
|
928
|
+
])
|
|
929
|
+
expect(await ids({ op: "contains", propertyId: "reviewers", value: carol })).toEqual([
|
|
930
|
+
"t2",
|
|
931
|
+
"t5",
|
|
932
|
+
])
|
|
933
|
+
expect(await ids({ op: "contains", propertyId: "reviewers", value: alice })).toEqual(["t4"])
|
|
934
|
+
|
|
935
|
+
const facets = await facetObjects(
|
|
936
|
+
{
|
|
937
|
+
projectId,
|
|
938
|
+
query: { kind: "start", objectTypeId: Task.id },
|
|
939
|
+
facets: [{ propertyId: "assignee", limit: 10 }],
|
|
940
|
+
},
|
|
941
|
+
{ ontology: objectQueryContractOntology, storage }
|
|
942
|
+
)
|
|
943
|
+
expect(facets.plan.mode).toBe("pushdown")
|
|
944
|
+
expect(facets.facets).toEqual([
|
|
945
|
+
{
|
|
946
|
+
propertyId: "assignee",
|
|
947
|
+
buckets: [
|
|
948
|
+
{ value: alice, count: 3 },
|
|
949
|
+
{ value: bob, count: 2 },
|
|
950
|
+
{ value: null, count: 1 },
|
|
951
|
+
],
|
|
952
|
+
},
|
|
953
|
+
])
|
|
954
|
+
})
|
|
955
|
+
})
|
|
956
|
+
|
|
838
957
|
test("counts matching objects by facetable properties without returning rows", async () => {
|
|
839
958
|
await withStorage(async ({ objects: storage, fixture }) => {
|
|
840
959
|
await seedObjectQueryContractData(fixture)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AuthorizablePrincipal } from "../execution/types"
|
|
1
2
|
import { createEventId } from "../materialization/identity"
|
|
2
3
|
import type {
|
|
3
4
|
MaterializationPlanHeader,
|
|
@@ -29,6 +30,11 @@ const emptyChunk = {
|
|
|
29
30
|
outbox: [],
|
|
30
31
|
} as const
|
|
31
32
|
|
|
33
|
+
/** The request executor `ensureContractExecution` records for a contract commit. */
|
|
34
|
+
export function contractExecutor(id: string) {
|
|
35
|
+
return { type: "request" as const, requestId: `contract-request:${id}` }
|
|
36
|
+
}
|
|
37
|
+
|
|
32
38
|
export function contractEditHeader(id: string): MaterializationPlanHeader {
|
|
33
39
|
return {
|
|
34
40
|
commit: {
|
|
@@ -38,6 +44,7 @@ export function contractEditHeader(id: string): MaterializationPlanHeader {
|
|
|
38
44
|
requestHash: `hash:${id}`,
|
|
39
45
|
executionId: `contract-execution:${id}`,
|
|
40
46
|
origin: { kind: "runtime", requestId: id },
|
|
47
|
+
executor: contractExecutor(id),
|
|
41
48
|
ontologyRevision: "ontology-contract-revision",
|
|
42
49
|
intent: { kind: "edit", mode: "atomic", operationCount: 0 },
|
|
43
50
|
committedAt: CONTRACT_COMMITTED_AT,
|
|
@@ -90,9 +97,15 @@ export async function commitExactObject(
|
|
|
90
97
|
readonly primaryId?: string
|
|
91
98
|
readonly omitFinalize?: boolean
|
|
92
99
|
readonly throwAfterFinalize?: boolean
|
|
100
|
+
/** Must name an existing auth principal: SQL providers reference it from the execution. */
|
|
101
|
+
readonly requestedBy?: AuthorizablePrincipal
|
|
93
102
|
} = {}
|
|
94
103
|
): Promise<{ readonly eventId: string }> {
|
|
95
|
-
const
|
|
104
|
+
const defaultHeader = contractEditHeader(id)
|
|
105
|
+
const header: MaterializationPlanHeader =
|
|
106
|
+
options.requestedBy === undefined
|
|
107
|
+
? defaultHeader
|
|
108
|
+
: { ...defaultHeader, commit: { ...defaultHeader.commit, requestedBy: options.requestedBy } }
|
|
96
109
|
const ref = { objectTypeId: "ContractDevice", primaryId: options.primaryId ?? id }
|
|
97
110
|
const row = {
|
|
98
111
|
ref,
|
|
@@ -109,6 +122,8 @@ export async function commitExactObject(
|
|
|
109
122
|
occurredAt: header.commit.committedAt,
|
|
110
123
|
correlationId: `contract-correlation:${id}`,
|
|
111
124
|
origin: header.commit.origin,
|
|
125
|
+
...(header.commit.requestedBy === undefined ? {} : { requestedBy: header.commit.requestedBy }),
|
|
126
|
+
executor: header.commit.executor,
|
|
112
127
|
commitId: id,
|
|
113
128
|
type: "object.created" as const,
|
|
114
129
|
topic: "objects" as const,
|
|
@@ -214,12 +229,17 @@ export async function ensureContractExecution(
|
|
|
214
229
|
) {
|
|
215
230
|
return
|
|
216
231
|
}
|
|
232
|
+
const { requestedBy } = header.commit
|
|
217
233
|
await storage.executions.create({
|
|
218
234
|
id: header.commit.executionId,
|
|
219
235
|
projectId: header.commit.projectId,
|
|
220
|
-
|
|
236
|
+
...(requestedBy === undefined ? {} : { requestedBy }),
|
|
237
|
+
executor: contractExecutor(header.commit.id),
|
|
221
238
|
source: { type: "http", requestId: `contract-request:${header.commit.id}` },
|
|
222
239
|
correlationId: `contract-correlation:${header.commit.id}`,
|
|
223
|
-
authorizationRef:
|
|
240
|
+
authorizationRef:
|
|
241
|
+
requestedBy === undefined
|
|
242
|
+
? { type: "disabled" }
|
|
243
|
+
: { type: "principal", principal: requestedBy },
|
|
224
244
|
})
|
|
225
245
|
}
|