@supernova-studio/client 1.96.5 → 1.96.7
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/dist/index.d.mts +101428 -143199
- package/dist/index.d.ts +101428 -143199
- package/dist/index.js +489 -99
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5607 -5217
- package/dist/index.mjs.map +1 -1
- package/package.json +20 -9
- package/src/api/client.ts +62 -0
- package/src/api/conversion/analytics/index.ts +3 -0
- package/src/api/conversion/analytics/page-visits-to-comparison-dto.ts +65 -0
- package/src/api/conversion/analytics/page-visits-to-dto.ts +68 -0
- package/src/api/conversion/analytics/page-visits-to-heatmap-dto.ts +49 -0
- package/src/api/conversion/documentation/documentation-group-v1-to-dto.ts +114 -0
- package/src/api/conversion/documentation/documentation-group-v2-to-dto.ts +91 -0
- package/src/api/conversion/documentation/documentation-item-configuration-v1-to-dto.ts +52 -0
- package/src/api/conversion/documentation/documentation-item-configuration-v2-to-dto.ts +34 -0
- package/src/api/conversion/documentation/documentation-page-to-dto-utils.ts +134 -0
- package/src/api/conversion/documentation/documentation-page-v1-to-dto.ts +69 -0
- package/src/api/conversion/documentation/documentation-page-v2-to-dto.ts +84 -0
- package/src/api/conversion/documentation/documentation-settings-to-dto.ts +14 -0
- package/src/api/conversion/documentation/index.ts +8 -0
- package/src/api/conversion/export/index.ts +1 -0
- package/src/api/conversion/export/pipeline.ts +27 -0
- package/src/api/conversion/index.ts +4 -0
- package/src/api/conversion/integrations/git.ts +37 -0
- package/src/api/conversion/integrations/index.ts +2 -0
- package/src/api/conversion/integrations/integration.ts +37 -0
- package/src/api/dto/access-tokens/access-token.ts +45 -0
- package/src/api/dto/access-tokens/index.ts +1 -0
- package/src/api/dto/aux/color.ts +7 -0
- package/src/api/dto/aux/index.ts +4 -0
- package/src/api/dto/aux/meta.ts +8 -0
- package/src/api/dto/aux/object-metadata.ts +29 -0
- package/src/api/dto/aux/pagination.ts +8 -0
- package/src/api/dto/bff/app-bootstrap-data.ts +20 -0
- package/src/api/dto/bff/index.ts +1 -0
- package/src/api/dto/collections/index.ts +1 -0
- package/src/api/dto/collections/token-collection.ts +32 -0
- package/src/api/dto/design-systems/brand.ts +44 -0
- package/src/api/dto/design-systems/code-component-usage.ts +52 -0
- package/src/api/dto/design-systems/code-component.ts +101 -0
- package/src/api/dto/design-systems/code-history.ts +43 -0
- package/src/api/dto/design-systems/code-scan.ts +29 -0
- package/src/api/dto/design-systems/code-snapshots.ts +46 -0
- package/src/api/dto/design-systems/component.ts +40 -0
- package/src/api/dto/design-systems/contact.ts +11 -0
- package/src/api/dto/design-systems/data-source.ts +216 -0
- package/src/api/dto/design-systems/design-system.ts +75 -0
- package/src/api/dto/design-systems/documentation-search.ts +31 -0
- package/src/api/dto/design-systems/elements-diff.ts +14 -0
- package/src/api/dto/design-systems/figma-variables.ts +122 -0
- package/src/api/dto/design-systems/file.ts +71 -0
- package/src/api/dto/design-systems/import-job.ts +62 -0
- package/src/api/dto/design-systems/index.ts +24 -0
- package/src/api/dto/design-systems/members.ts +52 -0
- package/src/api/dto/design-systems/redirects.ts +33 -0
- package/src/api/dto/design-systems/role.ts +11 -0
- package/src/api/dto/design-systems/stats.ts +20 -0
- package/src/api/dto/design-systems/storybook.ts +45 -0
- package/src/api/dto/design-systems/user-design-systems.ts +10 -0
- package/src/api/dto/design-systems/version-room.ts +12 -0
- package/src/api/dto/design-systems/version.ts +56 -0
- package/src/api/dto/design-systems/view.ts +45 -0
- package/src/api/dto/design-tokens/design-token.ts +78 -0
- package/src/api/dto/design-tokens/index.ts +1 -0
- package/src/api/dto/documentation/analytics-v2.ts +80 -0
- package/src/api/dto/documentation/analytics.ts +32 -0
- package/src/api/dto/documentation/anchor.ts +15 -0
- package/src/api/dto/documentation/approvals.ts +21 -0
- package/src/api/dto/documentation/block-definition.ts +28 -0
- package/src/api/dto/documentation/block.ts +6 -0
- package/src/api/dto/documentation/documentation-page-snapshot.ts +18 -0
- package/src/api/dto/documentation/documentation.ts +34 -0
- package/src/api/dto/documentation/index.ts +11 -0
- package/src/api/dto/documentation/link-preview.ts +23 -0
- package/src/api/dto/documentation/publish.ts +23 -0
- package/src/api/dto/documentation/room.ts +12 -0
- package/src/api/dto/elements/components/figma-component-group.ts +19 -0
- package/src/api/dto/elements/components/figma-component.ts +56 -0
- package/src/api/dto/elements/components/index.ts +2 -0
- package/src/api/dto/elements/documentation/configuration.ts +20 -0
- package/src/api/dto/elements/documentation/draft-state.ts +37 -0
- package/src/api/dto/elements/documentation/group-action.ts +108 -0
- package/src/api/dto/elements/documentation/group-v1.ts +35 -0
- package/src/api/dto/elements/documentation/group-v2.ts +117 -0
- package/src/api/dto/elements/documentation/hierarchy.ts +25 -0
- package/src/api/dto/elements/documentation/index.ts +16 -0
- package/src/api/dto/elements/documentation/item-configuration-v1.ts +24 -0
- package/src/api/dto/elements/documentation/item-configuration-v2.ts +14 -0
- package/src/api/dto/elements/documentation/metadata.ts +8 -0
- package/src/api/dto/elements/documentation/page-actions-v2.ts +138 -0
- package/src/api/dto/elements/documentation/page-content.ts +15 -0
- package/src/api/dto/elements/documentation/page-dependencies.ts +30 -0
- package/src/api/dto/elements/documentation/page-v1.ts +21 -0
- package/src/api/dto/elements/documentation/page-v2.ts +132 -0
- package/src/api/dto/elements/documentation/settings.ts +9 -0
- package/src/api/dto/elements/documentation/structure.ts +37 -0
- package/src/api/dto/elements/elements-action-v2.ts +125 -0
- package/src/api/dto/elements/figma-nodes/figma-node-structure.ts +27 -0
- package/src/api/dto/elements/figma-nodes/figma-node-v1.ts +32 -0
- package/src/api/dto/elements/figma-nodes/figma-node-v2.ts +32 -0
- package/src/api/dto/elements/figma-nodes/figma-node.ts +103 -0
- package/src/api/dto/elements/figma-nodes/index.ts +5 -0
- package/src/api/dto/elements/figma-nodes/node-actions-v2.ts +25 -0
- package/src/api/dto/elements/frame-node-structures/frame-node-structure.ts +17 -0
- package/src/api/dto/elements/frame-node-structures/index.ts +1 -0
- package/src/api/dto/elements/get-elements-v2.ts +27 -0
- package/src/api/dto/elements/index.ts +7 -0
- package/src/api/dto/elements/properties/index.ts +2 -0
- package/src/api/dto/elements/properties/property-definitions.ts +75 -0
- package/src/api/dto/elements/properties/property-values.ts +50 -0
- package/src/api/dto/events/forge-project.ts +51 -0
- package/src/api/dto/events/index.ts +2 -0
- package/src/api/dto/events/workspace.ts +81 -0
- package/src/api/dto/export/exporter-property.ts +114 -0
- package/src/api/dto/export/exporter.ts +115 -0
- package/src/api/dto/export/filter.ts +20 -0
- package/src/api/dto/export/index.ts +5 -0
- package/src/api/dto/export/job.ts +114 -0
- package/src/api/dto/export/pipeline.ts +60 -0
- package/src/api/dto/figma-components/assets/download.ts +30 -0
- package/src/api/dto/figma-components/assets/index.ts +1 -0
- package/src/api/dto/figma-components/index.ts +1 -0
- package/src/api/dto/figma-exporter/figma-node.ts +11 -0
- package/src/api/dto/figma-exporter/index.ts +1 -0
- package/src/api/dto/files/files.ts +94 -0
- package/src/api/dto/files/index.ts +1 -0
- package/src/api/dto/forge/agent.ts +38 -0
- package/src/api/dto/forge/artifact.ts +94 -0
- package/src/api/dto/forge/feature-messages.ts +551 -0
- package/src/api/dto/forge/feature-room.ts +12 -0
- package/src/api/dto/forge/figma-node.ts +117 -0
- package/src/api/dto/forge/index.ts +28 -0
- package/src/api/dto/forge/iteration-message-old.ts +43 -0
- package/src/api/dto/forge/knowledge-item.ts +67 -0
- package/src/api/dto/forge/memory.ts +67 -0
- package/src/api/dto/forge/participant.ts +44 -0
- package/src/api/dto/forge/project-action.ts +123 -0
- package/src/api/dto/forge/project-artifact-room.ts +12 -0
- package/src/api/dto/forge/project-artifact.ts +85 -0
- package/src/api/dto/forge/project-context-feedback.ts +141 -0
- package/src/api/dto/forge/project-context-override.ts +41 -0
- package/src/api/dto/forge/project-context-scope.ts +23 -0
- package/src/api/dto/forge/project-context-v2.ts +228 -0
- package/src/api/dto/forge/project-context.ts +72 -0
- package/src/api/dto/forge/project-feature.ts +86 -0
- package/src/api/dto/forge/project-figma-node.ts +9 -0
- package/src/api/dto/forge/project-file.ts +48 -0
- package/src/api/dto/forge/project-invitation.ts +46 -0
- package/src/api/dto/forge/project-iteration-old.ts +54 -0
- package/src/api/dto/forge/project-member.ts +67 -0
- package/src/api/dto/forge/project-room.ts +12 -0
- package/src/api/dto/forge/project-section.ts +37 -0
- package/src/api/dto/forge/project.ts +105 -0
- package/src/api/dto/forge/relation.ts +34 -0
- package/src/api/dto/forge/threads.ts +153 -0
- package/src/api/dto/index.ts +25 -0
- package/src/api/dto/liveblocks/auth-response.ts +7 -0
- package/src/api/dto/liveblocks/index.ts +1 -0
- package/src/api/dto/mcp/index.ts +1 -0
- package/src/api/dto/mcp/stream.ts +17 -0
- package/src/api/dto/notifications/index.ts +2 -0
- package/src/api/dto/notifications/notifications.ts +65 -0
- package/src/api/dto/notifications/settings.ts +10 -0
- package/src/api/dto/portal/index.ts +1 -0
- package/src/api/dto/portal/portal-settings.ts +45 -0
- package/src/api/dto/sandboxes/index.ts +1 -0
- package/src/api/dto/sandboxes/template.ts +143 -0
- package/src/api/dto/storybook-sites/index.ts +1 -0
- package/src/api/dto/storybook-sites/storybook-sites.ts +60 -0
- package/src/api/dto/themes/index.ts +2 -0
- package/src/api/dto/themes/override.ts +27 -0
- package/src/api/dto/themes/theme.ts +53 -0
- package/src/api/dto/threads/index.ts +1 -0
- package/src/api/dto/threads/threads.ts +280 -0
- package/src/api/dto/trail-events/index.ts +1 -0
- package/src/api/dto/trail-events/trail-events.ts +172 -0
- package/src/api/dto/users/authenticated-user.ts +92 -0
- package/src/api/dto/users/index.ts +2 -0
- package/src/api/dto/users/user.ts +27 -0
- package/src/api/dto/workspaces/billing.ts +156 -0
- package/src/api/dto/workspaces/enums.ts +13 -0
- package/src/api/dto/workspaces/git.ts +32 -0
- package/src/api/dto/workspaces/index.ts +15 -0
- package/src/api/dto/workspaces/integrations.ts +34 -0
- package/src/api/dto/workspaces/invitations.ts +47 -0
- package/src/api/dto/workspaces/ip-whitelist.ts +33 -0
- package/src/api/dto/workspaces/knowledge-items-search.ts +37 -0
- package/src/api/dto/workspaces/login-screen.ts +42 -0
- package/src/api/dto/workspaces/membership.ts +55 -0
- package/src/api/dto/workspaces/npm-registry.ts +62 -0
- package/src/api/dto/workspaces/products.ts +45 -0
- package/src/api/dto/workspaces/subscription.ts +170 -0
- package/src/api/dto/workspaces/transfer-ownership.ts +7 -0
- package/src/api/dto/workspaces/untyped-data.ts +35 -0
- package/src/api/dto/workspaces/workspace.ts +49 -0
- package/src/api/endpoints/auth-tokens.ts +28 -0
- package/src/api/endpoints/codegen/codegen.ts +16 -0
- package/src/api/endpoints/codegen/ds-pipelines.ts +37 -0
- package/src/api/endpoints/codegen/exporters.ts +54 -0
- package/src/api/endpoints/codegen/index.ts +5 -0
- package/src/api/endpoints/codegen/jobs.ts +15 -0
- package/src/api/endpoints/codegen/pipelines.ts +55 -0
- package/src/api/endpoints/design-system/analytics.ts +14 -0
- package/src/api/endpoints/design-system/bff.ts +13 -0
- package/src/api/endpoints/design-system/code-snapshots.ts +47 -0
- package/src/api/endpoints/design-system/contact.ts +12 -0
- package/src/api/endpoints/design-system/design-systems.ts +90 -0
- package/src/api/endpoints/design-system/figma-node-structures.ts +20 -0
- package/src/api/endpoints/design-system/index.ts +11 -0
- package/src/api/endpoints/design-system/members.ts +24 -0
- package/src/api/endpoints/design-system/redirects.ts +46 -0
- package/src/api/endpoints/design-system/sources.ts +80 -0
- package/src/api/endpoints/design-system/storybook.ts +28 -0
- package/src/api/endpoints/design-system/versions/brands.ts +45 -0
- package/src/api/endpoints/design-system/versions/documentation.ts +107 -0
- package/src/api/endpoints/design-system/versions/ds-components.ts +30 -0
- package/src/api/endpoints/design-system/versions/elements-action.ts +65 -0
- package/src/api/endpoints/design-system/versions/elements.ts +27 -0
- package/src/api/endpoints/design-system/versions/figma-component-groups.ts +13 -0
- package/src/api/endpoints/design-system/versions/figma-components.ts +15 -0
- package/src/api/endpoints/design-system/versions/figma-frame-structures.ts +13 -0
- package/src/api/endpoints/design-system/versions/files.ts +43 -0
- package/src/api/endpoints/design-system/versions/import-jobs.ts +13 -0
- package/src/api/endpoints/design-system/versions/index.ts +19 -0
- package/src/api/endpoints/design-system/versions/overrides.ts +17 -0
- package/src/api/endpoints/design-system/versions/property-definitions.ts +43 -0
- package/src/api/endpoints/design-system/versions/property-values.ts +25 -0
- package/src/api/endpoints/design-system/versions/stats.ts +12 -0
- package/src/api/endpoints/design-system/versions/themes.ts +35 -0
- package/src/api/endpoints/design-system/versions/token-collections.ts +13 -0
- package/src/api/endpoints/design-system/versions/token-groups.ts +30 -0
- package/src/api/endpoints/design-system/versions/tokens.ts +29 -0
- package/src/api/endpoints/design-system/versions/versions.ts +90 -0
- package/src/api/endpoints/feedback.ts +60 -0
- package/src/api/endpoints/files.ts +25 -0
- package/src/api/endpoints/forge/agents.ts +54 -0
- package/src/api/endpoints/forge/artifacts.ts +54 -0
- package/src/api/endpoints/forge/documents.ts +18 -0
- package/src/api/endpoints/forge/feature-artifacts.ts +39 -0
- package/src/api/endpoints/forge/feature-iterations.ts +49 -0
- package/src/api/endpoints/forge/feature-messages.ts +68 -0
- package/src/api/endpoints/forge/features.ts +63 -0
- package/src/api/endpoints/forge/forge.ts +38 -0
- package/src/api/endpoints/forge/index.ts +16 -0
- package/src/api/endpoints/forge/iteration-tags.ts +13 -0
- package/src/api/endpoints/forge/memory.ts +41 -0
- package/src/api/endpoints/forge/project-contexts.ts +49 -0
- package/src/api/endpoints/forge/project-files.ts +41 -0
- package/src/api/endpoints/forge/project-invitations.ts +39 -0
- package/src/api/endpoints/forge/project-iterations.ts +65 -0
- package/src/api/endpoints/forge/project-members.ts +55 -0
- package/src/api/endpoints/forge/projects.ts +56 -0
- package/src/api/endpoints/index.ts +13 -0
- package/src/api/endpoints/liveblocks.ts +14 -0
- package/src/api/endpoints/mcp/index.ts +1 -0
- package/src/api/endpoints/mcp/streams.ts +21 -0
- package/src/api/endpoints/sandboxes/builds.ts +30 -0
- package/src/api/endpoints/sandboxes/index.ts +3 -0
- package/src/api/endpoints/sandboxes/sandboxes.ts +13 -0
- package/src/api/endpoints/sandboxes/templates.ts +16 -0
- package/src/api/endpoints/storybook-sites.ts +42 -0
- package/src/api/endpoints/threads.ts +38 -0
- package/src/api/endpoints/users.ts +26 -0
- package/src/api/endpoints/workspaces/billing.ts +24 -0
- package/src/api/endpoints/workspaces/chat-threads.ts +95 -0
- package/src/api/endpoints/workspaces/index.ts +9 -0
- package/src/api/endpoints/workspaces/integrations.ts +15 -0
- package/src/api/endpoints/workspaces/invites.ts +34 -0
- package/src/api/endpoints/workspaces/knowledge-items.ts +59 -0
- package/src/api/endpoints/workspaces/members.ts +31 -0
- package/src/api/endpoints/workspaces/npm-register.ts +20 -0
- package/src/api/endpoints/workspaces/subscription.ts +31 -0
- package/src/api/endpoints/workspaces/workspaces.ts +84 -0
- package/src/api/index.ts +6 -0
- package/src/api/payloads/design-systems/code-snapshots.ts +27 -0
- package/src/api/payloads/design-systems/index.ts +3 -0
- package/src/api/payloads/design-systems/update-design-system.ts +42 -0
- package/src/api/payloads/design-systems/version.ts +29 -0
- package/src/api/payloads/documentation/analytics.ts +36 -0
- package/src/api/payloads/documentation/block-definitions.ts +18 -0
- package/src/api/payloads/documentation/design-data-doc-diff.ts +7 -0
- package/src/api/payloads/documentation/index.ts +3 -0
- package/src/api/payloads/export/index.ts +1 -0
- package/src/api/payloads/export/pipeline.ts +111 -0
- package/src/api/payloads/index.ts +6 -0
- package/src/api/payloads/liveblocks/auth.ts +7 -0
- package/src/api/payloads/liveblocks/index.ts +1 -0
- package/src/api/payloads/users/index.ts +1 -0
- package/src/api/payloads/users/notifications/index.ts +1 -0
- package/src/api/payloads/users/notifications/notification-settings.ts +17 -0
- package/src/api/payloads/workspaces/index.ts +2 -0
- package/src/api/payloads/workspaces/workspace-configuration.ts +62 -0
- package/src/api/payloads/workspaces/workspace-integrations.ts +35 -0
- package/src/api/transport/index.ts +2 -0
- package/src/api/transport/request-executor-error.ts +60 -0
- package/src/api/transport/request-executor.ts +94 -0
- package/src/events/design-system.ts +21 -0
- package/src/events/event.ts +6 -0
- package/src/events/index.ts +2 -0
- package/src/index.ts +5 -0
- package/src/sync/docs-local-action-executor.ts +412 -0
- package/src/sync/docs-structure-repo.ts +283 -0
- package/src/sync/index.ts +5 -0
- package/src/sync/project-content-repo.ts +215 -0
- package/src/sync/project-local-action-executor.ts +415 -0
- package/src/sync/types.ts +37 -0
- package/src/utils/figma.ts +72 -0
- package/src/utils/hash.ts +62 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/query.ts +41 -0
- package/src/utils/redirect-validation.ts +76 -0
- package/src/yjs/design-system-content/documentation-hierarchy.ts +35 -0
- package/src/yjs/design-system-content/index.ts +2 -0
- package/src/yjs/design-system-content/item-configuration.ts +62 -0
- package/src/yjs/docs-editor/blocks-to-prosemirror.ts +764 -0
- package/src/yjs/docs-editor/index.ts +7 -0
- package/src/yjs/docs-editor/list-tree-builder.ts +127 -0
- package/src/yjs/docs-editor/mock.ts +2271 -0
- package/src/yjs/docs-editor/model/block.ts +8 -0
- package/src/yjs/docs-editor/model/index.ts +2 -0
- package/src/yjs/docs-editor/model/page.ts +8 -0
- package/src/yjs/docs-editor/prosemirror/index.ts +3 -0
- package/src/yjs/docs-editor/prosemirror/inner-editor-schema.ts +145 -0
- package/src/yjs/docs-editor/prosemirror/main-editor-schema.ts +577 -0
- package/src/yjs/docs-editor/prosemirror/types.ts +19 -0
- package/src/yjs/docs-editor/prosemirror-to-blocks.ts +986 -0
- package/src/yjs/docs-editor/utils.ts +115 -0
- package/src/yjs/feature-room/backend.ts +36 -0
- package/src/yjs/feature-room/base.ts +109 -0
- package/src/yjs/feature-room/frontend.ts +53 -0
- package/src/yjs/feature-room/index.ts +3 -0
- package/src/yjs/forge-project-room/backend.ts +59 -0
- package/src/yjs/forge-project-room/base.ts +190 -0
- package/src/yjs/forge-project-room/index.ts +2 -0
- package/src/yjs/index.ts +7 -0
- package/src/yjs/thread-room/backend.ts +32 -0
- package/src/yjs/thread-room/base.ts +71 -0
- package/src/yjs/thread-room/frontend.ts +39 -0
- package/src/yjs/thread-room/index.ts +3 -0
- package/src/yjs/utils/index.ts +1 -0
- package/src/yjs/utils/key-value-storage.ts +57 -0
- package/src/yjs/version-room/backend.ts +101 -0
- package/src/yjs/version-room/base.ts +323 -0
- package/src/yjs/version-room/compute-dto.ts +387 -0
- package/src/yjs/version-room/frontend.ts +76 -0
- package/src/yjs/version-room/index.ts +6 -0
- package/src/yjs/version-room/types.ts +31 -0
- package/src/yjs/version-room/utils.ts +109 -0
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DocumentationItemConfigurationV2,
|
|
3
|
+
DocumentationPageSnapshot,
|
|
4
|
+
ElementGroupSnapshot,
|
|
5
|
+
defaultDocumentationItemConfigurationV2,
|
|
6
|
+
mapByUnique,
|
|
7
|
+
pickLatestGroupSnapshots,
|
|
8
|
+
pickLatestPageSnapshots,
|
|
9
|
+
recordToMap,
|
|
10
|
+
} from "@supernova-studio/model";
|
|
11
|
+
import {
|
|
12
|
+
DTODocumentationDraftState,
|
|
13
|
+
DTODocumentationDraftStateUpdated,
|
|
14
|
+
DTODocumentationGroupApprovalState,
|
|
15
|
+
DTODocumentationHierarchyV2,
|
|
16
|
+
documentationItemConfigurationToDTOV2,
|
|
17
|
+
documentationPagesToDTOV2,
|
|
18
|
+
elementGroupsToDocumentationGroupDTOV2,
|
|
19
|
+
} from "../../api";
|
|
20
|
+
import { DTODocumentationPublishMetadata } from "../../api/dto/elements/documentation/metadata";
|
|
21
|
+
import { LocalApproval, LocalDocsPage, LocalDocsPageGroup } from "../../sync/types";
|
|
22
|
+
import { generateHash } from "../../utils";
|
|
23
|
+
import { DocumentationHierarchySettings } from "../design-system-content";
|
|
24
|
+
import { VersionRoomApproval, VersionRoomDocsPage, VersionRoomDocsPageGroup } from "./types";
|
|
25
|
+
|
|
26
|
+
type ItemState = {
|
|
27
|
+
title: string;
|
|
28
|
+
configuration: DocumentationItemConfigurationV2;
|
|
29
|
+
contentHash: string;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
type DocsPage = VersionRoomDocsPage | LocalDocsPage;
|
|
33
|
+
type DocsPageGroup = VersionRoomDocsPageGroup | LocalDocsPageGroup;
|
|
34
|
+
type Approval = VersionRoomApproval | LocalApproval;
|
|
35
|
+
|
|
36
|
+
type Input = {
|
|
37
|
+
pages: DocsPage[];
|
|
38
|
+
pageSnapshots: DocumentationPageSnapshot[];
|
|
39
|
+
pageContentHashes: Record<string, string>;
|
|
40
|
+
pageLiveblockRoomIds: Record<string, string>;
|
|
41
|
+
|
|
42
|
+
groups: DocsPageGroup[];
|
|
43
|
+
groupSnapshots: ElementGroupSnapshot[];
|
|
44
|
+
|
|
45
|
+
approvals: Approval[];
|
|
46
|
+
settings: DocumentationHierarchySettings;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export function computeDocsHierarchy(
|
|
50
|
+
input: Input,
|
|
51
|
+
options: { includeDeletedContent?: boolean; debug?: boolean } = {}
|
|
52
|
+
): DTODocumentationHierarchyV2 {
|
|
53
|
+
const includeDeletedContent = options.includeDeletedContent ?? false;
|
|
54
|
+
const debug = options.debug ?? false;
|
|
55
|
+
|
|
56
|
+
// Read current room data
|
|
57
|
+
const { pages, groups, pageSnapshots, groupSnapshots, settings, pageContentHashes, approvals, pageLiveblockRoomIds } =
|
|
58
|
+
input;
|
|
59
|
+
|
|
60
|
+
if (settings.isDraftFeatureAdopted && includeDeletedContent) {
|
|
61
|
+
pages.push(...getDeletedPages(pages, pageSnapshots));
|
|
62
|
+
groups.push(...getDeletedGroups(groups, groupSnapshots));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Convert pages to DTOs
|
|
66
|
+
const pageDTOs = documentationPagesToDTOV2(pages, groups, settings.routingVersion, recordToMap(pageLiveblockRoomIds));
|
|
67
|
+
const groupDTOs = elementGroupsToDocumentationGroupDTOV2(groups, pages);
|
|
68
|
+
|
|
69
|
+
// Calculate hasPublishedDocumentationContent
|
|
70
|
+
const hasPublishedPages = pageSnapshots.some(s => s.reason === "Publish");
|
|
71
|
+
const hasPublishedGroups = groupSnapshots.some(s => s.reason === "Publish");
|
|
72
|
+
const hasPublishedDocumentationContent = hasPublishedPages || hasPublishedGroups;
|
|
73
|
+
|
|
74
|
+
// If draft feature is not yet adopted, no snapshot-based features should not be provided
|
|
75
|
+
if (!settings.isDraftFeatureAdopted) {
|
|
76
|
+
return {
|
|
77
|
+
hasPublishedDocumentationContent,
|
|
78
|
+
pages: pageDTOs,
|
|
79
|
+
groups: groupDTOs,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const pageDraftStates = buildPageDraftCreatedAndUpdatedStates(pages, pageSnapshots, pageContentHashes, debug);
|
|
84
|
+
const pageDraftDeletedStates = buildPageDraftDeletedStates(pages, pageSnapshots);
|
|
85
|
+
const pagePublishedMetadata = buildPagePublishedMetadata(pages, pageSnapshots);
|
|
86
|
+
const pageApprovalStates = mapByUnique(approvals, a => a.pagePersistentId);
|
|
87
|
+
|
|
88
|
+
pageDTOs.forEach(p => {
|
|
89
|
+
// Assign draft state
|
|
90
|
+
const draftState = pageDraftDeletedStates.get(p.persistentId) ?? pageDraftStates.get(p.persistentId);
|
|
91
|
+
draftState && (p.draftState = draftState);
|
|
92
|
+
|
|
93
|
+
// Assign publish metadata
|
|
94
|
+
const publishMetadata = pagePublishedMetadata.get(p.persistentId);
|
|
95
|
+
publishMetadata && (p.publishMetadata = publishMetadata);
|
|
96
|
+
|
|
97
|
+
// Assign approval state
|
|
98
|
+
const approvalState = pageApprovalStates.get(p.persistentId);
|
|
99
|
+
approvalState && (p.approvalState = approvalState);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const groupDraftStates = buildGroupDraftCreatedAndUpdatedStates(groups, groupSnapshots, debug);
|
|
103
|
+
const groupDraftDeletedStates = buildGroupDraftDeletedStates(groups, groupSnapshots);
|
|
104
|
+
const groupPublishedMetadata = buildGroupPublishedMetadata(groups, groupSnapshots);
|
|
105
|
+
const groupApprovalStates = buildGroupApprovalStates(groups, groupSnapshots);
|
|
106
|
+
groupDTOs.forEach(g => {
|
|
107
|
+
// Assign draft state
|
|
108
|
+
const draftState = groupDraftDeletedStates.get(g.persistentId) ?? groupDraftStates.get(g.persistentId);
|
|
109
|
+
draftState && (g.draftState = draftState);
|
|
110
|
+
|
|
111
|
+
// Assign publish metadata
|
|
112
|
+
const publishMetadata = groupPublishedMetadata.get(g.persistentId);
|
|
113
|
+
publishMetadata && (g.publishMetadata = publishMetadata);
|
|
114
|
+
|
|
115
|
+
const approvalState = groupApprovalStates.get(g.persistentId);
|
|
116
|
+
approvalState && (g.approvalState = approvalState);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
hasPublishedDocumentationContent,
|
|
121
|
+
pages: pageDTOs,
|
|
122
|
+
groups: groupDTOs,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function getDeletedPages(pages: DocsPage[], pageSnapshots: DocumentationPageSnapshot[]): DocsPage[] {
|
|
127
|
+
const existingPagePersistentIds = new Set(pages.map(p => p.persistentId));
|
|
128
|
+
const latestSnapshots = pickLatestPageSnapshots(pageSnapshots);
|
|
129
|
+
return latestSnapshots.filter(s => !existingPagePersistentIds.has(s.page.persistentId)).map(s => s.page);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function getDeletedGroups(groups: DocsPageGroup[], groupSnapshots: ElementGroupSnapshot[]): DocsPageGroup[] {
|
|
133
|
+
const existingGroupPersistentIds = new Set(groups.map(p => p.persistentId));
|
|
134
|
+
const latestSnapshots = pickLatestGroupSnapshots(groupSnapshots);
|
|
135
|
+
return latestSnapshots.filter(s => !existingGroupPersistentIds.has(s.group.persistentId)).map(s => s.group);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function buildPageDraftCreatedAndUpdatedStates(
|
|
139
|
+
pages: DocsPage[],
|
|
140
|
+
pageSnapshots: DocumentationPageSnapshot[],
|
|
141
|
+
pageHashes: Record<string, string>,
|
|
142
|
+
debug: boolean
|
|
143
|
+
): Map<string, DTODocumentationDraftState> {
|
|
144
|
+
// Read room data
|
|
145
|
+
const publishedSnapshots = pickLatestPageSnapshots(pageSnapshots.filter(s => s.reason === "Publish"));
|
|
146
|
+
const publishedSnapshotsByPagePersistentId = mapByUnique(publishedSnapshots, s => s.page.persistentId);
|
|
147
|
+
|
|
148
|
+
const result = new Map<string, DTODocumentationDraftState>();
|
|
149
|
+
|
|
150
|
+
pages.forEach(page => {
|
|
151
|
+
// Published state
|
|
152
|
+
const snapshot = publishedSnapshotsByPagePersistentId.get(page.persistentId);
|
|
153
|
+
let publishedState: ItemState | undefined;
|
|
154
|
+
if (snapshot) {
|
|
155
|
+
publishedState = itemStateFromPage(snapshot.page, snapshot.pageContentHash);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Current state - if content hash is undefined, it means that the page hasn't changed
|
|
159
|
+
const currentPageContentHash = pageHashes[page.persistentId] ?? snapshot?.pageContentHash ?? "";
|
|
160
|
+
const currentState: ItemState = itemStateFromPage(page, currentPageContentHash);
|
|
161
|
+
|
|
162
|
+
// Calculate draft
|
|
163
|
+
const draftState = createDraftState(page.persistentId, currentState, publishedState, debug);
|
|
164
|
+
if (draftState) result.set(page.persistentId, draftState);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function itemStateFromPage(page: DocsPage, pageContentHash: string): ItemState {
|
|
171
|
+
return {
|
|
172
|
+
title: page.meta.name,
|
|
173
|
+
configuration: page.data.configuration ?? defaultDocumentationItemConfigurationV2,
|
|
174
|
+
contentHash: pageContentHash,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function buildPagePublishedMetadata(
|
|
179
|
+
pages: DocsPage[],
|
|
180
|
+
pageSnapshots: DocumentationPageSnapshot[]
|
|
181
|
+
): Map<string, DTODocumentationPublishMetadata> {
|
|
182
|
+
const publishedPageSnapshotsByPersistentId = mapByUnique(
|
|
183
|
+
pickLatestPageSnapshots(pageSnapshots.filter(s => s.reason === "Publish")),
|
|
184
|
+
s => s.page.persistentId
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
const result = new Map<string, DTODocumentationPublishMetadata>();
|
|
188
|
+
|
|
189
|
+
pages.forEach(p => {
|
|
190
|
+
const publishedSnapshot = publishedPageSnapshotsByPersistentId.get(p.persistentId);
|
|
191
|
+
if (!publishedSnapshot) return;
|
|
192
|
+
|
|
193
|
+
result.set(p.persistentId, {
|
|
194
|
+
lastPublishedAt: publishedSnapshot.createdAt,
|
|
195
|
+
lastPublishedByUserId: publishedSnapshot.createdByUserId,
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function createDraftState(
|
|
203
|
+
itemPersistentId: string,
|
|
204
|
+
currentState: ItemState,
|
|
205
|
+
publishedState: ItemState | undefined,
|
|
206
|
+
debug: boolean
|
|
207
|
+
): DTODocumentationDraftState | undefined {
|
|
208
|
+
if (!publishedState) {
|
|
209
|
+
// New item (hasn't been published yet)
|
|
210
|
+
return { changeType: "Created" };
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Compare current item state to the published state
|
|
214
|
+
const updatedDraftState: DTODocumentationDraftStateUpdated = {
|
|
215
|
+
changeType: "Updated",
|
|
216
|
+
changes: {},
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
if (currentState.title !== publishedState.title) {
|
|
220
|
+
if (debug) {
|
|
221
|
+
console.log(`Item ${itemPersistentId} (${currentState.title}): updated title`);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
updatedDraftState.changes.previousTitle = publishedState.title;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const currentConfigHash = generateHash(currentState.configuration, debug);
|
|
228
|
+
const publishedConfigHash = generateHash(publishedState.configuration, debug);
|
|
229
|
+
|
|
230
|
+
if (currentConfigHash !== publishedConfigHash) {
|
|
231
|
+
if (debug) {
|
|
232
|
+
console.log(`Item ${itemPersistentId} (${currentState.title}): updated configuration`);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const configurationDto = documentationItemConfigurationToDTOV2(publishedState.configuration);
|
|
236
|
+
updatedDraftState.changes.previousConfiguration = configurationDto;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (currentState.contentHash !== publishedState.contentHash) {
|
|
240
|
+
if (debug) {
|
|
241
|
+
console.log(`Item ${itemPersistentId} (${currentState.title}): updated content hash`);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
updatedDraftState.changes.previousContentHash = publishedState.contentHash;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (Object.keys(updatedDraftState.changes).length) {
|
|
248
|
+
// Item has at least one of the draft changes
|
|
249
|
+
return updatedDraftState;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Item has no draft changes compared to the published item
|
|
253
|
+
return undefined;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function buildGroupApprovalStates(groups: DocsPageGroup[], groupSnapshots: ElementGroupSnapshot[]) {
|
|
257
|
+
const result = new Map<string, DTODocumentationGroupApprovalState>();
|
|
258
|
+
const allGroups = [...groups, ...groupSnapshots];
|
|
259
|
+
for (const g of allGroups) {
|
|
260
|
+
const approvalState: DTODocumentationGroupApprovalState = {
|
|
261
|
+
approvalState: "Approved",
|
|
262
|
+
designSystemVersionId: g.designSystemVersionId,
|
|
263
|
+
persistentId: g.persistentId,
|
|
264
|
+
groupPersistentId: g.persistentId,
|
|
265
|
+
};
|
|
266
|
+
result.set(g.persistentId, approvalState);
|
|
267
|
+
}
|
|
268
|
+
return result;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function buildPageDraftDeletedStates(
|
|
272
|
+
pages: DocsPage[],
|
|
273
|
+
pageSnapshots: DocumentationPageSnapshot[]
|
|
274
|
+
): Map<string, DTODocumentationDraftState> {
|
|
275
|
+
const deletedSnapshotsByPagePersistentId = mapByUnique(
|
|
276
|
+
pickLatestPageSnapshots(pageSnapshots.filter(s => s.reason === "Deletion")),
|
|
277
|
+
s => s.page.persistentId
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
const result = new Map<string, DTODocumentationDraftState>();
|
|
281
|
+
|
|
282
|
+
pages.forEach(page => {
|
|
283
|
+
const deletedSnapshot = deletedSnapshotsByPagePersistentId.get(page.persistentId);
|
|
284
|
+
if (!deletedSnapshot) return;
|
|
285
|
+
|
|
286
|
+
result.set(page.persistentId, {
|
|
287
|
+
changeType: "Deleted",
|
|
288
|
+
deletedAt: deletedSnapshot.createdAt,
|
|
289
|
+
deletedByUserId: deletedSnapshot.createdByUserId,
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
return result;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function buildGroupDraftDeletedStates(
|
|
297
|
+
groups: DocsPageGroup[],
|
|
298
|
+
groupSnapshots: ElementGroupSnapshot[]
|
|
299
|
+
): Map<string, DTODocumentationDraftState> {
|
|
300
|
+
const deletedSnapshotsByGroupPersistentId = mapByUnique(
|
|
301
|
+
pickLatestGroupSnapshots(groupSnapshots.filter(s => s.reason === "Deletion")),
|
|
302
|
+
s => s.group.persistentId
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
const result = new Map<string, DTODocumentationDraftState>();
|
|
306
|
+
|
|
307
|
+
groups.forEach(group => {
|
|
308
|
+
if (!group.parentPersistentId) return;
|
|
309
|
+
|
|
310
|
+
const deletedSnapshot = deletedSnapshotsByGroupPersistentId.get(group.persistentId);
|
|
311
|
+
if (!deletedSnapshot) return;
|
|
312
|
+
|
|
313
|
+
result.set(group.persistentId, {
|
|
314
|
+
changeType: "Deleted",
|
|
315
|
+
deletedAt: deletedSnapshot.createdAt,
|
|
316
|
+
deletedByUserId: deletedSnapshot.createdByUserId,
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
return result;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function buildGroupDraftCreatedAndUpdatedStates(
|
|
324
|
+
groups: DocsPageGroup[],
|
|
325
|
+
groupSnapshots: ElementGroupSnapshot[],
|
|
326
|
+
debug: boolean
|
|
327
|
+
): Map<string, DTODocumentationDraftState> {
|
|
328
|
+
// Read room data
|
|
329
|
+
const publishedSnapshots = pickLatestGroupSnapshots(groupSnapshots.filter(s => s.reason === "Publish"));
|
|
330
|
+
const publishedSnapshotsByGroupPersistent = mapByUnique(publishedSnapshots, s => s.group.persistentId);
|
|
331
|
+
|
|
332
|
+
const result = new Map<string, DTODocumentationDraftState>();
|
|
333
|
+
|
|
334
|
+
groups.forEach(group => {
|
|
335
|
+
if (!group.parentPersistentId) return;
|
|
336
|
+
|
|
337
|
+
// Current state
|
|
338
|
+
const currentState: ItemState = itemStateFromGroup(group);
|
|
339
|
+
|
|
340
|
+
// Published state
|
|
341
|
+
const snapshot = publishedSnapshotsByGroupPersistent.get(group.persistentId);
|
|
342
|
+
let publishedState: ItemState | undefined;
|
|
343
|
+
if (snapshot) {
|
|
344
|
+
publishedState = itemStateFromGroup(snapshot.group);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Calculate draft
|
|
348
|
+
const draftState = createDraftState(group.persistentId, currentState, publishedState, debug);
|
|
349
|
+
if (draftState) result.set(group.persistentId, draftState);
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
return result;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function itemStateFromGroup(group: DocsPageGroup): ItemState {
|
|
356
|
+
return {
|
|
357
|
+
title: group.meta.name,
|
|
358
|
+
configuration: group.data?.configuration ?? defaultDocumentationItemConfigurationV2,
|
|
359
|
+
contentHash: "-",
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function buildGroupPublishedMetadata(
|
|
364
|
+
groups: DocsPageGroup[],
|
|
365
|
+
groupSnapshots: ElementGroupSnapshot[]
|
|
366
|
+
): Map<string, DTODocumentationPublishMetadata> {
|
|
367
|
+
const publishedGroupSnapshotsByPersistentId = mapByUnique(
|
|
368
|
+
pickLatestGroupSnapshots(groupSnapshots.filter(s => s.reason === "Publish")),
|
|
369
|
+
s => s.group.persistentId
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
const result = new Map<string, DTODocumentationPublishMetadata>();
|
|
373
|
+
|
|
374
|
+
groups.forEach(g => {
|
|
375
|
+
if (!g.parentPersistentId) return;
|
|
376
|
+
|
|
377
|
+
const publishedSnapshot = publishedGroupSnapshotsByPersistentId.get(g.persistentId);
|
|
378
|
+
if (!publishedSnapshot) return;
|
|
379
|
+
|
|
380
|
+
result.set(g.persistentId, {
|
|
381
|
+
lastPublishedAt: publishedSnapshot.createdAt,
|
|
382
|
+
lastPublishedByUserId: publishedSnapshot.createdByUserId,
|
|
383
|
+
});
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
return result;
|
|
387
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { PageBlockDefinition } from "@supernova-studio/model";
|
|
2
|
+
import * as Y from "yjs";
|
|
3
|
+
import { DTODocumentationHierarchyV2 } from "../../api";
|
|
4
|
+
import { DocumentationPageEditorModel } from "../docs-editor";
|
|
5
|
+
import { VersionRoomBaseYDoc } from "./base";
|
|
6
|
+
import { computeDocsHierarchy } from "./compute-dto";
|
|
7
|
+
import { generatePageContentHash } from "./utils";
|
|
8
|
+
|
|
9
|
+
export class FrontendVersionRoomYDoc {
|
|
10
|
+
private readonly yDoc: Y.Doc;
|
|
11
|
+
|
|
12
|
+
constructor(yDoc: Y.Doc, private readonly debug = false) {
|
|
13
|
+
this.yDoc = yDoc;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//
|
|
17
|
+
// Hierarchy
|
|
18
|
+
//
|
|
19
|
+
|
|
20
|
+
getDocumentationHierarchy(
|
|
21
|
+
options: { includeDeletedContent?: boolean; debug?: boolean } = {}
|
|
22
|
+
): DTODocumentationHierarchyV2 {
|
|
23
|
+
const doc = new VersionRoomBaseYDoc(this.yDoc);
|
|
24
|
+
return computeDocsHierarchy(doc.getState(), options);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
//
|
|
28
|
+
// Update page content hash
|
|
29
|
+
//
|
|
30
|
+
|
|
31
|
+
notifyDocumentationPageContentUpdated(
|
|
32
|
+
pageId: string,
|
|
33
|
+
content: DocumentationPageEditorModel,
|
|
34
|
+
definitions: PageBlockDefinition[]
|
|
35
|
+
) {
|
|
36
|
+
const pageContentHash = generatePageContentHash(content, definitions, this.debug);
|
|
37
|
+
if (this.debug) {
|
|
38
|
+
console.log(`Will set page content hash: '${pageId}' : '${pageContentHash}'`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
new VersionRoomBaseYDoc(this.yDoc).updateDocumentationPageContentHashes({
|
|
42
|
+
[pageId]: pageContentHash,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//
|
|
47
|
+
// Misc
|
|
48
|
+
//
|
|
49
|
+
|
|
50
|
+
isDraftFeatureAdopted() {
|
|
51
|
+
const doc = new VersionRoomBaseYDoc(this.yDoc);
|
|
52
|
+
const settings = doc.getDocumentationInternalSettings();
|
|
53
|
+
return settings.isDraftFeatureAdopted;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
hasPublishedDocumentationContent() {
|
|
57
|
+
const doc = new VersionRoomBaseYDoc(this.yDoc);
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
doc.getPageSnapshots().filter(s => s.reason === "Publish").length > 0 ||
|
|
61
|
+
doc.getGroupSnapshots().filter(s => s.reason === "Publish").length > 0
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
isApprovalsFeatureEnabled() {
|
|
66
|
+
const doc = new VersionRoomBaseYDoc(this.yDoc);
|
|
67
|
+
const settings = doc.getDocumentationInternalSettings();
|
|
68
|
+
return settings.isApprovalFeatureEnabled;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
isApprovalRequiredForPublishing() {
|
|
72
|
+
const doc = new VersionRoomBaseYDoc(this.yDoc);
|
|
73
|
+
const settings = doc.getDocumentationInternalSettings();
|
|
74
|
+
return settings.approvalRequiredForPublishing;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DocumentationPageApproval,
|
|
3
|
+
DocumentationPageSnapshot,
|
|
4
|
+
DocumentationPageV2,
|
|
5
|
+
ElementGroup,
|
|
6
|
+
ElementGroupSnapshot,
|
|
7
|
+
} from "@supernova-studio/model";
|
|
8
|
+
import { DocumentationHierarchySettings } from "../design-system-content";
|
|
9
|
+
|
|
10
|
+
export type VersionRoomDocsPage = DocumentationPageV2;
|
|
11
|
+
export type VersionRoomDocsPageGroup = ElementGroup;
|
|
12
|
+
export type VersionRoomApproval = DocumentationPageApproval;
|
|
13
|
+
|
|
14
|
+
export type VersionRoomBaseYDocState = {
|
|
15
|
+
isLoaded: boolean;
|
|
16
|
+
|
|
17
|
+
pages: VersionRoomDocsPage[];
|
|
18
|
+
pageSnapshots: DocumentationPageSnapshot[];
|
|
19
|
+
pageContentHashes: Record<string, string>;
|
|
20
|
+
pageLiveblockRoomIds: Record<string, string>;
|
|
21
|
+
|
|
22
|
+
groups: VersionRoomDocsPageGroup[];
|
|
23
|
+
groupSnapshots: ElementGroupSnapshot[];
|
|
24
|
+
|
|
25
|
+
approvals: DocumentationPageApproval[];
|
|
26
|
+
settings: DocumentationHierarchySettings;
|
|
27
|
+
|
|
28
|
+
executedTransactionIds: string[];
|
|
29
|
+
|
|
30
|
+
storageVersion: number;
|
|
31
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PageBlockDefinition,
|
|
3
|
+
PageBlockDefinitionsMap,
|
|
4
|
+
PageBlockItemMultiRichTextValue,
|
|
5
|
+
PageBlockItemRichTextValue,
|
|
6
|
+
PageBlockItemTableValue,
|
|
7
|
+
PageBlockText,
|
|
8
|
+
mapPageBlockItemValuesV2,
|
|
9
|
+
removeCommentSpans,
|
|
10
|
+
} from "@supernova-studio/model";
|
|
11
|
+
import { generateHash } from "../../utils";
|
|
12
|
+
import { DocumentationPageEditorModel } from "../docs-editor";
|
|
13
|
+
|
|
14
|
+
export function generatePageContentHash(
|
|
15
|
+
content: DocumentationPageEditorModel,
|
|
16
|
+
definitions: PageBlockDefinition[],
|
|
17
|
+
debug = false
|
|
18
|
+
) {
|
|
19
|
+
let sanitizedContent = structuredClone(content);
|
|
20
|
+
|
|
21
|
+
// Remove comment spans
|
|
22
|
+
sanitizedContent = sanitizePageContents(sanitizedContent, definitions);
|
|
23
|
+
|
|
24
|
+
// Make sure hashes of empty pages always match
|
|
25
|
+
if (isPageContentEmpty(sanitizedContent)) {
|
|
26
|
+
sanitizedContent = { blocks: [] };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return generateHash(sanitizedContent, debug);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Empty page content can be one of the following:
|
|
34
|
+
* - page without any blocks
|
|
35
|
+
* - page with a single block, the block is a paragraph whithout any text
|
|
36
|
+
*/
|
|
37
|
+
function isPageContentEmpty(content: DocumentationPageEditorModel): boolean {
|
|
38
|
+
if (content.blocks.length > 1) return false;
|
|
39
|
+
if (content.blocks.length < 1) return true;
|
|
40
|
+
|
|
41
|
+
const singleBlock = content.blocks[0];
|
|
42
|
+
if (singleBlock.type !== "Block" || singleBlock.data.packageId !== "io.supernova.block.rich-text") {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const singleItem = singleBlock.data.items[0];
|
|
47
|
+
|
|
48
|
+
// Block has no value, effectively the same as empty value
|
|
49
|
+
if (!singleItem || !singleItem.props["text"]) return true;
|
|
50
|
+
|
|
51
|
+
const textValue = singleItem.props["text"] as PageBlockItemRichTextValue;
|
|
52
|
+
return !textValue.value.spans.length;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function sanitizePageContents(
|
|
56
|
+
content: DocumentationPageEditorModel,
|
|
57
|
+
definitions: PageBlockDefinition[]
|
|
58
|
+
): DocumentationPageEditorModel {
|
|
59
|
+
const defMap = new PageBlockDefinitionsMap(definitions);
|
|
60
|
+
|
|
61
|
+
mapPageBlockItemValuesV2(content.blocks, defMap, (block, item, prop, value) => {
|
|
62
|
+
if (prop.type === "RichText") {
|
|
63
|
+
const richTextValue = value as PageBlockItemRichTextValue;
|
|
64
|
+
return {
|
|
65
|
+
...richTextValue,
|
|
66
|
+
value: sanitizeRichText(richTextValue.value),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (prop.type === "MultiRichText") {
|
|
71
|
+
const multiRichTextValue = value as PageBlockItemMultiRichTextValue;
|
|
72
|
+
return {
|
|
73
|
+
...multiRichTextValue,
|
|
74
|
+
value: multiRichTextValue.value.map(sanitizeRichText),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (prop.type === "Table") {
|
|
79
|
+
const tableValue = value as PageBlockItemTableValue;
|
|
80
|
+
tableValue.value.forEach(r => {
|
|
81
|
+
r.cells.forEach(c => {
|
|
82
|
+
c.nodes.forEach(n => {
|
|
83
|
+
if (n.type === "RichText") {
|
|
84
|
+
n.value = sanitizeRichText(n.value);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
return tableValue;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return value;
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
return content;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function sanitizeRichText(richText: PageBlockText): PageBlockText {
|
|
100
|
+
return sortSpanAttributes(removeCommentSpans(richText));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function sortSpanAttributes(richText: PageBlockText) {
|
|
104
|
+
richText.spans.forEach(s => {
|
|
105
|
+
s.attributes.sort((lhs, rhs) => lhs.type.localeCompare(rhs.type));
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
return richText;
|
|
109
|
+
}
|