@jini-ai/admin 0.4.2 → 0.4.4
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/CHANGELOG.md +15 -0
- package/README.md +7 -0
- package/dist/agent-plugins/react/components/AgentPluginListPanel.d.ts +1 -1
- package/dist/agent-plugins/react/hooks/AgentPluginInspector.hooks.js +1 -1
- package/dist/agent-plugins/react/hooks/AgentPluginPanel.hooks.d.ts +1 -1
- package/dist/agent-plugins/react/hooks/AgentPluginsPage.hooks.d.ts +1 -1
- package/dist/agent-plugins/react/hooks/AgentPluginsPage.hooks.js +1 -1
- package/dist/agent-plugins/react/hooks/MarketplaceTab.hooks.d.ts +1 -1
- package/dist/agent-plugins/react/index.js +1 -1
- package/dist/agent-plugins/react/pages/AgentPluginsPage.d.ts +1 -1
- package/dist/agent-plugins/react/tabs/DownloadedTab.d.ts +1 -1
- package/dist/agent-plugins/react/tabs/InstalledTab.d.ts +1 -1
- package/dist/agent-plugins/react/tabs/MarketplaceTab.d.ts +1 -1
- package/dist/comments/adapters/http.d.ts +29 -0
- package/dist/comments/adapters/http.js +50 -0
- package/dist/comments/adapters/memory.d.ts +17 -0
- package/dist/comments/adapters/memory.js +61 -0
- package/dist/comments/comments.module.d.ts +73 -0
- package/dist/comments/comments.module.js +16 -0
- package/dist/comments/conformance/comments-api.conformance.d.ts +9 -0
- package/dist/comments/conformance/comments-api.conformance.js +63 -0
- package/dist/comments/controllers/comment-queue.controller.d.ts +48 -0
- package/dist/comments/controllers/comment-queue.controller.js +164 -0
- package/dist/comments/controllers/comment-settings.controller.d.ts +32 -0
- package/dist/comments/controllers/comment-settings.controller.js +77 -0
- package/dist/comments/controllers/comments.controller.d.ts +16 -0
- package/dist/comments/controllers/comments.controller.js +16 -0
- package/dist/comments/index.d.ts +13 -0
- package/dist/comments/index.js +8 -0
- package/dist/comments/messages.en.d.ts +54 -0
- package/dist/comments/messages.en.js +56 -0
- package/dist/comments/models.d.ts +22 -0
- package/dist/comments/models.js +2 -0
- package/dist/comments/ports.d.ts +14 -0
- package/dist/comments/ports.js +5 -0
- package/dist/comments/react/components/QueueSection.d.ts +30 -0
- package/dist/comments/react/components/QueueSection.js +57 -0
- package/dist/comments/react/components/SettingsSection.d.ts +14 -0
- package/dist/comments/react/components/SettingsSection.js +23 -0
- package/dist/comments/react/hooks/CommentsPage.hooks.d.ts +9 -0
- package/dist/comments/react/hooks/CommentsPage.hooks.js +10 -0
- package/dist/comments/react/hooks/CommentsPorts.hooks.d.ts +13 -0
- package/dist/comments/react/hooks/CommentsPorts.hooks.js +15 -0
- package/dist/comments/react/hooks/QueueSection.hooks.d.ts +62 -0
- package/dist/comments/react/hooks/QueueSection.hooks.js +57 -0
- package/dist/comments/react/hooks/SettingsSection.hooks.d.ts +12 -0
- package/dist/comments/react/hooks/SettingsSection.hooks.js +21 -0
- package/dist/comments/react/hooks/use-comment-queue.hooks.d.ts +34 -0
- package/dist/comments/react/hooks/use-comment-queue.hooks.js +47 -0
- package/dist/comments/react/hooks/use-comment-settings.hooks.d.ts +22 -0
- package/dist/comments/react/hooks/use-comment-settings.hooks.js +30 -0
- package/dist/comments/react/hooks/use-comments.hooks.d.ts +15 -0
- package/dist/comments/react/hooks/use-comments.hooks.js +20 -0
- package/dist/comments/react/index.d.ts +316 -0
- package/dist/comments/react/index.js +35 -0
- package/dist/comments/react/pages/CommentsPage.d.ts +12 -0
- package/dist/comments/react/pages/CommentsPage.js +15 -0
- package/dist/comments/rules.d.ts +140 -0
- package/dist/comments/rules.js +199 -0
- package/dist/core/index.d.ts +3 -1
- package/dist/core/index.js +1 -0
- package/dist/core/ledger-slice.d.ts +90 -0
- package/dist/core/ledger-slice.js +81 -0
- package/dist/core/ports/comments.d.ts +2 -0
- package/dist/core/ports/forms.d.ts +19 -7
- package/dist/core/ports/forms.js +4 -4
- package/dist/core/ports/index.d.ts +1 -1
- package/dist/core/ports/seo.d.ts +33 -6
- package/dist/core/react/bind-react.d.ts +46 -0
- package/dist/core/react/bind-react.js +28 -0
- package/dist/core/react/index.d.ts +3 -0
- package/dist/core/react/index.js +3 -0
- package/dist/core/react/use-controller.d.ts +16 -0
- package/dist/core/react/use-controller.js +18 -0
- package/dist/forms/adapters/http.d.ts +26 -0
- package/dist/forms/adapters/http.js +43 -0
- package/dist/forms/adapters/memory.d.ts +14 -0
- package/dist/forms/adapters/memory.js +77 -0
- package/dist/forms/conformance/forms-api.conformance.d.ts +17 -0
- package/dist/forms/conformance/forms-api.conformance.js +71 -0
- package/dist/forms/controllers/draft-store.d.ts +18 -0
- package/dist/forms/controllers/draft-store.js +17 -0
- package/dist/forms/controllers/field-attributes-dialog.controller.d.ts +37 -0
- package/dist/forms/controllers/field-attributes-dialog.controller.js +27 -0
- package/dist/forms/controllers/form-editor.controller.d.ts +36 -0
- package/dist/forms/controllers/form-editor.controller.js +22 -0
- package/dist/forms/controllers/form-fields-editor.controller.d.ts +20 -0
- package/dist/forms/controllers/form-fields-editor.controller.js +10 -0
- package/dist/forms/controllers/form-submission-detail.controller.d.ts +20 -0
- package/dist/forms/controllers/form-submission-detail.controller.js +10 -0
- package/dist/forms/controllers/form-submissions.controller.d.ts +25 -0
- package/dist/forms/controllers/form-submissions.controller.js +10 -0
- package/dist/forms/controllers/forms-list.controller.d.ts +22 -0
- package/dist/forms/controllers/forms-list.controller.js +10 -0
- package/dist/forms/forms.module.d.ts +138 -0
- package/dist/forms/forms.module.js +17 -0
- package/dist/forms/html-rules.d.ts +34 -0
- package/dist/forms/html-rules.js +34 -0
- package/dist/forms/index.d.ts +14 -0
- package/dist/forms/index.js +12 -0
- package/dist/forms/messages.en.d.ts +101 -0
- package/dist/forms/messages.en.js +105 -0
- package/dist/forms/models.d.ts +29 -0
- package/dist/forms/models.js +8 -0
- package/dist/forms/ports.d.ts +26 -0
- package/dist/forms/ports.js +6 -0
- package/dist/forms/react/components/FieldAttributesDialog.d.ts +14 -0
- package/dist/forms/react/components/FieldAttributesDialog.js +47 -0
- package/dist/forms/react/components/FormEditorFieldsBody.d.ts +28 -0
- package/dist/forms/react/components/FormEditorFieldsBody.js +24 -0
- package/dist/forms/react/components/FormEditorHeaderText.d.ts +7 -0
- package/dist/forms/react/components/FormEditorHeaderText.js +8 -0
- package/dist/forms/react/components/FormEditorMainPanel.d.ts +12 -0
- package/dist/forms/react/components/FormEditorMainPanel.js +13 -0
- package/dist/forms/react/components/FormEditorTabStrip.d.ts +13 -0
- package/dist/forms/react/components/FormEditorTabStrip.js +14 -0
- package/dist/forms/react/components/FormFieldsEditor.d.ts +13 -0
- package/dist/forms/react/components/FormFieldsEditor.js +39 -0
- package/dist/forms/react/components/FormSubmissionDate.d.ts +8 -0
- package/dist/forms/react/components/FormSubmissionDate.js +5 -0
- package/dist/forms/react/components/FormSubmissionDetail.d.ts +15 -0
- package/dist/forms/react/components/FormSubmissionDetail.js +30 -0
- package/dist/forms/react/components/FormSubmissions.d.ts +12 -0
- package/dist/forms/react/components/FormSubmissions.js +46 -0
- package/dist/forms/react/hooks/FormsPorts.hooks.d.ts +41 -0
- package/dist/forms/react/hooks/FormsPorts.hooks.js +16 -0
- package/dist/forms/react/hooks/forms-view.hooks.d.ts +117 -0
- package/dist/forms/react/hooks/forms-view.hooks.js +78 -0
- package/dist/forms/react/hooks/use-field-attributes-dialog.hooks.d.ts +31 -0
- package/dist/forms/react/hooks/use-field-attributes-dialog.hooks.js +22 -0
- package/dist/forms/react/hooks/use-form-editor.hooks.d.ts +118 -0
- package/dist/forms/react/hooks/use-form-editor.hooks.js +208 -0
- package/dist/forms/react/hooks/use-form-fields-editor.hooks.d.ts +34 -0
- package/dist/forms/react/hooks/use-form-fields-editor.hooks.js +36 -0
- package/dist/forms/react/hooks/use-form-submission-date.hooks.d.ts +12 -0
- package/dist/forms/react/hooks/use-form-submission-date.hooks.js +9 -0
- package/dist/forms/react/hooks/use-form-submission-detail.hooks.d.ts +68 -0
- package/dist/forms/react/hooks/use-form-submission-detail.hooks.js +81 -0
- package/dist/forms/react/hooks/use-form-submissions.hooks.d.ts +67 -0
- package/dist/forms/react/hooks/use-form-submissions.hooks.js +110 -0
- package/dist/forms/react/hooks/use-forms-list.hooks.d.ts +78 -0
- package/dist/forms/react/hooks/use-forms-list.hooks.js +103 -0
- package/dist/forms/react/index.d.ts +452 -0
- package/dist/forms/react/index.js +35 -0
- package/dist/forms/react/pages/FormEditor.d.ts +19 -0
- package/dist/forms/react/pages/FormEditor.js +40 -0
- package/dist/forms/react/pages/FormsList.d.ts +39 -0
- package/dist/forms/react/pages/FormsList.js +50 -0
- package/dist/forms/rules.d.ts +291 -0
- package/dist/forms/rules.js +338 -0
- package/dist/media/react/hooks/EditMediaPanel.hooks.js +1 -1
- package/dist/media/react/hooks/LibraryTab.hooks.d.ts +1 -1
- package/dist/media/react/hooks/LibraryTab.hooks.js +1 -1
- package/dist/media/react/hooks/MediaCard.hooks.js +6 -20
- package/dist/media/react/hooks/MediaGrid.hooks.d.ts +2 -2
- package/dist/media/react/hooks/MediaPage.hooks.d.ts +1 -1
- package/dist/media/react/hooks/MediaPage.hooks.js +1 -1
- package/dist/media/react/hooks/MediaPicker.hooks.js +1 -1
- package/dist/media/react/index.js +1 -1
- package/dist/media/react/tabs/LibraryTab.d.ts +1 -1
- package/dist/media/react/tabs/ProvidersTab.d.ts +1 -1
- package/dist/playground/react/components/Canvas.d.ts +1 -1
- package/dist/playground/react/hooks/Canvas.hooks.d.ts +1 -1
- package/dist/playground/react/hooks/Canvas.hooks.js +1 -1
- package/dist/playground/react/hooks/PlaygroundPage.hooks.d.ts +1 -1
- package/dist/playground/react/index.js +1 -1
- package/dist/playground/react/pages/PlaygroundPage.d.ts +1 -1
- package/dist/playground/react/tabs/CanvasTab.d.ts +1 -1
- package/dist/react/bind-react.d.ts +1 -45
- package/dist/react/bind-react.js +2 -27
- package/dist/react/components/ConfirmDialog/ConfirmDialog.d.ts +22 -5
- package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.d.ts +2 -2
- package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.js +17 -55
- package/dist/react/components/ConfirmDialog/ConfirmDialog.js +33 -70
- package/dist/react/components/RowMenu/RowMenu.hooks.js +14 -3
- package/dist/react/use-controller.d.ts +1 -15
- package/dist/react/use-controller.js +2 -17
- package/dist/redirects/adapters/http.d.ts +20 -0
- package/dist/redirects/adapters/http.js +31 -0
- package/dist/redirects/adapters/memory.d.ts +13 -0
- package/dist/redirects/adapters/memory.js +83 -0
- package/dist/redirects/conformance/redirects-api.conformance.d.ts +12 -0
- package/dist/redirects/conformance/redirects-api.conformance.js +66 -0
- package/dist/redirects/controllers/hit-count.controller.d.ts +14 -0
- package/dist/redirects/controllers/hit-count.controller.js +10 -0
- package/dist/redirects/controllers/import-redirects.controller.d.ts +28 -0
- package/dist/redirects/controllers/import-redirects.controller.js +29 -0
- package/dist/redirects/controllers/redirects.controller.d.ts +37 -0
- package/dist/redirects/controllers/redirects.controller.js +38 -0
- package/dist/redirects/index.d.ts +11 -0
- package/dist/redirects/index.js +10 -0
- package/dist/redirects/messages.en.d.ts +58 -0
- package/dist/redirects/messages.en.js +60 -0
- package/dist/redirects/models.d.ts +14 -0
- package/dist/redirects/models.js +2 -0
- package/dist/redirects/ports.d.ts +9 -0
- package/dist/redirects/ports.js +4 -0
- package/dist/redirects/react/components/HitCountCell.d.ts +19 -0
- package/dist/redirects/react/components/HitCountCell.js +19 -0
- package/dist/redirects/react/components/ImportRedirectsForm.d.ts +17 -0
- package/dist/redirects/react/components/ImportRedirectsForm.js +12 -0
- package/dist/redirects/react/hooks/RedirectsOptions.hooks.d.ts +27 -0
- package/dist/redirects/react/hooks/RedirectsOptions.hooks.js +15 -0
- package/dist/redirects/react/hooks/RedirectsPage.hooks.d.ts +50 -0
- package/dist/redirects/react/hooks/RedirectsPage.hooks.js +30 -0
- package/dist/redirects/react/hooks/RedirectsPorts.hooks.d.ts +10 -0
- package/dist/redirects/react/hooks/RedirectsPorts.hooks.js +11 -0
- package/dist/redirects/react/hooks/use-hit-count-cell.hooks.d.ts +19 -0
- package/dist/redirects/react/hooks/use-hit-count-cell.hooks.js +15 -0
- package/dist/redirects/react/hooks/use-import-redirects-form.hooks.d.ts +21 -0
- package/dist/redirects/react/hooks/use-import-redirects-form.hooks.js +25 -0
- package/dist/redirects/react/hooks/use-redirects.hooks.d.ts +34 -0
- package/dist/redirects/react/hooks/use-redirects.hooks.js +63 -0
- package/dist/redirects/react/hooks/wired.hooks.d.ts +55 -0
- package/dist/redirects/react/hooks/wired.hooks.js +31 -0
- package/dist/redirects/react/index.d.ts +324 -0
- package/dist/redirects/react/index.js +28 -0
- package/dist/redirects/react/pages/RedirectsPage.d.ts +15 -0
- package/dist/redirects/react/pages/RedirectsPage.js +20 -0
- package/dist/redirects/redirects.module.d.ts +77 -0
- package/dist/redirects/redirects.module.js +13 -0
- package/dist/redirects/rules.d.ts +131 -0
- package/dist/redirects/rules.js +134 -0
- package/dist/security/react/hooks/AccessTokensTab.hooks.d.ts +1 -1
- package/dist/security/react/hooks/AccessTokensTab.hooks.js +1 -1
- package/dist/security/react/hooks/RootKeyTab.hooks.d.ts +1 -1
- package/dist/security/react/hooks/RootKeyTab.hooks.js +1 -1
- package/dist/security/react/hooks/SecurityPage.hooks.d.ts +1 -1
- package/dist/security/react/index.js +1 -1
- package/dist/security/react/pages/SecurityPage.d.ts +1 -1
- package/dist/security/react/tabs/AccessTokensTab.d.ts +1 -1
- package/dist/security/react/tabs/RootKeyTab.d.ts +1 -1
- package/dist/seo/adapters/http.d.ts +31 -0
- package/dist/seo/adapters/http.js +37 -0
- package/dist/seo/adapters/memory.d.ts +28 -0
- package/dist/seo/adapters/memory.js +129 -0
- package/dist/seo/conformance/seo-api.conformance.d.ts +8 -0
- package/dist/seo/conformance/seo-api.conformance.js +44 -0
- package/dist/seo/controllers/entry-picker.controller.d.ts +21 -0
- package/dist/seo/controllers/entry-picker.controller.js +17 -0
- package/dist/seo/controllers/entry-section.controller.d.ts +20 -0
- package/dist/seo/controllers/entry-section.controller.js +7 -0
- package/dist/seo/controllers/media-ref.controller.d.ts +26 -0
- package/dist/seo/controllers/media-ref.controller.js +14 -0
- package/dist/seo/controllers/seo-entry.controller.d.ts +31 -0
- package/dist/seo/controllers/seo-entry.controller.js +52 -0
- package/dist/seo/controllers/seo.controller.d.ts +29 -0
- package/dist/seo/controllers/seo.controller.js +50 -0
- package/dist/seo/controllers/sitemap.controller.d.ts +25 -0
- package/dist/seo/controllers/sitemap.controller.js +27 -0
- package/dist/seo/index.d.ts +14 -0
- package/dist/seo/index.js +12 -0
- package/dist/seo/messages.en.d.ts +79 -0
- package/dist/seo/messages.en.js +79 -0
- package/dist/seo/models.d.ts +179 -0
- package/dist/seo/models.js +8 -0
- package/dist/seo/ports.d.ts +11 -0
- package/dist/seo/ports.js +4 -0
- package/dist/seo/react/components/MediaPickerBridge.d.ts +4 -0
- package/dist/seo/react/components/MediaPickerBridge.js +8 -0
- package/dist/seo/react/components/MediaRefField.d.ts +40 -0
- package/dist/seo/react/components/MediaRefField.js +12 -0
- package/dist/seo/react/components/SeoIcons.d.ts +13 -0
- package/dist/seo/react/components/SeoIcons.js +32 -0
- package/dist/seo/react/components/SitemapModal.d.ts +48 -0
- package/dist/seo/react/components/SitemapModal.js +72 -0
- package/dist/seo/react/hooks/MediaPickerBridge.hooks.d.ts +6 -0
- package/dist/seo/react/hooks/MediaPickerBridge.hooks.js +27 -0
- package/dist/seo/react/hooks/MediaRefField.hooks.d.ts +25 -0
- package/dist/seo/react/hooks/MediaRefField.hooks.js +30 -0
- package/dist/seo/react/hooks/SeoModuleTabs.d.ts +14 -0
- package/dist/seo/react/hooks/SeoModuleTabs.js +18 -0
- package/dist/seo/react/hooks/SeoPage.hooks.d.ts +69 -0
- package/dist/seo/react/hooks/SeoPage.hooks.js +37 -0
- package/dist/seo/react/hooks/SeoPorts.hooks.d.ts +19 -0
- package/dist/seo/react/hooks/SeoPorts.hooks.js +22 -0
- package/dist/seo/react/hooks/SitemapModal.hooks.d.ts +26 -0
- package/dist/seo/react/hooks/SitemapModal.hooks.js +20 -0
- package/dist/seo/react/hooks/use-entry-picker.hooks.d.ts +11 -0
- package/dist/seo/react/hooks/use-entry-picker.hooks.js +20 -0
- package/dist/seo/react/hooks/use-seo-entry-panel.hooks.d.ts +14 -0
- package/dist/seo/react/hooks/use-seo-entry-panel.hooks.js +26 -0
- package/dist/seo/react/hooks/use-seo-entry-section.hooks.d.ts +4 -0
- package/dist/seo/react/hooks/use-seo-entry-section.hooks.js +7 -0
- package/dist/seo/react/hooks/use-seo.hooks.d.ts +11 -0
- package/dist/seo/react/hooks/use-seo.hooks.js +29 -0
- package/dist/seo/react/hooks/use-sitemap-modal.hooks.d.ts +10 -0
- package/dist/seo/react/hooks/use-sitemap-modal.hooks.js +18 -0
- package/dist/seo/react/index.d.ts +369 -0
- package/dist/seo/react/index.js +30 -0
- package/dist/seo/react/options.d.ts +26 -0
- package/dist/seo/react/options.js +2 -0
- package/dist/seo/react/pages/SeoPage.d.ts +161 -0
- package/dist/seo/react/pages/SeoPage.js +215 -0
- package/dist/seo/rules.d.ts +142 -0
- package/dist/seo/rules.js +220 -0
- package/dist/seo/seo.module.d.ts +115 -0
- package/dist/seo/seo.module.js +14 -0
- package/dist/source-control/react/hooks/ProvidersTab.hooks.d.ts +1 -1
- package/dist/source-control/react/hooks/ProvidersTab.hooks.js +1 -1
- package/dist/source-control/react/hooks/SourceControlPage.hooks.d.ts +1 -1
- package/dist/source-control/react/index.js +1 -1
- package/dist/source-control/react/pages/SourceControlPage.d.ts +1 -1
- package/dist/source-control/react/tabs/ProvidersTab.d.ts +1 -1
- package/dist/widgets/adapters/http.d.ts +19 -0
- package/dist/widgets/adapters/http.js +33 -0
- package/dist/widgets/adapters/memory.d.ts +22 -0
- package/dist/widgets/adapters/memory.js +93 -0
- package/dist/widgets/conformance/widgets-api.conformance.d.ts +6 -0
- package/dist/widgets/conformance/widgets-api.conformance.js +55 -0
- package/dist/widgets/controllers/instance-editor.controller.d.ts +49 -0
- package/dist/widgets/controllers/instance-editor.controller.js +87 -0
- package/dist/widgets/controllers/library.controller.d.ts +33 -0
- package/dist/widgets/controllers/library.controller.js +53 -0
- package/dist/widgets/controllers/region-editor.controller.d.ts +42 -0
- package/dist/widgets/controllers/region-editor.controller.js +69 -0
- package/dist/widgets/controllers/regions.controller.d.ts +27 -0
- package/dist/widgets/controllers/regions.controller.js +44 -0
- package/dist/widgets/index.d.ts +11 -0
- package/dist/widgets/index.js +9 -0
- package/dist/widgets/messages.en.d.ts +78 -0
- package/dist/widgets/messages.en.js +83 -0
- package/dist/widgets/models.d.ts +62 -0
- package/dist/widgets/models.js +2 -0
- package/dist/widgets/ports.d.ts +79 -0
- package/dist/widgets/ports.js +5 -0
- package/dist/widgets/react/components/WidgetInstanceNotices.d.ts +14 -0
- package/dist/widgets/react/components/WidgetInstanceNotices.js +25 -0
- package/dist/widgets/react/components/WidgetRegionEditorHeaderActions.d.ts +22 -0
- package/dist/widgets/react/components/WidgetRegionEditorHeaderActions.js +18 -0
- package/dist/widgets/react/components/WidgetsLibraryNotices.d.ts +13 -0
- package/dist/widgets/react/components/WidgetsLibraryNotices.js +10 -0
- package/dist/widgets/react/hooks/WidgetsPorts.hooks.d.ts +270 -0
- package/dist/widgets/react/hooks/WidgetsPorts.hooks.js +17 -0
- package/dist/widgets/react/hooks/navigation.hooks.d.ts +9 -0
- package/dist/widgets/react/hooks/navigation.hooks.js +6 -0
- package/dist/widgets/react/hooks/page-views.hooks.d.ts +87 -0
- package/dist/widgets/react/hooks/page-views.hooks.js +30 -0
- package/dist/widgets/react/hooks/use-widget-instance-editor.hooks.d.ts +56 -0
- package/dist/widgets/react/hooks/use-widget-instance-editor.hooks.js +38 -0
- package/dist/widgets/react/hooks/use-widget-region-editor.hooks.d.ts +32 -0
- package/dist/widgets/react/hooks/use-widget-region-editor.hooks.js +22 -0
- package/dist/widgets/react/hooks/use-widget-regions.hooks.d.ts +23 -0
- package/dist/widgets/react/hooks/use-widget-regions.hooks.js +22 -0
- package/dist/widgets/react/hooks/use-widgets-library.hooks.d.ts +37 -0
- package/dist/widgets/react/hooks/use-widgets-library.hooks.js +23 -0
- package/dist/widgets/react/index.d.ts +391 -0
- package/dist/widgets/react/index.js +31 -0
- package/dist/widgets/react/pages/WidgetInstanceEditor.d.ts +23 -0
- package/dist/widgets/react/pages/WidgetInstanceEditor.js +37 -0
- package/dist/widgets/react/pages/WidgetRegionEditor.d.ts +22 -0
- package/dist/widgets/react/pages/WidgetRegionEditor.js +25 -0
- package/dist/widgets/react/pages/WidgetRegions.d.ts +21 -0
- package/dist/widgets/react/pages/WidgetRegions.js +31 -0
- package/dist/widgets/react/pages/WidgetsLibrary.d.ts +24 -0
- package/dist/widgets/react/pages/WidgetsLibrary.js +61 -0
- package/dist/widgets/rules.d.ts +94 -0
- package/dist/widgets/rules.js +83 -0
- package/dist/widgets/widgets.module.d.ts +122 -0
- package/dist/widgets/widgets.module.js +21 -0
- package/package.json +206 -9
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/** Existing route identity and permission are part of the host's navigation contract. */
|
|
2
|
+
export declare const redirectsModule: {
|
|
3
|
+
readonly id: "redirects";
|
|
4
|
+
readonly requires: {
|
|
5
|
+
readonly redirectsApi: import("../core/module/token.js").AdminPortToken<import("./ports.js").AdminRedirectsPort, "admin.redirects.api">;
|
|
6
|
+
};
|
|
7
|
+
readonly optional: {
|
|
8
|
+
readonly redirectsEvents: import("../core/module/token.js").AdminPortToken<import("./ports.js").RedirectsEventsPort, "admin.redirects.events">;
|
|
9
|
+
};
|
|
10
|
+
readonly messages: {
|
|
11
|
+
readonly "Loading\u2026": "Loading…";
|
|
12
|
+
readonly "Load hits": "Load hits";
|
|
13
|
+
readonly "Bulk import": "Bulk import";
|
|
14
|
+
readonly "rule objects (1-500 items)": "rule objects (1-500 items)";
|
|
15
|
+
readonly "Importing\u2026": "Importing…";
|
|
16
|
+
readonly Import: "Import";
|
|
17
|
+
readonly Marketing: "Marketing";
|
|
18
|
+
readonly Redirects: "Redirects";
|
|
19
|
+
readonly "Manage URL redirects, including those created automatically when a page's address changes.": "Manage URL redirects, including those created automatically when a page's address changes.";
|
|
20
|
+
readonly "Match type": "Match type";
|
|
21
|
+
readonly "From path": "From path";
|
|
22
|
+
readonly "To target": "To target";
|
|
23
|
+
readonly "Status code": "Status code";
|
|
24
|
+
readonly "301 (permanent)": "301 (permanent)";
|
|
25
|
+
readonly "302 (temporary)": "302 (temporary)";
|
|
26
|
+
readonly "307 (temporary, method-preserving)": "307 (temporary, method-preserving)";
|
|
27
|
+
readonly "308 (permanent, method-preserving)": "308 (permanent, method-preserving)";
|
|
28
|
+
readonly "Add redirect": "Add redirect";
|
|
29
|
+
readonly "No redirect rules yet.": "No redirect rules yet.";
|
|
30
|
+
readonly From: "From";
|
|
31
|
+
readonly To: "To";
|
|
32
|
+
readonly Type: "Type";
|
|
33
|
+
readonly Code: "Code";
|
|
34
|
+
readonly Source: "Source";
|
|
35
|
+
readonly Hits: "Hits";
|
|
36
|
+
readonly "Delete redirect rule?": "Delete redirect rule?";
|
|
37
|
+
readonly "Loading redirects\u2026": "Loading redirects…";
|
|
38
|
+
readonly "Not valid JSON.": "Not valid JSON.";
|
|
39
|
+
readonly "Must be a JSON array of rule objects.": "Must be a JSON array of rule objects.";
|
|
40
|
+
readonly exact: "Exact match";
|
|
41
|
+
readonly prefix: "Starts with";
|
|
42
|
+
readonly wildcard: "Wildcard";
|
|
43
|
+
readonly Status: "Status";
|
|
44
|
+
readonly More: "More";
|
|
45
|
+
readonly Delete: "Delete";
|
|
46
|
+
readonly Disable: "Disable";
|
|
47
|
+
readonly Enable: "Enable";
|
|
48
|
+
readonly "Saving\u2026": "Saving…";
|
|
49
|
+
readonly Created: "Created";
|
|
50
|
+
readonly active: "Active";
|
|
51
|
+
readonly disabled: "Disabled";
|
|
52
|
+
readonly "{created} created, {failed} failed.": "{created} created, {failed} failed.";
|
|
53
|
+
readonly "Item {index} ({code})": "Item {index} ({code})";
|
|
54
|
+
readonly "Actions for redirect rule from \"{fromPattern}\"": "Actions for redirect rule from \"{fromPattern}\"";
|
|
55
|
+
readonly "Paste a JSON array of ": "Paste a JSON array of ";
|
|
56
|
+
readonly " rule objects (1-500 items)": " rule objects (1-500 items)";
|
|
57
|
+
readonly "Delete the redirect rule from \"": "Delete the redirect rule from \"";
|
|
58
|
+
readonly "\"?": "\"?";
|
|
59
|
+
readonly manual: "Manual";
|
|
60
|
+
readonly auto_slug_change: "URL change";
|
|
61
|
+
readonly import: "Imported";
|
|
62
|
+
};
|
|
63
|
+
readonly pages: {
|
|
64
|
+
readonly list: {
|
|
65
|
+
readonly path: "/redirects";
|
|
66
|
+
readonly label: "Redirects";
|
|
67
|
+
readonly permissions: readonly ["admin.redirects.manage"];
|
|
68
|
+
readonly agentReachable: true;
|
|
69
|
+
readonly nav: {
|
|
70
|
+
readonly group: "marketing";
|
|
71
|
+
readonly icon: "arrow-right";
|
|
72
|
+
};
|
|
73
|
+
readonly tabs: {};
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=redirects.module.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineAdminModule } from '../core/module/index.js';
|
|
2
|
+
import { redirectsApiToken, redirectsEventsToken } from './ports.js';
|
|
3
|
+
import { redirectsMessagesEn } from './messages.en.js';
|
|
4
|
+
/** Existing route identity and permission are part of the host's navigation contract. */
|
|
5
|
+
export const redirectsModule = defineAdminModule({
|
|
6
|
+
id: 'redirects',
|
|
7
|
+
requires: { redirectsApi: redirectsApiToken },
|
|
8
|
+
optional: { redirectsEvents: redirectsEventsToken },
|
|
9
|
+
messages: redirectsMessagesEn,
|
|
10
|
+
pages: { list: { path: '/redirects', label: 'Redirects', permissions: ['admin.redirects.manage'],
|
|
11
|
+
agentReachable: true, nav: { group: 'marketing', icon: 'arrow-right' }, tabs: {} } },
|
|
12
|
+
});
|
|
13
|
+
//# sourceMappingURL=redirects.module.js.map
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { AdminRedirect, AdminRedirectCreateInput } from '../core/ports/redirects.js';
|
|
2
|
+
import type { RedirectsRowAction, RedirectsTranslate, RedirectsWriteState } from './models.js';
|
|
3
|
+
/**
|
|
4
|
+
* @file Pure logic for the `redirects` feature — everything that computes a value rather than
|
|
5
|
+
* rendering one. Follows the convention `features/posts/rules.ts` establishes: no React, no
|
|
6
|
+
* hooks, importable and directly testable.
|
|
7
|
+
*
|
|
8
|
+
* `KEYS` lives here rather than inside a hook file because three separate hook files
|
|
9
|
+
* (`use-redirects`, `use-hit-count-cell`, `use-import-redirects-form`) each need one branch of it.
|
|
10
|
+
* A cache-identity constant copied per hook is exactly the drift `@jini-ai/ui/fetch-query`'s own
|
|
11
|
+
* `QueryKey` doc warns about — a hand-typed second `["redirects"]` silently stops matching the
|
|
12
|
+
* first the moment one of them is edited.
|
|
13
|
+
*/
|
|
14
|
+
/** One cache identity per resource, defined once so a write's `invalidates` and a read's `key`
|
|
15
|
+
* cannot drift apart — the failure mode being an invalidation that silently matches nothing and a
|
|
16
|
+
* list that never refreshes. */
|
|
17
|
+
export declare const KEYS: {
|
|
18
|
+
list: readonly ["redirects"];
|
|
19
|
+
hits: ({ redirectId }: {
|
|
20
|
+
redirectId: string;
|
|
21
|
+
}, _optional?: {}) => string[];
|
|
22
|
+
};
|
|
23
|
+
/** This screen's name on the host refresh bus — see `taxonomy/rules.ts`'s `TAXONOMY_RESOURCE`
|
|
24
|
+
* for why this is a plain colocated constant rather than a shared registry. Agent-writable via
|
|
25
|
+
* `redirects_create`/`redirects_update`/`redirects_tombstone` (`apps/website/src/features/redirects/
|
|
26
|
+
* agent-tools.ts`) — `redirects_import` is excluded from that catalog entirely, but the three wired
|
|
27
|
+
* single-row writes are enough to make this list go stale the same way Posts/Media did. */
|
|
28
|
+
export declare const REDIRECTS_RESOURCE = "redirects";
|
|
29
|
+
/**
|
|
30
|
+
* The status a "Disable"/"Enable" row action moves a rule TO — the inverse of its current status.
|
|
31
|
+
*
|
|
32
|
+
* @complexity Time/space: O(1).
|
|
33
|
+
*/
|
|
34
|
+
export declare function nextRedirectStatus({ currentStatus }: {
|
|
35
|
+
currentStatus: string;
|
|
36
|
+
}, _optional?: {}): string;
|
|
37
|
+
/**
|
|
38
|
+
* Shapes the create-redirect form's raw `FormData` into `api.createRedirect`'s input — the create
|
|
39
|
+
* mutation's payload, extracted so the shaping is testable without submitting a real form.
|
|
40
|
+
*
|
|
41
|
+
* @complexity Time/space: O(1) — four fixed field reads.
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildCreateRedirectPayload({ form }: {
|
|
44
|
+
form: FormData;
|
|
45
|
+
}, _optional?: {}): AdminRedirectCreateInput;
|
|
46
|
+
/** The callbacks a redirect row menu needs. Passed in rather than imported so this module stays
|
|
47
|
+
* free of state, mirroring `posts/rules.ts`'s `PostRowMenuHandlers`. */
|
|
48
|
+
export interface RedirectRowMenuHandlers {
|
|
49
|
+
onToggleStatus: (rule: AdminRedirect) => void;
|
|
50
|
+
onRequestDelete: (rule: AdminRedirect) => void;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The row-action menu for one redirect rule.
|
|
54
|
+
*
|
|
55
|
+
* The label is the reason this is exported: it reads the rule's CURRENT status to decide between
|
|
56
|
+
* "Disable" and "Enable", a branch that was otherwise reachable only by rendering the table and
|
|
57
|
+
* opening a popover. "Delete" only OPENS the confirmation; the delete itself is
|
|
58
|
+
* `useRedirects().confirmDelete`, gated on `ConfirmDialog` — same split as `posts/rules.ts`'s
|
|
59
|
+
* `postRowMenuItems`.
|
|
60
|
+
*
|
|
61
|
+
* @complexity Time/space: O(1) — two fixed entries, no iteration.
|
|
62
|
+
*/
|
|
63
|
+
export declare function redirectRowMenuItems({ rule, handlers }: {
|
|
64
|
+
rule: AdminRedirect;
|
|
65
|
+
handlers: RedirectRowMenuHandlers;
|
|
66
|
+
}, { t }?: {
|
|
67
|
+
t?: RedirectsTranslate;
|
|
68
|
+
}): RedirectsRowAction[];
|
|
69
|
+
/** One write's status/error — the two fields these derivations need from `useFetchMutation`'s
|
|
70
|
+
* `MutationResult`, named locally so this module does not have to import the whole type. */
|
|
71
|
+
export type WriteState = RedirectsWriteState;
|
|
72
|
+
/**
|
|
73
|
+
* True while any of the screen's independent writes (create/toggle/delete) is in flight — gates
|
|
74
|
+
* the row-menu guard and the submit button's "Saving…" label.
|
|
75
|
+
*
|
|
76
|
+
* @complexity Time/space: O(w) in the number of writes (currently 3, fixed).
|
|
77
|
+
*/
|
|
78
|
+
export declare function isAnyWritePending({ writes }: {
|
|
79
|
+
writes: readonly WriteState[];
|
|
80
|
+
}, _optional?: {}): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* The first still-active write failure, in WRITE-ARRAY order rather than recency.
|
|
83
|
+
*
|
|
84
|
+
* Order matters: three independent mutations each keep their own error until reset, so returning
|
|
85
|
+
* by recency would let a failed Create's banner persist on screen after a later, entirely
|
|
86
|
+
* successful Disable — blaming an operation that worked. `clearOtherWriteErrors` (in
|
|
87
|
+
* `use-redirects.hooks.ts`) is this rule's other half: it clears every write's error except the
|
|
88
|
+
* one just started, so at most one of these ever holds a stale failure at a time.
|
|
89
|
+
*
|
|
90
|
+
* @complexity Time/space: O(w) in the number of writes.
|
|
91
|
+
*/
|
|
92
|
+
export declare function firstWriteError({ writes }: {
|
|
93
|
+
writes: readonly WriteState[];
|
|
94
|
+
}, _optional?: {}): Error | null;
|
|
95
|
+
/**
|
|
96
|
+
* The error banner's source of truth: an active write's own failure takes precedence over a
|
|
97
|
+
* background list-refresh failure, and the list failure is suppressed entirely while a write is
|
|
98
|
+
* running — a failed background list refresh keeps `listError` set while the table still shows its
|
|
99
|
+
* last good data, and rendered unconditionally that error would become the banner the operator
|
|
100
|
+
* sees the instant they click Disable, reading as "your Disable failed" when the write is merely in
|
|
101
|
+
* flight and the stale message belongs to an earlier refresh. It returns afterwards if the list is
|
|
102
|
+
* genuinely still failing, which is honest rather than hidden.
|
|
103
|
+
*
|
|
104
|
+
* @complexity Time/space: O(1).
|
|
105
|
+
*/
|
|
106
|
+
export declare function visibleRedirectsError(params: {
|
|
107
|
+
writeError: Error | null;
|
|
108
|
+
saving: boolean;
|
|
109
|
+
listError: Error | null;
|
|
110
|
+
}, _optional?: {}): Error | null;
|
|
111
|
+
/** Discriminated parse result for the bulk-import textarea. */
|
|
112
|
+
export type ImportPayloadParseResult = {
|
|
113
|
+
ok: true;
|
|
114
|
+
rules: AdminRedirectCreateInput[];
|
|
115
|
+
} | {
|
|
116
|
+
ok: false;
|
|
117
|
+
error: string;
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Client-side shape check for the bulk-import textarea: valid JSON, and an array. Nothing deeper —
|
|
121
|
+
* the server remains the actual validator and reports per-item failures in its own `207`;
|
|
122
|
+
* duplicating that schema client-side would be a second source of truth for it (see
|
|
123
|
+
* `useImportRedirectsForm`'s `run:` comment).
|
|
124
|
+
*
|
|
125
|
+
* @complexity Time/space: O(1) beyond `JSON.parse`'s own cost in input length.
|
|
126
|
+
*/
|
|
127
|
+
export declare function parseImportPayload({ raw, translate }: {
|
|
128
|
+
raw: string;
|
|
129
|
+
translate: RedirectsTranslate;
|
|
130
|
+
}, _optional?: {}): ImportPayloadParseResult;
|
|
131
|
+
//# sourceMappingURL=rules.d.ts.map
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Pure logic for the `redirects` feature — everything that computes a value rather than
|
|
3
|
+
* rendering one. Follows the convention `features/posts/rules.ts` establishes: no React, no
|
|
4
|
+
* hooks, importable and directly testable.
|
|
5
|
+
*
|
|
6
|
+
* `KEYS` lives here rather than inside a hook file because three separate hook files
|
|
7
|
+
* (`use-redirects`, `use-hit-count-cell`, `use-import-redirects-form`) each need one branch of it.
|
|
8
|
+
* A cache-identity constant copied per hook is exactly the drift `@jini-ai/ui/fetch-query`'s own
|
|
9
|
+
* `QueryKey` doc warns about — a hand-typed second `["redirects"]` silently stops matching the
|
|
10
|
+
* first the moment one of them is edited.
|
|
11
|
+
*/
|
|
12
|
+
/** One cache identity per resource, defined once so a write's `invalidates` and a read's `key`
|
|
13
|
+
* cannot drift apart — the failure mode being an invalidation that silently matches nothing and a
|
|
14
|
+
* list that never refreshes. */
|
|
15
|
+
export const KEYS = {
|
|
16
|
+
list: ["redirects"],
|
|
17
|
+
hits: ({ redirectId }, _optional = {}) => ["redirects", redirectId, "hits"],
|
|
18
|
+
};
|
|
19
|
+
/** This screen's name on the host refresh bus — see `taxonomy/rules.ts`'s `TAXONOMY_RESOURCE`
|
|
20
|
+
* for why this is a plain colocated constant rather than a shared registry. Agent-writable via
|
|
21
|
+
* `redirects_create`/`redirects_update`/`redirects_tombstone` (`apps/website/src/features/redirects/
|
|
22
|
+
* agent-tools.ts`) — `redirects_import` is excluded from that catalog entirely, but the three wired
|
|
23
|
+
* single-row writes are enough to make this list go stale the same way Posts/Media did. */
|
|
24
|
+
export const REDIRECTS_RESOURCE = "redirects";
|
|
25
|
+
/**
|
|
26
|
+
* The status a "Disable"/"Enable" row action moves a rule TO — the inverse of its current status.
|
|
27
|
+
*
|
|
28
|
+
* @complexity Time/space: O(1).
|
|
29
|
+
*/
|
|
30
|
+
export function nextRedirectStatus({ currentStatus }, _optional = {}) {
|
|
31
|
+
return currentStatus === "active" ? "disabled" : "active";
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Shapes the create-redirect form's raw `FormData` into `api.createRedirect`'s input — the create
|
|
35
|
+
* mutation's payload, extracted so the shaping is testable without submitting a real form.
|
|
36
|
+
*
|
|
37
|
+
* @complexity Time/space: O(1) — four fixed field reads.
|
|
38
|
+
*/
|
|
39
|
+
export function buildCreateRedirectPayload({ form }, _optional = {}) {
|
|
40
|
+
return {
|
|
41
|
+
matchType: String(form.get("matchType") ?? "exact"),
|
|
42
|
+
fromPattern: String(form.get("fromPattern") ?? ""),
|
|
43
|
+
toTarget: String(form.get("toTarget") ?? ""),
|
|
44
|
+
statusCode: Number(form.get("statusCode") ?? 301),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The row-action menu for one redirect rule.
|
|
49
|
+
*
|
|
50
|
+
* The label is the reason this is exported: it reads the rule's CURRENT status to decide between
|
|
51
|
+
* "Disable" and "Enable", a branch that was otherwise reachable only by rendering the table and
|
|
52
|
+
* opening a popover. "Delete" only OPENS the confirmation; the delete itself is
|
|
53
|
+
* `useRedirects().confirmDelete`, gated on `ConfirmDialog` — same split as `posts/rules.ts`'s
|
|
54
|
+
* `postRowMenuItems`.
|
|
55
|
+
*
|
|
56
|
+
* @complexity Time/space: O(1) — two fixed entries, no iteration.
|
|
57
|
+
*/
|
|
58
|
+
export function redirectRowMenuItems({ rule, handlers }, { t = (key) => key } = {}) {
|
|
59
|
+
return [
|
|
60
|
+
{
|
|
61
|
+
key: "toggle",
|
|
62
|
+
label: rule.status === "active" ? t("Disable") : t("Enable"),
|
|
63
|
+
onSelect: () => handlers.onToggleStatus(rule),
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
key: "delete",
|
|
67
|
+
label: t("Delete"),
|
|
68
|
+
destructive: true,
|
|
69
|
+
onSelect: () => handlers.onRequestDelete(rule),
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* True while any of the screen's independent writes (create/toggle/delete) is in flight — gates
|
|
75
|
+
* the row-menu guard and the submit button's "Saving…" label.
|
|
76
|
+
*
|
|
77
|
+
* @complexity Time/space: O(w) in the number of writes (currently 3, fixed).
|
|
78
|
+
*/
|
|
79
|
+
export function isAnyWritePending({ writes }, _optional = {}) {
|
|
80
|
+
return writes.some((write) => write.status === "pending");
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The first still-active write failure, in WRITE-ARRAY order rather than recency.
|
|
84
|
+
*
|
|
85
|
+
* Order matters: three independent mutations each keep their own error until reset, so returning
|
|
86
|
+
* by recency would let a failed Create's banner persist on screen after a later, entirely
|
|
87
|
+
* successful Disable — blaming an operation that worked. `clearOtherWriteErrors` (in
|
|
88
|
+
* `use-redirects.hooks.ts`) is this rule's other half: it clears every write's error except the
|
|
89
|
+
* one just started, so at most one of these ever holds a stale failure at a time.
|
|
90
|
+
*
|
|
91
|
+
* @complexity Time/space: O(w) in the number of writes.
|
|
92
|
+
*/
|
|
93
|
+
export function firstWriteError({ writes }, _optional = {}) {
|
|
94
|
+
return writes.find((write) => write.error)?.error ?? null;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The error banner's source of truth: an active write's own failure takes precedence over a
|
|
98
|
+
* background list-refresh failure, and the list failure is suppressed entirely while a write is
|
|
99
|
+
* running — a failed background list refresh keeps `listError` set while the table still shows its
|
|
100
|
+
* last good data, and rendered unconditionally that error would become the banner the operator
|
|
101
|
+
* sees the instant they click Disable, reading as "your Disable failed" when the write is merely in
|
|
102
|
+
* flight and the stale message belongs to an earlier refresh. It returns afterwards if the list is
|
|
103
|
+
* genuinely still failing, which is honest rather than hidden.
|
|
104
|
+
*
|
|
105
|
+
* @complexity Time/space: O(1).
|
|
106
|
+
*/
|
|
107
|
+
export function visibleRedirectsError(params, _optional = {}) {
|
|
108
|
+
return params.writeError ?? (params.saving ? null : params.listError);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Client-side shape check for the bulk-import textarea: valid JSON, and an array. Nothing deeper —
|
|
112
|
+
* the server remains the actual validator and reports per-item failures in its own `207`;
|
|
113
|
+
* duplicating that schema client-side would be a second source of truth for it (see
|
|
114
|
+
* `useImportRedirectsForm`'s `run:` comment).
|
|
115
|
+
*
|
|
116
|
+
* @complexity Time/space: O(1) beyond `JSON.parse`'s own cost in input length.
|
|
117
|
+
*/
|
|
118
|
+
export function parseImportPayload({ raw, translate }, _optional = {}) {
|
|
119
|
+
let rules;
|
|
120
|
+
try {
|
|
121
|
+
rules = JSON.parse(raw);
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
return { ok: false, error: translate("Not valid JSON.") };
|
|
125
|
+
}
|
|
126
|
+
if (!Array.isArray(rules)) {
|
|
127
|
+
return { ok: false, error: translate("Must be a JSON array of rule objects.") };
|
|
128
|
+
}
|
|
129
|
+
// Unchecked by design (see `useImportRedirectsForm`'s `run:` comment). `Array.isArray` narrows
|
|
130
|
+
// `unknown` to `any[]`, which the mutation's input type accepted silently before this
|
|
131
|
+
// extraction; this states it instead.
|
|
132
|
+
return { ok: true, rules: rules };
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TabViewProps } from '../../../react/bind-react.js';
|
|
1
|
+
import type { TabViewProps } from '../../../core/react/bind-react.js';
|
|
2
2
|
import type { CredentialSummary, OtherCredentialSummary, CredentialCategory } from '../../models.js';
|
|
3
3
|
export declare function useAccessTokensTab({ permissions }: TabViewProps, _optional?: {}): {
|
|
4
4
|
denied: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState } from 'react';
|
|
2
|
-
import { useController } from '../../../react/use-controller.js';
|
|
2
|
+
import { useController } from '../../../core/react/use-controller.js';
|
|
3
3
|
import { createAccessTokensController } from '../../controllers/access-tokens.controller.js';
|
|
4
4
|
import { createOtherCredentialsController } from '../../controllers/other-credentials.controller.js';
|
|
5
5
|
import { CATEGORIES, credentialLabel, filterCredentials, filterOtherCredentials, otherWritePermission, writePermission } from '../../rules.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TabViewProps } from '../../../react/bind-react.js';
|
|
1
|
+
import type { TabViewProps } from '../../../core/react/bind-react.js';
|
|
2
2
|
export declare function useRootKeyTab({ permissions, params }: TabViewProps, _optional?: {}): {
|
|
3
3
|
denied: boolean;
|
|
4
4
|
loading: boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useController } from '../../../react/use-controller.js';
|
|
1
|
+
import { useController } from '../../../core/react/use-controller.js';
|
|
2
2
|
import { createRootKeyController } from '../../controllers/root-key.controller.js';
|
|
3
3
|
import { ROOT_KEY_PERMISSION, START_FRESH_CONFIRMATION, isRootKeyLocked } from '../../rules.js';
|
|
4
4
|
import { unavailableRootKey, useSecurityPorts } from './SecurityPorts.hooks.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bindReact } from '../../react/bind-react.js';
|
|
1
|
+
import { bindReact } from '../../core/react/bind-react.js';
|
|
2
2
|
import { securityModule } from '../security.module.js';
|
|
3
3
|
import { SecurityPortsContext } from './hooks/SecurityPorts.hooks.js';
|
|
4
4
|
export { useSecurityPorts } from './hooks/SecurityPorts.hooks.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ModulePageProps } from '../../../react/bind-react.js';
|
|
1
|
+
import type { ModulePageProps } from '../../../core/react/bind-react.js';
|
|
2
2
|
export declare function SecurityPage(props: ModulePageProps, _optional?: {}): import("react").JSX.Element;
|
|
3
3
|
export default SecurityPage;
|
|
4
4
|
//# sourceMappingURL=SecurityPage.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TabViewProps } from '../../../react/bind-react.js';
|
|
1
|
+
import type { TabViewProps } from '../../../core/react/bind-react.js';
|
|
2
2
|
export declare function AccessTokensTab(props: TabViewProps, _optional?: {}): import("react").JSX.Element;
|
|
3
3
|
export default AccessTokensTab;
|
|
4
4
|
//# sourceMappingURL=AccessTokensTab.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TabViewProps } from '../../../react/bind-react.js';
|
|
1
|
+
import type { TabViewProps } from '../../../core/react/bind-react.js';
|
|
2
2
|
export declare function RootKeyTab(props: TabViewProps, _optional?: {}): import("react").JSX.Element;
|
|
3
3
|
export default RootKeyTab;
|
|
4
4
|
//# sourceMappingURL=RootKeyTab.d.ts.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AdminSeoPort } from '../ports.js';
|
|
2
|
+
/** Host owns authentication, workspace addressing, retries, JSON and API error decoding. */
|
|
3
|
+
export interface SeoTransportPort {
|
|
4
|
+
request<T>(required: {
|
|
5
|
+
path: string;
|
|
6
|
+
method: 'GET' | 'PUT' | 'POST';
|
|
7
|
+
body?: unknown;
|
|
8
|
+
}, optional?: {
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
}): Promise<T>;
|
|
11
|
+
url(required: {
|
|
12
|
+
path: string;
|
|
13
|
+
}, optional?: Record<string, never>): string;
|
|
14
|
+
}
|
|
15
|
+
/** Public XML uses the host's raw transport, since the admin JSON transport cannot decode XML. */
|
|
16
|
+
export interface SeoSitemapTransportPort {
|
|
17
|
+
get(required: {
|
|
18
|
+
path: '/sitemap.xml';
|
|
19
|
+
credentials: 'same-origin';
|
|
20
|
+
}, optional?: {
|
|
21
|
+
signal?: AbortSignal;
|
|
22
|
+
}): Promise<Pick<Response, 'ok' | 'status' | 'headers' | 'text'>>;
|
|
23
|
+
}
|
|
24
|
+
/** Preserves every existing SEO request path and body; basePath is the host workspace path. */
|
|
25
|
+
export declare function createHttpSeoApi({ transport, basePath }: {
|
|
26
|
+
transport: SeoTransportPort;
|
|
27
|
+
basePath: string;
|
|
28
|
+
}, { sitemapTransport }?: {
|
|
29
|
+
sitemapTransport?: SeoSitemapTransportPort;
|
|
30
|
+
}): AdminSeoPort;
|
|
31
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Preserves every existing SEO request path and body; basePath is the host workspace path. */
|
|
2
|
+
export function createHttpSeoApi({ transport, basePath }, { sitemapTransport } = {}) {
|
|
3
|
+
const base = basePath.replace(/\/$/, '');
|
|
4
|
+
const entryPath = (entryId) => `${base}/seo/entries/${encodeURIComponent(entryId)}`;
|
|
5
|
+
async function data(path, method, body) {
|
|
6
|
+
const response = await transport.request({ path, method, ...(body === undefined ? {} : { body }) });
|
|
7
|
+
return response.data;
|
|
8
|
+
}
|
|
9
|
+
async function choices(kind) {
|
|
10
|
+
const response = await transport.request({ path: `${base}/${kind}`, method: 'GET' });
|
|
11
|
+
return response.posts.map(({ post }) => post);
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
getSeoSettings: () => data(`${base}/seo/settings`, 'GET'),
|
|
15
|
+
putSeoSettings: (_required, patch = {}) => data(`${base}/seo/settings`, 'PUT', patch),
|
|
16
|
+
regenerateSeoSitemap: () => data(`${base}/seo/sitemap/regenerate`, 'POST'),
|
|
17
|
+
getSeoEntry: ({ entryId }) => data(entryPath(entryId), 'GET'),
|
|
18
|
+
putSeoEntry: ({ entryId }, patch = {}) => data(entryPath(entryId), 'PUT', patch),
|
|
19
|
+
analyzeSeoEntry: ({ entryId }) => data(`${entryPath(entryId)}/analyze`, 'GET'),
|
|
20
|
+
listSeoPosts: () => choices('posts'),
|
|
21
|
+
listSeoPages: () => choices('pages'),
|
|
22
|
+
mediaOriginalUrl: ({ id }) => transport.url({ path: `${base}/media/${encodeURIComponent(id)}/original` }),
|
|
23
|
+
async fetchSitemapXml(_required, options = {}) {
|
|
24
|
+
if (!sitemapTransport)
|
|
25
|
+
throw new Error('SEO sitemap transport unavailable');
|
|
26
|
+
options.signal?.throwIfAborted();
|
|
27
|
+
const response = await sitemapTransport.get({ path: '/sitemap.xml', credentials: 'same-origin' }, options);
|
|
28
|
+
// Non-XML often means a dev proxy, stale build or captive portal answered instead. Do not
|
|
29
|
+
// silently parse an HTML error page as a sitemap with zero URLs (source defensive guard).
|
|
30
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
31
|
+
if (!response.ok || !contentType.includes('xml'))
|
|
32
|
+
throw new Error(`Could not load the sitemap (HTTP ${response.status}).`);
|
|
33
|
+
return { text: await response.text() };
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AdminSeoPort } from '../ports.js';
|
|
2
|
+
import type { SeoEntryMeta, SeoEntryAnalysis, SeoEntryOverridesPatch, SeoSettings, AdminPost } from '../models.js';
|
|
3
|
+
export interface SeoEntrySeed {
|
|
4
|
+
meta: SeoEntryMeta;
|
|
5
|
+
analysis: SeoEntryAnalysis;
|
|
6
|
+
}
|
|
7
|
+
export interface MemorySeoOptions {
|
|
8
|
+
settings?: SeoSettings;
|
|
9
|
+
entries?: Record<string, SeoEntrySeed>;
|
|
10
|
+
posts?: readonly AdminPost[];
|
|
11
|
+
pages?: readonly AdminPost[];
|
|
12
|
+
sitemapText?: string;
|
|
13
|
+
sitemapError?: string;
|
|
14
|
+
mediaOriginalUrl?: (required: {
|
|
15
|
+
id: string;
|
|
16
|
+
}, optional?: Record<string, never>) => string;
|
|
17
|
+
}
|
|
18
|
+
/** Isolated memory backend with seeded effective defaults; never implements a CMS repository.
|
|
19
|
+
* Clears resolve back to the seed, and prior returned snapshots never change on subsequent writes.
|
|
20
|
+
* A host with richer content derivation can supply resolveEntry rather than fork the adapter. */
|
|
21
|
+
export declare function createMemorySeoApi(required?: MemorySeoOptions, { resolveEntry }?: {
|
|
22
|
+
resolveEntry?: (required: {
|
|
23
|
+
entryId: string;
|
|
24
|
+
base: SeoEntryMeta;
|
|
25
|
+
overrides: SeoEntryOverridesPatch;
|
|
26
|
+
}, optional?: Record<string, never>) => SeoEntryMeta;
|
|
27
|
+
}): AdminSeoPort;
|
|
28
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
const defaultSettings = () => ({ titleTemplate: '%s', defaultRobots: { noindex: false, nofollow: false }, sitemapEnabled: true, robotsRules: [] });
|
|
2
|
+
const clone = (value) => structuredClone(value);
|
|
3
|
+
/** `patch value ?? meta value`, named — {@link applySeoPatch} calls this once per field instead of
|
|
4
|
+
* inlining `??` at each of its 13 fields: a plain function call isn't a decision point the way an
|
|
5
|
+
* inline `??` is, so this is what keeps that merge under the complexity ceiling (same fix this
|
|
6
|
+
* codebase's `orEmpty` established elsewhere for the same class of violation — a flat run of
|
|
7
|
+
* independent fallbacks, not real branching logic).
|
|
8
|
+
*
|
|
9
|
+
* `null` (the patch's CLEAR sentinel) falls through to the meta value by the same `??`, which is
|
|
10
|
+
* the right model for this fake: the server drops the override and re-resolves, and the seeded
|
|
11
|
+
* `meta` is the closest thing this fake has to that resolved value. It is only an approximation —
|
|
12
|
+
* a test that needs to prove a clear actually reached the wire must assert on the PUT body, not on
|
|
13
|
+
* what comes back. */
|
|
14
|
+
function orMeta(patchValue, metaValue) {
|
|
15
|
+
return patchValue ?? metaValue;
|
|
16
|
+
}
|
|
17
|
+
/** Applies a {@link SeoEntryOverridesPatch} onto a resolved {@link SeoEntryMeta} — only the fields
|
|
18
|
+
* a fake's own tests plausibly touch are merged (title/description/canonical directly, robots and
|
|
19
|
+
* the OG/Twitter card objects field-by-field); this mirrors the server's `SeoExtFields` -> `SeoMeta`
|
|
20
|
+
* merge closely enough for hook-level tests without re-implementing the real resolution rules. */
|
|
21
|
+
// Optional read fields are absent when unresolved; write-only null never reaches the read shape.
|
|
22
|
+
function optionalString(key, value) {
|
|
23
|
+
return value === undefined ? {} : { [key]: value };
|
|
24
|
+
}
|
|
25
|
+
function applySeoPatch(meta, patch) {
|
|
26
|
+
return {
|
|
27
|
+
...meta,
|
|
28
|
+
title: orMeta(patch.title, meta.title),
|
|
29
|
+
...optionalString('description', orMeta(patch.description, meta.description)),
|
|
30
|
+
canonical: orMeta(patch.canonical, meta.canonical),
|
|
31
|
+
robots: {
|
|
32
|
+
noindex: orMeta(patch.noindex, meta.robots.noindex),
|
|
33
|
+
nofollow: orMeta(patch.nofollow, meta.robots.nofollow),
|
|
34
|
+
},
|
|
35
|
+
openGraph: {
|
|
36
|
+
...meta.openGraph,
|
|
37
|
+
title: orMeta(patch.ogTitle, meta.openGraph.title),
|
|
38
|
+
...optionalString('description', orMeta(patch.ogDescription, meta.openGraph.description)),
|
|
39
|
+
...optionalString('image', orMeta(patch.ogImage, meta.openGraph.image)),
|
|
40
|
+
type: orMeta(patch.ogType, meta.openGraph.type),
|
|
41
|
+
},
|
|
42
|
+
twitter: {
|
|
43
|
+
...meta.twitter,
|
|
44
|
+
card: orMeta(patch.twitterCard, meta.twitter.card),
|
|
45
|
+
title: orMeta(patch.twitterTitle, meta.twitter.title),
|
|
46
|
+
...optionalString('description', orMeta(patch.twitterDescription, meta.twitter.description)),
|
|
47
|
+
...optionalString('image', orMeta(patch.twitterImage, meta.twitter.image)),
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/** One of the three site-wide scalars the server registers as `nullable: true` (`SEO_DEFINITIONS`,
|
|
52
|
+
* `apps/website/src/features/seo/settings.ts`), under the real write's own rule: an omitted key
|
|
53
|
+
* (`undefined`) keeps the current value, `null` clears it, and a string overwrites. */
|
|
54
|
+
function settingOrCleared(patchValue, currentValue) {
|
|
55
|
+
if (patchValue === undefined)
|
|
56
|
+
return currentValue;
|
|
57
|
+
return patchValue ?? undefined;
|
|
58
|
+
}
|
|
59
|
+
/** Applies a {@link SeoSettingsPatch} the way the real `setSeoSettings` does: an omitted key leaves
|
|
60
|
+
* the current value alone (it is a MERGE — `buildScalarWrites` skips every `undefined`), and a
|
|
61
|
+
* `null` on one of the three nullable scalars clears it back to absent, which `getSeoSettings`
|
|
62
|
+
* reads back as `undefined` (via its `undefinedIfEmpty`). Naming those three explicitly rather
|
|
63
|
+
* than spreading the patch verbatim is what stops a `null` from surviving into a `SeoSettings`
|
|
64
|
+
* the fake hands back — no real response can contain one.
|
|
65
|
+
*
|
|
66
|
+
* @complexity O(1) — three fixed field reads, no iteration. */
|
|
67
|
+
function applySettingsPatch(current, patch) {
|
|
68
|
+
const { defaultDescription, defaultOgImage, twitterSite, ...rest } = patch;
|
|
69
|
+
const { defaultDescription: _description, defaultOgImage: _image, twitterSite: _site, ...retained } = current;
|
|
70
|
+
return {
|
|
71
|
+
...retained,
|
|
72
|
+
...rest,
|
|
73
|
+
...optionalString('defaultDescription', settingOrCleared(defaultDescription, current.defaultDescription)),
|
|
74
|
+
...optionalString('defaultOgImage', settingOrCleared(defaultOgImage, current.defaultOgImage)),
|
|
75
|
+
...optionalString('twitterSite', settingOrCleared(twitterSite, current.twitterSite)),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/** Isolated memory backend with seeded effective defaults; never implements a CMS repository.
|
|
79
|
+
* Clears resolve back to the seed, and prior returned snapshots never change on subsequent writes.
|
|
80
|
+
* A host with richer content derivation can supply resolveEntry rather than fork the adapter. */
|
|
81
|
+
export function createMemorySeoApi(required = {}, { resolveEntry } = {}) {
|
|
82
|
+
let settings = clone(required.settings ?? defaultSettings());
|
|
83
|
+
const entries = clone(required.entries ?? {});
|
|
84
|
+
const posts = clone(required.posts ?? []);
|
|
85
|
+
const pages = clone(required.pages ?? []);
|
|
86
|
+
const overrides = {};
|
|
87
|
+
const lookup = (entryId) => {
|
|
88
|
+
const found = entries[entryId];
|
|
89
|
+
if (!found)
|
|
90
|
+
throw new Error(`fake seo port: unknown entry ${entryId}`);
|
|
91
|
+
return found;
|
|
92
|
+
};
|
|
93
|
+
const resolved = (entryId) => {
|
|
94
|
+
const base = lookup(entryId).meta;
|
|
95
|
+
const patch = overrides[entryId] ?? {};
|
|
96
|
+
return resolveEntry ? resolveEntry({ entryId, base: clone(base), overrides: clone(patch) }) : applySeoPatch(base, patch);
|
|
97
|
+
};
|
|
98
|
+
return {
|
|
99
|
+
async getSeoSettings() { return clone(settings); },
|
|
100
|
+
async putSeoSettings(_required, patch = {}) { settings = applySettingsPatch(settings, patch); return clone(settings); },
|
|
101
|
+
async regenerateSeoSitemap() { return { accepted: true }; },
|
|
102
|
+
async getSeoEntry({ entryId }) { return clone(resolved(entryId)); },
|
|
103
|
+
async putSeoEntry({ entryId }, patch = {}) {
|
|
104
|
+
lookup(entryId);
|
|
105
|
+
const current = { ...overrides[entryId] };
|
|
106
|
+
// O(k) in patch keys; null removes only touched overrides, omission preserves other edits.
|
|
107
|
+
for (const key of Object.keys(patch)) {
|
|
108
|
+
const value = patch[key];
|
|
109
|
+
if (value === null)
|
|
110
|
+
delete current[key];
|
|
111
|
+
else if (value !== undefined)
|
|
112
|
+
Object.assign(current, { [key]: value });
|
|
113
|
+
}
|
|
114
|
+
overrides[entryId] = current;
|
|
115
|
+
return clone(resolved(entryId));
|
|
116
|
+
},
|
|
117
|
+
async analyzeSeoEntry({ entryId }) { return clone(lookup(entryId).analysis); },
|
|
118
|
+
async listSeoPosts() { return clone(posts); },
|
|
119
|
+
async listSeoPages() { return clone(pages); },
|
|
120
|
+
async fetchSitemapXml(_required, { signal } = {}) {
|
|
121
|
+
signal?.throwIfAborted();
|
|
122
|
+
if (required.sitemapError !== undefined)
|
|
123
|
+
throw new Error(required.sitemapError);
|
|
124
|
+
return { text: required.sitemapText ?? '<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n</urlset>\n' };
|
|
125
|
+
},
|
|
126
|
+
mediaOriginalUrl({ id }) { return required.mediaOriginalUrl?.({ id }) ?? `memory://media/${encodeURIComponent(id)}/original`; },
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=memory.js.map
|