@supernova-studio/client 0.58.16 → 0.58.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +248 -64
- package/dist/index.d.ts +248 -64
- package/dist/index.js +93 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +422 -341
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/api/client.ts +3 -0
- package/src/api/dto/documentation/index.ts +1 -0
- package/src/api/dto/documentation/room.ts +12 -0
- package/src/api/dto/elements/figma-nodes/figma-node.ts +37 -3
- package/src/api/endpoints/design-system/versions/documentation.ts +11 -7
- package/src/api/endpoints/index.ts +1 -0
- package/src/api/endpoints/liveblocks.ts +14 -0
- package/src/utils/figma.ts +53 -0
- package/src/utils/index.ts +1 -0
package/package.json
CHANGED
package/src/api/client.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CodegenEndpoint, WorkspacesEndpoint } from "./endpoints";
|
|
2
2
|
import { DesignSystemsEndpoint } from "./endpoints/design-system";
|
|
3
|
+
import { LiveblocksEndpoint } from "./endpoints/liveblocks";
|
|
3
4
|
import { UsersEndpoint } from "./endpoints/users";
|
|
4
5
|
import { RequestExecutor } from "./transport/request-executor";
|
|
5
6
|
|
|
@@ -13,6 +14,7 @@ export class SupernovaApiClient {
|
|
|
13
14
|
readonly workspaces: WorkspacesEndpoint;
|
|
14
15
|
readonly designSystems: DesignSystemsEndpoint;
|
|
15
16
|
readonly codegen: CodegenEndpoint;
|
|
17
|
+
readonly liveblocks: LiveblocksEndpoint;
|
|
16
18
|
|
|
17
19
|
constructor(config: SupernovaApiClientConfig) {
|
|
18
20
|
const requestExecutor = new RequestExecutor({
|
|
@@ -24,5 +26,6 @@ export class SupernovaApiClient {
|
|
|
24
26
|
this.workspaces = new WorkspacesEndpoint(requestExecutor);
|
|
25
27
|
this.designSystems = new DesignSystemsEndpoint(requestExecutor);
|
|
26
28
|
this.codegen = new CodegenEndpoint(requestExecutor);
|
|
29
|
+
this.liveblocks = new LiveblocksEndpoint(requestExecutor);
|
|
27
30
|
}
|
|
28
31
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const DTODocumentationPageRoom = z.object({
|
|
4
|
+
id: z.string(),
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
export const DTODocumentationPageRoomResponse = z.object({
|
|
8
|
+
room: DTODocumentationPageRoom,
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export type DTODocumentationPageRoom = z.infer<typeof DTODocumentationPageRoom>;
|
|
12
|
+
export type DTODocumentationPageRoomResponse = z.infer<typeof DTODocumentationPageRoomResponse>;
|
|
@@ -52,7 +52,26 @@ export type DTOFigmaNode = z.infer<typeof DTOFigmaNode>;
|
|
|
52
52
|
// Write
|
|
53
53
|
//
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Properties that are available on all types of Figma node render requests
|
|
57
|
+
*/
|
|
58
|
+
const DTOFigmaNodeRenderInputBase = z.object({
|
|
59
|
+
/**
|
|
60
|
+
* Format in which the node must be rendered, png by default.
|
|
61
|
+
*/
|
|
62
|
+
format: FigmaNodeRenderFormat.default("Png"),
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Figma node render request that uses source ID + node ID to identify the requested
|
|
67
|
+
* node to render. The node ID can be obtained from the source's Figma node structure.
|
|
68
|
+
*/
|
|
69
|
+
const DTOFigmaNodeRenderIdInput = DTOFigmaNodeRenderInputBase.extend({
|
|
70
|
+
inputType: z
|
|
71
|
+
.literal("NodeId")
|
|
72
|
+
.optional()
|
|
73
|
+
.transform(v => v ?? "NodeId"),
|
|
74
|
+
|
|
56
75
|
/**
|
|
57
76
|
* Id of a design system's data source representing a linked Figma file
|
|
58
77
|
*/
|
|
@@ -62,11 +81,26 @@ export const DTOFigmaNodeRenderInput = z.object({
|
|
|
62
81
|
* Id of a node within the Figma file
|
|
63
82
|
*/
|
|
64
83
|
figmaFileNodeId: z.string(),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Figma node render request that uses Figma URL to identify the requested
|
|
88
|
+
* node to render. The URL can be obtained by the user directly from the Figma app.
|
|
89
|
+
*/
|
|
90
|
+
const DTOFigmaNodeRenderUrlInput = DTOFigmaNodeRenderInputBase.extend({
|
|
91
|
+
inputType: z.literal("URL"),
|
|
65
92
|
|
|
66
93
|
/**
|
|
67
|
-
*
|
|
94
|
+
* Id of a design system's data source representing a linked Figma file
|
|
68
95
|
*/
|
|
69
|
-
|
|
96
|
+
figmaNodeUrl: z.string(),
|
|
70
97
|
});
|
|
71
98
|
|
|
99
|
+
export const DTOFigmaNodeRenderInput = z.discriminatedUnion("inputType", [
|
|
100
|
+
DTOFigmaNodeRenderIdInput,
|
|
101
|
+
DTOFigmaNodeRenderUrlInput,
|
|
102
|
+
]);
|
|
103
|
+
|
|
104
|
+
export type DTOFigmaNodeRenderIdInput = z.infer<typeof DTOFigmaNodeRenderIdInput>;
|
|
105
|
+
export type DTOFigmaNodeRenderUrlInput = z.infer<typeof DTOFigmaNodeRenderUrlInput>;
|
|
72
106
|
export type DTOFigmaNodeRenderInput = z.infer<typeof DTOFigmaNodeRenderInput>;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DTODocumentationPageRoomResponse, DTODocumentationStructure } from "../../../dto";
|
|
2
2
|
import { RequestExecutor } from "../../../transport/request-executor";
|
|
3
3
|
|
|
4
4
|
export class DocumentationEndpoint {
|
|
5
5
|
constructor(private readonly requestExecutor: RequestExecutor) {}
|
|
6
6
|
|
|
7
|
-
getStructure(designSystemId: string, versionId: string) {
|
|
8
|
-
return this.requestExecutor.json(
|
|
7
|
+
async getStructure(designSystemId: string, versionId: string) {
|
|
8
|
+
return await this.requestExecutor.json(
|
|
9
9
|
`/design-systems/${designSystemId}/versions/${versionId}/documentation/structure`,
|
|
10
10
|
DTODocumentationStructure
|
|
11
11
|
);
|
|
@@ -14,10 +14,14 @@ export class DocumentationEndpoint {
|
|
|
14
14
|
async getDocStructure(dsId: string, vId: string) {
|
|
15
15
|
return await this.requestExecutor.json(
|
|
16
16
|
`/design-systems/${dsId}/versions/${vId}/documentation/structure`,
|
|
17
|
-
DTODocumentationStructure
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
DTODocumentationStructure
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async getPageRoom(dsId: string, vId: string, pageId: string) {
|
|
22
|
+
return await this.requestExecutor.json(
|
|
23
|
+
`/design-systems/${dsId}/versions/${vId}/documentation/pages/${pageId}/room`,
|
|
24
|
+
DTODocumentationPageRoomResponse
|
|
21
25
|
);
|
|
22
26
|
}
|
|
23
27
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DTOLiveblocksAuthResponse } from "../dto";
|
|
2
|
+
import { DTOLiveblocksAuthRequest } from "../payloads";
|
|
3
|
+
import { RequestExecutor } from "../transport/request-executor";
|
|
4
|
+
|
|
5
|
+
export class LiveblocksEndpoint {
|
|
6
|
+
constructor(private readonly requestExecutor: RequestExecutor) {}
|
|
7
|
+
|
|
8
|
+
auth(body: DTOLiveblocksAuthRequest) {
|
|
9
|
+
return this.requestExecutor.json("/liveblocks/auth", DTOLiveblocksAuthResponse, {
|
|
10
|
+
method: "POST",
|
|
11
|
+
body,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const figmaFileIdRegex = /^[0-9a-zA-Z]{22,128}$/;
|
|
2
|
+
const nodeIdRegex = /^d+-d+$/;
|
|
3
|
+
const nodeTypeRegex = /^[0-9a-zA-Z]^/;
|
|
4
|
+
|
|
5
|
+
type ParsedFigmaFileURL = {
|
|
6
|
+
fileId: string;
|
|
7
|
+
fileName: string | null;
|
|
8
|
+
nodeId: string | null;
|
|
9
|
+
nodeType: string | null;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const FigmaUtils = {
|
|
13
|
+
tryParseFigmaFileURL(urlString: string): ParsedFigmaFileURL | null {
|
|
14
|
+
if (!URL.canParse(urlString)) return null;
|
|
15
|
+
|
|
16
|
+
// Validate that this is a Figma URL
|
|
17
|
+
const url = new URL(urlString);
|
|
18
|
+
if (!url.hostname.endsWith("figma.com")) return null;
|
|
19
|
+
|
|
20
|
+
// Validate that the URL type is the correct one (pointing to a design file)
|
|
21
|
+
const pathSegments = url.pathname.split("/");
|
|
22
|
+
if (pathSegments[0] !== "design" && pathSegments[0] !== "file") return null;
|
|
23
|
+
|
|
24
|
+
// Validate Figma file ID
|
|
25
|
+
const fileId = pathSegments[1];
|
|
26
|
+
if (!fileId || !fileId.match(figmaFileIdRegex)) return null;
|
|
27
|
+
|
|
28
|
+
// Parse Figma file name
|
|
29
|
+
let fileName: string | null = null;
|
|
30
|
+
const rawFileName = pathSegments[2];
|
|
31
|
+
if (rawFileName) {
|
|
32
|
+
fileName = rawFileName.replaceAll("-", " ");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Parse node id
|
|
36
|
+
let nodeId: string | null = null;
|
|
37
|
+
const nodeIdRaw = url.searchParams.get("node-id");
|
|
38
|
+
if (nodeIdRaw && nodeIdRaw.match(nodeIdRegex)) {
|
|
39
|
+
nodeId = nodeIdRaw.replace("-", ":");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Parse node type
|
|
43
|
+
let nodeType: string | null = null;
|
|
44
|
+
const nodeTypeRaw = url.searchParams.get("node-type");
|
|
45
|
+
if (nodeTypeRaw && nodeTypeRaw.match(nodeTypeRegex)) {
|
|
46
|
+
nodeType = nodeTypeRaw;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return { fileId, fileName, nodeId, nodeType };
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// https://www.figma.com/design/U3Mg3I8WbvqF6CcZtRJM7w?node-id=2-3&t=9Qev2vhsldyFMhuE-1
|
package/src/utils/index.ts
CHANGED