@figma/code-connect 1.4.2 → 1.4.4
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/README.md +2 -22
- package/dist/commands/connect.d.ts +5 -2
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +93 -29
- 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/filter_project_info.d.ts +7 -0
- package/dist/commands/filter_project_info.d.ts.map +1 -0
- package/dist/commands/filter_project_info.js +32 -0
- package/dist/commands/filter_project_info.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 +390 -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/intrinsics.d.ts +3 -3
- package/dist/connect/intrinsics.d.ts.map +1 -1
- package/dist/connect/intrinsics.js +21 -10
- package/dist/connect/intrinsics.js.map +1 -1
- package/dist/connect/migration_helpers.d.ts +10 -3
- package/dist/connect/migration_helpers.d.ts.map +1 -1
- package/dist/connect/migration_helpers.js +43 -22
- package/dist/connect/migration_helpers.js.map +1 -1
- package/dist/connect/parser_common.d.ts +3 -2
- package/dist/connect/parser_common.d.ts.map +1 -1
- package/dist/connect/parser_common.js +2 -2
- package/dist/connect/parser_common.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/html/parser.d.ts +2 -2
- package/dist/html/parser.d.ts.map +1 -1
- package/dist/html/parser.js +7 -5
- package/dist/html/parser.js.map +1 -1
- package/dist/react/parser.d.ts +3 -3
- package/dist/react/parser.d.ts.map +1 -1
- package/dist/react/parser.js +9 -7
- package/dist/react/parser.js.map +1 -1
- package/dist/storybook/convert.d.ts +7 -1
- package/dist/storybook/convert.d.ts.map +1 -1
- package/dist/storybook/convert.js +11 -4
- package/dist/storybook/convert.js.map +1 -1
- package/{figma-module.d.ts → figma-types.d.ts} +13 -3
- package/package.json +8 -4
|
@@ -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"]}
|
|
@@ -88,9 +88,9 @@ export type Intrinsic = FigmaBoolean | FigmaEnum | FigmaString | FigmaInstance |
|
|
|
88
88
|
* @returns
|
|
89
89
|
*/
|
|
90
90
|
export declare function parseIntrinsic(exp: ts.CallExpression, parserContext: ParserContext): Intrinsic;
|
|
91
|
-
export declare function valueToString(value: ValueMappingKind, childLayer?: string): string;
|
|
92
|
-
export declare function valueMappingToString(valueMapping: ValueMapping, childLayer?: string): string;
|
|
93
|
-
export declare function intrinsicToString({ kind, args, modifiers }: Intrinsic, childLayer?: string): string;
|
|
91
|
+
export declare function valueToString(value: ValueMappingKind, childLayer?: string, isForMigration?: boolean): string;
|
|
92
|
+
export declare function valueMappingToString(valueMapping: ValueMapping, childLayer?: string, isForMigration?: boolean): string;
|
|
93
|
+
export declare function intrinsicToString({ kind, args, modifiers }: Intrinsic, childLayer?: string, isForMigration?: boolean): string;
|
|
94
94
|
/**
|
|
95
95
|
* Parses the `props` field in a `figma.connect()` call, returning a mapping of
|
|
96
96
|
* prop names to their respective intrinsic types
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intrinsics.d.ts","sourceRoot":"","sources":["../../src/connect/intrinsics.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"intrinsics.d.ts","sourceRoot":"","sources":["../../src/connect/intrinsics.ts"],"names":[],"mappings":"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"}
|
|
@@ -322,7 +322,7 @@ function parseIntrinsic(exp, parserContext) {
|
|
|
322
322
|
function replaceNewlines(str) {
|
|
323
323
|
return str.toString().replaceAll('\n', '\\n').replaceAll("'", "\\'");
|
|
324
324
|
}
|
|
325
|
-
function valueToString(value, childLayer) {
|
|
325
|
+
function valueToString(value, childLayer, isForMigration) {
|
|
326
326
|
if (typeof value === 'boolean' || typeof value === 'number' || typeof value === 'undefined') {
|
|
327
327
|
return `${value}`;
|
|
328
328
|
}
|
|
@@ -331,7 +331,7 @@ function valueToString(value, childLayer) {
|
|
|
331
331
|
}
|
|
332
332
|
if ('kind' in value) {
|
|
333
333
|
// Mappings can be nested, e.g. an enum value can be figma.instance(...)
|
|
334
|
-
return `${intrinsicToString(value, childLayer)}`;
|
|
334
|
+
return `${intrinsicToString(value, childLayer, isForMigration)}`;
|
|
335
335
|
}
|
|
336
336
|
// Convert objects to strings
|
|
337
337
|
const str = typeof value.$value === 'string' ? value.$value : `${JSON.stringify(value.$value)}`;
|
|
@@ -355,19 +355,19 @@ function valueToString(value, childLayer) {
|
|
|
355
355
|
throw new parser_common_1.InternalError(`Unknown helper type: ${value}`);
|
|
356
356
|
}
|
|
357
357
|
}
|
|
358
|
-
function valueMappingToString(valueMapping, childLayer) {
|
|
358
|
+
function valueMappingToString(valueMapping, childLayer, isForMigration) {
|
|
359
359
|
// For enums (and booleans with a valueMapping provided), convert the
|
|
360
360
|
// value mapping to an object.
|
|
361
361
|
return ('{\n' +
|
|
362
362
|
Object.entries(valueMapping)
|
|
363
363
|
.map(([key, value]) => {
|
|
364
|
-
return `"${key}": ${valueToString(value, childLayer)}`;
|
|
364
|
+
return `"${key}": ${valueToString(value, childLayer, isForMigration)}`;
|
|
365
365
|
})
|
|
366
366
|
.join(',\n') +
|
|
367
367
|
'}');
|
|
368
368
|
}
|
|
369
369
|
let nestedLayerCount = 0;
|
|
370
|
-
function intrinsicToString({ kind, args, modifiers = [] }, childLayer) {
|
|
370
|
+
function intrinsicToString({ kind, args, modifiers = [] }, childLayer, isForMigration) {
|
|
371
371
|
const selector = childLayer ?? `figma.currentLayer`;
|
|
372
372
|
switch (kind) {
|
|
373
373
|
case IntrinsicKind.String:
|
|
@@ -387,14 +387,14 @@ function intrinsicToString({ kind, args, modifiers = [] }, childLayer) {
|
|
|
387
387
|
}
|
|
388
388
|
case IntrinsicKind.Boolean: {
|
|
389
389
|
if (args.valueMapping) {
|
|
390
|
-
const mappingString = valueMappingToString(args.valueMapping, childLayer);
|
|
390
|
+
const mappingString = valueMappingToString(args.valueMapping, childLayer, isForMigration);
|
|
391
391
|
// Outputs: `const propName = figma.properties.boolean('propName', { ... mapping object from above ... })`
|
|
392
392
|
return `${selector}.__properties__.boolean('${args.figmaPropName}', ${mappingString})`;
|
|
393
393
|
}
|
|
394
394
|
return `${selector}.__properties__.boolean('${args.figmaPropName}')`;
|
|
395
395
|
}
|
|
396
396
|
case IntrinsicKind.Enum: {
|
|
397
|
-
const mappingString = valueMappingToString(args.valueMapping, childLayer);
|
|
397
|
+
const mappingString = valueMappingToString(args.valueMapping, childLayer, isForMigration);
|
|
398
398
|
// Outputs: `const propName = figma.properties.enum('propName', { ... mapping object from above ... })`
|
|
399
399
|
return `${selector}.__properties__.enum('${args.figmaPropName}', ${mappingString})`;
|
|
400
400
|
}
|
|
@@ -407,7 +407,7 @@ function intrinsicToString({ kind, args, modifiers = [] }, childLayer) {
|
|
|
407
407
|
}
|
|
408
408
|
case IntrinsicKind.ClassName: {
|
|
409
409
|
// Outputs: `const propName = ['btn-base', figma.currentLayer.__properties__.enum('Size, { Large: 'btn-large' })].join(" ")`
|
|
410
|
-
return `[${args.className.map((className) => (typeof className === 'string' ? `"${className}"` : `${intrinsicToString(className, childLayer)}`)).join(', ')}].filter(v => !!v).join(' ')`;
|
|
410
|
+
return `[${args.className.map((className) => (typeof className === 'string' ? `"${className}"` : `${intrinsicToString(className, childLayer, isForMigration)}`)).join(', ')}].filter(v => !!v).join(' ')`;
|
|
411
411
|
}
|
|
412
412
|
case IntrinsicKind.TextContent: {
|
|
413
413
|
return `${selector}.__findChildWithCriteria__({ name: '${args.layer}', type: "TEXT" }).__render__()`;
|
|
@@ -421,9 +421,20 @@ function intrinsicToString({ kind, args, modifiers = [] }, childLayer) {
|
|
|
421
421
|
// currently is to keep the error checking out of global scope
|
|
422
422
|
const nestedLayerRef = `nestedLayer${nestedLayerCount++}`;
|
|
423
423
|
body += `const ${nestedLayerRef} = figma.currentLayer.__find__("${args.layer}")\n`;
|
|
424
|
-
|
|
425
|
-
|
|
424
|
+
if (isForMigration) {
|
|
425
|
+
// Generate a TypeScript-safe pattern that always returns the object shape.
|
|
426
|
+
// The error case uses `undefined` per-property so the result is always
|
|
427
|
+
// `{ key: T | undefined }`, avoiding the `ErrorHandle | { key: T }` union
|
|
428
|
+
// that would require optional chaining at every call site.
|
|
429
|
+
body += `return {\n${Object.entries(args.props)
|
|
430
|
+
.map(([key, intrinsic]) => `${key}: ${nestedLayerRef}.type !== "ERROR" ? ${intrinsicToString(intrinsic, nestedLayerRef, isForMigration)} : undefined,\n`)
|
|
431
|
+
.join('')}\n }\n`;
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
body += `return ${nestedLayerRef}.type === "ERROR" ? ${nestedLayerRef} : {
|
|
435
|
+
${Object.entries(args.props).map(([key, intrinsic]) => `${key}: ${intrinsicToString(intrinsic, nestedLayerRef, isForMigration)}\n`)}
|
|
426
436
|
}\n`;
|
|
437
|
+
}
|
|
427
438
|
return `(function () {${body}})()`;
|
|
428
439
|
}
|
|
429
440
|
default:
|