@figma/code-connect 1.4.3 → 1.4.5
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/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +61 -10
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/connect_template.d.ts +36 -0
- package/dist/commands/connect_template.d.ts.map +1 -0
- package/dist/commands/connect_template.js +324 -0
- package/dist/commands/connect_template.js.map +1 -0
- package/dist/commands/preview_utils.d.ts +49 -0
- package/dist/commands/preview_utils.d.ts.map +1 -0
- package/dist/commands/preview_utils.js +451 -0
- package/dist/commands/preview_utils.js.map +1 -0
- package/dist/connect/batch_templates.d.ts +11 -0
- package/dist/connect/batch_templates.d.ts.map +1 -0
- package/dist/connect/batch_templates.js +70 -0
- package/dist/connect/batch_templates.js.map +1 -0
- package/dist/connect/create.d.ts.map +1 -1
- package/dist/connect/create.js +13 -0
- package/dist/connect/create.js.map +1 -1
- package/dist/connect/create_template.d.ts +22 -0
- package/dist/connect/create_template.d.ts.map +1 -0
- package/dist/connect/create_template.js +195 -0
- package/dist/connect/create_template.js.map +1 -0
- package/dist/connect/delete_docs.d.ts +2 -1
- package/dist/connect/delete_docs.d.ts.map +1 -1
- package/dist/connect/delete_docs.js +2 -2
- package/dist/connect/delete_docs.js.map +1 -1
- package/dist/connect/figma_rest_api.d.ts +1 -5
- package/dist/connect/figma_rest_api.d.ts.map +1 -1
- package/dist/connect/figma_rest_api.js +9 -3
- package/dist/connect/figma_rest_api.js.map +1 -1
- package/dist/connect/project.d.ts +9 -7
- package/dist/connect/project.d.ts.map +1 -1
- package/dist/connect/project.js +39 -25
- package/dist/connect/project.js.map +1 -1
- package/dist/connect/raw_templates.d.ts +8 -1
- package/dist/connect/raw_templates.d.ts.map +1 -1
- package/dist/connect/raw_templates.js +20 -7
- package/dist/connect/raw_templates.js.map +1 -1
- package/dist/connect/upload.d.ts +3 -1
- package/dist/connect/upload.d.ts.map +1 -1
- package/dist/connect/upload.js +23 -8
- package/dist/connect/upload.js.map +1 -1
- package/dist/connect/validation.d.ts +2 -2
- package/dist/connect/validation.d.ts.map +1 -1
- package/dist/connect/validation.js +4 -4
- package/dist/connect/validation.js.map +1 -1
- package/dist/connect/wizard/helpers.js.map +1 -1
- package/dist/storybook/convert.d.ts.map +1 -1
- package/dist/storybook/convert.js +1 -1
- package/dist/storybook/convert.js.map +1 -1
- package/figma-types.d.ts +3 -0
- package/package.json +8 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/connect/create.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n exitWithFeedbackMessage,\n findComponentsInDocument,\n parseFileKey,\n parseNodeIds,\n} from './helpers'\nimport fs from 'fs'\nimport { FigmaRestApi, getApiUrl, getHeaders } from './figma_rest_api'\nimport { exitWithError, logger } from '../common/logging'\nimport { callParser, handleMessages } from './parser_executables'\nimport { CodeConnectExecutableParserConfig, ProjectInfo } from './project'\nimport { createReactCodeConnect } from '../react/create'\nimport { z } from 'zod'\nimport {\n CreateRequestPayload,\n CreateRequestPayloadMulti,\n CreateResponsePayload,\n} from './parser_executable_types'\nimport { fromError } from 'zod-validation-error'\nimport { createHtmlCodeConnect } from '../html/create'\nimport { isFetchError, request } from '../common/fetch'\nimport { BaseCommand } from '../commands/connect'\n\ninterface GenerateDocsArgs {\n accessToken: string\n figmaNodeUrl: string\n outFile: string\n outDir: string\n projectInfo: ProjectInfo\n cmd: BaseCommand\n}\n\nexport function normalizeComponentName(name: string) {\n // Convert the string to PascalCase and ensure first character is not a digit\n return name\n .replace(/[^a-zA-Z0-9]/g, ' ')\n .split(' ')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join('')\n .replace(/^[0-9]/, '_$&')\n}\n\nexport async function createCodeConnectFromUrl({\n accessToken,\n figmaNodeUrl,\n outFile,\n outDir,\n projectInfo,\n cmd,\n}: GenerateDocsArgs) {\n try {\n const fileKey = parseFileKey(figmaNodeUrl)\n const nodeIds = parseNodeIds([figmaNodeUrl])\n\n const apiUrl =\n getApiUrl(figmaNodeUrl ?? '', cmd.apiUrl || projectInfo.config.apiUrl) +\n `/code_connect/${fileKey}/cli_data?ids=${nodeIds.join(',')}`\n\n if (nodeIds.length === 0) {\n exitWithError(\n `Invalid figma node URL: the provided url \"${figmaNodeUrl}\" does not contain a node-id`,\n )\n } else if (nodeIds.length > 1) {\n exitWithError(\n `Invalid figma node URL: the provided url \"${figmaNodeUrl}\" contains more than one node-id`,\n )\n }\n\n logger.info('Fetching component information from Figma...')\n const response = process.env.CODE_CONNECT_MOCK_CREATE_API_RESPONSE\n ? {\n response: { status: 200 },\n data: JSON.parse(\n fs.readFileSync(process.env.CODE_CONNECT_MOCK_CREATE_API_RESPONSE, 'utf-8'),\n ) as { document: FigmaRestApi.Node },\n }\n : await request.get<{ document: FigmaRestApi.Node }>(apiUrl, {\n headers: getHeaders(accessToken),\n })\n\n if (response.response.status === 200) {\n logger.info('Parsing response')\n const component = findComponentsInDocument(response.data.document, nodeIds)[0]\n if (component === undefined) {\n exitWithError('Could not find a component in the provided URL')\n }\n const normalizedName = normalizeComponentName(component.name)\n\n const componentPayload = {\n figmaNodeUrl,\n id: component.id,\n name: component.name,\n normalizedName,\n type: component.type,\n componentPropertyDefinitions: component.componentPropertyDefinitions,\n }\n\n logger.info('Generating Code Connect files...')\n\n let result: z.infer<typeof CreateResponsePayload>\n\n if (projectInfo.config.parser === 'react') {\n const payload: CreateRequestPayloadMulti = {\n mode: 'CREATE',\n destinationDir: outDir ?? process.env.INIT_CWD ?? process.cwd(),\n destinationFile: outFile,\n normalizedName,\n figmaConnections: [{ component: componentPayload }],\n config: projectInfo.config,\n }\n result = await createReactCodeConnect(payload)\n } else if (projectInfo.config.parser === 'html') {\n const payload: CreateRequestPayloadMulti = {\n mode: 'CREATE',\n destinationDir: outDir ?? process.env.INIT_CWD ?? process.cwd(),\n destinationFile: outFile,\n normalizedName,\n figmaConnections: [{ component: componentPayload }],\n config: projectInfo.config,\n }\n result = await createHtmlCodeConnect(payload)\n } else {\n try {\n const payload: CreateRequestPayload = {\n mode: 'CREATE',\n destinationDir: outDir ?? process.env.INIT_CWD ?? process.cwd(),\n destinationFile: outFile,\n component: componentPayload,\n config: projectInfo.config,\n verbose: cmd.verbose,\n }\n const stdout = await callParser(\n // We use `as` because the React parser makes the types difficult\n // TODO remove once React is an executable parser\n projectInfo.config as CodeConnectExecutableParserConfig,\n payload,\n projectInfo.absPath,\n )\n\n result = CreateResponsePayload.parse(stdout)\n } catch (e) {\n throw fromError(e)\n }\n }\n\n const { hasErrors } = handleMessages(result.messages)\n\n if (hasErrors) {\n exitWithError('Errors encountered calling parser, exiting')\n }\n\n logger.info('Code Connect files generated successfully:')\n result.createdFiles.forEach((file) => {\n logger.info(`${file.filePath}`)\n })\n } else {\n logger.error(\n `Failed to get node information from Figma with status: ${response.response.status}`,\n )\n logger.debug('Failed to get node information from Figma with Body:', response.data)\n }\n } catch (err) {\n if (isFetchError(err)) {\n if (err.response) {\n logger.error(\n `Failed to get node data from Figma (${err.response.status}): ${err.response.status} ${err.data?.err ?? err.data?.message}`,\n )\n } else {\n logger.error(`Failed to get node data from Figma: ${err.message}`)\n }\n logger.debug(JSON.stringify(err.data))\n } else {\n logger.error(`Failed to create: ${err}`)\n }\n exitWithFeedbackMessage(1)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../../src/connect/create.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n exitWithFeedbackMessage,\n findComponentsInDocument,\n parseFileKey,\n parseNodeIds,\n} from './helpers'\nimport fs from 'fs'\nimport { FigmaRestApi, getApiUrl, getHeaders } from './figma_rest_api'\nimport { exitWithError, logger } from '../common/logging'\nimport { callParser, handleMessages } from './parser_executables'\nimport { CodeConnectExecutableParserConfig, ProjectInfo } from './project'\nimport { createReactCodeConnect } from '../react/create'\nimport { z } from 'zod'\nimport {\n CreateRequestPayload,\n CreateRequestPayloadMulti,\n CreateResponsePayload,\n} from './parser_executable_types'\nimport { fromError } from 'zod-validation-error'\nimport { createHtmlCodeConnect } from '../html/create'\nimport { createTemplateCodeConnect } from './create_template'\nimport { isFetchError, request } from '../common/fetch'\nimport { BaseCommand } from '../commands/connect'\n\ninterface GenerateDocsArgs {\n accessToken: string\n figmaNodeUrl: string\n outFile: string\n outDir: string\n projectInfo: ProjectInfo\n cmd: BaseCommand\n}\n\nexport function normalizeComponentName(name: string) {\n // Convert the string to PascalCase and ensure first character is not a digit\n return name\n .replace(/[^a-zA-Z0-9]/g, ' ')\n .split(' ')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join('')\n .replace(/^[0-9]/, '_$&')\n}\n\nexport async function createCodeConnectFromUrl({\n accessToken,\n figmaNodeUrl,\n outFile,\n outDir,\n projectInfo,\n cmd,\n}: GenerateDocsArgs) {\n try {\n const fileKey = parseFileKey(figmaNodeUrl)\n const nodeIds = parseNodeIds([figmaNodeUrl])\n\n const apiUrl =\n getApiUrl(figmaNodeUrl ?? '', cmd.apiUrl || projectInfo.config.apiUrl) +\n `/code_connect/${fileKey}/cli_data?ids=${nodeIds.join(',')}`\n\n if (nodeIds.length === 0) {\n exitWithError(\n `Invalid figma node URL: the provided url \"${figmaNodeUrl}\" does not contain a node-id`,\n )\n } else if (nodeIds.length > 1) {\n exitWithError(\n `Invalid figma node URL: the provided url \"${figmaNodeUrl}\" contains more than one node-id`,\n )\n }\n\n logger.info('Fetching component information from Figma...')\n const response = process.env.CODE_CONNECT_MOCK_CREATE_API_RESPONSE\n ? {\n response: { status: 200 },\n data: JSON.parse(\n fs.readFileSync(process.env.CODE_CONNECT_MOCK_CREATE_API_RESPONSE, 'utf-8'),\n ) as { document: FigmaRestApi.Node },\n }\n : await request.get<{ document: FigmaRestApi.Node }>(apiUrl, {\n headers: getHeaders(accessToken),\n })\n\n if (response.response.status === 200) {\n logger.info('Parsing response')\n const component = findComponentsInDocument(response.data.document, nodeIds)[0]\n if (component === undefined) {\n exitWithError('Could not find a component in the provided URL')\n }\n const normalizedName = normalizeComponentName(component.name)\n\n const componentPayload = {\n figmaNodeUrl,\n id: component.id,\n name: component.name,\n normalizedName,\n type: component.type,\n componentPropertyDefinitions: component.componentPropertyDefinitions,\n }\n\n logger.info('Generating Code Connect files...')\n\n let result: z.infer<typeof CreateResponsePayload>\n\n if (projectInfo.config.parser === 'react') {\n const payload: CreateRequestPayloadMulti = {\n mode: 'CREATE',\n destinationDir: outDir ?? process.env.INIT_CWD ?? process.cwd(),\n destinationFile: outFile,\n normalizedName,\n figmaConnections: [{ component: componentPayload }],\n config: projectInfo.config,\n }\n result = await createReactCodeConnect(payload)\n } else if (projectInfo.config.parser === 'html') {\n const payload: CreateRequestPayloadMulti = {\n mode: 'CREATE',\n destinationDir: outDir ?? process.env.INIT_CWD ?? process.cwd(),\n destinationFile: outFile,\n normalizedName,\n figmaConnections: [{ component: componentPayload }],\n config: projectInfo.config,\n }\n result = await createHtmlCodeConnect(payload)\n } else if (!(projectInfo.config as { parser?: string }).parser) {\n const filename = createTemplateCodeConnect({\n component: componentPayload,\n normalizedName,\n destinationDir: outDir ?? process.env.INIT_CWD ?? process.cwd(),\n destinationFile: outFile,\n })\n result = {\n createdFiles: [{ filePath: filename }],\n messages: [],\n }\n } else {\n try {\n const payload: CreateRequestPayload = {\n mode: 'CREATE',\n destinationDir: outDir ?? process.env.INIT_CWD ?? process.cwd(),\n destinationFile: outFile,\n component: componentPayload,\n config: projectInfo.config,\n verbose: cmd.verbose,\n }\n const stdout = await callParser(\n // We use `as` because the React parser makes the types difficult\n // TODO remove once React is an executable parser\n projectInfo.config as CodeConnectExecutableParserConfig,\n payload,\n projectInfo.absPath,\n )\n\n result = CreateResponsePayload.parse(stdout)\n } catch (e) {\n throw fromError(e)\n }\n }\n\n const { hasErrors } = handleMessages(result.messages)\n\n if (hasErrors) {\n exitWithError('Errors encountered calling parser, exiting')\n }\n\n logger.info('Code Connect files generated successfully:')\n result.createdFiles.forEach((file) => {\n logger.info(`${file.filePath}`)\n })\n } else {\n logger.error(\n `Failed to get node information from Figma with status: ${response.response.status}`,\n )\n logger.debug('Failed to get node information from Figma with Body:', response.data)\n }\n } catch (err) {\n if (isFetchError(err)) {\n if (err.response) {\n logger.error(\n `Failed to get node data from Figma (${err.response.status}): ${err.response.status} ${err.data?.err ?? err.data?.message}`,\n )\n } else {\n logger.error(`Failed to get node data from Figma: ${err.message}`)\n }\n logger.debug(JSON.stringify(err.data))\n } else {\n logger.error(`Failed to create: ${err}`)\n }\n exitWithFeedbackMessage(1)\n }\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type FigmaConnectionComponent } from './parser_executable_types';
|
|
2
|
+
import { ProjectInfo } from './project';
|
|
3
|
+
import { BaseCommand } from '../commands/connect_template';
|
|
4
|
+
interface GenerateDocsArgs {
|
|
5
|
+
accessToken: string;
|
|
6
|
+
figmaNodeUrl: string;
|
|
7
|
+
outFile: string;
|
|
8
|
+
outDir: string;
|
|
9
|
+
projectInfo: ProjectInfo;
|
|
10
|
+
cmd: BaseCommand;
|
|
11
|
+
}
|
|
12
|
+
export declare function normalizeComponentName(name: string): string;
|
|
13
|
+
export declare function createCodeConnectFromUrl({ accessToken, figmaNodeUrl, outFile, outDir, projectInfo, cmd, }: GenerateDocsArgs): Promise<void>;
|
|
14
|
+
interface CreateTemplateArgs {
|
|
15
|
+
component: FigmaConnectionComponent;
|
|
16
|
+
normalizedName: string;
|
|
17
|
+
destinationDir: string;
|
|
18
|
+
destinationFile: string | undefined;
|
|
19
|
+
}
|
|
20
|
+
export declare function createTemplateCodeConnect(args: CreateTemplateArgs): string;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=create_template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_template.d.ts","sourceRoot":"","sources":["../../src/connect/create_template.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,2BAA2B,CAAA;AAWlC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAEvC,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAA;AAE1D,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,WAAW,CAAA;IACxB,GAAG,EAAE,WAAW,CAAA;CACjB;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,UAQlD;AAED,wBAAsB,wBAAwB,CAAC,EAC7C,WAAW,EACX,YAAY,EACZ,OAAO,EACP,MAAM,EACN,WAAW,EACX,GAAG,GACJ,EAAE,gBAAgB,iBAgFlB;AAED,UAAU,kBAAkB;IAC1B,SAAS,EAAE,wBAAwB,CAAA;IACnC,cAAc,EAAE,MAAM,CAAA;IACtB,cAAc,EAAE,MAAM,CAAA;IACtB,eAAe,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC;AA8ED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CA8C1E"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.normalizeComponentName = normalizeComponentName;
|
|
7
|
+
exports.createCodeConnectFromUrl = createCodeConnectFromUrl;
|
|
8
|
+
exports.createTemplateCodeConnect = createTemplateCodeConnect;
|
|
9
|
+
const lodash_1 = require("lodash");
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const create_common_1 = require("./create_common");
|
|
13
|
+
const helpers_1 = require("./helpers");
|
|
14
|
+
const figma_rest_api_1 = require("./figma_rest_api");
|
|
15
|
+
const logging_1 = require("../common/logging");
|
|
16
|
+
const fetch_1 = require("../common/fetch");
|
|
17
|
+
function normalizeComponentName(name) {
|
|
18
|
+
// Convert the string to PascalCase and ensure first character is not a digit
|
|
19
|
+
return name
|
|
20
|
+
.replace(/[^a-zA-Z0-9]/g, ' ')
|
|
21
|
+
.split(' ')
|
|
22
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
23
|
+
.join('')
|
|
24
|
+
.replace(/^[0-9]/, '_$&');
|
|
25
|
+
}
|
|
26
|
+
async function createCodeConnectFromUrl({ accessToken, figmaNodeUrl, outFile, outDir, projectInfo, cmd, }) {
|
|
27
|
+
try {
|
|
28
|
+
const fileKey = (0, helpers_1.parseFileKey)(figmaNodeUrl);
|
|
29
|
+
const nodeIds = (0, helpers_1.parseNodeIds)([figmaNodeUrl]);
|
|
30
|
+
const apiUrl = (0, figma_rest_api_1.getApiUrl)(figmaNodeUrl ?? '', cmd.apiUrl || projectInfo.config.apiUrl) +
|
|
31
|
+
`/code_connect/${fileKey}/cli_data?ids=${nodeIds.join(',')}`;
|
|
32
|
+
if (nodeIds.length === 0) {
|
|
33
|
+
(0, logging_1.exitWithError)(`Invalid figma node URL: the provided url "${figmaNodeUrl}" does not contain a node-id`);
|
|
34
|
+
}
|
|
35
|
+
else if (nodeIds.length > 1) {
|
|
36
|
+
(0, logging_1.exitWithError)(`Invalid figma node URL: the provided url "${figmaNodeUrl}" contains more than one node-id`);
|
|
37
|
+
}
|
|
38
|
+
logging_1.logger.info('Fetching component information from Figma...');
|
|
39
|
+
const response = process.env.CODE_CONNECT_MOCK_CREATE_API_RESPONSE
|
|
40
|
+
? {
|
|
41
|
+
response: { status: 200 },
|
|
42
|
+
data: JSON.parse(fs_1.default.readFileSync(process.env.CODE_CONNECT_MOCK_CREATE_API_RESPONSE, 'utf-8')),
|
|
43
|
+
}
|
|
44
|
+
: await fetch_1.request.get(apiUrl, {
|
|
45
|
+
headers: (0, figma_rest_api_1.getHeaders)(accessToken),
|
|
46
|
+
});
|
|
47
|
+
if (response.response.status === 200) {
|
|
48
|
+
logging_1.logger.info('Parsing response');
|
|
49
|
+
const component = (0, helpers_1.findComponentsInDocument)(response.data.document, nodeIds)[0];
|
|
50
|
+
if (component === undefined) {
|
|
51
|
+
(0, logging_1.exitWithError)('Could not find a component in the provided URL');
|
|
52
|
+
}
|
|
53
|
+
const normalizedName = normalizeComponentName(component.name);
|
|
54
|
+
const componentPayload = {
|
|
55
|
+
figmaNodeUrl,
|
|
56
|
+
id: component.id,
|
|
57
|
+
name: component.name,
|
|
58
|
+
normalizedName,
|
|
59
|
+
type: component.type,
|
|
60
|
+
componentPropertyDefinitions: component.componentPropertyDefinitions,
|
|
61
|
+
};
|
|
62
|
+
logging_1.logger.info('Generating Code Connect files...');
|
|
63
|
+
const filename = createTemplateCodeConnect({
|
|
64
|
+
component: componentPayload,
|
|
65
|
+
normalizedName,
|
|
66
|
+
destinationDir: outDir ?? process.env.INIT_CWD ?? process.cwd(),
|
|
67
|
+
destinationFile: outFile,
|
|
68
|
+
});
|
|
69
|
+
logging_1.logger.info('Code Connect file generated successfully:');
|
|
70
|
+
logging_1.logger.info(`${filename}`);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
logging_1.logger.error(`Failed to get node information from Figma with status: ${response.response.status}`);
|
|
74
|
+
logging_1.logger.debug('Failed to get node information from Figma with Body:', response.data);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
if ((0, fetch_1.isFetchError)(err)) {
|
|
79
|
+
if (err.response) {
|
|
80
|
+
logging_1.logger.error(`Failed to get node data from Figma (${err.response.status}): ${err.response.status} ${err.data?.err ?? err.data?.message}`);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
logging_1.logger.error(`Failed to get node data from Figma: ${err.message}`);
|
|
84
|
+
}
|
|
85
|
+
logging_1.logger.debug(JSON.stringify(err.data));
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
logging_1.logger.error(`Failed to create: ${err}`);
|
|
89
|
+
}
|
|
90
|
+
(0, helpers_1.exitWithFeedbackMessage)(1);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function normalizePropName(name) {
|
|
94
|
+
return name.replace(/#[0-9:]*/g, '');
|
|
95
|
+
}
|
|
96
|
+
function normalizePropValue(name) {
|
|
97
|
+
return name.replace(/[^a-zA-Z0-9]/g, '-').toLowerCase();
|
|
98
|
+
}
|
|
99
|
+
function generateCodePropName(name) {
|
|
100
|
+
return (0, lodash_1.camelCase)(name.replace(/#[0-9:]+$/g, '').replace(/[^a-zA-Z0-9\s]/g, ''));
|
|
101
|
+
}
|
|
102
|
+
function isBooleanKind(propValue) {
|
|
103
|
+
const normalized = propValue.toLowerCase();
|
|
104
|
+
return (normalized === 'true' ||
|
|
105
|
+
normalized === 'false' ||
|
|
106
|
+
normalized === 'yes' ||
|
|
107
|
+
normalized === 'no' ||
|
|
108
|
+
normalized === 'on' ||
|
|
109
|
+
normalized === 'off');
|
|
110
|
+
}
|
|
111
|
+
function isValidIdentifier(name) {
|
|
112
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name);
|
|
113
|
+
}
|
|
114
|
+
function generatePropDeclaration(propName, propDef) {
|
|
115
|
+
const codePropName = generateCodePropName(propName);
|
|
116
|
+
const figmaPropName = normalizePropName(propName);
|
|
117
|
+
if (propDef.type === 'BOOLEAN') {
|
|
118
|
+
return `const ${codePropName} = figma.selectedInstance.getBoolean("${figmaPropName}")`;
|
|
119
|
+
}
|
|
120
|
+
if (propDef.type === 'TEXT') {
|
|
121
|
+
return `const ${codePropName} = figma.selectedInstance.getString("${figmaPropName}")`;
|
|
122
|
+
}
|
|
123
|
+
if (propDef.type === 'VARIANT') {
|
|
124
|
+
const isBooleanVariant = propDef.variantOptions?.length === 2 && propDef.variantOptions.every(isBooleanKind);
|
|
125
|
+
if (isBooleanVariant) {
|
|
126
|
+
return `const ${codePropName} = figma.selectedInstance.getBoolean("${figmaPropName}")`;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const options = (propDef.variantOptions || [])
|
|
130
|
+
.map((v) => {
|
|
131
|
+
const key = isValidIdentifier(v) ? v : `"${v}"`;
|
|
132
|
+
return ` ${key}: "${normalizePropValue(v)}"`;
|
|
133
|
+
})
|
|
134
|
+
.join(',\n');
|
|
135
|
+
return `const ${codePropName} = figma.selectedInstance.getEnum("${figmaPropName}", {\n${options},\n})`;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
function generateTemplateBody(component) {
|
|
141
|
+
const defs = component.componentPropertyDefinitions || {};
|
|
142
|
+
const declarations = [];
|
|
143
|
+
for (const [propName, propDef] of Object.entries(defs)) {
|
|
144
|
+
const decl = generatePropDeclaration(propName, propDef);
|
|
145
|
+
if (decl) {
|
|
146
|
+
declarations.push(decl);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
declarations: declarations.join('\n'),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function createTemplateCodeConnect(args) {
|
|
154
|
+
const { component, normalizedName, destinationDir, destinationFile } = args;
|
|
155
|
+
const filePath = (0, create_common_1.getOutFileName)({
|
|
156
|
+
outFile: destinationFile,
|
|
157
|
+
outDir: destinationDir,
|
|
158
|
+
sourceFilename: normalizedName,
|
|
159
|
+
extension: 'ts',
|
|
160
|
+
});
|
|
161
|
+
const { declarations } = generateTemplateBody(component);
|
|
162
|
+
const codeConnect = [
|
|
163
|
+
`// url=${component.figmaNodeUrl}`,
|
|
164
|
+
`import figma from "figma"`,
|
|
165
|
+
'',
|
|
166
|
+
`/**`,
|
|
167
|
+
` * NEXT STEPS:`,
|
|
168
|
+
` * - Replace the \`example\` with the actual code snippet you want to show`,
|
|
169
|
+
` * (e.g. figma.code\`<Button label="\${propertyValue}" />\`)`,
|
|
170
|
+
` * - Update the \`imports\` array with any lines of code that should be displayed`,
|
|
171
|
+
` * at the top (e.g. imports: ['import { Button } from "./Button"'])`,
|
|
172
|
+
` */`,
|
|
173
|
+
'',
|
|
174
|
+
declarations || null,
|
|
175
|
+
declarations ? '' : null,
|
|
176
|
+
`export default {`,
|
|
177
|
+
` example: figma.code\`\`,`,
|
|
178
|
+
` imports: [],`,
|
|
179
|
+
` id: "${normalizedName}",`,
|
|
180
|
+
` metadata: {`,
|
|
181
|
+
` nestable: true,`,
|
|
182
|
+
` },`,
|
|
183
|
+
`}`,
|
|
184
|
+
'',
|
|
185
|
+
]
|
|
186
|
+
.filter((line) => line !== null)
|
|
187
|
+
.join('\n');
|
|
188
|
+
if (fs_1.default.existsSync(filePath)) {
|
|
189
|
+
(0, logging_1.exitWithError)(`File ${filePath} already exists, skipping creation`);
|
|
190
|
+
}
|
|
191
|
+
fs_1.default.mkdirSync(path_1.default.dirname(filePath), { recursive: true });
|
|
192
|
+
fs_1.default.writeFileSync(filePath, codeConnect);
|
|
193
|
+
return filePath;
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=create_template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create_template.js","sourceRoot":"","sources":["../../src/connect/create_template.ts"],"names":[],"mappings":"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","sourcesContent":["import { camelCase } from 'lodash'\nimport fs from 'fs'\nimport {\n type ComponentPropertyDefinition,\n type FigmaConnectionComponent,\n} from './parser_executable_types'\nimport path from 'path'\nimport { getOutFileName } from './create_common'\nimport {\n exitWithFeedbackMessage,\n findComponentsInDocument,\n parseFileKey,\n parseNodeIds,\n} from './helpers'\nimport { FigmaRestApi, getApiUrl, getHeaders } from './figma_rest_api'\nimport { exitWithError, logger } from '../common/logging'\nimport { ProjectInfo } from './project'\nimport { isFetchError, request } from '../common/fetch'\nimport { BaseCommand } from '../commands/connect_template'\n\ninterface GenerateDocsArgs {\n accessToken: string\n figmaNodeUrl: string\n outFile: string\n outDir: string\n projectInfo: ProjectInfo\n cmd: BaseCommand\n}\n\nexport function normalizeComponentName(name: string) {\n // Convert the string to PascalCase and ensure first character is not a digit\n return name\n .replace(/[^a-zA-Z0-9]/g, ' ')\n .split(' ')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join('')\n .replace(/^[0-9]/, '_$&')\n}\n\nexport async function createCodeConnectFromUrl({\n accessToken,\n figmaNodeUrl,\n outFile,\n outDir,\n projectInfo,\n cmd,\n}: GenerateDocsArgs) {\n try {\n const fileKey = parseFileKey(figmaNodeUrl)\n const nodeIds = parseNodeIds([figmaNodeUrl])\n\n const apiUrl =\n getApiUrl(figmaNodeUrl ?? '', cmd.apiUrl || projectInfo.config.apiUrl) +\n `/code_connect/${fileKey}/cli_data?ids=${nodeIds.join(',')}`\n\n if (nodeIds.length === 0) {\n exitWithError(\n `Invalid figma node URL: the provided url \"${figmaNodeUrl}\" does not contain a node-id`,\n )\n } else if (nodeIds.length > 1) {\n exitWithError(\n `Invalid figma node URL: the provided url \"${figmaNodeUrl}\" contains more than one node-id`,\n )\n }\n\n logger.info('Fetching component information from Figma...')\n const response = process.env.CODE_CONNECT_MOCK_CREATE_API_RESPONSE\n ? {\n response: { status: 200 },\n data: JSON.parse(\n fs.readFileSync(process.env.CODE_CONNECT_MOCK_CREATE_API_RESPONSE, 'utf-8'),\n ) as { document: FigmaRestApi.Node },\n }\n : await request.get<{ document: FigmaRestApi.Node }>(apiUrl, {\n headers: getHeaders(accessToken),\n })\n\n if (response.response.status === 200) {\n logger.info('Parsing response')\n const component = findComponentsInDocument(response.data.document, nodeIds)[0]\n if (component === undefined) {\n exitWithError('Could not find a component in the provided URL')\n }\n const normalizedName = normalizeComponentName(component.name)\n\n const componentPayload = {\n figmaNodeUrl,\n id: component.id,\n name: component.name,\n normalizedName,\n type: component.type,\n componentPropertyDefinitions: component.componentPropertyDefinitions,\n }\n\n logger.info('Generating Code Connect files...')\n\n const filename = createTemplateCodeConnect({\n component: componentPayload,\n normalizedName,\n destinationDir: outDir ?? process.env.INIT_CWD ?? process.cwd(),\n destinationFile: outFile,\n })\n\n logger.info('Code Connect file generated successfully:')\n logger.info(`${filename}`)\n } else {\n logger.error(\n `Failed to get node information from Figma with status: ${response.response.status}`,\n )\n logger.debug('Failed to get node information from Figma with Body:', response.data)\n }\n } catch (err) {\n if (isFetchError(err)) {\n if (err.response) {\n logger.error(\n `Failed to get node data from Figma (${err.response.status}): ${err.response.status} ${err.data?.err ?? err.data?.message}`,\n )\n } else {\n logger.error(`Failed to get node data from Figma: ${err.message}`)\n }\n logger.debug(JSON.stringify(err.data))\n } else {\n logger.error(`Failed to create: ${err}`)\n }\n exitWithFeedbackMessage(1)\n }\n}\n\ninterface CreateTemplateArgs {\n component: FigmaConnectionComponent\n normalizedName: string\n destinationDir: string\n destinationFile: string | undefined\n}\n\nfunction normalizePropName(name: string) {\n return name.replace(/#[0-9:]*/g, '')\n}\n\nfunction normalizePropValue(name: string) {\n return name.replace(/[^a-zA-Z0-9]/g, '-').toLowerCase()\n}\n\nfunction generateCodePropName(name: string) {\n return camelCase(name.replace(/#[0-9:]+$/g, '').replace(/[^a-zA-Z0-9\\s]/g, ''))\n}\n\nfunction isBooleanKind(propValue: string) {\n const normalized = propValue.toLowerCase()\n return (\n normalized === 'true' ||\n normalized === 'false' ||\n normalized === 'yes' ||\n normalized === 'no' ||\n normalized === 'on' ||\n normalized === 'off'\n )\n}\n\nfunction isValidIdentifier(name: string): boolean {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(name)\n}\n\nfunction generatePropDeclaration(\n propName: string,\n propDef: ComponentPropertyDefinition,\n): string | null {\n const codePropName = generateCodePropName(propName)\n const figmaPropName = normalizePropName(propName)\n\n if (propDef.type === 'BOOLEAN') {\n return `const ${codePropName} = figma.selectedInstance.getBoolean(\"${figmaPropName}\")`\n }\n if (propDef.type === 'TEXT') {\n return `const ${codePropName} = figma.selectedInstance.getString(\"${figmaPropName}\")`\n }\n if (propDef.type === 'VARIANT') {\n const isBooleanVariant =\n propDef.variantOptions?.length === 2 && propDef.variantOptions.every(isBooleanKind)\n if (isBooleanVariant) {\n return `const ${codePropName} = figma.selectedInstance.getBoolean(\"${figmaPropName}\")`\n } else {\n const options = (propDef.variantOptions || [])\n .map((v) => {\n const key = isValidIdentifier(v) ? v : `\"${v}\"`\n return ` ${key}: \"${normalizePropValue(v)}\"`\n })\n .join(',\\n')\n return `const ${codePropName} = figma.selectedInstance.getEnum(\"${figmaPropName}\", {\\n${options},\\n})`\n }\n }\n return null\n}\n\nfunction generateTemplateBody(component: FigmaConnectionComponent) {\n const defs = component.componentPropertyDefinitions || {}\n\n const declarations: string[] = []\n\n for (const [propName, propDef] of Object.entries(defs)) {\n const decl = generatePropDeclaration(propName, propDef)\n if (decl) {\n declarations.push(decl)\n }\n }\n\n return {\n declarations: declarations.join('\\n'),\n }\n}\n\nexport function createTemplateCodeConnect(args: CreateTemplateArgs): string {\n const { component, normalizedName, destinationDir, destinationFile } = args\n\n const filePath = getOutFileName({\n outFile: destinationFile,\n outDir: destinationDir,\n sourceFilename: normalizedName,\n extension: 'ts',\n })\n\n const { declarations } = generateTemplateBody(component)\n\n const codeConnect = [\n `// url=${component.figmaNodeUrl}`,\n `import figma from \"figma\"`,\n '',\n `/**`,\n ` * NEXT STEPS:`,\n ` * - Replace the \\`example\\` with the actual code snippet you want to show`,\n ` * (e.g. figma.code\\`<Button label=\"\\${propertyValue}\" />\\`)`,\n ` * - Update the \\`imports\\` array with any lines of code that should be displayed`,\n ` * at the top (e.g. imports: ['import { Button } from \"./Button\"'])`,\n ` */`,\n '',\n declarations || null,\n declarations ? '' : null,\n `export default {`,\n ` example: figma.code\\`\\`,`,\n ` imports: [],`,\n ` id: \"${normalizedName}\",`,\n ` metadata: {`,\n ` nestable: true,`,\n ` },`,\n `}`,\n '',\n ]\n .filter((line) => line !== null)\n .join('\\n')\n\n if (fs.existsSync(filePath)) {\n exitWithError(`File ${filePath} already exists, skipping creation`)\n }\n fs.mkdirSync(path.dirname(filePath), { recursive: true })\n fs.writeFileSync(filePath, codeConnect)\n\n return filePath\n}\n"]}
|
|
@@ -4,9 +4,10 @@ interface NodesToDeleteInfo {
|
|
|
4
4
|
}
|
|
5
5
|
interface Args {
|
|
6
6
|
accessToken: string;
|
|
7
|
+
useOAuth?: boolean;
|
|
7
8
|
docs: NodesToDeleteInfo[];
|
|
8
9
|
apiUrl?: string;
|
|
9
10
|
}
|
|
10
|
-
export declare function delete_docs({ accessToken, docs, apiUrl: apiUrlOverride }: Args): Promise<void>;
|
|
11
|
+
export declare function delete_docs({ accessToken, useOAuth, docs, apiUrl: apiUrlOverride, }: Args): Promise<void>;
|
|
11
12
|
export {};
|
|
12
13
|
//# sourceMappingURL=delete_docs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete_docs.d.ts","sourceRoot":"","sources":["../../src/connect/delete_docs.ts"],"names":[],"mappings":"AAKA,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,UAAU,IAAI;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,iBAAiB,EAAE,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAsB,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"delete_docs.d.ts","sourceRoot":"","sources":["../../src/connect/delete_docs.ts"],"names":[],"mappings":"AAKA,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,UAAU,IAAI;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,EAAE,iBAAiB,EAAE,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAsB,WAAW,CAAC,EAChC,WAAW,EACX,QAAgB,EAChB,IAAI,EACJ,MAAM,EAAE,cAAc,GACvB,EAAE,IAAI,iBA+EN"}
|
|
@@ -5,12 +5,12 @@ const fetch_1 = require("../common/fetch");
|
|
|
5
5
|
const logging_1 = require("../common/logging");
|
|
6
6
|
const figma_rest_api_1 = require("./figma_rest_api");
|
|
7
7
|
const helpers_1 = require("./helpers");
|
|
8
|
-
async function delete_docs({ accessToken, docs, apiUrl: apiUrlOverride }) {
|
|
8
|
+
async function delete_docs({ accessToken, useOAuth = false, docs, apiUrl: apiUrlOverride, }) {
|
|
9
9
|
const apiUrl = (0, figma_rest_api_1.getApiUrl)(docs?.[0]?.figmaNode ?? '', apiUrlOverride) + '/code_connect';
|
|
10
10
|
try {
|
|
11
11
|
logging_1.logger.info(`Unpublishing Code Connect files from Figma...`);
|
|
12
12
|
const response = await fetch_1.request.delete(apiUrl, { nodes_to_delete: docs }, {
|
|
13
|
-
headers: (0, figma_rest_api_1.getHeaders)(accessToken),
|
|
13
|
+
headers: (0, figma_rest_api_1.getHeaders)(accessToken, useOAuth),
|
|
14
14
|
});
|
|
15
15
|
const responseData = response.data;
|
|
16
16
|
const result = responseData.meta ?? response.data;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete_docs.js","sourceRoot":"","sources":["../../src/connect/delete_docs.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"delete_docs.js","sourceRoot":"","sources":["../../src/connect/delete_docs.ts"],"names":[],"mappings":"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","sourcesContent":["import { isFetchError, request } from '../common/fetch'\nimport { logger } from '../common/logging'\nimport { getApiUrl, getHeaders } from './figma_rest_api'\nimport { exitWithFeedbackMessage } from './helpers'\n\ninterface NodesToDeleteInfo {\n figmaNode: string\n label: string\n}\n\ninterface Args {\n accessToken: string\n useOAuth?: boolean\n docs: NodesToDeleteInfo[]\n apiUrl?: string\n}\n\nexport async function delete_docs({\n accessToken,\n useOAuth = false,\n docs,\n apiUrl: apiUrlOverride,\n}: Args) {\n const apiUrl = getApiUrl(docs?.[0]?.figmaNode ?? '', apiUrlOverride) + '/code_connect'\n\n try {\n logger.info(`Unpublishing Code Connect files from Figma...`)\n\n const response = await request.delete(\n apiUrl,\n { nodes_to_delete: docs },\n {\n headers: getHeaders(accessToken, useOAuth),\n },\n )\n\n interface DeleteResult {\n success: boolean\n deleted_count: number\n failed_count: number\n deleted_nodes: Array<{ figmaNode: string; label: string }>\n failed_nodes: Array<{ figmaNode: string; label: string; reason: string }>\n }\n\n const responseData = response.data as {\n meta?: DeleteResult\n }\n\n const result: DeleteResult = responseData.meta ?? (response.data as DeleteResult)\n\n if (result.deleted_count > 0) {\n logger.info(\n `\\nSuccessfully deleted ${\n result.deleted_count\n } Code Connect mapping(s):\\n${result.deleted_nodes\n .map((doc) => `${doc.figmaNode} (${doc.label})`)\n .join('\\n')}`,\n )\n }\n\n if (result.failed_count > 0) {\n logger.error(\n `\\nFailed to delete ${result.failed_count} Code Connect mapping(s):\\n${result.failed_nodes\n .map((doc) => `✗ ${doc.figmaNode} (${doc.label}): ${doc.reason}`)\n .join('\\n')}`,\n )\n exitWithFeedbackMessage(1)\n }\n\n if (result.deleted_count === 0 && result.failed_count === 0) {\n logger.warn('No Code Connect mappings were found to delete.')\n }\n } catch (err) {\n if (isFetchError(err)) {\n if (err.response) {\n // Provide more specific error message based on status code\n if (err.response.status === 400) {\n const errorMsg = err.data?.err ?? err.data?.message ?? 'Bad request'\n if (errorMsg.includes('insufficient permissions')) {\n logger.error(`Insufficient permissions to unpublish Code Connect for this file.`)\n } else if (errorMsg.includes('Failed to parse')) {\n logger.error(`Invalid Figma URL format in the request.`)\n } else {\n logger.error(`Failed to unpublish from Figma: ${errorMsg}`)\n }\n } else {\n logger.error(\n `Failed to unpublish from Figma (${err.response.status}): ${\n err.data?.err ?? err.data?.message ?? 'Unknown error'\n }`,\n )\n }\n } else {\n logger.error(`Failed to unpublish from Figma: ${err.message}`)\n }\n logger.debug(JSON.stringify(err.data))\n } else {\n logger.error(`Failed to delete docs: ${err}`)\n }\n exitWithFeedbackMessage(1)\n }\n}\n"]}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
export declare function getApiUrl(figmaNode: string, apiUrlOverride?: string): string;
|
|
2
|
-
export declare function getHeaders(
|
|
3
|
-
'X-Figma-Token': string;
|
|
4
|
-
'Content-Type': string;
|
|
5
|
-
'User-Agent': string;
|
|
6
|
-
};
|
|
2
|
+
export declare function getHeaders(token: string, useOAuth?: boolean): Record<string, string>;
|
|
7
3
|
export declare namespace FigmaRestApi {
|
|
8
4
|
enum ComponentPropertyType {
|
|
9
5
|
Boolean = "BOOLEAN",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"figma_rest_api.d.ts","sourceRoot":"","sources":["../../src/connect/figma_rest_api.ts"],"names":[],"mappings":"AAKA,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,UAMnE;AAED,wBAAgB,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"figma_rest_api.d.ts","sourceRoot":"","sources":["../../src/connect/figma_rest_api.ts"],"names":[],"mappings":"AAKA,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,UAMnE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,UAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWlF;AAGD,yBAAiB,YAAY,CAAC;IAC5B,KAAY,qBAAqB;QAC/B,OAAO,YAAY;QACnB,YAAY,kBAAkB;QAC9B,IAAI,SAAS;QACb,OAAO,YAAY;KACpB;IAED,UAAiB,2BAA2B;QAC1C,YAAY,EAAE,OAAO,GAAG,MAAM,CAAA;QAC9B,IAAI,EAAE,qBAAqB,CAAA;QAC3B;;WAEG;QACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;QACzB;;WAEG;QACH,eAAe,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,EAAE,CAAA;KAClD;IAED,UAAiB,IAAI;QAEnB,IAAI,EAAE,WAAW,GAAG,eAAe,GAAG,OAAO,GAAG,QAAQ,CAAA;QACxD,IAAI,EAAE,MAAM,CAAA;QACZ,EAAE,EAAE,MAAM,CAAA;QACV,QAAQ,EAAE,IAAI,EAAE,CAAA;KACjB;IAED,UAAiB,gBAAiB,SAAQ,IAAI;QAC5C,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,MAAM,CAAA;KACjB;IAED,UAAiB,SAAU,SAAQ,gBAAgB;QACjD,IAAI,EAAE,WAAW,GAAG,eAAe,CAAA;QACnC,4BAA4B,EAAE,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAA;KAC1E;CACF;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAgC9F"}
|
|
@@ -14,12 +14,18 @@ function getApiUrl(figmaNode, apiUrlOverride) {
|
|
|
14
14
|
}
|
|
15
15
|
return 'https://api.figma.com/v1';
|
|
16
16
|
}
|
|
17
|
-
function getHeaders(
|
|
18
|
-
|
|
19
|
-
'X-Figma-Token': accessToken,
|
|
17
|
+
function getHeaders(token, useOAuth = false) {
|
|
18
|
+
const headers = {
|
|
20
19
|
'Content-Type': 'application/json',
|
|
21
20
|
'User-Agent': `code-connect-cli/${version}`,
|
|
22
21
|
};
|
|
22
|
+
if (useOAuth) {
|
|
23
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
headers['X-Figma-Token'] = token;
|
|
27
|
+
}
|
|
28
|
+
return headers;
|
|
23
29
|
}
|
|
24
30
|
// These typings are a subset of the Figma REST API
|
|
25
31
|
var FigmaRestApi;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"figma_rest_api.js","sourceRoot":"","sources":["../../src/connect/figma_rest_api.ts"],"names":[],"mappings":";;;AAKA,8BAMC;AAED,
|
|
1
|
+
{"version":3,"file":"figma_rest_api.js","sourceRoot":"","sources":["../../src/connect/figma_rest_api.ts"],"names":[],"mappings":"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","sourcesContent":["import { isFetchError, request } from '../common/fetch'\nimport { logger } from '../common/logging'\n\nconst version = require('../../package.json').version\n\nexport function getApiUrl(figmaNode: string, apiUrlOverride?: string) {\n if (apiUrlOverride) {\n logger.debug(`Using custom API URL: ${apiUrlOverride}`)\n return apiUrlOverride\n }\n return 'https://api.figma.com/v1'\n}\n\nexport function getHeaders(token: string, useOAuth = false): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'User-Agent': `code-connect-cli/${version}`,\n }\n if (useOAuth) {\n headers['Authorization'] = `Bearer ${token}`\n } else {\n headers['X-Figma-Token'] = token\n }\n return headers\n}\n\n// These typings are a subset of the Figma REST API\nexport namespace FigmaRestApi {\n export enum ComponentPropertyType {\n Boolean = 'BOOLEAN',\n InstanceSwap = 'INSTANCE_SWAP',\n Text = 'TEXT',\n Variant = 'VARIANT',\n }\n\n export interface ComponentPropertyDefinition {\n defaultValue: boolean | string\n type: ComponentPropertyType\n /**\n * All possible values for this property. Only exists on VARIANT properties\n */\n variantOptions?: string[]\n /**\n * Only exists on INSTANCE_SWAP properties\n */\n preferredValues?: { type: string; key: string }[]\n }\n\n export interface Node {\n // we don't care about other node types\n type: 'COMPONENT' | 'COMPONENT_SET' | 'OTHER' | 'CANVAS'\n name: string\n id: string\n children: Node[]\n }\n\n export interface NodeWithPageInfo extends Node {\n pageId: string\n pageName: string\n }\n\n export interface Component extends NodeWithPageInfo {\n type: 'COMPONENT' | 'COMPONENT_SET'\n componentPropertyDefinitions: Record<string, ComponentPropertyDefinition>\n }\n}\n\nexport async function getDocument(url: string, accessToken: string): Promise<FigmaRestApi.Node> {\n try {\n logger.info('Fetching component information from Figma...')\n const response = await request.get<{ document: FigmaRestApi.Node }>(url, {\n headers: getHeaders(accessToken),\n })\n\n if (response.response.status === 200) {\n logger.info('Successfully fetched component information from Figma')\n return response.data.document\n } else {\n logger.error(\n `Failed to get node information from Figma with status: ${response.response.status}`,\n )\n logger.debug('Failed to get node information from Figma with Body:', response.data)\n return Promise.reject()\n }\n } catch (err) {\n if (isFetchError(err)) {\n if (err.response) {\n logger.error(\n `Failed to get node data from Figma (${err.response.status}): ${err.response.status} ${err.data?.err ?? err.data?.message}`,\n )\n } else {\n logger.error(`Failed to get node data from Figma: ${err.message}`)\n }\n logger.debug(JSON.stringify(err.data))\n } else {\n logger.error(`Failed to create: ${err}`)\n }\n return Promise.reject()\n }\n}\n"]}
|
|
@@ -33,7 +33,7 @@ export type BaseCodeConnectConfig = {
|
|
|
33
33
|
/**
|
|
34
34
|
* The parser name, if using an internal parser.
|
|
35
35
|
*/
|
|
36
|
-
parser
|
|
36
|
+
parser?: CodeConnectParser;
|
|
37
37
|
/**
|
|
38
38
|
* Label to use for the uploaded code examples
|
|
39
39
|
*/
|
|
@@ -98,12 +98,14 @@ export type CodeConnectReactConfig = BaseCodeConnectConfig & {
|
|
|
98
98
|
};
|
|
99
99
|
};
|
|
100
100
|
export type CodeConnectHtmlConfig = BaseCodeConnectConfig & {};
|
|
101
|
-
export type CodeConnectParserlessConfig =
|
|
102
|
-
|
|
101
|
+
export type CodeConnectParserlessConfig = BaseCodeConnectConfig & {
|
|
102
|
+
parser: undefined;
|
|
103
|
+
};
|
|
104
|
+
export type CodeConnectConfig = CodeConnectReactConfig | CodeConnectExecutableParserConfig | CodeConnectCustomExecutableParserConfig | CodeConnectHtmlConfig | BaseCodeConnectConfig | CodeConnectParserlessConfig;
|
|
103
105
|
interface FigmaConfig {
|
|
104
106
|
codeConnect?: CodeConnectConfig;
|
|
105
107
|
}
|
|
106
|
-
export declare function determineConfigFromProject(dir: string, exitOnError?: boolean): FigmaConfig | undefined;
|
|
108
|
+
export declare function determineConfigFromProject(dir: string, exitOnError?: boolean, isTemplatesOnlyCLI?: boolean): FigmaConfig | undefined;
|
|
107
109
|
export declare function determineLabelFromProject(dir: string): string | undefined;
|
|
108
110
|
export declare function getGitRemoteURL(repoPath: string): string;
|
|
109
111
|
/**
|
|
@@ -148,7 +150,7 @@ export type ReactProjectInfo = ProjectInfo<CodeConnectReactConfig> & {
|
|
|
148
150
|
};
|
|
149
151
|
export declare function getDefaultConfigPath(dir: string): string;
|
|
150
152
|
export declare function getEnvPath(dir: string): string;
|
|
151
|
-
export declare function parseOrDetermineConfig(dir: string, configPath: string): Promise<{
|
|
153
|
+
export declare function parseOrDetermineConfig(dir: string, configPath: string, isTemplatesOnlyCLI?: boolean): Promise<{
|
|
152
154
|
config: CodeConnectConfig;
|
|
153
155
|
hasConfigFile: boolean;
|
|
154
156
|
}>;
|
|
@@ -166,7 +168,7 @@ export declare function checkForEnvAndToken(dir: string): Promise<{
|
|
|
166
168
|
* @param config Code Connect config
|
|
167
169
|
* @returns Object containing information about the project
|
|
168
170
|
*/
|
|
169
|
-
export declare function getProjectInfoFromConfig(dir: string, config: CodeConnectConfig): Promise<ProjectInfo>;
|
|
171
|
+
export declare function getProjectInfoFromConfig(dir: string, config: CodeConnectConfig, isTemplatesOnlyCLI?: boolean): Promise<ProjectInfo>;
|
|
170
172
|
/**
|
|
171
173
|
* Gets information about a project from a directory.
|
|
172
174
|
*
|
|
@@ -174,7 +176,7 @@ export declare function getProjectInfoFromConfig(dir: string, config: CodeConnec
|
|
|
174
176
|
* @param configPath Optional path to Code Connect config file
|
|
175
177
|
* @returns Object containing information about the project
|
|
176
178
|
*/
|
|
177
|
-
export declare function getProjectInfo(dir: string, configPath: string): Promise<ProjectInfo>;
|
|
179
|
+
export declare function getProjectInfo(dir: string, configPath: string, isTemplatesOnlyCLI?: boolean): Promise<ProjectInfo>;
|
|
178
180
|
export declare function getReactProjectInfo(projectInfo: ProjectInfo<CodeConnectReactConfig>): ReactProjectInfo;
|
|
179
181
|
export declare function getTsProgram(projectInfo: ProjectInfo<CodeConnectConfig>): ts.Program;
|
|
180
182
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/connect/project.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,YAAY,CAAA;AAO3B,OAAO,EAAoB,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAKpF,eAAO,MAAM,+BAA+B;;;;;;;CAQ3C,CAAA;AAED,eAAO,MAAM,wBAAwB,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAG/E,CAAA;AAGD,MAAM,MAAM,2BAA2B,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,GAAG,eAAe,CAAA;AAK1F,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,GAAG,2BAA2B,CAAA;AAE9E,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB;;;;OAIG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjD;;OAEG;IACH,MAAM,EAAE,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/connect/project.ts"],"names":[],"mappings":"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"}
|