@vertesia/common 1.5.0-dev.20260722.120446Z → 1.5.0-dev.20260804.124748Z
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/lib/access-control-values.d.ts +98 -0
- package/lib/access-control-values.d.ts.map +1 -0
- package/lib/access-control-values.js +101 -0
- package/lib/access-control-values.js.map +1 -0
- package/lib/access-control.d.ts +22 -119
- package/lib/access-control.d.ts.map +1 -1
- package/lib/access-control.js +6 -78
- package/lib/access-control.js.map +1 -1
- package/lib/account-values.d.ts +53 -0
- package/lib/account-values.d.ts.map +1 -0
- package/lib/account-values.js +91 -0
- package/lib/account-values.js.map +1 -0
- package/lib/analytics.d.ts +12 -38
- package/lib/analytics.d.ts.map +1 -1
- package/lib/api-schemas/access-control.d.ts +215 -0
- package/lib/api-schemas/access-control.d.ts.map +1 -0
- package/lib/api-schemas/access-control.js +165 -0
- package/lib/api-schemas/access-control.js.map +1 -0
- package/lib/api-schemas/account.d.ts +101 -0
- package/lib/api-schemas/account.d.ts.map +1 -0
- package/lib/api-schemas/account.js +136 -0
- package/lib/api-schemas/account.js.map +1 -0
- package/lib/api-schemas/adapter.d.ts +80 -0
- package/lib/api-schemas/adapter.d.ts.map +1 -0
- package/lib/api-schemas/adapter.js +726 -0
- package/lib/api-schemas/adapter.js.map +1 -0
- package/lib/api-schemas/agent-runs.d.ts +3781 -0
- package/lib/api-schemas/agent-runs.d.ts.map +1 -0
- package/lib/api-schemas/agent-runs.js +991 -0
- package/lib/api-schemas/agent-runs.js.map +1 -0
- package/lib/api-schemas/analytics.d.ts +86 -0
- package/lib/api-schemas/analytics.d.ts.map +1 -0
- package/lib/api-schemas/analytics.js +58 -0
- package/lib/api-schemas/analytics.js.map +1 -0
- package/lib/api-schemas/apikey.d.ts +231 -0
- package/lib/api-schemas/apikey.d.ts.map +1 -0
- package/lib/api-schemas/apikey.js +172 -0
- package/lib/api-schemas/apikey.js.map +1 -0
- package/lib/api-schemas/app-lifecycle.d.ts +1114 -0
- package/lib/api-schemas/app-lifecycle.d.ts.map +1 -0
- package/lib/api-schemas/app-lifecycle.js +750 -0
- package/lib/api-schemas/app-lifecycle.js.map +1 -0
- package/lib/api-schemas/app-runtime.d.ts +9056 -0
- package/lib/api-schemas/app-runtime.d.ts.map +1 -0
- package/lib/api-schemas/app-runtime.js +782 -0
- package/lib/api-schemas/app-runtime.js.map +1 -0
- package/lib/api-schemas/apps.d.ts +247 -0
- package/lib/api-schemas/apps.d.ts.map +1 -0
- package/lib/api-schemas/apps.js +366 -0
- package/lib/api-schemas/apps.js.map +1 -0
- package/lib/api-schemas/audit-trail.d.ts +465 -0
- package/lib/api-schemas/audit-trail.d.ts.map +1 -0
- package/lib/api-schemas/audit-trail.js +218 -0
- package/lib/api-schemas/audit-trail.js.map +1 -0
- package/lib/api-schemas/bulk-operation.d.ts +104 -0
- package/lib/api-schemas/bulk-operation.d.ts.map +1 -0
- package/lib/api-schemas/bulk-operation.js +66 -0
- package/lib/api-schemas/bulk-operation.js.map +1 -0
- package/lib/api-schemas/commands.d.ts +50 -0
- package/lib/api-schemas/commands.d.ts.map +1 -0
- package/lib/api-schemas/commands.js +58 -0
- package/lib/api-schemas/commands.js.map +1 -0
- package/lib/api-schemas/content.d.ts +3561 -0
- package/lib/api-schemas/content.d.ts.map +1 -0
- package/lib/api-schemas/content.js +842 -0
- package/lib/api-schemas/content.js.map +1 -0
- package/lib/api-schemas/cost-analytics.d.ts +300 -0
- package/lib/api-schemas/cost-analytics.d.ts.map +1 -0
- package/lib/api-schemas/cost-analytics.js +218 -0
- package/lib/api-schemas/cost-analytics.js.map +1 -0
- package/lib/api-schemas/dashboard.d.ts +408 -0
- package/lib/api-schemas/dashboard.d.ts.map +1 -0
- package/lib/api-schemas/dashboard.js +311 -0
- package/lib/api-schemas/dashboard.js.map +1 -0
- package/lib/api-schemas/data-store.d.ts +1650 -0
- package/lib/api-schemas/data-store.d.ts.map +1 -0
- package/lib/api-schemas/data-store.js +504 -0
- package/lib/api-schemas/data-store.js.map +1 -0
- package/lib/api-schemas/document-processing.d.ts +1501 -0
- package/lib/api-schemas/document-processing.d.ts.map +1 -0
- package/lib/api-schemas/document-processing.js +312 -0
- package/lib/api-schemas/document-processing.js.map +1 -0
- package/lib/api-schemas/embeddings.d.ts +184 -0
- package/lib/api-schemas/embeddings.d.ts.map +1 -0
- package/lib/api-schemas/embeddings.js +102 -0
- package/lib/api-schemas/embeddings.js.map +1 -0
- package/lib/api-schemas/environment.d.ts +412 -0
- package/lib/api-schemas/environment.d.ts.map +1 -0
- package/lib/api-schemas/environment.js +170 -0
- package/lib/api-schemas/environment.js.map +1 -0
- package/lib/api-schemas/events.d.ts +4880 -0
- package/lib/api-schemas/events.d.ts.map +1 -0
- package/lib/api-schemas/events.js +832 -0
- package/lib/api-schemas/events.js.map +1 -0
- package/lib/api-schemas/files.d.ts +107 -0
- package/lib/api-schemas/files.d.ts.map +1 -0
- package/lib/api-schemas/files.js +137 -0
- package/lib/api-schemas/files.js.map +1 -0
- package/lib/api-schemas/group.d.ts +122 -0
- package/lib/api-schemas/group.d.ts.map +1 -0
- package/lib/api-schemas/group.js +142 -0
- package/lib/api-schemas/group.js.map +1 -0
- package/lib/api-schemas/index.d.ts +36 -0
- package/lib/api-schemas/index.d.ts.map +1 -0
- package/lib/api-schemas/index.js +36 -0
- package/lib/api-schemas/index.js.map +1 -0
- package/lib/api-schemas/indexing.d.ts +144 -0
- package/lib/api-schemas/indexing.d.ts.map +1 -0
- package/lib/api-schemas/indexing.js +217 -0
- package/lib/api-schemas/indexing.js.map +1 -0
- package/lib/api-schemas/integrations.d.ts +269 -0
- package/lib/api-schemas/integrations.d.ts.map +1 -0
- package/lib/api-schemas/integrations.js +335 -0
- package/lib/api-schemas/integrations.js.map +1 -0
- package/lib/api-schemas/interaction.d.ts +22454 -0
- package/lib/api-schemas/interaction.d.ts.map +1 -0
- package/lib/api-schemas/interaction.js +2065 -0
- package/lib/api-schemas/interaction.js.map +1 -0
- package/lib/api-schemas/invites.d.ts +162 -0
- package/lib/api-schemas/invites.d.ts.map +1 -0
- package/lib/api-schemas/invites.js +106 -0
- package/lib/api-schemas/invites.js.map +1 -0
- package/lib/api-schemas/oauth-server.d.ts +415 -0
- package/lib/api-schemas/oauth-server.d.ts.map +1 -0
- package/lib/api-schemas/oauth-server.js +193 -0
- package/lib/api-schemas/oauth-server.js.map +1 -0
- package/lib/api-schemas/oauth.d.ts +150 -0
- package/lib/api-schemas/oauth.d.ts.map +1 -0
- package/lib/api-schemas/oauth.js +148 -0
- package/lib/api-schemas/oauth.js.map +1 -0
- package/lib/api-schemas/parameters.d.ts +64 -0
- package/lib/api-schemas/parameters.d.ts.map +1 -0
- package/lib/api-schemas/parameters.js +246 -0
- package/lib/api-schemas/parameters.js.map +1 -0
- package/lib/api-schemas/process.d.ts +499 -0
- package/lib/api-schemas/process.d.ts.map +1 -0
- package/lib/api-schemas/process.js +817 -0
- package/lib/api-schemas/process.js.map +1 -0
- package/lib/api-schemas/project-configuration.d.ts +4900 -0
- package/lib/api-schemas/project-configuration.d.ts.map +1 -0
- package/lib/api-schemas/project-configuration.js +425 -0
- package/lib/api-schemas/project-configuration.js.map +1 -0
- package/lib/api-schemas/project.d.ts +7247 -0
- package/lib/api-schemas/project.d.ts.map +1 -0
- package/lib/api-schemas/project.js +185 -0
- package/lib/api-schemas/project.js.map +1 -0
- package/lib/api-schemas/prompt.d.ts +70 -0
- package/lib/api-schemas/prompt.d.ts.map +1 -0
- package/lib/api-schemas/prompt.js +77 -0
- package/lib/api-schemas/prompt.js.map +1 -0
- package/lib/api-schemas/quota.d.ts +90 -0
- package/lib/api-schemas/quota.d.ts.map +1 -0
- package/lib/api-schemas/quota.js +95 -0
- package/lib/api-schemas/quota.js.map +1 -0
- package/lib/api-schemas/registry.d.ts +97458 -0
- package/lib/api-schemas/registry.d.ts.map +1 -0
- package/lib/api-schemas/registry.js +2586 -0
- package/lib/api-schemas/registry.js.map +1 -0
- package/lib/api-schemas/schema-primitives.d.ts +5 -0
- package/lib/api-schemas/schema-primitives.d.ts.map +1 -0
- package/lib/api-schemas/schema-primitives.js +11 -0
- package/lib/api-schemas/schema-primitives.js.map +1 -0
- package/lib/api-schemas/secrets.d.ts +497 -0
- package/lib/api-schemas/secrets.d.ts.map +1 -0
- package/lib/api-schemas/secrets.js +298 -0
- package/lib/api-schemas/secrets.js.map +1 -0
- package/lib/api-schemas/store.d.ts +22140 -0
- package/lib/api-schemas/store.d.ts.map +1 -0
- package/lib/api-schemas/store.js +557 -0
- package/lib/api-schemas/store.js.map +1 -0
- package/lib/api-schemas/sts.d.ts +156 -0
- package/lib/api-schemas/sts.d.ts.map +1 -0
- package/lib/api-schemas/sts.js +96 -0
- package/lib/api-schemas/sts.js.map +1 -0
- package/lib/api-schemas/task.d.ts +215 -0
- package/lib/api-schemas/task.d.ts.map +1 -0
- package/lib/api-schemas/task.js +95 -0
- package/lib/api-schemas/task.js.map +1 -0
- package/lib/api-schemas/tools.d.ts +111 -0
- package/lib/api-schemas/tools.d.ts.map +1 -0
- package/lib/api-schemas/tools.js +122 -0
- package/lib/api-schemas/tools.js.map +1 -0
- package/lib/api-schemas/user.d.ts +208 -0
- package/lib/api-schemas/user.d.ts.map +1 -0
- package/lib/api-schemas/user.js +180 -0
- package/lib/api-schemas/user.js.map +1 -0
- package/lib/api-schemas/view-execution.d.ts +3163 -0
- package/lib/api-schemas/view-execution.d.ts.map +1 -0
- package/lib/api-schemas/view-execution.js +172 -0
- package/lib/api-schemas/view-execution.js.map +1 -0
- package/lib/api-schemas/views.d.ts +5990 -0
- package/lib/api-schemas/views.d.ts.map +1 -0
- package/lib/api-schemas/views.js +396 -0
- package/lib/api-schemas/views.js.map +1 -0
- package/lib/api-schemas/workflow-runs.d.ts +2209 -0
- package/lib/api-schemas/workflow-runs.d.ts.map +1 -0
- package/lib/api-schemas/workflow-runs.js +589 -0
- package/lib/api-schemas/workflow-runs.js.map +1 -0
- package/lib/apikey-values.d.ts +10 -0
- package/lib/apikey-values.d.ts.map +1 -0
- package/lib/apikey-values.js +11 -0
- package/lib/apikey-values.js.map +1 -0
- package/lib/apikey.d.ts +37 -36
- package/lib/apikey.d.ts.map +1 -1
- package/lib/apikey.js +5 -4
- package/lib/apikey.js.map +1 -1
- package/lib/apps.d.ts +116 -1121
- package/lib/apps.d.ts.map +1 -1
- package/lib/apps.js.map +1 -1
- package/lib/ask-user.d.ts +8 -1
- package/lib/ask-user.d.ts.map +1 -1
- package/lib/audit-trail.d.ts +17 -128
- package/lib/audit-trail.d.ts.map +1 -1
- package/lib/audit-trail.js.map +1 -1
- package/lib/browser-credentials.d.ts +11 -106
- package/lib/browser-credentials.d.ts.map +1 -1
- package/lib/common.d.ts +59 -81
- package/lib/common.d.ts.map +1 -1
- package/lib/cost-analytics.d.ts +14 -167
- package/lib/cost-analytics.d.ts.map +1 -1
- package/lib/cost-analytics.js.map +1 -1
- package/lib/data-platform.d.ts +122 -786
- package/lib/data-platform.d.ts.map +1 -1
- package/lib/data-platform.js +41 -61
- package/lib/data-platform.js.map +1 -1
- package/lib/email.d.ts +5 -17
- package/lib/email.d.ts.map +1 -1
- package/lib/email.js +0 -3
- package/lib/email.js.map +1 -1
- package/lib/embeddings.d.ts +14 -56
- package/lib/embeddings.d.ts.map +1 -1
- package/lib/environment.d.ts +19 -113
- package/lib/environment.d.ts.map +1 -1
- package/lib/environment.js +3 -0
- package/lib/environment.js.map +1 -1
- package/lib/facets.d.ts +4 -7
- package/lib/facets.d.ts.map +1 -1
- package/lib/group.d.ts +33 -39
- package/lib/group.d.ts.map +1 -1
- package/lib/group.js +0 -1
- package/lib/group.js.map +1 -1
- package/lib/index.d.ts +7 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/integrations.d.ts +20 -108
- package/lib/integrations.d.ts.map +1 -1
- package/lib/integrations.js.map +1 -1
- package/lib/interaction-values.d.ts +11 -0
- package/lib/interaction-values.d.ts.map +1 -0
- package/lib/interaction-values.js +24 -0
- package/lib/interaction-values.js.map +1 -0
- package/lib/interaction.d.ts +116 -734
- package/lib/interaction.d.ts.map +1 -1
- package/lib/interaction.js +56 -12
- package/lib/interaction.js.map +1 -1
- package/lib/meters.d.ts +11 -7
- package/lib/meters.d.ts.map +1 -1
- package/lib/meters.js.map +1 -1
- package/lib/oauth-server.d.ts +33 -119
- package/lib/oauth-server.d.ts.map +1 -1
- package/lib/oauth.d.ts +14 -96
- package/lib/oauth.d.ts.map +1 -1
- package/lib/oauth.js +0 -4
- package/lib/oauth.js.map +1 -1
- package/lib/payload.d.ts +15 -38
- package/lib/payload.d.ts.map +1 -1
- package/lib/platform-event.d.ts +49 -462
- package/lib/platform-event.d.ts.map +1 -1
- package/lib/platform-event.js.map +1 -1
- package/lib/principal-context.d.ts +10 -15
- package/lib/principal-context.d.ts.map +1 -1
- package/lib/project-values.d.ts +24 -0
- package/lib/project-values.d.ts.map +1 -0
- package/lib/project-values.js +42 -0
- package/lib/project-values.js.map +1 -0
- package/lib/project.d.ts +55 -503
- package/lib/project.d.ts.map +1 -1
- package/lib/project.js +6 -76
- package/lib/project.js.map +1 -1
- package/lib/prompt.d.ts +20 -51
- package/lib/prompt.d.ts.map +1 -1
- package/lib/prompt.js.map +1 -1
- package/lib/query.d.ts +27 -88
- package/lib/query.d.ts.map +1 -1
- package/lib/rate-limiter.d.ts +19 -70
- package/lib/rate-limiter.d.ts.map +1 -1
- package/lib/rate-limiter.js +0 -3
- package/lib/rate-limiter.js.map +1 -1
- package/lib/refs.d.ts +3 -11
- package/lib/refs.d.ts.map +1 -1
- package/lib/refs.js.map +1 -1
- package/lib/roles/types.d.ts +14 -20
- package/lib/roles/types.d.ts.map +1 -1
- package/lib/roles/types.js +5 -9
- package/lib/roles/types.js.map +1 -1
- package/lib/runs.d.ts +6 -25
- package/lib/runs.d.ts.map +1 -1
- package/lib/secrets.d.ts +20 -105
- package/lib/secrets.d.ts.map +1 -1
- package/lib/store/agent-approval.d.ts +5 -14
- package/lib/store/agent-approval.d.ts.map +1 -1
- package/lib/store/agent-approval.js.map +1 -1
- package/lib/store/agent-run.d.ts +63 -342
- package/lib/store/agent-run.d.ts.map +1 -1
- package/lib/store/collections.d.ts +11 -63
- package/lib/store/collections.d.ts.map +1 -1
- package/lib/store/collections.js.map +1 -1
- package/lib/store/conversation-state.d.ts +63 -61
- package/lib/store/conversation-state.d.ts.map +1 -1
- package/lib/store/conversation-state.js +2 -0
- package/lib/store/conversation-state.js.map +1 -1
- package/lib/store/doc-analyzer.d.ts +9 -32
- package/lib/store/doc-analyzer.d.ts.map +1 -1
- package/lib/store/dsl-workflow.d.ts +37 -151
- package/lib/store/dsl-workflow.d.ts.map +1 -1
- package/lib/store/dsl-workflow.js.map +1 -1
- package/lib/store/editing-policy-schema.generated.d.ts +3 -0
- package/lib/store/editing-policy-schema.generated.d.ts.map +1 -0
- package/lib/store/editing-policy-schema.generated.js +28 -0
- package/lib/store/editing-policy-schema.generated.js.map +1 -0
- package/lib/store/grounded-extraction.d.ts +7 -104
- package/lib/store/grounded-extraction.d.ts.map +1 -1
- package/lib/store/grounded-extraction.js.map +1 -1
- package/lib/store/index.d.ts +2 -0
- package/lib/store/index.d.ts.map +1 -1
- package/lib/store/index.js +3 -0
- package/lib/store/index.js.map +1 -1
- package/lib/store/intake-policy-schema.generated.d.ts +3 -0
- package/lib/store/intake-policy-schema.generated.d.ts.map +1 -0
- package/lib/store/intake-policy-schema.generated.js +1425 -0
- package/lib/store/intake-policy-schema.generated.js.map +1 -0
- package/lib/store/process-schema.d.ts +80 -0
- package/lib/store/process-schema.d.ts.map +1 -1
- package/lib/store/process-schema.js +79 -0
- package/lib/store/process-schema.js.map +1 -1
- package/lib/store/process-validation.d.ts.map +1 -1
- package/lib/store/process-validation.js +70 -2
- package/lib/store/process-validation.js.map +1 -1
- package/lib/store/process.d.ts +36 -125
- package/lib/store/process.d.ts.map +1 -1
- package/lib/store/process.js.map +1 -1
- package/lib/store/rendering.d.ts +9 -64
- package/lib/store/rendering.d.ts.map +1 -1
- package/lib/store/rendering.js.map +1 -1
- package/lib/store/store.d.ts +98 -693
- package/lib/store/store.d.ts.map +1 -1
- package/lib/store/store.js +4 -443
- package/lib/store/store.js.map +1 -1
- package/lib/store/task.d.ts +15 -59
- package/lib/store/task.d.ts.map +1 -1
- package/lib/store/task.js +0 -3
- package/lib/store/task.js.map +1 -1
- package/lib/store/workflow.d.ts +56 -516
- package/lib/store/workflow.d.ts.map +1 -1
- package/lib/store/workflow.js +28 -11
- package/lib/store/workflow.js.map +1 -1
- package/lib/sts-token-types.d.ts +12 -66
- package/lib/sts-token-types.d.ts.map +1 -1
- package/lib/sts-token-types.js.map +1 -1
- package/lib/tools.d.ts +8 -100
- package/lib/tools.d.ts.map +1 -1
- package/lib/transient-tokens-values.d.ts +11 -0
- package/lib/transient-tokens-values.d.ts.map +1 -0
- package/lib/transient-tokens-values.js +12 -0
- package/lib/transient-tokens-values.js.map +1 -0
- package/lib/transient-tokens.d.ts +15 -13
- package/lib/transient-tokens.d.ts.map +1 -1
- package/lib/transient-tokens.js +5 -5
- package/lib/transient-tokens.js.map +1 -1
- package/lib/user.d.ts +54 -155
- package/lib/user.d.ts.map +1 -1
- package/lib/user.js +1 -78
- package/lib/user.js.map +1 -1
- package/lib/versions.d.ts +24 -1
- package/lib/versions.d.ts.map +1 -1
- package/lib/versions.js +23 -0
- package/lib/versions.js.map +1 -1
- package/lib/vertesia-common.js +6 -2
- package/lib/vertesia-common.js.map +1 -1
- package/lib/views-schema.d.ts +4 -4
- package/lib/views.d.ts +56 -312
- package/lib/views.d.ts.map +1 -1
- package/lib/views.js.map +1 -1
- package/package.json +14 -5
- package/src/access-control-values.ts +113 -0
- package/src/access-control.ts +33 -138
- package/src/account-values.ts +95 -0
- package/src/agent-resources.test.ts +100 -0
- package/src/analytics.ts +18 -42
- package/src/api-schemas/access-control.contract.test.ts +209 -0
- package/src/api-schemas/access-control.ts +208 -0
- package/src/api-schemas/account.contract.test.ts +318 -0
- package/src/api-schemas/account.ts +150 -0
- package/src/api-schemas/adapter-edge-cases.test.ts +480 -0
- package/src/api-schemas/adapter.ts +778 -0
- package/src/api-schemas/agent-runs.ts +1081 -0
- package/src/api-schemas/analytics.ts +65 -0
- package/src/api-schemas/apikey.contract.test.ts +270 -0
- package/src/api-schemas/apikey.ts +199 -0
- package/src/api-schemas/app-lifecycle.ts +841 -0
- package/src/api-schemas/app-runtime.ts +919 -0
- package/src/api-schemas/apps.ts +415 -0
- package/src/api-schemas/audit-trail.ts +243 -0
- package/src/api-schemas/bulk-operation.contract.test.ts +39 -0
- package/src/api-schemas/bulk-operation.ts +75 -0
- package/src/api-schemas/bundle-isolation.test.ts +80 -0
- package/src/api-schemas/commands.contract.test.ts +51 -0
- package/src/api-schemas/commands.ts +62 -0
- package/src/api-schemas/content.ts +939 -0
- package/src/api-schemas/cost-analytics.contract.test.ts +64 -0
- package/src/api-schemas/cost-analytics.ts +235 -0
- package/src/api-schemas/dashboard.contract.test.ts +127 -0
- package/src/api-schemas/dashboard.ts +351 -0
- package/src/api-schemas/data-store.contract.test.ts +91 -0
- package/src/api-schemas/data-store.ts +571 -0
- package/src/api-schemas/document-processing.contract.test.ts +76 -0
- package/src/api-schemas/document-processing.ts +344 -0
- package/src/api-schemas/embeddings.ts +113 -0
- package/src/api-schemas/environment.contract.test.ts +184 -0
- package/src/api-schemas/environment.ts +190 -0
- package/src/api-schemas/events.ts +921 -0
- package/src/api-schemas/files.ts +159 -0
- package/src/api-schemas/group.contract.test.ts +205 -0
- package/src/api-schemas/group.ts +155 -0
- package/src/api-schemas/index.ts +35 -0
- package/src/api-schemas/indexing.contract.test.ts +83 -0
- package/src/api-schemas/indexing.ts +234 -0
- package/src/api-schemas/integrations.ts +369 -0
- package/src/api-schemas/interaction.ts +2357 -0
- package/src/api-schemas/invites.contract.test.ts +268 -0
- package/src/api-schemas/invites.ts +127 -0
- package/src/api-schemas/llumiverse.contract.test.ts +108 -0
- package/src/api-schemas/oauth-server.ts +219 -0
- package/src/api-schemas/oauth.contract.test.ts +118 -0
- package/src/api-schemas/oauth.ts +166 -0
- package/src/api-schemas/parameters.test.ts +402 -0
- package/src/api-schemas/parameters.ts +310 -0
- package/src/api-schemas/process.ts +929 -0
- package/src/api-schemas/project-configuration.ts +478 -0
- package/src/api-schemas/project.contract.test.ts +365 -0
- package/src/api-schemas/project.ts +214 -0
- package/src/api-schemas/prompt.ts +88 -0
- package/src/api-schemas/pruning-limits.test.ts +189 -0
- package/src/api-schemas/quota.contract.test.ts +147 -0
- package/src/api-schemas/quota.ts +122 -0
- package/src/api-schemas/registry-groups.test.ts +91 -0
- package/src/api-schemas/registry.ts +3487 -0
- package/src/api-schemas/response-pruning.test.ts +260 -0
- package/src/api-schemas/schema-primitives.ts +12 -0
- package/src/api-schemas/secrets.ts +332 -0
- package/src/api-schemas/store.contract.test.ts +450 -0
- package/src/api-schemas/store.ts +604 -0
- package/src/api-schemas/sts.contract.test.ts +80 -0
- package/src/api-schemas/sts.ts +110 -0
- package/src/api-schemas/task.ts +104 -0
- package/src/api-schemas/tools.ts +140 -0
- package/src/api-schemas/user.contract.test.ts +191 -0
- package/src/api-schemas/user.ts +204 -0
- package/src/api-schemas/view-execution.ts +200 -0
- package/src/api-schemas/views.ts +437 -0
- package/src/api-schemas/workflow-runs.ts +653 -0
- package/src/apikey-values.ts +10 -0
- package/src/apikey.ts +49 -40
- package/src/apps.ts +249 -1179
- package/src/ask-user.ts +9 -1
- package/src/audit-trail.ts +45 -137
- package/src/browser-credentials.ts +21 -106
- package/src/common.ts +67 -78
- package/src/cost-analytics.ts +37 -176
- package/src/data-platform.ts +205 -776
- package/src/email.ts +5 -17
- package/src/embeddings.ts +22 -60
- package/src/environment.ts +52 -124
- package/src/facets.ts +4 -7
- package/src/group.ts +38 -42
- package/src/index.ts +11 -0
- package/src/integrations.ts +39 -129
- package/src/interaction-values.ts +23 -0
- package/src/interaction.ts +231 -841
- package/src/meters.ts +11 -7
- package/src/oauth-server.ts +58 -127
- package/src/oauth.ts +24 -108
- package/src/payload.ts +25 -40
- package/src/platform-event.ts +98 -484
- package/src/principal-context.ts +11 -15
- package/src/project-values.ts +41 -0
- package/src/project.ts +116 -588
- package/src/prompt.ts +34 -61
- package/src/query.ts +34 -93
- package/src/rate-limiter.ts +27 -75
- package/src/refs.ts +4 -11
- package/src/roles/types.ts +20 -20
- package/src/runs.ts +11 -24
- package/src/secrets.ts +38 -117
- package/src/store/agent-approval.ts +9 -14
- package/src/store/agent-run.ts +106 -434
- package/src/store/collections.ts +21 -63
- package/src/store/content-type-editing.test.ts +17 -0
- package/src/store/conversation-state.ts +78 -64
- package/src/store/doc-analyzer.ts +17 -33
- package/src/store/dsl-workflow.ts +62 -158
- package/src/store/editing-policy-schema.generated.ts +30 -0
- package/src/store/grounded-extraction.ts +13 -104
- package/src/store/index.ts +3 -0
- package/src/store/intake-policy-schema.generated.ts +1442 -0
- package/src/store/process-schema.test.ts +43 -0
- package/src/store/process-schema.ts +79 -0
- package/src/store/process-validation.test.ts +141 -0
- package/src/store/process-validation.ts +82 -2
- package/src/store/process.ts +70 -146
- package/src/store/rendering.ts +15 -64
- package/src/store/store.ts +197 -1182
- package/src/store/task.ts +25 -59
- package/src/store/workflow.ts +103 -554
- package/src/sts-token-types.ts +24 -75
- package/src/tools.ts +18 -97
- package/src/transient-tokens-values.ts +11 -0
- package/src/transient-tokens.ts +16 -13
- package/src/user.ts +74 -214
- package/src/versions.ts +24 -0
- package/src/views-schema.test.ts +9 -1
- package/src/views.ts +106 -329
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The run-analytics query and its result rows.
|
|
5
|
+
*
|
|
6
|
+
* `POST /environments/:envId/analytics` and `POST /analytics` take the same body, so the components
|
|
7
|
+
* are shared rather than duplicated per resource.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export const TimeResolutionSchema = z
|
|
11
|
+
.enum(['minute', 'hour', 'day', 'week', 'month', 'year'])
|
|
12
|
+
.meta({ id: 'TimeResolution' });
|
|
13
|
+
|
|
14
|
+
export const RunAnalyticsGroupBySchema = z
|
|
15
|
+
.enum(['interaction', 'modelId', 'project', 'status', 'tags', 'environment'])
|
|
16
|
+
.meta({ id: 'RunAnalyticsGroupBy' });
|
|
17
|
+
|
|
18
|
+
export const AnalyticsAxisSchema = z
|
|
19
|
+
.strictObject({
|
|
20
|
+
environment: z.string().optional(),
|
|
21
|
+
project: z.string().optional(),
|
|
22
|
+
interactions: z.array(z.string()).optional(),
|
|
23
|
+
models: z.array(z.string()).optional(),
|
|
24
|
+
status: z.array(z.string()).optional(),
|
|
25
|
+
tags: z.array(z.string()).optional(),
|
|
26
|
+
selectedOnly: z.boolean().optional(),
|
|
27
|
+
})
|
|
28
|
+
.meta({ id: 'AnalyticsAxis' });
|
|
29
|
+
|
|
30
|
+
export const RunAnalyticsQuerySchema = z
|
|
31
|
+
.strictObject({
|
|
32
|
+
filterBy: AnalyticsAxisSchema.meta({ description: 'filters to apply to the query' }),
|
|
33
|
+
groupBy: RunAnalyticsGroupBySchema.meta({ description: 'The field to group by' }).optional(),
|
|
34
|
+
from: z.number().meta({ description: 'The start date of the query in EPOCH format' }).optional(),
|
|
35
|
+
to: z.number().meta({ description: 'The end date of the query in EPOCH format' }).optional(),
|
|
36
|
+
resolution: TimeResolutionSchema.meta({
|
|
37
|
+
description: 'The time resolution unit of the analytics query',
|
|
38
|
+
}).optional(),
|
|
39
|
+
resolutionStep: z
|
|
40
|
+
.number()
|
|
41
|
+
.meta({
|
|
42
|
+
description:
|
|
43
|
+
"The step size for the resolution (e.g., 4 with resolution='hour' means 4-hour " +
|
|
44
|
+
'intervals). Defaults to 1.',
|
|
45
|
+
})
|
|
46
|
+
.optional(),
|
|
47
|
+
virtual: z.boolean().meta({ description: 'The field to sort by' }).optional(),
|
|
48
|
+
})
|
|
49
|
+
.meta({ id: 'RunAnalyticsQuery' });
|
|
50
|
+
|
|
51
|
+
export const RunAnalyticsResultSchema = z
|
|
52
|
+
.strictObject({
|
|
53
|
+
date: z.string(),
|
|
54
|
+
timestamp: z.string(),
|
|
55
|
+
group: z.string(),
|
|
56
|
+
count: z.number(),
|
|
57
|
+
execution_time: z.strictObject({
|
|
58
|
+
avg: z.number(),
|
|
59
|
+
min: z.number(),
|
|
60
|
+
max: z.number(),
|
|
61
|
+
}),
|
|
62
|
+
})
|
|
63
|
+
.meta({ id: 'RunAnalyticsResult' });
|
|
64
|
+
|
|
65
|
+
export const RunAnalyticsResultArraySchema = z.array(RunAnalyticsResultSchema).meta({ id: 'RunAnalyticsResultArray' });
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { Ajv2020 } from 'ajv/dist/2020.js';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import {
|
|
4
|
+
type ApiKey,
|
|
5
|
+
type ApiKeyArray,
|
|
6
|
+
type ApiKeyReadResponse,
|
|
7
|
+
ApiKeyTypes,
|
|
8
|
+
type ApiKeyWithValue,
|
|
9
|
+
type CreateApiKeyPayload,
|
|
10
|
+
type UpdateApiKeyPayload,
|
|
11
|
+
} from '../apikey.js';
|
|
12
|
+
import { type ProjectRef, SystemRoles } from '../project.js';
|
|
13
|
+
import type { JsonObject } from './adapter.js';
|
|
14
|
+
import type { ProjectRefArrayFromSchema } from './apikey.js';
|
|
15
|
+
import { ApiSchemaComponents, apiComponentRef, validateApiRequest, validateApiResponse } from './registry.js';
|
|
16
|
+
|
|
17
|
+
/** Exact type identity — `extends` in both directions is too weak (any/unknown slip through). */
|
|
18
|
+
type Equals<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2 ? true : false;
|
|
19
|
+
function assertType<T extends true>(_ok: T): void {}
|
|
20
|
+
|
|
21
|
+
function compile(name: string) {
|
|
22
|
+
const ajv = new Ajv2020({ strictSchema: false, allErrors: true });
|
|
23
|
+
ajv.addSchema({ $id: 'vertesia://openapi', components: { schemas: ApiSchemaComponents } });
|
|
24
|
+
return ajv.compile({ $ref: `vertesia://openapi${apiComponentRef(name as never)}` });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const VALID_PROJECT_REF = {
|
|
28
|
+
id: '69d4762f24d3048c99149d0b',
|
|
29
|
+
name: 'Research',
|
|
30
|
+
account: '68b1779130afe5403a1589ba',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const VALID_KEY = {
|
|
34
|
+
id: '68b1779130afe5403a1589bc',
|
|
35
|
+
name: 'CI',
|
|
36
|
+
type: ApiKeyTypes.secret,
|
|
37
|
+
role: SystemRoles.developer,
|
|
38
|
+
account: '68b1779130afe5403a1589ba',
|
|
39
|
+
project: VALID_PROJECT_REF,
|
|
40
|
+
enabled: true,
|
|
41
|
+
created_by: 'ada@acme.test',
|
|
42
|
+
updated_by: 'ada@acme.test',
|
|
43
|
+
created_at: '2026-01-01T00:00:00.000Z',
|
|
44
|
+
updated_at: '2026-01-02T00:00:00.000Z',
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
describe('gate 1 — the schema is the single source of truth for the public API key types', () => {
|
|
48
|
+
it('publishes the exact schema-derived type, not a hand-written twin', () => {
|
|
49
|
+
assertType<Equals<ApiKeyArray, ApiKey[]>>(true);
|
|
50
|
+
assertType<Equals<ProjectRefArrayFromSchema, ProjectRef[]>>(true);
|
|
51
|
+
expect(true).toBe(true);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('types the timestamps as strings, which is what the document always published', () => {
|
|
55
|
+
// The hand-written `ApiKey` said `Date` for all three. JSON has no date type and the
|
|
56
|
+
// component has always declared `format: date-time`, so the old declaration described the
|
|
57
|
+
// Mongoose document, not the response — the same correction `User` and `UserGroup` needed.
|
|
58
|
+
assertType<Equals<ApiKey['created_at'], string>>(true);
|
|
59
|
+
assertType<Equals<ApiKey['updated_at'], string>>(true);
|
|
60
|
+
assertType<Equals<ApiKey['expires_at'], string | undefined>>(true);
|
|
61
|
+
expect(true).toBe(true);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('keeps the secret off the base type and derives the two shapes that carry it', () => {
|
|
65
|
+
// `value` is absent from `ApiKey` entirely, so a handler cannot leak a secret by returning
|
|
66
|
+
// the wrong shape — it has to name a component that declares one.
|
|
67
|
+
assertType<Equals<Extract<keyof ApiKey, 'value'>, never>>(true);
|
|
68
|
+
// Creation always returns the secret; the single-key read returns it only when asked for it
|
|
69
|
+
// AND permitted, which is why the two cannot share a component.
|
|
70
|
+
assertType<Equals<ApiKeyWithValue['value'], string>>(true);
|
|
71
|
+
assertType<Equals<ApiKeyReadResponse['value'], string | undefined>>(true);
|
|
72
|
+
// Everything else is inherited rather than restated.
|
|
73
|
+
assertType<Equals<ApiKeyWithValue['project'], ApiKey['project']>>(true);
|
|
74
|
+
assertType<Equals<ApiKeyReadResponse['role'], ApiKey['role']>>(true);
|
|
75
|
+
expect(true).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('gives create and update the different payloads the two operations actually have', () => {
|
|
79
|
+
// Both pick from `ApiKeySchema`, so a field's type and documentation keep one home; what
|
|
80
|
+
// differs is requiredness and which fields are writable at all — the only two things a write
|
|
81
|
+
// payload legitimately changes about a field it shares.
|
|
82
|
+
// Compared against `ApiKey`, not against the enums directly: the claim is that the payloads
|
|
83
|
+
// are PICKED from the key, so the identity that matters is with the field they came from.
|
|
84
|
+
assertType<Equals<CreateApiKeyPayload['name'], ApiKey['name']>>(true);
|
|
85
|
+
assertType<Equals<CreateApiKeyPayload['role'], ApiKey['role']>>(true);
|
|
86
|
+
assertType<Equals<CreateApiKeyPayload['type'], ApiKey['type'] | undefined>>(true);
|
|
87
|
+
assertType<Equals<CreateApiKeyPayload['expires_at'], ApiKey['expires_at']>>(true);
|
|
88
|
+
assertType<Equals<UpdateApiKeyPayload['name'], ApiKey['name'] | undefined>>(true);
|
|
89
|
+
assertType<Equals<UpdateApiKeyPayload['role'], ApiKey['role'] | undefined>>(true);
|
|
90
|
+
assertType<Equals<UpdateApiKeyPayload['enabled'], ApiKey['enabled'] | undefined>>(true);
|
|
91
|
+
// `name` and `role` are required on create and optional on update — the only difference a
|
|
92
|
+
// write payload legitimately introduces.
|
|
93
|
+
assertType<Equals<CreateApiKeyPayload['name'], string>>(true);
|
|
94
|
+
assertType<Equals<UpdateApiKeyPayload['name'], string | undefined>>(true);
|
|
95
|
+
|
|
96
|
+
// What the picks leave out is the whitelist, and it is now an explicit list rather than a
|
|
97
|
+
// consequence of `Partial<ApiKey>`: the server-owned fields are unreachable from either.
|
|
98
|
+
assertType<Equals<Extract<keyof CreateApiKeyPayload, 'id' | 'account' | 'maskedValue'>, never>>(true);
|
|
99
|
+
assertType<Equals<Extract<keyof CreateApiKeyPayload, 'created_at' | 'enabled' | 'project'>, never>>(true);
|
|
100
|
+
// `type` and `expires_at` are immutable after creation, so update cannot name them.
|
|
101
|
+
assertType<Equals<Extract<keyof UpdateApiKeyPayload, 'type' | 'expires_at'>, never>>(true);
|
|
102
|
+
expect(true).toBe(true);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe('gate 2 — the published components match the closure the types come from', () => {
|
|
107
|
+
it('publishes the single-member key type as a const, not a one-member enum', () => {
|
|
108
|
+
// Both validate identically; only one is byte-identical to what the TypeScript scanner
|
|
109
|
+
// emitted, and slots that have not converted still derive this component — the generator
|
|
110
|
+
// fails the build if the two definitions disagree.
|
|
111
|
+
expect(ApiSchemaComponents.ApiKeyTypes).toEqual({ type: 'string', const: 'sk' });
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('keeps ProjectRef and SystemRoles as shared components rather than inlining them', () => {
|
|
115
|
+
const props = ApiSchemaComponents.ApiKey.properties as Record<string, JsonObject>;
|
|
116
|
+
expect(props.project).toEqual({ $ref: '#/components/schemas/ProjectRef' });
|
|
117
|
+
expect(props.role).toEqual({ $ref: '#/components/schemas/SystemRoles' });
|
|
118
|
+
expect(props.type).toEqual({ $ref: '#/components/schemas/ApiKeyTypes' });
|
|
119
|
+
expect(ApiSchemaComponents.SystemRoles.enum).toContain('content_superadmin');
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('tightens the API key timestamps to date-time, unlike the ACE ones', () => {
|
|
123
|
+
// Safe here in a way it was not for an access control entry: every one of these is written
|
|
124
|
+
// by the server. `expires_at` too — it is computed from a TTL, never copied out of a payload.
|
|
125
|
+
const props = ApiSchemaComponents.ApiKey.properties as Record<string, JsonObject>;
|
|
126
|
+
expect(props.created_at).toEqual({ type: 'string', format: 'date-time' });
|
|
127
|
+
expect(props.updated_at).toEqual({ type: 'string', format: 'date-time' });
|
|
128
|
+
expect(props.expires_at).toEqual({ type: 'string', format: 'date-time' });
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('does not declare value on the base component', () => {
|
|
132
|
+
expect(Object.keys(ApiSchemaComponents.ApiKey.properties as JsonObject)).not.toContain('value');
|
|
133
|
+
expect(ApiSchemaComponents.ApiKey.additionalProperties).toBe(false);
|
|
134
|
+
expect((ApiSchemaComponents.ApiKeyWithValue.required as string[]) ?? []).toContain('value');
|
|
135
|
+
expect((ApiSchemaComponents.ApiKeyReadResponse.required as string[]) ?? []).not.toContain('value');
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('publishes ProjectRef closed, with the documentation the list endpoints rely on', () => {
|
|
139
|
+
const props = ApiSchemaComponents.ProjectRef.properties as Record<string, JsonObject>;
|
|
140
|
+
expect(ApiSchemaComponents.ProjectRef.additionalProperties).toBe(false);
|
|
141
|
+
expect(props.restricted.description).toContain('org admin or owner');
|
|
142
|
+
expect(ApiSchemaComponents.ProjectRef.required).toEqual(['id', 'name', 'account']);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
describe('gate 3 — AJV validates the same canonical objects that are published', () => {
|
|
147
|
+
it('accepts a minimal key and rejects a missing required field', () => {
|
|
148
|
+
const validate = compile('ApiKey');
|
|
149
|
+
expect(validate(VALID_KEY)).toBe(true);
|
|
150
|
+
const { project: _dropped, ...incomplete } = VALID_KEY;
|
|
151
|
+
expect(validate(incomplete)).toBe(false);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('rejects a base key response that carries a secret', () => {
|
|
155
|
+
// The point of splitting the components: a handler that returns the wrong one is caught at
|
|
156
|
+
// the boundary rather than shipping the secret.
|
|
157
|
+
expect(compile('ApiKey')({ ...VALID_KEY, value: 'sk-live-abcdef' })).toBe(false);
|
|
158
|
+
expect(compile('ApiKeyWithValue')({ ...VALID_KEY, value: 'sk-live-abcdef' })).toBe(true);
|
|
159
|
+
expect(compile('ApiKeyReadResponse')({ ...VALID_KEY, value: 'sk-live-abcdef' })).toBe(true);
|
|
160
|
+
expect(compile('ApiKeyReadResponse')(VALID_KEY)).toBe(true);
|
|
161
|
+
// ...and one that omits it where it is promised.
|
|
162
|
+
expect(compile('ApiKeyWithValue')(VALID_KEY)).toBe(false);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('rejects a Date where the contract declares a date-time string', () => {
|
|
166
|
+
// What `jsonDoc()` produced before `toApiKeyResponse` existed: `toJSON()` leaves `Date`
|
|
167
|
+
// objects in place, and only `JSON.stringify` converts them — after the enforcer has run.
|
|
168
|
+
// A `Date` fails on `type: string` alone, so this holds with or without format assertion.
|
|
169
|
+
expect(compile('ApiKey')({ ...VALID_KEY, created_at: new Date('2026-01-01T00:00:00.000Z') })).toBe(false);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it('enforces the date-time format through the registry validator, which is what registers formats', () => {
|
|
173
|
+
// The local `compile()` above deliberately does NOT add ajv-formats — it exists to check the
|
|
174
|
+
// published SHAPE. `format` is only asserted by the production validator, so a malformed
|
|
175
|
+
// timestamp has to be checked there or the assertion would pass vacuously.
|
|
176
|
+
expect(validateApiResponse('ApiKey', { ...VALID_KEY, created_at: 'last tuesday' }).valid).toBe(false);
|
|
177
|
+
expect(validateApiResponse('ApiKey', VALID_KEY).valid).toBe(true);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('rejects the internal fields a serialized document would have leaked', () => {
|
|
181
|
+
const validate = compile('ApiKey');
|
|
182
|
+
expect(validate({ ...VALID_KEY, _id: 'deadbeef' })).toBe(false);
|
|
183
|
+
expect(validate({ ...VALID_KEY, hashed_value: 'deadbeef' })).toBe(false);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('constrains the key type and the role to their catalogs', () => {
|
|
187
|
+
const validate = compile('ApiKey');
|
|
188
|
+
expect(validate({ ...VALID_KEY, type: 'pk' })).toBe(false);
|
|
189
|
+
expect(validate({ ...VALID_KEY, role: 'superuser' })).toBe(false);
|
|
190
|
+
expect(validate({ ...VALID_KEY, role: SystemRoles.content_superadmin })).toBe(true);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('requires name and role on a create, which the handler needed and the payload never said', () => {
|
|
194
|
+
const validate = compile('CreateApiKeyPayload');
|
|
195
|
+
expect(validate({ name: 'CI', role: SystemRoles.reader })).toBe(true);
|
|
196
|
+
expect(validate({ name: 'CI', role: SystemRoles.reader, type: 'sk', expires_at: '2030-01-01T00:00:00Z' })).toBe(
|
|
197
|
+
true,
|
|
198
|
+
);
|
|
199
|
+
// `role` is `required: true` on the Mongoose schema: this used to be accepted here and fail
|
|
200
|
+
// inside `ApiKeyModel.create`, which the endpoint reported as a 500.
|
|
201
|
+
expect(validate({ name: 'CI' })).toBe(false);
|
|
202
|
+
// `name` is required by the published `ApiKey` component, so a key created without one could
|
|
203
|
+
// not produce a conforming response.
|
|
204
|
+
expect(validate({ role: SystemRoles.reader })).toBe(false);
|
|
205
|
+
expect(validate({})).toBe(false);
|
|
206
|
+
// Server-owned fields are no longer declared, so sending one is now an error rather than
|
|
207
|
+
// silently ignored.
|
|
208
|
+
expect(validate({ name: 'CI', role: SystemRoles.reader, id: 'x' })).toBe(false);
|
|
209
|
+
expect(validate({ name: 'CI', role: SystemRoles.reader, enabled: true })).toBe(false);
|
|
210
|
+
expect(validate({ name: 'CI', role: SystemRoles.reader, project: VALID_PROJECT_REF })).toBe(false);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('accepts a partial update and rejects the fields creation owns', () => {
|
|
214
|
+
const validate = compile('UpdateApiKeyPayload');
|
|
215
|
+
expect(validate({})).toBe(true);
|
|
216
|
+
expect(validate({ enabled: false })).toBe(true);
|
|
217
|
+
expect(validate({ name: 'CI', role: SystemRoles.reader, enabled: true })).toBe(true);
|
|
218
|
+
expect(validate({ role: 'superuser' })).toBe(false);
|
|
219
|
+
// Immutable after creation.
|
|
220
|
+
expect(validate({ type: 'sk' })).toBe(false);
|
|
221
|
+
expect(validate({ expires_at: '2030-01-01T00:00:00Z' })).toBe(false);
|
|
222
|
+
expect(validate({ rogue_field: 1 })).toBe(false);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('validates the two query components the scanner expands into parameters', () => {
|
|
226
|
+
expect(compile('ApiKeyListQuery')({ level: 'project' })).toBe(true);
|
|
227
|
+
expect(compile('ApiKeyListQuery')({})).toBe(true);
|
|
228
|
+
expect(compile('ApiKeyListQuery')({ level: 'organization' })).toBe(false);
|
|
229
|
+
expect(compile('ApiKeyReadQuery')({ withValue: true })).toBe(true);
|
|
230
|
+
expect(compile('ApiKeyReadQuery')({ withValue: 'yes' })).toBe(false);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
describe('gate 4 — runtime enforcement uses the published components', () => {
|
|
235
|
+
it('checks every member of a listing against the same key component', () => {
|
|
236
|
+
expect(validateApiResponse('ApiKeyArray', [VALID_KEY, VALID_KEY]).valid).toBe(true);
|
|
237
|
+
expect(validateApiResponse('ApiKeyArray', []).valid).toBe(true);
|
|
238
|
+
// One key in the listing still carrying its secret is exactly what the fail-closed boundary
|
|
239
|
+
// in `toApiKeyResponse` exists to make impossible.
|
|
240
|
+
expect(validateApiResponse('ApiKeyArray', [VALID_KEY, { ...VALID_KEY, value: 'sk-leak' }]).valid).toBe(false);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('rejects an undeclared payload field without removing it', () => {
|
|
244
|
+
const payload: Record<string, unknown> = { name: 'CI', role: SystemRoles.reader, rogue_field: 42 };
|
|
245
|
+
const result = validateApiRequest('CreateApiKeyPayload', payload);
|
|
246
|
+
expect(result.valid).toBe(false);
|
|
247
|
+
expect(payload.rogue_field).toBe(42);
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it('hands back the component type on the valid branch', () => {
|
|
251
|
+
const result = validateApiResponse('ApiKey', VALID_KEY);
|
|
252
|
+
expect(result.valid).toBe(true);
|
|
253
|
+
if (result.valid) {
|
|
254
|
+
assertType<Equals<typeof result.data, ApiKey>>(true);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it('checks the shared project listing against the ref component', () => {
|
|
259
|
+
expect(validateApiResponse('ProjectRefArray', [VALID_PROJECT_REF]).valid).toBe(true);
|
|
260
|
+
expect(validateApiResponse('ProjectRefArray', [{ ...VALID_PROJECT_REF, restricted: true }]).valid).toBe(true);
|
|
261
|
+
expect(validateApiResponse('ProjectRefArray', [{ id: 'p1', name: 'Research' }]).valid).toBe(false);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it('checks the two single-field responses the key endpoints publish', () => {
|
|
265
|
+
expect(validateApiResponse('AuthTokenResponse', { token: 'ey...' }).valid).toBe(true);
|
|
266
|
+
expect(validateApiResponse('AuthTokenResponse', { token: 'ey...', refresh: 'x' }).valid).toBe(false);
|
|
267
|
+
expect(validateApiResponse('DeleteOperationResult', { acknowledged: true, deletedCount: 1 }).valid).toBe(true);
|
|
268
|
+
expect(validateApiResponse('DeleteOperationResult', { acknowledged: true }).valid).toBe(false);
|
|
269
|
+
});
|
|
270
|
+
});
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
// From the values modules, never from `../apikey.js` / `../project.js`: both derive their public
|
|
3
|
+
// types from the schemas below, so importing them here would invert the dependency.
|
|
4
|
+
import { ApiKeyTypes } from '../apikey-values.js';
|
|
5
|
+
import { SystemRoles } from '../project-values.js';
|
|
6
|
+
import { ProjectSchema } from './project.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Runtime API schemas for API key endpoints and their compact project reference.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export const ApiKeyListQuerySchema = z
|
|
13
|
+
.object({
|
|
14
|
+
/** Restricts the listing to keys scoped at the account or the project level. */
|
|
15
|
+
level: z.enum(['account', 'project']).optional(),
|
|
16
|
+
})
|
|
17
|
+
.meta({ id: 'ApiKeyListQuery' });
|
|
18
|
+
|
|
19
|
+
export const ApiKeyReadQuerySchema = z
|
|
20
|
+
.object({
|
|
21
|
+
withValue: z.boolean().optional(),
|
|
22
|
+
})
|
|
23
|
+
.meta({ id: 'ApiKeyReadQuery' });
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* `z.literal` rather than `z.enum`, because the enum has exactly one member and the document
|
|
27
|
+
* publishes it as `const: 'sk'`. A one-member `enum: ['sk']` would validate identically but change
|
|
28
|
+
* the generated contract.
|
|
29
|
+
*/
|
|
30
|
+
export const ApiKeyTypesSchema = z.literal(ApiKeyTypes.secret).meta({ id: 'ApiKeyTypes' });
|
|
31
|
+
|
|
32
|
+
export const SystemRolesSchema = z.enum(SystemRoles).meta({ id: 'SystemRoles' });
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The compact project shape embedded in other resources' responses.
|
|
36
|
+
*
|
|
37
|
+
* Kept as a documented bridge because its recursive consumers require the named public interface;
|
|
38
|
+
* `apikey.contract.test.ts` asserts exact parity with the project projection.
|
|
39
|
+
*/
|
|
40
|
+
export const ProjectRefSchema = ProjectSchema.pick({ id: true, name: true, account: true })
|
|
41
|
+
.extend({
|
|
42
|
+
restricted: z
|
|
43
|
+
.boolean()
|
|
44
|
+
.optional()
|
|
45
|
+
.meta({
|
|
46
|
+
description:
|
|
47
|
+
'Only set when fetching the list of projects visible to an user which is an org admin or owner. ' +
|
|
48
|
+
'If present and true, it means that the project is not accessible to the user.(even if it visible ' +
|
|
49
|
+
'in listing) If not present or false then the project is accessible to the user.',
|
|
50
|
+
}),
|
|
51
|
+
})
|
|
52
|
+
.meta({ id: 'ProjectRef' });
|
|
53
|
+
|
|
54
|
+
export const ProjectRefArraySchema = z.array(ProjectRefSchema).meta({ id: 'ProjectRefArray' });
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The API key as it crosses the wire.
|
|
58
|
+
*
|
|
59
|
+
* `created_at`, `updated_at` and `expires_at` are `z.string()` while the public TypeScript type said
|
|
60
|
+
* `Date`. The document has always published `format: date-time`, and JSON has no date type, so the
|
|
61
|
+
* old declaration described the Mongoose document rather than the response — the same correction
|
|
62
|
+
* `UserGroup` needed.
|
|
63
|
+
*
|
|
64
|
+
* Enforcing that format on read is safe here in a way it was not for an ACE, but not for the reason
|
|
65
|
+
* an earlier draft of this comment gave: `expires_at` DOES originate in the caller's create payload.
|
|
66
|
+
* What makes it safe is that it is a `Date` on the Mongoose schema, so a value Mongoose cannot cast
|
|
67
|
+
* is rejected at write time and everything stored is a real date — and the response mapper renders
|
|
68
|
+
* it with `toISOString()` rather than echoing what the caller sent. The ACE's `expires_at` is a
|
|
69
|
+
* plain string all the way down, which is why tightening it there would have turned stored data into
|
|
70
|
+
* a 500 on read.
|
|
71
|
+
*
|
|
72
|
+
* `value` is deliberately absent. A key's secret is published only by the two components that
|
|
73
|
+
* declare it — {@link ApiKeyWithValueSchema} on creation and {@link ApiKeyReadResponseSchema} on an
|
|
74
|
+
* explicit `?withValue=true` read — so a handler cannot leak it by returning the wrong shape.
|
|
75
|
+
*/
|
|
76
|
+
export const ApiKeySchema = z
|
|
77
|
+
.object({
|
|
78
|
+
id: z.string(),
|
|
79
|
+
name: z.string(),
|
|
80
|
+
type: ApiKeyTypesSchema,
|
|
81
|
+
role: SystemRolesSchema,
|
|
82
|
+
maskedValue: z.string().optional(),
|
|
83
|
+
can_retrieve_value: z.boolean().optional(),
|
|
84
|
+
account: z.string(),
|
|
85
|
+
project: ProjectRefSchema,
|
|
86
|
+
enabled: z.boolean(),
|
|
87
|
+
created_by: z.string(),
|
|
88
|
+
updated_by: z.string(),
|
|
89
|
+
created_at: z.string().meta({ format: 'date-time' }),
|
|
90
|
+
updated_at: z.string().meta({ format: 'date-time' }),
|
|
91
|
+
expires_at: z.string().meta({ format: 'date-time' }).optional(),
|
|
92
|
+
properties: z
|
|
93
|
+
.record(z.string(), z.unknown())
|
|
94
|
+
.meta({
|
|
95
|
+
description:
|
|
96
|
+
'Custom properties for dynamic permission matching (PrincipalSet / $principal. conditions)',
|
|
97
|
+
})
|
|
98
|
+
.optional(),
|
|
99
|
+
clearance: z
|
|
100
|
+
.number()
|
|
101
|
+
.meta({ description: 'BLP clearance level — the maximum document sensitivity the key can access' })
|
|
102
|
+
.optional(),
|
|
103
|
+
compartments: z
|
|
104
|
+
.array(z.string())
|
|
105
|
+
.meta({ description: 'Compartments the key belongs to — restricts access to matching documents' })
|
|
106
|
+
.optional(),
|
|
107
|
+
})
|
|
108
|
+
.meta({ id: 'ApiKey' });
|
|
109
|
+
|
|
110
|
+
export const ApiKeyArraySchema = z.array(ApiKeySchema).meta({ id: 'ApiKeyArray' });
|
|
111
|
+
|
|
112
|
+
/** The creation response: the only time the secret is returned unconditionally. */
|
|
113
|
+
export const ApiKeyWithValueSchema = ApiKeySchema.extend({
|
|
114
|
+
value: z.string(),
|
|
115
|
+
}).meta({ id: 'ApiKeyWithValue' });
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* The single-key read. `value` is present only when the caller asked for it AND holds
|
|
119
|
+
* `api_key:secret_read`, so it is optional here where creation makes it required — which is exactly
|
|
120
|
+
* why the two cannot share one component.
|
|
121
|
+
*/
|
|
122
|
+
export const ApiKeyReadResponseSchema = ApiKeySchema.extend({
|
|
123
|
+
value: z.string().optional(),
|
|
124
|
+
}).meta({ id: 'ApiKeyReadResponse' });
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* What `POST /apikeys` accepts.
|
|
128
|
+
*
|
|
129
|
+
* Create and update used to share one `CreateOrUpdateApiKeyPayload extends Partial<ApiKey>`, and
|
|
130
|
+
* translating that literally as `ApiKeySchema.partial()` reproduced a payload that could not
|
|
131
|
+
* describe either operation truthfully:
|
|
132
|
+
*
|
|
133
|
+
* - `role` is `required: true` on the Mongoose schema, so a create that omitted it reached
|
|
134
|
+
* `ApiKeyModel.create` with `role: undefined` and failed validation inside the handler. Requiring
|
|
135
|
+
* it here turns a 500 into the 400 it always was.
|
|
136
|
+
* - `name` is required by the published `ApiKey` component, so a key created without one could not
|
|
137
|
+
* produce a conforming response.
|
|
138
|
+
* - It declared every server-owned field — `id`, `account`, `maskedValue`, `can_retrieve_value`,
|
|
139
|
+
* the timestamps — all of which the handler has always ignored.
|
|
140
|
+
*
|
|
141
|
+
* `.pick()` rather than a fresh object, so the seven fields keep one declaration; `.partial()` on the
|
|
142
|
+
* two the server defaults (`type` falls back to `sk`, `expires_at` means "never"). Requiredness is
|
|
143
|
+
* the only thing a write payload legitimately changes about a field it shares.
|
|
144
|
+
*/
|
|
145
|
+
export const CreateApiKeyPayloadSchema = ApiKeySchema.pick({
|
|
146
|
+
name: true,
|
|
147
|
+
role: true,
|
|
148
|
+
type: true,
|
|
149
|
+
expires_at: true,
|
|
150
|
+
properties: true,
|
|
151
|
+
clearance: true,
|
|
152
|
+
compartments: true,
|
|
153
|
+
})
|
|
154
|
+
.partial({ type: true, expires_at: true })
|
|
155
|
+
.meta({ id: 'CreateApiKeyPayload' });
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* What `PUT /apikeys/:keyId` accepts: the six fields the handler applies, each optional.
|
|
159
|
+
*
|
|
160
|
+
* Narrower than the create payload in both directions — `type` and `expires_at` are immutable after
|
|
161
|
+
* creation, `enabled` is only settable here — which is precisely why one shared component could not
|
|
162
|
+
* be right for both. The handler now applies only the properties actually present; it used to assign
|
|
163
|
+
* `payload.name`, `payload.role` and `payload.enabled` unconditionally, so omitting `role` in a
|
|
164
|
+
* partial update unset a required path and made `save()` throw.
|
|
165
|
+
*/
|
|
166
|
+
export const UpdateApiKeyPayloadSchema = ApiKeySchema.pick({
|
|
167
|
+
name: true,
|
|
168
|
+
role: true,
|
|
169
|
+
enabled: true,
|
|
170
|
+
properties: true,
|
|
171
|
+
clearance: true,
|
|
172
|
+
compartments: true,
|
|
173
|
+
})
|
|
174
|
+
.partial()
|
|
175
|
+
.meta({ id: 'UpdateApiKeyPayload' });
|
|
176
|
+
|
|
177
|
+
export const AuthTokenResponseSchema = z.object({ token: z.string() }).meta({ id: 'AuthTokenResponse' });
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* The raw Mongo delete acknowledgement, published as-is — `deletedCount` is `number` rather than
|
|
181
|
+
* `integer` because that is the public contract.
|
|
182
|
+
*/
|
|
183
|
+
export const DeleteOperationResultSchema = z
|
|
184
|
+
.object({
|
|
185
|
+
acknowledged: z.boolean(),
|
|
186
|
+
deletedCount: z.number(),
|
|
187
|
+
})
|
|
188
|
+
.meta({ id: 'DeleteOperationResult' });
|
|
189
|
+
|
|
190
|
+
export type ApiKeyListQueryFromSchema = z.infer<typeof ApiKeyListQuerySchema>;
|
|
191
|
+
export type ApiKeyReadQueryFromSchema = z.infer<typeof ApiKeyReadQuerySchema>;
|
|
192
|
+
export type ProjectRefArrayFromSchema = z.infer<typeof ProjectRefArraySchema>;
|
|
193
|
+
export type ApiKeyFromSchema = z.infer<typeof ApiKeySchema>;
|
|
194
|
+
export type ApiKeyArrayFromSchema = z.infer<typeof ApiKeyArraySchema>;
|
|
195
|
+
export type ApiKeyWithValueFromSchema = z.infer<typeof ApiKeyWithValueSchema>;
|
|
196
|
+
export type ApiKeyReadResponseFromSchema = z.infer<typeof ApiKeyReadResponseSchema>;
|
|
197
|
+
export type CreateApiKeyPayloadFromSchema = z.infer<typeof CreateApiKeyPayloadSchema>;
|
|
198
|
+
export type UpdateApiKeyPayloadFromSchema = z.infer<typeof UpdateApiKeyPayloadSchema>;
|
|
199
|
+
export type AuthTokenResponseFromSchema = z.infer<typeof AuthTokenResponseSchema>;
|