@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,490 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
|
|
4
|
+
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
|
|
5
|
+
import { hasAllFeatures } from "@open-mercato/shared/lib/auth/featureMatch";
|
|
6
|
+
import {
|
|
7
|
+
ORGANIZATION_SCOPE_REQUIRED_ERROR_CODE,
|
|
8
|
+
resolveActiveOrganizationId
|
|
9
|
+
} from "@open-mercato/shared/lib/auth/organizationScope";
|
|
10
|
+
import { CrudHttpError, isCrudHttpError } from "@open-mercato/shared/lib/crud/errors";
|
|
11
|
+
import {
|
|
12
|
+
runRouteMutationGuards
|
|
13
|
+
} from "@open-mercato/shared/lib/crud/route-mutation-guard";
|
|
14
|
+
import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
|
|
15
|
+
import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
|
|
16
|
+
import { createLogger } from "@open-mercato/shared/lib/logger";
|
|
17
|
+
import {
|
|
18
|
+
Document,
|
|
19
|
+
DocumentShare
|
|
20
|
+
} from "../data/entities.js";
|
|
21
|
+
import {
|
|
22
|
+
deriveDocumentCapabilities
|
|
23
|
+
} from "../lib/capabilities.js";
|
|
24
|
+
import {
|
|
25
|
+
resolveActiveSubjectRoleIds,
|
|
26
|
+
resolvePermission
|
|
27
|
+
} from "../lib/permissions.js";
|
|
28
|
+
import { hasResolvedDocumentsOrganizationAccess } from "../lib/organizationAccess.js";
|
|
29
|
+
import { containsCanonicalUuid } from "../lib/displayLabels.js";
|
|
30
|
+
import {
|
|
31
|
+
DOCUMENTS_JSON_BODY_LIMITS,
|
|
32
|
+
readBoundedJsonBody
|
|
33
|
+
} from "../lib/requestBody.js";
|
|
34
|
+
import { resolveOrganizationScopeService } from "../lib/platformServices.js";
|
|
35
|
+
const logger = createLogger("documents").child({ component: "api" });
|
|
36
|
+
const routeErrorSchema = z.object({ error: z.string(), code: z.string().optional() });
|
|
37
|
+
const ORGANIZATION_SCOPE_REQUIRED_DESCRIPTION = `Organization scope could not be resolved (\`code: ${ORGANIZATION_SCOPE_REQUIRED_ERROR_CODE}\`)`;
|
|
38
|
+
const ORGANIZATION_SELECTION_INVALID_ERROR_CODE = "organization_selection_invalid";
|
|
39
|
+
const ORGANIZATION_SELECTION_INVALID_DESCRIPTION = `The selected organization no longer resolves (\`code: ${ORGANIZATION_SELECTION_INVALID_ERROR_CODE}\`)`;
|
|
40
|
+
function withDocumentsContextErrors(doc) {
|
|
41
|
+
const methods = {};
|
|
42
|
+
for (const method of Object.keys(doc.methods)) {
|
|
43
|
+
const methodDoc = doc.methods[method];
|
|
44
|
+
if (!methodDoc) continue;
|
|
45
|
+
const merge = (errors2, status, description) => errors2.some((error) => error.status === status) ? errors2.map((error) => error.status === status ? {
|
|
46
|
+
...error,
|
|
47
|
+
description: error.description ? `${error.description}, or ${description}` : description,
|
|
48
|
+
schema: error.schema ?? routeErrorSchema
|
|
49
|
+
} : error) : [...errors2, { status, description, schema: routeErrorSchema }];
|
|
50
|
+
let errors = merge(methodDoc.errors ?? [], 400, ORGANIZATION_SCOPE_REQUIRED_DESCRIPTION);
|
|
51
|
+
errors = merge(errors, 422, ORGANIZATION_SELECTION_INVALID_DESCRIPTION);
|
|
52
|
+
methods[method] = { ...methodDoc, errors };
|
|
53
|
+
}
|
|
54
|
+
return { ...doc, methods };
|
|
55
|
+
}
|
|
56
|
+
const actorUuidSchema = z.string().uuid();
|
|
57
|
+
const ROUTE_ERROR_TRANSLATIONS = {
|
|
58
|
+
Unauthorized: { key: "api.errors.unauthorized", fallback: "Unauthorized" },
|
|
59
|
+
Forbidden: { key: "api.errors.forbidden", fallback: "Forbidden" },
|
|
60
|
+
"Organization context is required": {
|
|
61
|
+
key: "documents.errors.organizationRequired",
|
|
62
|
+
fallback: "Organization context is required"
|
|
63
|
+
},
|
|
64
|
+
"Validation failed": { key: "api.errors.invalidPayload", fallback: "Invalid payload." },
|
|
65
|
+
"Internal server error": { key: "api.errors.internal", fallback: "Internal server error" },
|
|
66
|
+
"Record changed by another user": {
|
|
67
|
+
key: "documents.errors.recordChanged",
|
|
68
|
+
fallback: "Record changed by another user"
|
|
69
|
+
},
|
|
70
|
+
"Document not found": { key: "documents.documents.notFound", fallback: "Document not found." },
|
|
71
|
+
"documents.content.notFound": {
|
|
72
|
+
key: "documents.content.notFound",
|
|
73
|
+
fallback: "Document content not found."
|
|
74
|
+
},
|
|
75
|
+
"documents.versions.notFound": {
|
|
76
|
+
key: "documents.versions.notFound",
|
|
77
|
+
fallback: "Version not found."
|
|
78
|
+
},
|
|
79
|
+
"documents.folders.error.invalidPlacement": {
|
|
80
|
+
key: "documents.folders.error.invalidPlacement",
|
|
81
|
+
fallback: "This folder cannot be placed there."
|
|
82
|
+
},
|
|
83
|
+
"Folder not found": { key: "documents.folders.notFound", fallback: "Folder not found." },
|
|
84
|
+
"Share not found": { key: "documents.share.notFound", fallback: "Share not found." },
|
|
85
|
+
"Comment not found": { key: "documents.comments.notFound", fallback: "Comment not found." },
|
|
86
|
+
"Document comment limit reached": {
|
|
87
|
+
key: "documents.comments.limitExceeded",
|
|
88
|
+
fallback: "This document has reached its comment limit."
|
|
89
|
+
},
|
|
90
|
+
"Document version history storage limit exceeded": {
|
|
91
|
+
key: "documents.versions.quotaExceeded",
|
|
92
|
+
fallback: "Version history could not retain this snapshot within the document storage limit."
|
|
93
|
+
},
|
|
94
|
+
"documents.errors.requestBodyTooLarge": {
|
|
95
|
+
key: "documents.errors.requestBodyTooLarge",
|
|
96
|
+
fallback: "Request body is too large."
|
|
97
|
+
},
|
|
98
|
+
"Share principal not found in this organization": {
|
|
99
|
+
key: "documents.share.principalNotFound",
|
|
100
|
+
fallback: "Share principal not found in this organization"
|
|
101
|
+
},
|
|
102
|
+
"Private attachment partition is not configured": {
|
|
103
|
+
key: "documents.attachments.partitionUnavailable",
|
|
104
|
+
fallback: "Private attachment partition is not configured"
|
|
105
|
+
},
|
|
106
|
+
"Expected multipart/form-data": {
|
|
107
|
+
key: "documents.attachments.multipartRequired",
|
|
108
|
+
fallback: "Expected multipart/form-data"
|
|
109
|
+
},
|
|
110
|
+
"File is required": { key: "documents.attachments.fileRequired", fallback: "File is required" },
|
|
111
|
+
"Attachment exceeds the maximum upload size.": {
|
|
112
|
+
key: "documents.attachments.tooLarge",
|
|
113
|
+
fallback: "Attachment exceeds the maximum upload size."
|
|
114
|
+
},
|
|
115
|
+
"Executable file types are not allowed as attachments.": {
|
|
116
|
+
key: "documents.attachments.executableBlocked",
|
|
117
|
+
fallback: "Executable file types are not allowed as attachments."
|
|
118
|
+
},
|
|
119
|
+
"Active content uploads are not allowed.": {
|
|
120
|
+
key: "documents.attachments.activeContentBlocked",
|
|
121
|
+
fallback: "Active content uploads are not allowed."
|
|
122
|
+
},
|
|
123
|
+
"Attachment storage quota exceeded for this tenant.": {
|
|
124
|
+
key: "documents.attachments.quotaExceeded",
|
|
125
|
+
fallback: "Attachment storage quota exceeded for this tenant."
|
|
126
|
+
},
|
|
127
|
+
"Attachment not found": { key: "documents.attachments.notFound", fallback: "Attachment not found" },
|
|
128
|
+
"Partition misconfigured": {
|
|
129
|
+
key: "documents.attachments.partitionMisconfigured",
|
|
130
|
+
fallback: "Attachment partition is misconfigured"
|
|
131
|
+
},
|
|
132
|
+
"File not available": {
|
|
133
|
+
key: "documents.attachments.fileUnavailable",
|
|
134
|
+
fallback: "File not available"
|
|
135
|
+
},
|
|
136
|
+
"Unsupported format": { key: "documents.export.unsupportedFormat", fallback: "Unsupported format" },
|
|
137
|
+
"documents.export.runtimeUnavailable": {
|
|
138
|
+
key: "documents.export.runtimeUnavailable",
|
|
139
|
+
fallback: "PDF export is temporarily unavailable."
|
|
140
|
+
},
|
|
141
|
+
"documents.errors.organizationSelectionInvalid": {
|
|
142
|
+
key: "documents.errors.organizationSelectionInvalid",
|
|
143
|
+
fallback: "Your selected organization is no longer available. Please re-select an organization and try again."
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
const ROUTE_ERROR_KEY_FALLBACKS = Object.fromEntries(
|
|
147
|
+
Object.values(ROUTE_ERROR_TRANSLATIONS).map(({ key, fallback }) => [key, fallback])
|
|
148
|
+
);
|
|
149
|
+
function normalizeStrings(values) {
|
|
150
|
+
if (!Array.isArray(values)) return [];
|
|
151
|
+
return Array.from(
|
|
152
|
+
new Set(
|
|
153
|
+
values.map((value) => typeof value === "string" ? value.trim() : "").filter((value) => value.length > 0)
|
|
154
|
+
)
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
function resolveSelectedOrganization(auth, scope) {
|
|
158
|
+
const activeOrganizationId = resolveActiveOrganizationId(auth);
|
|
159
|
+
const allowed = scope?.filterIds ?? scope?.allowedIds ?? (activeOrganizationId ? [activeOrganizationId] : null);
|
|
160
|
+
const candidates = [
|
|
161
|
+
scope?.selectedId ?? null,
|
|
162
|
+
activeOrganizationId,
|
|
163
|
+
Array.isArray(allowed) && allowed.length > 0 ? allowed[0] : null
|
|
164
|
+
];
|
|
165
|
+
for (const candidate of candidates) {
|
|
166
|
+
if (!candidate) continue;
|
|
167
|
+
if (!Array.isArray(allowed) || allowed.includes(candidate)) return candidate;
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
function readAuthScopeId(auth, key) {
|
|
172
|
+
const value = auth[key];
|
|
173
|
+
if (typeof value === "string" && value.trim().length > 0) return value.trim();
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
function normalizeActorUuid(value) {
|
|
177
|
+
if (typeof value !== "string") return null;
|
|
178
|
+
const normalized = value.trim();
|
|
179
|
+
return actorUuidSchema.safeParse(normalized).success ? normalized : null;
|
|
180
|
+
}
|
|
181
|
+
function isApiKeyAuth(auth) {
|
|
182
|
+
return auth.isApiKey === true || auth.sub.trim().startsWith("api_key:");
|
|
183
|
+
}
|
|
184
|
+
function hasDocumentsFeature(auth, feature) {
|
|
185
|
+
if (auth.isSuperAdmin === true) return true;
|
|
186
|
+
return hasAllFeatures([feature], auth.features);
|
|
187
|
+
}
|
|
188
|
+
function hasAnyDocumentsFeature(auth, features) {
|
|
189
|
+
if (auth.isSuperAdmin === true) return true;
|
|
190
|
+
return features.some((feature) => hasAllFeatures([feature], auth.features));
|
|
191
|
+
}
|
|
192
|
+
function deriveCapabilitiesForContext(ctx, relationshipTier, options = {}) {
|
|
193
|
+
return deriveDocumentCapabilities({
|
|
194
|
+
relationshipTier,
|
|
195
|
+
managerOverride: hasDocumentsFeature(ctx.auth, "documents.manage"),
|
|
196
|
+
archived: options.archived === true,
|
|
197
|
+
userFeatures: ctx.auth.features
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
async function resolveDocumentCapabilityProjection(ctx, documentId, options = {}) {
|
|
201
|
+
const relationshipTier = await resolvePermission(ctx.em, documentId, ctx.auth);
|
|
202
|
+
return {
|
|
203
|
+
relationshipTier,
|
|
204
|
+
capabilities: deriveCapabilitiesForContext(ctx, relationshipTier, options)
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
async function loadDocumentArchivedState(ctx, documentId) {
|
|
208
|
+
const document = await findOneWithDecryption(
|
|
209
|
+
ctx.em,
|
|
210
|
+
Document,
|
|
211
|
+
{
|
|
212
|
+
id: documentId,
|
|
213
|
+
tenantId: ctx.tenantId,
|
|
214
|
+
organizationId: ctx.organizationId,
|
|
215
|
+
deletedAt: null
|
|
216
|
+
},
|
|
217
|
+
{ fields: ["id", "archivedAt"] },
|
|
218
|
+
{ tenantId: ctx.tenantId, organizationId: ctx.organizationId }
|
|
219
|
+
);
|
|
220
|
+
if (!document) throw new CrudHttpError(404, { error: "documents.documents.notFound" });
|
|
221
|
+
return { archivedAt: document.archivedAt ?? null };
|
|
222
|
+
}
|
|
223
|
+
async function assertDocumentNotArchived(ctx, documentId) {
|
|
224
|
+
const state = await loadDocumentArchivedState(ctx, documentId);
|
|
225
|
+
if (state.archivedAt !== null) {
|
|
226
|
+
throw new CrudHttpError(403, { error: "documents.errors.documentArchived" });
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
async function resolveDocumentsContext(request, requiredFeatures) {
|
|
230
|
+
const container = await createRequestContainer();
|
|
231
|
+
const em = container.resolve("em");
|
|
232
|
+
const auth = await getAuthFromRequest(request);
|
|
233
|
+
if (!auth || !auth.tenantId) {
|
|
234
|
+
throw new CrudHttpError(401, { error: "api.errors.unauthorized" });
|
|
235
|
+
}
|
|
236
|
+
const authenticatedActorUserId = resolveActorUserId(auth);
|
|
237
|
+
const actorTenantId = readAuthScopeId(auth, "actorTenantId") ?? auth.tenantId;
|
|
238
|
+
const actorOrganizationId = readAuthScopeId(auth, "actorOrgId") ?? auth.orgId;
|
|
239
|
+
const rbacService = container.resolve("rbacService");
|
|
240
|
+
const actorAcl = await rbacService.loadAcl(auth.sub, {
|
|
241
|
+
tenantId: actorTenantId,
|
|
242
|
+
organizationId: actorOrganizationId
|
|
243
|
+
});
|
|
244
|
+
const scopeAuth = {
|
|
245
|
+
...auth,
|
|
246
|
+
// API-key authentication validates both keyId and any backing user. Keep
|
|
247
|
+
// the prefixed subject for ACL while projecting its UUID domain actor for
|
|
248
|
+
// ownership/share/audit helpers. An unbound key uses its own key UUID.
|
|
249
|
+
userId: authenticatedActorUserId,
|
|
250
|
+
isSuperAdmin: actorAcl.isSuperAdmin === true
|
|
251
|
+
};
|
|
252
|
+
const organizationScopeService = resolveOrganizationScopeService(container);
|
|
253
|
+
if (!organizationScopeService) {
|
|
254
|
+
throw new CrudHttpError(403, { error: "api.errors.forbidden" });
|
|
255
|
+
}
|
|
256
|
+
const scope = await organizationScopeService.resolveForRequest({ auth: scopeAuth, request });
|
|
257
|
+
if (scope?.selectionRejected) {
|
|
258
|
+
throw new CrudHttpError(422, {
|
|
259
|
+
error: "documents.errors.organizationSelectionInvalid",
|
|
260
|
+
code: ORGANIZATION_SELECTION_INVALID_ERROR_CODE
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
const tenantId = scope?.tenantId ?? auth.tenantId;
|
|
264
|
+
const organizationId = resolveSelectedOrganization(scopeAuth, scope);
|
|
265
|
+
if (!tenantId) {
|
|
266
|
+
throw new CrudHttpError(400, { error: "documents.errors.organizationRequired" });
|
|
267
|
+
}
|
|
268
|
+
if (!organizationId) {
|
|
269
|
+
const unrestricted = (scope?.filterIds ?? scope?.allowedIds ?? null) === null;
|
|
270
|
+
if (unrestricted) {
|
|
271
|
+
throw new CrudHttpError(400, {
|
|
272
|
+
error: "documents.errors.organizationRequired",
|
|
273
|
+
code: ORGANIZATION_SCOPE_REQUIRED_ERROR_CODE
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
throw new CrudHttpError(403, { error: "api.errors.forbidden" });
|
|
277
|
+
}
|
|
278
|
+
const acl = await rbacService.loadAcl(auth.sub, { tenantId, organizationId });
|
|
279
|
+
if (!hasResolvedDocumentsOrganizationAccess(acl, organizationId, scope)) {
|
|
280
|
+
throw new CrudHttpError(403, { error: "api.errors.forbidden" });
|
|
281
|
+
}
|
|
282
|
+
const roleIds = await resolveActiveSubjectRoleIds(
|
|
283
|
+
container,
|
|
284
|
+
{ tenantId, organizationId },
|
|
285
|
+
auth.sub
|
|
286
|
+
);
|
|
287
|
+
const documentsAuth = {
|
|
288
|
+
...scopeAuth,
|
|
289
|
+
tenantId,
|
|
290
|
+
orgId: organizationId,
|
|
291
|
+
organizationId,
|
|
292
|
+
roleIds,
|
|
293
|
+
resolvedRoleIds: roleIds,
|
|
294
|
+
// JWT/trusted-request claims are only authentication hints. The current
|
|
295
|
+
// RBAC projection is authoritative for features and superadmin status so
|
|
296
|
+
// a revoked grant cannot survive in a long-lived token.
|
|
297
|
+
features: acl.isSuperAdmin === true ? ["*"] : normalizeStrings(acl.features),
|
|
298
|
+
isSuperAdmin: acl.isSuperAdmin === true
|
|
299
|
+
};
|
|
300
|
+
if (!hasAnyDocumentsFeature(documentsAuth, requiredFeatures)) {
|
|
301
|
+
throw new CrudHttpError(403, { error: "api.errors.forbidden" });
|
|
302
|
+
}
|
|
303
|
+
return {
|
|
304
|
+
container,
|
|
305
|
+
em,
|
|
306
|
+
auth: documentsAuth,
|
|
307
|
+
tenantId,
|
|
308
|
+
organizationId,
|
|
309
|
+
request
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function resolveActorUserId(auth) {
|
|
313
|
+
const subject = auth.sub.trim();
|
|
314
|
+
if (isApiKeyAuth(auth)) {
|
|
315
|
+
const keyId = normalizeActorUuid(auth.keyId);
|
|
316
|
+
if (!keyId || subject !== `api_key:${keyId}`) {
|
|
317
|
+
throw new CrudHttpError(403, { error: "api.errors.forbidden" });
|
|
318
|
+
}
|
|
319
|
+
if (auth.userId === void 0 || auth.userId === null) return keyId;
|
|
320
|
+
const backingUserId = normalizeActorUuid(auth.userId);
|
|
321
|
+
if (backingUserId) return backingUserId;
|
|
322
|
+
throw new CrudHttpError(403, { error: "api.errors.forbidden" });
|
|
323
|
+
}
|
|
324
|
+
const actorUserId = normalizeActorUuid(subject);
|
|
325
|
+
const claimedUserId = auth.userId === void 0 || auth.userId === null ? actorUserId : normalizeActorUuid(auth.userId);
|
|
326
|
+
if (actorUserId && claimedUserId === actorUserId) return actorUserId;
|
|
327
|
+
throw new CrudHttpError(403, { error: "api.errors.forbidden" });
|
|
328
|
+
}
|
|
329
|
+
async function readBody(request, maxBytes = DOCUMENTS_JSON_BODY_LIMITS.standard) {
|
|
330
|
+
return await readBoundedJsonBody(request, maxBytes, {}) ?? {};
|
|
331
|
+
}
|
|
332
|
+
async function localizeRouteErrorBody(body) {
|
|
333
|
+
const rawError = typeof body.error === "string" ? body.error : null;
|
|
334
|
+
if (!rawError) return body;
|
|
335
|
+
if (containsCanonicalUuid(rawError)) {
|
|
336
|
+
const { key: key2, fallback: fallback2 } = ROUTE_ERROR_TRANSLATIONS["Internal server error"];
|
|
337
|
+
try {
|
|
338
|
+
const { translate } = await resolveTranslations();
|
|
339
|
+
return { ...body, error: translate(key2, fallback2) };
|
|
340
|
+
} catch {
|
|
341
|
+
return { ...body, error: fallback2 };
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
const literal = ROUTE_ERROR_TRANSLATIONS[rawError];
|
|
345
|
+
const key = literal?.key ?? rawError;
|
|
346
|
+
const fallback = literal?.fallback ?? ROUTE_ERROR_KEY_FALLBACKS[key];
|
|
347
|
+
if (!key.startsWith("documents.") && !key.startsWith("api.") && !key.startsWith("attachments.")) return body;
|
|
348
|
+
try {
|
|
349
|
+
const { translate } = await resolveTranslations();
|
|
350
|
+
return { ...body, error: translate(key, fallback) };
|
|
351
|
+
} catch {
|
|
352
|
+
return { ...body, error: fallback ?? key };
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
async function handleDocumentsRouteError(error, label) {
|
|
356
|
+
if (isCrudHttpError(error)) {
|
|
357
|
+
const body = error.body && typeof error.body === "object" && !Array.isArray(error.body) ? error.body : { error: "api.errors.internal" };
|
|
358
|
+
return NextResponse.json(await localizeRouteErrorBody(body), { status: error.status });
|
|
359
|
+
}
|
|
360
|
+
if (error instanceof z.ZodError) {
|
|
361
|
+
return NextResponse.json(
|
|
362
|
+
await localizeRouteErrorBody({ error: "api.errors.invalidPayload", details: error.issues }),
|
|
363
|
+
{ status: 400 }
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
logger.error(`${label} failed`, { err: error });
|
|
367
|
+
return NextResponse.json(
|
|
368
|
+
await localizeRouteErrorBody({ error: "api.errors.internal" }),
|
|
369
|
+
{ status: 500 }
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
async function loadScopedDocument(ctx, id) {
|
|
373
|
+
const document = await findOneWithDecryption(ctx.em, Document, {
|
|
374
|
+
id,
|
|
375
|
+
tenantId: ctx.tenantId,
|
|
376
|
+
organizationId: ctx.organizationId,
|
|
377
|
+
deletedAt: null
|
|
378
|
+
}, void 0, { tenantId: ctx.tenantId, organizationId: ctx.organizationId });
|
|
379
|
+
if (!document) throw new CrudHttpError(404, { error: "documents.documents.notFound" });
|
|
380
|
+
return document;
|
|
381
|
+
}
|
|
382
|
+
async function loadScopedShare(ctx, documentId, shareId) {
|
|
383
|
+
const share = await findOneWithDecryption(ctx.em, DocumentShare, {
|
|
384
|
+
id: shareId,
|
|
385
|
+
documentId,
|
|
386
|
+
tenantId: ctx.tenantId,
|
|
387
|
+
organizationId: ctx.organizationId,
|
|
388
|
+
deletedAt: null
|
|
389
|
+
}, void 0, { tenantId: ctx.tenantId, organizationId: ctx.organizationId });
|
|
390
|
+
if (!share) throw new CrudHttpError(404, { error: "documents.share.notFound" });
|
|
391
|
+
return share;
|
|
392
|
+
}
|
|
393
|
+
function serializeDocument(document) {
|
|
394
|
+
return {
|
|
395
|
+
id: document.id,
|
|
396
|
+
title: document.title,
|
|
397
|
+
folderId: document.folderId ?? null,
|
|
398
|
+
ownerUserId: document.ownerUserId,
|
|
399
|
+
createdByUserId: document.createdByUserId,
|
|
400
|
+
isActive: document.isActive,
|
|
401
|
+
createdAt: document.createdAt.toISOString(),
|
|
402
|
+
updatedAt: document.updatedAt.toISOString()
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
function serializeContent(content) {
|
|
406
|
+
return {
|
|
407
|
+
contentHtml: content?.contentHtml ?? "",
|
|
408
|
+
contentText: content?.contentText ?? "",
|
|
409
|
+
updatedAt: content?.updatedAt ? content.updatedAt.toISOString() : null
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
function serializeFolder(folder) {
|
|
413
|
+
return {
|
|
414
|
+
id: folder.id,
|
|
415
|
+
name: folder.name,
|
|
416
|
+
parentFolderId: folder.parentFolderId ?? null,
|
|
417
|
+
ownerUserId: folder.ownerUserId,
|
|
418
|
+
createdAt: folder.createdAt.toISOString(),
|
|
419
|
+
updatedAt: folder.updatedAt.toISOString()
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
function serializeShare(share) {
|
|
423
|
+
return {
|
|
424
|
+
id: share.id,
|
|
425
|
+
documentId: share.documentId,
|
|
426
|
+
principalType: share.principalType,
|
|
427
|
+
principalId: share.principalId,
|
|
428
|
+
permission: share.permission,
|
|
429
|
+
createdByUserId: share.createdByUserId,
|
|
430
|
+
createdAt: share.createdAt.toISOString(),
|
|
431
|
+
updatedAt: share.updatedAt.toISOString()
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
async function validateMutationGuard(ctx, input) {
|
|
435
|
+
const guardResult = await runRouteMutationGuards({
|
|
436
|
+
container: ctx.container,
|
|
437
|
+
req: ctx.request,
|
|
438
|
+
auth: {
|
|
439
|
+
tenantId: ctx.tenantId,
|
|
440
|
+
organizationId: ctx.organizationId,
|
|
441
|
+
userId: resolveActorUserId(ctx.auth),
|
|
442
|
+
userFeatures: ctx.auth.features
|
|
443
|
+
},
|
|
444
|
+
input: {
|
|
445
|
+
resourceKind: input.resourceKind,
|
|
446
|
+
resourceId: input.resourceId,
|
|
447
|
+
operation: input.operation,
|
|
448
|
+
mutationPayload: input.mutationPayload ?? null
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
if (!guardResult.ok) {
|
|
452
|
+
throw new CrudHttpError(guardResult.errorStatus, guardResult.errorBody);
|
|
453
|
+
}
|
|
454
|
+
if (guardResult.modifiedPayload && input.mutationPayload) {
|
|
455
|
+
const transformed = input.mutationPayloadSchema ? input.mutationPayloadSchema.parse(guardResult.modifiedPayload) : guardResult.modifiedPayload;
|
|
456
|
+
for (const key of Object.keys(input.mutationPayload)) delete input.mutationPayload[key];
|
|
457
|
+
Object.assign(input.mutationPayload, transformed);
|
|
458
|
+
}
|
|
459
|
+
return guardResult;
|
|
460
|
+
}
|
|
461
|
+
async function runMutationGuardAfterSuccess(_ctx, guardResult, _input) {
|
|
462
|
+
await guardResult.runAfterSuccess();
|
|
463
|
+
}
|
|
464
|
+
export {
|
|
465
|
+
ORGANIZATION_SCOPE_REQUIRED_DESCRIPTION,
|
|
466
|
+
ORGANIZATION_SELECTION_INVALID_DESCRIPTION,
|
|
467
|
+
ORGANIZATION_SELECTION_INVALID_ERROR_CODE,
|
|
468
|
+
ROUTE_ERROR_TRANSLATIONS,
|
|
469
|
+
assertDocumentNotArchived,
|
|
470
|
+
deriveCapabilitiesForContext,
|
|
471
|
+
handleDocumentsRouteError,
|
|
472
|
+
hasAnyDocumentsFeature,
|
|
473
|
+
hasDocumentsFeature,
|
|
474
|
+
loadDocumentArchivedState,
|
|
475
|
+
loadScopedDocument,
|
|
476
|
+
loadScopedShare,
|
|
477
|
+
readBody,
|
|
478
|
+
resolveActorUserId,
|
|
479
|
+
resolveDocumentCapabilityProjection,
|
|
480
|
+
resolveDocumentsContext,
|
|
481
|
+
routeErrorSchema,
|
|
482
|
+
runMutationGuardAfterSuccess,
|
|
483
|
+
serializeContent,
|
|
484
|
+
serializeDocument,
|
|
485
|
+
serializeFolder,
|
|
486
|
+
serializeShare,
|
|
487
|
+
validateMutationGuard,
|
|
488
|
+
withDocumentsContextErrors
|
|
489
|
+
};
|
|
490
|
+
//# sourceMappingURL=_shared.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/documents/api/_shared.ts"],
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { AwilixContainer } from 'awilix'\nimport { z } from 'zod'\nimport { getAuthFromRequest, type AuthContext } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { hasAllFeatures } from '@open-mercato/shared/lib/auth/featureMatch'\nimport {\n ORGANIZATION_SCOPE_REQUIRED_ERROR_CODE,\n resolveActiveOrganizationId,\n} from '@open-mercato/shared/lib/auth/organizationScope'\nimport { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport {\n runRouteMutationGuards,\n type RouteMutationGuardPassed,\n} from '@open-mercato/shared/lib/crud/route-mutation-guard'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport type { OpenApiHttpMethod, OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport {\n Document,\n DocumentContent,\n DocumentFolder,\n DocumentShare,\n} from '../data/entities'\nimport {\n deriveDocumentCapabilities,\n type DocumentCapabilities,\n} from '../lib/capabilities'\nimport {\n resolveActiveSubjectRoleIds,\n resolvePermission,\n type DocumentTier,\n} from '../lib/permissions'\nimport { hasResolvedDocumentsOrganizationAccess } from '../lib/organizationAccess'\nimport { containsCanonicalUuid } from '../lib/displayLabels'\nimport {\n DOCUMENTS_JSON_BODY_LIMITS,\n readBoundedJsonBody,\n} from '../lib/requestBody'\nimport { resolveOrganizationScopeService } from '../lib/platformServices'\n\nconst logger = createLogger('documents').child({ component: 'api' })\n\nexport type DocumentsAuthContext = NonNullable<AuthContext> & {\n features: string[]\n roleIds: string[]\n resolvedRoleIds: string[]\n organizationId: string\n}\n\nexport type DocumentsRouteContext = {\n container: AwilixContainer\n em: EntityManager\n auth: DocumentsAuthContext\n tenantId: string\n organizationId: string\n request: Request\n}\n\ntype RbacServiceLike = {\n loadAcl: (\n userId: string,\n scope: { tenantId: string | null; organizationId: string | null },\n ) => Promise<{\n isSuperAdmin: boolean\n features: string[]\n organizations: string[] | null\n }>\n}\n\nexport type MutationGuardResult = RouteMutationGuardPassed\n\nexport type DocumentCapabilityProjection = {\n relationshipTier: DocumentTier | null\n capabilities: DocumentCapabilities\n}\n\n/**\n * Every documents error body carries a translated `error` message. Some also\n * carry a machine-readable `code` discriminator: without it a client cannot\n * tell an unresolved organization scope (recoverable \u2014 pick an organization)\n * apart from an ordinary validation rejection, since both are a 400.\n */\nexport const routeErrorSchema = z.object({ error: z.string(), code: z.string().optional() })\n\nexport const ORGANIZATION_SCOPE_REQUIRED_DESCRIPTION =\n `Organization scope could not be resolved (\\`code: ${ORGANIZATION_SCOPE_REQUIRED_ERROR_CODE}\\`)`\n\nexport const ORGANIZATION_SELECTION_INVALID_ERROR_CODE = 'organization_selection_invalid'\n\nexport const ORGANIZATION_SELECTION_INVALID_DESCRIPTION =\n `The selected organization no longer resolves (\\`code: ${ORGANIZATION_SELECTION_INVALID_ERROR_CODE}\\`)`\n\n/**\n * `resolveDocumentsContext` answers 400 with the\n * `organization_scope_required` discriminator whenever an unrestricted caller\n * (a super-admin viewing a foreign tenant with \"all organizations\" selected)\n * has no resolvable organization. Every route that resolves a documents\n * context can therefore return it, including methods whose own contract\n * declares no 400 at all \u2014 so the contract has to say so, or generated clients\n * and the API reference cannot model the recovery path.\n *\n * Responses are keyed by status when the document is built, so a route that\n * already documents a 400 must merge rather than append a second entry.\n */\nexport function withDocumentsContextErrors(doc: OpenApiRouteDoc): OpenApiRouteDoc {\n const methods: OpenApiRouteDoc['methods'] = {}\n for (const method of Object.keys(doc.methods) as OpenApiHttpMethod[]) {\n const methodDoc = doc.methods[method]\n if (!methodDoc) continue\n const merge = (\n errors: NonNullable<typeof methodDoc.errors>,\n status: number,\n description: string,\n ): NonNullable<typeof methodDoc.errors> => (\n errors.some((error) => error.status === status)\n ? errors.map((error) => (error.status === status\n ? {\n ...error,\n description: error.description\n ? `${error.description}, or ${description}`\n : description,\n schema: error.schema ?? routeErrorSchema,\n }\n : error))\n : [...errors, { status, description, schema: routeErrorSchema }]\n )\n // `resolveDocumentsContext` answers 400 `organization_scope_required` and\n // 422 `organization_selection_invalid` from the same call, so both ride on\n // every route that resolves a documents context.\n let errors = merge(methodDoc.errors ?? [], 400, ORGANIZATION_SCOPE_REQUIRED_DESCRIPTION)\n errors = merge(errors, 422, ORGANIZATION_SELECTION_INVALID_DESCRIPTION)\n methods[method] = { ...methodDoc, errors }\n }\n return { ...doc, methods }\n}\n\nconst actorUuidSchema = z.string().uuid()\n\nexport const ROUTE_ERROR_TRANSLATIONS: Record<string, { key: string; fallback: string }> = {\n Unauthorized: { key: 'api.errors.unauthorized', fallback: 'Unauthorized' },\n Forbidden: { key: 'api.errors.forbidden', fallback: 'Forbidden' },\n 'Organization context is required': {\n key: 'documents.errors.organizationRequired',\n fallback: 'Organization context is required',\n },\n 'Validation failed': { key: 'api.errors.invalidPayload', fallback: 'Invalid payload.' },\n 'Internal server error': { key: 'api.errors.internal', fallback: 'Internal server error' },\n 'Record changed by another user': {\n key: 'documents.errors.recordChanged',\n fallback: 'Record changed by another user',\n },\n 'Document not found': { key: 'documents.documents.notFound', fallback: 'Document not found.' },\n 'documents.content.notFound': {\n key: 'documents.content.notFound',\n fallback: 'Document content not found.',\n },\n 'documents.versions.notFound': {\n key: 'documents.versions.notFound',\n fallback: 'Version not found.',\n },\n 'documents.folders.error.invalidPlacement': {\n key: 'documents.folders.error.invalidPlacement',\n fallback: 'This folder cannot be placed there.',\n },\n 'Folder not found': { key: 'documents.folders.notFound', fallback: 'Folder not found.' },\n 'Share not found': { key: 'documents.share.notFound', fallback: 'Share not found.' },\n 'Comment not found': { key: 'documents.comments.notFound', fallback: 'Comment not found.' },\n 'Document comment limit reached': {\n key: 'documents.comments.limitExceeded',\n fallback: 'This document has reached its comment limit.',\n },\n 'Document version history storage limit exceeded': {\n key: 'documents.versions.quotaExceeded',\n fallback: 'Version history could not retain this snapshot within the document storage limit.',\n },\n 'documents.errors.requestBodyTooLarge': {\n key: 'documents.errors.requestBodyTooLarge',\n fallback: 'Request body is too large.',\n },\n 'Share principal not found in this organization': {\n key: 'documents.share.principalNotFound',\n fallback: 'Share principal not found in this organization',\n },\n 'Private attachment partition is not configured': {\n key: 'documents.attachments.partitionUnavailable',\n fallback: 'Private attachment partition is not configured',\n },\n 'Expected multipart/form-data': {\n key: 'documents.attachments.multipartRequired',\n fallback: 'Expected multipart/form-data',\n },\n 'File is required': { key: 'documents.attachments.fileRequired', fallback: 'File is required' },\n 'Attachment exceeds the maximum upload size.': {\n key: 'documents.attachments.tooLarge',\n fallback: 'Attachment exceeds the maximum upload size.',\n },\n 'Executable file types are not allowed as attachments.': {\n key: 'documents.attachments.executableBlocked',\n fallback: 'Executable file types are not allowed as attachments.',\n },\n 'Active content uploads are not allowed.': {\n key: 'documents.attachments.activeContentBlocked',\n fallback: 'Active content uploads are not allowed.',\n },\n 'Attachment storage quota exceeded for this tenant.': {\n key: 'documents.attachments.quotaExceeded',\n fallback: 'Attachment storage quota exceeded for this tenant.',\n },\n 'Attachment not found': { key: 'documents.attachments.notFound', fallback: 'Attachment not found' },\n 'Partition misconfigured': {\n key: 'documents.attachments.partitionMisconfigured',\n fallback: 'Attachment partition is misconfigured',\n },\n 'File not available': {\n key: 'documents.attachments.fileUnavailable',\n fallback: 'File not available',\n },\n 'Unsupported format': { key: 'documents.export.unsupportedFormat', fallback: 'Unsupported format' },\n 'documents.export.runtimeUnavailable': {\n key: 'documents.export.runtimeUnavailable',\n fallback: 'PDF export is temporarily unavailable.',\n },\n 'documents.errors.organizationSelectionInvalid': {\n key: 'documents.errors.organizationSelectionInvalid',\n fallback: 'Your selected organization is no longer available. Please re-select an organization and try again.',\n },\n}\n\nconst ROUTE_ERROR_KEY_FALLBACKS = Object.fromEntries(\n Object.values(ROUTE_ERROR_TRANSLATIONS).map(({ key, fallback }) => [key, fallback]),\n) as Record<string, string>\n\nfunction normalizeStrings(values: unknown): string[] {\n if (!Array.isArray(values)) return []\n return Array.from(\n new Set(\n values\n .map((value) => (typeof value === 'string' ? value.trim() : ''))\n .filter((value) => value.length > 0),\n ),\n )\n}\n\nfunction resolveSelectedOrganization(\n auth: NonNullable<AuthContext>,\n scope: { selectedId?: string | null; filterIds?: string[] | null; allowedIds?: string[] | null; tenantId?: string | null } | null,\n): string | null {\n // Every document row carries one organization, so there is no \"all\n // organizations\" view of this module. When the super-admin switcher clears\n // `auth.orgId`, keep the operator on their own organization (the shared\n // helper refuses the fallback once the tenant override moved them elsewhere)\n // instead of failing every request.\n const activeOrganizationId = resolveActiveOrganizationId(auth)\n const allowed = scope?.filterIds ?? scope?.allowedIds ?? (activeOrganizationId ? [activeOrganizationId] : null)\n const candidates = [\n scope?.selectedId ?? null,\n activeOrganizationId,\n Array.isArray(allowed) && allowed.length > 0 ? allowed[0] : null,\n ]\n for (const candidate of candidates) {\n if (!candidate) continue\n if (!Array.isArray(allowed) || allowed.includes(candidate)) return candidate\n }\n return null\n}\n\nfunction readAuthScopeId(auth: NonNullable<AuthContext>, key: 'actorTenantId' | 'actorOrgId'): string | null {\n const value = auth[key]\n if (typeof value === 'string' && value.trim().length > 0) return value.trim()\n return null\n}\n\nfunction normalizeActorUuid(value: unknown): string | null {\n if (typeof value !== 'string') return null\n const normalized = value.trim()\n return actorUuidSchema.safeParse(normalized).success ? normalized : null\n}\n\nfunction isApiKeyAuth(auth: NonNullable<AuthContext>): boolean {\n return auth.isApiKey === true || auth.sub.trim().startsWith('api_key:')\n}\n\nexport function hasDocumentsFeature(auth: DocumentsAuthContext, feature: string): boolean {\n if (auth.isSuperAdmin === true) return true\n return hasAllFeatures([feature], auth.features)\n}\n\nexport function hasAnyDocumentsFeature(auth: DocumentsAuthContext, features: string[]): boolean {\n if (auth.isSuperAdmin === true) return true\n return features.some((feature) => hasAllFeatures([feature], auth.features))\n}\n\nexport function deriveCapabilitiesForContext(\n ctx: DocumentsRouteContext,\n relationshipTier: DocumentTier | null,\n options: { archived?: boolean } = {},\n): DocumentCapabilities {\n return deriveDocumentCapabilities({\n relationshipTier,\n managerOverride: hasDocumentsFeature(ctx.auth, 'documents.manage'),\n archived: options.archived === true,\n userFeatures: ctx.auth.features,\n })\n}\n\nexport async function resolveDocumentCapabilityProjection(\n ctx: DocumentsRouteContext,\n documentId: string,\n options: { archived?: boolean } = {},\n): Promise<DocumentCapabilityProjection> {\n const relationshipTier = await resolvePermission(ctx.em, documentId, ctx.auth)\n return {\n relationshipTier,\n capabilities: deriveCapabilitiesForContext(ctx, relationshipTier, options),\n }\n}\n\nexport async function loadDocumentArchivedState(\n ctx: DocumentsRouteContext,\n documentId: string,\n): Promise<{ archivedAt: Date | null }> {\n const document = await findOneWithDecryption(\n ctx.em,\n Document,\n {\n id: documentId,\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId,\n deletedAt: null,\n },\n { fields: ['id', 'archivedAt'] },\n { tenantId: ctx.tenantId, organizationId: ctx.organizationId },\n )\n if (!document) throw new CrudHttpError(404, { error: 'documents.documents.notFound' })\n return { archivedAt: document.archivedAt ?? null }\n}\n\nexport async function assertDocumentNotArchived(\n ctx: DocumentsRouteContext,\n documentId: string,\n): Promise<void> {\n const state = await loadDocumentArchivedState(ctx, documentId)\n if (state.archivedAt !== null) {\n throw new CrudHttpError(403, { error: 'documents.errors.documentArchived' })\n }\n}\n\nexport async function resolveDocumentsContext(\n request: Request,\n requiredFeatures: string[],\n): Promise<DocumentsRouteContext> {\n const container = await createRequestContainer()\n const em = container.resolve('em') as EntityManager\n const auth = await getAuthFromRequest(request)\n if (!auth || !auth.tenantId) {\n throw new CrudHttpError(401, { error: 'api.errors.unauthorized' })\n }\n\n const authenticatedActorUserId = resolveActorUserId(auth)\n const actorTenantId = readAuthScopeId(auth, 'actorTenantId') ?? auth.tenantId\n const actorOrganizationId = readAuthScopeId(auth, 'actorOrgId') ?? auth.orgId\n const rbacService = container.resolve('rbacService') as RbacServiceLike\n const actorAcl = await rbacService.loadAcl(auth.sub, {\n tenantId: actorTenantId,\n organizationId: actorOrganizationId,\n })\n // Organization scope resolution historically accepts the authenticated\n // superadmin bit to support tenant/org switching. Replace that potentially\n // stale token bit with the live RBAC decision before asking the shared scope\n // resolver to expand parent grants into descendant organizations.\n const scopeAuth = {\n ...auth,\n // API-key authentication validates both keyId and any backing user. Keep\n // the prefixed subject for ACL while projecting its UUID domain actor for\n // ownership/share/audit helpers. An unbound key uses its own key UUID.\n userId: authenticatedActorUserId,\n isSuperAdmin: actorAcl.isSuperAdmin === true,\n }\n const organizationScopeService = resolveOrganizationScopeService(container)\n if (!organizationScopeService) {\n throw new CrudHttpError(403, { error: 'api.errors.forbidden' })\n }\n const scope = await organizationScopeService.resolveForRequest({ auth: scopeAuth, request })\n // The caller explicitly selected an organization that no longer resolves to a\n // real, accessible org (stale selected-org cookie after a delete or an access\n // loss). The scope resolver falls back to another allowed org, so continuing\n // would silently read and write against an organization the caller never\n // chose. Fail loud on every documents operation instead \u2014 the same contract\n // `makeCrudRoute` enforces via `rejectInvalidOrgSelection` (#3936).\n if (scope?.selectionRejected) {\n throw new CrudHttpError(422, {\n error: 'documents.errors.organizationSelectionInvalid',\n code: ORGANIZATION_SELECTION_INVALID_ERROR_CODE,\n })\n }\n const tenantId = scope?.tenantId ?? auth.tenantId\n const organizationId = resolveSelectedOrganization(scopeAuth, scope)\n if (!tenantId) {\n throw new CrudHttpError(400, { error: 'documents.errors.organizationRequired' })\n }\n if (!organizationId) {\n // An unrestricted caller with no resolvable organization (a super-admin\n // viewing a foreign tenant with \"all organizations\" selected) is a 400, not\n // a 401 (which `apiFetch` would turn into a refresh loop) and not a 403 (the\n // caller is allowed in; they only need to pick an organization). A caller\n // whose grants expand to no organization at all stays a 403.\n const unrestricted = (scope?.filterIds ?? scope?.allowedIds ?? null) === null\n if (unrestricted) {\n throw new CrudHttpError(400, {\n error: 'documents.errors.organizationRequired',\n code: ORGANIZATION_SCOPE_REQUIRED_ERROR_CODE,\n })\n }\n throw new CrudHttpError(403, { error: 'api.errors.forbidden' })\n }\n\n const acl = await rbacService.loadAcl(auth.sub, { tenantId, organizationId })\n if (!hasResolvedDocumentsOrganizationAccess(acl, organizationId, scope)) {\n throw new CrudHttpError(403, { error: 'api.errors.forbidden' })\n }\n const roleIds = await resolveActiveSubjectRoleIds(\n container,\n { tenantId, organizationId },\n auth.sub,\n )\n const documentsAuth: DocumentsAuthContext = {\n ...scopeAuth,\n tenantId,\n orgId: organizationId,\n organizationId,\n roleIds,\n resolvedRoleIds: roleIds,\n // JWT/trusted-request claims are only authentication hints. The current\n // RBAC projection is authoritative for features and superadmin status so\n // a revoked grant cannot survive in a long-lived token.\n features: acl.isSuperAdmin === true ? ['*'] : normalizeStrings(acl.features),\n isSuperAdmin: acl.isSuperAdmin === true,\n }\n\n if (!hasAnyDocumentsFeature(documentsAuth, requiredFeatures)) {\n throw new CrudHttpError(403, { error: 'api.errors.forbidden' })\n }\n\n return {\n container,\n em,\n auth: documentsAuth,\n tenantId,\n organizationId,\n request,\n }\n}\n\nexport function resolveActorUserId(auth: NonNullable<AuthContext>): string {\n const subject = auth.sub.trim()\n if (isApiKeyAuth(auth)) {\n // `keyId` is populated only by successful API-key authentication. Do not\n // recover an actor by parsing an arbitrary prefixed subject when that\n // validated field is absent, malformed, or disagrees with the subject.\n const keyId = normalizeActorUuid(auth.keyId)\n if (!keyId || subject !== `api_key:${keyId}`) {\n throw new CrudHttpError(403, { error: 'api.errors.forbidden' })\n }\n if (auth.userId === undefined || auth.userId === null) return keyId\n const backingUserId = normalizeActorUuid(auth.userId)\n if (backingUserId) return backingUserId\n throw new CrudHttpError(403, { error: 'api.errors.forbidden' })\n }\n\n const actorUserId = normalizeActorUuid(subject)\n const claimedUserId = auth.userId === undefined || auth.userId === null\n ? actorUserId\n : normalizeActorUuid(auth.userId)\n if (actorUserId && claimedUserId === actorUserId) return actorUserId\n throw new CrudHttpError(403, { error: 'api.errors.forbidden' })\n}\n\nexport async function readBody(\n request: Request,\n maxBytes = DOCUMENTS_JSON_BODY_LIMITS.standard,\n): Promise<Record<string, unknown>> {\n return (await readBoundedJsonBody<Record<string, unknown>>(request, maxBytes, {})) ?? {}\n}\n\nasync function localizeRouteErrorBody(body: Record<string, unknown>): Promise<Record<string, unknown>> {\n const rawError = typeof body.error === 'string' ? body.error : null\n if (!rawError) return body\n\n if (containsCanonicalUuid(rawError)) {\n const { key, fallback } = ROUTE_ERROR_TRANSLATIONS['Internal server error']!\n try {\n const { translate } = await resolveTranslations()\n return { ...body, error: translate(key, fallback) }\n } catch {\n return { ...body, error: fallback }\n }\n }\n\n const literal = ROUTE_ERROR_TRANSLATIONS[rawError]\n const key = literal?.key ?? rawError\n const fallback = literal?.fallback ?? ROUTE_ERROR_KEY_FALLBACKS[key]\n // Attachment failures reach these routes as the attachments module's own\n // catalogued keys. The locale dictionary is merged across modules, so they\n // resolve here; without this prefix the raw key would reach the client.\n if (\n !key.startsWith('documents.')\n && !key.startsWith('api.')\n && !key.startsWith('attachments.')\n ) return body\n\n try {\n const { translate } = await resolveTranslations()\n return { ...body, error: translate(key, fallback) }\n } catch {\n return { ...body, error: fallback ?? key }\n }\n}\n\nexport async function handleDocumentsRouteError(error: unknown, label: string): Promise<Response> {\n if (isCrudHttpError(error)) {\n const body = error.body && typeof error.body === 'object' && !Array.isArray(error.body)\n ? error.body as Record<string, unknown>\n : { error: 'api.errors.internal' }\n return NextResponse.json(await localizeRouteErrorBody(body), { status: error.status })\n }\n if (error instanceof z.ZodError) {\n return NextResponse.json(\n await localizeRouteErrorBody({ error: 'api.errors.invalidPayload', details: error.issues }),\n { status: 400 },\n )\n }\n logger.error(`${label} failed`, { err: error })\n return NextResponse.json(\n await localizeRouteErrorBody({ error: 'api.errors.internal' }),\n { status: 500 },\n )\n}\n\nexport async function loadScopedDocument(ctx: DocumentsRouteContext, id: string): Promise<Document> {\n const document = await findOneWithDecryption(ctx.em, Document, {\n id,\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId,\n deletedAt: null,\n }, undefined, { tenantId: ctx.tenantId, organizationId: ctx.organizationId })\n if (!document) throw new CrudHttpError(404, { error: 'documents.documents.notFound' })\n return document\n}\n\nexport async function loadScopedShare(\n ctx: DocumentsRouteContext,\n documentId: string,\n shareId: string,\n): Promise<DocumentShare> {\n const share = await findOneWithDecryption(ctx.em, DocumentShare, {\n id: shareId,\n documentId,\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId,\n deletedAt: null,\n }, undefined, { tenantId: ctx.tenantId, organizationId: ctx.organizationId })\n if (!share) throw new CrudHttpError(404, { error: 'documents.share.notFound' })\n return share\n}\n\nexport function serializeDocument(document: Document): Record<string, unknown> {\n return {\n id: document.id,\n title: document.title,\n folderId: document.folderId ?? null,\n ownerUserId: document.ownerUserId,\n createdByUserId: document.createdByUserId,\n isActive: document.isActive,\n createdAt: document.createdAt.toISOString(),\n updatedAt: document.updatedAt.toISOString(),\n }\n}\n\nexport function serializeContent(content: DocumentContent | null): Record<string, unknown> {\n return {\n contentHtml: content?.contentHtml ?? '',\n contentText: content?.contentText ?? '',\n updatedAt: content?.updatedAt ? content.updatedAt.toISOString() : null,\n }\n}\n\nexport function serializeFolder(folder: DocumentFolder): Record<string, unknown> {\n return {\n id: folder.id,\n name: folder.name,\n parentFolderId: folder.parentFolderId ?? null,\n ownerUserId: folder.ownerUserId,\n createdAt: folder.createdAt.toISOString(),\n updatedAt: folder.updatedAt.toISOString(),\n }\n}\n\nexport function serializeShare(share: DocumentShare): Record<string, unknown> {\n return {\n id: share.id,\n documentId: share.documentId,\n principalType: share.principalType,\n principalId: share.principalId,\n permission: share.permission,\n createdByUserId: share.createdByUserId,\n createdAt: share.createdAt.toISOString(),\n updatedAt: share.updatedAt.toISOString(),\n }\n}\n\nexport async function validateMutationGuard(\n ctx: DocumentsRouteContext,\n input: {\n resourceKind: string\n resourceId: string\n operation: 'create' | 'update' | 'delete' | 'custom'\n mutationPayload?: Record<string, unknown> | null\n /**\n * Re-parses a guard's `modifiedPayload` before it reaches the command. A\n * registry guard may rewrite the payload, and the route's own schema is the\n * only thing that still guarantees the command receives a shape it can trust.\n */\n mutationPayloadSchema?: { parse: (value: unknown) => Record<string, unknown> }\n },\n): Promise<MutationGuardResult> {\n // `runRouteMutationGuards` runs EVERY registered guard plus the bridged legacy\n // DI service. The deprecated `validateCrudMutationGuard` /\n // `runCrudMutationGuardAfterSuccess` pair used here before resolved only the\n // single DI-registered guard service, so every guard a module contributed\n // through the registry \u2014 along with its payload transformation and its\n // after-success callback \u2014 was silently skipped on Documents writes.\n const guardResult = await runRouteMutationGuards({\n container: ctx.container,\n req: ctx.request,\n auth: {\n tenantId: ctx.tenantId,\n organizationId: ctx.organizationId,\n userId: resolveActorUserId(ctx.auth),\n userFeatures: ctx.auth.features,\n },\n input: {\n resourceKind: input.resourceKind,\n resourceId: input.resourceId,\n operation: input.operation,\n mutationPayload: input.mutationPayload ?? null,\n },\n })\n if (!guardResult.ok) {\n throw new CrudHttpError(guardResult.errorStatus, guardResult.errorBody)\n }\n if (guardResult.modifiedPayload && input.mutationPayload) {\n const transformed = input.mutationPayloadSchema\n ? input.mutationPayloadSchema.parse(guardResult.modifiedPayload)\n : guardResult.modifiedPayload\n // Routes read the object they handed in, so the transformation has to land\n // there rather than only on the guard result.\n for (const key of Object.keys(input.mutationPayload)) delete input.mutationPayload[key]\n Object.assign(input.mutationPayload, transformed)\n }\n return guardResult\n}\n\nexport async function runMutationGuardAfterSuccess(\n _ctx: DocumentsRouteContext,\n guardResult: MutationGuardResult,\n _input: {\n resourceKind: string\n resourceId: string\n operation: 'create' | 'update' | 'delete' | 'custom'\n },\n): Promise<void> {\n await guardResult.runAfterSuccess()\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["errors", "key", "fallback"]
|
|
7
|
+
}
|