@open-mercato/documents 0.6.8-develop.7016.1.4ed7b1e49d

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 (602) hide show
  1. package/README.md +88 -0
  2. package/build.mjs +23 -0
  3. package/dist/index.js +5 -0
  4. package/dist/index.js.map +7 -0
  5. package/dist/modules/documents/acl.js +15 -0
  6. package/dist/modules/documents/acl.js.map +7 -0
  7. package/dist/modules/documents/api/[id]/archive/route.js +116 -0
  8. package/dist/modules/documents/api/[id]/archive/route.js.map +7 -0
  9. package/dist/modules/documents/api/[id]/attachments/[attachmentId]/route.js +155 -0
  10. package/dist/modules/documents/api/[id]/attachments/[attachmentId]/route.js.map +7 -0
  11. package/dist/modules/documents/api/[id]/attachments/route.js +153 -0
  12. package/dist/modules/documents/api/[id]/attachments/route.js.map +7 -0
  13. package/dist/modules/documents/api/[id]/collab-token/route.js +180 -0
  14. package/dist/modules/documents/api/[id]/collab-token/route.js.map +7 -0
  15. package/dist/modules/documents/api/[id]/comments/access-check/route.js +86 -0
  16. package/dist/modules/documents/api/[id]/comments/access-check/route.js.map +7 -0
  17. package/dist/modules/documents/api/[id]/comments/route.js +387 -0
  18. package/dist/modules/documents/api/[id]/comments/route.js.map +7 -0
  19. package/dist/modules/documents/api/[id]/content/route.js +143 -0
  20. package/dist/modules/documents/api/[id]/content/route.js.map +7 -0
  21. package/dist/modules/documents/api/[id]/duplicate/route.js +200 -0
  22. package/dist/modules/documents/api/[id]/duplicate/route.js.map +7 -0
  23. package/dist/modules/documents/api/[id]/export/route.js +421 -0
  24. package/dist/modules/documents/api/[id]/export/route.js.map +7 -0
  25. package/dist/modules/documents/api/[id]/favorite/route.js +96 -0
  26. package/dist/modules/documents/api/[id]/favorite/route.js.map +7 -0
  27. package/dist/modules/documents/api/[id]/links/[linkId]/route.js +85 -0
  28. package/dist/modules/documents/api/[id]/links/[linkId]/route.js.map +7 -0
  29. package/dist/modules/documents/api/[id]/links/route.js +257 -0
  30. package/dist/modules/documents/api/[id]/links/route.js.map +7 -0
  31. package/dist/modules/documents/api/[id]/principals/route.js +299 -0
  32. package/dist/modules/documents/api/[id]/principals/route.js.map +7 -0
  33. package/dist/modules/documents/api/[id]/route.js +246 -0
  34. package/dist/modules/documents/api/[id]/route.js.map +7 -0
  35. package/dist/modules/documents/api/[id]/shares/route.js +335 -0
  36. package/dist/modules/documents/api/[id]/shares/route.js.map +7 -0
  37. package/dist/modules/documents/api/[id]/unarchive/route.js +39 -0
  38. package/dist/modules/documents/api/[id]/unarchive/route.js.map +7 -0
  39. package/dist/modules/documents/api/[id]/versions/[versionId]/restore/route.js +133 -0
  40. package/dist/modules/documents/api/[id]/versions/[versionId]/restore/route.js.map +7 -0
  41. package/dist/modules/documents/api/[id]/versions/[versionId]/route.js +93 -0
  42. package/dist/modules/documents/api/[id]/versions/[versionId]/route.js.map +7 -0
  43. package/dist/modules/documents/api/[id]/versions/route.js +193 -0
  44. package/dist/modules/documents/api/[id]/versions/route.js.map +7 -0
  45. package/dist/modules/documents/api/[id]/watch/route.js +97 -0
  46. package/dist/modules/documents/api/[id]/watch/route.js.map +7 -0
  47. package/dist/modules/documents/api/_commands.js +34 -0
  48. package/dist/modules/documents/api/_commands.js.map +7 -0
  49. package/dist/modules/documents/api/_shared.js +490 -0
  50. package/dist/modules/documents/api/_shared.js.map +7 -0
  51. package/dist/modules/documents/api/folders/route.js +256 -0
  52. package/dist/modules/documents/api/folders/route.js.map +7 -0
  53. package/dist/modules/documents/api/instantiate/route.js +108 -0
  54. package/dist/modules/documents/api/instantiate/route.js.map +7 -0
  55. package/dist/modules/documents/api/route.js +322 -0
  56. package/dist/modules/documents/api/route.js.map +7 -0
  57. package/dist/modules/documents/api/templates/[templateId]/preview/route.js +94 -0
  58. package/dist/modules/documents/api/templates/[templateId]/preview/route.js.map +7 -0
  59. package/dist/modules/documents/api/templates/[templateId]/route.js +82 -0
  60. package/dist/modules/documents/api/templates/[templateId]/route.js.map +7 -0
  61. package/dist/modules/documents/api/templates/route.js +344 -0
  62. package/dist/modules/documents/api/templates/route.js.map +7 -0
  63. package/dist/modules/documents/backend/documents/DocumentsPageClient.js +160 -0
  64. package/dist/modules/documents/backend/documents/DocumentsPageClient.js.map +7 -0
  65. package/dist/modules/documents/backend/documents/DocumentsTable.js +143 -0
  66. package/dist/modules/documents/backend/documents/DocumentsTable.js.map +7 -0
  67. package/dist/modules/documents/backend/documents/FolderDialog.js +55 -0
  68. package/dist/modules/documents/backend/documents/FolderDialog.js.map +7 -0
  69. package/dist/modules/documents/backend/documents/FolderTree.js +40 -0
  70. package/dist/modules/documents/backend/documents/FolderTree.js.map +7 -0
  71. package/dist/modules/documents/backend/documents/MoveDocumentDialog.js +64 -0
  72. package/dist/modules/documents/backend/documents/MoveDocumentDialog.js.map +7 -0
  73. package/dist/modules/documents/backend/documents/[id]/CommentAnchorNavigation.js +77 -0
  74. package/dist/modules/documents/backend/documents/[id]/CommentAnchorNavigation.js.map +7 -0
  75. package/dist/modules/documents/backend/documents/[id]/CommentComposer.js +126 -0
  76. package/dist/modules/documents/backend/documents/[id]/CommentComposer.js.map +7 -0
  77. package/dist/modules/documents/backend/documents/[id]/CommentThreadList.js +88 -0
  78. package/dist/modules/documents/backend/documents/[id]/CommentThreadList.js.map +7 -0
  79. package/dist/modules/documents/backend/documents/[id]/CommentsRail.js +123 -0
  80. package/dist/modules/documents/backend/documents/[id]/CommentsRail.js.map +7 -0
  81. package/dist/modules/documents/backend/documents/[id]/DocumentCanvas.js +91 -0
  82. package/dist/modules/documents/backend/documents/[id]/DocumentCanvas.js.map +7 -0
  83. package/dist/modules/documents/backend/documents/[id]/DocumentEditorErrorBoundary.js +27 -0
  84. package/dist/modules/documents/backend/documents/[id]/DocumentEditorErrorBoundary.js.map +7 -0
  85. package/dist/modules/documents/backend/documents/[id]/DocumentEditorIsland.js +50 -0
  86. package/dist/modules/documents/backend/documents/[id]/DocumentEditorIsland.js.map +7 -0
  87. package/dist/modules/documents/backend/documents/[id]/DocumentEditorSurface.js +168 -0
  88. package/dist/modules/documents/backend/documents/[id]/DocumentEditorSurface.js.map +7 -0
  89. package/dist/modules/documents/backend/documents/[id]/DocumentNavigator.js +129 -0
  90. package/dist/modules/documents/backend/documents/[id]/DocumentNavigator.js.map +7 -0
  91. package/dist/modules/documents/backend/documents/[id]/DocumentPageClient.js +429 -0
  92. package/dist/modules/documents/backend/documents/[id]/DocumentPageClient.js.map +7 -0
  93. package/dist/modules/documents/backend/documents/[id]/EditorColorTools.js +68 -0
  94. package/dist/modules/documents/backend/documents/[id]/EditorColorTools.js.map +7 -0
  95. package/dist/modules/documents/backend/documents/[id]/EditorStatusPresence.js +69 -0
  96. package/dist/modules/documents/backend/documents/[id]/EditorStatusPresence.js.map +7 -0
  97. package/dist/modules/documents/backend/documents/[id]/EditorToolbar.js +151 -0
  98. package/dist/modules/documents/backend/documents/[id]/EditorToolbar.js.map +7 -0
  99. package/dist/modules/documents/backend/documents/[id]/ExportMenu.js +121 -0
  100. package/dist/modules/documents/backend/documents/[id]/ExportMenu.js.map +7 -0
  101. package/dist/modules/documents/backend/documents/[id]/MentionPicker.js +114 -0
  102. package/dist/modules/documents/backend/documents/[id]/MentionPicker.js.map +7 -0
  103. package/dist/modules/documents/backend/documents/[id]/OutlinePane.js +70 -0
  104. package/dist/modules/documents/backend/documents/[id]/OutlinePane.js.map +7 -0
  105. package/dist/modules/documents/backend/documents/[id]/RecordFieldsDialog.js +157 -0
  106. package/dist/modules/documents/backend/documents/[id]/RecordFieldsDialog.js.map +7 -0
  107. package/dist/modules/documents/backend/documents/[id]/RelatedRecordsPanel.js +266 -0
  108. package/dist/modules/documents/backend/documents/[id]/RelatedRecordsPanel.js.map +7 -0
  109. package/dist/modules/documents/backend/documents/[id]/VersionHistoryPanel.js +227 -0
  110. package/dist/modules/documents/backend/documents/[id]/VersionHistoryPanel.js.map +7 -0
  111. package/dist/modules/documents/backend/documents/[id]/VersionPreviewDialog.js +157 -0
  112. package/dist/modules/documents/backend/documents/[id]/VersionPreviewDialog.js.map +7 -0
  113. package/dist/modules/documents/backend/documents/[id]/commentTypes.js +150 -0
  114. package/dist/modules/documents/backend/documents/[id]/commentTypes.js.map +7 -0
  115. package/dist/modules/documents/backend/documents/[id]/componentCapabilities.js +13 -0
  116. package/dist/modules/documents/backend/documents/[id]/componentCapabilities.js.map +7 -0
  117. package/dist/modules/documents/backend/documents/[id]/documentPagination.js +295 -0
  118. package/dist/modules/documents/backend/documents/[id]/documentPagination.js.map +7 -0
  119. package/dist/modules/documents/backend/documents/[id]/editorPresenceStyles.js +81 -0
  120. package/dist/modules/documents/backend/documents/[id]/editorPresenceStyles.js.map +7 -0
  121. package/dist/modules/documents/backend/documents/[id]/editorTypes.js +52 -0
  122. package/dist/modules/documents/backend/documents/[id]/editorTypes.js.map +7 -0
  123. package/dist/modules/documents/backend/documents/[id]/page.js +10 -0
  124. package/dist/modules/documents/backend/documents/[id]/page.js.map +7 -0
  125. package/dist/modules/documents/backend/documents/[id]/page.meta.js +16 -0
  126. package/dist/modules/documents/backend/documents/[id]/page.meta.js.map +7 -0
  127. package/dist/modules/documents/backend/documents/[id]/relatedRecordModel.js +38 -0
  128. package/dist/modules/documents/backend/documents/[id]/relatedRecordModel.js.map +7 -0
  129. package/dist/modules/documents/backend/documents/[id]/restoreVersion.js +33 -0
  130. package/dist/modules/documents/backend/documents/[id]/restoreVersion.js.map +7 -0
  131. package/dist/modules/documents/backend/documents/[id]/useDocumentCollaboration.js +392 -0
  132. package/dist/modules/documents/backend/documents/[id]/useDocumentCollaboration.js.map +7 -0
  133. package/dist/modules/documents/backend/documents/[id]/useDocumentComments.js +253 -0
  134. package/dist/modules/documents/backend/documents/[id]/useDocumentComments.js.map +7 -0
  135. package/dist/modules/documents/backend/documents/[id]/useDocumentEditor.js +149 -0
  136. package/dist/modules/documents/backend/documents/[id]/useDocumentEditor.js.map +7 -0
  137. package/dist/modules/documents/backend/documents/[id]/useDocumentTitle.js +82 -0
  138. package/dist/modules/documents/backend/documents/[id]/useDocumentTitle.js.map +7 -0
  139. package/dist/modules/documents/backend/documents/[id]/useEditorInsertions.js +144 -0
  140. package/dist/modules/documents/backend/documents/[id]/useEditorInsertions.js.map +7 -0
  141. package/dist/modules/documents/backend/documents/[id]/useFallbackContentPersistence.js +237 -0
  142. package/dist/modules/documents/backend/documents/[id]/useFallbackContentPersistence.js.map +7 -0
  143. package/dist/modules/documents/backend/documents/[id]/useMentionPicker.js +216 -0
  144. package/dist/modules/documents/backend/documents/[id]/useMentionPicker.js.map +7 -0
  145. package/dist/modules/documents/backend/documents/[id]/versionHistoryModel.js +25 -0
  146. package/dist/modules/documents/backend/documents/[id]/versionHistoryModel.js.map +7 -0
  147. package/dist/modules/documents/backend/documents/components/EntityPicker.js +156 -0
  148. package/dist/modules/documents/backend/documents/components/EntityPicker.js.map +7 -0
  149. package/dist/modules/documents/backend/documents/components/EntityPickerResults.js +46 -0
  150. package/dist/modules/documents/backend/documents/components/EntityPickerResults.js.map +7 -0
  151. package/dist/modules/documents/backend/documents/components/NewFromTemplateDialog.js +127 -0
  152. package/dist/modules/documents/backend/documents/components/NewFromTemplateDialog.js.map +7 -0
  153. package/dist/modules/documents/backend/documents/components/PrincipalPicker.js +84 -0
  154. package/dist/modules/documents/backend/documents/components/PrincipalPicker.js.map +7 -0
  155. package/dist/modules/documents/backend/documents/components/ShareDialog.js +77 -0
  156. package/dist/modules/documents/backend/documents/components/ShareDialog.js.map +7 -0
  157. package/dist/modules/documents/backend/documents/components/ShareDialogAddForm.js +93 -0
  158. package/dist/modules/documents/backend/documents/components/ShareDialogAddForm.js.map +7 -0
  159. package/dist/modules/documents/backend/documents/components/ShareDialogList.js +82 -0
  160. package/dist/modules/documents/backend/documents/components/ShareDialogList.js.map +7 -0
  161. package/dist/modules/documents/backend/documents/components/TemplateBodyEditor.js +96 -0
  162. package/dist/modules/documents/backend/documents/components/TemplateBodyEditor.js.map +7 -0
  163. package/dist/modules/documents/backend/documents/components/TemplateEditorDialog.js +169 -0
  164. package/dist/modules/documents/backend/documents/components/TemplateEditorDialog.js.map +7 -0
  165. package/dist/modules/documents/backend/documents/components/TemplatePreview.js +38 -0
  166. package/dist/modules/documents/backend/documents/components/TemplatePreview.js.map +7 -0
  167. package/dist/modules/documents/backend/documents/components/TemplateSlotFields.js +69 -0
  168. package/dist/modules/documents/backend/documents/components/TemplateSlotFields.js.map +7 -0
  169. package/dist/modules/documents/backend/documents/components/TemplateSlotsEditor.js +71 -0
  170. package/dist/modules/documents/backend/documents/components/TemplateSlotsEditor.js.map +7 -0
  171. package/dist/modules/documents/backend/documents/components/principalPickerModel.js +63 -0
  172. package/dist/modules/documents/backend/documents/components/principalPickerModel.js.map +7 -0
  173. package/dist/modules/documents/backend/documents/components/shareDialogModel.js +68 -0
  174. package/dist/modules/documents/backend/documents/components/shareDialogModel.js.map +7 -0
  175. package/dist/modules/documents/backend/documents/components/templateUi.js +89 -0
  176. package/dist/modules/documents/backend/documents/components/templateUi.js.map +7 -0
  177. package/dist/modules/documents/backend/documents/components/useAvailableEntityRegistry.js +30 -0
  178. package/dist/modules/documents/backend/documents/components/useAvailableEntityRegistry.js.map +7 -0
  179. package/dist/modules/documents/backend/documents/components/useEntitySearch.js +191 -0
  180. package/dist/modules/documents/backend/documents/components/useEntitySearch.js.map +7 -0
  181. package/dist/modules/documents/backend/documents/components/usePrincipalPicker.js +221 -0
  182. package/dist/modules/documents/backend/documents/components/usePrincipalPicker.js.map +7 -0
  183. package/dist/modules/documents/backend/documents/components/useShareDialog.js +236 -0
  184. package/dist/modules/documents/backend/documents/components/useShareDialog.js.map +7 -0
  185. package/dist/modules/documents/backend/documents/components/useTemplateDetail.js +49 -0
  186. package/dist/modules/documents/backend/documents/components/useTemplateDetail.js.map +7 -0
  187. package/dist/modules/documents/backend/documents/components/useTemplateInstantiation.js +234 -0
  188. package/dist/modules/documents/backend/documents/components/useTemplateInstantiation.js.map +7 -0
  189. package/dist/modules/documents/backend/documents/documentUi.js +106 -0
  190. package/dist/modules/documents/backend/documents/documentUi.js.map +7 -0
  191. package/dist/modules/documents/backend/documents/documentsListTypes.js +132 -0
  192. package/dist/modules/documents/backend/documents/documentsListTypes.js.map +7 -0
  193. package/dist/modules/documents/backend/documents/page.js +9 -0
  194. package/dist/modules/documents/backend/documents/page.js.map +7 -0
  195. package/dist/modules/documents/backend/documents/page.meta.js +26 -0
  196. package/dist/modules/documents/backend/documents/page.meta.js.map +7 -0
  197. package/dist/modules/documents/backend/documents/templates/TemplatesPageClient.js +91 -0
  198. package/dist/modules/documents/backend/documents/templates/TemplatesPageClient.js.map +7 -0
  199. package/dist/modules/documents/backend/documents/templates/TemplatesTable.js +58 -0
  200. package/dist/modules/documents/backend/documents/templates/TemplatesTable.js.map +7 -0
  201. package/dist/modules/documents/backend/documents/templates/page.js +9 -0
  202. package/dist/modules/documents/backend/documents/templates/page.js.map +7 -0
  203. package/dist/modules/documents/backend/documents/templates/page.meta.js +34 -0
  204. package/dist/modules/documents/backend/documents/templates/page.meta.js.map +7 -0
  205. package/dist/modules/documents/backend/documents/templates/useTemplatesPage.js +139 -0
  206. package/dist/modules/documents/backend/documents/templates/useTemplatesPage.js.map +7 -0
  207. package/dist/modules/documents/backend/documents/useDocumentsList.js +314 -0
  208. package/dist/modules/documents/backend/documents/useDocumentsList.js.map +7 -0
  209. package/dist/modules/documents/ce.js +8 -0
  210. package/dist/modules/documents/ce.js.map +7 -0
  211. package/dist/modules/documents/commands/aggregate.js +99 -0
  212. package/dist/modules/documents/commands/aggregate.js.map +7 -0
  213. package/dist/modules/documents/commands/attachments.js +252 -0
  214. package/dist/modules/documents/commands/attachments.js.map +7 -0
  215. package/dist/modules/documents/commands/comments.js +782 -0
  216. package/dist/modules/documents/commands/comments.js.map +7 -0
  217. package/dist/modules/documents/commands/content.js +238 -0
  218. package/dist/modules/documents/commands/content.js.map +7 -0
  219. package/dist/modules/documents/commands/document-crud.js +505 -0
  220. package/dist/modules/documents/commands/document-crud.js.map +7 -0
  221. package/dist/modules/documents/commands/documents.js +473 -0
  222. package/dist/modules/documents/commands/documents.js.map +7 -0
  223. package/dist/modules/documents/commands/duplicate.js +640 -0
  224. package/dist/modules/documents/commands/duplicate.js.map +7 -0
  225. package/dist/modules/documents/commands/favorites.js +150 -0
  226. package/dist/modules/documents/commands/favorites.js.map +7 -0
  227. package/dist/modules/documents/commands/folders.js +420 -0
  228. package/dist/modules/documents/commands/folders.js.map +7 -0
  229. package/dist/modules/documents/commands/index.js +64 -0
  230. package/dist/modules/documents/commands/index.js.map +7 -0
  231. package/dist/modules/documents/commands/interceptors.js +300 -0
  232. package/dist/modules/documents/commands/interceptors.js.map +7 -0
  233. package/dist/modules/documents/commands/lifecycle.js +249 -0
  234. package/dist/modules/documents/commands/lifecycle.js.map +7 -0
  235. package/dist/modules/documents/commands/links.js +410 -0
  236. package/dist/modules/documents/commands/links.js.map +7 -0
  237. package/dist/modules/documents/commands/mutation-helpers.js +42 -0
  238. package/dist/modules/documents/commands/mutation-helpers.js.map +7 -0
  239. package/dist/modules/documents/commands/projection-types.js +1 -0
  240. package/dist/modules/documents/commands/projection-types.js.map +7 -0
  241. package/dist/modules/documents/commands/shared.js +143 -0
  242. package/dist/modules/documents/commands/shared.js.map +7 -0
  243. package/dist/modules/documents/commands/shares.js +527 -0
  244. package/dist/modules/documents/commands/shares.js.map +7 -0
  245. package/dist/modules/documents/commands/side-effects.js +103 -0
  246. package/dist/modules/documents/commands/side-effects.js.map +7 -0
  247. package/dist/modules/documents/commands/templates.js +461 -0
  248. package/dist/modules/documents/commands/templates.js.map +7 -0
  249. package/dist/modules/documents/commands/versions.js +432 -0
  250. package/dist/modules/documents/commands/versions.js.map +7 -0
  251. package/dist/modules/documents/commands/watchers.js +164 -0
  252. package/dist/modules/documents/commands/watchers.js.map +7 -0
  253. package/dist/modules/documents/data/entities.js +653 -0
  254. package/dist/modules/documents/data/entities.js.map +7 -0
  255. package/dist/modules/documents/data/extensions.js +44 -0
  256. package/dist/modules/documents/data/extensions.js.map +7 -0
  257. package/dist/modules/documents/data/validators.js +219 -0
  258. package/dist/modules/documents/data/validators.js.map +7 -0
  259. package/dist/modules/documents/di.js +35 -0
  260. package/dist/modules/documents/di.js.map +7 -0
  261. package/dist/modules/documents/encryption.js +12 -0
  262. package/dist/modules/documents/encryption.js.map +7 -0
  263. package/dist/modules/documents/events.js +27 -0
  264. package/dist/modules/documents/events.js.map +7 -0
  265. package/dist/modules/documents/index.js +19 -0
  266. package/dist/modules/documents/index.js.map +7 -0
  267. package/dist/modules/documents/lib/attachmentServicePort.js +30 -0
  268. package/dist/modules/documents/lib/attachmentServicePort.js.map +7 -0
  269. package/dist/modules/documents/lib/capabilities.js +32 -0
  270. package/dist/modules/documents/lib/capabilities.js.map +7 -0
  271. package/dist/modules/documents/lib/collabCloseEvents.js +17 -0
  272. package/dist/modules/documents/lib/collabCloseEvents.js.map +7 -0
  273. package/dist/modules/documents/lib/collabEndpoint.js +22 -0
  274. package/dist/modules/documents/lib/collabEndpoint.js.map +7 -0
  275. package/dist/modules/documents/lib/collabMaterializer.js +107 -0
  276. package/dist/modules/documents/lib/collabMaterializer.js.map +7 -0
  277. package/dist/modules/documents/lib/collabToken.js +120 -0
  278. package/dist/modules/documents/lib/collabToken.js.map +7 -0
  279. package/dist/modules/documents/lib/collaborationAwareness.js +68 -0
  280. package/dist/modules/documents/lib/collaborationAwareness.js.map +7 -0
  281. package/dist/modules/documents/lib/commentAnchors.js +15 -0
  282. package/dist/modules/documents/lib/commentAnchors.js.map +7 -0
  283. package/dist/modules/documents/lib/constants.js +25 -0
  284. package/dist/modules/documents/lib/constants.js.map +7 -0
  285. package/dist/modules/documents/lib/contentService.js +248 -0
  286. package/dist/modules/documents/lib/contentService.js.map +7 -0
  287. package/dist/modules/documents/lib/displayLabels.js +23 -0
  288. package/dist/modules/documents/lib/displayLabels.js.map +7 -0
  289. package/dist/modules/documents/lib/docxRenderer.js +601 -0
  290. package/dist/modules/documents/lib/docxRenderer.js.map +7 -0
  291. package/dist/modules/documents/lib/duplicateContent.js +22 -0
  292. package/dist/modules/documents/lib/duplicateContent.js.map +7 -0
  293. package/dist/modules/documents/lib/editorConfig.js +287 -0
  294. package/dist/modules/documents/lib/editorConfig.js.map +7 -0
  295. package/dist/modules/documents/lib/entityLinks.js +148 -0
  296. package/dist/modules/documents/lib/entityLinks.js.map +7 -0
  297. package/dist/modules/documents/lib/entityRegistry.js +258 -0
  298. package/dist/modules/documents/lib/entityRegistry.js.map +7 -0
  299. package/dist/modules/documents/lib/entityRegistry.server.js +189 -0
  300. package/dist/modules/documents/lib/entityRegistry.server.js.map +7 -0
  301. package/dist/modules/documents/lib/entityRegistryAvailability.server.js +9 -0
  302. package/dist/modules/documents/lib/entityRegistryAvailability.server.js.map +7 -0
  303. package/dist/modules/documents/lib/entitySuggestion.js +50 -0
  304. package/dist/modules/documents/lib/entitySuggestion.js.map +7 -0
  305. package/dist/modules/documents/lib/favorites.js +22 -0
  306. package/dist/modules/documents/lib/favorites.js.map +7 -0
  307. package/dist/modules/documents/lib/folderHierarchySerialization.js +19 -0
  308. package/dist/modules/documents/lib/folderHierarchySerialization.js.map +7 -0
  309. package/dist/modules/documents/lib/historyLimits.js +100 -0
  310. package/dist/modules/documents/lib/historyLimits.js.map +7 -0
  311. package/dist/modules/documents/lib/historyPolicy.js +14 -0
  312. package/dist/modules/documents/lib/historyPolicy.js.map +7 -0
  313. package/dist/modules/documents/lib/organizationAccess.js +17 -0
  314. package/dist/modules/documents/lib/organizationAccess.js.map +7 -0
  315. package/dist/modules/documents/lib/pdfHtml.js +62 -0
  316. package/dist/modules/documents/lib/pdfHtml.js.map +7 -0
  317. package/dist/modules/documents/lib/pdfRenderer.js +284 -0
  318. package/dist/modules/documents/lib/pdfRenderer.js.map +7 -0
  319. package/dist/modules/documents/lib/permissions.js +222 -0
  320. package/dist/modules/documents/lib/permissions.js.map +7 -0
  321. package/dist/modules/documents/lib/platformServices.js +35 -0
  322. package/dist/modules/documents/lib/platformServices.js.map +7 -0
  323. package/dist/modules/documents/lib/recordFieldInsertion.js +58 -0
  324. package/dist/modules/documents/lib/recordFieldInsertion.js.map +7 -0
  325. package/dist/modules/documents/lib/requestBody.js +80 -0
  326. package/dist/modules/documents/lib/requestBody.js.map +7 -0
  327. package/dist/modules/documents/lib/resourceLimits.js +62 -0
  328. package/dist/modules/documents/lib/resourceLimits.js.map +7 -0
  329. package/dist/modules/documents/lib/shareCounts.js +25 -0
  330. package/dist/modules/documents/lib/shareCounts.js.map +7 -0
  331. package/dist/modules/documents/lib/templateFill.js +84 -0
  332. package/dist/modules/documents/lib/templateFill.js.map +7 -0
  333. package/dist/modules/documents/lib/templateInstantiation.js +147 -0
  334. package/dist/modules/documents/lib/templateInstantiation.js.map +7 -0
  335. package/dist/modules/documents/lib/templatePreviewDigest.js +82 -0
  336. package/dist/modules/documents/lib/templatePreviewDigest.js.map +7 -0
  337. package/dist/modules/documents/lib/templateSeeds.js +201 -0
  338. package/dist/modules/documents/lib/templateSeeds.js.map +7 -0
  339. package/dist/modules/documents/lib/userLabels.js +37 -0
  340. package/dist/modules/documents/lib/userLabels.js.map +7 -0
  341. package/dist/modules/documents/lib/versionContent.js +131 -0
  342. package/dist/modules/documents/lib/versionContent.js.map +7 -0
  343. package/dist/modules/documents/lib/versionLabels.js +12 -0
  344. package/dist/modules/documents/lib/versionLabels.js.map +7 -0
  345. package/dist/modules/documents/lib/versioning.js +14 -0
  346. package/dist/modules/documents/lib/versioning.js.map +7 -0
  347. package/dist/modules/documents/lib/visibility.js +422 -0
  348. package/dist/modules/documents/lib/visibility.js.map +7 -0
  349. package/dist/modules/documents/lib/watchers.js +106 -0
  350. package/dist/modules/documents/lib/watchers.js.map +7 -0
  351. package/dist/modules/documents/migrations/Migration20260708163836_documents.js +44 -0
  352. package/dist/modules/documents/migrations/Migration20260708163836_documents.js.map +7 -0
  353. package/dist/modules/documents/migrations/Migration20260709164720_documents.js +17 -0
  354. package/dist/modules/documents/migrations/Migration20260709164720_documents.js.map +7 -0
  355. package/dist/modules/documents/migrations/Migration20260710002318_documents.js +32 -0
  356. package/dist/modules/documents/migrations/Migration20260710002318_documents.js.map +7 -0
  357. package/dist/modules/documents/migrations/Migration20260710071003_documents.js +13 -0
  358. package/dist/modules/documents/migrations/Migration20260710071003_documents.js.map +7 -0
  359. package/dist/modules/documents/migrations/Migration20260712120000_documents.js +13 -0
  360. package/dist/modules/documents/migrations/Migration20260712120000_documents.js.map +7 -0
  361. package/dist/modules/documents/migrations/Migration20260712183000_documents.js +14 -0
  362. package/dist/modules/documents/migrations/Migration20260712183000_documents.js.map +7 -0
  363. package/dist/modules/documents/migrations/Migration20260713092156_documents.js +29 -0
  364. package/dist/modules/documents/migrations/Migration20260713092156_documents.js.map +7 -0
  365. package/dist/modules/documents/migrations/Migration20260717000000_documents.js +37 -0
  366. package/dist/modules/documents/migrations/Migration20260717000000_documents.js.map +7 -0
  367. package/dist/modules/documents/notifications.js +47 -0
  368. package/dist/modules/documents/notifications.js.map +7 -0
  369. package/dist/modules/documents/search.js +101 -0
  370. package/dist/modules/documents/search.js.map +7 -0
  371. package/dist/modules/documents/setup.js +19 -0
  372. package/dist/modules/documents/setup.js.map +7 -0
  373. package/dist/modules/documents/widgets/injection/related-documents/LinkDocumentDialog.js +214 -0
  374. package/dist/modules/documents/widgets/injection/related-documents/LinkDocumentDialog.js.map +7 -0
  375. package/dist/modules/documents/widgets/injection/related-documents/context.js +84 -0
  376. package/dist/modules/documents/widgets/injection/related-documents/context.js.map +7 -0
  377. package/dist/modules/documents/widgets/injection/related-documents/useRelatedDocuments.js +98 -0
  378. package/dist/modules/documents/widgets/injection/related-documents/useRelatedDocuments.js.map +7 -0
  379. package/dist/modules/documents/widgets/injection/related-documents/widget.client.js +83 -0
  380. package/dist/modules/documents/widgets/injection/related-documents/widget.client.js.map +7 -0
  381. package/dist/modules/documents/widgets/injection/related-documents/widget.js +19 -0
  382. package/dist/modules/documents/widgets/injection/related-documents/widget.js.map +7 -0
  383. package/dist/modules/documents/widgets/injection-table.js +21 -0
  384. package/dist/modules/documents/widgets/injection-table.js.map +7 -0
  385. package/dist/server/documents-collab-server.js +2260 -0
  386. package/dist/server/documents-collab-server.js.map +7 -0
  387. package/generated/entities/document/index.ts +12 -0
  388. package/generated/entities/document_attachment/index.ts +9 -0
  389. package/generated/entities/document_comment/index.ts +14 -0
  390. package/generated/entities/document_content/index.ts +11 -0
  391. package/generated/entities/document_entity_link/index.ts +19 -0
  392. package/generated/entities/document_favorite/index.ts +7 -0
  393. package/generated/entities/document_folder/index.ts +9 -0
  394. package/generated/entities/document_share/index.ts +11 -0
  395. package/generated/entities/document_template/index.ts +13 -0
  396. package/generated/entities/document_version/index.ts +9 -0
  397. package/generated/entities/document_watcher/index.ts +7 -0
  398. package/generated/entities.ids.generated.ts +21 -0
  399. package/generated/entity-fields-registry.ts +151 -0
  400. package/jest.config.cjs +34 -0
  401. package/package.json +149 -0
  402. package/server/documents-collab-server.ts +3416 -0
  403. package/src/index.ts +1 -0
  404. package/src/modules/documents/acl.ts +11 -0
  405. package/src/modules/documents/api/[id]/archive/route.ts +132 -0
  406. package/src/modules/documents/api/[id]/attachments/[attachmentId]/route.ts +166 -0
  407. package/src/modules/documents/api/[id]/attachments/route.ts +173 -0
  408. package/src/modules/documents/api/[id]/collab-token/route.ts +203 -0
  409. package/src/modules/documents/api/[id]/comments/access-check/route.ts +96 -0
  410. package/src/modules/documents/api/[id]/comments/route.ts +442 -0
  411. package/src/modules/documents/api/[id]/content/route.ts +156 -0
  412. package/src/modules/documents/api/[id]/duplicate/route.ts +231 -0
  413. package/src/modules/documents/api/[id]/export/route.ts +535 -0
  414. package/src/modules/documents/api/[id]/favorite/route.ts +110 -0
  415. package/src/modules/documents/api/[id]/links/[linkId]/route.ts +92 -0
  416. package/src/modules/documents/api/[id]/links/route.ts +301 -0
  417. package/src/modules/documents/api/[id]/principals/route.ts +375 -0
  418. package/src/modules/documents/api/[id]/route.ts +267 -0
  419. package/src/modules/documents/api/[id]/shares/route.ts +372 -0
  420. package/src/modules/documents/api/[id]/unarchive/route.ts +42 -0
  421. package/src/modules/documents/api/[id]/versions/[versionId]/restore/route.ts +152 -0
  422. package/src/modules/documents/api/[id]/versions/[versionId]/route.ts +100 -0
  423. package/src/modules/documents/api/[id]/versions/route.ts +207 -0
  424. package/src/modules/documents/api/[id]/watch/route.ts +111 -0
  425. package/src/modules/documents/api/_commands.ts +53 -0
  426. package/src/modules/documents/api/_shared.ts +676 -0
  427. package/src/modules/documents/api/folders/route.ts +287 -0
  428. package/src/modules/documents/api/instantiate/route.ts +114 -0
  429. package/src/modules/documents/api/route.ts +362 -0
  430. package/src/modules/documents/api/templates/[templateId]/preview/route.ts +97 -0
  431. package/src/modules/documents/api/templates/[templateId]/route.ts +92 -0
  432. package/src/modules/documents/api/templates/route.ts +370 -0
  433. package/src/modules/documents/backend/documents/DocumentsPageClient.tsx +150 -0
  434. package/src/modules/documents/backend/documents/DocumentsTable.tsx +168 -0
  435. package/src/modules/documents/backend/documents/FolderDialog.tsx +62 -0
  436. package/src/modules/documents/backend/documents/FolderTree.tsx +72 -0
  437. package/src/modules/documents/backend/documents/MoveDocumentDialog.tsx +70 -0
  438. package/src/modules/documents/backend/documents/[id]/CommentAnchorNavigation.ts +88 -0
  439. package/src/modules/documents/backend/documents/[id]/CommentComposer.tsx +136 -0
  440. package/src/modules/documents/backend/documents/[id]/CommentThreadList.tsx +131 -0
  441. package/src/modules/documents/backend/documents/[id]/CommentsRail.tsx +138 -0
  442. package/src/modules/documents/backend/documents/[id]/DocumentCanvas.tsx +111 -0
  443. package/src/modules/documents/backend/documents/[id]/DocumentEditorErrorBoundary.tsx +39 -0
  444. package/src/modules/documents/backend/documents/[id]/DocumentEditorIsland.tsx +50 -0
  445. package/src/modules/documents/backend/documents/[id]/DocumentEditorSurface.tsx +162 -0
  446. package/src/modules/documents/backend/documents/[id]/DocumentNavigator.tsx +129 -0
  447. package/src/modules/documents/backend/documents/[id]/DocumentPageClient.tsx +463 -0
  448. package/src/modules/documents/backend/documents/[id]/EditorColorTools.tsx +71 -0
  449. package/src/modules/documents/backend/documents/[id]/EditorStatusPresence.tsx +78 -0
  450. package/src/modules/documents/backend/documents/[id]/EditorToolbar.tsx +108 -0
  451. package/src/modules/documents/backend/documents/[id]/ExportMenu.tsx +144 -0
  452. package/src/modules/documents/backend/documents/[id]/MentionPicker.tsx +137 -0
  453. package/src/modules/documents/backend/documents/[id]/OutlinePane.tsx +98 -0
  454. package/src/modules/documents/backend/documents/[id]/RecordFieldsDialog.tsx +185 -0
  455. package/src/modules/documents/backend/documents/[id]/RelatedRecordsPanel.tsx +320 -0
  456. package/src/modules/documents/backend/documents/[id]/VersionHistoryPanel.tsx +244 -0
  457. package/src/modules/documents/backend/documents/[id]/VersionPreviewDialog.tsx +197 -0
  458. package/src/modules/documents/backend/documents/[id]/commentTypes.ts +192 -0
  459. package/src/modules/documents/backend/documents/[id]/componentCapabilities.ts +17 -0
  460. package/src/modules/documents/backend/documents/[id]/documentPagination.ts +352 -0
  461. package/src/modules/documents/backend/documents/[id]/editorPresenceStyles.ts +77 -0
  462. package/src/modules/documents/backend/documents/[id]/editorTypes.ts +84 -0
  463. package/src/modules/documents/backend/documents/[id]/page.meta.ts +12 -0
  464. package/src/modules/documents/backend/documents/[id]/page.tsx +6 -0
  465. package/src/modules/documents/backend/documents/[id]/relatedRecordModel.ts +49 -0
  466. package/src/modules/documents/backend/documents/[id]/restoreVersion.ts +49 -0
  467. package/src/modules/documents/backend/documents/[id]/useDocumentCollaboration.ts +458 -0
  468. package/src/modules/documents/backend/documents/[id]/useDocumentComments.ts +286 -0
  469. package/src/modules/documents/backend/documents/[id]/useDocumentEditor.ts +157 -0
  470. package/src/modules/documents/backend/documents/[id]/useDocumentTitle.ts +77 -0
  471. package/src/modules/documents/backend/documents/[id]/useEditorInsertions.ts +147 -0
  472. package/src/modules/documents/backend/documents/[id]/useFallbackContentPersistence.ts +277 -0
  473. package/src/modules/documents/backend/documents/[id]/useMentionPicker.ts +259 -0
  474. package/src/modules/documents/backend/documents/[id]/versionHistoryModel.ts +29 -0
  475. package/src/modules/documents/backend/documents/components/EntityPicker.tsx +171 -0
  476. package/src/modules/documents/backend/documents/components/EntityPickerResults.tsx +64 -0
  477. package/src/modules/documents/backend/documents/components/NewFromTemplateDialog.tsx +136 -0
  478. package/src/modules/documents/backend/documents/components/PrincipalPicker.tsx +90 -0
  479. package/src/modules/documents/backend/documents/components/ShareDialog.tsx +88 -0
  480. package/src/modules/documents/backend/documents/components/ShareDialogAddForm.tsx +113 -0
  481. package/src/modules/documents/backend/documents/components/ShareDialogList.tsx +117 -0
  482. package/src/modules/documents/backend/documents/components/TemplateBodyEditor.tsx +96 -0
  483. package/src/modules/documents/backend/documents/components/TemplateEditorDialog.tsx +171 -0
  484. package/src/modules/documents/backend/documents/components/TemplatePreview.tsx +43 -0
  485. package/src/modules/documents/backend/documents/components/TemplateSlotFields.tsx +72 -0
  486. package/src/modules/documents/backend/documents/components/TemplateSlotsEditor.tsx +72 -0
  487. package/src/modules/documents/backend/documents/components/principalPickerModel.ts +86 -0
  488. package/src/modules/documents/backend/documents/components/shareDialogModel.ts +94 -0
  489. package/src/modules/documents/backend/documents/components/templateUi.ts +128 -0
  490. package/src/modules/documents/backend/documents/components/useAvailableEntityRegistry.ts +43 -0
  491. package/src/modules/documents/backend/documents/components/useEntitySearch.ts +197 -0
  492. package/src/modules/documents/backend/documents/components/usePrincipalPicker.ts +165 -0
  493. package/src/modules/documents/backend/documents/components/useShareDialog.ts +267 -0
  494. package/src/modules/documents/backend/documents/components/useTemplateDetail.ts +54 -0
  495. package/src/modules/documents/backend/documents/components/useTemplateInstantiation.ts +252 -0
  496. package/src/modules/documents/backend/documents/documentUi.ts +134 -0
  497. package/src/modules/documents/backend/documents/documentsListTypes.ts +163 -0
  498. package/src/modules/documents/backend/documents/page.meta.ts +24 -0
  499. package/src/modules/documents/backend/documents/page.tsx +5 -0
  500. package/src/modules/documents/backend/documents/templates/TemplatesPageClient.tsx +93 -0
  501. package/src/modules/documents/backend/documents/templates/TemplatesTable.tsx +71 -0
  502. package/src/modules/documents/backend/documents/templates/page.meta.ts +32 -0
  503. package/src/modules/documents/backend/documents/templates/page.tsx +5 -0
  504. package/src/modules/documents/backend/documents/templates/useTemplatesPage.tsx +148 -0
  505. package/src/modules/documents/backend/documents/useDocumentsList.tsx +305 -0
  506. package/src/modules/documents/ce.ts +6 -0
  507. package/src/modules/documents/commands/aggregate.ts +128 -0
  508. package/src/modules/documents/commands/attachments.ts +309 -0
  509. package/src/modules/documents/commands/comments.ts +966 -0
  510. package/src/modules/documents/commands/content.ts +294 -0
  511. package/src/modules/documents/commands/document-crud.ts +609 -0
  512. package/src/modules/documents/commands/documents.ts +581 -0
  513. package/src/modules/documents/commands/duplicate.ts +772 -0
  514. package/src/modules/documents/commands/favorites.ts +171 -0
  515. package/src/modules/documents/commands/folders.ts +506 -0
  516. package/src/modules/documents/commands/index.ts +33 -0
  517. package/src/modules/documents/commands/interceptors.ts +402 -0
  518. package/src/modules/documents/commands/lifecycle.ts +333 -0
  519. package/src/modules/documents/commands/links.ts +486 -0
  520. package/src/modules/documents/commands/mutation-helpers.ts +48 -0
  521. package/src/modules/documents/commands/projection-types.ts +77 -0
  522. package/src/modules/documents/commands/shared.ts +219 -0
  523. package/src/modules/documents/commands/shares.ts +612 -0
  524. package/src/modules/documents/commands/side-effects.ts +130 -0
  525. package/src/modules/documents/commands/templates.ts +522 -0
  526. package/src/modules/documents/commands/versions.ts +537 -0
  527. package/src/modules/documents/commands/watchers.ts +181 -0
  528. package/src/modules/documents/data/entities.ts +631 -0
  529. package/src/modules/documents/data/extensions.ts +42 -0
  530. package/src/modules/documents/data/validators.ts +248 -0
  531. package/src/modules/documents/di.ts +33 -0
  532. package/src/modules/documents/encryption.ts +14 -0
  533. package/src/modules/documents/events.ts +23 -0
  534. package/src/modules/documents/i18n/.hardcoded-allowlist.json +9 -0
  535. package/src/modules/documents/i18n/de.json +522 -0
  536. package/src/modules/documents/i18n/en.json +522 -0
  537. package/src/modules/documents/i18n/es.json +522 -0
  538. package/src/modules/documents/i18n/ko.json +522 -0
  539. package/src/modules/documents/i18n/pl.json +522 -0
  540. package/src/modules/documents/index.ts +17 -0
  541. package/src/modules/documents/lib/attachmentServicePort.ts +94 -0
  542. package/src/modules/documents/lib/capabilities.ts +57 -0
  543. package/src/modules/documents/lib/collabCloseEvents.ts +26 -0
  544. package/src/modules/documents/lib/collabEndpoint.ts +43 -0
  545. package/src/modules/documents/lib/collabMaterializer.ts +140 -0
  546. package/src/modules/documents/lib/collabToken.ts +170 -0
  547. package/src/modules/documents/lib/collaborationAwareness.ts +102 -0
  548. package/src/modules/documents/lib/commentAnchors.ts +19 -0
  549. package/src/modules/documents/lib/constants.ts +39 -0
  550. package/src/modules/documents/lib/contentService.ts +340 -0
  551. package/src/modules/documents/lib/displayLabels.ts +31 -0
  552. package/src/modules/documents/lib/docxRenderer.ts +685 -0
  553. package/src/modules/documents/lib/duplicateContent.ts +32 -0
  554. package/src/modules/documents/lib/editorConfig.ts +371 -0
  555. package/src/modules/documents/lib/entityLinks.ts +250 -0
  556. package/src/modules/documents/lib/entityRegistry.server.ts +267 -0
  557. package/src/modules/documents/lib/entityRegistry.ts +345 -0
  558. package/src/modules/documents/lib/entityRegistryAvailability.server.ts +19 -0
  559. package/src/modules/documents/lib/entitySuggestion.ts +61 -0
  560. package/src/modules/documents/lib/favorites.ts +35 -0
  561. package/src/modules/documents/lib/folderHierarchySerialization.ts +34 -0
  562. package/src/modules/documents/lib/historyLimits.ts +154 -0
  563. package/src/modules/documents/lib/historyPolicy.ts +7 -0
  564. package/src/modules/documents/lib/organizationAccess.ts +44 -0
  565. package/src/modules/documents/lib/pdfHtml.ts +65 -0
  566. package/src/modules/documents/lib/pdfRenderer.ts +367 -0
  567. package/src/modules/documents/lib/permissions.ts +299 -0
  568. package/src/modules/documents/lib/platformServices.ts +70 -0
  569. package/src/modules/documents/lib/recordFieldInsertion.ts +72 -0
  570. package/src/modules/documents/lib/requestBody.ts +97 -0
  571. package/src/modules/documents/lib/resourceLimits.ts +94 -0
  572. package/src/modules/documents/lib/shareCounts.ts +44 -0
  573. package/src/modules/documents/lib/templateFill.ts +138 -0
  574. package/src/modules/documents/lib/templateInstantiation.ts +206 -0
  575. package/src/modules/documents/lib/templatePreviewDigest.ts +122 -0
  576. package/src/modules/documents/lib/templateSeeds.ts +248 -0
  577. package/src/modules/documents/lib/userLabels.ts +58 -0
  578. package/src/modules/documents/lib/versionContent.ts +163 -0
  579. package/src/modules/documents/lib/versionLabels.ts +9 -0
  580. package/src/modules/documents/lib/versioning.ts +29 -0
  581. package/src/modules/documents/lib/visibility.ts +610 -0
  582. package/src/modules/documents/lib/watchers.ts +129 -0
  583. package/src/modules/documents/migrations/.snapshot-open-mercato.json +2892 -0
  584. package/src/modules/documents/migrations/Migration20260708163836_documents.ts +50 -0
  585. package/src/modules/documents/migrations/Migration20260709164720_documents.ts +19 -0
  586. package/src/modules/documents/migrations/Migration20260710002318_documents.ts +35 -0
  587. package/src/modules/documents/migrations/Migration20260710071003_documents.ts +13 -0
  588. package/src/modules/documents/migrations/Migration20260712120000_documents.ts +13 -0
  589. package/src/modules/documents/migrations/Migration20260712183000_documents.ts +12 -0
  590. package/src/modules/documents/migrations/Migration20260713092156_documents.ts +43 -0
  591. package/src/modules/documents/migrations/Migration20260717000000_documents.ts +40 -0
  592. package/src/modules/documents/notifications.ts +45 -0
  593. package/src/modules/documents/search.ts +118 -0
  594. package/src/modules/documents/setup.ts +19 -0
  595. package/src/modules/documents/widgets/injection/related-documents/LinkDocumentDialog.tsx +224 -0
  596. package/src/modules/documents/widgets/injection/related-documents/context.ts +101 -0
  597. package/src/modules/documents/widgets/injection/related-documents/useRelatedDocuments.ts +112 -0
  598. package/src/modules/documents/widgets/injection/related-documents/widget.client.tsx +76 -0
  599. package/src/modules/documents/widgets/injection/related-documents/widget.ts +19 -0
  600. package/src/modules/documents/widgets/injection-table.ts +20 -0
  601. package/tsconfig.json +9 -0
  602. package/watch.mjs +6 -0
