@supernova-studio/client 0.58.15 → 0.58.17

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.58.15",
3
+ "version": "0.58.17",
4
4
  "description": "Supernova Data Models",
5
5
  "source": "src/index.ts",
6
6
  "main": "dist/index.js",
@@ -52,7 +52,26 @@ export type DTOFigmaNode = z.infer<typeof DTOFigmaNode>;
52
52
  // Write
53
53
  //
54
54
 
55
- export const DTOFigmaNodeRenderInput = z.object({
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
- * Format in which the node must be rendered, png by default.
94
+ * Id of a design system's data source representing a linked Figma file
68
95
  */
69
- format: FigmaNodeRenderFormat.default("Png"),
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>;
@@ -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
@@ -1,2 +1,3 @@
1
+ export * from "./figma";
1
2
  export * from "./hash";
2
3
  export * from "./query";