@supernova-studio/client 0.58.19 → 1.0.0-alpha.3

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 (196) hide show
  1. package/dist/index.d.mts +1363 -1321
  2. package/dist/index.d.ts +1363 -1321
  3. package/dist/index.js +536 -339
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +839 -642
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +4 -3
  8. package/src/api/client.ts +0 -31
  9. package/src/api/conversion/documentation/documentation-group-v1-to-dto.ts +0 -114
  10. package/src/api/conversion/documentation/documentation-group-v2-to-dto.ts +0 -92
  11. package/src/api/conversion/documentation/documentation-item-configuration-v1-to-dto.ts +0 -52
  12. package/src/api/conversion/documentation/documentation-item-configuration-v2-to-dto.ts +0 -34
  13. package/src/api/conversion/documentation/documentation-page-to-dto-utils.ts +0 -131
  14. package/src/api/conversion/documentation/documentation-page-v1-to-dto.ts +0 -69
  15. package/src/api/conversion/documentation/documentation-page-v2-to-dto.ts +0 -72
  16. package/src/api/conversion/documentation/index.ts +0 -7
  17. package/src/api/conversion/export/index.ts +0 -1
  18. package/src/api/conversion/export/pipeline.ts +0 -25
  19. package/src/api/conversion/index.ts +0 -3
  20. package/src/api/conversion/integrations/git.ts +0 -37
  21. package/src/api/conversion/integrations/index.ts +0 -2
  22. package/src/api/conversion/integrations/integration.ts +0 -37
  23. package/src/api/dto/aux/color.ts +0 -7
  24. package/src/api/dto/aux/index.ts +0 -3
  25. package/src/api/dto/aux/meta.ts +0 -8
  26. package/src/api/dto/aux/pagination.ts +0 -8
  27. package/src/api/dto/bff/app-bootstrap-data.ts +0 -20
  28. package/src/api/dto/bff/index.ts +0 -1
  29. package/src/api/dto/collections/index.ts +0 -1
  30. package/src/api/dto/collections/token-collection.ts +0 -24
  31. package/src/api/dto/design-systems/brand.ts +0 -44
  32. package/src/api/dto/design-systems/component.ts +0 -40
  33. package/src/api/dto/design-systems/contact.ts +0 -11
  34. package/src/api/dto/design-systems/data-source.ts +0 -141
  35. package/src/api/dto/design-systems/design-system.ts +0 -68
  36. package/src/api/dto/design-systems/elements-diff.ts +0 -14
  37. package/src/api/dto/design-systems/figma-variables.ts +0 -108
  38. package/src/api/dto/design-systems/import-job.ts +0 -61
  39. package/src/api/dto/design-systems/index.ts +0 -13
  40. package/src/api/dto/design-systems/members.ts +0 -50
  41. package/src/api/dto/design-systems/role.ts +0 -11
  42. package/src/api/dto/design-systems/stats.ts +0 -19
  43. package/src/api/dto/design-systems/version.ts +0 -56
  44. package/src/api/dto/design-systems/view.ts +0 -45
  45. package/src/api/dto/design-tokens/design-token.ts +0 -78
  46. package/src/api/dto/design-tokens/index.ts +0 -1
  47. package/src/api/dto/documentation/anchor.ts +0 -15
  48. package/src/api/dto/documentation/approvals.ts +0 -15
  49. package/src/api/dto/documentation/block-definition.ts +0 -28
  50. package/src/api/dto/documentation/block.ts +0 -6
  51. package/src/api/dto/documentation/documentation-page-snapshot.ts +0 -18
  52. package/src/api/dto/documentation/index.ts +0 -8
  53. package/src/api/dto/documentation/link-preview.ts +0 -23
  54. package/src/api/dto/documentation/publish.ts +0 -23
  55. package/src/api/dto/documentation/room.ts +0 -12
  56. package/src/api/dto/elements/components/figma-component-group.ts +0 -19
  57. package/src/api/dto/elements/components/figma-component.ts +0 -56
  58. package/src/api/dto/elements/components/index.ts +0 -2
  59. package/src/api/dto/elements/documentation/draft-state.ts +0 -37
  60. package/src/api/dto/elements/documentation/group-action.ts +0 -108
  61. package/src/api/dto/elements/documentation/group-v1.ts +0 -35
  62. package/src/api/dto/elements/documentation/group-v2.ts +0 -117
  63. package/src/api/dto/elements/documentation/hierarchy.ts +0 -22
  64. package/src/api/dto/elements/documentation/index.ts +0 -13
  65. package/src/api/dto/elements/documentation/item-configuration-v1.ts +0 -24
  66. package/src/api/dto/elements/documentation/item-configuration-v2.ts +0 -14
  67. package/src/api/dto/elements/documentation/metadata.ts +0 -8
  68. package/src/api/dto/elements/documentation/page-actions-v2.ts +0 -121
  69. package/src/api/dto/elements/documentation/page-content.ts +0 -15
  70. package/src/api/dto/elements/documentation/page-v1.ts +0 -21
  71. package/src/api/dto/elements/documentation/page-v2.ts +0 -120
  72. package/src/api/dto/elements/documentation/structure.ts +0 -37
  73. package/src/api/dto/elements/elements-action-v2.ts +0 -104
  74. package/src/api/dto/elements/figma-nodes/figma-node.ts +0 -106
  75. package/src/api/dto/elements/figma-nodes/index.ts +0 -2
  76. package/src/api/dto/elements/figma-nodes/node-actions-v2.ts +0 -24
  77. package/src/api/dto/elements/frame-node-structures/frame-node-structure.ts +0 -17
  78. package/src/api/dto/elements/frame-node-structures/index.ts +0 -1
  79. package/src/api/dto/elements/get-elements-v2.ts +0 -21
  80. package/src/api/dto/elements/index.ts +0 -7
  81. package/src/api/dto/elements/properties/index.ts +0 -2
  82. package/src/api/dto/elements/properties/property-definitions.ts +0 -75
  83. package/src/api/dto/elements/properties/property-values.ts +0 -38
  84. package/src/api/dto/export/exporter-property.ts +0 -95
  85. package/src/api/dto/export/exporter.ts +0 -87
  86. package/src/api/dto/export/filter.ts +0 -6
  87. package/src/api/dto/export/index.ts +0 -5
  88. package/src/api/dto/export/job.ts +0 -87
  89. package/src/api/dto/export/pipeline.ts +0 -43
  90. package/src/api/dto/figma-components/assets/download.ts +0 -30
  91. package/src/api/dto/figma-components/assets/index.ts +0 -1
  92. package/src/api/dto/figma-components/index.ts +0 -1
  93. package/src/api/dto/index.ts +0 -13
  94. package/src/api/dto/liveblocks/auth-response.ts +0 -7
  95. package/src/api/dto/liveblocks/index.ts +0 -1
  96. package/src/api/dto/themes/index.ts +0 -2
  97. package/src/api/dto/themes/override.ts +0 -27
  98. package/src/api/dto/themes/theme.ts +0 -45
  99. package/src/api/dto/users/authenticated-user.ts +0 -43
  100. package/src/api/dto/users/index.ts +0 -3
  101. package/src/api/dto/users/update.ts +0 -8
  102. package/src/api/dto/users/user.ts +0 -31
  103. package/src/api/dto/workspaces/git.ts +0 -32
  104. package/src/api/dto/workspaces/index.ts +0 -6
  105. package/src/api/dto/workspaces/integrations.ts +0 -34
  106. package/src/api/dto/workspaces/invitations.ts +0 -30
  107. package/src/api/dto/workspaces/membership.ts +0 -41
  108. package/src/api/dto/workspaces/npm-registry.ts +0 -35
  109. package/src/api/dto/workspaces/workspace.ts +0 -34
  110. package/src/api/endpoints/codegen/codegen.ts +0 -13
  111. package/src/api/endpoints/codegen/exporters.ts +0 -13
  112. package/src/api/endpoints/codegen/index.ts +0 -3
  113. package/src/api/endpoints/codegen/pipelines.ts +0 -37
  114. package/src/api/endpoints/design-system/bff.ts +0 -13
  115. package/src/api/endpoints/design-system/contact.ts +0 -12
  116. package/src/api/endpoints/design-system/design-systems.ts +0 -55
  117. package/src/api/endpoints/design-system/index.ts +0 -6
  118. package/src/api/endpoints/design-system/members.ts +0 -24
  119. package/src/api/endpoints/design-system/sources.ts +0 -35
  120. package/src/api/endpoints/design-system/versions/brands.ts +0 -45
  121. package/src/api/endpoints/design-system/versions/documentation.ts +0 -27
  122. package/src/api/endpoints/design-system/versions/ds-components.ts +0 -28
  123. package/src/api/endpoints/design-system/versions/elements-action.ts +0 -55
  124. package/src/api/endpoints/design-system/versions/elements.ts +0 -13
  125. package/src/api/endpoints/design-system/versions/figma-component-groups.ts +0 -13
  126. package/src/api/endpoints/design-system/versions/figma-components.ts +0 -13
  127. package/src/api/endpoints/design-system/versions/figma-frame-structures.ts +0 -13
  128. package/src/api/endpoints/design-system/versions/import-jobs.ts +0 -13
  129. package/src/api/endpoints/design-system/versions/index.ts +0 -18
  130. package/src/api/endpoints/design-system/versions/overrides.ts +0 -17
  131. package/src/api/endpoints/design-system/versions/property-definitions.ts +0 -43
  132. package/src/api/endpoints/design-system/versions/property-values.ts +0 -25
  133. package/src/api/endpoints/design-system/versions/stats.ts +0 -12
  134. package/src/api/endpoints/design-system/versions/themes.ts +0 -35
  135. package/src/api/endpoints/design-system/versions/token-collections.ts +0 -13
  136. package/src/api/endpoints/design-system/versions/token-groups.ts +0 -28
  137. package/src/api/endpoints/design-system/versions/tokens.ts +0 -27
  138. package/src/api/endpoints/design-system/versions/versions.ts +0 -79
  139. package/src/api/endpoints/index.ts +0 -5
  140. package/src/api/endpoints/liveblocks.ts +0 -14
  141. package/src/api/endpoints/users.ts +0 -26
  142. package/src/api/endpoints/workspaces/index.ts +0 -3
  143. package/src/api/endpoints/workspaces/workspace-invites.ts +0 -34
  144. package/src/api/endpoints/workspaces/workspace-members.ts +0 -31
  145. package/src/api/endpoints/workspaces/workspaces.ts +0 -47
  146. package/src/api/index.ts +0 -6
  147. package/src/api/payloads/design-systems/index.ts +0 -2
  148. package/src/api/payloads/design-systems/update-design-system.ts +0 -29
  149. package/src/api/payloads/design-systems/version.ts +0 -29
  150. package/src/api/payloads/documentation/block-definitions.ts +0 -12
  151. package/src/api/payloads/documentation/design-data-doc-diff.ts +0 -7
  152. package/src/api/payloads/documentation/index.ts +0 -2
  153. package/src/api/payloads/export/index.ts +0 -1
  154. package/src/api/payloads/export/pipeline.ts +0 -50
  155. package/src/api/payloads/index.ts +0 -6
  156. package/src/api/payloads/liveblocks/auth.ts +0 -7
  157. package/src/api/payloads/liveblocks/index.ts +0 -1
  158. package/src/api/payloads/users/index.ts +0 -2
  159. package/src/api/payloads/users/notifications/index.ts +0 -1
  160. package/src/api/payloads/users/notifications/notification-settings.ts +0 -17
  161. package/src/api/payloads/users/profile/index.ts +0 -1
  162. package/src/api/payloads/users/profile/update.ts +0 -4
  163. package/src/api/payloads/workspaces/index.ts +0 -3
  164. package/src/api/payloads/workspaces/transfer-ownership.ts +0 -7
  165. package/src/api/payloads/workspaces/workspace-configuration.ts +0 -50
  166. package/src/api/payloads/workspaces/workspace-integrations.ts +0 -26
  167. package/src/api/transport/index.ts +0 -2
  168. package/src/api/transport/request-executor-error.ts +0 -66
  169. package/src/api/transport/request-executor.ts +0 -87
  170. package/src/index.ts +0 -3
  171. package/src/utils/figma.ts +0 -53
  172. package/src/utils/hash.ts +0 -62
  173. package/src/utils/index.ts +0 -3
  174. package/src/utils/query.ts +0 -18
  175. package/src/yjs/design-system-content/documentation-hierarchy.ts +0 -35
  176. package/src/yjs/design-system-content/index.ts +0 -2
  177. package/src/yjs/design-system-content/item-configuration.ts +0 -93
  178. package/src/yjs/docs-editor/blocks-to-prosemirror.ts +0 -764
  179. package/src/yjs/docs-editor/index.ts +0 -7
  180. package/src/yjs/docs-editor/list-tree-builder.ts +0 -127
  181. package/src/yjs/docs-editor/mock.ts +0 -2104
  182. package/src/yjs/docs-editor/model/block.ts +0 -8
  183. package/src/yjs/docs-editor/model/index.ts +0 -2
  184. package/src/yjs/docs-editor/model/page.ts +0 -8
  185. package/src/yjs/docs-editor/prosemirror/index.ts +0 -3
  186. package/src/yjs/docs-editor/prosemirror/inner-editor-schema.ts +0 -145
  187. package/src/yjs/docs-editor/prosemirror/main-editor-schema.ts +0 -577
  188. package/src/yjs/docs-editor/prosemirror/types.ts +0 -19
  189. package/src/yjs/docs-editor/prosemirror-to-blocks.ts +0 -975
  190. package/src/yjs/docs-editor/utils.ts +0 -115
  191. package/src/yjs/index.ts +0 -3
  192. package/src/yjs/version-room/backend.ts +0 -78
  193. package/src/yjs/version-room/base.ts +0 -211
  194. package/src/yjs/version-room/frontend.ts +0 -461
  195. package/src/yjs/version-room/index.ts +0 -4
  196. package/src/yjs/version-room/utils.ts +0 -109
