@hotmeshio/long-tail 0.22.0 → 0.22.2
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/build/api/escalations/accumulate.d.ts +10 -1
- package/build/api/escalations/accumulate.js +121 -34
- package/build/api/escalations/metadata.d.ts +5 -0
- package/build/api/escalations/metadata.js +6 -2
- package/build/api/escalations/resolve-batch.js +18 -11
- package/build/api/roles.js +4 -0
- package/build/api/scan-codes/badge-policy.d.ts +10 -0
- package/build/api/scan-codes/badge-policy.js +72 -0
- package/build/api/scan-codes/choice.js +18 -11
- package/build/api/scan-codes/context.d.ts +45 -1
- package/build/api/scan-codes/context.js +51 -3
- package/build/api/scan-codes/execute.js +73 -35
- package/build/api/scan-codes/grant.d.ts +27 -0
- package/build/api/scan-codes/grant.js +67 -0
- package/build/api/scan-codes/hold.d.ts +10 -0
- package/build/api/scan-codes/hold.js +98 -0
- package/build/api/scan-codes/identity.d.ts +5 -2
- package/build/api/scan-codes/identity.js +26 -8
- package/build/api/scan-codes/subject.d.ts +15 -0
- package/build/api/scan-codes/subject.js +68 -0
- package/build/api/scan-codes/verb-accumulate.d.ts +24 -0
- package/build/api/scan-codes/verb-accumulate.js +147 -0
- package/build/api/scan-codes/verb-fill.d.ts +6 -0
- package/build/api/scan-codes/verb-fill.js +152 -0
- package/build/api/scan-codes/verbs-subject.d.ts +14 -0
- package/build/api/scan-codes/verbs-subject.js +270 -0
- package/build/api/scan-codes/verbs.d.ts +7 -22
- package/build/api/scan-codes/verbs.js +35 -114
- package/build/api/workflows/invocation.d.ts +8 -4
- package/build/api/workflows/invocation.js +26 -9
- package/build/index.d.ts +1 -0
- package/build/index.js +8 -2
- package/build/lib/cli/commands/workflows.js +9 -4
- package/build/lib/db/schemas/037_scan_gtin_and_subject_grants.sql +27 -0
- package/build/routes/escalations/accumulate.js +13 -6
- package/build/routes/escalations/acting.d.ts +5 -0
- package/build/routes/escalations/acting.js +8 -1
- package/build/routes/scan-codes.js +3 -0
- package/build/sdk/index.d.ts +3 -0
- package/build/services/escalation/crud.d.ts +2 -2
- package/build/services/escalation/crud.js +4 -2
- package/build/services/escalation/facet-sql.js +8 -0
- package/build/services/escalation/sql.d.ts +4 -2
- package/build/services/escalation/sql.js +10 -2
- package/build/services/export/index.d.ts +8 -3
- package/build/services/export/index.js +15 -21
- package/build/services/iam/acting-identity.d.ts +29 -4
- package/build/services/iam/acting-identity.js +60 -17
- package/build/services/iam/ephemeral.d.ts +21 -0
- package/build/services/iam/ephemeral.js +32 -1
- package/build/services/iam/sql.d.ts +10 -0
- package/build/services/iam/sql.js +32 -3
- package/build/services/pipelines/events.js +2 -1
- package/build/services/pipelines/execution-builder.js +2 -1
- package/build/services/pipelines/queries.js +2 -1
- package/build/services/role/badge-grant.d.ts +5 -0
- package/build/services/role/badge-grant.js +36 -0
- package/build/services/role/seed.js +5 -0
- package/build/services/role/types.d.ts +14 -0
- package/build/services/role/types.js +5 -0
- package/build/services/scan-code/index.d.ts +3 -2
- package/build/services/scan-code/index.js +7 -1
- package/build/services/scan-code/parse.d.ts +23 -20
- package/build/services/scan-code/parse.js +45 -90
- package/build/services/scan-code/read.js +1 -0
- package/build/services/scan-code/sql.d.ts +3 -3
- package/build/services/scan-code/sql.js +11 -8
- package/build/services/scan-code/validate-subject.d.ts +7 -0
- package/build/services/scan-code/validate-subject.js +158 -0
- package/build/services/scan-code/validate.d.ts +7 -0
- package/build/services/scan-code/validate.js +111 -16
- package/build/services/scan-code/write.d.ts +1 -0
- package/build/services/scan-code/write.js +9 -3
- package/build/services/workflow-state.d.ts +21 -0
- package/build/services/workflow-state.js +39 -0
- package/build/shared/form-validation/field-validator.js +4 -0
- package/build/shared/form-validation/index.d.ts +1 -0
- package/build/shared/form-validation/index.js +1 -0
- package/build/shared/form-validation/x-lt-scan.d.ts +52 -0
- package/build/shared/form-validation/x-lt-scan.js +166 -0
- package/build/shared/scan-code/gtin.d.ts +5 -0
- package/build/shared/scan-code/gtin.js +25 -0
- package/build/shared/scan-code/index.d.ts +2 -0
- package/build/shared/scan-code/index.js +10 -0
- package/build/shared/scan-code/parse.d.ts +46 -0
- package/build/shared/scan-code/parse.js +133 -0
- package/build/shared/workflow-state.d.ts +17 -0
- package/build/shared/workflow-state.js +29 -0
- package/build/system/mcp-servers/admin/escalations.js +8 -4
- package/build/system/mcp-servers/admin/scan-codes.js +10 -4
- package/build/system/mcp-servers/admin/schemas.d.ts +792 -23
- package/build/system/mcp-servers/admin/schemas.js +61 -4
- package/build/system/mcp-servers/admin/workflows.js +20 -31
- package/build/system/mcp-servers/human-queue-schemas.d.ts +6 -6
- package/build/system/seed/tool-manifests-admin.d.ts +94 -0
- package/build/system/seed/tool-manifests-admin.js +3 -3
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/escalation.d.ts +2 -0
- package/build/types/escalation.js +3 -1
- package/build/types/facets.d.ts +14 -0
- package/build/types/index.d.ts +3 -3
- package/build/types/index.js +8 -1
- package/build/types/scan-code/constants.d.ts +182 -0
- package/build/types/{scan-code.js → scan-code/constants.js} +62 -12
- package/build/types/scan-code/index.d.ts +3 -0
- package/build/types/scan-code/index.js +17 -0
- package/build/types/scan-code/response.d.ts +140 -0
- package/build/types/scan-code/response.js +2 -0
- package/build/types/scan-code/rule.d.ts +199 -0
- package/build/types/scan-code/rule.js +2 -0
- package/build/types/startup.d.ts +3 -1
- package/dashboard/dist/assets/{AdminDashboard-Covdam48.js → AdminDashboard-DBW12qQt.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-Covdam48.js.map → AdminDashboard-DBW12qQt.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-CE1k6J5r.js → AgentConfigPage-CmHv8U9M.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-CE1k6J5r.js.map → AgentConfigPage-CmHv8U9M.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-CWJZIZP1.js → AgentDetailPage-D1scIbz-.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-CWJZIZP1.js.map → AgentDetailPage-D1scIbz-.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage---Dg5ufF.js → AgentsPage-BA_ai9HJ.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage---Dg5ufF.js.map → AgentsPage-BA_ai9HJ.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-C2_5aEFW.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-C2_5aEFW.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-D3drO3-T.js → BotPicker-BZo4Kp4a.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-D3drO3-T.js.map → BotPicker-BZo4Kp4a.js.map} +1 -1
- package/dashboard/dist/assets/{BulkAssignModal-BOAWsViq.js → BulkAssignModal-BFhyxY2T.js} +2 -2
- package/dashboard/dist/assets/{BulkAssignModal-BOAWsViq.js.map → BulkAssignModal-BFhyxY2T.js.map} +1 -1
- package/dashboard/dist/assets/CapabilitiesPage-CvOX6vAc.js +2 -0
- package/dashboard/dist/assets/{CapabilitiesPage-RGgD3YZO.js.map → CapabilitiesPage-CvOX6vAc.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-DNkZn87n.js → CollapsibleSection-GCJsV9Oq.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-DNkZn87n.js.map → CollapsibleSection-GCJsV9Oq.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-BqzOwhPr.js → ConfirmDeleteModal-CAgYLcef.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-BqzOwhPr.js.map → ConfirmDeleteModal-CAgYLcef.js.map} +1 -1
- package/dashboard/dist/assets/CountdownTimer-Dik2z0M_.js +2 -0
- package/dashboard/dist/assets/{CountdownTimer-BaexQMK6.js.map → CountdownTimer-Dik2z0M_.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-D7abp0aS.js → CredentialsPage-twd2xCOW.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-D7abp0aS.js.map → CredentialsPage-twd2xCOW.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-DZiWmTwJ.js → CronLabel-DdnIuudX.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-DZiWmTwJ.js.map → CronLabel-DdnIuudX.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-f1o-GLM8.js → DropZone-B1Tdfddc.js} +2 -2
- package/dashboard/dist/assets/{DropZone-f1o-GLM8.js.map → DropZone-B1Tdfddc.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-BdGO_w4v.js → ElapsedCell-DCctVv5R.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-BdGO_w4v.js.map → ElapsedCell-DCctVv5R.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel-DIDcF5Yu.js → EntityTimelinePanel-CMnskyWv.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel-DIDcF5Yu.js.map → EntityTimelinePanel-CMnskyWv.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-C28rn9XC.js → EscalationListSchemaPage-VfCn6WDb.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-C28rn9XC.js.map → EscalationListSchemaPage-VfCn6WDb.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListView-CkBnkpDJ.js → EscalationListView-CGQZxcC-.js} +2 -2
- package/dashboard/dist/assets/{EscalationListView-CkBnkpDJ.js.map → EscalationListView-CGQZxcC-.js.map} +1 -1
- package/dashboard/dist/assets/EscalationSchemaPage-BX0tx-PM.js +9 -0
- package/dashboard/dist/assets/EscalationSchemaPage-BX0tx-PM.js.map +1 -0
- package/dashboard/dist/assets/EscalationTimeline-DKoSM56J.js +2 -0
- package/dashboard/dist/assets/EscalationTimeline-DKoSM56J.js.map +1 -0
- package/dashboard/dist/assets/{EscalationTitleSelect-CzKfavri.js → EscalationTitleSelect-DWGLBOmS.js} +2 -2
- package/dashboard/dist/assets/{EscalationTitleSelect-CzKfavri.js.map → EscalationTitleSelect-DWGLBOmS.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-Tdu3Yx2c.js → EscalationsOverview-C2XoguaA.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-Tdu3Yx2c.js.map → EscalationsOverview-C2XoguaA.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-DiIxOJwO.js → EventTable-CBUWq7--.js} +2 -2
- package/dashboard/dist/assets/{EventTable-DiIxOJwO.js.map → EventTable-CBUWq7--.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-CvMBCVIo.js → FilterBar-8IdbleZ9.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-CvMBCVIo.js.map → FilterBar-8IdbleZ9.js.map} +1 -1
- package/dashboard/dist/assets/GrantScopeField-BzWGzBfA.js +2 -0
- package/dashboard/dist/assets/GrantScopeField-BzWGzBfA.js.map +1 -0
- package/dashboard/dist/assets/{GraphInvokePage-DO-yyhi6.js → GraphInvokePage-CUvoPzsW.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-DO-yyhi6.js.map → GraphInvokePage-CUvoPzsW.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-DSS3eHR2.js → HomePage-BP7v9GLJ.js} +2 -2
- package/dashboard/dist/assets/{HomePage-DSS3eHR2.js.map → HomePage-BP7v9GLJ.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-C3-Tqqub.js → ListToolbar-Cnacuwoy.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-C3-Tqqub.js.map → ListToolbar-Cnacuwoy.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-DEJmsdVi.js → McpOverview-C2JoNoDA.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-DEJmsdVi.js.map → McpOverview-C2JoNoDA.js.map} +1 -1
- package/dashboard/dist/assets/McpQueryDetailPage-C_nih0w-.js +5 -0
- package/dashboard/dist/assets/McpQueryDetailPage-C_nih0w-.js.map +1 -0
- package/dashboard/dist/assets/{McpQueryPage-BBcG_UuU.js → McpQueryPage-U_wNXow2.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-BBcG_UuU.js.map → McpQueryPage-U_wNXow2.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-C6xw0kBg.js → McpRunDetailPage-DtKoJq6J.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-C6xw0kBg.js.map → McpRunDetailPage-DtKoJq6J.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-CRQqrF4Q.js → McpRunsPage-CnYtfGhf.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-CRQqrF4Q.js.map → McpRunsPage-CnYtfGhf.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-DADRJOUl.js → NamespacePill-DwM5pNA4.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-DADRJOUl.js.map → NamespacePill-DwM5pNA4.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-Dlfwzf-0.js → OperationsPage-C7hupIer.js} +2 -2
- package/dashboard/dist/assets/{OperationsPage-Dlfwzf-0.js.map → OperationsPage-C7hupIer.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-DoiDGZ9R.js → OperatorDashboard-fVuLn2D5.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-DoiDGZ9R.js.map → OperatorDashboard-fVuLn2D5.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-Csq434-v.js → PageHeader-CMd3f4bz.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-Csq434-v.js.map → PageHeader-CMd3f4bz.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-CSnk1p5A.js → PageHeaderWithStats-DHj8Mqox.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-CSnk1p5A.js.map → PageHeaderWithStats-DHj8Mqox.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-BzbA4Prr.js → PersonaDetailPage-C-4o8lPw.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-BzbA4Prr.js.map → PersonaDetailPage-C-4o8lPw.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-B36yn4hU.js → PersonasPage-BL1FwLmv.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-B36yn4hU.js.map → PersonasPage-BL1FwLmv.js.map} +1 -1
- package/dashboard/dist/assets/{PortalPage-BkD4YfDf.js → PortalPage-tJG5sgb1.js} +2 -2
- package/dashboard/dist/assets/{PortalPage-BkD4YfDf.js.map → PortalPage-tJG5sgb1.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-BT0eiBWY.js → ProcessDetailPage-Dz_jY4Yt.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-BT0eiBWY.js.map → ProcessDetailPage-Dz_jY4Yt.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-BEqeeNae.js → ProcessesListPage-Cbn9cter.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-BEqeeNae.js.map → ProcessesListPage-Cbn9cter.js.map} +1 -1
- package/dashboard/dist/assets/ResolverForm-Bk8iXQ6-.js +8 -0
- package/dashboard/dist/assets/ResolverForm-Bk8iXQ6-.js.map +1 -0
- package/dashboard/dist/assets/RoleDetailPage-owPi6gI9.js +8 -0
- package/dashboard/dist/assets/RoleDetailPage-owPi6gI9.js.map +1 -0
- package/dashboard/dist/assets/{RolePill-BafrASDX.js → RolePill-Di2CAHuD.js} +2 -2
- package/dashboard/dist/assets/{RolePill-BafrASDX.js.map → RolePill-Di2CAHuD.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-80quJU5-.js → RolesPage-NwmMvZFa.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-80quJU5-.js.map → RolesPage-NwmMvZFa.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-BoePhWVD.js → RunAsSelector-tgEooTyU.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-BoePhWVD.js.map → RunAsSelector-tgEooTyU.js.map} +1 -1
- package/dashboard/dist/assets/ScanCodesPage-CUv_8ic6.js +2 -0
- package/dashboard/dist/assets/ScanCodesPage-CUv_8ic6.js.map +1 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-YHqbu7oK.js +2 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-YHqbu7oK.js.map +1 -0
- package/dashboard/dist/assets/ScanStationPage-B275l6r_.js +2 -0
- package/dashboard/dist/assets/ScanStationPage-B275l6r_.js.map +1 -0
- package/dashboard/dist/assets/{ScopeBadge-b6MIBiYD.js → ScopeBadge-CSItPVOH.js} +2 -2
- package/dashboard/dist/assets/{ScopeBadge-b6MIBiYD.js.map → ScopeBadge-CSItPVOH.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-9ITrei_d.js → StickyPagination-CsTI_gvJ.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-9ITrei_d.js.map → StickyPagination-CsTI_gvJ.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-BkYvEHFY.js → StreamMessageDetail-auRlvjTh.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-BkYvEHFY.js.map → StreamMessageDetail-auRlvjTh.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-B1rotFix.js → SwimlaneTimeline-BLoVHYAd.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-B1rotFix.js.map → SwimlaneTimeline-BLoVHYAd.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-ZrIIrEUP.js → TagInput-CAgdLN_b.js} +2 -2
- package/dashboard/dist/assets/{TagInput-ZrIIrEUP.js.map → TagInput-CAgdLN_b.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-zhn_U_eC.js → TaskDetailPage-BPsZ1bK_.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-zhn_U_eC.js.map → TaskDetailPage-BPsZ1bK_.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-DkQ1uc6y.js → TaskQueuePill-h0oorVMe.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-DkQ1uc6y.js.map → TaskQueuePill-h0oorVMe.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-CNbNeagx.js → TasksListPage-BNGM74yT.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-CNbNeagx.js.map → TasksListPage-BNGM74yT.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-0YVMBwls.js → TimeAgo-BnAHXGK7.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-0YVMBwls.js.map → TimeAgo-BnAHXGK7.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-DB7r3np8.js → TimestampCell-J4yae6mc.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-DB7r3np8.js.map → TimestampCell-J4yae6mc.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-Baxm02L6.js → ToolPill-CQCsVdzD.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-Baxm02L6.js.map → ToolPill-CQCsVdzD.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-BLfA02wv.js → ToolTestPanel-BdzzgXDu.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-BLfA02wv.js.map → ToolTestPanel-BdzzgXDu.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-eAqPKShq.js → TopicDetailPage-DJKg8lb7.js} +4 -4
- package/dashboard/dist/assets/{TopicDetailPage-eAqPKShq.js.map → TopicDetailPage-DJKg8lb7.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-BNNWD-zl.js → TopicsPage-DQV0WxG6.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-BNNWD-zl.js.map → TopicsPage-DQV0WxG6.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-Pw46tO_k.js → UserName-Ct09nGh5.js} +2 -2
- package/dashboard/dist/assets/{UserName-Pw46tO_k.js.map → UserName-Ct09nGh5.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-DvA51lT3.js → WorkflowExecutionPage-B5WJOsee.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-DvA51lT3.js.map → WorkflowExecutionPage-B5WJOsee.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-ZepbO_ny.js → WorkflowPill-Dg7BDTyM.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-ZepbO_ny.js.map → WorkflowPill-Dg7BDTyM.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-DFDTwnhn.js → WorkflowsDashboard-Hc87TRgD.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DFDTwnhn.js.map → WorkflowsDashboard-Hc87TRgD.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-5i2Tcy-p.js → WorkflowsOverview-CJQbyOj-.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-5i2Tcy-p.js.map → WorkflowsOverview-CJQbyOj-.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-p4VEYZS0.js → YamlWorkflowDetailPage-BMeED677.js} +8 -8
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-p4VEYZS0.js.map → YamlWorkflowDetailPage-BMeED677.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-Cq-hMVxl.js → YamlWorkflowsPage-BMMg0Id6.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-Cq-hMVxl.js.map → YamlWorkflowsPage-BMMg0Id6.js.map} +1 -1
- package/dashboard/dist/assets/{agents-EyBPJMYa.js → agents-CdFkgFvg.js} +2 -2
- package/dashboard/dist/assets/{agents-EyBPJMYa.js.map → agents-CdFkgFvg.js.map} +1 -1
- package/dashboard/dist/assets/{bots-DX6jjqtF.js → bots-Mj3LHWWg.js} +2 -2
- package/dashboard/dist/assets/{bots-DX6jjqtF.js.map → bots-Mj3LHWWg.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-ZdLv9xBQ.js → capabilities-Dw1ObK2-.js} +2 -2
- package/dashboard/dist/assets/{capabilities-ZdLv9xBQ.js.map → capabilities-Dw1ObK2-.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-CpvZaJuw.js → controlplane-DcNE1APv.js} +2 -2
- package/dashboard/dist/assets/{controlplane-CpvZaJuw.js.map → controlplane-DcNE1APv.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-Mvsze5eV.js → escalation-columns-D364Trpy.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-Mvsze5eV.js.map → escalation-columns-D364Trpy.js.map} +1 -1
- package/dashboard/dist/assets/{index-Cn8uJsd7.js → index-B3veJ698.js} +2 -2
- package/dashboard/dist/assets/{index-Cn8uJsd7.js.map → index-B3veJ698.js.map} +1 -1
- package/dashboard/dist/assets/index-BQeHJHYN.js +67 -0
- package/dashboard/dist/assets/index-BQeHJHYN.js.map +1 -0
- package/dashboard/dist/assets/{index-D-Xs4rAW.js → index-BRGTmoYY.js} +2 -2
- package/dashboard/dist/assets/{index-D-Xs4rAW.js.map → index-BRGTmoYY.js.map} +1 -1
- package/dashboard/dist/assets/{index-DkrBFFSO.js → index-Bd6-KmBE.js} +3 -3
- package/dashboard/dist/assets/{index-DkrBFFSO.js.map → index-Bd6-KmBE.js.map} +1 -1
- package/dashboard/dist/assets/{index-Bhb89oHH.js → index-BiVce3n0.js} +2 -2
- package/dashboard/dist/assets/{index-Bhb89oHH.js.map → index-BiVce3n0.js.map} +1 -1
- package/dashboard/dist/assets/{index-z5Hpeidu.js → index-BmNAVd4s.js} +2 -2
- package/dashboard/dist/assets/{index-z5Hpeidu.js.map → index-BmNAVd4s.js.map} +1 -1
- package/dashboard/dist/assets/{index-BbCjGO3M.js → index-Bq5XNEzD.js} +2 -2
- package/dashboard/dist/assets/{index-BbCjGO3M.js.map → index-Bq5XNEzD.js.map} +1 -1
- package/dashboard/dist/assets/{index-DGmzBY9D.js → index-DPStdq4T.js} +2 -2
- package/dashboard/dist/assets/{index-DGmzBY9D.js.map → index-DPStdq4T.js.map} +1 -1
- package/dashboard/dist/assets/index-DcppjzP5.css +1 -0
- package/dashboard/dist/assets/{index-PfSRKerc.js → index-DkcI4V_H.js} +2 -2
- package/dashboard/dist/assets/{index-PfSRKerc.js.map → index-DkcI4V_H.js.map} +1 -1
- package/dashboard/dist/assets/{index-oFKUFGQL.js → index-Dyotfa_k.js} +2 -2
- package/dashboard/dist/assets/{index-oFKUFGQL.js.map → index-Dyotfa_k.js.map} +1 -1
- package/dashboard/dist/assets/{index-Eo-l3Lqo.js → index-MDD4JYtu.js} +2 -2
- package/dashboard/dist/assets/{index-Eo-l3Lqo.js.map → index-MDD4JYtu.js.map} +1 -1
- package/dashboard/dist/assets/index-WSm8bgE7.js +3 -0
- package/dashboard/dist/assets/index-WSm8bgE7.js.map +1 -0
- package/dashboard/dist/assets/{index-DZhtP2Ok.js → index-eDm6cz0F.js} +2 -2
- package/dashboard/dist/assets/{index-DZhtP2Ok.js.map → index-eDm6cz0F.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-CgloEkaf.js → knowledge-Bafewjxk.js} +2 -2
- package/dashboard/dist/assets/{knowledge-CgloEkaf.js.map → knowledge-Bafewjxk.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-o-sGX2ST.js → mcp-query-BzTtIG90.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-o-sGX2ST.js.map → mcp-query-BzTtIG90.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-Bix7QYO7.js → mcp-vLIutbnc.js} +2 -2
- package/dashboard/dist/assets/{mcp-Bix7QYO7.js.map → mcp-vLIutbnc.js.map} +1 -1
- package/dashboard/dist/assets/{personas-30azkJ_s.js → personas-WD40EDS_.js} +2 -2
- package/dashboard/dist/assets/{personas-30azkJ_s.js.map → personas-WD40EDS_.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-Bfk2GFK7.js → pipelines-DFwULWs3.js} +2 -2
- package/dashboard/dist/assets/{pipelines-Bfk2GFK7.js.map → pipelines-DFwULWs3.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-CpdopewW.js → tasks-La_-WAUn.js} +2 -2
- package/dashboard/dist/assets/{tasks-CpdopewW.js.map → tasks-La_-WAUn.js.map} +1 -1
- package/dashboard/dist/assets/{topics--bvCV9Yp.js → topics-CzYMlvqm.js} +2 -2
- package/dashboard/dist/assets/{topics--bvCV9Yp.js.map → topics-CzYMlvqm.js.map} +1 -1
- package/dashboard/dist/assets/{useDebouncedValue-Da0lPmj3.js → useDebouncedValue-C0FQyANW.js} +2 -2
- package/dashboard/dist/assets/{useDebouncedValue-Da0lPmj3.js.map → useDebouncedValue-C0FQyANW.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-DD_Esl6n.js → useNamespace-WW_XjAb3.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-DD_Esl6n.js.map → useNamespace-WW_XjAb3.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-AeAhZJJk.js → useYamlActivityEvents-B3YxPeFt.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-AeAhZJJk.js.map → useYamlActivityEvents-B3YxPeFt.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-B7OcUM6b.js → vendor-icons-CeVtUKyP.js} +2 -2
- package/dashboard/dist/assets/{vendor-icons-B7OcUM6b.js.map → vendor-icons-CeVtUKyP.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-BHAOOGvn.js → yaml-workflows-COHOjdhF.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-BHAOOGvn.js.map → yaml-workflows-COHOjdhF.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/accumulator.md +37 -1
- package/docs/api/mcp/admin.md +3 -2
- package/docs/api/sdk/escalations.md +6 -0
- package/docs/api/sdk/exports.md +1 -1
- package/docs/api/sdk/workflows.md +23 -4
- package/docs/cli.md +1 -1
- package/docs/dashboard.md +2 -2
- package/docs/faceted-routing.md +2 -0
- package/docs/hitl/x-lt-scan.md +51 -0
- package/docs/hitl/x-lt-widget.md +5 -0
- package/docs/hitl-guide.md +2 -0
- package/docs/scan-codes.md +252 -19
- package/package.json +1 -1
- package/build/types/scan-code.d.ts +0 -308
- package/dashboard/dist/assets/AvailableEscalationsPage-CpbC8oTN.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-CpbC8oTN.js.map +0 -1
- package/dashboard/dist/assets/CapabilitiesPage-RGgD3YZO.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-BaexQMK6.js +0 -2
- package/dashboard/dist/assets/EscalationSchemaPage-W5r0A1kj.js +0 -9
- package/dashboard/dist/assets/EscalationSchemaPage-W5r0A1kj.js.map +0 -1
- package/dashboard/dist/assets/EscalationTimeline-DKyTz6sM.js +0 -2
- package/dashboard/dist/assets/EscalationTimeline-DKyTz6sM.js.map +0 -1
- package/dashboard/dist/assets/McpQueryDetailPage-DYJr16l7.js +0 -5
- package/dashboard/dist/assets/McpQueryDetailPage-DYJr16l7.js.map +0 -1
- package/dashboard/dist/assets/ResolverForm-BwgjIX97.js +0 -7
- package/dashboard/dist/assets/ResolverForm-BwgjIX97.js.map +0 -1
- package/dashboard/dist/assets/RoleDetailPage-BFuLNJXa.js +0 -8
- package/dashboard/dist/assets/RoleDetailPage-BFuLNJXa.js.map +0 -1
- package/dashboard/dist/assets/ScanCodesPage-Cu1bKEix.js +0 -2
- package/dashboard/dist/assets/ScanCodesPage-Cu1bKEix.js.map +0 -1
- package/dashboard/dist/assets/ScanSchemeDetailPage-D9AbS6UY.js +0 -2
- package/dashboard/dist/assets/ScanSchemeDetailPage-D9AbS6UY.js.map +0 -1
- package/dashboard/dist/assets/ScanStationPage-gcZGefvT.js +0 -2
- package/dashboard/dist/assets/ScanStationPage-gcZGefvT.js.map +0 -1
- package/dashboard/dist/assets/index-B_GT23TE.js +0 -3
- package/dashboard/dist/assets/index-B_GT23TE.js.map +0 -1
- package/dashboard/dist/assets/index-CgUcYveM.js +0 -67
- package/dashboard/dist/assets/index-CgUcYveM.js.map +0 -1
- package/dashboard/dist/assets/index-Dh8MJl3L.css +0 -1
|
@@ -33,28 +33,71 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ACTING_ERRORS = void 0;
|
|
37
|
+
exports.peekActingAuth = peekActingAuth;
|
|
38
|
+
exports.consumeActingGrant = consumeActingGrant;
|
|
39
|
+
exports.refundActingGrant = refundActingGrant;
|
|
36
40
|
exports.resolveActingAuth = resolveActingAuth;
|
|
37
41
|
const userService = __importStar(require("../user"));
|
|
38
42
|
const ephemeral_1 = require("./ephemeral");
|
|
39
43
|
const types_1 = require("../../types");
|
|
44
|
+
exports.ACTING_ERRORS = {
|
|
45
|
+
NOT_A_GRANT: 'actingToken is not an acting-identity grant',
|
|
46
|
+
EXPIRED: 'acting identity expired — scan your badge again',
|
|
47
|
+
INACTIVE: 'acting identity is no longer an active user',
|
|
48
|
+
OTHER_SUBJECT: 'this badge already acted on another item; scan your badge again',
|
|
49
|
+
};
|
|
50
|
+
function isActingGrant(actingToken) {
|
|
51
|
+
const parsed = (0, ephemeral_1.parseEphemeralToken)(actingToken);
|
|
52
|
+
return parsed && parsed.label === types_1.ACTING_IDENTITY_LABEL ? parsed.uuid : null;
|
|
53
|
+
}
|
|
54
|
+
async function toAuth(grant, consumed) {
|
|
55
|
+
const user = await userService.getUser(grant.value);
|
|
56
|
+
if (!user || user.status !== 'active')
|
|
57
|
+
return { ok: false, error: exports.ACTING_ERRORS.INACTIVE };
|
|
58
|
+
return {
|
|
59
|
+
ok: true,
|
|
60
|
+
auth: { userId: user.id },
|
|
61
|
+
grant: { consumed, remaining: grant.remaining, bound: grant.bound },
|
|
62
|
+
};
|
|
63
|
+
}
|
|
40
64
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
65
|
+
* Read a supplied acting grant without spending it. A token that fails
|
|
66
|
+
* (wrong label, expired, exhausted, or a vanished user) is a terminal error,
|
|
67
|
+
* never a silent fall-back to the session identity: that would misattribute
|
|
68
|
+
* whatever follows.
|
|
45
69
|
*/
|
|
46
|
-
async function
|
|
47
|
-
const
|
|
48
|
-
if (!
|
|
49
|
-
return { ok: false, error:
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
70
|
+
async function peekActingAuth(actingToken) {
|
|
71
|
+
const uuid = isActingGrant(actingToken);
|
|
72
|
+
if (!uuid)
|
|
73
|
+
return { ok: false, error: exports.ACTING_ERRORS.NOT_A_GRANT };
|
|
74
|
+
const grant = await (0, ephemeral_1.peekEphemeral)(uuid);
|
|
75
|
+
if (!grant)
|
|
76
|
+
return { ok: false, error: exports.ACTING_ERRORS.EXPIRED };
|
|
77
|
+
return toAuth(grant, false);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Spend one use of the grant for an act. `ref` names the subject the act
|
|
81
|
+
* lands on; a subject-scoped grant binds to it on first spend.
|
|
82
|
+
*/
|
|
83
|
+
async function consumeActingGrant(actingToken, ref = null) {
|
|
84
|
+
const uuid = isActingGrant(actingToken);
|
|
85
|
+
if (!uuid)
|
|
86
|
+
return { ok: false, error: exports.ACTING_ERRORS.NOT_A_GRANT };
|
|
87
|
+
const grant = await (0, ephemeral_1.consumeEphemeral)(uuid, ref);
|
|
88
|
+
if (!grant) {
|
|
89
|
+
const live = ref ? await (0, ephemeral_1.peekEphemeral)(uuid) : null;
|
|
90
|
+
return { ok: false, error: live?.bound ? exports.ACTING_ERRORS.OTHER_SUBJECT : exports.ACTING_ERRORS.EXPIRED };
|
|
58
91
|
}
|
|
59
|
-
return
|
|
92
|
+
return toAuth(grant, true);
|
|
93
|
+
}
|
|
94
|
+
/** Return a use whose act missed. `unbind` when that spend bound the grant. */
|
|
95
|
+
async function refundActingGrant(actingToken, unbind) {
|
|
96
|
+
const uuid = isActingGrant(actingToken);
|
|
97
|
+
if (uuid)
|
|
98
|
+
await (0, ephemeral_1.refundEphemeral)(uuid, unbind);
|
|
99
|
+
}
|
|
100
|
+
/** Spend the grant up front: the escalation work routes always act. */
|
|
101
|
+
async function resolveActingAuth(actingToken) {
|
|
102
|
+
return consumeActingGrant(actingToken);
|
|
60
103
|
}
|
|
@@ -21,6 +21,8 @@ export interface StoreEphemeralOptions {
|
|
|
21
21
|
ttlSeconds?: number;
|
|
22
22
|
/** Human-readable label for debugging. */
|
|
23
23
|
label?: string;
|
|
24
|
+
/** The first ref-carrying spend binds the token to that ref (see consumeEphemeral). */
|
|
25
|
+
bindOnUse?: boolean;
|
|
24
26
|
}
|
|
25
27
|
/**
|
|
26
28
|
* Store a sensitive value. Returns the raw token UUID.
|
|
@@ -40,6 +42,25 @@ export declare function storeEphemeral(value: string, opts?: StoreEphemeralOptio
|
|
|
40
42
|
* - Row is deleted when use_count reaches max_uses (if max_uses > 0)
|
|
41
43
|
*/
|
|
42
44
|
export declare function exchangeEphemeral(token: string): Promise<string | null>;
|
|
45
|
+
/** A live token's value and how many uses it has left (null = unbounded). */
|
|
46
|
+
export interface EphemeralGrant {
|
|
47
|
+
value: string;
|
|
48
|
+
remaining: number | null;
|
|
49
|
+
/** True once the token is bound to a ref; it then acts only on that ref. */
|
|
50
|
+
bound: boolean;
|
|
51
|
+
}
|
|
52
|
+
/** Read a live token without spending a use. */
|
|
53
|
+
export declare function peekEphemeral(token: string): Promise<EphemeralGrant | null>;
|
|
54
|
+
/**
|
|
55
|
+
* Spend one use of a token. A token stored with `bindOnUse` binds to `ref`
|
|
56
|
+
* on its first ref-carrying spend; after that it spends freely on that ref
|
|
57
|
+
* and never on another. Returns null when expired, exhausted, or bound
|
|
58
|
+
* elsewhere. An exhausted row stays until its TTL so a spend whose act
|
|
59
|
+
* missed can be refunded.
|
|
60
|
+
*/
|
|
61
|
+
export declare function consumeEphemeral(token: string, ref?: string | null): Promise<EphemeralGrant | null>;
|
|
62
|
+
/** Undo one spend whose act did not land. `unbind` undoes the binding that spend made. */
|
|
63
|
+
export declare function refundEphemeral(token: string, unbind: boolean): Promise<void>;
|
|
43
64
|
/**
|
|
44
65
|
* Explicitly revoke a token before expiry/exhaustion.
|
|
45
66
|
*/
|
|
@@ -7,6 +7,9 @@ exports.exchangeEphemeralToken = exchangeEphemeralToken;
|
|
|
7
7
|
exports.exchangeTokensInArgs = exchangeTokensInArgs;
|
|
8
8
|
exports.storeEphemeral = storeEphemeral;
|
|
9
9
|
exports.exchangeEphemeral = exchangeEphemeral;
|
|
10
|
+
exports.peekEphemeral = peekEphemeral;
|
|
11
|
+
exports.consumeEphemeral = consumeEphemeral;
|
|
12
|
+
exports.refundEphemeral = refundEphemeral;
|
|
10
13
|
exports.revokeEphemeral = revokeEphemeral;
|
|
11
14
|
exports.cleanupExpired = cleanupExpired;
|
|
12
15
|
const db_1 = require("../../lib/db");
|
|
@@ -81,7 +84,7 @@ async function storeEphemeral(value, opts = {}) {
|
|
|
81
84
|
const expiresAt = opts.ttlSeconds
|
|
82
85
|
? `NOW() + ${opts.ttlSeconds} * INTERVAL '1 second'`
|
|
83
86
|
: 'NULL';
|
|
84
|
-
const { rows } = await pool.query((0, sql_1.INSERT_EPHEMERAL)(expiresAt), [Buffer.from(encrypted, 'base64'), opts.label || null, maxUses]);
|
|
87
|
+
const { rows } = await pool.query((0, sql_1.INSERT_EPHEMERAL)(expiresAt), [Buffer.from(encrypted, 'base64'), opts.label || null, maxUses, opts.bindOnUse ?? false]);
|
|
85
88
|
return rows[0].token;
|
|
86
89
|
}
|
|
87
90
|
/**
|
|
@@ -106,6 +109,34 @@ async function exchangeEphemeral(token) {
|
|
|
106
109
|
}
|
|
107
110
|
return (0, crypto_1.decrypt)(buf.toString('base64'));
|
|
108
111
|
}
|
|
112
|
+
function toGrant(row) {
|
|
113
|
+
const bound = row.bound_ref !== null;
|
|
114
|
+
return {
|
|
115
|
+
value: (0, crypto_1.decrypt)(row.value.toString('base64')),
|
|
116
|
+
remaining: bound || row.max_uses === 0 ? null : Math.max(0, row.max_uses - row.use_count),
|
|
117
|
+
bound,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/** Read a live token without spending a use. */
|
|
121
|
+
async function peekEphemeral(token) {
|
|
122
|
+
const { rows } = await (0, db_1.getPool)().query(sql_1.PEEK_EPHEMERAL, [token]);
|
|
123
|
+
return rows.length ? toGrant(rows[0]) : null;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Spend one use of a token. A token stored with `bindOnUse` binds to `ref`
|
|
127
|
+
* on its first ref-carrying spend; after that it spends freely on that ref
|
|
128
|
+
* and never on another. Returns null when expired, exhausted, or bound
|
|
129
|
+
* elsewhere. An exhausted row stays until its TTL so a spend whose act
|
|
130
|
+
* missed can be refunded.
|
|
131
|
+
*/
|
|
132
|
+
async function consumeEphemeral(token, ref = null) {
|
|
133
|
+
const { rows } = await (0, db_1.getPool)().query(sql_1.CONSUME_EPHEMERAL, [token, ref]);
|
|
134
|
+
return rows.length ? toGrant(rows[0]) : null;
|
|
135
|
+
}
|
|
136
|
+
/** Undo one spend whose act did not land. `unbind` undoes the binding that spend made. */
|
|
137
|
+
async function refundEphemeral(token, unbind) {
|
|
138
|
+
await (0, db_1.getPool)().query(sql_1.REFUND_EPHEMERAL, [token, unbind]);
|
|
139
|
+
}
|
|
109
140
|
/**
|
|
110
141
|
* Explicitly revoke a token before expiry/exhaustion.
|
|
111
142
|
*/
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
/** Build INSERT for ephemeral credentials. expiresExpr is a SQL expression like 'NULL' or "NOW() + N * INTERVAL '1 second'". */
|
|
2
2
|
export declare const INSERT_EPHEMERAL: (expiresExpr: string) => string;
|
|
3
3
|
export declare const EXCHANGE_EPHEMERAL = "\n UPDATE lt_ephemeral_credentials\n SET use_count = use_count + 1\n WHERE token = $1\n AND (expires_at IS NULL OR expires_at > NOW())\n AND (max_uses = 0 OR use_count < max_uses)\n RETURNING value, use_count, max_uses";
|
|
4
|
+
/** Validity check without spending a use. A bound grant stays live until its TTL. */
|
|
5
|
+
export declare const PEEK_EPHEMERAL = "\n SELECT value, use_count, max_uses, bound_ref\n FROM lt_ephemeral_credentials\n WHERE token = $1\n AND (expires_at IS NULL OR expires_at > NOW())\n AND (bound_ref IS NOT NULL OR max_uses = 0 OR use_count < max_uses)";
|
|
6
|
+
/**
|
|
7
|
+
* Spend one use, binding a bind_on_use grant to $2 on its first spend.
|
|
8
|
+
* A bound grant acts again on its own ref without counting, and never on
|
|
9
|
+
* another ref. Without a ref ($2 NULL) the grant counts like any other.
|
|
10
|
+
*/
|
|
11
|
+
export declare const CONSUME_EPHEMERAL = "\n UPDATE lt_ephemeral_credentials\n SET use_count = CASE WHEN bound_ref IS NOT NULL THEN use_count ELSE use_count + 1 END,\n bound_ref = CASE WHEN bind_on_use AND bound_ref IS NULL THEN $2::text ELSE bound_ref END\n WHERE token = $1\n AND (expires_at IS NULL OR expires_at > NOW())\n AND (\n (bound_ref IS NOT NULL AND bound_ref = $2::text)\n OR (bound_ref IS NULL AND (max_uses = 0 OR use_count < max_uses))\n )\n RETURNING value, use_count, max_uses, bound_ref";
|
|
12
|
+
/** Return a use an act spent but did not land; $2 also undoes the binding that spend made. */
|
|
13
|
+
export declare const REFUND_EPHEMERAL = "\n UPDATE lt_ephemeral_credentials\n SET use_count = GREATEST(use_count - 1, 0),\n bound_ref = CASE WHEN $2::boolean THEN NULL ELSE bound_ref END\n WHERE token = $1";
|
|
4
14
|
export declare const DELETE_EPHEMERAL = "\n DELETE FROM lt_ephemeral_credentials WHERE token = $1";
|
|
5
15
|
export declare const CLEANUP_EXPIRED_EPHEMERAL = "\n DELETE FROM lt_ephemeral_credentials\n WHERE expires_at IS NOT NULL AND expires_at < NOW()";
|
|
6
16
|
export declare const LIST_BOTS = "\n SELECT * FROM lt_users\n WHERE account_type = 'bot'\n AND ($3::text IS NULL OR status = $3)\n AND ($4::text IS NULL\n OR display_name ILIKE '%' || $4 || '%'\n OR external_id ILIKE '%' || $4 || '%'\n OR metadata->>'description' ILIKE '%' || $4 || '%')\n ORDER BY created_at DESC\n LIMIT $1 OFFSET $2";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// ─── Ephemeral credentials ──────────────────────────────────────────────────
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.GET_USER_WITH_ROLES_FLEXIBLE = exports.GET_USER_BY_EXTERNAL_ID = exports.SET_ACCOUNT_TYPE_BOT = exports.COUNT_BOTS = exports.LIST_BOTS = exports.CLEANUP_EXPIRED_EPHEMERAL = exports.DELETE_EPHEMERAL = exports.EXCHANGE_EPHEMERAL = exports.INSERT_EPHEMERAL = void 0;
|
|
4
|
+
exports.GET_USER_WITH_ROLES_FLEXIBLE = exports.GET_USER_BY_EXTERNAL_ID = exports.SET_ACCOUNT_TYPE_BOT = exports.COUNT_BOTS = exports.LIST_BOTS = exports.CLEANUP_EXPIRED_EPHEMERAL = exports.DELETE_EPHEMERAL = exports.REFUND_EPHEMERAL = exports.CONSUME_EPHEMERAL = exports.PEEK_EPHEMERAL = exports.EXCHANGE_EPHEMERAL = exports.INSERT_EPHEMERAL = void 0;
|
|
5
5
|
/** Build INSERT for ephemeral credentials. expiresExpr is a SQL expression like 'NULL' or "NOW() + N * INTERVAL '1 second'". */
|
|
6
6
|
const INSERT_EPHEMERAL = (expiresExpr) => `
|
|
7
|
-
INSERT INTO lt_ephemeral_credentials (value, label, max_uses, expires_at)
|
|
8
|
-
VALUES ($1, $2, $3, ${expiresExpr})
|
|
7
|
+
INSERT INTO lt_ephemeral_credentials (value, label, max_uses, bind_on_use, expires_at)
|
|
8
|
+
VALUES ($1, $2, $3, $4, ${expiresExpr})
|
|
9
9
|
RETURNING token`;
|
|
10
10
|
exports.INSERT_EPHEMERAL = INSERT_EPHEMERAL;
|
|
11
11
|
exports.EXCHANGE_EPHEMERAL = `
|
|
@@ -15,6 +15,35 @@ exports.EXCHANGE_EPHEMERAL = `
|
|
|
15
15
|
AND (expires_at IS NULL OR expires_at > NOW())
|
|
16
16
|
AND (max_uses = 0 OR use_count < max_uses)
|
|
17
17
|
RETURNING value, use_count, max_uses`;
|
|
18
|
+
/** Validity check without spending a use. A bound grant stays live until its TTL. */
|
|
19
|
+
exports.PEEK_EPHEMERAL = `
|
|
20
|
+
SELECT value, use_count, max_uses, bound_ref
|
|
21
|
+
FROM lt_ephemeral_credentials
|
|
22
|
+
WHERE token = $1
|
|
23
|
+
AND (expires_at IS NULL OR expires_at > NOW())
|
|
24
|
+
AND (bound_ref IS NOT NULL OR max_uses = 0 OR use_count < max_uses)`;
|
|
25
|
+
/**
|
|
26
|
+
* Spend one use, binding a bind_on_use grant to $2 on its first spend.
|
|
27
|
+
* A bound grant acts again on its own ref without counting, and never on
|
|
28
|
+
* another ref. Without a ref ($2 NULL) the grant counts like any other.
|
|
29
|
+
*/
|
|
30
|
+
exports.CONSUME_EPHEMERAL = `
|
|
31
|
+
UPDATE lt_ephemeral_credentials
|
|
32
|
+
SET use_count = CASE WHEN bound_ref IS NOT NULL THEN use_count ELSE use_count + 1 END,
|
|
33
|
+
bound_ref = CASE WHEN bind_on_use AND bound_ref IS NULL THEN $2::text ELSE bound_ref END
|
|
34
|
+
WHERE token = $1
|
|
35
|
+
AND (expires_at IS NULL OR expires_at > NOW())
|
|
36
|
+
AND (
|
|
37
|
+
(bound_ref IS NOT NULL AND bound_ref = $2::text)
|
|
38
|
+
OR (bound_ref IS NULL AND (max_uses = 0 OR use_count < max_uses))
|
|
39
|
+
)
|
|
40
|
+
RETURNING value, use_count, max_uses, bound_ref`;
|
|
41
|
+
/** Return a use an act spent but did not land; $2 also undoes the binding that spend made. */
|
|
42
|
+
exports.REFUND_EPHEMERAL = `
|
|
43
|
+
UPDATE lt_ephemeral_credentials
|
|
44
|
+
SET use_count = GREATEST(use_count - 1, 0),
|
|
45
|
+
bound_ref = CASE WHEN $2::boolean THEN NULL ELSE bound_ref END
|
|
46
|
+
WHERE token = $1`;
|
|
18
47
|
exports.DELETE_EPHEMERAL = `
|
|
19
48
|
DELETE FROM lt_ephemeral_credentials WHERE token = $1`;
|
|
20
49
|
exports.CLEANUP_EXPIRED_EPHEMERAL = `
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildEvents = buildEvents;
|
|
4
4
|
const hotmesh_utils_1 = require("../hotmesh-utils");
|
|
5
|
+
const workflow_state_1 = require("../workflow-state");
|
|
5
6
|
/**
|
|
6
7
|
* Transform raw activities + job context into a chronological event list
|
|
7
8
|
* with back-references linking completions to their scheduled events.
|
|
@@ -84,7 +85,7 @@ function completionEvent(id, act, input, timelineKey, index) {
|
|
|
84
85
|
};
|
|
85
86
|
}
|
|
86
87
|
function appendWorkflowTerminalEvent(events, nextId, ctx) {
|
|
87
|
-
const status =
|
|
88
|
+
const status = (0, workflow_state_1.workflowStateFromStatus)(ctx.job.status);
|
|
88
89
|
if (status === 'completed') {
|
|
89
90
|
events.push({
|
|
90
91
|
event_id: nextId,
|
|
@@ -6,6 +6,7 @@ const hotmesh_utils_1 = require("../hotmesh-utils");
|
|
|
6
6
|
const enrichment_1 = require("./enrichment");
|
|
7
7
|
const events_1 = require("./events");
|
|
8
8
|
const sql_1 = require("./sql");
|
|
9
|
+
const workflow_state_1 = require("../workflow-state");
|
|
9
10
|
/**
|
|
10
11
|
* Build a complete execution export for a YAML engine workflow job.
|
|
11
12
|
*
|
|
@@ -88,7 +89,7 @@ function assembleExport(ctx, events, activities) {
|
|
|
88
89
|
workflow_type: ctx.workflowTopic,
|
|
89
90
|
workflow_name: ctx.workflowName,
|
|
90
91
|
task_queue: ctx.appId,
|
|
91
|
-
status:
|
|
92
|
+
status: (0, workflow_state_1.workflowStateFromStatus)(ctx.job.status),
|
|
92
93
|
start_time: startTime,
|
|
93
94
|
close_time: closeTime,
|
|
94
95
|
duration_ms: durationMs,
|
|
@@ -5,6 +5,7 @@ exports.listJobs = listJobs;
|
|
|
5
5
|
const db_1 = require("../../lib/db");
|
|
6
6
|
const hotmesh_utils_1 = require("../hotmesh-utils");
|
|
7
7
|
const sql_1 = require("./sql");
|
|
8
|
+
const workflow_state_1 = require("../workflow-state");
|
|
8
9
|
const SORTABLE_COLUMNS = new Set(['created_at', 'updated_at', 'entity', 'status']);
|
|
9
10
|
function buildOrderBy(sortBy, order) {
|
|
10
11
|
if (!sortBy || !SORTABLE_COLUMNS.has(sortBy)) {
|
|
@@ -75,7 +76,7 @@ async function listJobs(params) {
|
|
|
75
76
|
const jobs = dataResult.rows.map((row) => ({
|
|
76
77
|
workflow_id: row.key.startsWith(keyPrefix) ? row.key.slice(keyPrefix.length) : row.key,
|
|
77
78
|
entity: row.entity,
|
|
78
|
-
status:
|
|
79
|
+
status: (0, workflow_state_1.workflowStateFromStatus)(row.status),
|
|
79
80
|
is_live: row.is_live,
|
|
80
81
|
created_at: row.created_at,
|
|
81
82
|
updated_at: row.updated_at,
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type RoleBadgeGrant } from './types';
|
|
2
|
+
/** The problem with a `properties.badge_grant` value, or null when it is usable (or absent). */
|
|
3
|
+
export declare function badgeGrantError(value: unknown): string | null;
|
|
4
|
+
/** The role's badge policy from its properties bag, or null when it declares none (or an unusable one). */
|
|
5
|
+
export declare function readBadgeGrant(properties: Record<string, unknown> | null | undefined): RoleBadgeGrant | null;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.badgeGrantError = badgeGrantError;
|
|
4
|
+
exports.readBadgeGrant = readBadgeGrant;
|
|
5
|
+
const types_1 = require("./types");
|
|
6
|
+
const SCOPES = ['action', 'subject'];
|
|
7
|
+
/** The problem with a `properties.badge_grant` value, or null when it is usable (or absent). */
|
|
8
|
+
function badgeGrantError(value) {
|
|
9
|
+
if (value === undefined || value === null)
|
|
10
|
+
return null;
|
|
11
|
+
if (typeof value !== 'object' || Array.isArray(value))
|
|
12
|
+
return 'properties.badge_grant must be an object';
|
|
13
|
+
const grant = value;
|
|
14
|
+
const known = new Set(['ttl_seconds', 'max_uses', 'scope']);
|
|
15
|
+
const extra = Object.keys(grant).filter((k) => !known.has(k));
|
|
16
|
+
if (extra.length)
|
|
17
|
+
return `properties.badge_grant has unknown key(s): ${extra.join(', ')}`;
|
|
18
|
+
if (grant.ttl_seconds !== undefined
|
|
19
|
+
&& (!Number.isInteger(grant.ttl_seconds) || grant.ttl_seconds < 1 || grant.ttl_seconds > 86_400)) {
|
|
20
|
+
return 'properties.badge_grant.ttl_seconds must be an integer from 1 to 86400';
|
|
21
|
+
}
|
|
22
|
+
if (grant.max_uses !== undefined && (!Number.isInteger(grant.max_uses) || grant.max_uses < 0)) {
|
|
23
|
+
return 'properties.badge_grant.max_uses must be a non-negative integer';
|
|
24
|
+
}
|
|
25
|
+
if (grant.scope !== undefined && !SCOPES.includes(grant.scope)) {
|
|
26
|
+
return `properties.badge_grant.scope must be one of ${SCOPES.join(', ')}`;
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
/** The role's badge policy from its properties bag, or null when it declares none (or an unusable one). */
|
|
31
|
+
function readBadgeGrant(properties) {
|
|
32
|
+
const value = properties?.[types_1.ROLE_PROPERTY_KEYS.BADGE_GRANT];
|
|
33
|
+
if (value === undefined || value === null || badgeGrantError(value))
|
|
34
|
+
return null;
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
@@ -8,6 +8,8 @@ const db_1 = require("../../lib/db");
|
|
|
8
8
|
const logger_1 = require("../../lib/logger");
|
|
9
9
|
const index_1 = require("./index");
|
|
10
10
|
const sql_1 = require("./sql");
|
|
11
|
+
const badge_grant_1 = require("./badge-grant");
|
|
12
|
+
const types_1 = require("./types");
|
|
11
13
|
/** Recorded on schema snapshots written by the startup apply. */
|
|
12
14
|
exports.STARTUP_CHANGE_SUMMARY = 'startup apply (code)';
|
|
13
15
|
/** Metadata fields shared 1:1 between LTRoleConfig and UpdateRoleInput. */
|
|
@@ -79,6 +81,9 @@ async function listConfiguredRoles() {
|
|
|
79
81
|
* Escalation targets use replace semantics when declared.
|
|
80
82
|
*/
|
|
81
83
|
async function applyRoleConfig(cfg, codeOwned) {
|
|
84
|
+
const grantError = (0, badge_grant_1.badgeGrantError)(cfg.properties?.[types_1.ROLE_PROPERTY_KEYS.BADGE_GRANT]);
|
|
85
|
+
if (grantError)
|
|
86
|
+
throw new Error(`role ${cfg.role}: ${grantError}`);
|
|
82
87
|
const created = await (0, index_1.createRole)(cfg.role);
|
|
83
88
|
const pool = (0, db_1.getPool)();
|
|
84
89
|
const { rows } = await pool.query(sql_1.GET_ROLE_ROW, [cfg.role]);
|
|
@@ -15,6 +15,10 @@ export interface EscalationChain {
|
|
|
15
15
|
* MEMBER of exactly this one role, the dashboard drops the left nav, the
|
|
16
16
|
* role's escalation list becomes home, and navigation is held to the list,
|
|
17
17
|
* the detail page, and the scan screens. Multi-role users get full chrome.
|
|
18
|
+
* - BADGE_GRANT: RoleBadgeGrant — the badge policy at this role's stations.
|
|
19
|
+
* A badge scanned on a device signed in as a member of this role mints
|
|
20
|
+
* its acting grant under this policy instead of the badge scheme's own
|
|
21
|
+
* (see api/scan-codes/badge-policy.ts).
|
|
18
22
|
* - LINK_VARIABLES: RoleLinkVariable[] — metadata facet names members bind
|
|
19
23
|
* per device. Pins may reference `{lt:name}` as a whole facet value
|
|
20
24
|
* (e.g. `facets={"region":"{lt:region}"}`); the dashboard substitutes
|
|
@@ -27,7 +31,17 @@ export declare const ROLE_PROPERTY_KEYS: {
|
|
|
27
31
|
readonly WORKED_BY: "worked_by";
|
|
28
32
|
readonly KIOSK: "kiosk";
|
|
29
33
|
readonly LINK_VARIABLES: "link_variables";
|
|
34
|
+
readonly BADGE_GRANT: "badge_grant";
|
|
30
35
|
};
|
|
36
|
+
/** A station role's badge policy. Absent fields keep the badge scheme's value. */
|
|
37
|
+
export interface RoleBadgeGrant {
|
|
38
|
+
/** How long a badge scan stays primed (1-86400 s). */
|
|
39
|
+
ttl_seconds?: number;
|
|
40
|
+
/** 0 = TTL-bound; n = the grant covers n acts. */
|
|
41
|
+
max_uses?: number;
|
|
42
|
+
/** 'action' spends a use per act; 'subject' binds to one held item. */
|
|
43
|
+
scope?: 'action' | 'subject';
|
|
44
|
+
}
|
|
31
45
|
/**
|
|
32
46
|
* One link-variable declaration inside `properties.link_variables`. `name` is
|
|
33
47
|
* the metadata facet key (facet-key charset); `label` is the human annotation
|
|
@@ -14,6 +14,10 @@ exports.PORTAL_KEY = exports.PORTAL_LIMITS = exports.ROLE_PROPERTY_KEYS = void 0
|
|
|
14
14
|
* MEMBER of exactly this one role, the dashboard drops the left nav, the
|
|
15
15
|
* role's escalation list becomes home, and navigation is held to the list,
|
|
16
16
|
* the detail page, and the scan screens. Multi-role users get full chrome.
|
|
17
|
+
* - BADGE_GRANT: RoleBadgeGrant — the badge policy at this role's stations.
|
|
18
|
+
* A badge scanned on a device signed in as a member of this role mints
|
|
19
|
+
* its acting grant under this policy instead of the badge scheme's own
|
|
20
|
+
* (see api/scan-codes/badge-policy.ts).
|
|
17
21
|
* - LINK_VARIABLES: RoleLinkVariable[] — metadata facet names members bind
|
|
18
22
|
* per device. Pins may reference `{lt:name}` as a whole facet value
|
|
19
23
|
* (e.g. `facets={"region":"{lt:region}"}`); the dashboard substitutes
|
|
@@ -26,6 +30,7 @@ exports.ROLE_PROPERTY_KEYS = {
|
|
|
26
30
|
WORKED_BY: 'worked_by',
|
|
27
31
|
KIOSK: 'kiosk',
|
|
28
32
|
LINK_VARIABLES: 'link_variables',
|
|
33
|
+
BADGE_GRANT: 'badge_grant',
|
|
29
34
|
};
|
|
30
35
|
/** Bounds for a role's portals: how many, and the matrix of each (rows of cells, each cell a pin). */
|
|
31
36
|
exports.PORTAL_LIMITS = {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { listScanSchemes, getScanScheme, listScanRules, getScanRule, } from './read';
|
|
2
2
|
export { upsertScanScheme, deleteScanScheme, upsertScanRule, deleteScanRule, seedScanScheme, seedScanRule, applyScanScheme, applyScanRule, type ScanSchemeInput, type ScanRuleInput, } from './write';
|
|
3
|
-
export { parseScanCode, interpolateScanTemplate, mentionsClaimToken, ScanTemplateError, type ScanParseResult, type ScanParseFailure, type ScanTemplateContext, } from './parse';
|
|
4
|
-
export { assertValidScheme, assertValidSteps } from './validate';
|
|
3
|
+
export { parseScanCode, interpolateScanTemplate, mentionsClaimToken, renderScanCopy, ScanTemplateError, type ScanParseResult, type ScanParseFailure, type ScanTemplateContext, } from './parse';
|
|
4
|
+
export { assertValidScheme, assertValidSteps, assertValidIdentityRule, assertSchemesCoexist, } from './validate';
|
|
5
|
+
export { isValidGtin, normalizeGtin } from '../../shared/scan-code';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.assertValidSteps = exports.assertValidScheme = exports.ScanTemplateError = exports.mentionsClaimToken = exports.interpolateScanTemplate = exports.parseScanCode = exports.applyScanRule = exports.applyScanScheme = exports.seedScanRule = exports.seedScanScheme = exports.deleteScanRule = exports.upsertScanRule = exports.deleteScanScheme = exports.upsertScanScheme = exports.getScanRule = exports.listScanRules = exports.getScanScheme = exports.listScanSchemes = void 0;
|
|
3
|
+
exports.normalizeGtin = exports.isValidGtin = exports.assertSchemesCoexist = exports.assertValidIdentityRule = exports.assertValidSteps = exports.assertValidScheme = exports.ScanTemplateError = exports.renderScanCopy = exports.mentionsClaimToken = exports.interpolateScanTemplate = exports.parseScanCode = exports.applyScanRule = exports.applyScanScheme = exports.seedScanRule = exports.seedScanScheme = exports.deleteScanRule = exports.upsertScanRule = exports.deleteScanScheme = exports.upsertScanScheme = exports.getScanRule = exports.listScanRules = exports.getScanScheme = exports.listScanSchemes = void 0;
|
|
4
4
|
var read_1 = require("./read");
|
|
5
5
|
Object.defineProperty(exports, "listScanSchemes", { enumerable: true, get: function () { return read_1.listScanSchemes; } });
|
|
6
6
|
Object.defineProperty(exports, "getScanScheme", { enumerable: true, get: function () { return read_1.getScanScheme; } });
|
|
@@ -19,7 +19,13 @@ var parse_1 = require("./parse");
|
|
|
19
19
|
Object.defineProperty(exports, "parseScanCode", { enumerable: true, get: function () { return parse_1.parseScanCode; } });
|
|
20
20
|
Object.defineProperty(exports, "interpolateScanTemplate", { enumerable: true, get: function () { return parse_1.interpolateScanTemplate; } });
|
|
21
21
|
Object.defineProperty(exports, "mentionsClaimToken", { enumerable: true, get: function () { return parse_1.mentionsClaimToken; } });
|
|
22
|
+
Object.defineProperty(exports, "renderScanCopy", { enumerable: true, get: function () { return parse_1.renderScanCopy; } });
|
|
22
23
|
Object.defineProperty(exports, "ScanTemplateError", { enumerable: true, get: function () { return parse_1.ScanTemplateError; } });
|
|
23
24
|
var validate_1 = require("./validate");
|
|
24
25
|
Object.defineProperty(exports, "assertValidScheme", { enumerable: true, get: function () { return validate_1.assertValidScheme; } });
|
|
25
26
|
Object.defineProperty(exports, "assertValidSteps", { enumerable: true, get: function () { return validate_1.assertValidSteps; } });
|
|
27
|
+
Object.defineProperty(exports, "assertValidIdentityRule", { enumerable: true, get: function () { return validate_1.assertValidIdentityRule; } });
|
|
28
|
+
Object.defineProperty(exports, "assertSchemesCoexist", { enumerable: true, get: function () { return validate_1.assertSchemesCoexist; } });
|
|
29
|
+
var scan_code_1 = require("../../shared/scan-code");
|
|
30
|
+
Object.defineProperty(exports, "isValidGtin", { enumerable: true, get: function () { return scan_code_1.isValidGtin; } });
|
|
31
|
+
Object.defineProperty(exports, "normalizeGtin", { enumerable: true, get: function () { return scan_code_1.normalizeGtin; } });
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
+
import { type ScanParseFailure } from '../../shared/scan-code';
|
|
1
2
|
import { type ParsedScanCode, type ScanScheme } from '../../types';
|
|
2
|
-
export
|
|
3
|
-
/** Why the code did not parse. */
|
|
4
|
-
reason: 'empty' | 'unknown_version' | 'scheme_disabled' | 'malformed';
|
|
5
|
-
detail: string;
|
|
6
|
-
}
|
|
3
|
+
export type { ScanParseFailure };
|
|
7
4
|
export type ScanParseResult = {
|
|
8
5
|
ok: true;
|
|
9
6
|
parsed: ParsedScanCode;
|
|
@@ -12,26 +9,26 @@ export type ScanParseResult = {
|
|
|
12
9
|
ok: false;
|
|
13
10
|
failure: ScanParseFailure;
|
|
14
11
|
};
|
|
15
|
-
/**
|
|
16
|
-
* Parse a raw scan string against the configured schemes. Pure — no I/O.
|
|
17
|
-
*
|
|
18
|
-
* The leading TWO digits pick the scheme (10-99, so a code never starts with a
|
|
19
|
-
* leading zero); the scheme then defines how the remainder splits into a
|
|
20
|
-
* single-digit category (0-9) and the target:
|
|
21
|
-
* - delimited: `10:1:ABC-123` (delimiter from the scheme row)
|
|
22
|
-
* - fixed: `1017554332` (one category digit, then target_length digits)
|
|
23
|
-
*/
|
|
12
|
+
/** Parse a raw scan string against the configured schemes. Pure; see shared/scan-code. */
|
|
24
13
|
export declare function parseScanCode(raw: string, schemes: ScanScheme[]): ScanParseResult;
|
|
25
14
|
export interface ScanTemplateContext {
|
|
26
15
|
target: string;
|
|
27
16
|
category: string;
|
|
28
17
|
scannedAt: string;
|
|
18
|
+
/** The code as scanned; defaults to the target. */
|
|
19
|
+
code?: string;
|
|
29
20
|
/** The acting user's single live claim, its metadata; absent when none or ambiguous. */
|
|
30
21
|
claim?: Record<string, unknown>;
|
|
31
|
-
/** The row
|
|
22
|
+
/** The row the step located (item-mode accumulate, hold), its metadata. */
|
|
32
23
|
item?: Record<string, unknown>;
|
|
24
|
+
/** The held subject's row: its metadata plus `id`. */
|
|
25
|
+
subject?: Record<string, unknown>;
|
|
26
|
+
/** The container a subject step located, its metadata. */
|
|
27
|
+
container?: Record<string, unknown>;
|
|
28
|
+
/** The batch a fill step read: `pending`, `total`, `filled`. */
|
|
29
|
+
fill?: Record<string, unknown>;
|
|
33
30
|
}
|
|
34
|
-
/** A
|
|
31
|
+
/** A bag token the context cannot resolve. */
|
|
35
32
|
export declare class ScanTemplateError extends Error {
|
|
36
33
|
readonly token: string;
|
|
37
34
|
readonly reason: string;
|
|
@@ -41,9 +38,15 @@ export declare class ScanTemplateError extends Error {
|
|
|
41
38
|
export declare function mentionsClaimToken(value: unknown): boolean;
|
|
42
39
|
/**
|
|
43
40
|
* Replace the template tokens inside string values of a params object.
|
|
44
|
-
* Deep, pure, non-mutating. The
|
|
45
|
-
*
|
|
46
|
-
* facet bags and throw
|
|
47
|
-
*
|
|
41
|
+
* Deep, pure, non-mutating. The scan tokens are plain text replacement; the
|
|
42
|
+
* bag tokens (`{claim.x}`, `{item.x}`, `{subject.x}`, `{container.x}`,
|
|
43
|
+
* `{fill.x}`) read the context's facet bags and throw
|
|
44
|
+
* {@link ScanTemplateError} when they cannot resolve, so a literal token
|
|
45
|
+
* never reaches a row. No expression language.
|
|
48
46
|
*/
|
|
49
47
|
export declare function interpolateScanTemplate<T>(value: T, ctx: ScanTemplateContext): T;
|
|
48
|
+
/**
|
|
49
|
+
* Render refusal copy, degrading instead of failing: a token with nothing to
|
|
50
|
+
* read becomes an empty string, so a refusal always has words to show.
|
|
51
|
+
*/
|
|
52
|
+
export declare function renderScanCopy(markdown: string, ctx: ScanTemplateContext): string;
|