@supernova-studio/model 0.16.0 → 0.18.0

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/model",
3
- "version": "0.16.0",
3
+ "version": "0.18.0",
4
4
  "description": "Supernova Data Models",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { OmitStrict } from "../../helpers";
2
+ import { OmitStrict } from "../../utils";
3
3
 
4
4
  export const AssetType = z.enum(["Image", "Font"]);
5
5
  export const AssetScope = z.enum(["DocumentationFrame", "ComponentThumbnail", "DesignSystem", "Documentation"]);
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { SourceImportSummary } from "./import-summary";
3
- import { DbCreateInputOmit, DbUpdate, OmitStrict } from "../../helpers";
3
+ import { DbCreateInputOmit, DbUpdate } from "../../helpers";
4
+ import { OmitStrict } from "../../utils";
4
5
 
5
6
  //
6
7
  // Enums
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
- import { DbCreateInputOmit, DbUpdate, OmitStrict } from "../../helpers";
2
+ import { DbCreateInputOmit, DbUpdate } from "../../helpers";
3
+ import { OmitStrict } from "../../utils";
3
4
  import { DataSourceRemoteType } from "./data-source";
4
5
  import { Entity } from "../../common";
5
6
 
@@ -1,4 +1,5 @@
1
- import { DbCreateInputOmit, DbUpdate, OmitStrict } from "../../helpers";
1
+ import { DbCreateInputOmit, DbUpdate } from "../../helpers";
2
+ import { OmitStrict } from "../../utils";
2
3
  import { z } from "zod";