@@ -1,975 +0,0 @@
1
- import {
2
- PageBlockAppearanceV2,
3
- PageBlockCalloutType,
4
- PageBlockColorV2,
5
- PageBlockDefinition,
6
- PageBlockDefinitionProperty,
7
- PageBlockDefinitionPropertyType,
8
- PageBlockItemAssetPropertyValue,
9
- PageBlockItemAssetValue,
10
- PageBlockItemBooleanValue,
11
- PageBlockItemCodeValue,
12
- PageBlockItemColorValue,
13
- PageBlockItemComponentPropertyValue,
14
- PageBlockItemComponentValue,
15
- PageBlockItemDividerValue,
16
- PageBlockItemEmbedValue,
17
- PageBlockItemFigmaComponentValue,
18
- PageBlockItemFigmaNodeValue,
19
- PageBlockItemImageValue,
20
- PageBlockItemMarkdownValue,
21
- PageBlockItemMultiRichTextValue,
22
- PageBlockItemMultiSelectValue,
23
- PageBlockItemNumberValue,
24
- PageBlockItemRichTextEditorListNode,
25
- PageBlockItemRichTextEditorNode,
26
- PageBlockItemRichTextEditorParagraphNode,
27
- PageBlockItemRichTextEditorValue,
28
- PageBlockItemRichTextValue,
29
- PageBlockItemSandboxValue,
30
- PageBlockItemSingleSelectValue,
31
- PageBlockItemStorybookValue,
32
- PageBlockItemTableCell,
33
- PageBlockItemTableNode,
34
- PageBlockItemTableValue,
35
- PageBlockItemTextValue,
36
- PageBlockItemTokenPropertyValue,
37
- PageBlockItemTokenTypeValue,
38
- PageBlockItemTokenValue,
39
- PageBlockItemUntypedValue,
40
- PageBlockItemUrlValue,
41
- PageBlockItemV2,
42
- PageBlockTableCellAlignment,
43
- PageBlockText,
44
- PageBlockTextSpan,
45
- PageBlockTextSpanAttribute,
46
- PageSectionColumnV2,
47
- PageSectionItemV2,
48
- nullishToOptional,
49
- } from "@supernova-studio/model";
50
- import { yXmlFragmentToProsemirrorJSON } from "y-prosemirror";
51
- import * as Y from "yjs";
52
- import { ZodSchema, ZodTypeDef, z } from "zod";
53
- import { PageBlockEditorModel, PageSectionEditorModel } from "./model/block";
54
- import { DocumentationPageEditorModel } from "./model/page";
55
- import { ProsemirrorMark, ProsemirrorNode } from "./prosemirror/types";
56
- import { BlockDefinitionUtils } from "./utils";
57
-
58
- export function yDocToPage(yDoc: Y.Doc, definitions: PageBlockDefinition[]): DocumentationPageEditorModel {
59
- return yXmlFragmentToPage(yDoc.getXmlFragment("default"), definitions);
60
- }
61
-
62
- export function yXmlFragmentToPage(
63
- fragment: Y.XmlFragment,
64
- definitions: PageBlockDefinition[]
65
- ): DocumentationPageEditorModel {
66
- const prosemirrorJson = yXmlFragmentToProsemirrorJSON(fragment) as ProsemirrorNode;
67
- return prosemirrorDocToPage(prosemirrorJson, definitions);
68
- }
69
-
70
- export function prosemirrorDocToPage(
71
- prosemirrorDoc: ProsemirrorNode,
72
- definitions: PageBlockDefinition[]
73
- ): DocumentationPageEditorModel {
74
- const definitionsById = mapByUnique(definitions, d => d.id);
75
-
76
- return {
77
- blocks: internalProsemirrorNodesToPageItems(prosemirrorDoc.content ?? [], definitionsById),
78
- };
79
- }
80
-
81
- export function shallowProsemirrorNodeToBlock(
82
- prosemirrorNode: ProsemirrorNode,
83
- definition: PageBlockDefinition
84
- ): PageBlockEditorModel | null {
85
- return (
86
- prosemirrorNodeAndDefinitionToBlock(prosemirrorNode, definition, new Map([[definition.id, definition]]), 0)[0] ??
87
- null
88
- );
89
- }
90
-
91
- export function prosemirrorDocToRichTextPropertyValue(
92
- prosemirrorNode: ProsemirrorNode
93
- ): PageBlockItemRichTextEditorValue {
94
- return {
95
- value: (prosemirrorNode.content ?? [])
96
- .map(n => prosemirrorNodeToRichTextEditorPropertyNode(n))
97
- .filter(nonNullFilter),
98
- };
99
- }
100
-
101
- function prosemirrorNodeToRichTextEditorPropertyNode(
102
- prosemirrorNode: ProsemirrorNode
103
- ): PageBlockItemRichTextEditorNode | null {
104
- switch (prosemirrorNode.type) {
105
- case "paragraph":
106
- return parseAsParagraphNode(prosemirrorNode);
107
-
108
- case "orderedList":
109
- case "bulletList":
110
- return parseAsListNode(prosemirrorNode);
111
-
112
- default:
113
- return null;
114
- }
115
- }
116
-
117
- function parseAsParagraphNode(prosemirrorNode: ProsemirrorNode): PageBlockItemRichTextEditorParagraphNode {
118
- return {
119
- type: "Paragraph",
120
- value: parseRichText(prosemirrorNode.content ?? []),
121
- };
122
- }
123
-
124
- function parseAsListNode(prosemirrorNode: ProsemirrorNode): PageBlockItemRichTextEditorListNode {
125
- return {
126
- type: "List",
127
- listType: prosemirrorNode.type === "orderedList" ? "OL" : "UL",
128
- value: (prosemirrorNode.content ?? []).map(parseAsListNodeItem).filter(nonNullFilter),
129
- };
130
- }
131
-
132
- function parseAsListNodeItem(prosemirrorNode: ProsemirrorNode): PageBlockText | null {
133
- if (prosemirrorNode.type !== "listItem") return null;
134
-
135
- const firstChild = prosemirrorNode.content?.[0];
136
- if (!firstChild || firstChild.type !== "paragraph") return null;
137
-
138
- return parseRichText(firstChild.content ?? []);
139
- }
140
-
141
- //
142
- // Sections
143
- //
144
-
145
- export function prosemirrorNodeToSection(
146
- prosemirrorNode: ProsemirrorNode,
147
- definitions: PageBlockDefinition[]
148
- ): PageSectionEditorModel | null {
149
- const definitionsById = mapByUnique(definitions, d => d.id);
150
- return internalProsemirrorNodeToSection(prosemirrorNode, definitionsById);
151
- }
152
-
153
- function internalProsemirrorNodeToSection(
154
- prosemirrorNode: ProsemirrorNode,
155
- definitionsMap: Map<string, PageBlockDefinition>
156
- ): PageSectionEditorModel | null {
157
- const id = getProsemirrorBlockId(prosemirrorNode);
158
- if (!id) return null;
159
-
160
- return {
161
- id: id,
162
- type: "Section",
163
- variantId: getProsemirrorBlockVariantId(prosemirrorNode),
164
- sectionType: "Tabs",
165
- appearance: {
166
- contentExpandToEdges: true,
167
- expandToEdges: true,
168
- },
169
- items: (prosemirrorNode.content ?? [])
170
- .filter(c => c.type === "sectionItem")
171
- .map(c => prosemirrorNodeToSectionItem(c, definitionsMap))
172
- .filter(nonNullFilter),
173
- };
174
- }
175
-
176
- function prosemirrorNodeToSectionItem(
177
- prosemirrorNode: ProsemirrorNode,
178
- definitionsMap: Map<string, PageBlockDefinition>
179
- ): PageSectionItemV2 | null {
180
- const id = getProsemirrorBlockId(prosemirrorNode);
181
- if (!id) return null;
182
-
183
- return {
184
- id: id,
185
- title: getProsemirrorAttribute(prosemirrorNode, "title", z.string()) ?? "",
186
- columns: (prosemirrorNode.content ?? [])
187
- .filter(c => c.type === "sectionItemColumn")
188
- .map(c => prosemirrorNodeToSectionColumns(c, definitionsMap))
189
- .filter(nonNullFilter),
190
- };
191
- }
192
-
193
- function prosemirrorNodeToSectionColumns(
194
- prosemirrorNode: ProsemirrorNode,
195
- definitionsMap: Map<string, PageBlockDefinition>
196
- ): PageSectionColumnV2 | null {
197
- const id = getProsemirrorBlockId(prosemirrorNode);
198
- if (!id) return null;
199
-
200
- return {
201
- id: id,
202
- blocks: internalProsemirrorNodesToBlocks(prosemirrorNode.content ?? [], definitionsMap, 0),
203
- };
204
- }
205
-
206
- //
207
- // Blocks
208
- //
209
-
210
- export function prosemirrorNodesToBlocks(prosemirrorNodes: ProsemirrorNode[], definitions: PageBlockDefinition[]) {
211
- const definitionsById = mapByUnique(definitions, d => d.id);
212
- return internalProsemirrorNodesToBlocks(prosemirrorNodes, definitionsById, 0);
213
- }
214
-
215
- function internalProsemirrorNodesToPageItems(
216
- prosemirrorNodes: ProsemirrorNode[],
217
- definitionsMap: Map<string, PageBlockDefinition>
218
- ): (PageBlockEditorModel | PageSectionEditorModel)[] {
219
- const result: (PageBlockEditorModel | PageSectionEditorModel)[] = [];
220
-
221
- for (const prosemirrorNode of prosemirrorNodes) {
222
- if (prosemirrorNode.type === "tabsSection") {
223
- // Section
224
- const section = prosemirrorNodeToSection(prosemirrorNode, Array.from(definitionsMap.values()));
225
- section && result.push(section);
226
- } else {
227
- // Block
228
- result.push(...internalProsemirrorNodeToBlock(prosemirrorNode, definitionsMap, 0));
229
- }
230
- }
231
-
232
- return result;
233
- }
234
-
235
- function internalProsemirrorNodesToBlocks(
236
- prosemirrorNodes: ProsemirrorNode[],
237
- definitionsMap: Map<string, PageBlockDefinition>,
238
- depth: number
239
- ): PageBlockEditorModel[] {
240
- return prosemirrorNodes.flatMap(prosemirrorNode => {
241
- return internalProsemirrorNodeToBlock(prosemirrorNode, definitionsMap, depth);
242
- });
243
- }
244
-
245
- function internalProsemirrorNodeToBlock(
246
- prosemirrorNode: ProsemirrorNode,
247
- definitionsMap: Map<string, PageBlockDefinition>,
248
- depth: number
249
- ): PageBlockEditorModel[] {
250
- const definitionId = getProsemirrorAttribute(prosemirrorNode, "definitionId", z.string());
251
- if (!definitionId) {
252
- console.warn(`definitionId on ${prosemirrorNode.type} is required to be interpreted as a block, skipping node`);
253
-
254
- return [];
255
- }
256
-
257
- const definition = definitionsMap.get(definitionId);
258
- if (!definition) {
259
- console.warn(
260
- `Block definitionId "${definitionId}" (prosemirror node ${prosemirrorNode.type}) is not among available definitions`
261
- );
262
- console.warn(prosemirrorNode);
263
- return [];
264
- }
265
-
266
- return prosemirrorNodeAndDefinitionToBlock(prosemirrorNode, definition, definitionsMap, depth);
267
- }
268
-
269
- function prosemirrorNodeAndDefinitionToBlock(
270
- prosemirrorNode: ProsemirrorNode,
271
- definition: PageBlockDefinition,
272
- definitionsMap: Map<string, PageBlockDefinition>,
273
- depth: number
274
- ): PageBlockEditorModel[] {
275
- const multiRichTextProperty = BlockDefinitionUtils.firstMultiRichTextProperty(definition);
276
- if (multiRichTextProperty) {
277
- return parseAsMultiRichText(prosemirrorNode, definition, multiRichTextProperty, definitionsMap, depth);
278
- }
279
-
280
- const block = shallowProsemirrorNodeAndDefinitionToBlock(prosemirrorNode, definition);
281
- return block ? [block] : [];
282
- }
283
-
284
- function shallowProsemirrorNodeAndDefinitionToBlock(
285
- prosemirrorNode: ProsemirrorNode,
286
- definition: PageBlockDefinition
287
- ): PageBlockEditorModel | null {
288
- const richTextProperty = BlockDefinitionUtils.firstRichTextProperty(definition);
289
- if (richTextProperty) {
290
- return parseAsRichText(prosemirrorNode, definition, richTextProperty);
291
- }
292
-
293
- const tableProperty = BlockDefinitionUtils.firstTableProperty(definition);
294
- if (tableProperty) {
295
- return parseAsTable(prosemirrorNode, definition, tableProperty);
296
- }
297
-
298
- if (definition.id === "io.supernova.block.divider") {
299
- return parseAsDivider(prosemirrorNode, definition);
300
- }
301
-
302
- return parseAsCustomBlock(prosemirrorNode, definition);
303
- }
304
-
305
- //
306
- // Single rich text
307
- //
308
-
309
- function parseAsRichText(
310
- prosemirrorNode: ProsemirrorNode,
311
- definition: PageBlockDefinition,
312
- property: PageBlockDefinitionProperty
313
- ): PageBlockEditorModel | null {
314
- const id = getProsemirrorBlockId(prosemirrorNode);
315
- if (!id) return null;
316
-
317
- const variantId = getProsemirrorBlockVariantId(prosemirrorNode);
318
- const calloutType = parseCalloutType(getProsemirrorAttribute(prosemirrorNode, "type", z.string().optional()));
319
-
320
- return {
321
- id: id,
322
- type: "Block",
323
-
324
- data: {
325
- packageId: definition.id,
326
- indentLevel: 0,
327
- ...(variantId && { variantId: variantId }),
328
- items: [
329
- {
330
- id: id,
331
- props: {
332
- [property.id]: {
333
- // Required
334
- value: parseRichText(prosemirrorNode.content ?? []),
335
-
336
- // Optional
337
- ...(calloutType && { calloutType: calloutType }),
338
- } satisfies PageBlockItemRichTextValue,
339
- },
340
- },
341
- ],
342
- },
343
- };
344
- }
345
-
346
- function parseCalloutType(prosemirrorCalloutType: unknown): PageBlockCalloutType | undefined {
347
- if (!prosemirrorCalloutType) return undefined;
348
-
349
- switch (prosemirrorCalloutType) {
350
- case "critical":
351
- return "Error";
352
- case "neutral":
353
- return "Info";
354
- case "positive":
355
- return "Success";
356
- case "warning":
357
- return "Warning";
358
- case "primary":
359
- return "Primary";
360
- }
361
- }
362
-
363
- //
364
- // Multi rich text
365
- //
366
-
367
- function parseAsMultiRichText(
368
- prosemirrorNode: ProsemirrorNode,
369
- definition: PageBlockDefinition,
370
- property: PageBlockDefinitionProperty,
371
- definitionsMap: Map<string, PageBlockDefinition>,
372
- depth: number
373
- ): PageBlockEditorModel[] {
374
- const id = getProsemirrorBlockId(prosemirrorNode);
375
- if (!id) return [];
376
-
377
- const variantId = getProsemirrorBlockVariantId(prosemirrorNode);
378
- const result: PageBlockEditorModel[] = [];
379
-
380
- // Flatten items
381
- const listItems: ProsemirrorNode[] = [];
382
- prosemirrorNode.content?.forEach(c => {
383
- // Illegal child of a list
384
- if (c.type !== "listItem") return;
385
-
386
- c.content?.forEach(cc => {
387
- listItems.push(cc);
388
- });
389
- });
390
-
391
- // Text list items buffering
392
- let bufferedTextItems: ProsemirrorNode[] = [];
393
- function flushBufferedTextItems() {
394
- if (!bufferedTextItems.length) return;
395
-
396
- const idSuffix = result.length ? `-${result.length}` : "";
397
-
398
- result.push({
399
- id: id + idSuffix,
400
- type: "Block",
401
- data: {
402
- packageId: definition.id,
403
- indentLevel: depth,
404
- ...(variantId && { variantId: variantId }),
405
- items: [
406
- {
407
- id: id + idSuffix,
408
- props: {
409
- [property.id]: {
410
- value: bufferedTextItems.map(paragraph => {
411
- return parseRichText(paragraph.content ?? []);
412
- }),
413
- } satisfies PageBlockItemMultiRichTextValue,
414
- },
415
- },
416
- ],
417
- },
418
- });
419
-
420
- bufferedTextItems = [];
421
- }
422
-
423
- listItems.forEach(item => {
424
- if (item.type === "paragraph") {
425
- bufferedTextItems.push(item);
426
- return;
427
- }
428
-
429
- // This is not a paragraph, flush text items first
430
- flushBufferedTextItems();
431
-
432
- result.push(...internalProsemirrorNodeToBlock(item, definitionsMap, depth + 1));
433
- });
434
-
435
- // Flush text items at the end
436
- flushBufferedTextItems();
437
-
438
- return result;
439
- }
440
-
441
- //
442
- // Rich text
443
- //
444
-
445
- function parseRichText(spans: ProsemirrorNode[]): PageBlockText {
446
- return {
447
- spans: spans.map(parseRichTextSpan).filter(nonNullFilter),
448
- };
449
- }
450
-
451
- function parseRichTextSpan(span: ProsemirrorNode): PageBlockTextSpan | null {
452
- if (span.type === "hardBreak") {
453
- return { text: "\n", attributes: [] };
454
- }
455
-
456
- if (span.type !== "text" || !span.text) return null;
457
-
458
- const marks = span.marks ?? [];
459
-
460
- return {
461
- text: span.text,
462
- attributes: marks.map(parseRichTextAttribute).filter(nonNullFilter),
463
- };
464
- }
465
-
466
- function parseRichTextAttribute(mark: ProsemirrorMark): PageBlockTextSpanAttribute | null {
467
- switch (mark.type) {
468
- case "bold":
469
- return { type: "Bold" };
470
- case "italic":
471
- return { type: "Italic" };
472
- case "strike":
473
- return { type: "Strikethrough" };
474
- case "code":
475
- return { type: "Code" };
476
- case "link":
477
- return parseProsemirrorLink(mark);
478
- case "commentHighlight":
479
- return parseProsemirrorCommentHighlight(mark);
480
- }
481
-
482
- return null;
483
- }
484
-
485
- function parseProsemirrorLink(mark: ProsemirrorMark): PageBlockTextSpanAttribute | null {
486
- const href = getProsemirrorAttribute(mark, "href", z.string().optional());
487
- if (!href) return null;
488
-
489
- const target = getProsemirrorAttribute(mark, "target", z.string().optional());
490
- const openInNewTab = target === "_blank";
491
-
492
- if (href.startsWith("@")) {
493
- return {
494
- type: "Link",
495
- openInNewWindow: openInNewTab,
496
- openInNewTab: openInNewTab,
497
- documentationItemId: href.split(":")[1],
498
- };
499
- } else {
500
- return {
501
- type: "Link",
502
- openInNewWindow: openInNewTab,
503
- openInNewTab: openInNewTab,
504
- link: href,
505
- };
506
- }
507
- }
508
-
509
- function parseProsemirrorCommentHighlight(mark: ProsemirrorMark): PageBlockTextSpanAttribute | null {
510
- const highlightId = getProsemirrorAttribute(mark, "highlightId", z.string().optional());
511
- if (!highlightId) return null;
512
-
513
- const isResolved = getProsemirrorAttribute(mark, "resolved", z.boolean().optional()) ?? false;
514
-
515
- return {
516
- type: "Comment",
517
- commentHighlightId: highlightId,
518
- commentIsResolved: isResolved,
519
- };
520
- }
521
-
522
- //
523
- // Embed
524
- //
525
-
526
- function parseAsTable(
527
- prosemirrorNode: ProsemirrorNode,
528
- definition: PageBlockDefinition,
529
- property: PageBlockDefinitionProperty
530
- ): PageBlockEditorModel | null {
531
- const id = getProsemirrorBlockId(prosemirrorNode);
532
- if (!id) return null;
533
-
534
- const variantId = getProsemirrorBlockVariantId(prosemirrorNode);
535
- const hasBorder = getProsemirrorAttribute(prosemirrorNode, "hasBorder", z.boolean().optional()) !== false;
536
-
537
- const tableChild = prosemirrorNode.content?.find(c => c.type === "table");
538
- if (!tableChild) {
539
- return emptyTable(id, variantId, 0);
540
- }
541
-
542
- // Nodes can are considered rows if they have correct node type + their content is non-empty
543
- const rows = tableChild.content?.filter(c => c.type === "tableRow" && !!c.content?.length) ?? [];
544
- if (!rows.length) {
545
- return emptyTable(id, variantId, 0);
546
- }
547
-
548
- const rowHeaderCells = rows[0].content?.filter(c => c.type === "tableHeader").length ?? 0;
549
- const columnHeaderCells = rows.filter(r => r.content?.[0]?.type === "tableHeader").length;
550
-
551
- const hasHeaderRow = rows[0].content?.length === rowHeaderCells;
552
- const hasHeaderColumn = rows.length === columnHeaderCells;
553
-
554
- const tableValue: PageBlockItemTableValue = {
555
- showBorder: hasBorder,
556
- highlightHeaderRow: hasHeaderRow,
557
- highlightHeaderColumn: hasHeaderColumn,
558
- value: [],
559
- };
560
-
561
- tableValue.value = rows.map(row => {
562
- return {
563
- cells: (row.content ?? []).map(parseAsTableCell).filter(nonNullFilter),
564
- };
565
- });
566
-
567
- return {
568
- id: id,
569
- type: "Block",
570
- data: {
571
- packageId: "io.supernova.block.table",
572
- indentLevel: 0,
573
- variantId: "default",
574
-
575
- ...(variantId && { variantId: variantId }),
576
-
577
- items: [
578
- {
579
- id: id,
580
- props: {
581
- table: tableValue,
582
- },
583
- },
584
- ],
585
- },
586
- };
587
- }
588
-
589
- function parseAsTableCell(prosemirrorNode: ProsemirrorNode): PageBlockItemTableCell | null {
590
- const id = getProsemirrorBlockId(prosemirrorNode);
591
- if (!id) return null;
592
-
593
- const textAlign = getProsemirrorAttribute(prosemirrorNode, "textAlign", z.string().optional());
594
-
595
- let columnWidth: number | undefined;
596
- const columnWidthArray = getProsemirrorAttribute(prosemirrorNode, "colwidth", z.array(z.number()).nullish());
597
- if (columnWidthArray) {
598
- columnWidth = roundDimension(columnWidthArray[0]);
599
- }
600
-
601
- const tableNodes = (prosemirrorNode.content ?? []).map(parseAsTableNode).filter(nonNullFilter);
602
-
603
- return {
604
- id: id,
605
- alignment: parseTableCellAlignment(textAlign),
606
- ...(columnWidth && { columnWidth }),
607
- nodes: tableNodes.length ? tableNodes : emptyTableCellContent(),
608
- };
609
- }
610
-
611
- function parseTableCellAlignment(alignment: unknown): PageBlockTableCellAlignment {
612
- if (!alignment) return "Left";
613
-
614
- switch (alignment) {
615
- case "left":
616
- return "Left";
617
- case "center":
618
- return "Center";
619
- case "right":
620
- return "Right";
621
-
622
- default:
623
- return "Left";
624
- }
625
- }
626
-
627
- function parseAsTableNode(prosemirrorNode: ProsemirrorNode): PageBlockItemTableNode | null {
628
- const id = getProsemirrorBlockId(prosemirrorNode);
629
- if (!id) return null;
630
-
631
- switch (prosemirrorNode.type) {
632
- case "paragraph":
633
- return {
634
- type: "RichText",
635
- id: id,
636
- value: parseRichText(prosemirrorNode.content ?? []),
637
- };
638
-
639
- case "image":
640
- const items = getProsemirrorAttribute(prosemirrorNode, "items", z.string());
641
- if (!items) return null;
642
-
643
- const parsedItems = PageBlockItemV2.array().safeParse(JSON.parse(items));
644
- if (!parsedItems.success) return null;
645
-
646
- const rawImagePropertyValue = parsedItems.data[0]?.props.image;
647
- if (!rawImagePropertyValue) return null;
648
-
649
- const imagePropertyValueParseResult = PageBlockItemImageValue.safeParse(rawImagePropertyValue);
650
- if (!imagePropertyValueParseResult.success) return null;
651
-
652
- const { value, caption, alt, alignment } = imagePropertyValueParseResult.data;
653
-
654
- return {
655
- type: "Image",
656
- id,
657
- value,
658
- ...(alt && { alt }),
659
- ...(caption && { caption }),
660
- ...(alignment && { alignment }),
661
- };
662
-
663
- default:
664
- return null;
665
- }
666
- }
667
-
668
- function emptyTable(id: string, variantId?: string, indentLevel?: number): PageBlockEditorModel {
669
- const tableValue: PageBlockItemTableValue = {
670
- showBorder: true,
671
- highlightHeaderColumn: false,
672
- highlightHeaderRow: false,
673
- value: [],
674
- };
675
-
676
- for (let i = 0; i < 2; i++) {
677
- tableValue.value.push({
678
- cells: [],
679
- });
680
-
681
- for (let j = 0; j < 3; j++) {
682
- tableValue.value[i].cells.push({
683
- id: "",
684
- alignment: "Left",
685
- nodes: emptyTableCellContent(),
686
- });
687
- }
688
- }
689
-
690
- return {
691
- id: id,
692
- type: "Block",
693
- data: {
694
- packageId: "io.supernova.block.table",
695
- indentLevel: indentLevel ?? 0,
696
- variantId: variantId,
697
- items: [
698
- {
699
- id: id,
700
- props: {
701
- table: tableValue,
702
- },
703
- },
704
- ],
705
- },
706
- };
707
- }
708
-
709
- function emptyTableCellContent(): PageBlockItemTableNode[] {
710
- return [
711
- {
712
- type: "RichText",
713
- id: "",
714
- value: { spans: [] },
715
- },
716
- ];
717
- }
718
-
719
- //
720
- // Divider
721
- //
722
-
723
- function parseAsDivider(
724
- prosemirrorNode: ProsemirrorNode,
725
- definition: PageBlockDefinition
726
- ): PageBlockEditorModel | null {
727
- const id = getProsemirrorBlockId(prosemirrorNode);
728
- if (!id) return null;
729
-
730
- const variantId = getProsemirrorBlockVariantId(prosemirrorNode);
731
-
732
- return {
733
- id: id,
734
- type: "Block",
735
- data: {
736
- packageId: definition.id,
737
- indentLevel: 0,
738
-
739
- ...(variantId && { variantId: variantId }),
740
-
741
- items: [{ id: id, props: {} }],
742
- },
743
- };
744
- }
745
-
746
- //
747
- // Custom block
748
- //
749
-
750
- function parseAsCustomBlock(
751
- prosemirrorNode: ProsemirrorNode,
752
- definition: PageBlockDefinition
753
- ): PageBlockEditorModel | null {
754
- const id = getProsemirrorBlockId(prosemirrorNode);
755
- if (!id) return null;
756
-
757
- const variantId = getProsemirrorBlockVariantId(prosemirrorNode);
758
-
759
- const appearance = parseAppearance(prosemirrorNode);
760
-
761
- const parsedItems = parseBlockItems(prosemirrorNode, definition) ?? [];
762
-
763
- // Some blocks can expect at least one item to be always present. In such case we fallback to an item
764
- // without any properties defined which should be a valid item for any combination of block settings.
765
- if (!parsedItems.length && definitionExpectsPlaceholderItem(definition)) {
766
- parsedItems.push({
767
- id: id,
768
- props: {},
769
- });
770
- }
771
-
772
- return {
773
- id: id,
774
- type: "Block",
775
- data: {
776
- packageId: definition.id,
777
- indentLevel: 0,
778
-
779
- ...(variantId && { variantId: variantId }),
780
- ...(appearance && { appearance: appearance }),
781
-
782
- items: parsedItems,
783
- },
784
- };
785
- }
786
-
787
- function definitionExpectsPlaceholderItem(definition: PageBlockDefinition): boolean {
788
- return (
789
- // Block needs an item when it's a data block (tokens, components, etc)
790
- !definition.behavior.items ||
791
- // Block needs an item when number of items is expected to be 1
792
- definition.behavior.items.numberOfItems === 1
793
- );
794
- }
795
-
796
- function parseBlockItems(prosemirrorNode: ProsemirrorNode, definition: PageBlockDefinition): PageBlockItemV2[] | null {
797
- const itemsString = getProsemirrorAttribute(prosemirrorNode, "items", z.string());
798
- if (!itemsString) return null;
799
-
800
- const itemsJson: unknown = JSON.parse(itemsString);
801
- if (!Array.isArray(itemsJson)) {
802
- console.error("Block `items` property must be a json array");
803
- return null;
804
- }
805
-
806
- return itemsJson.map(i => parseItem(i, definition)).filter(nonNullFilter);
807
- }
808
-
809
- function parseAppearance(prosemirrorNode: ProsemirrorNode): PageBlockAppearanceV2 | undefined {
810
- let appearance: PageBlockAppearanceV2 = {};
811
-
812
- const rawAppearanceString = getProsemirrorAttribute(prosemirrorNode, "appearance", z.string().optional());
813
- if (rawAppearanceString) {
814
- const parsedAppearance = PageBlockAppearanceV2.safeParse(JSON.parse(rawAppearanceString));
815
- if (parsedAppearance.success) {
816
- appearance = parsedAppearance.data;
817
- }
818
- }
819
-
820
- const columns = getProsemirrorAttribute(prosemirrorNode, "columns", z.number().optional());
821
- if (columns) {
822
- appearance.numberOfColumns = columns;
823
- }
824
-
825
- const backgroundColor = getProsemirrorAttribute(prosemirrorNode, "backgroundColor", z.string().optional());
826
- if (backgroundColor) {
827
- const parsedColor = PageBlockColorV2.safeParse(JSON.parse(backgroundColor));
828
- if (parsedColor.success) {
829
- appearance.itemBackgroundColor = parsedColor.data;
830
- }
831
- }
832
-
833
- if (!Object.keys(appearance).length) return undefined;
834
-
835
- return appearance;
836
- }
837
-
838
- function parseItem(rawItem: unknown, definition: PageBlockDefinition): PageBlockItemV2 | null {
839
- const parsedItem = PageBlockItemV2.safeParse(rawItem);
840
- if (!parsedItem.success) {
841
- return null;
842
- }
843
-
844
- const sanitizedProps: Record<string, PageBlockItemUntypedValue> = {};
845
-
846
- for (const property of definition.item.properties) {
847
- const value = parsedItem.data.props[property.id];
848
- if (!value) {
849
- continue;
850
- }
851
-
852
- const valueSchema = valueSchemaForPropertyType(property.type);
853
- const validationResult = valueSchema.safeParse(value);
854
-
855
- if (validationResult.success) {
856
- sanitizedProps[property.id] = validationResult.data;
857
- } else {
858
- console.log(validationResult.error.toString());
859
- }
860
- }
861
-
862
- return {
863
- id: parsedItem.data.id,
864
- ...(parsedItem.data.linksTo && { linksTo: parsedItem.data.linksTo }),
865
- props: sanitizedProps,
866
- };
867
- }
868
-
869
- function valueSchemaForPropertyType(type: PageBlockDefinitionPropertyType) {
870
- switch (type) {
871
- case "RichText":
872
- return PageBlockItemRichTextValue;
873
- case "MultiRichText":
874
- return PageBlockItemMultiRichTextValue;
875
- case "Text":
876
- return PageBlockItemTextValue;
877
- case "Boolean":
878
- return PageBlockItemBooleanValue;
879
- case "Number":
880
- return PageBlockItemNumberValue;
881
- case "SingleSelect":
882
- return PageBlockItemSingleSelectValue;
883
- case "MultiSelect":
884
- return PageBlockItemMultiSelectValue;
885
- case "Image":
886
- return PageBlockItemImageValue;
887
- case "Token":
888
- return PageBlockItemTokenValue;
889
- case "TokenType":
890
- return PageBlockItemTokenTypeValue;
891
- case "TokenProperty":
892
- return PageBlockItemTokenPropertyValue;
893
- case "Component":
894
- return PageBlockItemComponentValue;
895
- case "ComponentProperty":
896
- return PageBlockItemComponentPropertyValue;
897
- case "Asset":
898
- return PageBlockItemAssetValue;
899
- case "AssetProperty":
900
- return PageBlockItemAssetPropertyValue;
901
- case "FigmaNode":
902
- return PageBlockItemFigmaNodeValue;
903
- case "EmbedURL":
904
- return PageBlockItemEmbedValue;
905
- case "URL":
906
- return PageBlockItemUrlValue;
907
- case "Markdown":
908
- return PageBlockItemMarkdownValue;
909
- case "Code":
910
- return PageBlockItemCodeValue;
911
- case "CodeSandbox":
912
- return PageBlockItemSandboxValue;
913
- case "Table":
914
- return PageBlockItemTableValue;
915
- case "Divider":
916
- return PageBlockItemDividerValue;
917
- case "Storybook":
918
- return PageBlockItemStorybookValue;
919
- case "Color":
920
- return PageBlockItemColorValue;
921
- case "FigmaComponent":
922
- return PageBlockItemFigmaComponentValue;
923
- case "RichTextEditor":
924
- return PageBlockItemRichTextEditorValue;
925
- }
926
- }
927
-
928
- //
929
- // Attributes
930
- //
931
-
932
- function getProsemirrorBlockId(prosemirrorNode: ProsemirrorNode): string | undefined {
933
- const id = getProsemirrorAttribute(prosemirrorNode, "id", z.string());
934
- if (!id) console.warn(`Prosemirror attribute "id" on ${prosemirrorNode.type} is required`);
935
- return id;
936
- }
937
-
938
- function getProsemirrorBlockVariantId(prosemirrorNode: ProsemirrorNode): string | undefined {
939
- return getProsemirrorAttribute(prosemirrorNode, "variantId", nullishToOptional(z.string()));
940
- }
941
-
942
- function getProsemirrorAttribute<I, O>(
943
- prosemirrorNode: ProsemirrorNode,
944
- attributeName: string,
945
- validationSchema: ZodSchema<O, ZodTypeDef, I>
946
- ): O | undefined {
947
- const parsedAttr = validationSchema.safeParse(prosemirrorNode.attrs?.[attributeName]);
948
- if (parsedAttr.success) {
949
- return parsedAttr.data;
950
- } else {
951
- console.warn(`Prosemirror attribute ${attributeName} on ${prosemirrorNode.type} is invalid`);
952
- console.warn(parsedAttr.error.flatten());
953
- return undefined;
954
- }
955
- }
956
-
957
- //
958
- // Utils
959
- //
960
-
961
- function nonNullFilter<T>(item: T | null): item is T {
962
- return item !== null;
963
- }
964
-
965
- function mapByUnique<V, K>(items: V[], keyFn: (item: V) => K): Map<K, V> {
966
- const result = new Map<K, V>();
967
- for (const item of items) {
968
- result.set(keyFn(item), item);
969
- }
970
- return result;
971
- }
972
-
973
- function roundDimension(dimension: number) {
974
- return Math.round(dimension * 100) / 100;
975
- }