@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.
- package/README.md +88 -0
- package/build.mjs +23 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +7 -0
- package/dist/modules/documents/acl.js +15 -0
- package/dist/modules/documents/acl.js.map +7 -0
- package/dist/modules/documents/api/[id]/archive/route.js +116 -0
- package/dist/modules/documents/api/[id]/archive/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/attachments/[attachmentId]/route.js +155 -0
- package/dist/modules/documents/api/[id]/attachments/[attachmentId]/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/attachments/route.js +153 -0
- package/dist/modules/documents/api/[id]/attachments/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/collab-token/route.js +180 -0
- package/dist/modules/documents/api/[id]/collab-token/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/comments/access-check/route.js +86 -0
- package/dist/modules/documents/api/[id]/comments/access-check/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/comments/route.js +387 -0
- package/dist/modules/documents/api/[id]/comments/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/content/route.js +143 -0
- package/dist/modules/documents/api/[id]/content/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/duplicate/route.js +200 -0
- package/dist/modules/documents/api/[id]/duplicate/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/export/route.js +421 -0
- package/dist/modules/documents/api/[id]/export/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/favorite/route.js +96 -0
- package/dist/modules/documents/api/[id]/favorite/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/links/[linkId]/route.js +85 -0
- package/dist/modules/documents/api/[id]/links/[linkId]/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/links/route.js +257 -0
- package/dist/modules/documents/api/[id]/links/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/principals/route.js +299 -0
- package/dist/modules/documents/api/[id]/principals/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/route.js +246 -0
- package/dist/modules/documents/api/[id]/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/shares/route.js +335 -0
- package/dist/modules/documents/api/[id]/shares/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/unarchive/route.js +39 -0
- package/dist/modules/documents/api/[id]/unarchive/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/versions/[versionId]/restore/route.js +133 -0
- package/dist/modules/documents/api/[id]/versions/[versionId]/restore/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/versions/[versionId]/route.js +93 -0
- package/dist/modules/documents/api/[id]/versions/[versionId]/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/versions/route.js +193 -0
- package/dist/modules/documents/api/[id]/versions/route.js.map +7 -0
- package/dist/modules/documents/api/[id]/watch/route.js +97 -0
- package/dist/modules/documents/api/[id]/watch/route.js.map +7 -0
- package/dist/modules/documents/api/_commands.js +34 -0
- package/dist/modules/documents/api/_commands.js.map +7 -0
- package/dist/modules/documents/api/_shared.js +490 -0
- package/dist/modules/documents/api/_shared.js.map +7 -0
- package/dist/modules/documents/api/folders/route.js +256 -0
- package/dist/modules/documents/api/folders/route.js.map +7 -0
- package/dist/modules/documents/api/instantiate/route.js +108 -0
- package/dist/modules/documents/api/instantiate/route.js.map +7 -0
- package/dist/modules/documents/api/route.js +322 -0
- package/dist/modules/documents/api/route.js.map +7 -0
- package/dist/modules/documents/api/templates/[templateId]/preview/route.js +94 -0
- package/dist/modules/documents/api/templates/[templateId]/preview/route.js.map +7 -0
- package/dist/modules/documents/api/templates/[templateId]/route.js +82 -0
- package/dist/modules/documents/api/templates/[templateId]/route.js.map +7 -0
- package/dist/modules/documents/api/templates/route.js +344 -0
- package/dist/modules/documents/api/templates/route.js.map +7 -0
- package/dist/modules/documents/backend/documents/DocumentsPageClient.js +160 -0
- package/dist/modules/documents/backend/documents/DocumentsPageClient.js.map +7 -0
- package/dist/modules/documents/backend/documents/DocumentsTable.js +143 -0
- package/dist/modules/documents/backend/documents/DocumentsTable.js.map +7 -0
- package/dist/modules/documents/backend/documents/FolderDialog.js +55 -0
- package/dist/modules/documents/backend/documents/FolderDialog.js.map +7 -0
- package/dist/modules/documents/backend/documents/FolderTree.js +40 -0
- package/dist/modules/documents/backend/documents/FolderTree.js.map +7 -0
- package/dist/modules/documents/backend/documents/MoveDocumentDialog.js +64 -0
- package/dist/modules/documents/backend/documents/MoveDocumentDialog.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/CommentAnchorNavigation.js +77 -0
- package/dist/modules/documents/backend/documents/[id]/CommentAnchorNavigation.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/CommentComposer.js +126 -0
- package/dist/modules/documents/backend/documents/[id]/CommentComposer.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/CommentThreadList.js +88 -0
- package/dist/modules/documents/backend/documents/[id]/CommentThreadList.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/CommentsRail.js +123 -0
- package/dist/modules/documents/backend/documents/[id]/CommentsRail.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/DocumentCanvas.js +91 -0
- package/dist/modules/documents/backend/documents/[id]/DocumentCanvas.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/DocumentEditorErrorBoundary.js +27 -0
- package/dist/modules/documents/backend/documents/[id]/DocumentEditorErrorBoundary.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/DocumentEditorIsland.js +50 -0
- package/dist/modules/documents/backend/documents/[id]/DocumentEditorIsland.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/DocumentEditorSurface.js +168 -0
- package/dist/modules/documents/backend/documents/[id]/DocumentEditorSurface.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/DocumentNavigator.js +129 -0
- package/dist/modules/documents/backend/documents/[id]/DocumentNavigator.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/DocumentPageClient.js +429 -0
- package/dist/modules/documents/backend/documents/[id]/DocumentPageClient.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/EditorColorTools.js +68 -0
- package/dist/modules/documents/backend/documents/[id]/EditorColorTools.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/EditorStatusPresence.js +69 -0
- package/dist/modules/documents/backend/documents/[id]/EditorStatusPresence.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/EditorToolbar.js +151 -0
- package/dist/modules/documents/backend/documents/[id]/EditorToolbar.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/ExportMenu.js +121 -0
- package/dist/modules/documents/backend/documents/[id]/ExportMenu.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/MentionPicker.js +114 -0
- package/dist/modules/documents/backend/documents/[id]/MentionPicker.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/OutlinePane.js +70 -0
- package/dist/modules/documents/backend/documents/[id]/OutlinePane.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/RecordFieldsDialog.js +157 -0
- package/dist/modules/documents/backend/documents/[id]/RecordFieldsDialog.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/RelatedRecordsPanel.js +266 -0
- package/dist/modules/documents/backend/documents/[id]/RelatedRecordsPanel.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/VersionHistoryPanel.js +227 -0
- package/dist/modules/documents/backend/documents/[id]/VersionHistoryPanel.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/VersionPreviewDialog.js +157 -0
- package/dist/modules/documents/backend/documents/[id]/VersionPreviewDialog.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/commentTypes.js +150 -0
- package/dist/modules/documents/backend/documents/[id]/commentTypes.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/componentCapabilities.js +13 -0
- package/dist/modules/documents/backend/documents/[id]/componentCapabilities.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/documentPagination.js +295 -0
- package/dist/modules/documents/backend/documents/[id]/documentPagination.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/editorPresenceStyles.js +81 -0
- package/dist/modules/documents/backend/documents/[id]/editorPresenceStyles.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/editorTypes.js +52 -0
- package/dist/modules/documents/backend/documents/[id]/editorTypes.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/page.js +10 -0
- package/dist/modules/documents/backend/documents/[id]/page.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/page.meta.js +16 -0
- package/dist/modules/documents/backend/documents/[id]/page.meta.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/relatedRecordModel.js +38 -0
- package/dist/modules/documents/backend/documents/[id]/relatedRecordModel.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/restoreVersion.js +33 -0
- package/dist/modules/documents/backend/documents/[id]/restoreVersion.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/useDocumentCollaboration.js +392 -0
- package/dist/modules/documents/backend/documents/[id]/useDocumentCollaboration.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/useDocumentComments.js +253 -0
- package/dist/modules/documents/backend/documents/[id]/useDocumentComments.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/useDocumentEditor.js +149 -0
- package/dist/modules/documents/backend/documents/[id]/useDocumentEditor.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/useDocumentTitle.js +82 -0
- package/dist/modules/documents/backend/documents/[id]/useDocumentTitle.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/useEditorInsertions.js +144 -0
- package/dist/modules/documents/backend/documents/[id]/useEditorInsertions.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/useFallbackContentPersistence.js +237 -0
- package/dist/modules/documents/backend/documents/[id]/useFallbackContentPersistence.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/useMentionPicker.js +216 -0
- package/dist/modules/documents/backend/documents/[id]/useMentionPicker.js.map +7 -0
- package/dist/modules/documents/backend/documents/[id]/versionHistoryModel.js +25 -0
- package/dist/modules/documents/backend/documents/[id]/versionHistoryModel.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/EntityPicker.js +156 -0
- package/dist/modules/documents/backend/documents/components/EntityPicker.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/EntityPickerResults.js +46 -0
- package/dist/modules/documents/backend/documents/components/EntityPickerResults.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/NewFromTemplateDialog.js +127 -0
- package/dist/modules/documents/backend/documents/components/NewFromTemplateDialog.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/PrincipalPicker.js +84 -0
- package/dist/modules/documents/backend/documents/components/PrincipalPicker.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/ShareDialog.js +77 -0
- package/dist/modules/documents/backend/documents/components/ShareDialog.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/ShareDialogAddForm.js +93 -0
- package/dist/modules/documents/backend/documents/components/ShareDialogAddForm.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/ShareDialogList.js +82 -0
- package/dist/modules/documents/backend/documents/components/ShareDialogList.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/TemplateBodyEditor.js +96 -0
- package/dist/modules/documents/backend/documents/components/TemplateBodyEditor.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/TemplateEditorDialog.js +169 -0
- package/dist/modules/documents/backend/documents/components/TemplateEditorDialog.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/TemplatePreview.js +38 -0
- package/dist/modules/documents/backend/documents/components/TemplatePreview.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/TemplateSlotFields.js +69 -0
- package/dist/modules/documents/backend/documents/components/TemplateSlotFields.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/TemplateSlotsEditor.js +71 -0
- package/dist/modules/documents/backend/documents/components/TemplateSlotsEditor.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/principalPickerModel.js +63 -0
- package/dist/modules/documents/backend/documents/components/principalPickerModel.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/shareDialogModel.js +68 -0
- package/dist/modules/documents/backend/documents/components/shareDialogModel.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/templateUi.js +89 -0
- package/dist/modules/documents/backend/documents/components/templateUi.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/useAvailableEntityRegistry.js +30 -0
- package/dist/modules/documents/backend/documents/components/useAvailableEntityRegistry.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/useEntitySearch.js +191 -0
- package/dist/modules/documents/backend/documents/components/useEntitySearch.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/usePrincipalPicker.js +221 -0
- package/dist/modules/documents/backend/documents/components/usePrincipalPicker.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/useShareDialog.js +236 -0
- package/dist/modules/documents/backend/documents/components/useShareDialog.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/useTemplateDetail.js +49 -0
- package/dist/modules/documents/backend/documents/components/useTemplateDetail.js.map +7 -0
- package/dist/modules/documents/backend/documents/components/useTemplateInstantiation.js +234 -0
- package/dist/modules/documents/backend/documents/components/useTemplateInstantiation.js.map +7 -0
- package/dist/modules/documents/backend/documents/documentUi.js +106 -0
- package/dist/modules/documents/backend/documents/documentUi.js.map +7 -0
- package/dist/modules/documents/backend/documents/documentsListTypes.js +132 -0
- package/dist/modules/documents/backend/documents/documentsListTypes.js.map +7 -0
- package/dist/modules/documents/backend/documents/page.js +9 -0
- package/dist/modules/documents/backend/documents/page.js.map +7 -0
- package/dist/modules/documents/backend/documents/page.meta.js +26 -0
- package/dist/modules/documents/backend/documents/page.meta.js.map +7 -0
- package/dist/modules/documents/backend/documents/templates/TemplatesPageClient.js +91 -0
- package/dist/modules/documents/backend/documents/templates/TemplatesPageClient.js.map +7 -0
- package/dist/modules/documents/backend/documents/templates/TemplatesTable.js +58 -0
- package/dist/modules/documents/backend/documents/templates/TemplatesTable.js.map +7 -0
- package/dist/modules/documents/backend/documents/templates/page.js +9 -0
- package/dist/modules/documents/backend/documents/templates/page.js.map +7 -0
- package/dist/modules/documents/backend/documents/templates/page.meta.js +34 -0
- package/dist/modules/documents/backend/documents/templates/page.meta.js.map +7 -0
- package/dist/modules/documents/backend/documents/templates/useTemplatesPage.js +139 -0
- package/dist/modules/documents/backend/documents/templates/useTemplatesPage.js.map +7 -0
- package/dist/modules/documents/backend/documents/useDocumentsList.js +314 -0
- package/dist/modules/documents/backend/documents/useDocumentsList.js.map +7 -0
- package/dist/modules/documents/ce.js +8 -0
- package/dist/modules/documents/ce.js.map +7 -0
- package/dist/modules/documents/commands/aggregate.js +99 -0
- package/dist/modules/documents/commands/aggregate.js.map +7 -0
- package/dist/modules/documents/commands/attachments.js +252 -0
- package/dist/modules/documents/commands/attachments.js.map +7 -0
- package/dist/modules/documents/commands/comments.js +782 -0
- package/dist/modules/documents/commands/comments.js.map +7 -0
- package/dist/modules/documents/commands/content.js +238 -0
- package/dist/modules/documents/commands/content.js.map +7 -0
- package/dist/modules/documents/commands/document-crud.js +505 -0
- package/dist/modules/documents/commands/document-crud.js.map +7 -0
- package/dist/modules/documents/commands/documents.js +473 -0
- package/dist/modules/documents/commands/documents.js.map +7 -0
- package/dist/modules/documents/commands/duplicate.js +640 -0
- package/dist/modules/documents/commands/duplicate.js.map +7 -0
- package/dist/modules/documents/commands/favorites.js +150 -0
- package/dist/modules/documents/commands/favorites.js.map +7 -0
- package/dist/modules/documents/commands/folders.js +420 -0
- package/dist/modules/documents/commands/folders.js.map +7 -0
- package/dist/modules/documents/commands/index.js +64 -0
- package/dist/modules/documents/commands/index.js.map +7 -0
- package/dist/modules/documents/commands/interceptors.js +300 -0
- package/dist/modules/documents/commands/interceptors.js.map +7 -0
- package/dist/modules/documents/commands/lifecycle.js +249 -0
- package/dist/modules/documents/commands/lifecycle.js.map +7 -0
- package/dist/modules/documents/commands/links.js +410 -0
- package/dist/modules/documents/commands/links.js.map +7 -0
- package/dist/modules/documents/commands/mutation-helpers.js +42 -0
- package/dist/modules/documents/commands/mutation-helpers.js.map +7 -0
- package/dist/modules/documents/commands/projection-types.js +1 -0
- package/dist/modules/documents/commands/projection-types.js.map +7 -0
- package/dist/modules/documents/commands/shared.js +143 -0
- package/dist/modules/documents/commands/shared.js.map +7 -0
- package/dist/modules/documents/commands/shares.js +527 -0
- package/dist/modules/documents/commands/shares.js.map +7 -0
- package/dist/modules/documents/commands/side-effects.js +103 -0
- package/dist/modules/documents/commands/side-effects.js.map +7 -0
- package/dist/modules/documents/commands/templates.js +461 -0
- package/dist/modules/documents/commands/templates.js.map +7 -0
- package/dist/modules/documents/commands/versions.js +432 -0
- package/dist/modules/documents/commands/versions.js.map +7 -0
- package/dist/modules/documents/commands/watchers.js +164 -0
- package/dist/modules/documents/commands/watchers.js.map +7 -0
- package/dist/modules/documents/data/entities.js +653 -0
- package/dist/modules/documents/data/entities.js.map +7 -0
- package/dist/modules/documents/data/extensions.js +44 -0
- package/dist/modules/documents/data/extensions.js.map +7 -0
- package/dist/modules/documents/data/validators.js +219 -0
- package/dist/modules/documents/data/validators.js.map +7 -0
- package/dist/modules/documents/di.js +35 -0
- package/dist/modules/documents/di.js.map +7 -0
- package/dist/modules/documents/encryption.js +12 -0
- package/dist/modules/documents/encryption.js.map +7 -0
- package/dist/modules/documents/events.js +27 -0
- package/dist/modules/documents/events.js.map +7 -0
- package/dist/modules/documents/index.js +19 -0
- package/dist/modules/documents/index.js.map +7 -0
- package/dist/modules/documents/lib/attachmentServicePort.js +30 -0
- package/dist/modules/documents/lib/attachmentServicePort.js.map +7 -0
- package/dist/modules/documents/lib/capabilities.js +32 -0
- package/dist/modules/documents/lib/capabilities.js.map +7 -0
- package/dist/modules/documents/lib/collabCloseEvents.js +17 -0
- package/dist/modules/documents/lib/collabCloseEvents.js.map +7 -0
- package/dist/modules/documents/lib/collabEndpoint.js +22 -0
- package/dist/modules/documents/lib/collabEndpoint.js.map +7 -0
- package/dist/modules/documents/lib/collabMaterializer.js +107 -0
- package/dist/modules/documents/lib/collabMaterializer.js.map +7 -0
- package/dist/modules/documents/lib/collabToken.js +120 -0
- package/dist/modules/documents/lib/collabToken.js.map +7 -0
- package/dist/modules/documents/lib/collaborationAwareness.js +68 -0
- package/dist/modules/documents/lib/collaborationAwareness.js.map +7 -0
- package/dist/modules/documents/lib/commentAnchors.js +15 -0
- package/dist/modules/documents/lib/commentAnchors.js.map +7 -0
- package/dist/modules/documents/lib/constants.js +25 -0
- package/dist/modules/documents/lib/constants.js.map +7 -0
- package/dist/modules/documents/lib/contentService.js +248 -0
- package/dist/modules/documents/lib/contentService.js.map +7 -0
- package/dist/modules/documents/lib/displayLabels.js +23 -0
- package/dist/modules/documents/lib/displayLabels.js.map +7 -0
- package/dist/modules/documents/lib/docxRenderer.js +601 -0
- package/dist/modules/documents/lib/docxRenderer.js.map +7 -0
- package/dist/modules/documents/lib/duplicateContent.js +22 -0
- package/dist/modules/documents/lib/duplicateContent.js.map +7 -0
- package/dist/modules/documents/lib/editorConfig.js +287 -0
- package/dist/modules/documents/lib/editorConfig.js.map +7 -0
- package/dist/modules/documents/lib/entityLinks.js +148 -0
- package/dist/modules/documents/lib/entityLinks.js.map +7 -0
- package/dist/modules/documents/lib/entityRegistry.js +258 -0
- package/dist/modules/documents/lib/entityRegistry.js.map +7 -0
- package/dist/modules/documents/lib/entityRegistry.server.js +189 -0
- package/dist/modules/documents/lib/entityRegistry.server.js.map +7 -0
- package/dist/modules/documents/lib/entityRegistryAvailability.server.js +9 -0
- package/dist/modules/documents/lib/entityRegistryAvailability.server.js.map +7 -0
- package/dist/modules/documents/lib/entitySuggestion.js +50 -0
- package/dist/modules/documents/lib/entitySuggestion.js.map +7 -0
- package/dist/modules/documents/lib/favorites.js +22 -0
- package/dist/modules/documents/lib/favorites.js.map +7 -0
- package/dist/modules/documents/lib/folderHierarchySerialization.js +19 -0
- package/dist/modules/documents/lib/folderHierarchySerialization.js.map +7 -0
- package/dist/modules/documents/lib/historyLimits.js +100 -0
- package/dist/modules/documents/lib/historyLimits.js.map +7 -0
- package/dist/modules/documents/lib/historyPolicy.js +14 -0
- package/dist/modules/documents/lib/historyPolicy.js.map +7 -0
- package/dist/modules/documents/lib/organizationAccess.js +17 -0
- package/dist/modules/documents/lib/organizationAccess.js.map +7 -0
- package/dist/modules/documents/lib/pdfHtml.js +62 -0
- package/dist/modules/documents/lib/pdfHtml.js.map +7 -0
- package/dist/modules/documents/lib/pdfRenderer.js +284 -0
- package/dist/modules/documents/lib/pdfRenderer.js.map +7 -0
- package/dist/modules/documents/lib/permissions.js +222 -0
- package/dist/modules/documents/lib/permissions.js.map +7 -0
- package/dist/modules/documents/lib/platformServices.js +35 -0
- package/dist/modules/documents/lib/platformServices.js.map +7 -0
- package/dist/modules/documents/lib/recordFieldInsertion.js +58 -0
- package/dist/modules/documents/lib/recordFieldInsertion.js.map +7 -0
- package/dist/modules/documents/lib/requestBody.js +80 -0
- package/dist/modules/documents/lib/requestBody.js.map +7 -0
- package/dist/modules/documents/lib/resourceLimits.js +62 -0
- package/dist/modules/documents/lib/resourceLimits.js.map +7 -0
- package/dist/modules/documents/lib/shareCounts.js +25 -0
- package/dist/modules/documents/lib/shareCounts.js.map +7 -0
- package/dist/modules/documents/lib/templateFill.js +84 -0
- package/dist/modules/documents/lib/templateFill.js.map +7 -0
- package/dist/modules/documents/lib/templateInstantiation.js +147 -0
- package/dist/modules/documents/lib/templateInstantiation.js.map +7 -0
- package/dist/modules/documents/lib/templatePreviewDigest.js +82 -0
- package/dist/modules/documents/lib/templatePreviewDigest.js.map +7 -0
- package/dist/modules/documents/lib/templateSeeds.js +201 -0
- package/dist/modules/documents/lib/templateSeeds.js.map +7 -0
- package/dist/modules/documents/lib/userLabels.js +37 -0
- package/dist/modules/documents/lib/userLabels.js.map +7 -0
- package/dist/modules/documents/lib/versionContent.js +131 -0
- package/dist/modules/documents/lib/versionContent.js.map +7 -0
- package/dist/modules/documents/lib/versionLabels.js +12 -0
- package/dist/modules/documents/lib/versionLabels.js.map +7 -0
- package/dist/modules/documents/lib/versioning.js +14 -0
- package/dist/modules/documents/lib/versioning.js.map +7 -0
- package/dist/modules/documents/lib/visibility.js +422 -0
- package/dist/modules/documents/lib/visibility.js.map +7 -0
- package/dist/modules/documents/lib/watchers.js +106 -0
- package/dist/modules/documents/lib/watchers.js.map +7 -0
- package/dist/modules/documents/migrations/Migration20260708163836_documents.js +44 -0
- package/dist/modules/documents/migrations/Migration20260708163836_documents.js.map +7 -0
- package/dist/modules/documents/migrations/Migration20260709164720_documents.js +17 -0
- package/dist/modules/documents/migrations/Migration20260709164720_documents.js.map +7 -0
- package/dist/modules/documents/migrations/Migration20260710002318_documents.js +32 -0
- package/dist/modules/documents/migrations/Migration20260710002318_documents.js.map +7 -0
- package/dist/modules/documents/migrations/Migration20260710071003_documents.js +13 -0
- package/dist/modules/documents/migrations/Migration20260710071003_documents.js.map +7 -0
- package/dist/modules/documents/migrations/Migration20260712120000_documents.js +13 -0
- package/dist/modules/documents/migrations/Migration20260712120000_documents.js.map +7 -0
- package/dist/modules/documents/migrations/Migration20260712183000_documents.js +14 -0
- package/dist/modules/documents/migrations/Migration20260712183000_documents.js.map +7 -0
- package/dist/modules/documents/migrations/Migration20260713092156_documents.js +29 -0
- package/dist/modules/documents/migrations/Migration20260713092156_documents.js.map +7 -0
- package/dist/modules/documents/migrations/Migration20260717000000_documents.js +37 -0
- package/dist/modules/documents/migrations/Migration20260717000000_documents.js.map +7 -0
- package/dist/modules/documents/notifications.js +47 -0
- package/dist/modules/documents/notifications.js.map +7 -0
- package/dist/modules/documents/search.js +101 -0
- package/dist/modules/documents/search.js.map +7 -0
- package/dist/modules/documents/setup.js +19 -0
- package/dist/modules/documents/setup.js.map +7 -0
- package/dist/modules/documents/widgets/injection/related-documents/LinkDocumentDialog.js +214 -0
- package/dist/modules/documents/widgets/injection/related-documents/LinkDocumentDialog.js.map +7 -0
- package/dist/modules/documents/widgets/injection/related-documents/context.js +84 -0
- package/dist/modules/documents/widgets/injection/related-documents/context.js.map +7 -0
- package/dist/modules/documents/widgets/injection/related-documents/useRelatedDocuments.js +98 -0
- package/dist/modules/documents/widgets/injection/related-documents/useRelatedDocuments.js.map +7 -0
- package/dist/modules/documents/widgets/injection/related-documents/widget.client.js +83 -0
- package/dist/modules/documents/widgets/injection/related-documents/widget.client.js.map +7 -0
- package/dist/modules/documents/widgets/injection/related-documents/widget.js +19 -0
- package/dist/modules/documents/widgets/injection/related-documents/widget.js.map +7 -0
- package/dist/modules/documents/widgets/injection-table.js +21 -0
- package/dist/modules/documents/widgets/injection-table.js.map +7 -0
- package/dist/server/documents-collab-server.js +2260 -0
- package/dist/server/documents-collab-server.js.map +7 -0
- package/generated/entities/document/index.ts +12 -0
- package/generated/entities/document_attachment/index.ts +9 -0
- package/generated/entities/document_comment/index.ts +14 -0
- package/generated/entities/document_content/index.ts +11 -0
- package/generated/entities/document_entity_link/index.ts +19 -0
- package/generated/entities/document_favorite/index.ts +7 -0
- package/generated/entities/document_folder/index.ts +9 -0
- package/generated/entities/document_share/index.ts +11 -0
- package/generated/entities/document_template/index.ts +13 -0
- package/generated/entities/document_version/index.ts +9 -0
- package/generated/entities/document_watcher/index.ts +7 -0
- package/generated/entities.ids.generated.ts +21 -0
- package/generated/entity-fields-registry.ts +151 -0
- package/jest.config.cjs +34 -0
- package/package.json +149 -0
- package/server/documents-collab-server.ts +3416 -0
- package/src/index.ts +1 -0
- package/src/modules/documents/acl.ts +11 -0
- package/src/modules/documents/api/[id]/archive/route.ts +132 -0
- package/src/modules/documents/api/[id]/attachments/[attachmentId]/route.ts +166 -0
- package/src/modules/documents/api/[id]/attachments/route.ts +173 -0
- package/src/modules/documents/api/[id]/collab-token/route.ts +203 -0
- package/src/modules/documents/api/[id]/comments/access-check/route.ts +96 -0
- package/src/modules/documents/api/[id]/comments/route.ts +442 -0
- package/src/modules/documents/api/[id]/content/route.ts +156 -0
- package/src/modules/documents/api/[id]/duplicate/route.ts +231 -0
- package/src/modules/documents/api/[id]/export/route.ts +535 -0
- package/src/modules/documents/api/[id]/favorite/route.ts +110 -0
- package/src/modules/documents/api/[id]/links/[linkId]/route.ts +92 -0
- package/src/modules/documents/api/[id]/links/route.ts +301 -0
- package/src/modules/documents/api/[id]/principals/route.ts +375 -0
- package/src/modules/documents/api/[id]/route.ts +267 -0
- package/src/modules/documents/api/[id]/shares/route.ts +372 -0
- package/src/modules/documents/api/[id]/unarchive/route.ts +42 -0
- package/src/modules/documents/api/[id]/versions/[versionId]/restore/route.ts +152 -0
- package/src/modules/documents/api/[id]/versions/[versionId]/route.ts +100 -0
- package/src/modules/documents/api/[id]/versions/route.ts +207 -0
- package/src/modules/documents/api/[id]/watch/route.ts +111 -0
- package/src/modules/documents/api/_commands.ts +53 -0
- package/src/modules/documents/api/_shared.ts +676 -0
- package/src/modules/documents/api/folders/route.ts +287 -0
- package/src/modules/documents/api/instantiate/route.ts +114 -0
- package/src/modules/documents/api/route.ts +362 -0
- package/src/modules/documents/api/templates/[templateId]/preview/route.ts +97 -0
- package/src/modules/documents/api/templates/[templateId]/route.ts +92 -0
- package/src/modules/documents/api/templates/route.ts +370 -0
- package/src/modules/documents/backend/documents/DocumentsPageClient.tsx +150 -0
- package/src/modules/documents/backend/documents/DocumentsTable.tsx +168 -0
- package/src/modules/documents/backend/documents/FolderDialog.tsx +62 -0
- package/src/modules/documents/backend/documents/FolderTree.tsx +72 -0
- package/src/modules/documents/backend/documents/MoveDocumentDialog.tsx +70 -0
- package/src/modules/documents/backend/documents/[id]/CommentAnchorNavigation.ts +88 -0
- package/src/modules/documents/backend/documents/[id]/CommentComposer.tsx +136 -0
- package/src/modules/documents/backend/documents/[id]/CommentThreadList.tsx +131 -0
- package/src/modules/documents/backend/documents/[id]/CommentsRail.tsx +138 -0
- package/src/modules/documents/backend/documents/[id]/DocumentCanvas.tsx +111 -0
- package/src/modules/documents/backend/documents/[id]/DocumentEditorErrorBoundary.tsx +39 -0
- package/src/modules/documents/backend/documents/[id]/DocumentEditorIsland.tsx +50 -0
- package/src/modules/documents/backend/documents/[id]/DocumentEditorSurface.tsx +162 -0
- package/src/modules/documents/backend/documents/[id]/DocumentNavigator.tsx +129 -0
- package/src/modules/documents/backend/documents/[id]/DocumentPageClient.tsx +463 -0
- package/src/modules/documents/backend/documents/[id]/EditorColorTools.tsx +71 -0
- package/src/modules/documents/backend/documents/[id]/EditorStatusPresence.tsx +78 -0
- package/src/modules/documents/backend/documents/[id]/EditorToolbar.tsx +108 -0
- package/src/modules/documents/backend/documents/[id]/ExportMenu.tsx +144 -0
- package/src/modules/documents/backend/documents/[id]/MentionPicker.tsx +137 -0
- package/src/modules/documents/backend/documents/[id]/OutlinePane.tsx +98 -0
- package/src/modules/documents/backend/documents/[id]/RecordFieldsDialog.tsx +185 -0
- package/src/modules/documents/backend/documents/[id]/RelatedRecordsPanel.tsx +320 -0
- package/src/modules/documents/backend/documents/[id]/VersionHistoryPanel.tsx +244 -0
- package/src/modules/documents/backend/documents/[id]/VersionPreviewDialog.tsx +197 -0
- package/src/modules/documents/backend/documents/[id]/commentTypes.ts +192 -0
- package/src/modules/documents/backend/documents/[id]/componentCapabilities.ts +17 -0
- package/src/modules/documents/backend/documents/[id]/documentPagination.ts +352 -0
- package/src/modules/documents/backend/documents/[id]/editorPresenceStyles.ts +77 -0
- package/src/modules/documents/backend/documents/[id]/editorTypes.ts +84 -0
- package/src/modules/documents/backend/documents/[id]/page.meta.ts +12 -0
- package/src/modules/documents/backend/documents/[id]/page.tsx +6 -0
- package/src/modules/documents/backend/documents/[id]/relatedRecordModel.ts +49 -0
- package/src/modules/documents/backend/documents/[id]/restoreVersion.ts +49 -0
- package/src/modules/documents/backend/documents/[id]/useDocumentCollaboration.ts +458 -0
- package/src/modules/documents/backend/documents/[id]/useDocumentComments.ts +286 -0
- package/src/modules/documents/backend/documents/[id]/useDocumentEditor.ts +157 -0
- package/src/modules/documents/backend/documents/[id]/useDocumentTitle.ts +77 -0
- package/src/modules/documents/backend/documents/[id]/useEditorInsertions.ts +147 -0
- package/src/modules/documents/backend/documents/[id]/useFallbackContentPersistence.ts +277 -0
- package/src/modules/documents/backend/documents/[id]/useMentionPicker.ts +259 -0
- package/src/modules/documents/backend/documents/[id]/versionHistoryModel.ts +29 -0
- package/src/modules/documents/backend/documents/components/EntityPicker.tsx +171 -0
- package/src/modules/documents/backend/documents/components/EntityPickerResults.tsx +64 -0
- package/src/modules/documents/backend/documents/components/NewFromTemplateDialog.tsx +136 -0
- package/src/modules/documents/backend/documents/components/PrincipalPicker.tsx +90 -0
- package/src/modules/documents/backend/documents/components/ShareDialog.tsx +88 -0
- package/src/modules/documents/backend/documents/components/ShareDialogAddForm.tsx +113 -0
- package/src/modules/documents/backend/documents/components/ShareDialogList.tsx +117 -0
- package/src/modules/documents/backend/documents/components/TemplateBodyEditor.tsx +96 -0
- package/src/modules/documents/backend/documents/components/TemplateEditorDialog.tsx +171 -0
- package/src/modules/documents/backend/documents/components/TemplatePreview.tsx +43 -0
- package/src/modules/documents/backend/documents/components/TemplateSlotFields.tsx +72 -0
- package/src/modules/documents/backend/documents/components/TemplateSlotsEditor.tsx +72 -0
- package/src/modules/documents/backend/documents/components/principalPickerModel.ts +86 -0
- package/src/modules/documents/backend/documents/components/shareDialogModel.ts +94 -0
- package/src/modules/documents/backend/documents/components/templateUi.ts +128 -0
- package/src/modules/documents/backend/documents/components/useAvailableEntityRegistry.ts +43 -0
- package/src/modules/documents/backend/documents/components/useEntitySearch.ts +197 -0
- package/src/modules/documents/backend/documents/components/usePrincipalPicker.ts +165 -0
- package/src/modules/documents/backend/documents/components/useShareDialog.ts +267 -0
- package/src/modules/documents/backend/documents/components/useTemplateDetail.ts +54 -0
- package/src/modules/documents/backend/documents/components/useTemplateInstantiation.ts +252 -0
- package/src/modules/documents/backend/documents/documentUi.ts +134 -0
- package/src/modules/documents/backend/documents/documentsListTypes.ts +163 -0
- package/src/modules/documents/backend/documents/page.meta.ts +24 -0
- package/src/modules/documents/backend/documents/page.tsx +5 -0
- package/src/modules/documents/backend/documents/templates/TemplatesPageClient.tsx +93 -0
- package/src/modules/documents/backend/documents/templates/TemplatesTable.tsx +71 -0
- package/src/modules/documents/backend/documents/templates/page.meta.ts +32 -0
- package/src/modules/documents/backend/documents/templates/page.tsx +5 -0
- package/src/modules/documents/backend/documents/templates/useTemplatesPage.tsx +148 -0
- package/src/modules/documents/backend/documents/useDocumentsList.tsx +305 -0
- package/src/modules/documents/ce.ts +6 -0
- package/src/modules/documents/commands/aggregate.ts +128 -0
- package/src/modules/documents/commands/attachments.ts +309 -0
- package/src/modules/documents/commands/comments.ts +966 -0
- package/src/modules/documents/commands/content.ts +294 -0
- package/src/modules/documents/commands/document-crud.ts +609 -0
- package/src/modules/documents/commands/documents.ts +581 -0
- package/src/modules/documents/commands/duplicate.ts +772 -0
- package/src/modules/documents/commands/favorites.ts +171 -0
- package/src/modules/documents/commands/folders.ts +506 -0
- package/src/modules/documents/commands/index.ts +33 -0
- package/src/modules/documents/commands/interceptors.ts +402 -0
- package/src/modules/documents/commands/lifecycle.ts +333 -0
- package/src/modules/documents/commands/links.ts +486 -0
- package/src/modules/documents/commands/mutation-helpers.ts +48 -0
- package/src/modules/documents/commands/projection-types.ts +77 -0
- package/src/modules/documents/commands/shared.ts +219 -0
- package/src/modules/documents/commands/shares.ts +612 -0
- package/src/modules/documents/commands/side-effects.ts +130 -0
- package/src/modules/documents/commands/templates.ts +522 -0
- package/src/modules/documents/commands/versions.ts +537 -0
- package/src/modules/documents/commands/watchers.ts +181 -0
- package/src/modules/documents/data/entities.ts +631 -0
- package/src/modules/documents/data/extensions.ts +42 -0
- package/src/modules/documents/data/validators.ts +248 -0
- package/src/modules/documents/di.ts +33 -0
- package/src/modules/documents/encryption.ts +14 -0
- package/src/modules/documents/events.ts +23 -0
- package/src/modules/documents/i18n/.hardcoded-allowlist.json +9 -0
- package/src/modules/documents/i18n/de.json +522 -0
- package/src/modules/documents/i18n/en.json +522 -0
- package/src/modules/documents/i18n/es.json +522 -0
- package/src/modules/documents/i18n/ko.json +522 -0
- package/src/modules/documents/i18n/pl.json +522 -0
- package/src/modules/documents/index.ts +17 -0
- package/src/modules/documents/lib/attachmentServicePort.ts +94 -0
- package/src/modules/documents/lib/capabilities.ts +57 -0
- package/src/modules/documents/lib/collabCloseEvents.ts +26 -0
- package/src/modules/documents/lib/collabEndpoint.ts +43 -0
- package/src/modules/documents/lib/collabMaterializer.ts +140 -0
- package/src/modules/documents/lib/collabToken.ts +170 -0
- package/src/modules/documents/lib/collaborationAwareness.ts +102 -0
- package/src/modules/documents/lib/commentAnchors.ts +19 -0
- package/src/modules/documents/lib/constants.ts +39 -0
- package/src/modules/documents/lib/contentService.ts +340 -0
- package/src/modules/documents/lib/displayLabels.ts +31 -0
- package/src/modules/documents/lib/docxRenderer.ts +685 -0
- package/src/modules/documents/lib/duplicateContent.ts +32 -0
- package/src/modules/documents/lib/editorConfig.ts +371 -0
- package/src/modules/documents/lib/entityLinks.ts +250 -0
- package/src/modules/documents/lib/entityRegistry.server.ts +267 -0
- package/src/modules/documents/lib/entityRegistry.ts +345 -0
- package/src/modules/documents/lib/entityRegistryAvailability.server.ts +19 -0
- package/src/modules/documents/lib/entitySuggestion.ts +61 -0
- package/src/modules/documents/lib/favorites.ts +35 -0
- package/src/modules/documents/lib/folderHierarchySerialization.ts +34 -0
- package/src/modules/documents/lib/historyLimits.ts +154 -0
- package/src/modules/documents/lib/historyPolicy.ts +7 -0
- package/src/modules/documents/lib/organizationAccess.ts +44 -0
- package/src/modules/documents/lib/pdfHtml.ts +65 -0
- package/src/modules/documents/lib/pdfRenderer.ts +367 -0
- package/src/modules/documents/lib/permissions.ts +299 -0
- package/src/modules/documents/lib/platformServices.ts +70 -0
- package/src/modules/documents/lib/recordFieldInsertion.ts +72 -0
- package/src/modules/documents/lib/requestBody.ts +97 -0
- package/src/modules/documents/lib/resourceLimits.ts +94 -0
- package/src/modules/documents/lib/shareCounts.ts +44 -0
- package/src/modules/documents/lib/templateFill.ts +138 -0
- package/src/modules/documents/lib/templateInstantiation.ts +206 -0
- package/src/modules/documents/lib/templatePreviewDigest.ts +122 -0
- package/src/modules/documents/lib/templateSeeds.ts +248 -0
- package/src/modules/documents/lib/userLabels.ts +58 -0
- package/src/modules/documents/lib/versionContent.ts +163 -0
- package/src/modules/documents/lib/versionLabels.ts +9 -0
- package/src/modules/documents/lib/versioning.ts +29 -0
- package/src/modules/documents/lib/visibility.ts +610 -0
- package/src/modules/documents/lib/watchers.ts +129 -0
- package/src/modules/documents/migrations/.snapshot-open-mercato.json +2892 -0
- package/src/modules/documents/migrations/Migration20260708163836_documents.ts +50 -0
- package/src/modules/documents/migrations/Migration20260709164720_documents.ts +19 -0
- package/src/modules/documents/migrations/Migration20260710002318_documents.ts +35 -0
- package/src/modules/documents/migrations/Migration20260710071003_documents.ts +13 -0
- package/src/modules/documents/migrations/Migration20260712120000_documents.ts +13 -0
- package/src/modules/documents/migrations/Migration20260712183000_documents.ts +12 -0
- package/src/modules/documents/migrations/Migration20260713092156_documents.ts +43 -0
- package/src/modules/documents/migrations/Migration20260717000000_documents.ts +40 -0
- package/src/modules/documents/notifications.ts +45 -0
- package/src/modules/documents/search.ts +118 -0
- package/src/modules/documents/setup.ts +19 -0
- package/src/modules/documents/widgets/injection/related-documents/LinkDocumentDialog.tsx +224 -0
- package/src/modules/documents/widgets/injection/related-documents/context.ts +101 -0
- package/src/modules/documents/widgets/injection/related-documents/useRelatedDocuments.ts +112 -0
- package/src/modules/documents/widgets/injection/related-documents/widget.client.tsx +76 -0
- package/src/modules/documents/widgets/injection/related-documents/widget.ts +19 -0
- package/src/modules/documents/widgets/injection-table.ts +20 -0
- package/tsconfig.json +9 -0
- package/watch.mjs +6 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/documents/lib/docxRenderer.ts"],
|
|
4
|
+
"sourcesContent": ["import { createRequire } from 'node:module'\nimport { isAbsolute } from 'node:path'\nimport { Worker } from 'node:worker_threads'\n\nexport const DOCX_RENDER_MAX_CONCURRENCY = 2\nexport const DOCX_RENDER_MAX_QUEUE = 4\nexport const DOCX_RENDER_ACQUIRE_TIMEOUT_MS = 2_000\nexport const DOCX_RENDER_TIMEOUT_MS = 20_000\nexport const DOCX_MAX_OUTPUT_BYTES = 25 * 1024 * 1024\nexport const DOCX_WORKER_CHUNK_BYTES = 64 * 1024\nexport const DOCX_WORKER_RESOURCE_LIMITS = Object.freeze({\n maxOldGenerationSizeMb: 128,\n maxYoungGenerationSizeMb: 16,\n stackSizeMb: 4,\n})\nconst DOCX_OVERLOADED_MARKER = Symbol.for('open-mercato.documents.docxRenderer.overloaded')\nconst DOCX_TIMEOUT_MARKER = Symbol.for('open-mercato.documents.docxRenderer.timeout')\nconst DOCX_OUTPUT_TOO_LARGE_MARKER = Symbol.for('open-mercato.documents.docxRenderer.outputTooLarge')\nconst DOCX_FAILED_MARKER = Symbol.for('open-mercato.documents.docxRenderer.failed')\n\nexport class DocxRenderOverloadedError extends Error {\n readonly [DOCX_OVERLOADED_MARKER] = true\n constructor() {\n super('DOCX renderer is at capacity')\n this.name = 'DocxRenderOverloadedError'\n }\n}\n\nexport class DocxRenderTimeoutError extends Error {\n readonly [DOCX_TIMEOUT_MARKER] = true\n constructor() {\n super('DOCX renderer timed out')\n this.name = 'DocxRenderTimeoutError'\n }\n}\n\nexport class DocxRenderOutputTooLargeError extends Error {\n readonly [DOCX_OUTPUT_TOO_LARGE_MARKER] = true\n constructor() {\n super('DOCX renderer output exceeded its byte limit')\n this.name = 'DocxRenderOutputTooLargeError'\n }\n}\n\nexport class DocxRenderFailedError extends Error {\n readonly [DOCX_FAILED_MARKER] = true\n constructor(options: { cause?: unknown } = {}) {\n super('DOCX renderer failed', options)\n this.name = 'DocxRenderFailedError'\n }\n}\n\nfunction hasErrorMarker(error: unknown, marker: symbol): boolean {\n return Boolean(error && typeof error === 'object' && (error as Record<symbol, unknown>)[marker] === true)\n}\n\nexport const isDocxRenderOverloadedError = (error: unknown): boolean => (\n error instanceof DocxRenderOverloadedError || hasErrorMarker(error, DOCX_OVERLOADED_MARKER)\n)\nexport const isDocxRenderTimeoutError = (error: unknown): boolean => (\n error instanceof DocxRenderTimeoutError || hasErrorMarker(error, DOCX_TIMEOUT_MARKER)\n)\nexport const isDocxRenderOutputTooLargeError = (error: unknown): boolean => (\n error instanceof DocxRenderOutputTooLargeError || hasErrorMarker(error, DOCX_OUTPUT_TOO_LARGE_MARKER)\n)\nexport const isDocxRenderFailedError = (error: unknown): boolean => (\n error instanceof DocxRenderFailedError || hasErrorMarker(error, DOCX_FAILED_MARKER)\n)\n\ntype DocxRendererOptions = {\n maxConcurrency?: number\n maxQueue?: number\n acquireTimeoutMs?: number\n renderTimeoutMs?: number\n maxOutputBytes?: number\n}\n\nexport interface DocxWorker {\n on(event: 'message', listener: (message: unknown) => void): unknown\n on(event: 'error', listener: (error: Error) => void): unknown\n on(event: 'exit', listener: (code: number) => void): unknown\n terminate(): Promise<number>\n}\n\nexport type DocxWorkerFactoryInput = {\n html: string\n modulePath: string | null\n moduleSpecifier: string\n requireFrom: string\n maxOutputBytes: number\n chunkBytes: number\n}\n\nexport type DocxWorkerFactory = (input: DocxWorkerFactoryInput) => DocxWorker\n\ntype DocxRendererDeps = {\n workerFactory?: DocxWorkerFactory\n modulePath?: string | null\n allocateOutput?: (byteLength: number) => Uint8Array\n}\n\n/**\n * The worker body is a standalone source string because it is evaluated in a\n * fresh `worker_threads` context that cannot import from this package.\n *\n * The cost of that constraint: everything inside this template is invisible to\n * `tsc`, `eslint` and `ds-lint`, so a typo here is a runtime failure rather\n * than a build failure. The behaviour is pinned by __tests__/docxRenderer.test.ts,\n * which drives a real worker rather than only a fake \u2014 keep it that way when\n * editing this string.\n */\nconst DOCX_WORKER_SOURCE = String.raw`\nconst { parentPort, workerData } = require('node:worker_threads')\n\nconst VOID_TAGS = new Set(['br', 'hr', 'img', 'input'])\n\nfunction attributes(source) {\n const result = {}\n const pattern = /([A-Za-z_:][-A-Za-z0-9_:.]*)(?:\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s\"'=<>]+)))?/g\n let match\n while ((match = pattern.exec(source)) !== null) {\n result[match[1].toLowerCase()] = match[2] ?? match[3] ?? match[4] ?? ''\n }\n return result\n}\n\nfunction parseHtml(html) {\n const root = { tag: 'root', attrs: {}, children: [] }\n const stack = [root]\n const tokens = String(html).match(/<!--[\\s\\S]*?-->|<![^>]*>|<\\/?[A-Za-z][^>]*>|[^<]+/g) || []\n for (const token of tokens) {\n if (token.startsWith('<!--') || token.startsWith('<!')) continue\n if (!token.startsWith('<')) {\n stack[stack.length - 1].children.push(token)\n continue\n }\n const closing = /^<\\/\\s*([A-Za-z0-9-]+)/.exec(token)\n if (closing) {\n const tag = closing[1].toLowerCase()\n while (stack.length > 1) {\n const node = stack.pop()\n if (node.tag === tag) break\n }\n continue\n }\n const opening = /^<\\s*([A-Za-z0-9-]+)([\\s\\S]*?)\\/?\\s*>$/.exec(token)\n if (!opening) continue\n const tag = opening[1].toLowerCase()\n const node = { tag, attrs: attributes(opening[2]), children: [] }\n stack[stack.length - 1].children.push(node)\n if (!VOID_TAGS.has(tag) && !/\\/\\s*>$/.test(token)) stack.push(node)\n }\n return root\n}\n\nfunction decode(value) {\n return String(value)\n .replace(/&#x([0-9a-f]+);/gi, (_match, code) => String.fromCodePoint(Number.parseInt(code, 16)))\n .replace(/&#([0-9]+);/g, (_match, code) => String.fromCodePoint(Number.parseInt(code, 10)))\n .replace(/&(amp|lt|gt|quot|apos|nbsp);/g, (_match, name) => ({ amp: '&', lt: '<', gt: '>', quot: '\"', apos: \"'\", nbsp: ' ' })[name])\n}\n\nfunction inlineNodes(nodes, marks) {\n const result = []\n for (const child of Array.isArray(nodes) ? nodes : []) {\n if (typeof child === 'string') {\n const text = decode(child)\n if (text) result.push({ type: 'text', text, marks })\n continue\n }\n if (!child || typeof child !== 'object') continue\n if (child.tag === 'br') {\n result.push({ type: 'hardBreak' })\n continue\n }\n if (child.tag === 'img') {\n result.push({ type: 'image', attrs: { src: child.attrs.src || '' } })\n continue\n }\n const markType = ({ strong: 'bold', b: 'bold', em: 'italic', i: 'italic', u: 'underline', s: 'strike', strike: 'strike', code: 'code' })[child.tag]\n result.push(...inlineNodes(child.children, markType ? [...marks, { type: markType }] : marks))\n }\n return result\n}\n\nfunction blockNodes(nodes) {\n const result = []\n for (const child of Array.isArray(nodes) ? nodes : []) {\n if (typeof child === 'string') {\n if (decode(child).trim()) result.push({ type: 'paragraph', content: inlineNodes([child], []) })\n continue\n }\n if (!child || typeof child !== 'object') continue\n const align = /(?:^|;)\\s*text-align\\s*:\\s*(left|center|right|justify)/i.exec(child.attrs.style || '')\n if (child.tag === 'div' && String(child.attrs.class || '').split(/\\s+/).includes('page-break')) {\n result.push({ type: 'pageBreak' })\n } else if (child.tag === 'p' || child.tag === 'div') {\n result.push({ type: 'paragraph', attrs: { textAlign: align && align[1].toLowerCase() }, content: inlineNodes(child.children, []) })\n } else if (/^h[1-6]$/.test(child.tag)) {\n result.push({ type: 'heading', attrs: { level: Number(child.tag.slice(1)), textAlign: align && align[1].toLowerCase() }, content: inlineNodes(child.children, []) })\n } else if (child.tag === 'ul' || child.tag === 'ol') {\n result.push({\n type: child.tag === 'ol' ? 'orderedList' : 'bulletList',\n content: child.children.filter((item) => item && typeof item === 'object' && item.tag === 'li').map((item) => ({\n type: 'listItem',\n content: blockNodes(item.children).length ? blockNodes(item.children) : [{ type: 'paragraph', content: inlineNodes(item.children, []) }],\n })),\n })\n } else if (child.tag === 'blockquote') {\n result.push({ type: 'blockquote', content: inlineNodes(child.children, []) })\n } else if (child.tag === 'pre') {\n result.push({ type: 'codeBlock', content: inlineNodes(child.children, [{ type: 'code' }]) })\n } else if (child.tag === 'hr') {\n result.push({ type: 'horizontalRule' })\n } else if (child.tag === 'img') {\n result.push({ type: 'image', attrs: { src: child.attrs.src || '' } })\n } else if (child.tag === 'table') {\n const rows = []\n const visitRows = (entries) => {\n for (const entry of Array.isArray(entries) ? entries : []) {\n if (!entry || typeof entry !== 'object') continue\n if (entry.tag === 'tr') {\n rows.push({\n type: 'tableRow',\n content: entry.children.filter((cell) => cell && typeof cell === 'object' && ['td', 'th'].includes(cell.tag)).map((cell) => ({\n type: cell.tag === 'th' ? 'tableHeader' : 'tableCell',\n content: blockNodes(cell.children).length ? blockNodes(cell.children) : [{ type: 'paragraph', content: inlineNodes(cell.children, []) }],\n })),\n })\n } else visitRows(entry.children)\n }\n }\n visitRows(child.children)\n result.push({ type: 'table', content: rows })\n } else {\n const nested = blockNodes(child.children)\n if (nested.length) result.push(...nested)\n else if (inlineNodes(child.children, []).length) result.push({ type: 'paragraph', content: inlineNodes(child.children, []) })\n }\n }\n return result\n}\n\nfunction htmlToDocumentJson(html) {\n return { type: 'doc', content: blockNodes(parseHtml(html).children) }\n}\n\nfunction xml(value) {\n return String(value ?? '')\n .replaceAll('&', '&')\n .replaceAll('<', '<')\n .replaceAll('>', '>')\n .replaceAll('\"', '"')\n .replaceAll(\"'\", ''')\n}\n\nfunction markProperties(marks) {\n const names = new Set((Array.isArray(marks) ? marks : []).map((mark) => mark && mark.type))\n return [\n names.has('bold') ? '<w:b/>' : '',\n names.has('italic') ? '<w:i/>' : '',\n names.has('underline') ? '<w:u w:val=\"single\"/>' : '',\n names.has('strike') ? '<w:strike/>' : '',\n names.has('code') ? '<w:rFonts w:ascii=\"Courier New\" w:hAnsi=\"Courier New\"/>' : '',\n ].join('')\n}\n\nfunction textRun(node) {\n const text = String(node && node.text || '')\n const properties = markProperties(node && node.marks)\n return '<w:r>' + (properties ? '<w:rPr>' + properties + '</w:rPr>' : '')\n + '<w:t xml:space=\"preserve\">' + xml(text) + '</w:t></w:r>'\n}\n\nfunction inlineContent(nodes, state) {\n return (Array.isArray(nodes) ? nodes : []).map((node) => {\n if (!node || typeof node !== 'object') return ''\n if (node.type === 'text') return textRun(node)\n if (node.type === 'hardBreak') return '<w:r><w:br/></w:r>'\n if (node.type === 'entityRef') return textRun({ text: node.attrs && node.attrs.label || '' })\n if (node.type === 'image') return imageRun(node, state)\n return inlineContent(node.content, state)\n }).join('')\n}\n\nfunction paragraphProperties(node, options) {\n const properties = []\n if (options && options.style) properties.push('<w:pStyle w:val=\"' + xml(options.style) + '\"/>')\n if (options && options.numberId) {\n properties.push('<w:numPr><w:ilvl w:val=\"' + Number(options.level || 0) + '\"/><w:numId w:val=\"' + Number(options.numberId) + '\"/></w:numPr>')\n }\n const alignment = node && node.attrs && node.attrs.textAlign\n if (['left', 'center', 'right', 'justify'].includes(alignment)) {\n properties.push('<w:jc w:val=\"' + alignment + '\"/>')\n }\n return properties.length ? '<w:pPr>' + properties.join('') + '</w:pPr>' : ''\n}\n\nfunction paragraph(node, state, options) {\n return '<w:p>' + paragraphProperties(node, options) + inlineContent(node && node.content, state) + '</w:p>'\n}\n\nfunction imageDimensions(bytes, mimeType) {\n if (mimeType === 'image/png' && bytes.length >= 24) {\n return { width: bytes.readUInt32BE(16), height: bytes.readUInt32BE(20) }\n }\n if (mimeType === 'image/jpeg' && bytes.length >= 4) {\n let offset = 2\n while (offset + 8 < bytes.length) {\n if (bytes[offset] !== 0xff) break\n const marker = bytes[offset + 1]\n offset += 2\n if (marker === 0xd8 || marker === 0xd9 || marker === 0x01 || (marker >= 0xd0 && marker <= 0xd7)) continue\n if (offset + 2 > bytes.length) break\n const length = bytes.readUInt16BE(offset)\n if (length < 2 || offset + length > bytes.length) break\n if ([0xc0, 0xc1, 0xc2, 0xc3, 0xc5, 0xc6, 0xc7, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf].includes(marker)) {\n return { width: bytes.readUInt16BE(offset + 5), height: bytes.readUInt16BE(offset + 3) }\n }\n offset += length\n }\n }\n return { width: 640, height: 480 }\n}\n\nfunction imageRun(node, state) {\n const source = node && node.attrs && node.attrs.src\n const match = typeof source === 'string' && /^data:(image\\/(?:png|jpeg));base64,([A-Za-z0-9+/]+={0,2})$/.exec(source)\n if (!match) return ''\n const bytes = Buffer.from(match[2], 'base64')\n if (bytes.length === 0 || bytes.toString('base64') !== match[2]) return ''\n const extension = match[1] === 'image/png' ? 'png' : 'jpg'\n const imageId = state.images.length + 1\n const relationshipId = 'rId' + (imageId + 2)\n const dimensions = imageDimensions(bytes, match[1])\n const maxWidth = 5486400\n const scale = Math.min(1, 640 / Math.max(1, dimensions.width))\n const width = Math.max(9525, Math.round(dimensions.width * scale * 9525))\n const height = Math.max(9525, Math.round(dimensions.height * scale * 9525))\n state.images.push({ bytes, extension, relationshipId, imageId })\n return '<w:r><w:drawing><wp:inline distT=\"0\" distB=\"0\" distL=\"0\" distR=\"0\">'\n + '<wp:extent cx=\"' + Math.min(width, maxWidth) + '\" cy=\"' + Math.round(height * Math.min(1, maxWidth / width)) + '\"/>'\n + '<wp:docPr id=\"' + imageId + '\" name=\"Image ' + imageId + '\"/>'\n + '<a:graphic><a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">'\n + '<pic:pic><pic:nvPicPr><pic:cNvPr id=\"' + imageId + '\" name=\"image.' + extension + '\"/><pic:cNvPicPr/></pic:nvPicPr>'\n + '<pic:blipFill><a:blip r:embed=\"' + relationshipId + '\"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill>'\n + '<pic:spPr><a:xfrm><a:off x=\"0\" y=\"0\"/><a:ext cx=\"' + width + '\" cy=\"' + height + '\"/></a:xfrm>'\n + '<a:prstGeom prst=\"rect\"><a:avLst/></a:prstGeom></pic:spPr></pic:pic>'\n + '</a:graphicData></a:graphic></wp:inline></w:drawing></w:r>'\n}\n\nfunction renderList(node, state, level, numberId) {\n return (Array.isArray(node.content) ? node.content : []).map((item) => {\n const children = Array.isArray(item && item.content) ? item.content : []\n return children.map((child) => {\n if (child.type === 'paragraph') return paragraph(child, state, { numberId, level })\n if (child.type === 'bulletList') return renderList(child, state, level + 1, 1)\n if (child.type === 'orderedList') return renderList(child, state, level + 1, 2)\n return renderBlock(child, state)\n }).join('')\n }).join('')\n}\n\nfunction renderTable(node, state) {\n const rows = (Array.isArray(node.content) ? node.content : []).map((row) => {\n const cells = (Array.isArray(row && row.content) ? row.content : []).map((cell) => (\n '<w:tc><w:tcPr><w:tcW w:w=\"0\" w:type=\"auto\"/></w:tcPr>'\n + (Array.isArray(cell && cell.content) ? cell.content.map((entry) => renderBlock(entry, state)).join('') : '<w:p/>')\n + '</w:tc>'\n )).join('')\n return '<w:tr>' + cells + '</w:tr>'\n }).join('')\n return '<w:tbl><w:tblPr><w:tblBorders><w:top w:val=\"single\" w:sz=\"4\"/><w:left w:val=\"single\" w:sz=\"4\"/>'\n + '<w:bottom w:val=\"single\" w:sz=\"4\"/><w:right w:val=\"single\" w:sz=\"4\"/><w:insideH w:val=\"single\" w:sz=\"4\"/>'\n + '<w:insideV w:val=\"single\" w:sz=\"4\"/></w:tblBorders></w:tblPr>' + rows + '</w:tbl>'\n}\n\nfunction renderBlock(node, state) {\n if (!node || typeof node !== 'object') return ''\n if (node.type === 'paragraph') return paragraph(node, state)\n if (node.type === 'heading') return paragraph(node, state, { style: 'Heading' + Math.min(6, Math.max(1, Number(node.attrs && node.attrs.level || 1))) })\n if (node.type === 'bulletList' || node.type === 'taskList') return renderList(node, state, 0, 1)\n if (node.type === 'orderedList') return renderList(node, state, 0, 2)\n if (node.type === 'blockquote') return '<w:p><w:pPr><w:ind w:left=\"720\"/></w:pPr>' + inlineContent(node.content, state) + '</w:p>'\n if (node.type === 'codeBlock') return '<w:p><w:pPr><w:pStyle w:val=\"Code\"/></w:pPr>' + inlineContent(node.content, state) + '</w:p>'\n if (node.type === 'horizontalRule') return '<w:p><w:pPr><w:pBdr><w:bottom w:val=\"single\" w:sz=\"6\"/></w:pBdr></w:pPr></w:p>'\n if (node.type === 'table') return renderTable(node, state)\n if (node.type === 'pageBreak') return '<w:p><w:r><w:br w:type=\"page\"/></w:r></w:p>'\n if (node.type === 'image') return '<w:p>' + imageRun(node, state) + '</w:p>'\n return (Array.isArray(node.content) ? node.content : []).map((child) => renderBlock(child, state)).join('')\n}\n\nfunction documentXml(documentJson, state) {\n const body = (Array.isArray(documentJson && documentJson.content) ? documentJson.content : [])\n .map((node) => renderBlock(node, state)).join('')\n return '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>'\n + '<w:document xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" '\n + 'xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" '\n + 'xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" '\n + 'xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" '\n + 'xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">'\n + '<w:body>' + body + '<w:sectPr><w:pgSz w:w=\"11906\" w:h=\"16838\"/><w:pgMar w:top=\"1440\" w:right=\"1440\" w:bottom=\"1440\" w:left=\"1440\"/></w:sectPr></w:body></w:document>'\n}\n\nasync function convert(documentJson, JSZip) {\n const zip = new JSZip()\n const state = { images: [] }\n const document = documentXml(documentJson, state)\n zip.file('[Content_Types].xml', '<?xml version=\"1.0\" encoding=\"UTF-8\"?>'\n + '<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">'\n + '<Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>'\n + '<Default Extension=\"xml\" ContentType=\"application/xml\"/><Default Extension=\"png\" ContentType=\"image/png\"/>'\n + '<Default Extension=\"jpg\" ContentType=\"image/jpeg\"/>'\n + '<Override PartName=\"/word/document.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"/>'\n + '<Override PartName=\"/word/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml\"/>'\n + '<Override PartName=\"/word/numbering.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml\"/>'\n + '</Types>')\n zip.file('_rels/.rels', '<?xml version=\"1.0\" encoding=\"UTF-8\"?>'\n + '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">'\n + '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"word/document.xml\"/>'\n + '</Relationships>')\n zip.file('word/document.xml', document)\n zip.file('word/styles.xml', '<?xml version=\"1.0\" encoding=\"UTF-8\"?>'\n + '<w:styles xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">'\n + '<w:style w:type=\"paragraph\" w:default=\"1\" w:styleId=\"Normal\"><w:name w:val=\"Normal\"/></w:style>'\n + [1,2,3,4,5,6].map((level) => '<w:style w:type=\"paragraph\" w:styleId=\"Heading' + level + '\"><w:name w:val=\"heading ' + level + '\"/><w:basedOn w:val=\"Normal\"/><w:rPr><w:b/><w:sz w:val=\"' + (34 - level * 2) + '\"/></w:rPr></w:style>').join('')\n + '<w:style w:type=\"paragraph\" w:styleId=\"Code\"><w:name w:val=\"Code\"/><w:rPr><w:rFonts w:ascii=\"Courier New\" w:hAnsi=\"Courier New\"/></w:rPr></w:style>'\n + '</w:styles>')\n zip.file('word/numbering.xml', '<?xml version=\"1.0\" encoding=\"UTF-8\"?>'\n + '<w:numbering xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">'\n + '<w:abstractNum w:abstractNumId=\"1\"><w:lvl w:ilvl=\"0\"><w:numFmt w:val=\"bullet\"/><w:lvlText w:val=\"\u2022\"/></w:lvl></w:abstractNum>'\n + '<w:abstractNum w:abstractNumId=\"2\"><w:lvl w:ilvl=\"0\"><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1.\"/></w:lvl></w:abstractNum>'\n + '<w:num w:numId=\"1\"><w:abstractNumId w:val=\"1\"/></w:num><w:num w:numId=\"2\"><w:abstractNumId w:val=\"2\"/></w:num>'\n + '</w:numbering>')\n const relationships = [\n '<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>',\n '<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering\" Target=\"numbering.xml\"/>',\n ]\n for (const image of state.images) {\n zip.file('word/media/image' + image.imageId + '.' + image.extension, image.bytes)\n relationships.push('<Relationship Id=\"' + image.relationshipId + '\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"media/image' + image.imageId + '.' + image.extension + '\"/>')\n }\n zip.file('word/_rels/document.xml.rels', '<?xml version=\"1.0\" encoding=\"UTF-8\"?>'\n + '<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">'\n + relationships.join('') + '</Relationships>')\n return zip.generateAsync({ type: 'uint8array', compression: 'DEFLATE', compressionOptions: { level: 6 } })\n}\n\n;(async () => {\n const imported = typeof workerData.modulePath === 'string'\n ? require(workerData.modulePath)\n : require('node:module').createRequire(workerData.requireFrom)(workerData.moduleSpecifier)\n const JSZip = typeof imported === 'function' ? imported : imported && imported.default\n if (typeof JSZip !== 'function') throw new Error('[internal] JSZip export is not callable')\n const bytes = await convert(htmlToDocumentJson(workerData.html), JSZip)\n if (bytes.byteLength > workerData.maxOutputBytes) {\n parentPort.postMessage({ type: 'overflow' })\n parentPort.close()\n return\n }\n\n parentPort.postMessage({ type: 'start', totalBytes: bytes.byteLength })\n for (let offset = 0; offset < bytes.byteLength; offset += workerData.chunkBytes) {\n const length = Math.min(workerData.chunkBytes, bytes.byteLength - offset)\n const chunk = new Uint8Array(length)\n chunk.set(bytes.subarray(offset, offset + length))\n parentPort.postMessage({ type: 'chunk', chunk }, [chunk.buffer])\n }\n parentPort.postMessage({ type: 'done' })\n parentPort.close()\n})().catch((error) => {\n parentPort.postMessage({\n type: 'error',\n message: error && typeof error.message === 'string' ? error.message : 'DOCX conversion failed',\n })\n parentPort.close()\n})\n`\n\nconst requireFromHere = createRequire(import.meta.url)\n\nfunction defaultWorkerFactory(input: DocxWorkerFactoryInput): DocxWorker {\n return new Worker(DOCX_WORKER_SOURCE, {\n eval: true,\n workerData: input,\n resourceLimits: DOCX_WORKER_RESOURCE_LIMITS,\n // `--input-type=module` is valid only for the parent's eval/stdin entry and\n // would reinterpret this deliberately CommonJS worker source. Preserve all\n // other execArgv entries, including Yarn PnP loaders.\n execArgv: process.execArgv.filter((arg) => !arg.startsWith('--input-type')),\n })\n}\n\nfunction resolveDocxArchiveModuleReference(): Pick<DocxWorkerFactoryInput, 'modulePath' | 'moduleSpecifier' | 'requireFrom'> {\n // createRequire keeps node-modules and Yarn PnP resolution anchored to this\n // package. Turbopack rewrites a statically traced external `require.resolve`\n // to its numeric module id, which Node workers cannot require directly. Keep\n // the static lookup so output tracing includes the dependency, but fall back\n // to runtime resolution inside the unbundled worker when the value is not an\n // absolute Node path.\n const tracedPath: unknown = requireFromHere.resolve('jszip')\n return {\n modulePath: typeof tracedPath === 'string' && isAbsolute(tracedPath) ? tracedPath : null,\n moduleSpecifier: 'jszip',\n requireFrom: import.meta.url,\n }\n}\n\nexport function createDocxRenderer(\n options: DocxRendererOptions = {},\n deps: DocxRendererDeps = {},\n) {\n const maxConcurrency = options.maxConcurrency ?? DOCX_RENDER_MAX_CONCURRENCY\n const maxQueue = options.maxQueue ?? DOCX_RENDER_MAX_QUEUE\n const acquireTimeoutMs = options.acquireTimeoutMs ?? DOCX_RENDER_ACQUIRE_TIMEOUT_MS\n const renderTimeoutMs = options.renderTimeoutMs ?? DOCX_RENDER_TIMEOUT_MS\n const maxOutputBytes = options.maxOutputBytes ?? DOCX_MAX_OUTPUT_BYTES\n const workerFactory = deps.workerFactory ?? defaultWorkerFactory\n const allocateOutput = deps.allocateOutput ?? ((byteLength: number) => new Uint8Array(byteLength))\n let active = 0\n const waiters: Array<{\n resolve: (release: () => void) => void\n reject: (error: Error) => void\n timer: ReturnType<typeof setTimeout>\n }> = []\n\n const grant = (): (() => void) => {\n active += 1\n let released = false\n return () => {\n if (released) return\n released = true\n active -= 1\n const waiter = waiters.shift()\n if (!waiter) return\n clearTimeout(waiter.timer)\n waiter.resolve(grant())\n }\n }\n\n const acquire = async (): Promise<() => void> => {\n if (active < maxConcurrency) return grant()\n if (waiters.length >= maxQueue) throw new DocxRenderOverloadedError()\n return await new Promise<() => void>((resolve, reject) => {\n const waiter = {\n resolve,\n reject,\n timer: setTimeout(() => {\n const index = waiters.indexOf(waiter)\n if (index >= 0) waiters.splice(index, 1)\n reject(new DocxRenderOverloadedError())\n }, acquireTimeoutMs),\n }\n waiters.push(waiter)\n })\n }\n\n const runWorker = (html: string): Promise<Uint8Array> => new Promise((resolve, reject) => {\n let worker: DocxWorker\n try {\n const moduleReference = deps.modulePath === undefined\n ? resolveDocxArchiveModuleReference()\n : { modulePath: deps.modulePath, moduleSpecifier: 'jszip', requireFrom: import.meta.url }\n worker = workerFactory({\n html,\n ...moduleReference,\n maxOutputBytes,\n chunkBytes: DOCX_WORKER_CHUNK_BYTES,\n })\n } catch (error) {\n reject(new DocxRenderFailedError({ cause: error }))\n return\n }\n\n let settled = false\n let output: Uint8Array | null = null\n let expectedBytes: number | null = null\n let receivedBytes = 0\n const timer = setTimeout(() => {\n if (settled) return\n settled = true\n void worker.terminate().catch(() => undefined).then(() => {\n reject(new DocxRenderTimeoutError())\n })\n }, renderTimeoutMs)\n\n const terminateAndReject = (error: Error) => {\n if (settled) return\n settled = true\n clearTimeout(timer)\n void worker.terminate().catch(() => undefined).then(() => reject(error))\n }\n\n const terminateAndResolve = (value: Uint8Array) => {\n if (settled) return\n settled = true\n clearTimeout(timer)\n void worker.terminate().catch(() => undefined).then(() => resolve(value))\n }\n\n worker.on('message', (message) => {\n if (settled || !message || typeof message !== 'object') return\n const record = message as Record<string, unknown>\n if (record.type === 'overflow') {\n terminateAndReject(new DocxRenderOutputTooLargeError())\n return\n }\n if (record.type === 'error') {\n const message = typeof record.message === 'string'\n ? record.message\n : 'DOCX worker reported an unknown conversion failure'\n terminateAndReject(new DocxRenderFailedError({ cause: new Error(message) }))\n return\n }\n if (record.type === 'start') {\n const totalBytes = record.totalBytes\n if (\n expectedBytes !== null\n || typeof totalBytes !== 'number'\n || !Number.isSafeInteger(totalBytes)\n || totalBytes < 0\n || totalBytes > maxOutputBytes\n ) {\n terminateAndReject(new DocxRenderOutputTooLargeError())\n return\n }\n try {\n output = allocateOutput(totalBytes)\n if (output.byteLength !== totalBytes) throw new Error('[internal] invalid DOCX output allocation')\n expectedBytes = totalBytes\n } catch (error) {\n terminateAndReject(new DocxRenderFailedError({ cause: error }))\n }\n return\n }\n if (record.type === 'chunk') {\n const chunk = record.chunk\n if (\n expectedBytes === null\n || !output\n || !(chunk instanceof Uint8Array)\n || receivedBytes + chunk.byteLength > expectedBytes\n || receivedBytes + chunk.byteLength > maxOutputBytes\n ) {\n terminateAndReject(new DocxRenderOutputTooLargeError())\n return\n }\n output.set(chunk, receivedBytes)\n receivedBytes += chunk.byteLength\n return\n }\n if (record.type === 'done') {\n if (expectedBytes === null || !output || receivedBytes !== expectedBytes) {\n terminateAndReject(new DocxRenderFailedError())\n return\n }\n terminateAndResolve(output)\n }\n })\n worker.on('error', (error) => terminateAndReject(new DocxRenderFailedError({ cause: error })))\n worker.on('exit', (code) => {\n if (!settled) terminateAndReject(new DocxRenderFailedError({ cause: new Error(`DOCX worker exited with code ${code}`) }))\n })\n })\n\n const render = async (html: string): Promise<Uint8Array> => {\n const release = await acquire()\n try {\n return await runWorker(html)\n } finally {\n release()\n }\n }\n\n return { render }\n}\n\nconst DOCX_RENDERER_KEY = Symbol.for('open-mercato.documents.docxRenderer')\nconst globalStore = globalThis as typeof globalThis & {\n [DOCX_RENDERER_KEY]?: ReturnType<typeof createDocxRenderer>\n}\nconst processDocxRenderer = globalStore[DOCX_RENDERER_KEY]\n ?? (globalStore[DOCX_RENDERER_KEY] = createDocxRenderer())\n\nexport const renderDocxWithCapacity = processDocxRenderer.render\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAC3B,SAAS,cAAc;AAEhB,MAAM,8BAA8B;AACpC,MAAM,wBAAwB;AAC9B,MAAM,iCAAiC;AACvC,MAAM,yBAAyB;AAC/B,MAAM,wBAAwB,KAAK,OAAO;AAC1C,MAAM,0BAA0B,KAAK;AACrC,MAAM,8BAA8B,OAAO,OAAO;AAAA,EACvD,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,aAAa;AACf,CAAC;AACD,MAAM,yBAAyB,uBAAO,IAAI,gDAAgD;AAC1F,MAAM,sBAAsB,uBAAO,IAAI,6CAA6C;AACpF,MAAM,+BAA+B,uBAAO,IAAI,oDAAoD;AACpG,MAAM,qBAAqB,uBAAO,IAAI,4CAA4C;AAE3E,MAAM,mCAAkC,YACnC,6BADmC,IAAM;AAAA,EAEnD,cAAc;AACZ,UAAM,8BAA8B;AAFtC,SAAU,MAA0B;AAGlC,SAAK,OAAO;AAAA,EACd;AACF;AAEO,MAAM,gCAA+B,YAChC,0BADgC,IAAM;AAAA,EAEhD,cAAc;AACZ,UAAM,yBAAyB;AAFjC,SAAU,MAAuB;AAG/B,SAAK,OAAO;AAAA,EACd;AACF;AAEO,MAAM,uCAAsC,YACvC,mCADuC,IAAM;AAAA,EAEvD,cAAc;AACZ,UAAM,8CAA8C;AAFtD,SAAU,MAAgC;AAGxC,SAAK,OAAO;AAAA,EACd;AACF;AAEO,MAAM,+BAA8B,YAC/B,yBAD+B,IAAM;AAAA,EAE/C,YAAY,UAA+B,CAAC,GAAG;AAC7C,UAAM,wBAAwB,OAAO;AAFvC,SAAU,MAAsB;AAG9B,SAAK,OAAO;AAAA,EACd;AACF;AAEA,SAAS,eAAe,OAAgB,QAAyB;AAC/D,SAAO,QAAQ,SAAS,OAAO,UAAU,YAAa,MAAkC,MAAM,MAAM,IAAI;AAC1G;AAEO,MAAM,8BAA8B,CAAC,UAC1C,iBAAiB,6BAA6B,eAAe,OAAO,sBAAsB;AAErF,MAAM,2BAA2B,CAAC,UACvC,iBAAiB,0BAA0B,eAAe,OAAO,mBAAmB;AAE/E,MAAM,kCAAkC,CAAC,UAC9C,iBAAiB,iCAAiC,eAAe,OAAO,4BAA4B;AAE/F,MAAM,0BAA0B,CAAC,UACtC,iBAAiB,yBAAyB,eAAe,OAAO,kBAAkB;AA6CpF,MAAM,qBAAqB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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",
|
|
6
|
+
"names": ["message"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
function rewriteDuplicateAttachmentSrcUrl(src, input) {
|
|
2
|
+
const match = /^\/api\/documents\/([^/?#]+)\/attachments\/([^/?#]+)([?#].*)?$/.exec(src);
|
|
3
|
+
if (!match || match[1] !== input.sourceDocumentId) return src;
|
|
4
|
+
const replacementAttachmentId = input.attachmentIds.get(match[2] ?? "");
|
|
5
|
+
if (!replacementAttachmentId) return src;
|
|
6
|
+
return `/api/documents/${input.copyDocumentId}/attachments/${replacementAttachmentId}${match[3] ?? ""}`;
|
|
7
|
+
}
|
|
8
|
+
function rewriteDuplicateAttachmentUrls(contentHtml, input) {
|
|
9
|
+
return contentHtml.replace(
|
|
10
|
+
/((?<![\w-])src)(\s*=\s*)(["'])([^"']*)\3/gi,
|
|
11
|
+
(match, attribute, separator, quote, src) => {
|
|
12
|
+
const rewritten = rewriteDuplicateAttachmentSrcUrl(src, input);
|
|
13
|
+
if (rewritten === src) return match;
|
|
14
|
+
return `${attribute}${separator}${quote}${rewritten}${quote}`;
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
export {
|
|
19
|
+
rewriteDuplicateAttachmentSrcUrl,
|
|
20
|
+
rewriteDuplicateAttachmentUrls
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=duplicateContent.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/documents/lib/duplicateContent.ts"],
|
|
4
|
+
"sourcesContent": ["export type DuplicateAttachmentIdMap = ReadonlyMap<string, string>\n\ntype RewriteDuplicateAttachmentUrlInput = {\n sourceDocumentId: string\n copyDocumentId: string\n attachmentIds: DuplicateAttachmentIdMap\n}\n\nexport function rewriteDuplicateAttachmentSrcUrl(\n src: string,\n input: RewriteDuplicateAttachmentUrlInput,\n): string {\n const match = /^\\/api\\/documents\\/([^/?#]+)\\/attachments\\/([^/?#]+)([?#].*)?$/.exec(src)\n if (!match || match[1] !== input.sourceDocumentId) return src\n const replacementAttachmentId = input.attachmentIds.get(match[2] ?? '')\n if (!replacementAttachmentId) return src\n return `/api/documents/${input.copyDocumentId}/attachments/${replacementAttachmentId}${match[3] ?? ''}`\n}\n\nexport function rewriteDuplicateAttachmentUrls(\n contentHtml: string,\n input: RewriteDuplicateAttachmentUrlInput,\n): string {\n return contentHtml.replace(\n /((?<![\\w-])src)(\\s*=\\s*)([\"'])([^\"']*)\\3/gi,\n (match: string, attribute: string, separator: string, quote: string, src: string) => {\n const rewritten = rewriteDuplicateAttachmentSrcUrl(src, input)\n if (rewritten === src) return match\n return `${attribute}${separator}${quote}${rewritten}${quote}`\n },\n )\n}\n"],
|
|
5
|
+
"mappings": "AAQO,SAAS,iCACd,KACA,OACQ;AACR,QAAM,QAAQ,iEAAiE,KAAK,GAAG;AACvF,MAAI,CAAC,SAAS,MAAM,CAAC,MAAM,MAAM,iBAAkB,QAAO;AAC1D,QAAM,0BAA0B,MAAM,cAAc,IAAI,MAAM,CAAC,KAAK,EAAE;AACtE,MAAI,CAAC,wBAAyB,QAAO;AACrC,SAAO,kBAAkB,MAAM,cAAc,gBAAgB,uBAAuB,GAAG,MAAM,CAAC,KAAK,EAAE;AACvG;AAEO,SAAS,+BACd,aACA,OACQ;AACR,SAAO,YAAY;AAAA,IACjB;AAAA,IACA,CAAC,OAAe,WAAmB,WAAmB,OAAe,QAAgB;AACnF,YAAM,YAAY,iCAAiC,KAAK,KAAK;AAC7D,UAAI,cAAc,IAAK,QAAO;AAC9B,aAAO,GAAG,SAAS,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,GAAG,KAAK;AAAA,IAC7D;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { Mark, mergeAttributes, Node } from "@tiptap/core";
|
|
2
|
+
import StarterKit from "@tiptap/starter-kit";
|
|
3
|
+
import { Collaboration } from "@tiptap/extension-collaboration";
|
|
4
|
+
import { CollaborationCaret } from "@tiptap/extension-collaboration-caret";
|
|
5
|
+
import Link from "@tiptap/extension-link";
|
|
6
|
+
import Image from "@tiptap/extension-image";
|
|
7
|
+
import { Table } from "@tiptap/extension-table";
|
|
8
|
+
import TableRow from "@tiptap/extension-table-row";
|
|
9
|
+
import TableCell from "@tiptap/extension-table-cell";
|
|
10
|
+
import TableHeader from "@tiptap/extension-table-header";
|
|
11
|
+
import TaskList from "@tiptap/extension-task-list";
|
|
12
|
+
import TaskItem from "@tiptap/extension-task-item";
|
|
13
|
+
import Placeholder from "@tiptap/extension-placeholder";
|
|
14
|
+
import { TextAlign } from "@tiptap/extension-text-align";
|
|
15
|
+
import { Highlight } from "@tiptap/extension-highlight";
|
|
16
|
+
import { TextStyle, Color } from "@tiptap/extension-text-style";
|
|
17
|
+
import { CharacterCount } from "@tiptap/extensions";
|
|
18
|
+
import {
|
|
19
|
+
firstSafeDocumentsDisplayLabel,
|
|
20
|
+
sanitizeDocumentsDisplayLabel
|
|
21
|
+
} from "./displayLabels.js";
|
|
22
|
+
import {
|
|
23
|
+
firstSafeCollaborationAwarenessName,
|
|
24
|
+
normalizeCollaborationColor
|
|
25
|
+
} from "./collaborationAwareness.js";
|
|
26
|
+
const DEFAULT_ENTITY_REF_FALLBACK_LABEL = "Record";
|
|
27
|
+
function isHtmlLikeElement(value) {
|
|
28
|
+
return Boolean(
|
|
29
|
+
value && typeof value === "object" && typeof value.getAttribute === "function"
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
function readEntityRefAttribute(element, attribute) {
|
|
33
|
+
const value = element.getAttribute(attribute);
|
|
34
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
35
|
+
}
|
|
36
|
+
function readEntityRefSnapshotLabel(element) {
|
|
37
|
+
if (element.getAttribute("data-entity-label-invalid") !== null) return null;
|
|
38
|
+
return firstSafeDocumentsDisplayLabel(
|
|
39
|
+
readEntityRefAttribute(element, "data-label"),
|
|
40
|
+
element.textContent
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
function isSafeEntityHref(value) {
|
|
44
|
+
if (typeof value !== "string" || value !== value.trim() || !value.startsWith("/backend/") || value.startsWith("//") || value.includes("\\") || /[\u0000-\u001f\u007f]/.test(value)) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const base = new URL("https://open-mercato.invalid");
|
|
49
|
+
const resolved = new URL(value, base);
|
|
50
|
+
return resolved.origin === base.origin && resolved.pathname.startsWith("/backend/");
|
|
51
|
+
} catch {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function readClosestEntityHref(target, selector) {
|
|
56
|
+
if (!target || typeof target.closest !== "function") return null;
|
|
57
|
+
const element = target.closest(selector);
|
|
58
|
+
if (!element || typeof element !== "object") return null;
|
|
59
|
+
const dataset = element.dataset;
|
|
60
|
+
return isSafeEntityHref(dataset?.href) ? dataset.href : null;
|
|
61
|
+
}
|
|
62
|
+
function activateEntityRefFromPointerEvent(event, openHref) {
|
|
63
|
+
if (!event.metaKey && !event.ctrlKey) return false;
|
|
64
|
+
const href = readClosestEntityHref(event.target, "span[data-entity-ref]");
|
|
65
|
+
if (!href) return false;
|
|
66
|
+
openHref(href);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
function activateEntityRefFromKeyboardEvent(event, openHref) {
|
|
70
|
+
if (event.key !== "Enter" && event.key !== " ") return false;
|
|
71
|
+
const href = readClosestEntityHref(event.target, 'span[data-entity-ref][role="link"]');
|
|
72
|
+
if (!href) return false;
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
openHref(href);
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
const UnderlineMark = Mark.create({
|
|
78
|
+
name: "underline",
|
|
79
|
+
parseHTML() {
|
|
80
|
+
return [{ tag: "u" }];
|
|
81
|
+
},
|
|
82
|
+
renderHTML({ HTMLAttributes }) {
|
|
83
|
+
return ["u", mergeAttributes(HTMLAttributes), 0];
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
function createEntityRefNode(configuredFallbackLabel) {
|
|
87
|
+
const fallbackLabel = sanitizeDocumentsDisplayLabel(configuredFallbackLabel);
|
|
88
|
+
return Node.create({
|
|
89
|
+
name: "entityRef",
|
|
90
|
+
group: "inline",
|
|
91
|
+
inline: true,
|
|
92
|
+
atom: true,
|
|
93
|
+
selectable: true,
|
|
94
|
+
addAttributes() {
|
|
95
|
+
return {
|
|
96
|
+
entityType: {
|
|
97
|
+
default: null,
|
|
98
|
+
parseHTML: (element) => readEntityRefAttribute(element, "data-entity-type")
|
|
99
|
+
},
|
|
100
|
+
entityId: {
|
|
101
|
+
default: null,
|
|
102
|
+
parseHTML: (element) => readEntityRefAttribute(element, "data-entity-id")
|
|
103
|
+
},
|
|
104
|
+
label: {
|
|
105
|
+
default: null,
|
|
106
|
+
parseHTML: (element) => firstSafeDocumentsDisplayLabel(
|
|
107
|
+
readEntityRefSnapshotLabel(element),
|
|
108
|
+
fallbackLabel
|
|
109
|
+
)
|
|
110
|
+
},
|
|
111
|
+
labelInvalid: {
|
|
112
|
+
default: false,
|
|
113
|
+
rendered: false,
|
|
114
|
+
parseHTML: (element) => element.getAttribute("data-entity-label-invalid") !== null || !readEntityRefSnapshotLabel(element)
|
|
115
|
+
},
|
|
116
|
+
href: {
|
|
117
|
+
default: null,
|
|
118
|
+
parseHTML: (element) => readEntityRefSnapshotLabel(element) ? readEntityRefAttribute(element, "data-href") : null
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
},
|
|
122
|
+
parseHTML() {
|
|
123
|
+
return [
|
|
124
|
+
{
|
|
125
|
+
tag: "span[data-entity-ref]",
|
|
126
|
+
getAttrs: (value) => {
|
|
127
|
+
if (!isHtmlLikeElement(value)) return false;
|
|
128
|
+
return {
|
|
129
|
+
entityType: readEntityRefAttribute(value, "data-entity-type"),
|
|
130
|
+
entityId: readEntityRefAttribute(value, "data-entity-id"),
|
|
131
|
+
label: firstSafeDocumentsDisplayLabel(
|
|
132
|
+
readEntityRefSnapshotLabel(value),
|
|
133
|
+
fallbackLabel
|
|
134
|
+
),
|
|
135
|
+
labelInvalid: value.getAttribute("data-entity-label-invalid") !== null || !readEntityRefSnapshotLabel(value),
|
|
136
|
+
href: readEntityRefSnapshotLabel(value) ? readEntityRefAttribute(value, "data-href") : null
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
];
|
|
141
|
+
},
|
|
142
|
+
renderHTML({ node }) {
|
|
143
|
+
const attrs = node.attrs;
|
|
144
|
+
const safeSnapshotLabel = attrs.labelInvalid ? null : sanitizeDocumentsDisplayLabel(attrs.label);
|
|
145
|
+
const label = firstSafeDocumentsDisplayLabel(
|
|
146
|
+
safeSnapshotLabel,
|
|
147
|
+
fallbackLabel
|
|
148
|
+
) ?? "";
|
|
149
|
+
const href = safeSnapshotLabel && isSafeEntityHref(attrs.href) ? attrs.href : null;
|
|
150
|
+
const interactive = Boolean(label && href);
|
|
151
|
+
return [
|
|
152
|
+
"span",
|
|
153
|
+
mergeAttributes({
|
|
154
|
+
"data-entity-ref": "",
|
|
155
|
+
"data-entity-type": attrs.entityType ?? void 0,
|
|
156
|
+
"data-entity-id": attrs.entityId ?? void 0,
|
|
157
|
+
"data-label": safeSnapshotLabel ?? void 0,
|
|
158
|
+
"data-entity-label-invalid": safeSnapshotLabel ? void 0 : "",
|
|
159
|
+
"data-href": href ?? void 0,
|
|
160
|
+
role: interactive ? "link" : void 0,
|
|
161
|
+
tabindex: interactive ? "0" : void 0,
|
|
162
|
+
"aria-label": interactive ? label : void 0,
|
|
163
|
+
class: "om-entity-ref"
|
|
164
|
+
}),
|
|
165
|
+
label
|
|
166
|
+
];
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
const EntityRefNode = createEntityRefNode(DEFAULT_ENTITY_REF_FALLBACK_LABEL);
|
|
171
|
+
const COLLAB_FRAGMENT_FIELD = "default";
|
|
172
|
+
function getDocumentEditorExtensions(options) {
|
|
173
|
+
const starterKit = StarterKit.configure({
|
|
174
|
+
link: false,
|
|
175
|
+
underline: false,
|
|
176
|
+
...options?.history === false ? { undoRedo: false } : {}
|
|
177
|
+
});
|
|
178
|
+
return [
|
|
179
|
+
starterKit,
|
|
180
|
+
UnderlineMark,
|
|
181
|
+
Link.configure({
|
|
182
|
+
autolink: true,
|
|
183
|
+
linkOnPaste: true,
|
|
184
|
+
openOnClick: false
|
|
185
|
+
}),
|
|
186
|
+
Image.configure({
|
|
187
|
+
allowBase64: false,
|
|
188
|
+
inline: false
|
|
189
|
+
}),
|
|
190
|
+
Table.configure({
|
|
191
|
+
resizable: true
|
|
192
|
+
}),
|
|
193
|
+
TableRow,
|
|
194
|
+
TableCell,
|
|
195
|
+
TableHeader,
|
|
196
|
+
TaskList,
|
|
197
|
+
TaskItem.configure({
|
|
198
|
+
nested: true
|
|
199
|
+
}),
|
|
200
|
+
// Server-side CRDT materialization has no request locale. Preserve an
|
|
201
|
+
// invalid marker and an empty snapshot there; every user-visible editor
|
|
202
|
+
// supplies its localized fallback and renders it without persisting an
|
|
203
|
+
// arbitrary English label into the shared document.
|
|
204
|
+
createEntityRefNode(options?.entityRefFallbackLabel === void 0 ? null : firstSafeDocumentsDisplayLabel(
|
|
205
|
+
options.entityRefFallbackLabel,
|
|
206
|
+
DEFAULT_ENTITY_REF_FALLBACK_LABEL
|
|
207
|
+
)),
|
|
208
|
+
TextAlign.configure({ types: ["heading", "paragraph"] }),
|
|
209
|
+
Highlight.configure({ multicolor: true }),
|
|
210
|
+
TextStyle,
|
|
211
|
+
Color
|
|
212
|
+
];
|
|
213
|
+
}
|
|
214
|
+
function getClientEditorExtras() {
|
|
215
|
+
return [
|
|
216
|
+
CharacterCount.configure({})
|
|
217
|
+
];
|
|
218
|
+
}
|
|
219
|
+
function collaboratorSelectionAttributes(user) {
|
|
220
|
+
const color = normalizeCollaborationColor(user.color);
|
|
221
|
+
return {
|
|
222
|
+
style: `background-color: ${color}33`,
|
|
223
|
+
class: "ProseMirror-yjs-selection"
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function resolveCollaborationCaretLabel(user, fallbackUserLabel) {
|
|
227
|
+
return firstSafeCollaborationAwarenessName(user.name, fallbackUserLabel);
|
|
228
|
+
}
|
|
229
|
+
function resolveCollaborationCaretColor(user) {
|
|
230
|
+
return normalizeCollaborationColor(user.color);
|
|
231
|
+
}
|
|
232
|
+
function renderCollaborationCaret(user, fallbackUserLabel) {
|
|
233
|
+
const cursor = document.createElement("span");
|
|
234
|
+
cursor.classList.add("collaboration-carets__caret");
|
|
235
|
+
const color = resolveCollaborationCaretColor(user);
|
|
236
|
+
cursor.setAttribute("style", `border-color: ${color}`);
|
|
237
|
+
const labelText = resolveCollaborationCaretLabel(user, fallbackUserLabel);
|
|
238
|
+
if (labelText) {
|
|
239
|
+
cursor.setAttribute("role", "img");
|
|
240
|
+
cursor.setAttribute("aria-label", labelText);
|
|
241
|
+
cursor.setAttribute("title", labelText);
|
|
242
|
+
cursor.setAttribute("tabindex", "0");
|
|
243
|
+
cursor.setAttribute("contenteditable", "false");
|
|
244
|
+
const label = document.createElement("div");
|
|
245
|
+
label.classList.add("collaboration-carets__label");
|
|
246
|
+
label.setAttribute("style", `background-color: ${color}`);
|
|
247
|
+
label.setAttribute("aria-hidden", "true");
|
|
248
|
+
label.append(document.createTextNode(labelText));
|
|
249
|
+
cursor.append(label);
|
|
250
|
+
}
|
|
251
|
+
return cursor;
|
|
252
|
+
}
|
|
253
|
+
function getCollaborativeEditorExtensions(args) {
|
|
254
|
+
return [
|
|
255
|
+
...getDocumentEditorExtensions({
|
|
256
|
+
history: false,
|
|
257
|
+
entityRefFallbackLabel: args.fallbackEntityRefLabel
|
|
258
|
+
}),
|
|
259
|
+
Collaboration.configure({
|
|
260
|
+
document: args.ydoc,
|
|
261
|
+
field: COLLAB_FRAGMENT_FIELD
|
|
262
|
+
}),
|
|
263
|
+
CollaborationCaret.configure({
|
|
264
|
+
provider: args.provider,
|
|
265
|
+
user: args.user,
|
|
266
|
+
render: (user) => renderCollaborationCaret(user, args.fallbackUserLabel),
|
|
267
|
+
selectionRender: collaboratorSelectionAttributes
|
|
268
|
+
}),
|
|
269
|
+
Placeholder.configure({
|
|
270
|
+
placeholder: args.placeholder ?? "Start writing\u2026"
|
|
271
|
+
})
|
|
272
|
+
];
|
|
273
|
+
}
|
|
274
|
+
export {
|
|
275
|
+
COLLAB_FRAGMENT_FIELD,
|
|
276
|
+
EntityRefNode,
|
|
277
|
+
activateEntityRefFromKeyboardEvent,
|
|
278
|
+
activateEntityRefFromPointerEvent,
|
|
279
|
+
getClientEditorExtras,
|
|
280
|
+
getCollaborativeEditorExtensions,
|
|
281
|
+
getDocumentEditorExtensions,
|
|
282
|
+
isSafeEntityHref,
|
|
283
|
+
renderCollaborationCaret,
|
|
284
|
+
resolveCollaborationCaretColor,
|
|
285
|
+
resolveCollaborationCaretLabel
|
|
286
|
+
};
|
|
287
|
+
//# sourceMappingURL=editorConfig.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/documents/lib/editorConfig.ts"],
|
|
4
|
+
"sourcesContent": ["import { Mark, mergeAttributes, Node, type AnyExtension } from '@tiptap/core'\nimport StarterKit from '@tiptap/starter-kit'\nimport { Collaboration } from '@tiptap/extension-collaboration'\nimport { CollaborationCaret } from '@tiptap/extension-collaboration-caret'\nimport Link from '@tiptap/extension-link'\nimport Image from '@tiptap/extension-image'\nimport { Table } from '@tiptap/extension-table'\nimport TableRow from '@tiptap/extension-table-row'\nimport TableCell from '@tiptap/extension-table-cell'\nimport TableHeader from '@tiptap/extension-table-header'\nimport TaskList from '@tiptap/extension-task-list'\nimport TaskItem from '@tiptap/extension-task-item'\nimport Placeholder from '@tiptap/extension-placeholder'\nimport { TextAlign } from '@tiptap/extension-text-align'\nimport { Highlight } from '@tiptap/extension-highlight'\nimport { TextStyle, Color } from '@tiptap/extension-text-style'\nimport { CharacterCount } from '@tiptap/extensions'\nimport {\n firstSafeDocumentsDisplayLabel,\n sanitizeDocumentsDisplayLabel,\n} from './displayLabels'\nimport {\n firstSafeCollaborationAwarenessName,\n normalizeCollaborationColor,\n} from './collaborationAwareness'\n\nexport type EntityRefAttributes = {\n entityType: string\n entityId: string\n label: string\n href: string | null\n labelInvalid?: boolean\n}\n\nconst DEFAULT_ENTITY_REF_FALLBACK_LABEL = 'Record'\n\ntype HtmlLikeElement = {\n getAttribute: (name: string) => string | null\n textContent?: string | null\n}\n\nfunction isHtmlLikeElement(value: unknown): value is HtmlLikeElement {\n return Boolean(\n value &&\n typeof value === 'object' &&\n typeof (value as { getAttribute?: unknown }).getAttribute === 'function',\n )\n}\n\nfunction readEntityRefAttribute(element: HtmlLikeElement, attribute: string): string | null {\n const value = element.getAttribute(attribute)\n return typeof value === 'string' && value.length > 0 ? value : null\n}\n\nfunction readEntityRefSnapshotLabel(element: HtmlLikeElement): string | null {\n if (element.getAttribute('data-entity-label-invalid') !== null) return null\n return firstSafeDocumentsDisplayLabel(\n readEntityRefAttribute(element, 'data-label'),\n element.textContent,\n )\n}\n\nexport function isSafeEntityHref(value: unknown): value is string {\n if (\n typeof value !== 'string'\n || value !== value.trim()\n || !value.startsWith('/backend/')\n || value.startsWith('//')\n || value.includes('\\\\')\n || /[\\u0000-\\u001f\\u007f]/.test(value)\n ) {\n return false\n }\n\n try {\n const base = new URL('https://open-mercato.invalid')\n const resolved = new URL(value, base)\n return resolved.origin === base.origin && resolved.pathname.startsWith('/backend/')\n } catch {\n return false\n }\n}\n\ntype EntityRefPointerActivationEvent = {\n target: EventTarget | null\n metaKey: boolean\n ctrlKey: boolean\n}\n\ntype EntityRefKeyboardActivationEvent = {\n target: EventTarget | null\n key: string\n preventDefault: () => void\n}\n\ntype EntityHrefOpener = (href: string) => void\n\nfunction readClosestEntityHref(target: EventTarget | null, selector: string): string | null {\n if (!target || typeof (target as { closest?: unknown }).closest !== 'function') return null\n const element = (target as unknown as { closest: (value: string) => unknown }).closest(selector)\n if (!element || typeof element !== 'object') return null\n const dataset = (element as { dataset?: { href?: unknown } }).dataset\n return isSafeEntityHref(dataset?.href) ? dataset.href : null\n}\n\nexport function activateEntityRefFromPointerEvent(\n event: EntityRefPointerActivationEvent,\n openHref: EntityHrefOpener,\n): boolean {\n if (!event.metaKey && !event.ctrlKey) return false\n const href = readClosestEntityHref(event.target, 'span[data-entity-ref]')\n if (!href) return false\n openHref(href)\n return true\n}\n\nexport function activateEntityRefFromKeyboardEvent(\n event: EntityRefKeyboardActivationEvent,\n openHref: EntityHrefOpener,\n): boolean {\n if (event.key !== 'Enter' && event.key !== ' ') return false\n const href = readClosestEntityHref(event.target, 'span[data-entity-ref][role=\"link\"]')\n if (!href) return false\n event.preventDefault()\n openHref(href)\n return true\n}\n\nconst UnderlineMark = Mark.create({\n name: 'underline',\n parseHTML() {\n return [{ tag: 'u' }]\n },\n renderHTML({ HTMLAttributes }) {\n return ['u', mergeAttributes(HTMLAttributes), 0]\n },\n})\n\nfunction createEntityRefNode(configuredFallbackLabel: string | null) {\n const fallbackLabel = sanitizeDocumentsDisplayLabel(configuredFallbackLabel)\n return Node.create({\n name: 'entityRef',\n group: 'inline',\n inline: true,\n atom: true,\n selectable: true,\n addAttributes() {\n return {\n entityType: {\n default: null,\n parseHTML: (element: HtmlLikeElement) => readEntityRefAttribute(element, 'data-entity-type'),\n },\n entityId: {\n default: null,\n parseHTML: (element: HtmlLikeElement) => readEntityRefAttribute(element, 'data-entity-id'),\n },\n label: {\n default: null,\n parseHTML: (element: HtmlLikeElement) =>\n firstSafeDocumentsDisplayLabel(\n readEntityRefSnapshotLabel(element),\n fallbackLabel,\n ),\n },\n labelInvalid: {\n default: false,\n rendered: false,\n parseHTML: (element: HtmlLikeElement) => (\n element.getAttribute('data-entity-label-invalid') !== null\n || !readEntityRefSnapshotLabel(element)\n ),\n },\n href: {\n default: null,\n parseHTML: (element: HtmlLikeElement) => (\n readEntityRefSnapshotLabel(element)\n ? readEntityRefAttribute(element, 'data-href')\n : null\n ),\n },\n }\n },\n parseHTML() {\n return [\n {\n tag: 'span[data-entity-ref]',\n getAttrs: (value: unknown) => {\n if (!isHtmlLikeElement(value)) return false\n return {\n entityType: readEntityRefAttribute(value, 'data-entity-type'),\n entityId: readEntityRefAttribute(value, 'data-entity-id'),\n label: firstSafeDocumentsDisplayLabel(\n readEntityRefSnapshotLabel(value),\n fallbackLabel,\n ),\n labelInvalid: value.getAttribute('data-entity-label-invalid') !== null\n || !readEntityRefSnapshotLabel(value),\n href: readEntityRefSnapshotLabel(value)\n ? readEntityRefAttribute(value, 'data-href')\n : null,\n }\n },\n },\n ]\n },\n renderHTML({ node }) {\n const attrs = node.attrs as Partial<EntityRefAttributes>\n const safeSnapshotLabel = attrs.labelInvalid\n ? null\n : sanitizeDocumentsDisplayLabel(attrs.label)\n const label = firstSafeDocumentsDisplayLabel(\n safeSnapshotLabel,\n fallbackLabel,\n ) ?? ''\n const href = safeSnapshotLabel && isSafeEntityHref(attrs.href) ? attrs.href : null\n const interactive = Boolean(label && href)\n return [\n 'span',\n mergeAttributes({\n 'data-entity-ref': '',\n 'data-entity-type': attrs.entityType ?? undefined,\n 'data-entity-id': attrs.entityId ?? undefined,\n 'data-label': safeSnapshotLabel ?? undefined,\n 'data-entity-label-invalid': safeSnapshotLabel ? undefined : '',\n 'data-href': href ?? undefined,\n role: interactive ? 'link' : undefined,\n tabindex: interactive ? '0' : undefined,\n 'aria-label': interactive ? label : undefined,\n class: 'om-entity-ref',\n }),\n label,\n ]\n },\n })\n}\n\nexport const EntityRefNode = createEntityRefNode(DEFAULT_ENTITY_REF_FALLBACK_LABEL)\n\nexport const COLLAB_FRAGMENT_FIELD = 'default'\n\nexport function getDocumentEditorExtensions(options?: {\n history?: boolean\n entityRefFallbackLabel?: string\n}) {\n const starterKit = StarterKit.configure({\n link: false,\n underline: false,\n ...(options?.history === false ? { undoRedo: false as const } : {}),\n })\n\n return [\n starterKit,\n UnderlineMark,\n Link.configure({\n autolink: true,\n linkOnPaste: true,\n openOnClick: false,\n }),\n Image.configure({\n allowBase64: false,\n inline: false,\n }),\n Table.configure({\n resizable: true,\n }),\n TableRow,\n TableCell,\n TableHeader,\n TaskList,\n TaskItem.configure({\n nested: true,\n }),\n // Server-side CRDT materialization has no request locale. Preserve an\n // invalid marker and an empty snapshot there; every user-visible editor\n // supplies its localized fallback and renders it without persisting an\n // arbitrary English label into the shared document.\n createEntityRefNode(options?.entityRefFallbackLabel === undefined\n ? null\n : firstSafeDocumentsDisplayLabel(\n options.entityRefFallbackLabel,\n DEFAULT_ENTITY_REF_FALLBACK_LABEL,\n )),\n TextAlign.configure({ types: ['heading', 'paragraph'] }),\n Highlight.configure({ multicolor: true }),\n TextStyle,\n Color,\n ]\n}\n\nexport function getClientEditorExtras(): AnyExtension[] {\n return [\n CharacterCount.configure({}),\n ]\n}\n\n// Remote selections default to ~44% opacity (`${color}70`), which reads as a\n// heavy solid block. Google Docs uses a light wash \u2014 drop it to ~20% (`33`) so\n// overlapping text stays legible under a collaborator's highlight.\nfunction collaboratorSelectionAttributes(user: { color: string }) {\n const color = normalizeCollaborationColor(user.color)\n return {\n style: `background-color: ${color}33`,\n class: 'ProseMirror-yjs-selection',\n }\n}\n\nexport function resolveCollaborationCaretLabel(\n user: Record<string, unknown>,\n fallbackUserLabel: string,\n): string {\n return firstSafeCollaborationAwarenessName(user.name, fallbackUserLabel)\n}\n\nexport function resolveCollaborationCaretColor(user: Record<string, unknown>): string {\n return normalizeCollaborationColor(user.color)\n}\n\nexport function renderCollaborationCaret(\n user: Record<string, unknown>,\n fallbackUserLabel: string,\n): HTMLElement {\n const cursor = document.createElement('span')\n cursor.classList.add('collaboration-carets__caret')\n const color = resolveCollaborationCaretColor(user)\n cursor.setAttribute('style', `border-color: ${color}`)\n\n const labelText = resolveCollaborationCaretLabel(user, fallbackUserLabel)\n if (labelText) {\n cursor.setAttribute('role', 'img')\n cursor.setAttribute('aria-label', labelText)\n cursor.setAttribute('title', labelText)\n cursor.setAttribute('tabindex', '0')\n cursor.setAttribute('contenteditable', 'false')\n const label = document.createElement('div')\n label.classList.add('collaboration-carets__label')\n label.setAttribute('style', `background-color: ${color}`)\n label.setAttribute('aria-hidden', 'true')\n label.append(document.createTextNode(labelText))\n cursor.append(label)\n }\n return cursor\n}\n\nexport function getCollaborativeEditorExtensions(args: {\n ydoc: import('yjs').Doc\n provider: unknown\n user: { name: string; color: string }\n placeholder?: string\n fallbackUserLabel: string\n fallbackEntityRefLabel: string\n}) {\n return [\n ...getDocumentEditorExtensions({\n history: false,\n entityRefFallbackLabel: args.fallbackEntityRefLabel,\n }),\n Collaboration.configure({\n document: args.ydoc,\n field: COLLAB_FRAGMENT_FIELD,\n }),\n CollaborationCaret.configure({\n provider: args.provider,\n user: args.user,\n render: (user) => renderCollaborationCaret(user, args.fallbackUserLabel),\n selectionRender: collaboratorSelectionAttributes,\n }),\n Placeholder.configure({\n placeholder: args.placeholder ?? 'Start writing\u2026',\n }),\n ]\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
|
|
2
|
+
import { CrudHttpError } from "@open-mercato/shared/lib/crud/errors";
|
|
3
|
+
import { DocumentEntityLink } from "../data/entities.js";
|
|
4
|
+
import { sanitizeDocumentsDisplayLabel } from "./displayLabels.js";
|
|
5
|
+
import { getEntityTokenFieldNames } from "./entityRegistry.js";
|
|
6
|
+
import { DOCUMENTS_MAX_ENTITY_LINKS_PER_DOCUMENT } from "./resourceLimits.js";
|
|
7
|
+
const EMPTY_TARGET = {
|
|
8
|
+
customerEntityId: null,
|
|
9
|
+
customerKind: null,
|
|
10
|
+
dealId: null,
|
|
11
|
+
productId: null,
|
|
12
|
+
catalogOfferId: null,
|
|
13
|
+
quoteId: null,
|
|
14
|
+
salesOrderId: null,
|
|
15
|
+
linkedDocumentId: null
|
|
16
|
+
};
|
|
17
|
+
function sanitizeDocumentEntityValue(value) {
|
|
18
|
+
const label = sanitizeDocumentsDisplayLabel(value);
|
|
19
|
+
return label && label.length <= 1e4 ? label : null;
|
|
20
|
+
}
|
|
21
|
+
function buildDocumentEntityLinkTarget(entityType, entityId) {
|
|
22
|
+
const target = { ...EMPTY_TARGET };
|
|
23
|
+
if (entityType === "customer-person" || entityType === "customer-company") {
|
|
24
|
+
target.customerEntityId = entityId;
|
|
25
|
+
target.customerKind = entityType === "customer-person" ? "person" : "company";
|
|
26
|
+
} else if (entityType === "deal") {
|
|
27
|
+
target.dealId = entityId;
|
|
28
|
+
} else if (entityType === "product") {
|
|
29
|
+
target.productId = entityId;
|
|
30
|
+
} else if (entityType === "catalog-offer") {
|
|
31
|
+
target.catalogOfferId = entityId;
|
|
32
|
+
} else if (entityType === "quote") {
|
|
33
|
+
target.quoteId = entityId;
|
|
34
|
+
} else if (entityType === "document") {
|
|
35
|
+
target.linkedDocumentId = entityId;
|
|
36
|
+
} else {
|
|
37
|
+
target.salesOrderId = entityId;
|
|
38
|
+
}
|
|
39
|
+
return target;
|
|
40
|
+
}
|
|
41
|
+
function buildDocumentEntityLinkTargetWhere(entityType, entityId) {
|
|
42
|
+
return buildDocumentEntityLinkTarget(entityType, entityId);
|
|
43
|
+
}
|
|
44
|
+
function getDocumentEntityLinkType(link) {
|
|
45
|
+
if (link.customerEntityId) {
|
|
46
|
+
return link.customerKind === "company" ? "customer-company" : "customer-person";
|
|
47
|
+
}
|
|
48
|
+
if (link.dealId) return "deal";
|
|
49
|
+
if (link.productId) return "product";
|
|
50
|
+
if (link.catalogOfferId) return "catalog-offer";
|
|
51
|
+
if (link.quoteId) return "quote";
|
|
52
|
+
if (link.linkedDocumentId) return "document";
|
|
53
|
+
return "sales-order";
|
|
54
|
+
}
|
|
55
|
+
function getDocumentEntityLinkEntityId(link) {
|
|
56
|
+
return link.customerEntityId ?? link.dealId ?? link.productId ?? link.catalogOfferId ?? link.quoteId ?? link.linkedDocumentId ?? link.salesOrderId ?? "";
|
|
57
|
+
}
|
|
58
|
+
function createDocumentEntityLinkData(input) {
|
|
59
|
+
const labelSnapshot = sanitizeDocumentsDisplayLabel(input.link.label);
|
|
60
|
+
if (!labelSnapshot) {
|
|
61
|
+
throw new Error("[internal] document entity link label crossed persistence without a readable label");
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
id: input.id,
|
|
65
|
+
documentId: input.documentId,
|
|
66
|
+
tenantId: input.scope.tenantId,
|
|
67
|
+
organizationId: input.scope.organizationId,
|
|
68
|
+
labelSnapshot,
|
|
69
|
+
hrefSnapshot: input.link.href,
|
|
70
|
+
source: input.link.source,
|
|
71
|
+
createdByUserId: input.actorUserId,
|
|
72
|
+
...buildDocumentEntityLinkTarget(input.link.entityType, input.link.entityId)
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
async function findDocumentEntityLinks(em, documentId, scope, options = {}) {
|
|
76
|
+
const links = await findWithDecryption(
|
|
77
|
+
em,
|
|
78
|
+
DocumentEntityLink,
|
|
79
|
+
{
|
|
80
|
+
documentId,
|
|
81
|
+
tenantId: scope.tenantId,
|
|
82
|
+
organizationId: scope.organizationId,
|
|
83
|
+
...options.withDeleted ? {} : { deletedAt: null }
|
|
84
|
+
},
|
|
85
|
+
options.withDeleted ? { orderBy: { createdAt: "ASC" } } : {
|
|
86
|
+
orderBy: { createdAt: "ASC" },
|
|
87
|
+
limit: DOCUMENTS_MAX_ENTITY_LINKS_PER_DOCUMENT + 1
|
|
88
|
+
},
|
|
89
|
+
scope
|
|
90
|
+
);
|
|
91
|
+
if (!options.withDeleted) assertDocumentEntityLinkListWithinLimit(links);
|
|
92
|
+
return links;
|
|
93
|
+
}
|
|
94
|
+
function assertDocumentEntityLinkListWithinLimit(links) {
|
|
95
|
+
if (links.length <= DOCUMENTS_MAX_ENTITY_LINKS_PER_DOCUMENT) return;
|
|
96
|
+
throw new CrudHttpError(413, { error: "documents.links.limitExceeded" });
|
|
97
|
+
}
|
|
98
|
+
async function assertDocumentEntityLinkCapacity(em, documentId, scope) {
|
|
99
|
+
const activeCount = await em.count(DocumentEntityLink, {
|
|
100
|
+
documentId,
|
|
101
|
+
tenantId: scope.tenantId,
|
|
102
|
+
organizationId: scope.organizationId,
|
|
103
|
+
deletedAt: null
|
|
104
|
+
});
|
|
105
|
+
if (activeCount < DOCUMENTS_MAX_ENTITY_LINKS_PER_DOCUMENT) return;
|
|
106
|
+
throw new CrudHttpError(413, { error: "documents.links.limitExceeded" });
|
|
107
|
+
}
|
|
108
|
+
function serializeDocumentEntityLink(link, options) {
|
|
109
|
+
const entityType = getDocumentEntityLinkType(link);
|
|
110
|
+
const restrictedLabel = sanitizeDocumentsDisplayLabel(options.restrictedLabel);
|
|
111
|
+
const canonicalLabel = options.canonicalTarget ? sanitizeDocumentsDisplayLabel(options.canonicalTarget.label) : null;
|
|
112
|
+
const snapshotLabel = sanitizeDocumentsDisplayLabel(link.labelSnapshot);
|
|
113
|
+
const canOpen = options.canOpen && (options.canonicalTarget ? Boolean(canonicalLabel) : Boolean(snapshotLabel));
|
|
114
|
+
const readableLabel = canOpen ? canonicalLabel ?? snapshotLabel : restrictedLabel;
|
|
115
|
+
if (!readableLabel) {
|
|
116
|
+
throw new Error("[internal] document entity link serialization requires a readable fallback label");
|
|
117
|
+
}
|
|
118
|
+
const allowedValueFields = getEntityTokenFieldNames(entityType);
|
|
119
|
+
const values = options.canonicalTarget?.values ? Object.fromEntries(Array.from(allowedValueFields, (field) => [
|
|
120
|
+
field,
|
|
121
|
+
sanitizeDocumentEntityValue(options.canonicalTarget?.values?.[field])
|
|
122
|
+
])) : null;
|
|
123
|
+
const hasReadableValues = values ? Object.values(values).some((value) => value !== null) : false;
|
|
124
|
+
return {
|
|
125
|
+
id: link.id,
|
|
126
|
+
entityType,
|
|
127
|
+
entityId: canOpen ? options.canonicalTarget?.id ?? getDocumentEntityLinkEntityId(link) : null,
|
|
128
|
+
label: canOpen ? readableLabel : restrictedLabel ?? readableLabel,
|
|
129
|
+
href: canOpen ? options.canonicalTarget?.href ?? link.hrefSnapshot : null,
|
|
130
|
+
canOpen,
|
|
131
|
+
source: link.source,
|
|
132
|
+
createdAt: link.createdAt.toISOString(),
|
|
133
|
+
updatedAt: link.updatedAt.toISOString(),
|
|
134
|
+
...canOpen && hasReadableValues && values ? { values } : {}
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
export {
|
|
138
|
+
assertDocumentEntityLinkCapacity,
|
|
139
|
+
assertDocumentEntityLinkListWithinLimit,
|
|
140
|
+
buildDocumentEntityLinkTarget,
|
|
141
|
+
buildDocumentEntityLinkTargetWhere,
|
|
142
|
+
createDocumentEntityLinkData,
|
|
143
|
+
findDocumentEntityLinks,
|
|
144
|
+
getDocumentEntityLinkEntityId,
|
|
145
|
+
getDocumentEntityLinkType,
|
|
146
|
+
serializeDocumentEntityLink
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=entityLinks.js.map
|