@design-sdk/figma-url 0.0.53 → 0.1.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.
@@ -0,0 +1,161 @@
1
+ type FigmaEmbedInput = string | {
2
+ url: string;
3
+ } | {
4
+ fileid: string;
5
+ nodeid?: string;
6
+ };
7
+ /**
8
+ * build embedding url. - https://www.figma.com/developers/embed
9
+ * @param src : ;
10
+ * @returns
11
+ */
12
+ declare function embed(src: FigmaEmbedInput): string;
13
+ /**
14
+ * e.g. - https://www.figma.com/design/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0
15
+ *
16
+ * (*this does not contain logic for checking if input url is valid.*)
17
+ * @param src : ;
18
+ * @returns
19
+ */
20
+ declare function builEmbedableSourceUrl(src?: FigmaEmbedInput): string | undefined;
21
+
22
+ /**
23
+ * target node configuration for figma node that contains all fileid, nodeid and the figma url of the target.
24
+ */
25
+ interface FigmaTargetNodeConfig {
26
+ /**
27
+ * url of target node originated from figma
28
+ */
29
+ url: string;
30
+ /**
31
+ * id of the file originated from figma
32
+ */
33
+ file: string;
34
+ /**
35
+ * id of the node originated from figma
36
+ */
37
+ node: string;
38
+ }
39
+
40
+ /**
41
+ * extracts file id from share link
42
+ *
43
+ * Supports multiple Figma URL patterns:
44
+ * - Old: "https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
45
+ * - New: "https://www.figma.com/design/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
46
+ * - New: "https://www.figma.com/board/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
47
+ * - New: "https://www.figma.com/slides/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
48
+ * - New: "https://www.figma.com/site/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
49
+ *
50
+ * out - "Y0Gh77AqBoHH7dG1GtK3xF"
51
+ * @param url
52
+ * @returns
53
+ */
54
+ declare function parseFileId(url: string): string;
55
+ /**
56
+ * Figma file url's node-id changed over time, this function is to make sure we can handle both formats.
57
+ * to keep `00:00` format
58
+ * @param node_id
59
+ * @returns
60
+ */
61
+ declare function formatNodeId(node_id: string): string;
62
+ /**
63
+ * pattern examples:
64
+ * - "https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
65
+ * - "https://www.figma.com/design/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
66
+ * - "https://www.figma.com/board/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
67
+ * - "https://www.figma.com/slides/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
68
+ * - "https://www.figma.com/site/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
69
+ * @param url
70
+ */
71
+ declare function parseFileAndNodeId(url: string): FigmaTargetNodeConfig | undefined;
72
+
73
+ /**
74
+ * e.g.
75
+ *
76
+ * - **ok**: (public file) - https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/grida?node-id=1545%3A247
77
+ * - **not found**: (private file) - https://www.figma.com/file/8R57Uv5Siu1ZhhGkVIyyQg/private-file-api-demo?node-id=2%3A2
78
+ *
79
+ */
80
+ declare function isPublic(url: string): Promise<boolean>;
81
+
82
+ declare enum FigmaUrlType {
83
+ /**
84
+ * embed ready url
85
+ */
86
+ embed = "embed",
87
+ /**
88
+ * file id only url. this cannot be used for embedding (cannot be used as a source)
89
+ */
90
+ file = "file",
91
+ /**
92
+ * url with file & node this can be used for embedding. (can be used as a source)
93
+ */
94
+ node = "node",
95
+ /**
96
+ * empty url. undefined or ""
97
+ */
98
+ empty = "empty"
99
+ }
100
+ declare enum FigmaFileOrNodeIdType {
101
+ nodeid = "nodeid",
102
+ maybe_nodeid = "maybe_nodeid",
103
+ fileid = "fileid",
104
+ maybe_fileid = "maybe_fileid"
105
+ }
106
+ type FigmaInputAnalysisResult = FigmaUrlType | FigmaFileOrNodeIdType;
107
+ declare function analyze(url: string): FigmaInputAnalysisResult;
108
+
109
+ /**
110
+ * e.g. full url should look like -
111
+ * https://www.figma.com/embed?embed_host=astra&url=https://www.figma.com/design/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0
112
+ *
113
+ * ref: https://www.figma.com/developers/embed
114
+ */
115
+ declare const _FIGMA_EMBED_URL_PREFIX = "https://www.figma.com/embed";
116
+ /**
117
+ * Legacy file URL prefix (for backward compatibility)
118
+ * e.g. full url should look like -
119
+ * https://www.figma.com/file/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0
120
+ */
121
+ declare const _FIGMA_FILE_URL_PREFIX = "https://www.figma.com/file";
122
+ /**
123
+ * Design file URL prefix (current standard, replaces /file/)
124
+ * e.g. full url should look like -
125
+ * https://www.figma.com/design/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0
126
+ */
127
+ declare const _FIGMA_DESIGN_URL_PREFIX = "https://www.figma.com/design";
128
+ /**
129
+ * FigJam board URL prefix
130
+ * e.g. full url should look like -
131
+ * https://www.figma.com/board/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0
132
+ */
133
+ declare const _FIGMA_BOARD_URL_PREFIX = "https://www.figma.com/board";
134
+ /**
135
+ * Figma Slides URL prefix
136
+ * e.g. full url should look like -
137
+ * https://www.figma.com/slides/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0
138
+ */
139
+ declare const _FIGMA_SLIDES_URL_PREFIX = "https://www.figma.com/slides";
140
+ /**
141
+ * Figma Site URL prefix
142
+ * e.g. full url should look like -
143
+ * https://www.figma.com/site/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0
144
+ */
145
+ declare const _FIGMA_SITE_URL_PREFIX = "https://www.figma.com/site";
146
+ /**
147
+ * param key for node id specification.
148
+ *
149
+ * e.g. - `https://www.figma.com/file/ABC/?node-id=1234` `(node-id = 1234)`
150
+ */
151
+ declare const _PARAM_NODE_ID = "node-id";
152
+ /**
153
+ * file id of Grida design - https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/
154
+ */
155
+ declare const __FIGMA_DEMO_DEFAULT_FILE_ID = "Y0Gh77AqBoHH7dG1GtK3xF";
156
+ declare const __FIGMA_DEMO_DEFAULT_FILE_URL = "https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/";
157
+ declare const __FIGMA_DEMO_DEFAULT_FILE_NODE_URL = "https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=264%3A49";
158
+
159
+ declare function isSameDesignUrl(url1: string, url2: string): boolean;
160
+
161
+ export { type FigmaEmbedInput, FigmaFileOrNodeIdType, type FigmaInputAnalysisResult, type FigmaTargetNodeConfig, FigmaUrlType, _FIGMA_BOARD_URL_PREFIX, _FIGMA_DESIGN_URL_PREFIX, _FIGMA_EMBED_URL_PREFIX, _FIGMA_FILE_URL_PREFIX, _FIGMA_SITE_URL_PREFIX, _FIGMA_SLIDES_URL_PREFIX, _PARAM_NODE_ID, __FIGMA_DEMO_DEFAULT_FILE_ID, __FIGMA_DEMO_DEFAULT_FILE_NODE_URL, __FIGMA_DEMO_DEFAULT_FILE_URL, analyze, builEmbedableSourceUrl, embed, formatNodeId, isPublic, isSameDesignUrl, parseFileAndNodeId, parseFileId };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,161 @@
1
- export * from "./embed-url";
2
- export * from "./parse-url";
3
- export * from "./access-check";
4
- export * from "./analyze-url";
5
- export * from "./target-node-config";
6
- export * from "./constants";
7
- export * from "./compare-url";
1
+ type FigmaEmbedInput = string | {
2
+ url: string;
3
+ } | {
4
+ fileid: string;
5
+ nodeid?: string;
6
+ };
7
+ /**
8
+ * build embedding url. - https://www.figma.com/developers/embed
9
+ * @param src : ;
10
+ * @returns
11
+ */
12
+ declare function embed(src: FigmaEmbedInput): string;
13
+ /**
14
+ * e.g. - https://www.figma.com/design/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0
15
+ *
16
+ * (*this does not contain logic for checking if input url is valid.*)
17
+ * @param src : ;
18
+ * @returns
19
+ */
20
+ declare function builEmbedableSourceUrl(src?: FigmaEmbedInput): string | undefined;
21
+
22
+ /**
23
+ * target node configuration for figma node that contains all fileid, nodeid and the figma url of the target.
24
+ */
25
+ interface FigmaTargetNodeConfig {
26
+ /**
27
+ * url of target node originated from figma
28
+ */
29
+ url: string;
30
+ /**
31
+ * id of the file originated from figma
32
+ */
33
+ file: string;
34
+ /**
35
+ * id of the node originated from figma
36
+ */
37
+ node: string;
38
+ }
39
+
40
+ /**
41
+ * extracts file id from share link
42
+ *
43
+ * Supports multiple Figma URL patterns:
44
+ * - Old: "https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
45
+ * - New: "https://www.figma.com/design/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
46
+ * - New: "https://www.figma.com/board/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
47
+ * - New: "https://www.figma.com/slides/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
48
+ * - New: "https://www.figma.com/site/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
49
+ *
50
+ * out - "Y0Gh77AqBoHH7dG1GtK3xF"
51
+ * @param url
52
+ * @returns
53
+ */
54
+ declare function parseFileId(url: string): string;
55
+ /**
56
+ * Figma file url's node-id changed over time, this function is to make sure we can handle both formats.
57
+ * to keep `00:00` format
58
+ * @param node_id
59
+ * @returns
60
+ */
61
+ declare function formatNodeId(node_id: string): string;
62
+ /**
63
+ * pattern examples:
64
+ * - "https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
65
+ * - "https://www.figma.com/design/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
66
+ * - "https://www.figma.com/board/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
67
+ * - "https://www.figma.com/slides/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
68
+ * - "https://www.figma.com/site/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112"
69
+ * @param url
70
+ */
71
+ declare function parseFileAndNodeId(url: string): FigmaTargetNodeConfig | undefined;
72
+
73
+ /**
74
+ * e.g.
75
+ *
76
+ * - **ok**: (public file) - https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/grida?node-id=1545%3A247
77
+ * - **not found**: (private file) - https://www.figma.com/file/8R57Uv5Siu1ZhhGkVIyyQg/private-file-api-demo?node-id=2%3A2
78
+ *
79
+ */
80
+ declare function isPublic(url: string): Promise<boolean>;
81
+
82
+ declare enum FigmaUrlType {
83
+ /**
84
+ * embed ready url
85
+ */
86
+ embed = "embed",
87
+ /**
88
+ * file id only url. this cannot be used for embedding (cannot be used as a source)
89
+ */
90
+ file = "file",
91
+ /**
92
+ * url with file & node this can be used for embedding. (can be used as a source)
93
+ */
94
+ node = "node",
95
+ /**
96
+ * empty url. undefined or ""
97
+ */
98
+ empty = "empty"
99
+ }
100
+ declare enum FigmaFileOrNodeIdType {
101
+ nodeid = "nodeid",
102
+ maybe_nodeid = "maybe_nodeid",
103
+ fileid = "fileid",
104
+ maybe_fileid = "maybe_fileid"
105
+ }
106
+ type FigmaInputAnalysisResult = FigmaUrlType | FigmaFileOrNodeIdType;
107
+ declare function analyze(url: string): FigmaInputAnalysisResult;
108
+
109
+ /**
110
+ * e.g. full url should look like -
111
+ * https://www.figma.com/embed?embed_host=astra&url=https://www.figma.com/design/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0
112
+ *
113
+ * ref: https://www.figma.com/developers/embed
114
+ */
115
+ declare const _FIGMA_EMBED_URL_PREFIX = "https://www.figma.com/embed";
116
+ /**
117
+ * Legacy file URL prefix (for backward compatibility)
118
+ * e.g. full url should look like -
119
+ * https://www.figma.com/file/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0
120
+ */
121
+ declare const _FIGMA_FILE_URL_PREFIX = "https://www.figma.com/file";
122
+ /**
123
+ * Design file URL prefix (current standard, replaces /file/)
124
+ * e.g. full url should look like -
125
+ * https://www.figma.com/design/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0
126
+ */
127
+ declare const _FIGMA_DESIGN_URL_PREFIX = "https://www.figma.com/design";
128
+ /**
129
+ * FigJam board URL prefix
130
+ * e.g. full url should look like -
131
+ * https://www.figma.com/board/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0
132
+ */
133
+ declare const _FIGMA_BOARD_URL_PREFIX = "https://www.figma.com/board";
134
+ /**
135
+ * Figma Slides URL prefix
136
+ * e.g. full url should look like -
137
+ * https://www.figma.com/slides/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0
138
+ */
139
+ declare const _FIGMA_SLIDES_URL_PREFIX = "https://www.figma.com/slides";
140
+ /**
141
+ * Figma Site URL prefix
142
+ * e.g. full url should look like -
143
+ * https://www.figma.com/site/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0
144
+ */
145
+ declare const _FIGMA_SITE_URL_PREFIX = "https://www.figma.com/site";
146
+ /**
147
+ * param key for node id specification.
148
+ *
149
+ * e.g. - `https://www.figma.com/file/ABC/?node-id=1234` `(node-id = 1234)`
150
+ */
151
+ declare const _PARAM_NODE_ID = "node-id";
152
+ /**
153
+ * file id of Grida design - https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/
154
+ */
155
+ declare const __FIGMA_DEMO_DEFAULT_FILE_ID = "Y0Gh77AqBoHH7dG1GtK3xF";
156
+ declare const __FIGMA_DEMO_DEFAULT_FILE_URL = "https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/";
157
+ declare const __FIGMA_DEMO_DEFAULT_FILE_NODE_URL = "https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=264%3A49";
158
+
159
+ declare function isSameDesignUrl(url1: string, url2: string): boolean;
160
+
161
+ export { type FigmaEmbedInput, FigmaFileOrNodeIdType, type FigmaInputAnalysisResult, type FigmaTargetNodeConfig, FigmaUrlType, _FIGMA_BOARD_URL_PREFIX, _FIGMA_DESIGN_URL_PREFIX, _FIGMA_EMBED_URL_PREFIX, _FIGMA_FILE_URL_PREFIX, _FIGMA_SITE_URL_PREFIX, _FIGMA_SLIDES_URL_PREFIX, _PARAM_NODE_ID, __FIGMA_DEMO_DEFAULT_FILE_ID, __FIGMA_DEMO_DEFAULT_FILE_NODE_URL, __FIGMA_DEMO_DEFAULT_FILE_URL, analyze, builEmbedableSourceUrl, embed, formatNodeId, isPublic, isSameDesignUrl, parseFileAndNodeId, parseFileId };
package/dist/index.js CHANGED
@@ -1,19 +1,215 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
- };
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- __exportStar(require("./embed-url"), exports);
14
- __exportStar(require("./parse-url"), exports);
15
- __exportStar(require("./access-check"), exports);
16
- __exportStar(require("./analyze-url"), exports);
17
- __exportStar(require("./target-node-config"), exports);
18
- __exportStar(require("./constants"), exports);
19
- __exportStar(require("./compare-url"), exports);
1
+ 'use strict';
2
+
3
+ // lib/constants.ts
4
+ var _FIGMA_EMBED_URL_PREFIX = "https://www.figma.com/embed";
5
+ var _FIGMA_FILE_URL_PREFIX = "https://www.figma.com/file";
6
+ var _FIGMA_DESIGN_URL_PREFIX = "https://www.figma.com/design";
7
+ var _FIGMA_BOARD_URL_PREFIX = "https://www.figma.com/board";
8
+ var _FIGMA_SLIDES_URL_PREFIX = "https://www.figma.com/slides";
9
+ var _FIGMA_SITE_URL_PREFIX = "https://www.figma.com/site";
10
+ var _PARAM_NODE_ID = "node-id";
11
+ var __FIGMA_DEMO_DEFAULT_FILE_ID = "Y0Gh77AqBoHH7dG1GtK3xF";
12
+ var __FIGMA_DEMO_DEFAULT_FILE_URL = "https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/";
13
+ var __FIGMA_DEMO_DEFAULT_FILE_NODE_URL = "https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=264%3A49";
14
+
15
+ // lib/parse-url.ts
16
+ function parseFileId(url) {
17
+ const supportedPatterns = [
18
+ "https://www.figma.com/file/",
19
+ "https://www.figma.com/design/",
20
+ "https://www.figma.com/board/",
21
+ "https://www.figma.com/slides/",
22
+ "https://www.figma.com/site/"
23
+ ];
24
+ const matchedPattern = supportedPatterns.find(
25
+ (pattern) => url.includes(pattern)
26
+ );
27
+ if (matchedPattern) {
28
+ return url.split("/")[4];
29
+ } else {
30
+ throw `figma url must contain one of the supported patterns (file/, design/, board/, slides/, site/). the given was ${url}, which we cannot extract file id from it.`;
31
+ }
32
+ }
33
+ function formatNodeId(node_id) {
34
+ if (node_id.includes(":") || node_id.includes("%3A") || node_id.includes("-")) {
35
+ if (node_id.includes("%3A")) {
36
+ node_id = decodeURIComponent(node_id);
37
+ }
38
+ if (node_id.includes("-")) {
39
+ node_id = node_id.split("-").join(":");
40
+ }
41
+ if (node_id.match(/[0-9]+:[0-9]+/) !== null) {
42
+ return node_id;
43
+ }
44
+ }
45
+ }
46
+ function parseFileAndNodeId(url) {
47
+ try {
48
+ const _url = new URL(url);
49
+ const params = new URLSearchParams(_url.search);
50
+ const nodeId = formatNodeId(params.get("node-id"));
51
+ const fileId = parseFileId(url);
52
+ return {
53
+ url,
54
+ file: fileId,
55
+ node: nodeId
56
+ };
57
+ } catch (_) {
58
+ return;
59
+ }
60
+ }
61
+
62
+ // lib/analyze-url.ts
63
+ var FigmaUrlType = /* @__PURE__ */ ((FigmaUrlType2) => {
64
+ FigmaUrlType2["embed"] = "embed";
65
+ FigmaUrlType2["file"] = "file";
66
+ FigmaUrlType2["node"] = "node";
67
+ FigmaUrlType2["empty"] = "empty";
68
+ return FigmaUrlType2;
69
+ })(FigmaUrlType || {});
70
+ var FigmaFileOrNodeIdType = /* @__PURE__ */ ((FigmaFileOrNodeIdType2) => {
71
+ FigmaFileOrNodeIdType2["nodeid"] = "nodeid";
72
+ FigmaFileOrNodeIdType2["maybe_nodeid"] = "maybe_nodeid";
73
+ FigmaFileOrNodeIdType2["fileid"] = "fileid";
74
+ FigmaFileOrNodeIdType2["maybe_fileid"] = "maybe_fileid";
75
+ return FigmaFileOrNodeIdType2;
76
+ })(FigmaFileOrNodeIdType || {});
77
+ function analyze(url) {
78
+ if (!url) {
79
+ return "empty" /* empty */;
80
+ }
81
+ let _u;
82
+ try {
83
+ _u = new URL(url);
84
+ } catch (_) {
85
+ const maybeidlike = url;
86
+ if (maybeidlike.length > 0) {
87
+ if (formatNodeId(maybeidlike)) {
88
+ return "maybe_nodeid" /* maybe_nodeid */;
89
+ } else if (maybeidlike.length >= 22) {
90
+ const _taget = decodeURI(maybeidlike);
91
+ if (_taget.match(/[a-zA-Z0-9]/) !== null) {
92
+ if (_taget.length == 22) {
93
+ return "fileid" /* fileid */;
94
+ } else {
95
+ return "maybe_fileid" /* maybe_fileid */;
96
+ }
97
+ }
98
+ }
99
+ }
100
+ throw `this url cannot be analyzed. this is not a valid url string - "${url}"`;
101
+ }
102
+ if (url.startsWith(_FIGMA_EMBED_URL_PREFIX)) {
103
+ return "embed" /* embed */;
104
+ } else {
105
+ if (_u.hostname == "figma.com" || _u.hostname == "www.figma.com") {
106
+ const supportedPathPatterns = [
107
+ "file/",
108
+ "design/",
109
+ "board/",
110
+ "slides/",
111
+ "site/"
112
+ ];
113
+ const matchedPattern = supportedPathPatterns.find(
114
+ (pattern) => _u.pathname.includes(pattern)
115
+ );
116
+ if (matchedPattern) {
117
+ if (_u.searchParams.get(_PARAM_NODE_ID)?.length > 0) {
118
+ return "node" /* node */;
119
+ } else {
120
+ return "file" /* file */;
121
+ }
122
+ }
123
+ }
124
+ throw `not a valid figma url.`;
125
+ }
126
+ }
127
+
128
+ // lib/embed-url.ts
129
+ function embed(src) {
130
+ const url = builEmbedableSourceUrl(src);
131
+ const urltype = analyze(url);
132
+ switch (urltype) {
133
+ case "embed" /* embed */:
134
+ return url;
135
+ case "file" /* file */:
136
+ console.warn(
137
+ "incomplete url input. the target node is not specified in the embedding target source url. this wont display contents as expected"
138
+ );
139
+ return _build(url);
140
+ case "node" /* node */:
141
+ return _build(url);
142
+ case "empty" /* empty */:
143
+ return;
144
+ }
145
+ }
146
+ function _build(url) {
147
+ const _embed_url = `${_FIGMA_EMBED_URL_PREFIX}?embed_host=astra&url=${url}`;
148
+ return _embed_url;
149
+ }
150
+ function builEmbedableSourceUrl(src) {
151
+ if (!src) {
152
+ return;
153
+ }
154
+ if (typeof src == "string") {
155
+ return src;
156
+ } else if ("url" in src) {
157
+ return src.url;
158
+ } else if ("fileid" in src) {
159
+ return `https://www.figma.com/design/${src.fileid}/${src.nodeid && `?node-id=${src.nodeid}`}`;
160
+ } else {
161
+ return void 0;
162
+ }
163
+ }
164
+
165
+ // lib/access-check.ts
166
+ async function isPublic(url) {
167
+ analyze(url);
168
+ {
169
+ try {
170
+ const res = await fetch(url);
171
+ return res.status == 200;
172
+ } catch (e) {
173
+ return false;
174
+ }
175
+ }
176
+ return false;
177
+ }
178
+
179
+ // lib/compare-url.ts
180
+ function isSameDesignUrl(url1, url2) {
181
+ const analysis = analyze(url1);
182
+ switch (analysis) {
183
+ case "embed" /* embed */:
184
+ case "empty" /* empty */:
185
+ case "file" /* file */:
186
+ return false;
187
+ case "node" /* node */:
188
+ const parsed = parseFileAndNodeId(url1);
189
+ const _this_parsed = parseFileAndNodeId(url2);
190
+ return _this_parsed.file === parsed.file && _this_parsed.node === parsed.node;
191
+ }
192
+ }
193
+
194
+ exports.FigmaFileOrNodeIdType = FigmaFileOrNodeIdType;
195
+ exports.FigmaUrlType = FigmaUrlType;
196
+ exports._FIGMA_BOARD_URL_PREFIX = _FIGMA_BOARD_URL_PREFIX;
197
+ exports._FIGMA_DESIGN_URL_PREFIX = _FIGMA_DESIGN_URL_PREFIX;
198
+ exports._FIGMA_EMBED_URL_PREFIX = _FIGMA_EMBED_URL_PREFIX;
199
+ exports._FIGMA_FILE_URL_PREFIX = _FIGMA_FILE_URL_PREFIX;
200
+ exports._FIGMA_SITE_URL_PREFIX = _FIGMA_SITE_URL_PREFIX;
201
+ exports._FIGMA_SLIDES_URL_PREFIX = _FIGMA_SLIDES_URL_PREFIX;
202
+ exports._PARAM_NODE_ID = _PARAM_NODE_ID;
203
+ exports.__FIGMA_DEMO_DEFAULT_FILE_ID = __FIGMA_DEMO_DEFAULT_FILE_ID;
204
+ exports.__FIGMA_DEMO_DEFAULT_FILE_NODE_URL = __FIGMA_DEMO_DEFAULT_FILE_NODE_URL;
205
+ exports.__FIGMA_DEMO_DEFAULT_FILE_URL = __FIGMA_DEMO_DEFAULT_FILE_URL;
206
+ exports.analyze = analyze;
207
+ exports.builEmbedableSourceUrl = builEmbedableSourceUrl;
208
+ exports.embed = embed;
209
+ exports.formatNodeId = formatNodeId;
210
+ exports.isPublic = isPublic;
211
+ exports.isSameDesignUrl = isSameDesignUrl;
212
+ exports.parseFileAndNodeId = parseFileAndNodeId;
213
+ exports.parseFileId = parseFileId;
214
+ //# sourceMappingURL=index.js.map
215
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../lib/constants.ts","../lib/parse-url.ts","../lib/analyze-url.ts","../lib/embed-url.ts","../lib/access-check.ts","../lib/compare-url.ts"],"names":["FigmaUrlType","FigmaFileOrNodeIdType"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * e.g. full url should look like -\n * https://www.figma.com/embed?embed_host=astra&url=https://www.figma.com/design/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0\n *\n * ref: https://www.figma.com/developers/embed\n */\nexport const _FIGMA_EMBED_URL_PREFIX = \"https://www.figma.com/embed\";\n\n/**\n * Legacy file URL prefix (for backward compatibility)\n * e.g. full url should look like -\n * https://www.figma.com/file/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0\n */\nexport const _FIGMA_FILE_URL_PREFIX = \"https://www.figma.com/file\";\n\n/**\n * Design file URL prefix (current standard, replaces /file/)\n * e.g. full url should look like -\n * https://www.figma.com/design/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0\n */\nexport const _FIGMA_DESIGN_URL_PREFIX = \"https://www.figma.com/design\";\n\n/**\n * FigJam board URL prefix\n * e.g. full url should look like -\n * https://www.figma.com/board/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0\n */\nexport const _FIGMA_BOARD_URL_PREFIX = \"https://www.figma.com/board\";\n\n/**\n * Figma Slides URL prefix\n * e.g. full url should look like -\n * https://www.figma.com/slides/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0\n */\nexport const _FIGMA_SLIDES_URL_PREFIX = \"https://www.figma.com/slides\";\n\n/**\n * Figma Site URL prefix\n * e.g. full url should look like -\n * https://www.figma.com/site/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0\n */\nexport const _FIGMA_SITE_URL_PREFIX = \"https://www.figma.com/site\";\n\n/**\n * param key for node id specification.\n *\n * e.g. - `https://www.figma.com/file/ABC/?node-id=1234` `(node-id = 1234)`\n */\nexport const _PARAM_NODE_ID = \"node-id\";\n\n// ======================================================================================================\n// escape with __ for \"super-internal\" usage\n/**\n * file id of Grida design - https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/\n */\nexport const __FIGMA_DEMO_DEFAULT_FILE_ID = \"Y0Gh77AqBoHH7dG1GtK3xF\";\nexport const __FIGMA_DEMO_DEFAULT_FILE_URL =\n \"https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/\";\nexport const __FIGMA_DEMO_DEFAULT_FILE_NODE_URL =\n \"https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=264%3A49\";\n// ======================================================================================================\n","import { FigmaTargetNodeConfig } from \"./target-node-config\";\n\n/**\n * extracts file id from share link\n *\n * Supports multiple Figma URL patterns:\n * - Old: \"https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112\"\n * - New: \"https://www.figma.com/design/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112\"\n * - New: \"https://www.figma.com/board/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112\"\n * - New: \"https://www.figma.com/slides/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112\"\n * - New: \"https://www.figma.com/site/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112\"\n *\n * out - \"Y0Gh77AqBoHH7dG1GtK3xF\"\n * @param url\n * @returns\n */\nexport function parseFileId(url: string) {\n // File ID is in the same position (4th segment) for all URL patterns\n const supportedPatterns = [\n \"https://www.figma.com/file/\",\n \"https://www.figma.com/design/\",\n \"https://www.figma.com/board/\",\n \"https://www.figma.com/slides/\",\n \"https://www.figma.com/site/\",\n ];\n\n const matchedPattern = supportedPatterns.find((pattern) =>\n url.includes(pattern)\n );\n\n if (matchedPattern) {\n return url.split(\"/\")[4];\n } else {\n throw `figma url must contain one of the supported patterns (file/, design/, board/, slides/, site/). the given was ${url}, which we cannot extract file id from it.`;\n }\n}\n\n/**\n * Figma file url's node-id changed over time, this function is to make sure we can handle both formats.\n * to keep `00:00` format\n * @param node_id\n * @returns\n */\nexport function formatNodeId(node_id: string) {\n if (\n node_id.includes(\":\") ||\n node_id.includes(\"%3A\") ||\n node_id.includes(\"-\")\n ) {\n // \"%3A\" is \":\" as in url encoding\n if (node_id.includes(\"%3A\")) {\n // decode value, assuming it is url encoded\n node_id = decodeURIComponent(node_id);\n }\n if (node_id.includes(\"-\")) {\n // if id is formatted with `-` instead of `:`, replace it.\n node_id = node_id.split(\"-\").join(\":\");\n }\n // 2. run regex\n if (node_id.match(/[0-9]+:[0-9]+/) !== null) {\n return node_id;\n }\n }\n}\n\n/**\n * pattern examples:\n * - \"https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112\"\n * - \"https://www.figma.com/design/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112\"\n * - \"https://www.figma.com/board/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112\"\n * - \"https://www.figma.com/slides/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112\"\n * - \"https://www.figma.com/site/Y0Gh77AqBoHH7dG1GtK3xF/?node-id=775%3A112\"\n * @param url\n */\nexport function parseFileAndNodeId(\n url: string\n): FigmaTargetNodeConfig | undefined {\n try {\n const _url = new URL(url);\n const params = new URLSearchParams(_url.search);\n const nodeId = formatNodeId(params.get(\"node-id\"));\n const fileId = parseFileId(url);\n return {\n url: url,\n file: fileId,\n node: nodeId,\n };\n } catch (_) {\n // empty url, invalud url\n return;\n }\n}\n","import {\n _FIGMA_EMBED_URL_PREFIX,\n _FIGMA_FILE_URL_PREFIX,\n _PARAM_NODE_ID,\n} from \"./constants\";\nimport { formatNodeId } from \"./parse-url\";\n\nexport enum FigmaUrlType {\n /**\n * embed ready url\n */\n embed = \"embed\",\n\n /**\n * file id only url. this cannot be used for embedding (cannot be used as a source)\n */\n file = \"file\",\n\n /**\n * url with file & node this can be used for embedding. (can be used as a source)\n */\n node = \"node\",\n\n /**\n * empty url. undefined or \"\"\n */\n empty = \"empty\",\n}\n\nexport enum FigmaFileOrNodeIdType {\n nodeid = \"nodeid\",\n maybe_nodeid = \"maybe_nodeid\",\n fileid = \"fileid\",\n maybe_fileid = \"maybe_fileid\",\n}\n\nexport type FigmaInputAnalysisResult = FigmaUrlType | FigmaFileOrNodeIdType;\n\nexport function analyze(url: string): FigmaInputAnalysisResult {\n if (!url) {\n // return if url is empty\n return FigmaUrlType.empty;\n }\n let _u: URL;\n\n // pre url validation\n try {\n _u = new URL(url);\n } catch (_) {\n const maybeidlike = url;\n if (maybeidlike.length > 0) {\n if (formatNodeId(maybeidlike)) {\n return FigmaFileOrNodeIdType.maybe_nodeid;\n }\n\n // e.g. kLzb7R9xYuuphfX4TssVNe\n // e.g. 4hqwYFw6FKw1njvzEl3VUh\n // fileid is 22 chars at this point.\n else if (maybeidlike.length >= 22) {\n const _taget = decodeURI(maybeidlike);\n // figma file id does not contain special characters. it's like mongodb id\n if (_taget.match(/[a-zA-Z0-9]/) !== null) {\n if (_taget.length == 22) {\n return FigmaFileOrNodeIdType.fileid;\n } else {\n return FigmaFileOrNodeIdType.maybe_fileid;\n }\n }\n }\n }\n\n throw `this url cannot be analyzed. this is not a valid url string - \"${url}\"`;\n }\n\n //\n if (url.startsWith(_FIGMA_EMBED_URL_PREFIX)) {\n return FigmaUrlType.embed;\n } else {\n // you might think the value of the embed target might be encoded,\n // so it is wrong to compare value with raw string,\n // but the only case the url is encoded is when it's for embeding\n // - which will be returned above. it's fine.\n if (_u.hostname == \"figma.com\" || _u.hostname == \"www.figma.com\") {\n // Support all Figma URL patterns: file/, design/, board/, slides/, site/\n const supportedPathPatterns = [\n \"file/\",\n \"design/\",\n \"board/\",\n \"slides/\",\n \"site/\",\n ];\n const matchedPattern = supportedPathPatterns.find((pattern) =>\n _u.pathname.includes(pattern)\n );\n\n if (matchedPattern) {\n if (_u.searchParams.get(_PARAM_NODE_ID)?.length > 0) {\n return FigmaUrlType.node;\n } else {\n return FigmaUrlType.file;\n }\n }\n }\n // otherwise,\n throw `not a valid figma url.`;\n }\n}\n","import { analyze, FigmaUrlType } from \"./analyze-url\";\nimport { _FIGMA_EMBED_URL_PREFIX } from \"./constants\";\n\nexport type FigmaEmbedInput =\n | string\n | { url: string }\n | { fileid: string; nodeid?: string };\n\n/**\n * build embedding url. - https://www.figma.com/developers/embed\n * @param src : ;\n * @returns\n */\nexport function embed(src: FigmaEmbedInput) {\n const url = builEmbedableSourceUrl(src);\n const urltype = analyze(url);\n switch (urltype) {\n case FigmaUrlType.embed:\n return url;\n case FigmaUrlType.file:\n console.warn(\n \"incomplete url input. the target node is not specified in the embedding target source url. this wont display contents as expected\"\n );\n return _build(url);\n case FigmaUrlType.node:\n return _build(url);\n case FigmaUrlType.empty:\n return;\n }\n}\n\nfunction _build(url: string) {\n const _embed_url = `${_FIGMA_EMBED_URL_PREFIX}?embed_host=astra&url=${url}`;\n return _embed_url;\n}\n\n/**\n * e.g. - https://www.figma.com/design/HSozKEVWhh8saZa2vr1Nxd?node-id=111%3A0\n *\n * (*this does not contain logic for checking if input url is valid.*)\n * @param src : ;\n * @returns\n */\nexport function builEmbedableSourceUrl(\n src?: FigmaEmbedInput\n): string | undefined {\n if (!src) {\n return;\n }\n\n if (typeof src == \"string\") {\n return src;\n } else if (\"url\" in src) {\n return src.url;\n } else if (\"fileid\" in src) {\n /// WWW prefix is required. if non passed, figma embed won't accept it.\n /// Use /design/ pattern for new URLs (replaces /file/)\n return `https://www.figma.com/design/${src.fileid}/${\n src.nodeid && `?node-id=${src.nodeid}`\n }`;\n } else {\n return undefined;\n }\n}\n","///\n/// simple functions to check if file is accessible by public.\n///\n\nimport { analyze, FigmaUrlType } from \"./analyze-url\";\n\n/**\n * e.g.\n *\n * - **ok**: (public file) - https://www.figma.com/file/Y0Gh77AqBoHH7dG1GtK3xF/grida?node-id=1545%3A247\n * - **not found**: (private file) - https://www.figma.com/file/8R57Uv5Siu1ZhhGkVIyyQg/private-file-api-demo?node-id=2%3A2\n *\n */\nexport async function isPublic(url: string): Promise<boolean> {\n const type = analyze(url);\n if (type == FigmaUrlType.embed || FigmaUrlType.file || FigmaUrlType.node) {\n try {\n const res = await fetch(url);\n return res.status == 200;\n } catch (e) {\n return false;\n }\n }\n return false;\n}\n","import { analyze, FigmaUrlType } from \"./analyze-url\";\nimport { parseFileAndNodeId } from \"./parse-url\";\n\nexport function isSameDesignUrl(url1: string, url2: string): boolean {\n const analysis = analyze(url1);\n switch (analysis) {\n case FigmaUrlType.embed:\n case FigmaUrlType.empty:\n case FigmaUrlType.file:\n return false;\n case FigmaUrlType.node:\n const parsed = parseFileAndNodeId(url1);\n const _this_parsed = parseFileAndNodeId(url2);\n return (\n _this_parsed.file === parsed.file && _this_parsed.node === parsed.node\n );\n }\n}\n"]}