@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.
Files changed (349) hide show
  1. package/dist/index.d.mts +101428 -143199
  2. package/dist/index.d.ts +101428 -143199
  3. package/dist/index.js +489 -99
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +5607 -5217
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +20 -9
  8. package/src/api/client.ts +62 -0
  9. package/src/api/conversion/analytics/index.ts +3 -0
  10. package/src/api/conversion/analytics/page-visits-to-comparison-dto.ts +65 -0
  11. package/src/api/conversion/analytics/page-visits-to-dto.ts +68 -0
  12. package/src/api/conversion/analytics/page-visits-to-heatmap-dto.ts +49 -0
  13. package/src/api/conversion/documentation/documentation-group-v1-to-dto.ts +114 -0
  14. package/src/api/conversion/documentation/documentation-group-v2-to-dto.ts +91 -0
  15. package/src/api/conversion/documentation/documentation-item-configuration-v1-to-dto.ts +52 -0
  16. package/src/api/conversion/documentation/documentation-item-configuration-v2-to-dto.ts +34 -0
  17. package/src/api/conversion/documentation/documentation-page-to-dto-utils.ts +134 -0
  18. package/src/api/conversion/documentation/documentation-page-v1-to-dto.ts +69 -0
  19. package/src/api/conversion/documentation/documentation-page-v2-to-dto.ts +84 -0
  20. package/src/api/conversion/documentation/documentation-settings-to-dto.ts +14 -0
  21. package/src/api/conversion/documentation/index.ts +8 -0
  22. package/src/api/conversion/export/index.ts +1 -0
  23. package/src/api/conversion/export/pipeline.ts +27 -0
  24. package/src/api/conversion/index.ts +4 -0
  25. package/src/api/conversion/integrations/git.ts +37 -0
  26. package/src/api/conversion/integrations/index.ts +2 -0
  27. package/src/api/conversion/integrations/integration.ts +37 -0
  28. package/src/api/dto/access-tokens/access-token.ts +45 -0
  29. package/src/api/dto/access-tokens/index.ts +1 -0
  30. package/src/api/dto/aux/color.ts +7 -0
  31. package/src/api/dto/aux/index.ts +4 -0
  32. package/src/api/dto/aux/meta.ts +8 -0
  33. package/src/api/dto/aux/object-metadata.ts +29 -0
  34. package/src/api/dto/aux/pagination.ts +8 -0
  35. package/src/api/dto/bff/app-bootstrap-data.ts +20 -0
  36. package/src/api/dto/bff/index.ts +1 -0
  37. package/src/api/dto/collections/index.ts +1 -0
  38. package/src/api/dto/collections/token-collection.ts +32 -0
  39. package/src/api/dto/design-systems/brand.ts +44 -0
  40. package/src/api/dto/design-systems/code-component-usage.ts +52 -0
  41. package/src/api/dto/design-systems/code-component.ts +101 -0
  42. package/src/api/dto/design-systems/code-history.ts +43 -0
  43. package/src/api/dto/design-systems/code-scan.ts +29 -0
  44. package/src/api/dto/design-systems/code-snapshots.ts +46 -0
  45. package/src/api/dto/design-systems/component.ts +40 -0
  46. package/src/api/dto/design-systems/contact.ts +11 -0
  47. package/src/api/dto/design-systems/data-source.ts +216 -0
  48. package/src/api/dto/design-systems/design-system.ts +75 -0
  49. package/src/api/dto/design-systems/documentation-search.ts +31 -0
  50. package/src/api/dto/design-systems/elements-diff.ts +14 -0
  51. package/src/api/dto/design-systems/figma-variables.ts +122 -0
  52. package/src/api/dto/design-systems/file.ts +71 -0
  53. package/src/api/dto/design-systems/import-job.ts +62 -0
  54. package/src/api/dto/design-systems/index.ts +24 -0
  55. package/src/api/dto/design-systems/members.ts +52 -0
  56. package/src/api/dto/design-systems/redirects.ts +33 -0
  57. package/src/api/dto/design-systems/role.ts +11 -0
  58. package/src/api/dto/design-systems/stats.ts +20 -0
  59. package/src/api/dto/design-systems/storybook.ts +45 -0
  60. package/src/api/dto/design-systems/user-design-systems.ts +10 -0
  61. package/src/api/dto/design-systems/version-room.ts +12 -0
  62. package/src/api/dto/design-systems/version.ts +56 -0
  63. package/src/api/dto/design-systems/view.ts +45 -0
  64. package/src/api/dto/design-tokens/design-token.ts +78 -0
  65. package/src/api/dto/design-tokens/index.ts +1 -0
  66. package/src/api/dto/documentation/analytics-v2.ts +80 -0
  67. package/src/api/dto/documentation/analytics.ts +32 -0
  68. package/src/api/dto/documentation/anchor.ts +15 -0
  69. package/src/api/dto/documentation/approvals.ts +21 -0
  70. package/src/api/dto/documentation/block-definition.ts +28 -0
  71. package/src/api/dto/documentation/block.ts +6 -0
  72. package/src/api/dto/documentation/documentation-page-snapshot.ts +18 -0
  73. package/src/api/dto/documentation/documentation.ts +34 -0
  74. package/src/api/dto/documentation/index.ts +11 -0
  75. package/src/api/dto/documentation/link-preview.ts +23 -0
  76. package/src/api/dto/documentation/publish.ts +23 -0
  77. package/src/api/dto/documentation/room.ts +12 -0
  78. package/src/api/dto/elements/components/figma-component-group.ts +19 -0
  79. package/src/api/dto/elements/components/figma-component.ts +56 -0
  80. package/src/api/dto/elements/components/index.ts +2 -0
  81. package/src/api/dto/elements/documentation/configuration.ts +20 -0
  82. package/src/api/dto/elements/documentation/draft-state.ts +37 -0
  83. package/src/api/dto/elements/documentation/group-action.ts +108 -0
  84. package/src/api/dto/elements/documentation/group-v1.ts +35 -0
  85. package/src/api/dto/elements/documentation/group-v2.ts +117 -0
  86. package/src/api/dto/elements/documentation/hierarchy.ts +25 -0
  87. package/src/api/dto/elements/documentation/index.ts +16 -0
  88. package/src/api/dto/elements/documentation/item-configuration-v1.ts +24 -0
  89. package/src/api/dto/elements/documentation/item-configuration-v2.ts +14 -0
  90. package/src/api/dto/elements/documentation/metadata.ts +8 -0
  91. package/src/api/dto/elements/documentation/page-actions-v2.ts +138 -0
  92. package/src/api/dto/elements/documentation/page-content.ts +15 -0
  93. package/src/api/dto/elements/documentation/page-dependencies.ts +30 -0
  94. package/src/api/dto/elements/documentation/page-v1.ts +21 -0
  95. package/src/api/dto/elements/documentation/page-v2.ts +132 -0
  96. package/src/api/dto/elements/documentation/settings.ts +9 -0
  97. package/src/api/dto/elements/documentation/structure.ts +37 -0
  98. package/src/api/dto/elements/elements-action-v2.ts +125 -0
  99. package/src/api/dto/elements/figma-nodes/figma-node-structure.ts +27 -0
  100. package/src/api/dto/elements/figma-nodes/figma-node-v1.ts +32 -0
  101. package/src/api/dto/elements/figma-nodes/figma-node-v2.ts +32 -0
  102. package/src/api/dto/elements/figma-nodes/figma-node.ts +103 -0
  103. package/src/api/dto/elements/figma-nodes/index.ts +5 -0
  104. package/src/api/dto/elements/figma-nodes/node-actions-v2.ts +25 -0
  105. package/src/api/dto/elements/frame-node-structures/frame-node-structure.ts +17 -0
  106. package/src/api/dto/elements/frame-node-structures/index.ts +1 -0
  107. package/src/api/dto/elements/get-elements-v2.ts +27 -0
  108. package/src/api/dto/elements/index.ts +7 -0
  109. package/src/api/dto/elements/properties/index.ts +2 -0
  110. package/src/api/dto/elements/properties/property-definitions.ts +75 -0
  111. package/src/api/dto/elements/properties/property-values.ts +50 -0
  112. package/src/api/dto/events/forge-project.ts +51 -0
  113. package/src/api/dto/events/index.ts +2 -0
  114. package/src/api/dto/events/workspace.ts +81 -0
  115. package/src/api/dto/export/exporter-property.ts +114 -0
  116. package/src/api/dto/export/exporter.ts +115 -0
  117. package/src/api/dto/export/filter.ts +20 -0
  118. package/src/api/dto/export/index.ts +5 -0
  119. package/src/api/dto/export/job.ts +114 -0
  120. package/src/api/dto/export/pipeline.ts +60 -0
  121. package/src/api/dto/figma-components/assets/download.ts +30 -0
  122. package/src/api/dto/figma-components/assets/index.ts +1 -0
  123. package/src/api/dto/figma-components/index.ts +1 -0
  124. package/src/api/dto/figma-exporter/figma-node.ts +11 -0
  125. package/src/api/dto/figma-exporter/index.ts +1 -0
  126. package/src/api/dto/files/files.ts +94 -0
  127. package/src/api/dto/files/index.ts +1 -0
  128. package/src/api/dto/forge/agent.ts +38 -0
  129. package/src/api/dto/forge/artifact.ts +94 -0
  130. package/src/api/dto/forge/feature-messages.ts +551 -0
  131. package/src/api/dto/forge/feature-room.ts +12 -0
  132. package/src/api/dto/forge/figma-node.ts +117 -0
  133. package/src/api/dto/forge/index.ts +28 -0
  134. package/src/api/dto/forge/iteration-message-old.ts +43 -0
  135. package/src/api/dto/forge/knowledge-item.ts +67 -0
  136. package/src/api/dto/forge/memory.ts +67 -0
  137. package/src/api/dto/forge/participant.ts +44 -0
  138. package/src/api/dto/forge/project-action.ts +123 -0
  139. package/src/api/dto/forge/project-artifact-room.ts +12 -0
  140. package/src/api/dto/forge/project-artifact.ts +85 -0
  141. package/src/api/dto/forge/project-context-feedback.ts +141 -0
  142. package/src/api/dto/forge/project-context-override.ts +41 -0
  143. package/src/api/dto/forge/project-context-scope.ts +23 -0
  144. package/src/api/dto/forge/project-context-v2.ts +228 -0
  145. package/src/api/dto/forge/project-context.ts +72 -0
  146. package/src/api/dto/forge/project-feature.ts +86 -0
  147. package/src/api/dto/forge/project-figma-node.ts +9 -0
  148. package/src/api/dto/forge/project-file.ts +48 -0
  149. package/src/api/dto/forge/project-invitation.ts +46 -0
  150. package/src/api/dto/forge/project-iteration-old.ts +54 -0
  151. package/src/api/dto/forge/project-member.ts +67 -0
  152. package/src/api/dto/forge/project-room.ts +12 -0
  153. package/src/api/dto/forge/project-section.ts +37 -0
  154. package/src/api/dto/forge/project.ts +105 -0
  155. package/src/api/dto/forge/relation.ts +34 -0
  156. package/src/api/dto/forge/threads.ts +153 -0
  157. package/src/api/dto/index.ts +25 -0
  158. package/src/api/dto/liveblocks/auth-response.ts +7 -0
  159. package/src/api/dto/liveblocks/index.ts +1 -0
  160. package/src/api/dto/mcp/index.ts +1 -0
  161. package/src/api/dto/mcp/stream.ts +17 -0
  162. package/src/api/dto/notifications/index.ts +2 -0
  163. package/src/api/dto/notifications/notifications.ts +65 -0
  164. package/src/api/dto/notifications/settings.ts +10 -0
  165. package/src/api/dto/portal/index.ts +1 -0
  166. package/src/api/dto/portal/portal-settings.ts +45 -0
  167. package/src/api/dto/sandboxes/index.ts +1 -0
  168. package/src/api/dto/sandboxes/template.ts +143 -0
  169. package/src/api/dto/storybook-sites/index.ts +1 -0
  170. package/src/api/dto/storybook-sites/storybook-sites.ts +60 -0
  171. package/src/api/dto/themes/index.ts +2 -0
  172. package/src/api/dto/themes/override.ts +27 -0
  173. package/src/api/dto/themes/theme.ts +53 -0
  174. package/src/api/dto/threads/index.ts +1 -0
  175. package/src/api/dto/threads/threads.ts +280 -0
  176. package/src/api/dto/trail-events/index.ts +1 -0
  177. package/src/api/dto/trail-events/trail-events.ts +172 -0
  178. package/src/api/dto/users/authenticated-user.ts +92 -0
  179. package/src/api/dto/users/index.ts +2 -0
  180. package/src/api/dto/users/user.ts +27 -0
  181. package/src/api/dto/workspaces/billing.ts +156 -0
  182. package/src/api/dto/workspaces/enums.ts +13 -0
  183. package/src/api/dto/workspaces/git.ts +32 -0
  184. package/src/api/dto/workspaces/index.ts +15 -0
  185. package/src/api/dto/workspaces/integrations.ts +34 -0
  186. package/src/api/dto/workspaces/invitations.ts +47 -0
  187. package/src/api/dto/workspaces/ip-whitelist.ts +33 -0
  188. package/src/api/dto/workspaces/knowledge-items-search.ts +37 -0
  189. package/src/api/dto/workspaces/login-screen.ts +42 -0
  190. package/src/api/dto/workspaces/membership.ts +55 -0
  191. package/src/api/dto/workspaces/npm-registry.ts +62 -0
  192. package/src/api/dto/workspaces/products.ts +45 -0
  193. package/src/api/dto/workspaces/subscription.ts +170 -0
  194. package/src/api/dto/workspaces/transfer-ownership.ts +7 -0
  195. package/src/api/dto/workspaces/untyped-data.ts +35 -0
  196. package/src/api/dto/workspaces/workspace.ts +49 -0
  197. package/src/api/endpoints/auth-tokens.ts +28 -0
  198. package/src/api/endpoints/codegen/codegen.ts +16 -0
  199. package/src/api/endpoints/codegen/ds-pipelines.ts +37 -0
  200. package/src/api/endpoints/codegen/exporters.ts +54 -0
  201. package/src/api/endpoints/codegen/index.ts +5 -0
  202. package/src/api/endpoints/codegen/jobs.ts +15 -0
  203. package/src/api/endpoints/codegen/pipelines.ts +55 -0
  204. package/src/api/endpoints/design-system/analytics.ts +14 -0
  205. package/src/api/endpoints/design-system/bff.ts +13 -0
  206. package/src/api/endpoints/design-system/code-snapshots.ts +47 -0
  207. package/src/api/endpoints/design-system/contact.ts +12 -0
  208. package/src/api/endpoints/design-system/design-systems.ts +90 -0
  209. package/src/api/endpoints/design-system/figma-node-structures.ts +20 -0
  210. package/src/api/endpoints/design-system/index.ts +11 -0
  211. package/src/api/endpoints/design-system/members.ts +24 -0
  212. package/src/api/endpoints/design-system/redirects.ts +46 -0
  213. package/src/api/endpoints/design-system/sources.ts +80 -0
  214. package/src/api/endpoints/design-system/storybook.ts +28 -0
  215. package/src/api/endpoints/design-system/versions/brands.ts +45 -0
  216. package/src/api/endpoints/design-system/versions/documentation.ts +107 -0
  217. package/src/api/endpoints/design-system/versions/ds-components.ts +30 -0
  218. package/src/api/endpoints/design-system/versions/elements-action.ts +65 -0
  219. package/src/api/endpoints/design-system/versions/elements.ts +27 -0
  220. package/src/api/endpoints/design-system/versions/figma-component-groups.ts +13 -0
  221. package/src/api/endpoints/design-system/versions/figma-components.ts +15 -0
  222. package/src/api/endpoints/design-system/versions/figma-frame-structures.ts +13 -0
  223. package/src/api/endpoints/design-system/versions/files.ts +43 -0
  224. package/src/api/endpoints/design-system/versions/import-jobs.ts +13 -0
  225. package/src/api/endpoints/design-system/versions/index.ts +19 -0
  226. package/src/api/endpoints/design-system/versions/overrides.ts +17 -0
  227. package/src/api/endpoints/design-system/versions/property-definitions.ts +43 -0
  228. package/src/api/endpoints/design-system/versions/property-values.ts +25 -0
  229. package/src/api/endpoints/design-system/versions/stats.ts +12 -0
  230. package/src/api/endpoints/design-system/versions/themes.ts +35 -0
  231. package/src/api/endpoints/design-system/versions/token-collections.ts +13 -0
  232. package/src/api/endpoints/design-system/versions/token-groups.ts +30 -0
  233. package/src/api/endpoints/design-system/versions/tokens.ts +29 -0
  234. package/src/api/endpoints/design-system/versions/versions.ts +90 -0
  235. package/src/api/endpoints/feedback.ts +60 -0
  236. package/src/api/endpoints/files.ts +25 -0
  237. package/src/api/endpoints/forge/agents.ts +54 -0
  238. package/src/api/endpoints/forge/artifacts.ts +54 -0
  239. package/src/api/endpoints/forge/documents.ts +18 -0
  240. package/src/api/endpoints/forge/feature-artifacts.ts +39 -0
  241. package/src/api/endpoints/forge/feature-iterations.ts +49 -0
  242. package/src/api/endpoints/forge/feature-messages.ts +68 -0
  243. package/src/api/endpoints/forge/features.ts +63 -0
  244. package/src/api/endpoints/forge/forge.ts +38 -0
  245. package/src/api/endpoints/forge/index.ts +16 -0
  246. package/src/api/endpoints/forge/iteration-tags.ts +13 -0
  247. package/src/api/endpoints/forge/memory.ts +41 -0
  248. package/src/api/endpoints/forge/project-contexts.ts +49 -0
  249. package/src/api/endpoints/forge/project-files.ts +41 -0
  250. package/src/api/endpoints/forge/project-invitations.ts +39 -0
  251. package/src/api/endpoints/forge/project-iterations.ts +65 -0
  252. package/src/api/endpoints/forge/project-members.ts +55 -0
  253. package/src/api/endpoints/forge/projects.ts +56 -0
  254. package/src/api/endpoints/index.ts +13 -0
  255. package/src/api/endpoints/liveblocks.ts +14 -0
  256. package/src/api/endpoints/mcp/index.ts +1 -0
  257. package/src/api/endpoints/mcp/streams.ts +21 -0
  258. package/src/api/endpoints/sandboxes/builds.ts +30 -0
  259. package/src/api/endpoints/sandboxes/index.ts +3 -0
  260. package/src/api/endpoints/sandboxes/sandboxes.ts +13 -0
  261. package/src/api/endpoints/sandboxes/templates.ts +16 -0
  262. package/src/api/endpoints/storybook-sites.ts +42 -0
  263. package/src/api/endpoints/threads.ts +38 -0
  264. package/src/api/endpoints/users.ts +26 -0
  265. package/src/api/endpoints/workspaces/billing.ts +24 -0
  266. package/src/api/endpoints/workspaces/chat-threads.ts +95 -0
  267. package/src/api/endpoints/workspaces/index.ts +9 -0
  268. package/src/api/endpoints/workspaces/integrations.ts +15 -0
  269. package/src/api/endpoints/workspaces/invites.ts +34 -0
  270. package/src/api/endpoints/workspaces/knowledge-items.ts +59 -0
  271. package/src/api/endpoints/workspaces/members.ts +31 -0
  272. package/src/api/endpoints/workspaces/npm-register.ts +20 -0
  273. package/src/api/endpoints/workspaces/subscription.ts +31 -0
  274. package/src/api/endpoints/workspaces/workspaces.ts +84 -0
  275. package/src/api/index.ts +6 -0
  276. package/src/api/payloads/design-systems/code-snapshots.ts +27 -0
  277. package/src/api/payloads/design-systems/index.ts +3 -0
  278. package/src/api/payloads/design-systems/update-design-system.ts +42 -0
  279. package/src/api/payloads/design-systems/version.ts +29 -0
  280. package/src/api/payloads/documentation/analytics.ts +36 -0
  281. package/src/api/payloads/documentation/block-definitions.ts +18 -0
  282. package/src/api/payloads/documentation/design-data-doc-diff.ts +7 -0
  283. package/src/api/payloads/documentation/index.ts +3 -0
  284. package/src/api/payloads/export/index.ts +1 -0
  285. package/src/api/payloads/export/pipeline.ts +111 -0
  286. package/src/api/payloads/index.ts +6 -0
  287. package/src/api/payloads/liveblocks/auth.ts +7 -0
  288. package/src/api/payloads/liveblocks/index.ts +1 -0
  289. package/src/api/payloads/users/index.ts +1 -0
  290. package/src/api/payloads/users/notifications/index.ts +1 -0
  291. package/src/api/payloads/users/notifications/notification-settings.ts +17 -0
  292. package/src/api/payloads/workspaces/index.ts +2 -0
  293. package/src/api/payloads/workspaces/workspace-configuration.ts +62 -0
  294. package/src/api/payloads/workspaces/workspace-integrations.ts +35 -0
  295. package/src/api/transport/index.ts +2 -0
  296. package/src/api/transport/request-executor-error.ts +60 -0
  297. package/src/api/transport/request-executor.ts +94 -0
  298. package/src/events/design-system.ts +21 -0
  299. package/src/events/event.ts +6 -0
  300. package/src/events/index.ts +2 -0
  301. package/src/index.ts +5 -0
  302. package/src/sync/docs-local-action-executor.ts +412 -0
  303. package/src/sync/docs-structure-repo.ts +283 -0
  304. package/src/sync/index.ts +5 -0
  305. package/src/sync/project-content-repo.ts +215 -0
  306. package/src/sync/project-local-action-executor.ts +415 -0
  307. package/src/sync/types.ts +37 -0
  308. package/src/utils/figma.ts +72 -0
  309. package/src/utils/hash.ts +62 -0
  310. package/src/utils/index.ts +4 -0
  311. package/src/utils/query.ts +41 -0
  312. package/src/utils/redirect-validation.ts +76 -0
  313. package/src/yjs/design-system-content/documentation-hierarchy.ts +35 -0
  314. package/src/yjs/design-system-content/index.ts +2 -0
  315. package/src/yjs/design-system-content/item-configuration.ts +62 -0
  316. package/src/yjs/docs-editor/blocks-to-prosemirror.ts +764 -0
  317. package/src/yjs/docs-editor/index.ts +7 -0
  318. package/src/yjs/docs-editor/list-tree-builder.ts +127 -0
  319. package/src/yjs/docs-editor/mock.ts +2271 -0
  320. package/src/yjs/docs-editor/model/block.ts +8 -0
  321. package/src/yjs/docs-editor/model/index.ts +2 -0
  322. package/src/yjs/docs-editor/model/page.ts +8 -0
  323. package/src/yjs/docs-editor/prosemirror/index.ts +3 -0
  324. package/src/yjs/docs-editor/prosemirror/inner-editor-schema.ts +145 -0
  325. package/src/yjs/docs-editor/prosemirror/main-editor-schema.ts +577 -0
  326. package/src/yjs/docs-editor/prosemirror/types.ts +19 -0
  327. package/src/yjs/docs-editor/prosemirror-to-blocks.ts +986 -0
  328. package/src/yjs/docs-editor/utils.ts +115 -0
  329. package/src/yjs/feature-room/backend.ts +36 -0
  330. package/src/yjs/feature-room/base.ts +109 -0
  331. package/src/yjs/feature-room/frontend.ts +53 -0
  332. package/src/yjs/feature-room/index.ts +3 -0
  333. package/src/yjs/forge-project-room/backend.ts +59 -0
  334. package/src/yjs/forge-project-room/base.ts +190 -0
  335. package/src/yjs/forge-project-room/index.ts +2 -0
  336. package/src/yjs/index.ts +7 -0
  337. package/src/yjs/thread-room/backend.ts +32 -0
  338. package/src/yjs/thread-room/base.ts +71 -0
  339. package/src/yjs/thread-room/frontend.ts +39 -0
  340. package/src/yjs/thread-room/index.ts +3 -0
  341. package/src/yjs/utils/index.ts +1 -0
  342. package/src/yjs/utils/key-value-storage.ts +57 -0
  343. package/src/yjs/version-room/backend.ts +101 -0
  344. package/src/yjs/version-room/base.ts +323 -0
  345. package/src/yjs/version-room/compute-dto.ts +387 -0
  346. package/src/yjs/version-room/frontend.ts +76 -0
  347. package/src/yjs/version-room/index.ts +6 -0
  348. package/src/yjs/version-room/types.ts +31 -0
  349. 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,6 @@
1
+ export * from "./backend";
2
+ export * from "./base";
3
+ export * from "./compute-dto";
4
+ export * from "./frontend";
5
+ export * from "./types";
6
+ export * from "./utils";
@@ -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
+ }