@supernova-studio/client 0.48.13 → 0.48.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supernova-studio/client",
3
- "version": "0.48.13",
3
+ "version": "0.48.14",
4
4
  "description": "Supernova Data Models",
5
5
  "source": "src/index.ts",
6
6
  "main": "dist/index.js",
@@ -18,6 +18,8 @@ export const DTODocumentationDraftStateUpdated = z.object({
18
18
 
19
19
  export const DTODocumentationDraftStateDeleted = z.object({
20
20
  changeType: z.literal(DTODocumentationDraftChangeType.enum.Deleted),
21
+ deletedAt: z.coerce.date(),
22
+ deletedByUserId: z.string(),
21
23
  });
22
24
 
23
25
  export const DTODocumentationDraftState = z.discriminatedUnion("changeType", [
@@ -2,6 +2,7 @@ import { DocumentationGroupBehavior, ElementGroup } from "@supernova-studio/mode
2
2
  import { z } from "zod";
3
3
  import { DTODocumentationDraftState } from "./draft-state";
4
4
  import { DTODocumentationItemConfigurationV2 } from "./item-configuration-v2";
5
+ import { DTODocumentationPublishMetadata } from "./metadata";
5
6
 
6
7
  //
7
8
  // Read
@@ -26,6 +27,9 @@ export const DTODocumentationGroupV2 = ElementGroup.omit({
26
27
 
27
28
  /** Defined when a group has changed since last publish and can be included into a partial publish */
28
29
  draftState: DTODocumentationDraftState.optional(),
30
+
31
+ /** Defined if a group was published at least once and contains metadata about last publish */
32
+ publishMetadata: DTODocumentationPublishMetadata.optional(),
29
33
  });
30
34
 
31
35
  export type DTODocumentationGroupV2 = z.infer<typeof DTODocumentationGroupV2>;
@@ -17,20 +17,6 @@ export const DTODocumentationHierarchyV2 = z.object({
17
17
  draftState: DTODocumentationDraftState.optional(),
18
18
  })
19
19
  ),
20
-
21
- deletedPages: z.array(
22
- DTODocumentationPageV2.extend({
23
- /** Deleted page is always a draft change */
24
- draftState: DTODocumentationDraftState,
25
- })
26
- ),
27
-
28
- deletedGroups: z.array(
29
- DTODocumentationGroupV2.extend({
30
- /** Deleted page is always a draft change */
31
- draftState: DTODocumentationDraftState,
32
- })
33
- ),
34
20
  });
35
21
 
36
22
  export type DTODocumentationHierarchyV2 = z.infer<typeof DTODocumentationHierarchyV2>;
@@ -5,6 +5,7 @@ export * from "./group-v2";
5
5
  export * from "./hierarchy";
6
6
  export * from "./item-configuration-v1";
7
7
  export * from "./item-configuration-v2";
8
+ export * from "./metadata";
8
9
  export * from "./page-actions-v2";
9
10
  export * from "./page-content";
10
11
  export * from "./page-v1";
@@ -0,0 +1,8 @@
1
+ import { z } from "zod";
2
+
3
+ export const DTODocumentationPublishMetadata = z.object({
4
+ lastPublishedByUserId: z.string(),
5
+ lastPublishedAt: z.coerce.date(),
6
+ });
7
+
8
+ export type DTODocumentationPublishMetadata = z.infer<typeof DTODocumentationPublishMetadata>;
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { DTODocumentationDraftState } from "./draft-state";
3
3
  import { DTODocumentationItemConfigurationV2 } from "./item-configuration-v2";
4
+ import { DTODocumentationPublishMetadata } from "./metadata";
4
5
 
5
6
  //
6
7
  // Read
@@ -28,6 +29,9 @@ export const DTODocumentationPageV2 = z.object({
28
29
  /** Defined when a page has changed since last publish and can be included into a partial publish */
29
30
  draftState: DTODocumentationDraftState.optional(),
30
31
 
32
+ /** Defined if a page was published at least once and contains metadata about last publish */
33
+ publishMetadata: DTODocumentationPublishMetadata.optional(),
34
+
31
35
  // Backward compatibility
32
36
  type: z.literal("Page"),
33
37
  });
@@ -6,6 +6,8 @@ import {
6
6
  ElementGroupSnapshot,
7
7
  defaultDocumentationItemConfigurationV2,
8
8
  mapByUnique,
9
+ pickLatestGroupSnapshots,
10
+ pickLatestPageSnapshots,
9
11
  } from "@supernova-studio/model";
10
12
  import * as Y from "yjs";
11
13
  import {
@@ -16,6 +18,7 @@ import {
16
18
  documentationPagesToDTOV2,
17
19
  elementGroupsToDocumentationGroupDTOV2,
18
20
  } from "../../api";
21
+ import { DTODocumentationPublishMetadata } from "../../api/dto/elements/documentation/metadata";
19
22
  import { generateHash } from "../../utils";
20
23
  import { DocumentationPageEditorModel } from "../docs-editor";
21
24
  import { VersionRoomBaseYDoc } from "./base";
@@ -38,7 +41,9 @@ export class FrontendVersionRoomYDoc {
38
41
  // Hierarchy
39
42
  //
40
43
 
41
- getDocumentationHierarchy(): DTODocumentationHierarchyV2 {
44
+ getDocumentationHierarchy(options: { includeDeletedContent?: boolean } = {}): DTODocumentationHierarchyV2 {
45
+ const { includeDeletedContent } = options;
46
+
42
47
  const doc = new VersionRoomBaseYDoc(this.yDoc);
43
48
 
44
49
  // Read current room data
@@ -58,59 +63,68 @@ export class FrontendVersionRoomYDoc {
58
63
  return {
59
64
  pages: pageDTOs,
60
65
  groups: groupDTOs,
61
- deletedGroups: [],
62
- deletedPages: [],
63
66
  };
64
67
  }
65
68
 
66
69
  const pageDraftStates = this.buildPageDraftStates(pages, pageSnapshots);
70
+ const pagePublishedMetadata = this.buildPagePublishedMetadata(pages, pageSnapshots);
71
+
67
72
  pageDTOs.forEach(p => {
73
+ // Assign draft state
68
74
  const draftState = pageDraftStates.get(p.id);
69
75
  draftState && (p.draftState = draftState);
76
+
77
+ // Assign publish metadata
78
+ const publishMetadata = pagePublishedMetadata.get(p.id);
79
+ publishMetadata && (p.publishMetadata = publishMetadata);
70
80
  });
71
81
 
72
82
  const groupDraftStates = this.buildGroupDraftStates(groups, groupSnapshots);
83
+ const groupPublishedMetadata = this.buildGroupPublishedMetadata(groups, groupSnapshots);
84
+
73
85
  groupDTOs.forEach(g => {
86
+ // Assign draft state
74
87
  const draftState = groupDraftStates.get(g.id);
75
88
  draftState && (g.draftState = draftState);
76
- });
77
89
 
78
- // Read deleted pages
79
- const pageIds = new Set(pages.map(p => p.id));
80
- const deletedPagesMap = mapByUnique(
81
- pageSnapshots.filter(s => !pageIds.has(s.page.id)).map(s => s.page),
82
- p => p.id
83
- );
84
- const deletedPages = Array.from(deletedPagesMap.values());
85
-
86
- // Read deleted groups
87
- const groupIds = new Set(groups.map(p => p.id));
88
- const deletedGroupsMap = mapByUnique(
89
- groupSnapshots.filter(s => !groupIds.has(s.group.id)).map(s => s.group),
90
- g => g.id
91
- );
92
- const deletedGroups = Array.from(deletedGroupsMap.values());
93
-
94
- // Convert deleted pages to DTOs with draft states
95
- const deletedPageDTOs = documentationPagesToDTOV2(
96
- deletedPages,
97
- [...groups, ...deletedGroups],
98
- settings.routingVersion
99
- ).map(p => {
100
- return { ...p, draftState: { changeType: "Deleted" } } as const;
90
+ // Assign publish metadata
91
+ const publishMetadata = groupPublishedMetadata.get(g.id);
92
+ publishMetadata && (g.publishMetadata = publishMetadata);
101
93
  });
102
94
 
103
- // Convert deleted groups to DTOs with draft states
104
- const deletedGroupDTOs = elementGroupsToDocumentationGroupDTOV2(deletedGroups, deletedPages).map(g => {
105
- return { ...g, draftState: { changeType: "Deleted" } } as const;
106
- });
95
+ // // Read deleted pages
96
+ // const pageIds = new Set(pages.map(p => p.id));
97
+ // const deletedPagesMap = mapByUnique(
98
+ // pageSnapshots.filter(s => !pageIds.has(s.page.id)).map(s => s.page),
99
+ // p => p.id
100
+ // );
101
+ // const deletedPages = Array.from(deletedPagesMap.values());
102
+
103
+ // // Read deleted groups
104
+ // const groupIds = new Set(groups.map(p => p.id));
105
+ // const deletedGroupsMap = mapByUnique(
106
+ // groupSnapshots.filter(s => !groupIds.has(s.group.id)).map(s => s.group),
107
+ // g => g.id
108
+ // );
109
+ // const deletedGroups = Array.from(deletedGroupsMap.values());
110
+
111
+ // // Convert deleted pages to DTOs with draft states
112
+ // const deletedPageDTOs = documentationPagesToDTOV2(
113
+ // deletedPages,
114
+ // [...groups, ...deletedGroups],
115
+ // settings.routingVersion
116
+ // ).map(p => {
117
+ // return { ...p, draftState: { changeType: "Deleted" } } as const;
118
+ // });
119
+
120
+ // // Convert deleted groups to DTOs with draft states
121
+ // const deletedGroupDTOs = elementGroupsToDocumentationGroupDTOV2(deletedGroups, deletedPages).map(g => {
122
+ // return { ...g, draftState: { changeType: "Deleted" } } as const;
123
+ // });
107
124
 
108
125
  return {
109
126
  pages: pageDTOs,
110
127
  groups: groupDTOs,
111
-
112
- deletedPages: deletedPageDTOs,
113
- deletedGroups: deletedGroupDTOs,
114
128
  };
115
129
  }
116
130
 
@@ -157,6 +171,54 @@ export class FrontendVersionRoomYDoc {
157
171
  return result;
158
172
  }
159
173
 
174
+ private buildPagePublishedMetadata(
175
+ pages: DocumentationPageV2[],
176
+ pageSnapshots: DocumentationPageSnapshot[]
177
+ ): Map<string, DTODocumentationPublishMetadata> {
178
+ const publishedPageSnapshotsById = mapByUnique(
179
+ pickLatestPageSnapshots(pageSnapshots.filter(s => s.reason === "Publish")),
180
+ s => s.page.id
181
+ );
182
+
183
+ const result = new Map<string, DTODocumentationPublishMetadata>();
184
+
185
+ pages.forEach(p => {
186
+ const publishedSnapshot = publishedPageSnapshotsById.get(p.id);
187
+ if (!publishedSnapshot) return;
188
+
189
+ result.set(p.id, {
190
+ lastPublishedAt: publishedSnapshot.createdAt,
191
+ lastPublishedByUserId: publishedSnapshot.createdByUserId,
192
+ });
193
+ });
194
+
195
+ return result;
196
+ }
197
+
198
+ private buildGroupPublishedMetadata(
199
+ groups: ElementGroup[],
200
+ groupSnapshots: ElementGroupSnapshot[]
201
+ ): Map<string, DTODocumentationPublishMetadata> {
202
+ const publishedGroupSnapshotsById = mapByUnique(
203
+ pickLatestGroupSnapshots(groupSnapshots.filter(s => s.reason === "Publish")),
204
+ s => s.group.id
205
+ );
206
+
207
+ const result = new Map<string, DTODocumentationPublishMetadata>();
208
+
209
+ groups.forEach(g => {
210
+ const publishedSnapshot = publishedGroupSnapshotsById.get(g.id);
211
+ if (!publishedSnapshot) return;
212
+
213
+ result.set(g.id, {
214
+ lastPublishedAt: publishedSnapshot.createdAt,
215
+ lastPublishedByUserId: publishedSnapshot.createdByUserId,
216
+ });
217
+ });
218
+
219
+ return result;
220
+ }
221
+
160
222
  private itemStateFromPage(page: DocumentationPageV2, pageContentHash: string): ItemState {
161
223
  return {
162
224
  title: page.meta.name,
@@ -295,4 +357,13 @@ export class FrontendVersionRoomYDoc {
295
357
  const settings = doc.getDocumentationInternalSettings();
296
358
  return settings.isDraftFeatureAdopted;
297
359
  }
360
+
361
+ hasPublishedDocumentationContent() {
362
+ const doc = new VersionRoomBaseYDoc(this.yDoc);
363
+
364
+ return (
365
+ doc.getPageSnapshots().filter(s => s.reason === "Publish").length > 0 ||
366
+ doc.getGroupSnapshots().filter(s => s.reason === "Publish").length > 0
367
+ );
368
+ }
298
369
  }