3
4
  import {
4
5
  DesignElementBase,
@@ -155,6 +155,13 @@ export const PageBlockItemEmbedValue = z.object({
155
155
  value: z.string().optional(),
156
156
  caption: z.string().optional(),
157
157
  height: z.number().optional(),
158
+ openGraph: z
159
+ .object({
160
+ title: z.string().optional(),
161
+ description: z.string().optional(),
162
+ imageUrl: z.string().optional(),
163
+ })
164
+ .optional(),
158
165
  });
159
166
 
160
167
  export const PageBlockItemFigmaNodeValue = z.object({
@@ -1,7 +1,8 @@
1
1
  import { z } from "zod";
2
2
  import { DesignElementBase, DesignElementGroupableRequiredPart, DesignElementSlugPart } from "./base";
3
3
  import { DocumentationPageDataV1 } from "./data";
4
- import { DbCreateInputOmit, DbUpdate, OmitStrict } from "../../helpers";
4
+ import { DbCreateInputOmit, DbUpdate } from "../../helpers";
5
+ import { OmitStrict } from "../../utils";
5
6
 
6
7
  export const DocumentationPageV1 = DesignElementBase.extend(DesignElementGroupableRequiredPart.shape)
7
8
  .extend(DesignElementSlugPart.shape)
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { DesignElementBase, DesignElementGroupableRequiredPart, DesignElementSlugPart } from "./base";
3
- import { DbCreateInputOmit, DbUpdate, OmitStrict } from "../../helpers";
3
+ import { DbCreateInputOmit, DbUpdate } from "../../helpers";
4
+ import { OmitStrict } from "../../utils";
4
5
  import { DocumentationPageDataV2 } from "./data/documentation-page-v2";
5
6
 
6
7
  export const DocumentationPageV2 = DesignElementBase.extend(DesignElementGroupableRequiredPart.shape)
@@ -1,7 +1,8 @@
1
1
  import { z } from "zod";
2
2
  import { DesignElementBase } from "./base";
3
3
  import { FigmaFileStructureNode, FigmaFileStructureStatistics } from "./data/figma-file-structure";
4
- import { DbCreateInputOmit, DbUpdate, OmitStrict } from "../../helpers";
4
+ import { DbCreateInputOmit, DbUpdate } from "../../helpers";
5
+ import { OmitStrict } from "../../utils";
5
6
 
6
7
  export const FigmaFileStructureOrigin = z.object({
7
8
  sourceId: z.string(),
@@ -1,7 +1,8 @@
1
1
  import { z } from "zod";
2
2
  import { DesignElementBase } from "./base";
3
3
  import { FigmaNodeReferenceData } from "./data/figma-node-reference";
4
- import { DbCreateInputOmit, DbUpdate, OmitStrict } from "../../helpers";
4
+ import { DbCreateInputOmit, DbUpdate } from "../../helpers";
5
+ import { OmitStrict } from "../../utils";
5
6
 
6
7
  export const FigmaNodeReference = DesignElementBase.extend({
7
8
  data: FigmaNodeReferenceData,
@@ -2,9 +2,8 @@ import { DesignElementType } from "./raw-element";
2
2
  import { DesignElementBase, DesignElementBrandedPart, DesignElementGroupablePart, DesignElementSlugPart } from "./base";
3
3
  import { z } from "zod";
4
4
  import { DbCreateInputOmit, DbUpdate } from "../../helpers";
5
- import { OmitStrict } from "../../helpers";
6
- import { DocumentationGroupBehavior, ElementGroupData } from "./data";
7
- import { DocumentationItemConfiguration } from "./data";
5
+ import { OmitStrict } from "../../utils";
6
+ import { ElementGroupData } from "./data";
8
7
 
9
8
  export const ElementGroup = DesignElementBase.extend(DesignElementGroupablePart.shape)
10
9
  .extend(DesignElementSlugPart.shape)
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
- import { DbCreateInputOmit, DbUpdate, OmitStrict } from "../../helpers";
2
+ import { DbCreateInputOmit, DbUpdate } from "../../helpers";
3
+ import { OmitStrict } from "../../utils";
3
4
  import { ObjectMeta } from "../../common";
4
5
 
5
6
  export type CreateDesignElement = DbCreateInputOmit<DesignElement>;
@@ -2,7 +2,8 @@ import { z } from "zod";
2
2
  import { DesignTokenOrigin, DesignTokenOriginPart, DesignTokenTypedData } from "./tokens";
3
3
  import { DesignTokenType } from "./raw-element";
4
4
  import { DesignElementBase, DesignElementBrandedPart } from "./base";
5
- import { DbCreateInputOmit, DbUpdate, OmitStrict } from "../../helpers";
5
+ import { DbCreateInputOmit, DbUpdate } from "../../helpers";
6
+ import { OmitStrict } from "../../utils";
6
7
 
7
8
  //
8
9
  // Overrides
@@ -5,7 +5,8 @@ import {
5
5
  DesignElementGroupableRequiredPart,
6
6
  DesignElementOrigin,
7
7
  } from "./base";
8
- import { DbUpdate, OmitStrict, zodCreateInputOmit, zodUpdateInputOmit } from "../../helpers";
8
+ import { DbUpdate, zodCreateInputOmit, zodUpdateInputOmit } from "../../helpers";
9
+ import { OmitStrict } from "../../utils";
9
10
  import { DesignTokenType } from "./raw-element";
10
11
  import {
11
12
  TextCaseTokenData,
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
- import { DbCreateInputOmit, DbUpdate, OmitStrict } from "../../helpers";
2
+ import { DbCreateInputOmit, DbUpdate } from "../../helpers";
3
+ import { OmitStrict } from "../../utils";
3
4
 
4
5
  export const ElementPropertyValue = z.object({
5
6
  id: z.string(),
@@ -1,4 +1,5 @@
1
- import { DbCreateInputOmit, DbUpdate, OmitStrict } from "../helpers";
1
+ import { DbCreateInputOmit, DbUpdate } from "../helpers";
2
+ import { OmitStrict } from "../utils";
2
3
 
3
4
  export const SHORT_PERSISTENT_ID_LENGTH = 8;
4
5
 
@@ -1,4 +1,5 @@
1
- import { DbCreateInputOmit, DbUpdate, OmitStrict } from "../../helpers";
1
+ import { DbCreateInputOmit, DbUpdate } from "../../helpers";
2
+ import { OmitStrict } from "../../utils";
2
3
 
3
4
  export type ElementViewBaseColumnType = "Name" | "Description" | "Value" | "UpdatedAt";
4
5
 
@@ -1,3 +1,2 @@
1
- export * from "./common";
2
1
  export * from "./db";
3
2
  export * from "./nullish-to-optional";
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { Entity } from "../common/entity";
3
3
  import { DbCreateInputOmit, DbUpdate } from "../helpers";
4
+ import { DocumentationPageV2, ElementGroup } from "../dsm";
4
5
 
5
6
  export const DesignSystemVersionRoom = Entity.extend({
6
7
  designSystemVersionId: z.string(),
@@ -11,3 +12,20 @@ export type DesignSystemVersionRoom = z.infer<typeof DesignSystemVersionRoom>;
11
12
 
12
13
  export type CreateDesignSystemVersionRoom = DbCreateInputOmit<DesignSystemVersionRoom>;
13
14
  export type UpdateDesignSystemVersionRoom = DbUpdate<DesignSystemVersionRoom>;
15
+
16
+ //
17
+ // Update
18
+ //
19
+
20
+ export const DesignSystemVersionRoomInitialState = z.object({
21
+ pages: z.array(DocumentationPageV2),
22
+ groups: z.array(ElementGroup),
23
+ });
24
+
25
+ export const DesignSystemVersionRoomUpdate = DesignSystemVersionRoomInitialState.extend({
26
+ deletedPageIds: z.array(z.string()),
27
+ deletedGroupIds: z.array(z.string()),
28
+ });
29
+
30
+ export type DesignSystemVersionRoomInitialState = z.infer<typeof DesignSystemVersionRoomInitialState>;
31
+ export type DesignSystemVersionRoomUpdate = z.infer<typeof DesignSystemVersionRoomUpdate>;
@@ -1,6 +1,8 @@
1
1
  import { z } from "zod";
2
2
  import { Entity } from "../common/entity";
3
3
  import { DbCreateInputOmit, DbUpdate } from "../helpers";
4
+ import { DocumentationPageV2, ElementGroup, PageBlockDefinition } from "../dsm";
5
+ import { PageBlockEditorModel } from "@supernova-studio/client";
4
6
 
5
7
  export const DocumentationPageRoom = Entity.extend({
6
8
  designSystemVersionId: z.string(),
@@ -12,3 +14,20 @@ export type DocumentationPageRoom = z.infer<typeof DocumentationPageRoom>;
12
14
 
13
15
  export type CreateDocumentationPageRoom = DbCreateInputOmit<DocumentationPageRoom>;
14
16
  export type UpdateDocumentationPageRoom = DbUpdate<DocumentationPageRoom>;
17
+
18
+ //
19
+ // Room content
20
+ //
21
+
22
+ export const DocumentationPageRoomRoomUpdate = z.object({
23
+ page: DocumentationPageV2,
24
+ pageParent: ElementGroup,
25
+ });
26
+
27
+ export const DocumentationPageRoomInitialState = DocumentationPageRoomRoomUpdate.extend({
28
+ pageBlocks: z.array(PageBlockEditorModel),
29
+ blockDefinitions: z.array(PageBlockDefinition),
30
+ });
31
+
32
+ export type DocumentationPageRoomRoomUpdate = z.infer<typeof DocumentationPageRoomRoomUpdate>;
33
+ export type DocumentationPageRoomInitialState = z.infer<typeof DocumentationPageRoomInitialState>;
@@ -0,0 +1,111 @@
1
+ import { SupernovaException } from "./errors";
2
+
3
+ export type OmitStrict<T, K extends keyof T> = T extends any ? Pick<T, Exclude<keyof T, K>> : never;
4
+
5
+ export type Nullish<T> = T | null | undefined;
6
+
7
+ export type ExplicitPartial<T> = { [P in keyof T]: T[P] | undefined };
8
+
9
+ // Magic as far as I'm concerned.
10
+ // Taken from https://stackoverflow.com/a/50375286/3229534
11
+ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
12
+
13
+ // This utility lets T be indexed by any key
14
+ type Indexify<T> = T & { [str: string]: undefined };
15
+
16
+ // To make a type where all values are undefined, so that in AllUnionKeys<T>
17
+ // TS doesn't remove the keys whose values are incompatible, e.g. string & number
18
+ type UndefinedVals<T> = { [K in keyof T]: undefined };
19
+
20
+ // This returns a union of all keys present across all members of the union T
21
+ type AllUnionKeys<T> = keyof UnionToIntersection<UndefinedVals<T>>;
22
+
23
+ // Where the (rest of the) magic happens ✨
24
+ export type AllFields<T> = { [K in AllUnionKeys<T> & string]: Indexify<T>[K] };
25
+
26
+ export type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
27
+
28
+ export function forceUnwrapNullish<T>(value: Nullish<T>): T {
29
+ if (value === null) throw new Error("Illegal null");
30
+ if (value === undefined) throw new Error("Illegal undefined");
31
+ return value;
32
+ }
33
+
34
+ export function trimLeadingSlash(string: string): string {
35
+ return string.startsWith("/") ? string.substring(1) : string;
36
+ }
37
+
38
+ export function trimTrailingSlash(string: string): string {
39
+ return string.endsWith("/") ? string.substring(0, string.length - 1) : string;
40
+ }
41
+
42
+ export function parseUrl(url: string): URL {
43
+ return new URL(url.startsWith("https://") || url.startsWith("http://") ? url : `https://${url}`);
44
+ }
45
+
46
+ export function mapByUnique<V, K>(items: V[], keyFn: (item: V) => K): Map<K, V> {
47
+ const result = new Map<K, V>();
48
+ for (const item of items) {
49
+ result.set(keyFn(item), item);
50
+ }
51
+ return result;
52
+ }
53
+
54
+ export function groupBy<V, K>(items: V[], keyFn: (item: V) => K): Map<K, V[]> {
55
+ const result = new Map<K, V[]>();
56
+
57
+ for (const item of items) {
58
+ const key = keyFn(item);
59
+ const array = result.get(key);
60
+ if (array) {
61
+ array.push(item);
62
+ } else {
63
+ result.set(key, [item]);
64
+ }
65
+ }
66
+
67
+ return result;
68
+ }
69
+
70
+ export function filterNonNullish<T>(items: Nullish<T>[]): T[] {
71
+ return items.filter(Boolean) as T[];
72
+ }
73
+
74
+ export function nonNullishFilter<T>(item: Nullish<T>): item is T {
75
+ return !!item;
76
+ }
77
+
78
+ export function nonNullFilter<T>(item: T | null): item is T {
79
+ return item !== null;
80
+ }
81
+
82
+ export type ArrayElementType<T extends Default[], Default = any> = T extends (infer U)[] ? U : Default;
83
+
84
+ export function buildConstantEnum<Inferred extends ArrayElementType<Passed>[], Passed extends string[]>(
85
+ values: Inferred
86
+ ): { [key in Inferred[number]]: key } {
87
+ const constMap = values.reduce((acc, code) => ({ ...acc, [code]: code }), {});
88
+
89
+ return constMap as { [key in Inferred[number]]: key };
90
+ }
91
+
92
+ export async function promiseWithTimeout<T>(timeoutMs: number, promise: () => Promise<T>): Promise<T> {
93
+ let timeoutHandle: NodeJS.Timeout | undefined;
94
+ const timeoutPromise = new Promise<never>((_, reject) => {
95
+ timeoutHandle = setTimeout(() => reject(SupernovaException.timeout()), timeoutMs);
96
+ });
97
+
98
+ const result = await Promise.race([promise(), timeoutPromise]);
99
+
100
+ clearTimeout(timeoutHandle);
101
+ return result;
102
+ }
103
+
104
+ export async function sleep(ms: number): Promise<void> {
105
+ return new Promise(resolve => setTimeout(resolve, ms));
106
+ }
107
+
108
+ export type Pagination = {
109
+ skip?: number;
110
+ take?: number;
111
+ };
@@ -0,0 +1,94 @@
1
+ export type SupernovaExceptionType =
2
+ | "AccessDenied"
3
+ | "ResourceNotFound"
4
+ | "WrongFormat"
5
+ | "Timeout"
6
+ | "Conflict"
7
+ | "NotImplemented"
8
+ | "BadRequest"
9
+ | "WrongActionOrder"
10
+ | "InvalidOperation"
11
+ | "UnexpectedError"
12
+ | "IPRestricted"
13
+ | "PlanRestricted"
14
+ | "MissingWorkspacePermission"
15
+ | "MissingExporterPermission"
16
+ | "NoAccess";
17
+
18
+ export class SupernovaException extends Error {
19
+ static wrongFormat(message?: string): SupernovaException {
20
+ return new SupernovaException("WrongFormat", message);
21
+ }
22
+
23
+ static accessDenied(message?: string): SupernovaException {
24
+ return new SupernovaException("AccessDenied", message);
25
+ }
26
+
27
+ static notFound(message?: string): SupernovaException {
28
+ return new SupernovaException("ResourceNotFound", message);
29
+ }
30
+
31
+ static timeout(message?: string): SupernovaException {
32
+ return new SupernovaException("Timeout", message);
33
+ }
34
+
35
+ static conflict(message?: string): SupernovaException {
36
+ return new SupernovaException("Conflict", message);
37
+ }
38
+
39
+ static notImplemented(message?: string): SupernovaException {
40
+ return new SupernovaException("NotImplemented", message);
41
+ }
42
+
43
+ static wrongActionOrder(message?: string): SupernovaException {
44
+ return new SupernovaException("WrongActionOrder", message);
45
+ }
46
+
47
+ static invalidOperation(message?: string): SupernovaException {
48
+ return new SupernovaException("InvalidOperation", message);
49
+ }
50
+
51
+ static shouldNotHappen(message?: string): SupernovaException {
52
+ return new SupernovaException("UnexpectedError", message);
53
+ }
54
+
55
+ static ipRestricted(message?: string): SupernovaException {
56
+ return new SupernovaException("IPRestricted", message);
57
+ }
58
+
59
+ static planRestricted(message?: string): SupernovaException {
60
+ return new SupernovaException("PlanRestricted", message);
61
+ }
62
+
63
+ static missingWorkspacePermission(message?: string): SupernovaException {
64
+ return new SupernovaException("MissingWorkspacePermission", message);
65
+ }
66
+
67
+ static missingExporterPermission(message?: string): SupernovaException {
68
+ return new SupernovaException("MissingExporterPermission", message);
69
+ }
70
+
71
+ static missingIntegration(message?: string): SupernovaException {
72
+ return new SupernovaException("AccessDenied", message);
73
+ }
74
+
75
+ static noAccess(message?: string): SupernovaException {
76
+ return new SupernovaException("NoAccess", message);
77
+ }
78
+
79
+ //
80
+ // To refactor
81
+ //
82
+
83
+ static badRequest(message?: string): SupernovaException {
84
+ return new SupernovaException("BadRequest", message);
85
+ }
86
+
87
+ //
88
+ // Properties
89
+ //
90
+
91
+ constructor(readonly type: SupernovaExceptionType, message?: string) {
92
+ super(`${type}: ${message}`);
93
+ }
94
+ }
@@ -1,2 +1,5 @@
1
+ export * from "./common";
1
2
  export * from "./content-loader-instruction";
3
+ export * from "./errors";
4
+ export * from "./slugify";
2
5
  export * from "./validation";