@hotmeshio/long-tail 0.30.5 → 0.31.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (373) hide show
  1. package/build/api/labels/errors.d.ts +3 -0
  2. package/build/api/labels/errors.js +15 -0
  3. package/build/api/labels/index.d.ts +2 -0
  4. package/build/api/labels/index.js +17 -0
  5. package/build/api/labels/issue.d.ts +54 -0
  6. package/build/api/labels/issue.js +144 -0
  7. package/build/api/labels/templates.d.ts +29 -0
  8. package/build/api/labels/templates.js +98 -0
  9. package/build/api/users.d.ts +8 -4
  10. package/build/api/users.js +51 -13
  11. package/build/index.d.ts +1 -0
  12. package/build/index.js +4 -2
  13. package/build/lib/db/schemas/044_label_sheets.sql +65 -0
  14. package/build/lib/db/schemas/045_label_job_delivery.sql +14 -0
  15. package/build/lib/labels/transports.d.ts +23 -0
  16. package/build/lib/labels/transports.js +39 -0
  17. package/build/modules/auth.d.ts +2 -0
  18. package/build/modules/auth.js +3 -1
  19. package/build/modules/capabilities.d.ts +5 -1
  20. package/build/modules/capabilities.js +38 -8
  21. package/build/modules/config.d.ts +10 -0
  22. package/build/modules/config.js +10 -0
  23. package/build/routes/index.js +2 -0
  24. package/build/routes/labels.d.ts +2 -0
  25. package/build/routes/labels.js +135 -0
  26. package/build/routes/users.js +1 -1
  27. package/build/scripts/bambu-boat.d.ts +4 -2
  28. package/build/scripts/bambu-boat.js +4 -2
  29. package/build/scripts/bambu-print.d.ts +2 -1
  30. package/build/scripts/bambu-print.js +7 -3
  31. package/build/scripts/machine-line.js +2 -1
  32. package/build/services/labels/content.d.ts +13 -0
  33. package/build/services/labels/content.js +81 -0
  34. package/build/services/labels/errors.d.ts +5 -0
  35. package/build/services/labels/errors.js +12 -0
  36. package/build/services/labels/index.d.ts +11 -0
  37. package/build/services/labels/index.js +52 -0
  38. package/build/services/labels/issue.d.ts +38 -0
  39. package/build/services/labels/issue.js +181 -0
  40. package/build/services/labels/jobs.d.ts +37 -0
  41. package/build/services/labels/jobs.js +75 -0
  42. package/build/services/labels/media.d.ts +11 -0
  43. package/build/services/labels/media.js +44 -0
  44. package/build/services/labels/reissue.d.ts +13 -0
  45. package/build/services/labels/reissue.js +65 -0
  46. package/build/services/labels/render-pdf.d.ts +11 -0
  47. package/build/services/labels/render-pdf.js +138 -0
  48. package/build/services/labels/targets.d.ts +18 -0
  49. package/build/services/labels/targets.js +216 -0
  50. package/build/services/labels/templates/index.d.ts +3 -0
  51. package/build/services/labels/templates/index.js +18 -0
  52. package/build/services/labels/templates/read.d.ts +4 -0
  53. package/build/services/labels/templates/read.js +36 -0
  54. package/build/services/labels/templates/sql.d.ts +8 -0
  55. package/build/services/labels/templates/sql.js +50 -0
  56. package/build/services/labels/templates/validate.d.ts +19 -0
  57. package/build/services/labels/templates/validate.js +93 -0
  58. package/build/services/labels/templates/write.d.ts +16 -0
  59. package/build/services/labels/templates/write.js +75 -0
  60. package/build/services/labels/token.d.ts +9 -0
  61. package/build/services/labels/token.js +28 -0
  62. package/build/services/labels/verify.d.ts +4 -0
  63. package/build/services/labels/verify.js +38 -0
  64. package/build/services/scan-code/validate.d.ts +3 -0
  65. package/build/services/scan-code/validate.js +10 -0
  66. package/build/services/user/crud.d.ts +13 -1
  67. package/build/services/user/crud.js +42 -11
  68. package/build/services/user/index.d.ts +3 -2
  69. package/build/services/user/index.js +7 -1
  70. package/build/services/user/redact.d.ts +17 -0
  71. package/build/services/user/redact.js +32 -0
  72. package/build/services/user/sql.d.ts +8 -15
  73. package/build/services/user/sql.js +27 -3
  74. package/build/services/user/types.d.ts +21 -1
  75. package/build/shared/labels/compose.d.ts +12 -0
  76. package/build/shared/labels/compose.js +43 -0
  77. package/build/shared/labels/index.d.ts +9 -0
  78. package/build/shared/labels/index.js +54 -0
  79. package/build/shared/labels/label-content.d.ts +17 -0
  80. package/build/shared/labels/label-content.js +137 -0
  81. package/build/shared/labels/layout.d.ts +23 -0
  82. package/build/shared/labels/layout.js +81 -0
  83. package/build/shared/labels/media.d.ts +22 -0
  84. package/build/shared/labels/media.js +116 -0
  85. package/build/shared/labels/render-svg.d.ts +10 -0
  86. package/build/shared/labels/render-svg.js +58 -0
  87. package/build/shared/labels/render-zpl.d.ts +9 -0
  88. package/build/shared/labels/render-zpl.js +63 -0
  89. package/build/shared/labels/symbol.d.ts +18 -0
  90. package/build/shared/labels/symbol.js +74 -0
  91. package/build/shared/labels/tokens.d.ts +18 -0
  92. package/build/shared/labels/tokens.js +43 -0
  93. package/build/shared/labels/types.d.ts +105 -0
  94. package/build/shared/labels/types.js +11 -0
  95. package/build/start/adapters.js +16 -0
  96. package/build/start/workers.js +18 -2
  97. package/build/system/mcp-servers/admin/index.js +2 -0
  98. package/build/system/mcp-servers/admin/labels-schemas.d.ts +192 -0
  99. package/build/system/mcp-servers/admin/labels-schemas.js +46 -0
  100. package/build/system/mcp-servers/admin/labels.d.ts +9 -0
  101. package/build/system/mcp-servers/admin/labels.js +101 -0
  102. package/build/system/mcp-servers/admin/schemas.d.ts +30 -30
  103. package/build/system/mcp-servers/admin/users.js +1 -1
  104. package/build/system/seed/tool-manifests-admin.js +5 -0
  105. package/build/tsconfig.tsbuildinfo +1 -1
  106. package/build/types/capability.d.ts +2 -1
  107. package/build/types/index.d.ts +2 -1
  108. package/build/types/labels/index.d.ts +4 -0
  109. package/build/types/labels/index.js +2 -0
  110. package/build/types/labels/job.d.ts +51 -0
  111. package/build/types/labels/job.js +2 -0
  112. package/build/types/labels/source.d.ts +44 -0
  113. package/build/types/labels/source.js +2 -0
  114. package/build/types/labels/template.d.ts +46 -0
  115. package/build/types/labels/template.js +2 -0
  116. package/build/types/labels/transport.d.ts +24 -0
  117. package/build/types/labels/transport.js +2 -0
  118. package/build/types/scan-code/rule.d.ts +5 -0
  119. package/build/types/startup.d.ts +37 -0
  120. package/build/types/user.d.ts +2 -0
  121. package/dashboard/dist/assets/{AdminDashboard-D12QiMM5.js → AdminDashboard-BafKaq50.js} +2 -2
  122. package/dashboard/dist/assets/{AdminDashboard-D12QiMM5.js.map → AdminDashboard-BafKaq50.js.map} +1 -1
  123. package/dashboard/dist/assets/{AgentConfigPage-BKQd9b8m.js → AgentConfigPage-CFHf31DT.js} +6 -6
  124. package/dashboard/dist/assets/{AgentConfigPage-BKQd9b8m.js.map → AgentConfigPage-CFHf31DT.js.map} +1 -1
  125. package/dashboard/dist/assets/{AgentDetailPage-ie-DxsIj.js → AgentDetailPage-CEvz5rJr.js} +3 -3
  126. package/dashboard/dist/assets/{AgentDetailPage-ie-DxsIj.js.map → AgentDetailPage-CEvz5rJr.js.map} +1 -1
  127. package/dashboard/dist/assets/{AgentsPage-Nqm2DxCP.js → AgentsPage-DjQaio0O.js} +2 -2
  128. package/dashboard/dist/assets/{AgentsPage-Nqm2DxCP.js.map → AgentsPage-DjQaio0O.js.map} +1 -1
  129. package/dashboard/dist/assets/AvailableEscalationsPage-UB03VTJx.js +2 -0
  130. package/dashboard/dist/assets/AvailableEscalationsPage-UB03VTJx.js.map +1 -0
  131. package/dashboard/dist/assets/{BotPicker-BizdmeJp.js → BotPicker-C7MNWOF7.js} +2 -2
  132. package/dashboard/dist/assets/{BotPicker-BizdmeJp.js.map → BotPicker-C7MNWOF7.js.map} +1 -1
  133. package/dashboard/dist/assets/BulkAssignModal-h5fX-_cV.js +2 -0
  134. package/dashboard/dist/assets/{BulkAssignModal-BWfzPrRk.js.map → BulkAssignModal-h5fX-_cV.js.map} +1 -1
  135. package/dashboard/dist/assets/{CapabilitiesPage-DT8q7Zlh.js → CapabilitiesPage-BIzDl-ZT.js} +2 -2
  136. package/dashboard/dist/assets/{CapabilitiesPage-DT8q7Zlh.js.map → CapabilitiesPage-BIzDl-ZT.js.map} +1 -1
  137. package/dashboard/dist/assets/{CollapsibleSection-al5mqR4O.js → CollapsibleSection-B5TivtEg.js} +2 -2
  138. package/dashboard/dist/assets/{CollapsibleSection-al5mqR4O.js.map → CollapsibleSection-B5TivtEg.js.map} +1 -1
  139. package/dashboard/dist/assets/{ConfirmDeleteModal-BrlVktv2.js → ConfirmDeleteModal-CB4nKePb.js} +2 -2
  140. package/dashboard/dist/assets/{ConfirmDeleteModal-BrlVktv2.js.map → ConfirmDeleteModal-CB4nKePb.js.map} +1 -1
  141. package/dashboard/dist/assets/{ConnectedAppsPage-CLAsJ2yQ.js → ConnectedAppsPage-B3S5gVWw.js} +2 -2
  142. package/dashboard/dist/assets/{ConnectedAppsPage-CLAsJ2yQ.js.map → ConnectedAppsPage-B3S5gVWw.js.map} +1 -1
  143. package/dashboard/dist/assets/{CountdownTimer-D2D68exl.js → CountdownTimer-BHVIq3kA.js} +2 -2
  144. package/dashboard/dist/assets/{CountdownTimer-D2D68exl.js.map → CountdownTimer-BHVIq3kA.js.map} +1 -1
  145. package/dashboard/dist/assets/CredentialConfirmModal-w0AGmCIe.js +2 -0
  146. package/dashboard/dist/assets/CredentialConfirmModal-w0AGmCIe.js.map +1 -0
  147. package/dashboard/dist/assets/{CredentialsPage-DWrZbEI0.js → CredentialsPage-BtCGBJrT.js} +2 -2
  148. package/dashboard/dist/assets/{CredentialsPage-DWrZbEI0.js.map → CredentialsPage-BtCGBJrT.js.map} +1 -1
  149. package/dashboard/dist/assets/{CronLabel-DuXR8iWq.js → CronLabel-BG1rZK-5.js} +2 -2
  150. package/dashboard/dist/assets/{CronLabel-DuXR8iWq.js.map → CronLabel-BG1rZK-5.js.map} +1 -1
  151. package/dashboard/dist/assets/{DropZone-DefYTYQy.js → DropZone-D8ZVdEb5.js} +2 -2
  152. package/dashboard/dist/assets/{DropZone-DefYTYQy.js.map → DropZone-D8ZVdEb5.js.map} +1 -1
  153. package/dashboard/dist/assets/{ElapsedCell-ronqG5-E.js → ElapsedCell-l4m8Yvfv.js} +2 -2
  154. package/dashboard/dist/assets/{ElapsedCell-ronqG5-E.js.map → ElapsedCell-l4m8Yvfv.js.map} +1 -1
  155. package/dashboard/dist/assets/{EntityTimelinePanel-CKsktd84.js → EntityTimelinePanel-BOHlIaxF.js} +2 -2
  156. package/dashboard/dist/assets/{EntityTimelinePanel-CKsktd84.js.map → EntityTimelinePanel-BOHlIaxF.js.map} +1 -1
  157. package/dashboard/dist/assets/{EscalationListSchemaPage-C954ngy3.js → EscalationListSchemaPage-BotlwlX3.js} +3 -3
  158. package/dashboard/dist/assets/{EscalationListSchemaPage-C954ngy3.js.map → EscalationListSchemaPage-BotlwlX3.js.map} +1 -1
  159. package/dashboard/dist/assets/{EscalationSchemaPage-Dij9K0ON.js → EscalationSchemaPage-CfZSVOSD.js} +3 -3
  160. package/dashboard/dist/assets/{EscalationSchemaPage-Dij9K0ON.js.map → EscalationSchemaPage-CfZSVOSD.js.map} +1 -1
  161. package/dashboard/dist/assets/{EscalationTimeline-DT2Owdl0.js → EscalationTimeline-CCKpuRBU.js} +2 -2
  162. package/dashboard/dist/assets/{EscalationTimeline-DT2Owdl0.js.map → EscalationTimeline-CCKpuRBU.js.map} +1 -1
  163. package/dashboard/dist/assets/{EscalationTitleSelect-BdbfMA98.js → EscalationTitleSelect-cpTzPHiW.js} +2 -2
  164. package/dashboard/dist/assets/{EscalationTitleSelect-BdbfMA98.js.map → EscalationTitleSelect-cpTzPHiW.js.map} +1 -1
  165. package/dashboard/dist/assets/{EscalationsOverview-niahs84P.js → EscalationsOverview-DS-nK0qV.js} +2 -2
  166. package/dashboard/dist/assets/{EscalationsOverview-niahs84P.js.map → EscalationsOverview-DS-nK0qV.js.map} +1 -1
  167. package/dashboard/dist/assets/{EventTable-DuLMBrSx.js → EventTable-UfebhJf0.js} +2 -2
  168. package/dashboard/dist/assets/{EventTable-DuLMBrSx.js.map → EventTable-UfebhJf0.js.map} +1 -1
  169. package/dashboard/dist/assets/{FilterBar-jtY6KNpL.js → FilterBar-newA5l-X.js} +2 -2
  170. package/dashboard/dist/assets/{FilterBar-jtY6KNpL.js.map → FilterBar-newA5l-X.js.map} +1 -1
  171. package/dashboard/dist/assets/{GraphInvokePage-DSRAI0Zt.js → GraphInvokePage-6SCDyQcK.js} +2 -2
  172. package/dashboard/dist/assets/{GraphInvokePage-DSRAI0Zt.js.map → GraphInvokePage-6SCDyQcK.js.map} +1 -1
  173. package/dashboard/dist/assets/HomePage-BEc-XdKj.js +2 -0
  174. package/dashboard/dist/assets/{HomePage-BUlSnCg8.js.map → HomePage-BEc-XdKj.js.map} +1 -1
  175. package/dashboard/dist/assets/LabelJobsPage-BO50zXT5.js +2 -0
  176. package/dashboard/dist/assets/LabelJobsPage-BO50zXT5.js.map +1 -0
  177. package/dashboard/dist/assets/{LinePage-BJKhVM9Y.js → LinePage-NYxJQ-ex.js} +3 -3
  178. package/dashboard/dist/assets/{LinePage-BJKhVM9Y.js.map → LinePage-NYxJQ-ex.js.map} +1 -1
  179. package/dashboard/dist/assets/{LinesPage-CrpJua3_.js → LinesPage-RbWTaQRh.js} +3 -3
  180. package/dashboard/dist/assets/{LinesPage-CrpJua3_.js.map → LinesPage-RbWTaQRh.js.map} +1 -1
  181. package/dashboard/dist/assets/{ListToolbar-BN0UPt0L.js → ListToolbar-B-E9-toh.js} +2 -2
  182. package/dashboard/dist/assets/{ListToolbar-BN0UPt0L.js.map → ListToolbar-B-E9-toh.js.map} +1 -1
  183. package/dashboard/dist/assets/{McpOverview-BgbJXYPh.js → McpOverview-Shcf9QhZ.js} +2 -2
  184. package/dashboard/dist/assets/{McpOverview-BgbJXYPh.js.map → McpOverview-Shcf9QhZ.js.map} +1 -1
  185. package/dashboard/dist/assets/{McpQueryDetailPage-BNjm2nrc.js → McpQueryDetailPage-D8kmjy2v.js} +3 -3
  186. package/dashboard/dist/assets/{McpQueryDetailPage-BNjm2nrc.js.map → McpQueryDetailPage-D8kmjy2v.js.map} +1 -1
  187. package/dashboard/dist/assets/{McpQueryPage-DplR8wP9.js → McpQueryPage-ck-o5m8A.js} +2 -2
  188. package/dashboard/dist/assets/{McpQueryPage-DplR8wP9.js.map → McpQueryPage-ck-o5m8A.js.map} +1 -1
  189. package/dashboard/dist/assets/McpRunDetailPage-BJKkM9-3.js +2 -0
  190. package/dashboard/dist/assets/{McpRunDetailPage-BHVEcKV5.js.map → McpRunDetailPage-BJKkM9-3.js.map} +1 -1
  191. package/dashboard/dist/assets/{McpRunsPage-CtlLagcs.js → McpRunsPage-DqhHfD5G.js} +2 -2
  192. package/dashboard/dist/assets/{McpRunsPage-CtlLagcs.js.map → McpRunsPage-DqhHfD5G.js.map} +1 -1
  193. package/dashboard/dist/assets/{NamespacePill-CeSfHH-j.js → NamespacePill--uIaGtrN.js} +2 -2
  194. package/dashboard/dist/assets/{NamespacePill-CeSfHH-j.js.map → NamespacePill--uIaGtrN.js.map} +1 -1
  195. package/dashboard/dist/assets/{OperationsPage-DH67bcW9.js → OperationsPage-D6B9Vv__.js} +3 -3
  196. package/dashboard/dist/assets/{OperationsPage-DH67bcW9.js.map → OperationsPage-D6B9Vv__.js.map} +1 -1
  197. package/dashboard/dist/assets/OperatorDashboard-CIH1cxjQ.js +2 -0
  198. package/dashboard/dist/assets/{OperatorDashboard-CMkgMewd.js.map → OperatorDashboard-CIH1cxjQ.js.map} +1 -1
  199. package/dashboard/dist/assets/{PageHeader-DiGWAQlR.js → PageHeader-DClJ33fV.js} +2 -2
  200. package/dashboard/dist/assets/{PageHeader-DiGWAQlR.js.map → PageHeader-DClJ33fV.js.map} +1 -1
  201. package/dashboard/dist/assets/{PageHeaderWithStats-DwnKQ06j.js → PageHeaderWithStats-C-TrbKQL.js} +2 -2
  202. package/dashboard/dist/assets/{PageHeaderWithStats-DwnKQ06j.js.map → PageHeaderWithStats-C-TrbKQL.js.map} +1 -1
  203. package/dashboard/dist/assets/PersonaDetailPage-DjvfyIph.js +2 -0
  204. package/dashboard/dist/assets/{PersonaDetailPage-Cs1FFdNq.js.map → PersonaDetailPage-DjvfyIph.js.map} +1 -1
  205. package/dashboard/dist/assets/{PersonasPage-CHTRdneF.js → PersonasPage-D7ryA8Vc.js} +2 -2
  206. package/dashboard/dist/assets/{PersonasPage-CHTRdneF.js.map → PersonasPage-D7ryA8Vc.js.map} +1 -1
  207. package/dashboard/dist/assets/{PortalPage-ChB5pBTZ.js → PortalPage-D3ybr0mo.js} +2 -2
  208. package/dashboard/dist/assets/{PortalPage-ChB5pBTZ.js.map → PortalPage-D3ybr0mo.js.map} +1 -1
  209. package/dashboard/dist/assets/PrintLabelsPanel-D0HF5x8b.js +2 -0
  210. package/dashboard/dist/assets/PrintLabelsPanel-D0HF5x8b.js.map +1 -0
  211. package/dashboard/dist/assets/{ProcessDetailPage-CzyqSfal.js → ProcessDetailPage-0xS9EdHe.js} +2 -2
  212. package/dashboard/dist/assets/{ProcessDetailPage-CzyqSfal.js.map → ProcessDetailPage-0xS9EdHe.js.map} +1 -1
  213. package/dashboard/dist/assets/{ProcessesListPage-rOwNkaU9.js → ProcessesListPage-93SMj1Fd.js} +2 -2
  214. package/dashboard/dist/assets/{ProcessesListPage-rOwNkaU9.js.map → ProcessesListPage-93SMj1Fd.js.map} +1 -1
  215. package/dashboard/dist/assets/{ResolverForm-DibnlZ-A.js → ResolverForm-DfogHDzl.js} +5 -5
  216. package/dashboard/dist/assets/{ResolverForm-DibnlZ-A.js.map → ResolverForm-DfogHDzl.js.map} +1 -1
  217. package/dashboard/dist/assets/{RoleDetailPage-Bv9R7iQC.js → RoleDetailPage-DlUOJWSB.js} +3 -3
  218. package/dashboard/dist/assets/{RoleDetailPage-Bv9R7iQC.js.map → RoleDetailPage-DlUOJWSB.js.map} +1 -1
  219. package/dashboard/dist/assets/{RolePill-D3hkAdKf.js → RolePill-BjD1Qw5y.js} +2 -2
  220. package/dashboard/dist/assets/{RolePill-D3hkAdKf.js.map → RolePill-BjD1Qw5y.js.map} +1 -1
  221. package/dashboard/dist/assets/RolesPage-DqhHSvaw.js +2 -0
  222. package/dashboard/dist/assets/{RolesPage-CUP7EH5U.js.map → RolesPage-DqhHSvaw.js.map} +1 -1
  223. package/dashboard/dist/assets/{RosterWidget-DZtmQcjU.js → RosterWidget-BrIq61HR.js} +2 -2
  224. package/dashboard/dist/assets/{RosterWidget-DZtmQcjU.js.map → RosterWidget-BrIq61HR.js.map} +1 -1
  225. package/dashboard/dist/assets/RunAsSelector-D6zQrCNr.js +2 -0
  226. package/dashboard/dist/assets/{RunAsSelector-B9-1vgZr.js.map → RunAsSelector-D6zQrCNr.js.map} +1 -1
  227. package/dashboard/dist/assets/ScanCodesPage-B2S9DR2f.js +2 -0
  228. package/dashboard/dist/assets/{ScanCodesPage-KN_e2rJl.js.map → ScanCodesPage-B2S9DR2f.js.map} +1 -1
  229. package/dashboard/dist/assets/ScanSchemeDetailPage-gpxKN-pL.js +5 -0
  230. package/dashboard/dist/assets/ScanSchemeDetailPage-gpxKN-pL.js.map +1 -0
  231. package/dashboard/dist/assets/ScanStationPage-B-UTgXsG.js +2 -0
  232. package/dashboard/dist/assets/{ScanStationPage-B0qbUOwc.js.map → ScanStationPage-B-UTgXsG.js.map} +1 -1
  233. package/dashboard/dist/assets/{SchemeMatchFields-CL7TKnw3.js → SchemeMatchFields-BK24aa7K.js} +2 -2
  234. package/dashboard/dist/assets/{SchemeMatchFields-CL7TKnw3.js.map → SchemeMatchFields-BK24aa7K.js.map} +1 -1
  235. package/dashboard/dist/assets/{ScopeBadge-DGz79rmG.js → ScopeBadge-ofLQ6HW-.js} +2 -2
  236. package/dashboard/dist/assets/{ScopeBadge-DGz79rmG.js.map → ScopeBadge-ofLQ6HW-.js.map} +1 -1
  237. package/dashboard/dist/assets/{StickyPagination-CUwxfBQH.js → StickyPagination-CgVv7vc_.js} +2 -2
  238. package/dashboard/dist/assets/{StickyPagination-CUwxfBQH.js.map → StickyPagination-CgVv7vc_.js.map} +1 -1
  239. package/dashboard/dist/assets/{StreamMessageDetail-DOjcO7d2.js → StreamMessageDetail-B9sxDVw4.js} +2 -2
  240. package/dashboard/dist/assets/{StreamMessageDetail-DOjcO7d2.js.map → StreamMessageDetail-B9sxDVw4.js.map} +1 -1
  241. package/dashboard/dist/assets/{SwimlaneTimeline-SPMpoLHP.js → SwimlaneTimeline-DQc0CYSL.js} +2 -2
  242. package/dashboard/dist/assets/{SwimlaneTimeline-SPMpoLHP.js.map → SwimlaneTimeline-DQc0CYSL.js.map} +1 -1
  243. package/dashboard/dist/assets/{TagInput-DaIdhv3h.js → TagInput-47qVYzke.js} +2 -2
  244. package/dashboard/dist/assets/{TagInput-DaIdhv3h.js.map → TagInput-47qVYzke.js.map} +1 -1
  245. package/dashboard/dist/assets/{TaskDetailPage-DvfzR2IQ.js → TaskDetailPage-D6VOsA1f.js} +2 -2
  246. package/dashboard/dist/assets/{TaskDetailPage-DvfzR2IQ.js.map → TaskDetailPage-D6VOsA1f.js.map} +1 -1
  247. package/dashboard/dist/assets/{TaskQueuePill-sUA1nZe-.js → TaskQueuePill-C5KmdXAl.js} +2 -2
  248. package/dashboard/dist/assets/{TaskQueuePill-sUA1nZe-.js.map → TaskQueuePill-C5KmdXAl.js.map} +1 -1
  249. package/dashboard/dist/assets/{TasksListPage-Jp6wmL7t.js → TasksListPage-DG8hvO8G.js} +2 -2
  250. package/dashboard/dist/assets/{TasksListPage-Jp6wmL7t.js.map → TasksListPage-DG8hvO8G.js.map} +1 -1
  251. package/dashboard/dist/assets/{TimeAgo-BCQA0Gb_.js → TimeAgo-CL02EhFi.js} +2 -2
  252. package/dashboard/dist/assets/{TimeAgo-BCQA0Gb_.js.map → TimeAgo-CL02EhFi.js.map} +1 -1
  253. package/dashboard/dist/assets/{TimestampCell-xhdMHDQt.js → TimestampCell-BE7oKVJg.js} +2 -2
  254. package/dashboard/dist/assets/{TimestampCell-xhdMHDQt.js.map → TimestampCell-BE7oKVJg.js.map} +1 -1
  255. package/dashboard/dist/assets/{ToolPill-CpBAFdEX.js → ToolPill-Cp9Drk1s.js} +2 -2
  256. package/dashboard/dist/assets/{ToolPill-CpBAFdEX.js.map → ToolPill-Cp9Drk1s.js.map} +1 -1
  257. package/dashboard/dist/assets/{ToolTestPanel-D8M3ITrJ.js → ToolTestPanel-CRecLh6S.js} +2 -2
  258. package/dashboard/dist/assets/{ToolTestPanel-D8M3ITrJ.js.map → ToolTestPanel-CRecLh6S.js.map} +1 -1
  259. package/dashboard/dist/assets/{TopicDetailPage-DdBJQp31.js → TopicDetailPage-QzkinTfN.js} +3 -3
  260. package/dashboard/dist/assets/{TopicDetailPage-DdBJQp31.js.map → TopicDetailPage-QzkinTfN.js.map} +1 -1
  261. package/dashboard/dist/assets/{TopicsPage-vpvsynD9.js → TopicsPage-D8dW6J65.js} +2 -2
  262. package/dashboard/dist/assets/{TopicsPage-vpvsynD9.js.map → TopicsPage-D8dW6J65.js.map} +1 -1
  263. package/dashboard/dist/assets/{UserName-BK6Lzsdw.js → UserName-Dw3R_zrl.js} +2 -2
  264. package/dashboard/dist/assets/{UserName-BK6Lzsdw.js.map → UserName-Dw3R_zrl.js.map} +1 -1
  265. package/dashboard/dist/assets/WorkflowExecutionPage-BTocv8or.js +2 -0
  266. package/dashboard/dist/assets/{WorkflowExecutionPage-DkM1TS4I.js.map → WorkflowExecutionPage-BTocv8or.js.map} +1 -1
  267. package/dashboard/dist/assets/{WorkflowPill-CKHip3hH.js → WorkflowPill-BiLYq__w.js} +2 -2
  268. package/dashboard/dist/assets/{WorkflowPill-CKHip3hH.js.map → WorkflowPill-BiLYq__w.js.map} +1 -1
  269. package/dashboard/dist/assets/WorkflowsDashboard-CIPEt3et.js +2 -0
  270. package/dashboard/dist/assets/{WorkflowsDashboard-g_N4y3QS.js.map → WorkflowsDashboard-CIPEt3et.js.map} +1 -1
  271. package/dashboard/dist/assets/{WorkflowsOverview-Drjo-Lu-.js → WorkflowsOverview-Bj4MJIE-.js} +2 -2
  272. package/dashboard/dist/assets/{WorkflowsOverview-Drjo-Lu-.js.map → WorkflowsOverview-Bj4MJIE-.js.map} +1 -1
  273. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CLltNHjZ.js → YamlWorkflowDetailPage-DMEk5k9-.js} +2 -2
  274. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CLltNHjZ.js.map → YamlWorkflowDetailPage-DMEk5k9-.js.map} +1 -1
  275. package/dashboard/dist/assets/{YamlWorkflowsPage-CxQCB-Zi.js → YamlWorkflowsPage-F2yyyoiB.js} +2 -2
  276. package/dashboard/dist/assets/{YamlWorkflowsPage-CxQCB-Zi.js.map → YamlWorkflowsPage-F2yyyoiB.js.map} +1 -1
  277. package/dashboard/dist/assets/{agents-Dk25jjhj.js → agents-mSgxEPpI.js} +2 -2
  278. package/dashboard/dist/assets/{agents-Dk25jjhj.js.map → agents-mSgxEPpI.js.map} +1 -1
  279. package/dashboard/dist/assets/{bots-bRkCqhlq.js → bots-p4Hp0CV6.js} +2 -2
  280. package/dashboard/dist/assets/{bots-bRkCqhlq.js.map → bots-p4Hp0CV6.js.map} +1 -1
  281. package/dashboard/dist/assets/{capabilities-DARawLry.js → capabilities-D_-I_SXR.js} +2 -2
  282. package/dashboard/dist/assets/{capabilities-DARawLry.js.map → capabilities-D_-I_SXR.js.map} +1 -1
  283. package/dashboard/dist/assets/{controlplane-DKccxxs6.js → controlplane-DjdoQnRU.js} +2 -2
  284. package/dashboard/dist/assets/{controlplane-DKccxxs6.js.map → controlplane-DjdoQnRU.js.map} +1 -1
  285. package/dashboard/dist/assets/{escalation-columns-BaYuzMYf.js → escalation-columns-R_IEVQjQ.js} +2 -2
  286. package/dashboard/dist/assets/{escalation-columns-BaYuzMYf.js.map → escalation-columns-R_IEVQjQ.js.map} +1 -1
  287. package/dashboard/dist/assets/{escalation-items-CwbNFnsH.js → escalation-items-BGZlJMpk.js} +2 -2
  288. package/dashboard/dist/assets/{escalation-items-CwbNFnsH.js.map → escalation-items-BGZlJMpk.js.map} +1 -1
  289. package/dashboard/dist/assets/{index-Cf6qCgTf.js → index-BEMdD58x.js} +2 -2
  290. package/dashboard/dist/assets/{index-Cf6qCgTf.js.map → index-BEMdD58x.js.map} +1 -1
  291. package/dashboard/dist/assets/index-BUmz0NMg.css +1 -0
  292. package/dashboard/dist/assets/{index-hKOlahpE.js → index-BuCEhhnl.js} +2 -2
  293. package/dashboard/dist/assets/{index-hKOlahpE.js.map → index-BuCEhhnl.js.map} +1 -1
  294. package/dashboard/dist/assets/{index-D1uliPqS.js → index-BxbQmeqh.js} +2 -2
  295. package/dashboard/dist/assets/{index-D1uliPqS.js.map → index-BxbQmeqh.js.map} +1 -1
  296. package/dashboard/dist/assets/index-C5osluV3.js +2 -0
  297. package/dashboard/dist/assets/{index-CtrSYqmL.js.map → index-C5osluV3.js.map} +1 -1
  298. package/dashboard/dist/assets/{index-CU2UW2y6.js → index-C_dAJUzh.js} +25 -25
  299. package/dashboard/dist/assets/index-C_dAJUzh.js.map +1 -0
  300. package/dashboard/dist/assets/{index-Bx9HVzuT.js → index-D-FYj9jT.js} +2 -2
  301. package/dashboard/dist/assets/{index-Bx9HVzuT.js.map → index-D-FYj9jT.js.map} +1 -1
  302. package/dashboard/dist/assets/{index-BZgtzkkG.js → index-D6K_IgCz.js} +2 -2
  303. package/dashboard/dist/assets/{index-BZgtzkkG.js.map → index-D6K_IgCz.js.map} +1 -1
  304. package/dashboard/dist/assets/index-D7L_VoBD.js +2 -0
  305. package/dashboard/dist/assets/index-D7L_VoBD.js.map +1 -0
  306. package/dashboard/dist/assets/{index-DgpL_Lgc.js → index-D9RAN9sA.js} +2 -2
  307. package/dashboard/dist/assets/{index-DgpL_Lgc.js.map → index-D9RAN9sA.js.map} +1 -1
  308. package/dashboard/dist/assets/{index-dShcvdg3.js → index-DUYAGxwc.js} +2 -2
  309. package/dashboard/dist/assets/{index-dShcvdg3.js.map → index-DUYAGxwc.js.map} +1 -1
  310. package/dashboard/dist/assets/{index-E_hJ7vtX.js → index-Dk2KKo0z.js} +2 -2
  311. package/dashboard/dist/assets/{index-E_hJ7vtX.js.map → index-Dk2KKo0z.js.map} +1 -1
  312. package/dashboard/dist/assets/{index-DU2QCbgH.js → index-DlJkZ12b.js} +2 -2
  313. package/dashboard/dist/assets/{index-DU2QCbgH.js.map → index-DlJkZ12b.js.map} +1 -1
  314. package/dashboard/dist/assets/{index-kzifJWbM.js → index-FiNThtNU.js} +3 -3
  315. package/dashboard/dist/assets/{index-kzifJWbM.js.map → index-FiNThtNU.js.map} +1 -1
  316. package/dashboard/dist/assets/{knowledge-DOe5ks-E.js → knowledge-DSsPTqkK.js} +2 -2
  317. package/dashboard/dist/assets/{knowledge-DOe5ks-E.js.map → knowledge-DSsPTqkK.js.map} +1 -1
  318. package/dashboard/dist/assets/{machines-Zq_00v7k.js → machines-DSgGtqqr.js} +2 -2
  319. package/dashboard/dist/assets/{machines-Zq_00v7k.js.map → machines-DSgGtqqr.js.map} +1 -1
  320. package/dashboard/dist/assets/{mcp-BL8kD0oh.js → mcp-Cg-_uLw8.js} +2 -2
  321. package/dashboard/dist/assets/{mcp-BL8kD0oh.js.map → mcp-Cg-_uLw8.js.map} +1 -1
  322. package/dashboard/dist/assets/{mcp-query-BpokmJWi.js → mcp-query-DQombEK_.js} +2 -2
  323. package/dashboard/dist/assets/{mcp-query-BpokmJWi.js.map → mcp-query-DQombEK_.js.map} +1 -1
  324. package/dashboard/dist/assets/{personas-BubCnQZ8.js → personas-DYrcoVBu.js} +2 -2
  325. package/dashboard/dist/assets/{personas-BubCnQZ8.js.map → personas-DYrcoVBu.js.map} +1 -1
  326. package/dashboard/dist/assets/{pipelines--DUoMx7K.js → pipelines-wdb4xsey.js} +2 -2
  327. package/dashboard/dist/assets/{pipelines--DUoMx7K.js.map → pipelines-wdb4xsey.js.map} +1 -1
  328. package/dashboard/dist/assets/{tasks-CJXN4OB4.js → tasks-Bil7gvm9.js} +2 -2
  329. package/dashboard/dist/assets/{tasks-CJXN4OB4.js.map → tasks-Bil7gvm9.js.map} +1 -1
  330. package/dashboard/dist/assets/{topics-CAG08Ruo.js → topics-wBqaVhRR.js} +2 -2
  331. package/dashboard/dist/assets/{topics-CAG08Ruo.js.map → topics-wBqaVhRR.js.map} +1 -1
  332. package/dashboard/dist/assets/{useDebouncedValue-DQ2D8cm2.js → useDebouncedValue-CwrY8TpV.js} +2 -2
  333. package/dashboard/dist/assets/{useDebouncedValue-DQ2D8cm2.js.map → useDebouncedValue-CwrY8TpV.js.map} +1 -1
  334. package/dashboard/dist/assets/{useNamespace-DjEVAlJQ.js → useNamespace-Sod_xApz.js} +2 -2
  335. package/dashboard/dist/assets/{useNamespace-DjEVAlJQ.js.map → useNamespace-Sod_xApz.js.map} +1 -1
  336. package/dashboard/dist/assets/{useYamlActivityEvents-etcpfIwo.js → useYamlActivityEvents-CKLInV3C.js} +2 -2
  337. package/dashboard/dist/assets/{useYamlActivityEvents-etcpfIwo.js.map → useYamlActivityEvents-CKLInV3C.js.map} +1 -1
  338. package/dashboard/dist/assets/{validate-YJK_6a7m.js → validate-CYhW1xMJ.js} +2 -2
  339. package/dashboard/dist/assets/{validate-YJK_6a7m.js.map → validate-CYhW1xMJ.js.map} +1 -1
  340. package/dashboard/dist/assets/{vendor-icons-en0_uSRD.js → vendor-icons-ed7mYQw4.js} +2 -2
  341. package/dashboard/dist/assets/{vendor-icons-en0_uSRD.js.map → vendor-icons-ed7mYQw4.js.map} +1 -1
  342. package/dashboard/dist/assets/{yaml-workflows-D97Bz6li.js → yaml-workflows-C20qHo3L.js} +2 -2
  343. package/dashboard/dist/assets/{yaml-workflows-D97Bz6li.js.map → yaml-workflows-C20qHo3L.js.map} +1 -1
  344. package/dashboard/dist/index.html +3 -3
  345. package/docs/api/http/labels.md +115 -0
  346. package/docs/api/http/users.md +2 -0
  347. package/docs/api/mcp/admin.md +76 -1
  348. package/docs/code-owned-configuration.md +1 -1
  349. package/docs/iam.md +12 -0
  350. package/docs/label-sheets.md +267 -0
  351. package/docs/machines.md +2 -2
  352. package/docs/scan-codes.md +11 -5
  353. package/package.json +4 -1
  354. package/dashboard/dist/assets/AvailableEscalationsPage-BRKyG5qZ.js +0 -2
  355. package/dashboard/dist/assets/AvailableEscalationsPage-BRKyG5qZ.js.map +0 -1
  356. package/dashboard/dist/assets/BulkAssignModal-BWfzPrRk.js +0 -2
  357. package/dashboard/dist/assets/HomePage-BUlSnCg8.js +0 -2
  358. package/dashboard/dist/assets/McpRunDetailPage-BHVEcKV5.js +0 -2
  359. package/dashboard/dist/assets/OperatorDashboard-CMkgMewd.js +0 -2
  360. package/dashboard/dist/assets/PersonaDetailPage-Cs1FFdNq.js +0 -2
  361. package/dashboard/dist/assets/RolesPage-CUP7EH5U.js +0 -2
  362. package/dashboard/dist/assets/RunAsSelector-B9-1vgZr.js +0 -2
  363. package/dashboard/dist/assets/ScanCodesPage-KN_e2rJl.js +0 -2
  364. package/dashboard/dist/assets/ScanSchemeDetailPage-CqItQ67Y.js +0 -5
  365. package/dashboard/dist/assets/ScanSchemeDetailPage-CqItQ67Y.js.map +0 -1
  366. package/dashboard/dist/assets/ScanStationPage-B0qbUOwc.js +0 -2
  367. package/dashboard/dist/assets/WorkflowExecutionPage-DkM1TS4I.js +0 -2
  368. package/dashboard/dist/assets/WorkflowsDashboard-g_N4y3QS.js +0 -2
  369. package/dashboard/dist/assets/index-BmzscsXK.css +0 -1
  370. package/dashboard/dist/assets/index-CU2UW2y6.js.map +0 -1
  371. package/dashboard/dist/assets/index-CtrSYqmL.js +0 -2
  372. package/dashboard/dist/assets/index-DU-1gMks.js +0 -2
  373. package/dashboard/dist/assets/index-DU-1gMks.js.map +0 -1
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The label transport registry: named routes from issued labels to printers,
3
+ * registered at startup. Sending is a capability, not a side effect, so a
4
+ * name with no transport fails loudly instead of printing nothing.
5
+ */
6
+ import type { LTLabelTransport } from '../../types/labels';
7
+ export declare const LABEL_TRANSPORT_NOT_CONFIGURED = "No label transport is registered under that name; pass start({ labels: { transports } })";
8
+ declare class LTLabelTransportRegistry {
9
+ private transports;
10
+ /** Register a transport by name; replaces one registered before under the same name. */
11
+ register(name: string, transport: LTLabelTransport): void;
12
+ has(name: string): boolean;
13
+ /** The registered transports, by name, with the formats each accepts. */
14
+ list(): Array<{
15
+ name: string;
16
+ formats: LTLabelTransport['formats'];
17
+ }>;
18
+ get(name: string): LTLabelTransport;
19
+ /** Forget every transport (tests). */
20
+ clear(): void;
21
+ }
22
+ export declare const labelTransportRegistry: LTLabelTransportRegistry;
23
+ export {};
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ /**
3
+ * The label transport registry: named routes from issued labels to printers,
4
+ * registered at startup. Sending is a capability, not a side effect, so a
5
+ * name with no transport fails loudly instead of printing nothing.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.labelTransportRegistry = exports.LABEL_TRANSPORT_NOT_CONFIGURED = void 0;
9
+ exports.LABEL_TRANSPORT_NOT_CONFIGURED = 'No label transport is registered under that name; pass start({ labels: { transports } })';
10
+ class LTLabelTransportRegistry {
11
+ constructor() {
12
+ this.transports = new Map();
13
+ }
14
+ /** Register a transport by name; replaces one registered before under the same name. */
15
+ register(name, transport) {
16
+ if (!/^[a-z0-9][a-z0-9-]{0,62}$/.test(name)) {
17
+ throw new Error(`label transport name "${name}" must be lowercase letters, digits and dashes`);
18
+ }
19
+ this.transports.set(name, transport);
20
+ }
21
+ has(name) {
22
+ return this.transports.has(name);
23
+ }
24
+ /** The registered transports, by name, with the formats each accepts. */
25
+ list() {
26
+ return [...this.transports].map(([name, t]) => ({ name, formats: [...t.formats] }));
27
+ }
28
+ get(name) {
29
+ const transport = this.transports.get(name);
30
+ if (!transport)
31
+ throw new Error(`${exports.LABEL_TRANSPORT_NOT_CONFIGURED} (asked for "${name}")`);
32
+ return transport;
33
+ }
34
+ /** Forget every transport (tests). */
35
+ clear() {
36
+ this.transports.clear();
37
+ }
38
+ }
39
+ exports.labelTransportRegistry = new LTLabelTransportRegistry();
@@ -57,6 +57,8 @@ export declare const requireAdmin: RequestHandler<import("express-serve-static-c
57
57
  export declare const requireBuilder: RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
58
58
  /** Role-management access: admin access or the 'engineer' role. Backend twin of `isBuilder || isOps`. */
59
59
  export declare const requireRoleManager: RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
60
+ /** Credential access: superadmin or the 'credential-issuer' role. Gates badge printing and reissue. */
61
+ export declare const requireCredentialIssuer: RequestHandler<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>;
60
62
  /** Reads of one workflow run (`:workflowId`): builder access, or the person who started it or it runs as. */
61
63
  export declare const requireWorkflowReader: RequestHandler;
62
64
  /**
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.requireWorkflowReader = exports.requireRoleManager = exports.requireBuilder = exports.requireAdmin = exports.requireCredentialAuth = exports.requireAuth = exports.JwtAuthAdapter = void 0;
6
+ exports.requireWorkflowReader = exports.requireCredentialIssuer = exports.requireRoleManager = exports.requireBuilder = exports.requireAdmin = exports.requireCredentialAuth = exports.requireAuth = exports.JwtAuthAdapter = void 0;
7
7
  exports.createAuthMiddleware = createAuthMiddleware;
8
8
  exports.setAuthAdapter = setAuthAdapter;
9
9
  exports.signToken = signToken;
@@ -201,6 +201,8 @@ exports.requireAdmin = requireCapability(capabilities_1.mayAdminister, 'Forbidde
201
201
  exports.requireBuilder = requireCapability(capabilities_1.mayBuild, 'Forbidden: builder access required');
202
202
  /** Role-management access: admin access or the 'engineer' role. Backend twin of `isBuilder || isOps`. */
203
203
  exports.requireRoleManager = requireCapability(capabilities_1.mayManageRoles, 'Forbidden: role-management access required');
204
+ /** Credential access: superadmin or the 'credential-issuer' role. Gates badge printing and reissue. */
205
+ exports.requireCredentialIssuer = requireCapability(capabilities_1.mayIssueCredentials, 'Forbidden: credential-issuer access required');
204
206
  /** Reads of one workflow run (`:workflowId`): builder access, or the person who started it or it runs as. */
205
207
  const requireWorkflowReader = async (req, res, next) => {
206
208
  try {
@@ -19,10 +19,14 @@ export type GrantDecision = {
19
19
  allowed: false;
20
20
  error: string;
21
21
  };
22
+ /** Holders of this role may print and reissue identity credentials (badges). */
23
+ export declare const CREDENTIAL_ISSUER_ROLE = "credential-issuer";
22
24
  /** Admin or superadmin claim, or a superadmin in the database. */
23
25
  export declare function mayAdminister(principal: CapabilityPrincipal | undefined): Promise<boolean>;
24
26
  /** Superadmin (claim or database), or holder of the engineer role. */
25
27
  export declare function mayBuild(principal: CapabilityPrincipal | undefined): Promise<boolean>;
28
+ /** Superadmin (claim or database), or holder of the credential-issuer role. Admin type alone never grants it. */
29
+ export declare function mayIssueCredentials(principal: CapabilityPrincipal | undefined): Promise<boolean>;
26
30
  /**
27
31
  * Builder access, or the person a workflow run was started by or runs as,
28
32
  * read from the run's own start envelope.
@@ -51,7 +55,7 @@ export declare function mayRevokeRole(callerId: string, targetId: string, role:
51
55
  /**
52
56
  * Every capability the principal holds, with the same outcomes as the
53
57
  * predicates above. A superadmin claim costs no lookup; anyone else costs
54
- * at most one superadmin lookup and one engineer-role lookup.
58
+ * at most one superadmin lookup and two role lookups.
55
59
  */
56
60
  export declare function resolveCapabilities(principal: CapabilityPrincipal | undefined): Promise<CapabilitySet>;
57
61
  /**
@@ -33,8 +33,10 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CREDENTIAL_ISSUER_ROLE = void 0;
36
37
  exports.mayAdminister = mayAdminister;
37
38
  exports.mayBuild = mayBuild;
39
+ exports.mayIssueCredentials = mayIssueCredentials;
38
40
  exports.mayReadWorkflowRun = mayReadWorkflowRun;
39
41
  exports.mayManageRoles = mayManageRoles;
40
42
  exports.mayGrantRole = mayGrantRole;
@@ -47,9 +49,14 @@ const user_1 = require("../services/user");
47
49
  const export_1 = require("../services/export");
48
50
  const uuid_1 = require("../lib/uuid");
49
51
  const BUILDER_ROLE = 'engineer';
50
- async function hasBuilderRole(userId) {
52
+ /** Holders of this role may print and reissue identity credentials (badges). */
53
+ exports.CREDENTIAL_ISSUER_ROLE = 'credential-issuer';
54
+ async function holdsRole(userId, role) {
51
55
  const { hasRole } = await Promise.resolve().then(() => __importStar(require('../services/user/roles')));
52
- return hasRole(userId, BUILDER_ROLE);
56
+ return hasRole(userId, role);
57
+ }
58
+ async function hasBuilderRole(userId) {
59
+ return holdsRole(userId, BUILDER_ROLE);
53
60
  }
54
61
  /** Admin or superadmin claim, or a superadmin in the database. */
55
62
  async function mayAdminister(principal) {
@@ -69,6 +76,18 @@ async function mayBuild(principal) {
69
76
  return true;
70
77
  return hasBuilderRole(principal.userId);
71
78
  }
79
+ /** Superadmin (claim or database), or holder of the credential-issuer role. Admin type alone never grants it. */
80
+ async function mayIssueCredentials(principal) {
81
+ if (!principal?.userId)
82
+ return false;
83
+ if (principal.grantRoles)
84
+ return capabilitiesFromRoles(principal.grantRoles).credentialIssuer;
85
+ if (principal.role === 'superadmin')
86
+ return true;
87
+ if (await (0, user_1.isSuperAdmin)(principal.userId))
88
+ return true;
89
+ return holdsRole(principal.userId, exports.CREDENTIAL_ISSUER_ROLE);
90
+ }
72
91
  /**
73
92
  * Builder access, or the person a workflow run was started by or runs as,
74
93
  * read from the run's own start envelope.
@@ -148,15 +167,19 @@ function capabilitiesFromRoles(roles) {
148
167
  const superadmin = roles.some((r) => r.type === 'superadmin');
149
168
  const admin = superadmin || roles.some((r) => r.type === 'admin');
150
169
  const engineer = roles.some((r) => r.role === BUILDER_ROLE);
151
- return { caller: true, admin, builder: superadmin || engineer, roleManager: admin || engineer, superadmin };
170
+ const issuer = roles.some((r) => r.role === exports.CREDENTIAL_ISSUER_ROLE);
171
+ return {
172
+ caller: true, admin, builder: superadmin || engineer, roleManager: admin || engineer, superadmin,
173
+ credentialIssuer: superadmin || issuer,
174
+ };
152
175
  }
153
176
  const NO_CAPABILITIES = {
154
- caller: false, admin: false, builder: false, roleManager: false, superadmin: false,
177
+ caller: false, admin: false, builder: false, roleManager: false, superadmin: false, credentialIssuer: false,
155
178
  };
156
179
  /**
157
180
  * Every capability the principal holds, with the same outcomes as the
158
181
  * predicates above. A superadmin claim costs no lookup; anyone else costs
159
- * at most one superadmin lookup and one engineer-role lookup.
182
+ * at most one superadmin lookup and two role lookups.
160
183
  */
161
184
  async function resolveCapabilities(principal) {
162
185
  if (!principal?.userId)
@@ -164,11 +187,18 @@ async function resolveCapabilities(principal) {
164
187
  if (principal.grantRoles)
165
188
  return capabilitiesFromRoles(principal.grantRoles);
166
189
  if (principal.role === 'superadmin' || (await (0, user_1.isSuperAdmin)(principal.userId))) {
167
- return { caller: true, admin: true, builder: true, roleManager: true, superadmin: true };
190
+ return { caller: true, admin: true, builder: true, roleManager: true, superadmin: true, credentialIssuer: true };
168
191
  }
169
192
  const admin = principal.role === 'admin';
170
- const engineer = await hasBuilderRole(principal.userId);
171
- return { caller: true, admin, builder: engineer, roleManager: admin || engineer, superadmin: false };
193
+ const { hasRole } = await Promise.resolve().then(() => __importStar(require('../services/user/roles')));
194
+ const [engineer, issuer] = await Promise.all([
195
+ hasRole(principal.userId, BUILDER_ROLE),
196
+ hasRole(principal.userId, exports.CREDENTIAL_ISSUER_ROLE),
197
+ ]);
198
+ return {
199
+ caller: true, admin, builder: engineer, roleManager: admin || engineer, superadmin: false,
200
+ credentialIssuer: issuer,
201
+ };
172
202
  }
173
203
  /**
174
204
  * Capability checks for one request. `caller` needs only an authenticated
@@ -41,5 +41,15 @@ export declare const config: {
41
41
  LT_ANALYTICS_CACHE_TTL_MS: number;
42
42
  LT_ANALYTICS_PAST_CACHE_TTL_MS: number;
43
43
  LT_ANALYTICS_CACHE_MAX_ENTRIES: number;
44
+ /** Identity keys (badge tokens) leave user reads and need credentialIssuer to write. `false` keeps the earlier behavior. */
45
+ LT_PROTECT_IDENTITY_KEYS: boolean;
46
+ /** Label sheets: the media a job prints on when neither the job nor the template names one. */
47
+ LT_LABELS_DEFAULT_MEDIA: string;
48
+ /** Most labels one print job may hold. */
49
+ LT_LABELS_MAX_PER_JOB: number;
50
+ /** Most identity credentials (badges) one print job may hold. */
51
+ LT_LABELS_MAX_CREDENTIALS_PER_JOB: number;
52
+ /** How long one process holds a print job's delivery before a retry may send it. */
53
+ LT_LABELS_DELIVERY_LEASE_SECONDS: number;
44
54
  };
45
55
  export declare const postgres_options: Record<string, unknown>;
@@ -67,6 +67,16 @@ exports.config = {
67
67
  LT_ANALYTICS_CACHE_TTL_MS: parseInt(process.env.LT_ANALYTICS_CACHE_TTL_MS || '30000', 10),
68
68
  LT_ANALYTICS_PAST_CACHE_TTL_MS: parseInt(process.env.LT_ANALYTICS_PAST_CACHE_TTL_MS || '600000', 10),
69
69
  LT_ANALYTICS_CACHE_MAX_ENTRIES: parseInt(process.env.LT_ANALYTICS_CACHE_MAX_ENTRIES || '512', 10),
70
+ /** Identity keys (badge tokens) leave user reads and need credentialIssuer to write. `false` keeps the earlier behavior. */
71
+ LT_PROTECT_IDENTITY_KEYS: process.env.LT_PROTECT_IDENTITY_KEYS !== 'false',
72
+ /** Label sheets: the media a job prints on when neither the job nor the template names one. */
73
+ LT_LABELS_DEFAULT_MEDIA: process.env.LT_LABELS_DEFAULT_MEDIA || 'a4-l7160',
74
+ /** Most labels one print job may hold. */
75
+ LT_LABELS_MAX_PER_JOB: positiveInt('LT_LABELS_MAX_PER_JOB', 1000),
76
+ /** Most identity credentials (badges) one print job may hold. */
77
+ LT_LABELS_MAX_CREDENTIALS_PER_JOB: positiveInt('LT_LABELS_MAX_CREDENTIALS_PER_JOB', 200),
78
+ /** How long one process holds a print job's delivery before a retry may send it. */
79
+ LT_LABELS_DELIVERY_LEASE_SECONDS: positiveInt('LT_LABELS_DELIVERY_LEASE_SECONDS', 120),
70
80
  };
71
81
  exports.postgres_options = {
72
82
  host: exports.config.POSTGRES_HOST,
@@ -38,6 +38,7 @@ const capabilities_1 = __importDefault(require("./capabilities"));
38
38
  const topics_1 = __importDefault(require("./topics"));
39
39
  const nats_credentials_1 = __importDefault(require("./nats-credentials"));
40
40
  const scan_codes_1 = __importDefault(require("./scan-codes"));
41
+ const labels_1 = __importDefault(require("./labels"));
41
42
  const domain_1 = __importDefault(require("./domain"));
42
43
  const announcements_1 = __importDefault(require("./announcements"));
43
44
  const machines_1 = __importDefault(require("./machines"));
@@ -79,6 +80,7 @@ router.use('/agents', agents_1.default);
79
80
  router.use('/capabilities', capabilities_1.default);
80
81
  router.use('/topics', topics_1.default);
81
82
  router.use('/scan-codes', scan_codes_1.default);
83
+ router.use('/labels', labels_1.default);
82
84
  router.use('/domain', domain_1.default);
83
85
  router.use('/announcements', announcements_1.default);
84
86
  router.use('/machines', machines_1.default);
@@ -0,0 +1,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const http_1 = require("../lib/http");
37
+ const api = __importStar(require("../api/labels"));
38
+ const auth_1 = require("../modules/auth");
39
+ const router = (0, http_1.Router)();
40
+ /** An issue result: PDF and ZPL as files, a sheet as JSON. Codes are never cached. */
41
+ function sendIssued(res, result) {
42
+ res.set('Cache-Control', 'no-store');
43
+ if (result.status !== 200) {
44
+ res.status(result.status).json({ error: result.error });
45
+ return;
46
+ }
47
+ const { pdf, zpl, ...rest } = result.data;
48
+ res.set('X-LT-Label-Job', rest.job.id);
49
+ if (rest.warnings?.length)
50
+ res.set('X-LT-Label-Warnings', String(rest.warnings.length));
51
+ if (pdf) {
52
+ res.type('application/pdf').set('Content-Disposition', `attachment; filename="labels-${rest.job.id}.pdf"`).send(Buffer.from(pdf));
53
+ return;
54
+ }
55
+ if (zpl) {
56
+ res.type('application/vnd.zebra-zpl').set('Content-Disposition', `attachment; filename="labels-${rest.job.id}.zpl"`).send(zpl);
57
+ return;
58
+ }
59
+ res.json(rest);
60
+ }
61
+ // ── Templates ─────────────────────────────────────────────────────────────
62
+ /** GET /api/labels/templates?scheme=14 */
63
+ router.get('/templates', async (req, res) => {
64
+ const scheme = req.query.scheme ? Number(req.query.scheme) : undefined;
65
+ const result = await api.listLabelTemplates({ scheme });
66
+ res.status(result.status).json(result.data ?? { error: result.error });
67
+ });
68
+ /** GET /api/labels/templates/:name */
69
+ router.get('/templates/:name', async (req, res) => {
70
+ const result = await api.getLabelTemplate({ name: String(req.params.name) });
71
+ res.status(result.status).json(result.data ?? { error: result.error });
72
+ });
73
+ /** PUT /api/labels/templates/:name — body is the template; `expected_revision` guards a concurrent edit. */
74
+ router.put('/templates/:name', auth_1.requireRoleManager, async (req, res) => {
75
+ const result = await api.upsertLabelTemplate({ ...(req.body || {}), name: String(req.params.name) });
76
+ res.status(result.status).json(result.data ?? { error: result.error });
77
+ });
78
+ /** DELETE /api/labels/templates/:name */
79
+ router.delete('/templates/:name', auth_1.requireRoleManager, async (req, res) => {
80
+ const result = await api.deleteLabelTemplate({ name: String(req.params.name) });
81
+ res.status(result.status).json(result.data ?? { error: result.error });
82
+ });
83
+ /** GET /api/labels/media — presets and the default media. */
84
+ router.get('/media', async (_req, res) => {
85
+ const result = await api.listLabelMedia();
86
+ res.status(result.status).json(result.data);
87
+ });
88
+ /** GET /api/labels/transports — registered printer transports. */
89
+ router.get('/transports', async (_req, res) => {
90
+ const result = await api.listLabelTransports();
91
+ res.status(result.status).json(result.data);
92
+ });
93
+ // ── Print ─────────────────────────────────────────────────────────────────
94
+ /** POST /api/labels/preview — { template, source, layout? }. Sensitive templates come back masked. */
95
+ router.post('/preview', async (req, res) => {
96
+ const { template, source, layout } = req.body || {};
97
+ const result = await api.previewLabels({ template, source, layout }, req.auth);
98
+ res.set('Cache-Control', 'no-store');
99
+ res.status(result.status).json(result.data ?? { error: result.error });
100
+ });
101
+ /**
102
+ * POST /api/labels/issue — { template, source, layout?, output, confirm?, idempotencyKey?, destination? }.
103
+ * output: sheet (JSON), pdf, zpl, or transport:<name>.
104
+ */
105
+ router.post('/issue', async (req, res) => {
106
+ const { template, source, layout, output, confirm, idempotencyKey, destination, only } = req.body || {};
107
+ sendIssued(res, await api.issueLabels({ template, source, layout, output, confirm, idempotencyKey, destination, only }, req.auth));
108
+ });
109
+ /** POST /api/labels/badges/reissue — { userId, template, layout?, output, confirm }. */
110
+ router.post('/badges/reissue', async (req, res) => {
111
+ const { userId, template, layout, output, confirm } = req.body || {};
112
+ sendIssued(res, await api.reissueBadge({ userId, template, layout, output, confirm }, req.auth));
113
+ });
114
+ // ── History ───────────────────────────────────────────────────────────────
115
+ /** GET /api/labels/jobs?template=&subjectUserId=&limit=&offset= */
116
+ router.get('/jobs', async (req, res) => {
117
+ const result = await api.listLabelJobs({
118
+ template: req.query.template,
119
+ subjectUserId: req.query.subjectUserId,
120
+ limit: req.query.limit ? Number(req.query.limit) : undefined,
121
+ offset: req.query.offset ? Number(req.query.offset) : undefined,
122
+ }, req.auth);
123
+ res.status(result.status).json(result.data ?? { error: result.error });
124
+ });
125
+ /** GET /api/labels/jobs/:id */
126
+ router.get('/jobs/:id', async (req, res) => {
127
+ const result = await api.getLabelJob({ id: String(req.params.id) }, req.auth);
128
+ res.status(result.status).json(result.data ?? { error: result.error });
129
+ });
130
+ /** POST /api/labels/jobs/:id/reprint — { indices?, output, layout?, confirm? } */
131
+ router.post('/jobs/:id/reprint', async (req, res) => {
132
+ const { indices, output, layout, confirm } = req.body || {};
133
+ sendIssued(res, await api.reprintLabelJob({ id: String(req.params.id), indices, output, layout, confirm }, req.auth));
134
+ });
135
+ exports.default = router;
@@ -127,7 +127,7 @@ router.patch('/:id/properties', auth_1.requireBuilder, async (req, res) => {
127
127
  set,
128
128
  remove,
129
129
  rename,
130
- });
130
+ }, req.auth);
131
131
  res.status(result.status).json(result.data ?? { error: result.error });
132
132
  });
133
133
  /**
@@ -6,10 +6,12 @@
6
6
  * npm run bambu:boat
7
7
  *
8
8
  * 1. Download the model once into files/.
9
- * 2. Scale it (BAMBU_BOAT_SCALE, 0.5 by default: about ten minutes on a P1S).
9
+ * 2. Scale it (BAMBU_BOAT_SCALE, 0.5 by default).
10
10
  * 3. Slice it with the printer, process and filament presets. Each is an
11
11
  * OrcaSlicer system preset name or a path to a preset JSON, which may
12
- * inherit a system preset by name.
12
+ * inherit a system preset by name. Unset, a P1S with a 0.4 nozzle and PLA;
13
+ * the presets in examples/workflows/bambu-printer/boat/presets slice the
14
+ * example's boat (0.8 nozzle, TPU, about 11 minutes).
13
15
  *
14
16
  * Env: BAMBU_BOAT_PRINTER, BAMBU_BOAT_PROCESS, BAMBU_BOAT_FILAMENT, BAMBU_BOAT_SCALE,
15
17
  * ORCA_SLICER (the OrcaSlicer executable) and ORCA_PROFILES (its BBL profiles directory).
@@ -7,10 +7,12 @@
7
7
  * npm run bambu:boat
8
8
  *
9
9
  * 1. Download the model once into files/.
10
- * 2. Scale it (BAMBU_BOAT_SCALE, 0.5 by default: about ten minutes on a P1S).
10
+ * 2. Scale it (BAMBU_BOAT_SCALE, 0.5 by default).
11
11
  * 3. Slice it with the printer, process and filament presets. Each is an
12
12
  * OrcaSlicer system preset name or a path to a preset JSON, which may
13
- * inherit a system preset by name.
13
+ * inherit a system preset by name. Unset, a P1S with a 0.4 nozzle and PLA;
14
+ * the presets in examples/workflows/bambu-printer/boat/presets slice the
15
+ * example's boat (0.8 nozzle, TPU, about 11 minutes).
14
16
  *
15
17
  * Env: BAMBU_BOAT_PRINTER, BAMBU_BOAT_PROCESS, BAMBU_BOAT_FILAMENT, BAMBU_BOAT_SCALE,
16
18
  * ORCA_SLICER (the OrcaSlicer executable) and ORCA_PROFILES (its BBL profiles directory).
@@ -10,7 +10,8 @@
10
10
  * 1. Put the file on the printer (it prints only files on its own storage) and hash it: the unit's artifact.
11
11
  * 2. Start the unit route: one print step at the station, then a person unloads.
12
12
  * 3. Print the route's rows and their lifecycle items as they change, until the
13
- * route ends. The unload row is resolved by a person on the dashboard.
13
+ * route ends. The unload row is resolved by a person on the dashboard, and
14
+ * so is a failed print's decision, on the line's operator role.
14
15
  *
15
16
  * Env: LT_USERNAME and LT_PASSWORD (a Long Tail login that may invoke the route), BASE_URL
16
17
  * (http://localhost:3000), BAMBU_SITE_DIR (deploy/bambu-site), and the printers in .env.
@@ -11,7 +11,8 @@
11
11
  * 1. Put the file on the printer (it prints only files on its own storage) and hash it: the unit's artifact.
12
12
  * 2. Start the unit route: one print step at the station, then a person unloads.
13
13
  * 3. Print the route's rows and their lifecycle items as they change, until the
14
- * route ends. The unload row is resolved by a person on the dashboard.
14
+ * route ends. The unload row is resolved by a person on the dashboard, and
15
+ * so is a failed print's decision, on the line's operator role.
15
16
  *
16
17
  * Env: LT_USERNAME and LT_PASSWORD (a Long Tail login that may invoke the route), BASE_URL
17
18
  * (http://localhost:3000), BAMBU_SITE_DIR (deploy/bambu-site), and the printers in .env.
@@ -27,6 +28,8 @@ const path_1 = require("path");
27
28
  const env_1 = require("../examples/workflows/bambu-printer/env");
28
29
  const files_1 = require("../examples/workflows/bambu-printer/files");
29
30
  const route_1 = require("../examples/workflows/machine-line/workflows/route");
31
+ const line_1 = require("../lib/machines/line");
32
+ const contracts_1 = require("../services/machines/contracts");
30
33
  const env = process.env;
31
34
  const BASE_URL = env.BASE_URL || 'http://localhost:3000';
32
35
  const SITE_DIR = env.BAMBU_SITE_DIR || 'deploy/bambu-site';
@@ -67,7 +70,8 @@ async function look(orderRef, workflowId, shown) {
67
70
  const facets = encodeURIComponent(JSON.stringify({ orderRef }));
68
71
  const { escalations } = await api('GET', `/escalations?facets=${facets}&limit=20&sort_by=created_at&order=asc`);
69
72
  for (const row of escalations) {
70
- const { items = [] } = await api('GET', `/escalations/${row.id}/items`);
73
+ // Handoff rows hold the lifecycle items; a decision row holds none.
74
+ const { items = [] } = row.type === contracts_1.ROW_TYPE.HANDOFF ? await api('GET', `/escalations/${row.id}/items`) : {};
71
75
  const view = `${row.type}/${row.role} ${row.status}${row.assigned_to ? ' claimed' : ''} [${items.map((i) => i.itemKey).join(', ')}]`;
72
76
  if (shown.get(row.id) !== view)
73
77
  say(`${row.id.slice(0, 8)} ${view}`);
@@ -100,7 +104,7 @@ async function main() {
100
104
  siteId: line.siteId, lineId: line.lineId, routeKey, orderRef: `ORD-${routeKey}`,
101
105
  units: [{ unitId: `U-${routeKey}`, carrierId: `PLATE-${routeKey}` }],
102
106
  steps: [{ machineId: station, process: env_1.PRINT_PROCESS, recipe: { ...env_1.PRINT_RECIPE } }],
103
- artifact: { url, sha256 }, exitRole: env_1.BAMBU_ROLES.UNLOAD, handoffTimeout: env.BAMBU_HANDOFF_TIMEOUT || '6h',
107
+ artifact: { url, sha256 }, exitRole: (0, line_1.exitRole)(line), operatorRole: (0, line_1.operatorRole)(line), handoffTimeout: env.BAMBU_HANDOFF_TIMEOUT || '6h',
104
108
  };
105
109
  const workflowId = `bambu-${routeKey}`;
106
110
  await api('POST', `/workflows/${route_1.UNIT_ROUTE_WORKFLOW}/invoke`, { data: input, metadata: { source: 'bambu-print' }, workflowId });
@@ -215,7 +215,8 @@ async function startRoutes(artifact) {
215
215
  const name = (0, manifests_1.automatedAt)(i, MIX) ? MANIFEST.AUTOMATED : MANIFEST.MANUAL;
216
216
  const data = {
217
217
  siteId: line.siteId, lineId: line.lineId, routeKey, orderRef: `ORD-${RUN}`, units,
218
- steps: (0, manifests_1.manifestSteps)(line, manifests[name]), exitRole: (0, line_1.exitRole)(line), artifact, handoffTimeout: HANDOFF_TIMEOUT,
218
+ steps: (0, manifests_1.manifestSteps)(line, manifests[name]), exitRole: (0, line_1.exitRole)(line), operatorRole: (0, line_1.operatorRole)(line), qualityRole: (0, line_1.qualityRole)(line),
219
+ artifact, handoffTimeout: HANDOFF_TIMEOUT,
219
220
  };
220
221
  const workflowId = `mur-${routeKey}`;
221
222
  await api('POST', `/workflows/${route_1.UNIT_ROUTE_WORKFLOW}/invoke`, { workflowId, data, metadata: { source: 'machine-line', manifest: name } });
@@ -0,0 +1,13 @@
1
+ import { type ScanRule, type ScanScheme } from '../../types';
2
+ import type { LabelContent, LabelWarning } from '../../shared/labels/types';
3
+ import type { LabelTarget, LabelTemplate } from '../../types/labels';
4
+ export interface BuiltContents {
5
+ contents: LabelContent[];
6
+ warnings: LabelWarning[];
7
+ }
8
+ /**
9
+ * Compose every label. A target the scheme cannot carry (a fixed scheme's
10
+ * target with letters) prints its text without codes and is reported;
11
+ * identity warnings never repeat the target, which is the credential.
12
+ */
13
+ export declare function buildLabelContents(template: LabelTemplate, scheme: ScanScheme, rules: ScanRule[], targets: LabelTarget[], masked: boolean): BuiltContents;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ // One LabelContent per target: the template's codes composed under its scheme
3
+ // and its text rendered with the target's facts.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.buildLabelContents = buildLabelContents;
6
+ const compose_1 = require("../../shared/labels/compose");
7
+ const tokens_1 = require("../../shared/labels/tokens");
8
+ const types_1 = require("../../types");
9
+ const KEYS_NAMED = 6;
10
+ function present(value) {
11
+ return value !== undefined && value !== null && value !== '' && !(Array.isArray(value) && value.length === 0);
12
+ }
13
+ /**
14
+ * Tokens a label's text reads that its own facts lack: `line 1 reads
15
+ * {item.region}, which this label's data doesn't have`. Names the facts it
16
+ * does have, never their values.
17
+ */
18
+ function missingTokens(texts, ctx, index) {
19
+ const warnings = [];
20
+ const seen = new Set();
21
+ for (const [where, text] of texts) {
22
+ for (const token of (0, tokens_1.listLabelTokens)(text)) {
23
+ const [bag, key] = token.split('.', 2);
24
+ if ((bag !== 'item' && bag !== 'user') || !key || seen.has(token))
25
+ continue;
26
+ const facts = (bag === 'item' ? ctx.item : ctx.user) ?? {};
27
+ if (present(facts[key]))
28
+ continue;
29
+ seen.add(token);
30
+ const has = Object.keys(facts).filter((k) => present(facts[k]));
31
+ warnings.push({
32
+ index,
33
+ kind: 'missing_token',
34
+ detail: `${where} reads {${token}}, which this label's data doesn't have` +
35
+ (has.length ? ` (it has: ${has.slice(0, KEYS_NAMED).join(', ')}${has.length > KEYS_NAMED ? ', …' : ''})` : ''),
36
+ });
37
+ }
38
+ }
39
+ return warnings;
40
+ }
41
+ /**
42
+ * Compose every label. A target the scheme cannot carry (a fixed scheme's
43
+ * target with letters) prints its text without codes and is reported;
44
+ * identity warnings never repeat the target, which is the credential.
45
+ */
46
+ function buildLabelContents(template, scheme, rules, targets, masked) {
47
+ const identity = scheme.kind === types_1.SCAN_SCHEME_KINDS.IDENTITY;
48
+ const warnings = [];
49
+ const contents = targets.map((t, index) => {
50
+ const ctx = { target: t.target, item: t.item, user: t.user, scheme: { name: scheme.name } };
51
+ let codes = [];
52
+ try {
53
+ codes = template.codes.map((c) => ({
54
+ code: (0, compose_1.composeScanCode)(scheme, c.category, t.target),
55
+ // Only template captions carry tokens; a rule's name prints as written.
56
+ caption: c.caption != null
57
+ ? (0, tokens_1.renderLabelText)(c.caption, ctx)
58
+ : rules.find((r) => r.category === c.category)?.name ?? '',
59
+ tone: c.tone,
60
+ }));
61
+ }
62
+ catch (err) {
63
+ if (!(err instanceof compose_1.ScanComposeError))
64
+ throw err;
65
+ warnings.push({ index, kind: 'unparseable', detail: identity ? 'the bound credential does not fit the scheme' : err.message });
66
+ }
67
+ const lines = template.text.lines ?? [];
68
+ warnings.push(...missingTokens([
69
+ ['the heading', template.text.title ?? ''],
70
+ ...lines.map((line, i) => [`line ${i + 1}`, line]),
71
+ ...template.codes.map((c, i) => [`caption ${i + 1}`, c.caption ?? '']),
72
+ ], ctx, index));
73
+ return {
74
+ title: template.text.title ? (0, tokens_1.renderLabelText)(template.text.title, ctx) : undefined,
75
+ lines: lines.map((line) => (0, tokens_1.renderLabelText)(line, ctx)),
76
+ codes,
77
+ masked,
78
+ };
79
+ });
80
+ return { contents, warnings };
81
+ }
@@ -0,0 +1,5 @@
1
+ /** A label request refused before anything printed: bad input, access, or a missing confirmation. */
2
+ export declare class LabelRequestError extends Error {
3
+ status: 400 | 403 | 404 | 409 | 428 | 502;
4
+ constructor(status: 400 | 403 | 404 | 409 | 428 | 502, message: string);
5
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LabelRequestError = void 0;
4
+ /** A label request refused before anything printed: bad input, access, or a missing confirmation. */
5
+ class LabelRequestError extends Error {
6
+ constructor(status, message) {
7
+ super(message);
8
+ this.status = status;
9
+ this.name = 'LabelRequestError';
10
+ }
11
+ }
12
+ exports.LabelRequestError = LabelRequestError;
@@ -0,0 +1,11 @@
1
+ export * from './templates';
2
+ export { previewLabels, issueLabels, assertMayPrint, type LabelPreview, type LabelIssueResult } from './issue';
3
+ export { reissueBadge, type ReissueRequest } from './reissue';
4
+ export { getLabelJob, listLabelJobs, recordLabelJob } from './jobs';
5
+ export { resolveLabelTargets, parseListSource, expandRangeSource, markResolvedTargets } from './targets';
6
+ export { buildLabelContents } from './content';
7
+ export { verifyLabels } from './verify';
8
+ export { mintIdentityToken } from './token';
9
+ export { renderSheetPdf, registerLabelFonts, scalePath, type LabelFonts } from './render-pdf';
10
+ export { labelMediaPresets, defaultLabelMediaId, mediaForJob, registerLabelMedia, setDefaultLabelMedia, resetLabelMedia, } from './media';
11
+ export { LabelRequestError } from './errors';