@@ -0,0 +1,422 @@
1
+ import { raw } from "@mikro-orm/core";
2
+ import { escapeLikePattern } from "@open-mercato/shared/lib/db/escapeLikePattern";
3
+ import { findOneWithDecryption, findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
4
+ import { Document, DocumentFolder } from "../data/entities.js";
5
+ import { DOCUMENTS_MAX_FOLDER_DEPTH, DOCUMENTS_MAX_LISTED_FOLDERS } from "./constants.js";
6
+ function normalizeRoleIds(roleIds) {
7
+ return Array.from(new Set(roleIds.map((roleId) => roleId.trim()).filter(Boolean)));
8
+ }
9
+ function principalPredicate(shareAlias, userId, roleIds) {
10
+ const normalizedRoleIds = normalizeRoleIds(roleIds);
11
+ if (normalizedRoleIds.length === 0) {
12
+ return {
13
+ sql: `(${shareAlias}.principal_type = 'user' and ${shareAlias}.principal_id = ?)`,
14
+ params: [userId]
15
+ };
16
+ }
17
+ const rolePlaceholders = normalizedRoleIds.map(() => "?").join(", ");
18
+ return {
19
+ sql: `(
20
+ (${shareAlias}.principal_type = 'user' and ${shareAlias}.principal_id = ?)
21
+ or (${shareAlias}.principal_type = 'role' and ${shareAlias}.principal_id in (${rolePlaceholders}))
22
+ )`,
23
+ params: [userId, ...normalizedRoleIds]
24
+ };
25
+ }
26
+ function activeSharePredicate(shareAlias, documentAlias, input) {
27
+ const principal = principalPredicate(shareAlias, input.userId, input.roleIds);
28
+ return {
29
+ sql: `
30
+ ${shareAlias}.document_id = ${documentAlias}.id
31
+ and ${shareAlias}.tenant_id = ?
32
+ and ${shareAlias}.organization_id = ?
33
+ and ${shareAlias}.deleted_at is null
34
+ and ${principal.sql}
35
+ `,
36
+ params: [input.tenantId, input.organizationId, ...principal.params]
37
+ };
38
+ }
39
+ function relationshipTierSelection(input) {
40
+ const share = activeSharePredicate("tier_share", "document", input);
41
+ return raw(`
42
+ case
43
+ when document.owner_user_id = ? then 'owner'
44
+ else (
45
+ select tier_share.permission
46
+ from document_shares as tier_share
47
+ where ${share.sql}
48
+ order by case tier_share.permission
49
+ when 'editor' then 3
50
+ when 'commenter' then 2
51
+ when 'viewer' then 1
52
+ else 0
53
+ end desc
54
+ limit 1
55
+ )
56
+ end as "relationshipTier"
57
+ `, [input.userId, ...share.params]);
58
+ }
59
+ function addDocumentVisibilityPredicate(query, input) {
60
+ if (input.managerOverride) return;
61
+ const share = activeSharePredicate("visible_share", "document", input);
62
+ query.andWhere(`(
63
+ document.owner_user_id = ?
64
+ or exists (
65
+ select 1
66
+ from document_shares as visible_share
67
+ where ${share.sql}
68
+ )
69
+ )`, [input.userId, ...share.params]);
70
+ }
71
+ const RELATION_TARGET_COLUMNS = {
72
+ "customer-person": "customer_entity_id",
73
+ "customer-company": "customer_entity_id",
74
+ deal: "deal_id",
75
+ product: "product_id",
76
+ "catalog-offer": "catalog_offer_id",
77
+ quote: "quote_id",
78
+ "sales-order": "sales_order_id",
79
+ document: "linked_document_id"
80
+ };
81
+ function addDocumentRelationPredicate(query, input) {
82
+ if (!input.relationFilter) return;
83
+ const column = RELATION_TARGET_COLUMNS[input.relationFilter.entityType];
84
+ const customerKind = input.relationFilter.entityType === "customer-person" ? "person" : input.relationFilter.entityType === "customer-company" ? "company" : null;
85
+ query.andWhere(`exists (
86
+ select 1
87
+ from document_entity_links as relation_link
88
+ where relation_link.document_id = document.id
89
+ and relation_link.tenant_id = ?
90
+ and relation_link.organization_id = ?
91
+ and relation_link.deleted_at is null
92
+ and relation_link.${column} = ?
93
+ ${customerKind ? "and relation_link.customer_kind = ?" : ""}
94
+ )`, [
95
+ input.tenantId,
96
+ input.organizationId,
97
+ input.relationFilter.entityId,
98
+ ...customerKind ? [customerKind] : []
99
+ ]);
100
+ }
101
+ function addDocumentFavoritePredicate(query, input) {
102
+ if (!input.favoriteUserId) return;
103
+ query.andWhere(`exists (
104
+ select 1
105
+ from document_favorites as document_favorite
106
+ where document_favorite.document_id = document.id
107
+ and document_favorite.tenant_id = ?
108
+ and document_favorite.organization_id = ?
109
+ and document_favorite.user_id = ?
110
+ and document_favorite.deleted_at is null
111
+ )`, [input.tenantId, input.organizationId, input.favoriteUserId]);
112
+ }
113
+ function normalizeTier(value) {
114
+ return value === "owner" || value === "editor" || value === "commenter" || value === "viewer" ? value : null;
115
+ }
116
+ function normalizeTotal(value) {
117
+ const parsed = typeof value === "bigint" ? Number(value) : Number(value ?? 0);
118
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
119
+ }
120
+ function assertPageInput(page, pageSize) {
121
+ if (!Number.isInteger(page) || page < 1 || !Number.isInteger(pageSize) || pageSize < 1 || pageSize > 100) {
122
+ throw new Error("[internal] Invalid visible document page request");
123
+ }
124
+ }
125
+ function buildVisibleDocumentQuery(input) {
126
+ const archived = input.archived ?? "exclude";
127
+ const query = input.em.createQueryBuilder(Document, "document").where({
128
+ tenantId: input.tenantId,
129
+ organizationId: input.organizationId,
130
+ deletedAt: null,
131
+ ...input.id ? { id: input.id } : {},
132
+ ...!input.id && archived === "exclude" ? { archivedAt: null } : {},
133
+ ...!input.id && archived === "only" ? { archivedAt: { $ne: null } } : {}
134
+ });
135
+ addDocumentVisibilityPredicate(query, input);
136
+ addDocumentRelationPredicate(query, input);
137
+ addDocumentFavoritePredicate(query, input);
138
+ if (input.search?.trim()) {
139
+ query.andWhere("document.title ilike ?", [`%${escapeLikePattern(input.search.trim())}%`]);
140
+ }
141
+ if (input.folderId) {
142
+ query.andWhere({ folderId: input.folderId });
143
+ }
144
+ return query;
145
+ }
146
+ async function getVisibleDocumentPage(input) {
147
+ assertPageInput(input.page, input.pageSize);
148
+ const query = buildVisibleDocumentQuery(input).select([
149
+ "document.id",
150
+ relationshipTierSelection(input),
151
+ raw('count(*) over() as "total"')
152
+ ]);
153
+ const rawRows = await query.orderBy({ updatedAt: "DESC", id: "ASC" }).limit(input.pageSize).offset((input.page - 1) * input.pageSize).execute("all", false);
154
+ const rows = rawRows.flatMap((row) => {
155
+ if (typeof row.id !== "string" || row.id.length === 0) return [];
156
+ return [{
157
+ id: row.id,
158
+ relationshipTier: normalizeTier(row.relationshipTier ?? row.relationship_tier),
159
+ total: normalizeTotal(row.total)
160
+ }];
161
+ });
162
+ if (rows.length > 0 || input.page === 1) {
163
+ return { rows, total: rows[0]?.total ?? 0 };
164
+ }
165
+ const total = await buildVisibleDocumentQuery(input).getCount("document.id");
166
+ return { rows, total: normalizeTotal(total) };
167
+ }
168
+ async function getDirectVisibleFolderIds(input) {
169
+ const query = input.em.createQueryBuilder(Document, "document").select("document.folderId", true).where({
170
+ tenantId: input.tenantId,
171
+ organizationId: input.organizationId,
172
+ deletedAt: null,
173
+ folderId: { $ne: null }
174
+ });
175
+ addDocumentVisibilityPredicate(query, input);
176
+ const rows = await query.execute("all");
177
+ return new Set(rows.flatMap((row) => {
178
+ const folderId = row.folderId ?? row.folder_id;
179
+ return typeof folderId === "string" && folderId.length > 0 ? [folderId] : [];
180
+ }));
181
+ }
182
+ function assertFolderHierarchyContract(foldersById, requiredFolderIds) {
183
+ if (requiredFolderIds) {
184
+ for (const folderId of requiredFolderIds) {
185
+ if (!foldersById.has(folderId)) {
186
+ throw new Error("[internal] Visible folder hierarchy contains an unresolved folder");
187
+ }
188
+ }
189
+ }
190
+ for (const folder of foldersById.values()) {
191
+ const visited = /* @__PURE__ */ new Set();
192
+ let current = folder;
193
+ let depth = 0;
194
+ while (current) {
195
+ if (visited.has(current.id)) {
196
+ throw new Error("[internal] Folder hierarchy contains a cycle");
197
+ }
198
+ visited.add(current.id);
199
+ depth += 1;
200
+ if (depth > DOCUMENTS_MAX_FOLDER_DEPTH) {
201
+ throw new Error("[internal] Folder hierarchy exceeds the supported depth");
202
+ }
203
+ if (!current.parentFolderId) break;
204
+ current = foldersById.get(current.parentFolderId);
205
+ if (!current) {
206
+ throw new Error("[internal] Folder hierarchy contains an unresolved ancestor");
207
+ }
208
+ }
209
+ }
210
+ }
211
+ function retainFoldersReachableFromRoots(folders) {
212
+ const childrenByParentId = /* @__PURE__ */ new Map();
213
+ for (const folder of folders) {
214
+ if (!folder.parentFolderId) continue;
215
+ const siblings = childrenByParentId.get(folder.parentFolderId);
216
+ if (siblings) siblings.push(folder);
217
+ else childrenByParentId.set(folder.parentFolderId, [folder]);
218
+ }
219
+ const reachableIds = /* @__PURE__ */ new Set();
220
+ const pending = folders.filter((folder) => !folder.parentFolderId);
221
+ for (let index = 0; index < pending.length; index += 1) {
222
+ const folder = pending[index];
223
+ reachableIds.add(folder.id);
224
+ const children = childrenByParentId.get(folder.id);
225
+ if (children) pending.push(...children);
226
+ }
227
+ return folders.filter((folder) => reachableIds.has(folder.id));
228
+ }
229
+ async function getVisibleFolders(input) {
230
+ const scope = {
231
+ tenantId: input.tenantId,
232
+ organizationId: input.organizationId,
233
+ deletedAt: null
234
+ };
235
+ if (input.managerOverride) {
236
+ const folders = await findWithDecryption(
237
+ input.em,
238
+ DocumentFolder,
239
+ scope,
240
+ { orderBy: { name: "ASC" }, limit: DOCUMENTS_MAX_LISTED_FOLDERS + 1 },
241
+ { tenantId: input.tenantId, organizationId: input.organizationId }
242
+ );
243
+ const listed = folders.length > DOCUMENTS_MAX_LISTED_FOLDERS ? retainFoldersReachableFromRoots(folders.slice(0, DOCUMENTS_MAX_LISTED_FOLDERS)) : folders;
244
+ assertFolderHierarchyContract(new Map(listed.map((folder) => [folder.id, folder])));
245
+ return listed.map((folder) => ({
246
+ folder,
247
+ canEdit: input.canEditAction,
248
+ visibility: "owned"
249
+ }));
250
+ }
251
+ const [ownedFolders, directlyVisibleFolderIds] = await Promise.all([
252
+ findWithDecryption(
253
+ input.em,
254
+ DocumentFolder,
255
+ { ...scope, ownerUserId: input.userId },
256
+ void 0,
257
+ { tenantId: input.tenantId, organizationId: input.organizationId }
258
+ ),
259
+ getDirectVisibleFolderIds(input)
260
+ ]);
261
+ const foldersById = new Map(ownedFolders.map((folder) => [folder.id, folder]));
262
+ const visibilityById = /* @__PURE__ */ new Map();
263
+ for (const folder of ownedFolders) visibilityById.set(folder.id, "owned");
264
+ for (const folderId of directlyVisibleFolderIds) {
265
+ if (!visibilityById.has(folderId)) visibilityById.set(folderId, "contains-visible");
266
+ }
267
+ let pendingIds = new Set([
268
+ ...directlyVisibleFolderIds,
269
+ ...ownedFolders.flatMap((folder) => folder.parentFolderId ? [folder.parentFolderId] : [])
270
+ ].filter((folderId) => !foldersById.has(folderId)));
271
+ for (let depth = 0; pendingIds.size > 0 && depth < DOCUMENTS_MAX_FOLDER_DEPTH; depth += 1) {
272
+ const batchIds = Array.from(pendingIds);
273
+ pendingIds = /* @__PURE__ */ new Set();
274
+ const folders = await findWithDecryption(
275
+ input.em,
276
+ DocumentFolder,
277
+ {
278
+ ...scope,
279
+ id: { $in: batchIds }
280
+ },
281
+ void 0,
282
+ { tenantId: input.tenantId, organizationId: input.organizationId }
283
+ );
284
+ for (const folder of folders) {
285
+ foldersById.set(folder.id, folder);
286
+ if (!visibilityById.has(folder.id)) visibilityById.set(folder.id, "ancestor");
287
+ if (folder.parentFolderId && !foldersById.has(folder.parentFolderId)) {
288
+ pendingIds.add(folder.parentFolderId);
289
+ }
290
+ }
291
+ }
292
+ if (pendingIds.size > 0) {
293
+ throw new Error("[internal] Folder hierarchy exceeds the supported depth");
294
+ }
295
+ assertFolderHierarchyContract(foldersById, visibilityById.keys());
296
+ return Array.from(foldersById.values()).sort((left, right) => left.name.localeCompare(right.name)).map((folder) => ({
297
+ folder,
298
+ canEdit: input.canEditAction && folder.ownerUserId === input.userId,
299
+ visibility: visibilityById.get(folder.id) ?? "ancestor"
300
+ }));
301
+ }
302
+ async function inspectFolderAncestors(input) {
303
+ const scope = {
304
+ tenantId: input.tenantId,
305
+ organizationId: input.organizationId,
306
+ deletedAt: null
307
+ };
308
+ const visited = /* @__PURE__ */ new Set();
309
+ let ancestorId = input.parentFolderId;
310
+ let depth = 0;
311
+ while (ancestorId) {
312
+ if (ancestorId === input.folderId || visited.has(ancestorId)) {
313
+ return { depth, issue: "cycle" };
314
+ }
315
+ if (depth >= DOCUMENTS_MAX_FOLDER_DEPTH) {
316
+ return { depth, issue: "depth" };
317
+ }
318
+ visited.add(ancestorId);
319
+ const ancestor = await findOneWithDecryption(
320
+ input.em,
321
+ DocumentFolder,
322
+ {
323
+ ...scope,
324
+ id: ancestorId
325
+ },
326
+ void 0,
327
+ { tenantId: input.tenantId, organizationId: input.organizationId }
328
+ );
329
+ if (!ancestor) return { depth, issue: "missing-parent" };
330
+ depth += 1;
331
+ ancestorId = ancestor.parentFolderId ?? null;
332
+ }
333
+ return { depth, issue: null };
334
+ }
335
+ async function inspectFolderSubtree(input, parentDepth) {
336
+ const scope = {
337
+ tenantId: input.tenantId,
338
+ organizationId: input.organizationId,
339
+ deletedAt: null
340
+ };
341
+ const visited = /* @__PURE__ */ new Set([input.folderId]);
342
+ let frontier = [input.folderId];
343
+ let subtreeDepth = 1;
344
+ while (frontier.length > 0) {
345
+ if (parentDepth + subtreeDepth > DOCUMENTS_MAX_FOLDER_DEPTH) return "depth";
346
+ const children = await findWithDecryption(
347
+ input.em,
348
+ DocumentFolder,
349
+ {
350
+ ...scope,
351
+ parentFolderId: { $in: frontier }
352
+ },
353
+ { fields: ["id", "parentFolderId"] },
354
+ { tenantId: input.tenantId, organizationId: input.organizationId }
355
+ );
356
+ if (children.length === 0) return null;
357
+ const nextFrontier = [];
358
+ for (const child of children) {
359
+ if (visited.has(child.id)) return "cycle";
360
+ visited.add(child.id);
361
+ nextFrontier.push(child.id);
362
+ }
363
+ frontier = nextFrontier;
364
+ subtreeDepth += 1;
365
+ }
366
+ return null;
367
+ }
368
+ async function getFolderPlacementIssue(input) {
369
+ const ancestors = await inspectFolderAncestors(input);
370
+ if (ancestors.issue) return ancestors.issue;
371
+ if (!input.folderId) {
372
+ return ancestors.depth + 1 > DOCUMENTS_MAX_FOLDER_DEPTH ? "depth" : null;
373
+ }
374
+ return inspectFolderSubtree({
375
+ em: input.em,
376
+ tenantId: input.tenantId,
377
+ organizationId: input.organizationId,
378
+ folderId: input.folderId
379
+ }, ancestors.depth);
380
+ }
381
+ async function wouldCreateFolderCycle(input) {
382
+ const inspection = await inspectFolderAncestors(input);
383
+ return inspection.issue === "cycle" || inspection.issue === "depth";
384
+ }
385
+ async function hasActiveFolderContents(input) {
386
+ const scope = {
387
+ tenantId: input.tenantId,
388
+ organizationId: input.organizationId,
389
+ deletedAt: null
390
+ };
391
+ const [childFolder, document] = await Promise.all([
392
+ findOneWithDecryption(
393
+ input.em,
394
+ DocumentFolder,
395
+ {
396
+ ...scope,
397
+ parentFolderId: input.folderId
398
+ },
399
+ { fields: ["id"] },
400
+ { tenantId: input.tenantId, organizationId: input.organizationId }
401
+ ),
402
+ findOneWithDecryption(
403
+ input.em,
404
+ Document,
405
+ {
406
+ ...scope,
407
+ folderId: input.folderId
408
+ },
409
+ { fields: ["id"] },
410
+ { tenantId: input.tenantId, organizationId: input.organizationId }
411
+ )
412
+ ]);
413
+ return Boolean(childFolder || document);
414
+ }
415
+ export {
416
+ getFolderPlacementIssue,
417
+ getVisibleDocumentPage,
418
+ getVisibleFolders,
419
+ hasActiveFolderContents,
420
+ wouldCreateFolderCycle
421
+ };
422
+ //# sourceMappingURL=visibility.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/documents/lib/visibility.ts"],
4
+ "sourcesContent": ["import { raw } from '@mikro-orm/core'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { escapeLikePattern } from '@open-mercato/shared/lib/db/escapeLikePattern'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { Document, DocumentFolder } from '../data/entities'\nimport type { DocumentEntityType } from '../data/validators'\nimport { DOCUMENTS_MAX_FOLDER_DEPTH, DOCUMENTS_MAX_LISTED_FOLDERS } from './constants'\nimport type { DocumentTier } from './permissions'\n\nexport type VisibleDocumentPageRow = {\n id: string\n relationshipTier: DocumentTier | null\n total: number\n}\n\nexport type VisibleDocumentPage = {\n rows: VisibleDocumentPageRow[]\n total: number\n}\n\nexport type GetVisibleDocumentPageInput = {\n em: EntityManager\n tenantId: string\n organizationId: string\n userId: string\n roleIds: readonly string[]\n managerOverride: boolean\n page: number\n pageSize: number\n id?: string | null\n archived?: 'exclude' | 'include' | 'only'\n favoriteUserId?: string | null\n search?: string | null\n folderId?: string | null\n relationFilter?: { entityType: DocumentEntityType; entityId: string } | null\n}\n\nexport type FolderVisibility = 'owned' | 'contains-visible' | 'ancestor'\n\nexport type VisibleFolderRow = {\n folder: DocumentFolder\n canEdit: boolean\n visibility: FolderVisibility\n}\n\nexport type GetVisibleFoldersInput = Pick<\n GetVisibleDocumentPageInput,\n 'em' | 'tenantId' | 'organizationId' | 'userId' | 'roleIds' | 'managerOverride'\n> & {\n canEditAction: boolean\n}\n\nexport type FolderMutationScope = Pick<\n GetVisibleFoldersInput,\n 'em' | 'tenantId' | 'organizationId'\n>\n\nexport type FolderPlacementIssue = 'cycle' | 'depth' | 'missing-parent'\n\ntype RawVisibleDocumentRow = {\n id?: unknown\n relationshipTier?: unknown\n relationship_tier?: unknown\n total?: unknown\n}\n\ntype RawFolderIdRow = {\n folderId?: unknown\n folder_id?: unknown\n}\n\ntype PrincipalPredicate = {\n sql: string\n params: string[]\n}\n\ntype VisibilityPredicateQuery = {\n andWhere(condition: string, params?: string[]): unknown\n}\n\nfunction normalizeRoleIds(roleIds: readonly string[]): string[] {\n return Array.from(new Set(roleIds.map((roleId) => roleId.trim()).filter(Boolean)))\n}\n\nfunction principalPredicate(\n shareAlias: string,\n userId: string,\n roleIds: readonly string[],\n): PrincipalPredicate {\n const normalizedRoleIds = normalizeRoleIds(roleIds)\n if (normalizedRoleIds.length === 0) {\n return {\n sql: `(${shareAlias}.principal_type = 'user' and ${shareAlias}.principal_id = ?)`,\n params: [userId],\n }\n }\n\n const rolePlaceholders = normalizedRoleIds.map(() => '?').join(', ')\n return {\n sql: `(\n (${shareAlias}.principal_type = 'user' and ${shareAlias}.principal_id = ?)\n or (${shareAlias}.principal_type = 'role' and ${shareAlias}.principal_id in (${rolePlaceholders}))\n )`,\n params: [userId, ...normalizedRoleIds],\n }\n}\n\nfunction activeSharePredicate(\n shareAlias: string,\n documentAlias: string,\n input: Pick<GetVisibleDocumentPageInput, 'tenantId' | 'organizationId' | 'userId' | 'roleIds'>,\n): PrincipalPredicate {\n const principal = principalPredicate(shareAlias, input.userId, input.roleIds)\n return {\n sql: `\n ${shareAlias}.document_id = ${documentAlias}.id\n and ${shareAlias}.tenant_id = ?\n and ${shareAlias}.organization_id = ?\n and ${shareAlias}.deleted_at is null\n and ${principal.sql}\n `,\n params: [input.tenantId, input.organizationId, ...principal.params],\n }\n}\n\nfunction relationshipTierSelection(input: GetVisibleDocumentPageInput) {\n const share = activeSharePredicate('tier_share', 'document', input)\n return raw(`\n case\n when document.owner_user_id = ? then 'owner'\n else (\n select tier_share.permission\n from document_shares as tier_share\n where ${share.sql}\n order by case tier_share.permission\n when 'editor' then 3\n when 'commenter' then 2\n when 'viewer' then 1\n else 0\n end desc\n limit 1\n )\n end as \"relationshipTier\"\n `, [input.userId, ...share.params])\n}\n\nfunction addDocumentVisibilityPredicate(\n query: VisibilityPredicateQuery,\n input: Pick<\n GetVisibleDocumentPageInput,\n 'tenantId' | 'organizationId' | 'userId' | 'roleIds' | 'managerOverride'\n >,\n): void {\n if (input.managerOverride) return\n const share = activeSharePredicate('visible_share', 'document', input)\n query.andWhere(`(\n document.owner_user_id = ?\n or exists (\n select 1\n from document_shares as visible_share\n where ${share.sql}\n )\n )`, [input.userId, ...share.params])\n}\n\nconst RELATION_TARGET_COLUMNS: Record<DocumentEntityType, string> = {\n 'customer-person': 'customer_entity_id',\n 'customer-company': 'customer_entity_id',\n deal: 'deal_id',\n product: 'product_id',\n 'catalog-offer': 'catalog_offer_id',\n quote: 'quote_id',\n 'sales-order': 'sales_order_id',\n document: 'linked_document_id',\n}\n\nfunction addDocumentRelationPredicate(\n query: VisibilityPredicateQuery,\n input: Pick<GetVisibleDocumentPageInput, 'tenantId' | 'organizationId' | 'relationFilter'>,\n): void {\n if (!input.relationFilter) return\n const column = RELATION_TARGET_COLUMNS[input.relationFilter.entityType]\n const customerKind = input.relationFilter.entityType === 'customer-person'\n ? 'person'\n : input.relationFilter.entityType === 'customer-company'\n ? 'company'\n : null\n query.andWhere(`exists (\n select 1\n from document_entity_links as relation_link\n where relation_link.document_id = document.id\n and relation_link.tenant_id = ?\n and relation_link.organization_id = ?\n and relation_link.deleted_at is null\n and relation_link.${column} = ?\n ${customerKind ? 'and relation_link.customer_kind = ?' : ''}\n )`, [\n input.tenantId,\n input.organizationId,\n input.relationFilter.entityId,\n ...(customerKind ? [customerKind] : []),\n ])\n}\n\nfunction addDocumentFavoritePredicate(\n query: VisibilityPredicateQuery,\n input: Pick<\n GetVisibleDocumentPageInput,\n 'tenantId' | 'organizationId' | 'favoriteUserId'\n >,\n): void {\n if (!input.favoriteUserId) return\n query.andWhere(`exists (\n select 1\n from document_favorites as document_favorite\n where document_favorite.document_id = document.id\n and document_favorite.tenant_id = ?\n and document_favorite.organization_id = ?\n and document_favorite.user_id = ?\n and document_favorite.deleted_at is null\n )`, [input.tenantId, input.organizationId, input.favoriteUserId])\n}\n\nfunction normalizeTier(value: unknown): DocumentTier | null {\n return value === 'owner' || value === 'editor' || value === 'commenter' || value === 'viewer'\n ? value\n : null\n}\n\nfunction normalizeTotal(value: unknown): number {\n const parsed = typeof value === 'bigint' ? Number(value) : Number(value ?? 0)\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0\n}\n\nfunction assertPageInput(page: number, pageSize: number): void {\n if (!Number.isInteger(page) || page < 1 || !Number.isInteger(pageSize) || pageSize < 1 || pageSize > 100) {\n throw new Error('[internal] Invalid visible document page request')\n }\n}\n\nfunction buildVisibleDocumentQuery(input: GetVisibleDocumentPageInput) {\n const archived = input.archived ?? 'exclude'\n const query = input.em\n .createQueryBuilder(Document, 'document')\n .where({\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n ...(input.id ? { id: input.id } : {}),\n ...(!input.id && archived === 'exclude' ? { archivedAt: null } : {}),\n ...(!input.id && archived === 'only' ? { archivedAt: { $ne: null } } : {}),\n })\n\n addDocumentVisibilityPredicate(query, input)\n addDocumentRelationPredicate(query, input)\n addDocumentFavoritePredicate(query, input)\n if (input.search?.trim()) {\n query.andWhere('document.title ilike ?', [`%${escapeLikePattern(input.search.trim())}%`])\n }\n if (input.folderId) {\n query.andWhere({ folderId: input.folderId })\n }\n return query\n}\n\nexport async function getVisibleDocumentPage(\n input: GetVisibleDocumentPageInput,\n): Promise<VisibleDocumentPage> {\n assertPageInput(input.page, input.pageSize)\n\n const query = buildVisibleDocumentQuery(input)\n .select([\n 'document.id',\n relationshipTierSelection(input),\n raw('count(*) over() as \"total\"'),\n ])\n const rawRows = await query\n .orderBy({ updatedAt: 'DESC', id: 'ASC' })\n .limit(input.pageSize)\n .offset((input.page - 1) * input.pageSize)\n .execute<RawVisibleDocumentRow[]>('all', false)\n\n const rows = rawRows.flatMap((row): VisibleDocumentPageRow[] => {\n if (typeof row.id !== 'string' || row.id.length === 0) return []\n return [{\n id: row.id,\n relationshipTier: normalizeTier(row.relationshipTier ?? row.relationship_tier),\n total: normalizeTotal(row.total),\n }]\n })\n if (rows.length > 0 || input.page === 1) {\n return { rows, total: rows[0]?.total ?? 0 }\n }\n\n // A window count has no carrier row when the requested offset is beyond the\n // last page. Keep the fast one-query path for normal pages and issue one\n // bounded fallback count only for an empty out-of-range page.\n const total = await buildVisibleDocumentQuery(input).getCount('document.id')\n return { rows, total: normalizeTotal(total) }\n}\n\nasync function getDirectVisibleFolderIds(input: GetVisibleFoldersInput): Promise<Set<string>> {\n const query = input.em\n .createQueryBuilder(Document, 'document')\n .select('document.folderId', true)\n .where({\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n folderId: { $ne: null },\n })\n addDocumentVisibilityPredicate(query, input)\n\n const rows = await query.execute<RawFolderIdRow[]>('all')\n return new Set(rows.flatMap((row) => {\n const folderId = row.folderId ?? row.folder_id\n return typeof folderId === 'string' && folderId.length > 0 ? [folderId] : []\n }))\n}\n\nfunction assertFolderHierarchyContract(\n foldersById: ReadonlyMap<string, DocumentFolder>,\n requiredFolderIds?: Iterable<string>,\n): void {\n if (requiredFolderIds) {\n for (const folderId of requiredFolderIds) {\n if (!foldersById.has(folderId)) {\n throw new Error('[internal] Visible folder hierarchy contains an unresolved folder')\n }\n }\n }\n\n for (const folder of foldersById.values()) {\n const visited = new Set<string>()\n let current: DocumentFolder | undefined = folder\n let depth = 0\n while (current) {\n if (visited.has(current.id)) {\n throw new Error('[internal] Folder hierarchy contains a cycle')\n }\n visited.add(current.id)\n depth += 1\n if (depth > DOCUMENTS_MAX_FOLDER_DEPTH) {\n throw new Error('[internal] Folder hierarchy exceeds the supported depth')\n }\n if (!current.parentFolderId) break\n current = foldersById.get(current.parentFolderId)\n if (!current) {\n throw new Error('[internal] Folder hierarchy contains an unresolved ancestor')\n }\n }\n }\n}\n\n/**\n * Truncating a name-ordered listing can cut a parent while keeping its\n * children. Retaining only what a root still reaches leaves a coherent tree the\n * organization can prune back under the cap, instead of failing the whole\n * listing on an ancestor the bound removed.\n */\nfunction retainFoldersReachableFromRoots(folders: readonly DocumentFolder[]): DocumentFolder[] {\n const childrenByParentId = new Map<string, DocumentFolder[]>()\n for (const folder of folders) {\n if (!folder.parentFolderId) continue\n const siblings = childrenByParentId.get(folder.parentFolderId)\n if (siblings) siblings.push(folder)\n else childrenByParentId.set(folder.parentFolderId, [folder])\n }\n\n const reachableIds = new Set<string>()\n const pending = folders.filter((folder) => !folder.parentFolderId)\n for (let index = 0; index < pending.length; index += 1) {\n const folder = pending[index]\n reachableIds.add(folder.id)\n const children = childrenByParentId.get(folder.id)\n if (children) pending.push(...children)\n }\n return folders.filter((folder) => reachableIds.has(folder.id))\n}\n\nexport async function getVisibleFolders(input: GetVisibleFoldersInput): Promise<VisibleFolderRow[]> {\n const scope = {\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n }\n if (input.managerOverride) {\n const folders = await findWithDecryption(\n input.em,\n DocumentFolder,\n scope,\n { orderBy: { name: 'ASC' }, limit: DOCUMENTS_MAX_LISTED_FOLDERS + 1 },\n { tenantId: input.tenantId, organizationId: input.organizationId },\n )\n // Creation is capped well below this bound, so only an organization that\n // predates the cap can overflow. Degrade that one to a listable subtree\n // rather than letting the hierarchy contract reject the whole listing.\n const listed = folders.length > DOCUMENTS_MAX_LISTED_FOLDERS\n ? retainFoldersReachableFromRoots(folders.slice(0, DOCUMENTS_MAX_LISTED_FOLDERS))\n : folders\n assertFolderHierarchyContract(new Map(listed.map((folder) => [folder.id, folder])))\n return listed.map((folder) => ({\n folder,\n canEdit: input.canEditAction,\n visibility: 'owned',\n }))\n }\n\n const [ownedFolders, directlyVisibleFolderIds] = await Promise.all([\n findWithDecryption(\n input.em,\n DocumentFolder,\n { ...scope, ownerUserId: input.userId },\n undefined,\n { tenantId: input.tenantId, organizationId: input.organizationId },\n ),\n getDirectVisibleFolderIds(input),\n ])\n const foldersById = new Map(ownedFolders.map((folder) => [folder.id, folder]))\n const visibilityById = new Map<string, FolderVisibility>()\n for (const folder of ownedFolders) visibilityById.set(folder.id, 'owned')\n for (const folderId of directlyVisibleFolderIds) {\n if (!visibilityById.has(folderId)) visibilityById.set(folderId, 'contains-visible')\n }\n\n let pendingIds = new Set<string>([\n ...directlyVisibleFolderIds,\n ...ownedFolders.flatMap((folder) => folder.parentFolderId ? [folder.parentFolderId] : []),\n ].filter((folderId) => !foldersById.has(folderId)))\n\n for (let depth = 0; pendingIds.size > 0 && depth < DOCUMENTS_MAX_FOLDER_DEPTH; depth += 1) {\n const batchIds = Array.from(pendingIds)\n pendingIds = new Set()\n const folders = await findWithDecryption(\n input.em,\n DocumentFolder,\n {\n ...scope,\n id: { $in: batchIds },\n },\n undefined,\n { tenantId: input.tenantId, organizationId: input.organizationId },\n )\n for (const folder of folders) {\n foldersById.set(folder.id, folder)\n if (!visibilityById.has(folder.id)) visibilityById.set(folder.id, 'ancestor')\n if (folder.parentFolderId && !foldersById.has(folder.parentFolderId)) {\n pendingIds.add(folder.parentFolderId)\n }\n }\n }\n\n if (pendingIds.size > 0) {\n throw new Error('[internal] Folder hierarchy exceeds the supported depth')\n }\n assertFolderHierarchyContract(foldersById, visibilityById.keys())\n\n return Array.from(foldersById.values())\n .sort((left, right) => left.name.localeCompare(right.name))\n .map((folder) => ({\n folder,\n canEdit: input.canEditAction && folder.ownerUserId === input.userId,\n visibility: visibilityById.get(folder.id) ?? 'ancestor',\n }))\n}\n\ntype AncestorInspection = {\n depth: number\n issue: FolderPlacementIssue | null\n}\n\nasync function inspectFolderAncestors(\n input: FolderMutationScope & { folderId?: string | null; parentFolderId: string | null },\n): Promise<AncestorInspection> {\n const scope = {\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n }\n const visited = new Set<string>()\n let ancestorId = input.parentFolderId\n let depth = 0\n\n while (ancestorId) {\n if (ancestorId === input.folderId || visited.has(ancestorId)) {\n return { depth, issue: 'cycle' }\n }\n if (depth >= DOCUMENTS_MAX_FOLDER_DEPTH) {\n return { depth, issue: 'depth' }\n }\n visited.add(ancestorId)\n const ancestor = await findOneWithDecryption(\n input.em,\n DocumentFolder,\n {\n ...scope,\n id: ancestorId,\n },\n undefined,\n { tenantId: input.tenantId, organizationId: input.organizationId },\n )\n if (!ancestor) return { depth, issue: 'missing-parent' }\n depth += 1\n ancestorId = ancestor.parentFolderId ?? null\n }\n\n return { depth, issue: null }\n}\n\nasync function inspectFolderSubtree(\n input: FolderMutationScope & { folderId: string },\n parentDepth: number,\n): Promise<FolderPlacementIssue | null> {\n const scope = {\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n }\n const visited = new Set([input.folderId])\n let frontier = [input.folderId]\n let subtreeDepth = 1\n\n while (frontier.length > 0) {\n if (parentDepth + subtreeDepth > DOCUMENTS_MAX_FOLDER_DEPTH) return 'depth'\n const children = await findWithDecryption(\n input.em,\n DocumentFolder,\n {\n ...scope,\n parentFolderId: { $in: frontier },\n },\n { fields: ['id', 'parentFolderId'] as const },\n { tenantId: input.tenantId, organizationId: input.organizationId },\n )\n if (children.length === 0) return null\n\n const nextFrontier: string[] = []\n for (const child of children) {\n if (visited.has(child.id)) return 'cycle'\n visited.add(child.id)\n nextFrontier.push(child.id)\n }\n frontier = nextFrontier\n subtreeDepth += 1\n }\n\n return null\n}\n\n/**\n * Validates a proposed create/move against the same depth contract used by\n * folder visibility. A move includes the deepest descendant of the moved\n * subtree, so relocating a shallow parent cannot push hidden descendants past\n * the supported depth.\n */\nexport async function getFolderPlacementIssue(\n input: FolderMutationScope & { folderId?: string | null; parentFolderId: string | null },\n): Promise<FolderPlacementIssue | null> {\n const ancestors = await inspectFolderAncestors(input)\n if (ancestors.issue) return ancestors.issue\n if (!input.folderId) {\n return ancestors.depth + 1 > DOCUMENTS_MAX_FOLDER_DEPTH ? 'depth' : null\n }\n return inspectFolderSubtree({\n em: input.em,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n folderId: input.folderId,\n }, ancestors.depth)\n}\n\nexport async function wouldCreateFolderCycle(\n input: FolderMutationScope & { folderId: string; parentFolderId: string },\n): Promise<boolean> {\n const inspection = await inspectFolderAncestors(input)\n return inspection.issue === 'cycle' || inspection.issue === 'depth'\n}\n\nexport async function hasActiveFolderContents(\n input: FolderMutationScope & { folderId: string },\n): Promise<boolean> {\n const scope = {\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n deletedAt: null,\n }\n const [childFolder, document] = await Promise.all([\n findOneWithDecryption(\n input.em,\n DocumentFolder,\n {\n ...scope,\n parentFolderId: input.folderId,\n },\n { fields: ['id'] as const },\n { tenantId: input.tenantId, organizationId: input.organizationId },\n ),\n findOneWithDecryption(\n input.em,\n Document,\n {\n ...scope,\n folderId: input.folderId,\n },\n { fields: ['id'] as const },\n { tenantId: input.tenantId, organizationId: input.organizationId },\n ),\n ])\n return Boolean(childFolder || document)\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,106 @@
1
+ import { findOneWithDecryption, findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
2
+ import { createLogger } from "@open-mercato/shared/lib/logger";
3
+ import { DocumentWatcher } from "../data/entities.js";
4
+ import { loadScopedDocument, resolveLoadedDocumentUserAccess } from "./permissions.js";
5
+ const logger = createLogger("documents").child({ component: "watchers" });
6
+ const DOCUMENTS_MAX_ACTIVE_WATCHERS = 100;
7
+ const WATCHER_ACCESS_RESOLUTION_CONCURRENCY = 4;
8
+ async function resolveWatcherRecipients(input) {
9
+ let watchers;
10
+ try {
11
+ watchers = await findWithDecryption(
12
+ input.em,
13
+ DocumentWatcher,
14
+ {
15
+ documentId: input.documentId,
16
+ tenantId: input.scope.tenantId,
17
+ organizationId: input.scope.organizationId,
18
+ deletedAt: null
19
+ },
20
+ {
21
+ fields: ["userId"],
22
+ orderBy: { createdAt: "ASC", id: "ASC" },
23
+ limit: DOCUMENTS_MAX_ACTIVE_WATCHERS
24
+ },
25
+ input.scope
26
+ );
27
+ } catch (error) {
28
+ logger.error("Watcher recipient lookup failed", {
29
+ documentId: input.documentId,
30
+ err: error
31
+ });
32
+ return [];
33
+ }
34
+ const excludedUserIds = /* @__PURE__ */ new Set([
35
+ input.actorUserId.toLowerCase(),
36
+ ...(input.excludeUserIds ?? []).map((userId) => userId.toLowerCase())
37
+ ]);
38
+ const candidates = watchers.filter(
39
+ (watcher) => !excludedUserIds.has(watcher.userId.toLowerCase())
40
+ );
41
+ if (candidates.length === 0) return [];
42
+ const scopedDocument = await loadScopedDocument(
43
+ input.em,
44
+ input.documentId,
45
+ input.scope
46
+ ).catch((error) => {
47
+ logger.error("Watcher document lookup failed", {
48
+ documentId: input.documentId,
49
+ err: error
50
+ });
51
+ return null;
52
+ });
53
+ if (!scopedDocument) return [];
54
+ const permitted = new Array(candidates.length).fill(null);
55
+ let nextIndex = 0;
56
+ const workers = Array.from(
57
+ { length: Math.min(WATCHER_ACCESS_RESOLUTION_CONCURRENCY, candidates.length) },
58
+ async () => {
59
+ while (nextIndex < candidates.length) {
60
+ const index = nextIndex;
61
+ nextIndex += 1;
62
+ const watcher = candidates[index];
63
+ try {
64
+ const tier = await resolveLoadedDocumentUserAccess(
65
+ input.em,
66
+ scopedDocument,
67
+ input.scope,
68
+ watcher.userId,
69
+ input.container
70
+ );
71
+ if (tier) permitted[index] = watcher.userId;
72
+ } catch (error) {
73
+ logger.error("Watcher access resolution failed", {
74
+ documentId: input.documentId,
75
+ recipientUserId: watcher.userId,
76
+ err: error
77
+ });
78
+ }
79
+ }
80
+ }
81
+ );
82
+ await Promise.all(workers);
83
+ return permitted.filter((userId) => userId !== null);
84
+ }
85
+ async function isDocumentWatched(em, scope, documentId) {
86
+ const watcher = await findOneWithDecryption(
87
+ em,
88
+ DocumentWatcher,
89
+ {
90
+ documentId,
91
+ userId: scope.userId,
92
+ tenantId: scope.tenantId,
93
+ organizationId: scope.organizationId,
94
+ deletedAt: null
95
+ },
96
+ { fields: ["id"] },
97
+ scope
98
+ );
99
+ return watcher !== null;
100
+ }
101
+ export {
102
+ DOCUMENTS_MAX_ACTIVE_WATCHERS,
103
+ isDocumentWatched,
104
+ resolveWatcherRecipients
105
+ };
106
+ //# sourceMappingURL=watchers.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/documents/lib/watchers.ts"],
4
+ "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport { DocumentWatcher } from '../data/entities'\nimport { loadScopedDocument, resolveLoadedDocumentUserAccess } from './permissions'\nimport type { DocumentsServiceContainer } from './platformServices'\n\nconst logger = createLogger('documents').child({ component: 'watchers' })\n\nexport const DOCUMENTS_MAX_ACTIVE_WATCHERS = 100\nconst WATCHER_ACCESS_RESOLUTION_CONCURRENCY = 4\n\nexport type DocumentWatcherScope = {\n tenantId: string\n organizationId: string\n}\n\nexport async function resolveWatcherRecipients(input: {\n em: EntityManager\n container: DocumentsServiceContainer\n scope: DocumentWatcherScope\n documentId: string\n actorUserId: string\n excludeUserIds?: readonly string[]\n}): Promise<string[]> {\n let watchers: DocumentWatcher[]\n try {\n watchers = await findWithDecryption(\n input.em,\n DocumentWatcher,\n {\n documentId: input.documentId,\n tenantId: input.scope.tenantId,\n organizationId: input.scope.organizationId,\n deletedAt: null,\n },\n {\n fields: ['userId'],\n orderBy: { createdAt: 'ASC', id: 'ASC' },\n limit: DOCUMENTS_MAX_ACTIVE_WATCHERS,\n },\n input.scope,\n )\n } catch (error) {\n logger.error('Watcher recipient lookup failed', {\n documentId: input.documentId,\n err: error,\n })\n return []\n }\n\n const excludedUserIds = new Set([\n input.actorUserId.toLowerCase(),\n ...(input.excludeUserIds ?? []).map((userId) => userId.toLowerCase()),\n ])\n const candidates = watchers.filter(\n (watcher) => !excludedUserIds.has(watcher.userId.toLowerCase()),\n )\n if (candidates.length === 0) return []\n\n // The document is identical for every candidate, so it is read once instead\n // of once per watcher. The remaining per-watcher role and share lookups run\n // through a bounded worker pool that preserves watcher order and keeps a\n // failed resolution fail-closed for that recipient alone.\n const scopedDocument = await loadScopedDocument(\n input.em,\n input.documentId,\n input.scope,\n ).catch((error: unknown) => {\n logger.error('Watcher document lookup failed', {\n documentId: input.documentId,\n err: error,\n })\n return null\n })\n if (!scopedDocument) return []\n\n const permitted: Array<string | null> = new Array(candidates.length).fill(null)\n let nextIndex = 0\n const workers = Array.from(\n { length: Math.min(WATCHER_ACCESS_RESOLUTION_CONCURRENCY, candidates.length) },\n async () => {\n while (nextIndex < candidates.length) {\n const index = nextIndex\n nextIndex += 1\n const watcher = candidates[index]!\n try {\n const tier = await resolveLoadedDocumentUserAccess(\n input.em,\n scopedDocument,\n input.scope,\n watcher.userId,\n input.container,\n )\n if (tier) permitted[index] = watcher.userId\n } catch (error) {\n logger.error('Watcher access resolution failed', {\n documentId: input.documentId,\n recipientUserId: watcher.userId,\n err: error,\n })\n }\n }\n },\n )\n await Promise.all(workers)\n return permitted.filter((userId): userId is string => userId !== null)\n}\n\nexport async function isDocumentWatched(\n em: EntityManager,\n scope: DocumentWatcherScope & { userId: string },\n documentId: string,\n): Promise<boolean> {\n const watcher = await findOneWithDecryption(\n em,\n DocumentWatcher,\n {\n documentId,\n userId: scope.userId,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n deletedAt: null,\n },\n { fields: ['id'] },\n scope,\n )\n return watcher !== null\n}\n"],
5
+ "mappings": "AACA,SAAS,uBAAuB,0BAA0B;AAC1D,SAAS,oBAAoB;AAC7B,SAAS,uBAAuB;AAChC,SAAS,oBAAoB,uCAAuC;AAGpE,MAAM,SAAS,aAAa,WAAW,EAAE,MAAM,EAAE,WAAW,WAAW,CAAC;AAEjE,MAAM,gCAAgC;AAC7C,MAAM,wCAAwC;AAO9C,eAAsB,yBAAyB,OAOzB;AACpB,MAAI;AACJ,MAAI;AACF,eAAW,MAAM;AAAA,MACf,MAAM;AAAA,MACN;AAAA,MACA;AAAA,QACE,YAAY,MAAM;AAAA,QAClB,UAAU,MAAM,MAAM;AAAA,QACtB,gBAAgB,MAAM,MAAM;AAAA,QAC5B,WAAW;AAAA,MACb;AAAA,MACA;AAAA,QACE,QAAQ,CAAC,QAAQ;AAAA,QACjB,SAAS,EAAE,WAAW,OAAO,IAAI,MAAM;AAAA,QACvC,OAAO;AAAA,MACT;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EACF,SAAS,OAAO;AACd,WAAO,MAAM,mCAAmC;AAAA,MAC9C,YAAY,MAAM;AAAA,MAClB,KAAK;AAAA,IACP,CAAC;AACD,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,kBAAkB,oBAAI,IAAI;AAAA,IAC9B,MAAM,YAAY,YAAY;AAAA,IAC9B,IAAI,MAAM,kBAAkB,CAAC,GAAG,IAAI,CAAC,WAAW,OAAO,YAAY,CAAC;AAAA,EACtE,CAAC;AACD,QAAM,aAAa,SAAS;AAAA,IAC1B,CAAC,YAAY,CAAC,gBAAgB,IAAI,QAAQ,OAAO,YAAY,CAAC;AAAA,EAChE;AACA,MAAI,WAAW,WAAW,EAAG,QAAO,CAAC;AAMrC,QAAM,iBAAiB,MAAM;AAAA,IAC3B,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR,EAAE,MAAM,CAAC,UAAmB;AAC1B,WAAO,MAAM,kCAAkC;AAAA,MAC7C,YAAY,MAAM;AAAA,MAClB,KAAK;AAAA,IACP,CAAC;AACD,WAAO;AAAA,EACT,CAAC;AACD,MAAI,CAAC,eAAgB,QAAO,CAAC;AAE7B,QAAM,YAAkC,IAAI,MAAM,WAAW,MAAM,EAAE,KAAK,IAAI;AAC9E,MAAI,YAAY;AAChB,QAAM,UAAU,MAAM;AAAA,IACpB,EAAE,QAAQ,KAAK,IAAI,uCAAuC,WAAW,MAAM,EAAE;AAAA,IAC7E,YAAY;AACV,aAAO,YAAY,WAAW,QAAQ;AACpC,cAAM,QAAQ;AACd,qBAAa;AACb,cAAM,UAAU,WAAW,KAAK;AAChC,YAAI;AACF,gBAAM,OAAO,MAAM;AAAA,YACjB,MAAM;AAAA,YACN;AAAA,YACA,MAAM;AAAA,YACN,QAAQ;AAAA,YACR,MAAM;AAAA,UACR;AACA,cAAI,KAAM,WAAU,KAAK,IAAI,QAAQ;AAAA,QACvC,SAAS,OAAO;AACd,iBAAO,MAAM,oCAAoC;AAAA,YAC/C,YAAY,MAAM;AAAA,YAClB,iBAAiB,QAAQ;AAAA,YACzB,KAAK;AAAA,UACP,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,QAAM,QAAQ,IAAI,OAAO;AACzB,SAAO,UAAU,OAAO,CAAC,WAA6B,WAAW,IAAI;AACvE;AAEA,eAAsB,kBACpB,IACA,OACA,YACkB;AAClB,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA;AAAA,MACE;AAAA,MACA,QAAQ,MAAM;AAAA,MACd,UAAU,MAAM;AAAA,MAChB,gBAAgB,MAAM;AAAA,MACtB,WAAW;AAAA,IACb;AAAA,IACA,EAAE,QAAQ,CAAC,IAAI,EAAE;AAAA,IACjB;AAAA,EACF;AACA,SAAO,YAAY;AACrB;",
6
+ "names": []
7
+ }