@figma/code-connect 1.0.6 → 1.1.1
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 +48 -541
- package/dist/client/figma_client.d.ts +1 -1
- package/dist/client/figma_client.js +9 -7
- package/dist/client/figma_client.js.map +1 -1
- package/dist/commands/connect.d.ts +4 -2
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +97 -49
- package/dist/commands/connect.js.map +1 -1
- package/dist/{common → connect}/api.d.ts +6 -87
- package/dist/connect/api.d.ts.map +1 -0
- package/dist/{common → connect}/api.js.map +1 -1
- package/dist/connect/create.d.ts.map +1 -1
- package/dist/connect/create.js +4 -0
- package/dist/connect/create.js.map +1 -1
- package/dist/connect/create_common.d.ts +7 -0
- package/dist/connect/create_common.d.ts.map +1 -0
- package/dist/connect/create_common.js +19 -0
- package/dist/connect/create_common.js.map +1 -0
- package/dist/connect/external_types.d.ts +8 -0
- package/dist/connect/external_types.d.ts.map +1 -0
- package/dist/connect/external_types.js +31 -0
- package/dist/connect/external_types.js.map +1 -0
- package/dist/connect/figma_connect.d.ts.map +1 -0
- package/dist/connect/figma_connect.js.map +1 -0
- package/dist/connect/figma_rest_api.d.ts +7 -0
- package/dist/connect/figma_rest_api.d.ts.map +1 -1
- package/dist/connect/figma_rest_api.js.map +1 -1
- package/dist/connect/index_common.d.ts +3 -0
- package/dist/connect/index_common.d.ts.map +1 -0
- package/dist/connect/index_common.js +23 -0
- package/dist/connect/index_common.js.map +1 -0
- package/dist/{common → connect}/intrinsics.d.ts +4 -3
- package/dist/connect/intrinsics.d.ts.map +1 -0
- package/dist/{common → connect}/intrinsics.js +48 -24
- package/dist/connect/intrinsics.js.map +1 -0
- package/dist/connect/parser_common.d.ts +144 -0
- package/dist/connect/parser_common.d.ts.map +1 -0
- package/dist/connect/parser_common.js +297 -0
- package/dist/connect/parser_common.js.map +1 -0
- package/dist/connect/parser_executable_types.d.ts +20 -23
- package/dist/connect/parser_executable_types.d.ts.map +1 -1
- package/dist/connect/parser_executable_types.js.map +1 -1
- package/dist/connect/parser_executables.js +1 -1
- package/dist/connect/parser_executables.js.map +1 -1
- package/dist/connect/project.d.ts +20 -5
- package/dist/connect/project.d.ts.map +1 -1
- package/dist/connect/project.js +79 -16
- package/dist/connect/project.js.map +1 -1
- package/dist/connect/upload.d.ts +1 -1
- package/dist/connect/upload.d.ts.map +1 -1
- package/dist/connect/validation.d.ts +1 -1
- package/dist/connect/validation.d.ts.map +1 -1
- package/dist/connect/wizard/helpers.d.ts.map +1 -1
- package/dist/connect/wizard/helpers.js +18 -14
- package/dist/connect/wizard/helpers.js.map +1 -1
- package/dist/connect/wizard/prop_mapping.d.ts +12 -7
- package/dist/connect/wizard/prop_mapping.d.ts.map +1 -1
- package/dist/connect/wizard/prop_mapping.js +88 -89
- package/dist/connect/wizard/prop_mapping.js.map +1 -1
- package/dist/connect/wizard/run_wizard.d.ts.map +1 -1
- package/dist/connect/wizard/run_wizard.js +8 -3
- package/dist/connect/wizard/run_wizard.js.map +1 -1
- package/dist/connect/wizard/signature_extraction.d.ts +7 -0
- package/dist/connect/wizard/signature_extraction.d.ts.map +1 -0
- package/dist/connect/wizard/signature_extraction.js +46 -0
- package/dist/connect/wizard/signature_extraction.js.map +1 -0
- package/dist/html/__test__/parser/examples/NoConfigObject.figma.d.ts +2 -0
- package/dist/html/__test__/parser/examples/NoConfigObject.figma.d.ts.map +1 -0
- package/dist/html/__test__/parser/examples/NoConfigObject.figma.js +9 -0
- package/dist/html/__test__/parser/examples/NoConfigObject.figma.js.map +1 -0
- package/dist/html/__test__/parser/examples/NoExample.figma.d.ts +2 -0
- package/dist/html/__test__/parser/examples/NoExample.figma.d.ts.map +1 -0
- package/dist/html/__test__/parser/examples/NoExample.figma.js +9 -0
- package/dist/html/__test__/parser/examples/NoExample.figma.js.map +1 -0
- package/dist/html/__test__/parser/examples/RegularFunctionExampleWithExtraCode.figma.d.ts +2 -0
- package/dist/html/__test__/parser/examples/RegularFunctionExampleWithExtraCode.figma.d.ts.map +1 -0
- package/dist/html/__test__/parser/examples/RegularFunctionExampleWithExtraCode.figma.js +33 -0
- package/dist/html/__test__/parser/examples/RegularFunctionExampleWithExtraCode.figma.js.map +1 -0
- package/dist/html/__test__/parser/examples/WrongSignatureJsx.figma.d.ts +2 -0
- package/dist/html/__test__/parser/examples/WrongSignatureJsx.figma.d.ts.map +1 -0
- package/dist/html/__test__/parser/examples/WrongSignatureJsx.figma.js +15 -0
- package/dist/html/__test__/parser/examples/WrongSignatureJsx.figma.js.map +1 -0
- package/dist/html/__test__/parser/examples/WrongSignatureNoHtmlTag.figma.d.ts +2 -0
- package/dist/html/__test__/parser/examples/WrongSignatureNoHtmlTag.figma.d.ts.map +1 -0
- package/dist/html/__test__/parser/examples/WrongSignatureNoHtmlTag.figma.js +15 -0
- package/dist/html/__test__/parser/examples/WrongSignatureNoHtmlTag.figma.js.map +1 -0
- package/dist/html/__test__/parser/parser.test.d.ts +2 -0
- package/dist/html/__test__/parser/parser.test.d.ts.map +1 -0
- package/dist/html/__test__/parser/parser.test.js +50 -0
- package/dist/html/__test__/parser/parser.test.js.map +1 -0
- package/dist/html/create.d.ts +4 -0
- package/dist/html/create.d.ts.map +1 -0
- package/dist/html/create.js +81 -0
- package/dist/html/create.js.map +1 -0
- package/dist/html/external.d.ts +8 -0
- package/dist/html/external.d.ts.map +1 -0
- package/dist/html/external.js +25 -0
- package/dist/html/external.js.map +1 -0
- package/dist/html/index_html.d.ts +77 -0
- package/dist/html/index_html.d.ts.map +1 -0
- package/dist/html/index_html.js +42 -0
- package/dist/html/index_html.js.map +1 -0
- package/dist/html/parser.d.ts +19 -0
- package/dist/html/parser.d.ts.map +1 -0
- package/dist/html/parser.js +487 -0
- package/dist/html/parser.js.map +1 -0
- package/dist/html/parser_template_helpers.d.ts +2 -0
- package/dist/html/parser_template_helpers.d.ts.map +1 -0
- package/dist/html/parser_template_helpers.js +68 -0
- package/dist/html/parser_template_helpers.js.map +1 -0
- package/dist/html/template_literal.d.ts +5 -0
- package/dist/html/template_literal.d.ts.map +1 -0
- package/dist/html/template_literal.js +8 -0
- package/dist/html/template_literal.js.map +1 -0
- package/dist/parser_scripts/get_swift_parser_dir.d.ts +1 -1
- package/dist/parser_scripts/get_swift_parser_dir.d.ts.map +1 -1
- package/dist/parser_scripts/get_swift_parser_dir.js +38 -10
- package/dist/parser_scripts/get_swift_parser_dir.js.map +1 -1
- package/dist/react/create.d.ts +5 -0
- package/dist/react/create.d.ts.map +1 -1
- package/dist/react/create.js +144 -42
- package/dist/react/create.js.map +1 -1
- package/dist/react/external.d.ts +9 -0
- package/dist/react/external.d.ts.map +1 -0
- package/dist/{common → react}/external.js +8 -28
- package/dist/react/external.js.map +1 -0
- package/dist/react/index_react.d.ts +94 -0
- package/dist/react/index_react.d.ts.map +1 -0
- package/dist/{index.js → react/index_react.js} +5 -19
- package/dist/react/index_react.js.map +1 -0
- package/dist/react/parser.d.ts +6 -38
- package/dist/react/parser.d.ts.map +1 -1
- package/dist/react/parser.js +137 -295
- package/dist/react/parser.js.map +1 -1
- package/dist/react/parser_template_helpers.d.ts +15 -15
- package/dist/react/parser_template_helpers.d.ts.map +1 -1
- package/dist/react/parser_template_helpers.js +51 -35
- package/dist/react/parser_template_helpers.js.map +1 -1
- package/dist/storybook/convert.d.ts +1 -1
- package/dist/storybook/convert.d.ts.map +1 -1
- package/dist/storybook/convert.js +6 -4
- package/dist/storybook/convert.js.map +1 -1
- package/dist/storybook/external.d.ts +1 -1
- package/dist/storybook/external.d.ts.map +1 -1
- package/dist/typescript/compiler.d.ts +2 -2
- package/dist/typescript/compiler.d.ts.map +1 -1
- package/dist/typescript/compiler.js +50 -23
- package/dist/typescript/compiler.js.map +1 -1
- package/package.json +28 -8
- package/dist/common/__test__/project.test.d.ts +0 -2
- package/dist/common/__test__/project.test.d.ts.map +0 -1
- package/dist/common/__test__/project.test.js +0 -14
- package/dist/common/__test__/project.test.js.map +0 -1
- package/dist/common/api.d.ts.map +0 -1
- package/dist/common/external.d.ts +0 -14
- package/dist/common/external.d.ts.map +0 -1
- package/dist/common/external.js.map +0 -1
- package/dist/common/figma_connect.d.ts.map +0 -1
- package/dist/common/figma_connect.js.map +0 -1
- package/dist/common/intrinsics.d.ts.map +0 -1
- package/dist/common/intrinsics.js.map +0 -1
- package/dist/index.d.ts +0 -9
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- /package/dist/{common → connect}/api.js +0 -0
- /package/dist/{common → connect}/figma_connect.d.ts +0 -0
- /package/dist/{common → connect}/figma_connect.js +0 -0
package/dist/react/parser.js
CHANGED
|
@@ -3,42 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.parseReactDoc = exports.getDefaultTemplate = exports.parseRenderFunction = exports.parseComponentMetadata = exports.extractComponentTypeSignature = exports.findAndResolveImports = void 0;
|
|
7
7
|
const typescript_1 = __importDefault(require("typescript"));
|
|
8
8
|
const project_1 = require("../connect/project");
|
|
9
9
|
const logging_1 = require("../common/logging");
|
|
10
10
|
const compiler_1 = require("../typescript/compiler");
|
|
11
|
-
const intrinsics_1 = require("../
|
|
11
|
+
const intrinsics_1 = require("../connect/intrinsics");
|
|
12
12
|
const parser_template_helpers_1 = require("./parser_template_helpers");
|
|
13
|
-
|
|
14
|
-
constructor(message, context) {
|
|
15
|
-
super(message);
|
|
16
|
-
this.name = 'ParserError';
|
|
17
|
-
this.sourceFileName = context?.sourceFile.fileName || '';
|
|
18
|
-
this.sourceFilePosition =
|
|
19
|
-
context && context.node
|
|
20
|
-
? getPositionInSourceFile(context.node, context.sourceFile) || null
|
|
21
|
-
: null;
|
|
22
|
-
}
|
|
23
|
-
toString() {
|
|
24
|
-
let msg = `${(0, logging_1.highlight)((0, logging_1.error)(this.name))}: ${this.message}\n`;
|
|
25
|
-
if (this.sourceFileName && this.sourceFilePosition) {
|
|
26
|
-
msg += ` -> ${(0, logging_1.reset)(this.sourceFileName)}:${this.sourceFilePosition.line}:${this.sourceFilePosition.character}\n`;
|
|
27
|
-
}
|
|
28
|
-
return msg;
|
|
29
|
-
}
|
|
30
|
-
toDebugString() {
|
|
31
|
-
return this.toString() + `\n ${this.stack}`;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
exports.ParserError = ParserError;
|
|
35
|
-
class InternalError extends ParserError {
|
|
36
|
-
constructor(message) {
|
|
37
|
-
super(message);
|
|
38
|
-
this.name = 'InternalError';
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
exports.InternalError = InternalError;
|
|
13
|
+
const parser_common_1 = require("../connect/parser_common");
|
|
42
14
|
/**
|
|
43
15
|
* Traverses the AST and returns the first JSX element it finds
|
|
44
16
|
* @param node AST node
|
|
@@ -60,20 +32,6 @@ function findBlock(node) {
|
|
|
60
32
|
return typescript_1.default.forEachChild(node, findBlock);
|
|
61
33
|
}
|
|
62
34
|
}
|
|
63
|
-
function findDescendants(node, cb) {
|
|
64
|
-
const matches = [];
|
|
65
|
-
function visit(node) {
|
|
66
|
-
if (cb(node)) {
|
|
67
|
-
matches.push(node);
|
|
68
|
-
}
|
|
69
|
-
typescript_1.default.forEachChild(node, visit);
|
|
70
|
-
}
|
|
71
|
-
visit(node);
|
|
72
|
-
return matches;
|
|
73
|
-
}
|
|
74
|
-
function getPositionInSourceFile(node, sourceFile) {
|
|
75
|
-
return sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
76
|
-
}
|
|
77
35
|
/**
|
|
78
36
|
* Walks up the AST from an assignment to find the import declaration
|
|
79
37
|
*/
|
|
@@ -97,6 +55,33 @@ function getImportsOfModule(sourceFile) {
|
|
|
97
55
|
visit(sourceFile);
|
|
98
56
|
return imports;
|
|
99
57
|
}
|
|
58
|
+
function resolveModuleSpecifier(program, sourceFile, importSpecifier) {
|
|
59
|
+
const compilerHost = typescript_1.default.createCompilerHost(program.getCompilerOptions());
|
|
60
|
+
const moduleResolutionHost = {
|
|
61
|
+
fileExists: compilerHost.fileExists,
|
|
62
|
+
readFile: compilerHost.readFile,
|
|
63
|
+
directoryExists: compilerHost.directoryExists,
|
|
64
|
+
getCurrentDirectory: compilerHost.getCurrentDirectory,
|
|
65
|
+
getDirectories: compilerHost.getDirectories,
|
|
66
|
+
};
|
|
67
|
+
const resolvedModule = typescript_1.default.resolveModuleName(importSpecifier, sourceFile.fileName, program.getCompilerOptions(), moduleResolutionHost);
|
|
68
|
+
return resolvedModule.resolvedModule?.resolvedFileName;
|
|
69
|
+
}
|
|
70
|
+
// Traverse the source file and resolve imports
|
|
71
|
+
function findAndResolveImports(program, sourceFile) {
|
|
72
|
+
const importSpecifierToFilePath = {};
|
|
73
|
+
typescript_1.default.forEachChild(sourceFile, (node) => {
|
|
74
|
+
if (typescript_1.default.isImportDeclaration(node)) {
|
|
75
|
+
const importSpecifier = node.moduleSpecifier.text;
|
|
76
|
+
const resolvedFileName = resolveModuleSpecifier(program, sourceFile, importSpecifier);
|
|
77
|
+
if (resolvedFileName) {
|
|
78
|
+
importSpecifierToFilePath[importSpecifier] = resolvedFileName;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
return importSpecifierToFilePath;
|
|
83
|
+
}
|
|
84
|
+
exports.findAndResolveImports = findAndResolveImports;
|
|
100
85
|
/**
|
|
101
86
|
* Finds all import statements in a file that matches the given identifiers
|
|
102
87
|
*
|
|
@@ -104,13 +89,15 @@ function getImportsOfModule(sourceFile) {
|
|
|
104
89
|
* @param identifiers List of identifiers to find imports for
|
|
105
90
|
* @returns
|
|
106
91
|
*/
|
|
107
|
-
function
|
|
92
|
+
function getSourceFilesOfImportedIdentifiers(parserContext, _identifiers) {
|
|
93
|
+
const { sourceFile, resolvedImports } = parserContext;
|
|
108
94
|
const importDeclarations = getImportsOfModule(sourceFile);
|
|
109
95
|
const imports = [];
|
|
110
96
|
const identifiers = _identifiers.map((identifier) => identifier.split('.')[0]);
|
|
111
97
|
for (const declaration of importDeclarations) {
|
|
112
98
|
let statement = declaration.getText();
|
|
113
|
-
|
|
99
|
+
// remove the quotation marks around the module specifier
|
|
100
|
+
const moduleSpecifier = declaration.moduleSpecifier.getText().slice(1, -1);
|
|
114
101
|
if (declaration.importClause) {
|
|
115
102
|
// Default imports
|
|
116
103
|
if (declaration.importClause.name) {
|
|
@@ -118,7 +105,7 @@ function getImportsForIdentifiers({ sourceFile }, _identifiers) {
|
|
|
118
105
|
if (identifiers.includes(identifier)) {
|
|
119
106
|
imports.push({
|
|
120
107
|
statement,
|
|
121
|
-
file:
|
|
108
|
+
file: resolvedImports[moduleSpecifier],
|
|
122
109
|
});
|
|
123
110
|
}
|
|
124
111
|
}
|
|
@@ -133,7 +120,7 @@ function getImportsForIdentifiers({ sourceFile }, _identifiers) {
|
|
|
133
120
|
if (elements.length > 0) {
|
|
134
121
|
imports.push({
|
|
135
122
|
statement: statement.replace(/{.*}/s, `{ ${elements.join(', ')} }`),
|
|
136
|
-
file:
|
|
123
|
+
file: resolvedImports[moduleSpecifier],
|
|
137
124
|
});
|
|
138
125
|
}
|
|
139
126
|
}
|
|
@@ -143,7 +130,7 @@ function getImportsForIdentifiers({ sourceFile }, _identifiers) {
|
|
|
143
130
|
if (identifiers.includes(identifier)) {
|
|
144
131
|
imports.push({
|
|
145
132
|
statement,
|
|
146
|
-
file:
|
|
133
|
+
file: resolvedImports[moduleSpecifier],
|
|
147
134
|
});
|
|
148
135
|
}
|
|
149
136
|
}
|
|
@@ -193,6 +180,25 @@ function getDeclarationFromSymbol(symbol) {
|
|
|
193
180
|
}
|
|
194
181
|
return symbol.declarations[0];
|
|
195
182
|
}
|
|
183
|
+
function resolveIdentifierSymbol(identifier, checker) {
|
|
184
|
+
const componentSymbol = checker.getSymbolAtLocation(identifier);
|
|
185
|
+
if (!componentSymbol) {
|
|
186
|
+
throw new Error(`Symbol not found at location ${identifier.getText()}`);
|
|
187
|
+
}
|
|
188
|
+
const componentDeclaration = getDeclarationFromSymbol(componentSymbol);
|
|
189
|
+
if (typescript_1.default.isImportSpecifier(componentDeclaration) || typescript_1.default.isImportClause(componentDeclaration)) {
|
|
190
|
+
let importDeclaration = findParentImportDeclaration(componentDeclaration);
|
|
191
|
+
if (!importDeclaration) {
|
|
192
|
+
throw new Error('No import statement found for component');
|
|
193
|
+
}
|
|
194
|
+
// The component should be imported from another file, we need to follow the
|
|
195
|
+
// aliased symbol to get the correct function definition
|
|
196
|
+
if (componentSymbol.flags & typescript_1.default.SymbolFlags.Alias) {
|
|
197
|
+
return checker.getAliasedSymbol(componentSymbol);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return componentSymbol;
|
|
201
|
+
}
|
|
196
202
|
/**
|
|
197
203
|
* This handles a number of cases for finding the function expression of an exported symbol:
|
|
198
204
|
* - A function that is exported directly (function declaration)
|
|
@@ -219,17 +225,24 @@ function findFunctionExpression(declaration, checker, sourceFile) {
|
|
|
219
225
|
// Example: export const MemoButton = memo(Button)
|
|
220
226
|
// Example: export const ButtonWithRef = forwardRef(Button)
|
|
221
227
|
if (typescript_1.default.isVariableDeclaration(declaration)) {
|
|
222
|
-
|
|
223
|
-
const
|
|
224
|
-
|
|
225
|
-
|
|
228
|
+
let componentSymbol = undefined;
|
|
229
|
+
// Example: export const SomeAlias = Button
|
|
230
|
+
if (declaration.initializer && typescript_1.default.isIdentifier(declaration.initializer)) {
|
|
231
|
+
componentSymbol = resolveIdentifierSymbol(declaration.initializer, checker);
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
const callExpression = findCallExpression(declaration);
|
|
235
|
+
const component = callExpression.arguments[0];
|
|
236
|
+
// follow the symbol to its declaration, then try to find the function expression again
|
|
237
|
+
componentSymbol = checker.getSymbolAtLocation(component);
|
|
238
|
+
}
|
|
226
239
|
if (!componentSymbol) {
|
|
227
240
|
throw new Error('No symbol found at location');
|
|
228
241
|
}
|
|
229
242
|
const componentDeclaration = getDeclarationFromSymbol(componentSymbol);
|
|
230
243
|
return findFunctionExpression(componentDeclaration, checker, sourceFile);
|
|
231
244
|
}
|
|
232
|
-
throw new ParserError('Failed to find function expression for component', {
|
|
245
|
+
throw new parser_common_1.ParserError('Failed to find function expression for component', {
|
|
233
246
|
sourceFile,
|
|
234
247
|
node: declaration,
|
|
235
248
|
});
|
|
@@ -250,10 +263,25 @@ function findFunctionExpression(declaration, checker, sourceFile) {
|
|
|
250
263
|
function extractComponentTypeSignature(symbol, checker, sourceFile) {
|
|
251
264
|
const declaration = getDeclarationFromSymbol(symbol);
|
|
252
265
|
const ReactInterfaceNames = ['HTMLAttributes', 'Attributes', 'AriaAttributes', 'DOMAttributes'];
|
|
253
|
-
|
|
254
|
-
|
|
266
|
+
let propsType = null;
|
|
267
|
+
/**
|
|
268
|
+
* Special case for forwardRef as type is passed as generic arg
|
|
269
|
+
*/
|
|
270
|
+
if (typescript_1.default.isVariableDeclaration(declaration)) {
|
|
271
|
+
const callExpression = findCallExpression(declaration);
|
|
272
|
+
if ((callExpression?.expression.getText() === 'forwardRef' ||
|
|
273
|
+
callExpression?.expression.getText() === 'React.forwardRef') &&
|
|
274
|
+
callExpression.typeArguments &&
|
|
275
|
+
callExpression.typeArguments.length === 2) {
|
|
276
|
+
propsType = checker.getTypeAtLocation(callExpression.typeArguments[1]);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (!propsType) {
|
|
280
|
+
const functionExpression = findFunctionExpression(declaration, checker, sourceFile);
|
|
281
|
+
propsType = checker.getTypeAtLocation(functionExpression.parameters[0]);
|
|
282
|
+
}
|
|
255
283
|
if (!propsType) {
|
|
256
|
-
throw new InternalError(`Failed to extract props from component declaration: ${declaration.getText()}`);
|
|
284
|
+
throw new parser_common_1.InternalError(`Failed to extract props from component declaration: ${declaration.getText()}`);
|
|
257
285
|
}
|
|
258
286
|
const propsMap = {};
|
|
259
287
|
const props = propsType.getProperties();
|
|
@@ -297,7 +325,8 @@ exports.extractComponentTypeSignature = extractComponentTypeSignature;
|
|
|
297
325
|
* @param node The node being parsed. Used for error logging.
|
|
298
326
|
* @returns Metadata object
|
|
299
327
|
*/
|
|
300
|
-
async function parseComponentMetadata(node,
|
|
328
|
+
async function parseComponentMetadata(node, parserContext, silent) {
|
|
329
|
+
const { checker, sourceFile } = parserContext;
|
|
301
330
|
let componentSymbol = checker.getSymbolAtLocation(node);
|
|
302
331
|
let componentSourceFile = sourceFile;
|
|
303
332
|
let component = '';
|
|
@@ -306,7 +335,7 @@ async function parseComponentMetadata(node, { checker, sourceFile, absPath }, si
|
|
|
306
335
|
if (typescript_1.default.isPropertyAccessExpression(node)) {
|
|
307
336
|
componentSymbol = checker.getSymbolAtLocation(node.expression);
|
|
308
337
|
if (!componentSymbol) {
|
|
309
|
-
throw new ParserError(`Could not find symbol for component ${node.expression.getText()}`, {
|
|
338
|
+
throw new parser_common_1.ParserError(`Could not find symbol for component ${node.expression.getText()}`, {
|
|
310
339
|
sourceFile,
|
|
311
340
|
node,
|
|
312
341
|
});
|
|
@@ -319,7 +348,7 @@ async function parseComponentMetadata(node, { checker, sourceFile, absPath }, si
|
|
|
319
348
|
typescript_1.default.isImportClause(componentSymbol.declarations[0]))) {
|
|
320
349
|
let importDeclaration = findParentImportDeclaration(componentSymbol.declarations[0]);
|
|
321
350
|
if (!importDeclaration) {
|
|
322
|
-
throw new ParserError('No import statement found for component, make sure the component is imported', {
|
|
351
|
+
throw new parser_common_1.ParserError('No import statement found for component, make sure the component is imported', {
|
|
323
352
|
sourceFile,
|
|
324
353
|
node,
|
|
325
354
|
});
|
|
@@ -363,17 +392,17 @@ async function parseComponentMetadata(node, { checker, sourceFile, absPath }, si
|
|
|
363
392
|
}
|
|
364
393
|
const source = componentSourceFile.fileName;
|
|
365
394
|
if (!source) {
|
|
366
|
-
throw new InternalError(`Could not find source file for component ${component} - is this file included in the directory passed to \`figma connect <dir>\`?`);
|
|
395
|
+
throw new parser_common_1.InternalError(`Could not find source file for component ${component} - is this file included in the directory passed to \`figma connect <dir>\`?`);
|
|
367
396
|
}
|
|
368
397
|
if (!componentDeclaration) {
|
|
369
|
-
throw new ParserError(`Could not find declaration for component ${component}`, {
|
|
398
|
+
throw new parser_common_1.ParserError(`Could not find declaration for component ${component}`, {
|
|
370
399
|
sourceFile,
|
|
371
400
|
node,
|
|
372
401
|
});
|
|
373
402
|
}
|
|
374
|
-
const line = getPositionInSourceFile(componentDeclaration, componentSourceFile).line;
|
|
403
|
+
const line = (0, parser_common_1.getPositionInSourceFile)(componentDeclaration, componentSourceFile).line;
|
|
375
404
|
if (line === undefined) {
|
|
376
|
-
throw new InternalError(`Could not determine line number for component ${componentDeclaration.getStart(sourceFile)}`);
|
|
405
|
+
throw new parser_common_1.InternalError(`Could not determine line number for component ${componentDeclaration.getStart(sourceFile)}`);
|
|
377
406
|
}
|
|
378
407
|
return {
|
|
379
408
|
source,
|
|
@@ -382,104 +411,6 @@ async function parseComponentMetadata(node, { checker, sourceFile, absPath }, si
|
|
|
382
411
|
};
|
|
383
412
|
}
|
|
384
413
|
exports.parseComponentMetadata = parseComponentMetadata;
|
|
385
|
-
/**
|
|
386
|
-
* Checks if an AST node is a `figma.connect()` call
|
|
387
|
-
*
|
|
388
|
-
* @param node AST node
|
|
389
|
-
* @param sourceFile Source file
|
|
390
|
-
* @returns True if the node is a `figma.connect()` call
|
|
391
|
-
*/
|
|
392
|
-
function isFigmaConnectCall(node, sourceFile) {
|
|
393
|
-
return (typescript_1.default.isCallExpression(node) && node.expression.getText(sourceFile).includes(intrinsics_1.FIGMA_CONNECT_CALL));
|
|
394
|
-
}
|
|
395
|
-
/**
|
|
396
|
-
* Checks if a file contains Code Connect by looking for the `figma.connect()` function call
|
|
397
|
-
*
|
|
398
|
-
* @param program
|
|
399
|
-
* @param file
|
|
400
|
-
* @returns
|
|
401
|
-
*/
|
|
402
|
-
function isFigmaConnectFile(program, file) {
|
|
403
|
-
// We don't support Code Connect in JSX and this throws an error if we let it proceed
|
|
404
|
-
if (!file.endsWith('.tsx')) {
|
|
405
|
-
return false;
|
|
406
|
-
}
|
|
407
|
-
const sourceFile = program.getSourceFile(file);
|
|
408
|
-
if (!sourceFile) {
|
|
409
|
-
throw new InternalError(`Could not find source file for ${file}`);
|
|
410
|
-
}
|
|
411
|
-
return (findDescendants(sourceFile, (node) => {
|
|
412
|
-
if (isFigmaConnectCall(node, sourceFile)) {
|
|
413
|
-
return true;
|
|
414
|
-
}
|
|
415
|
-
return false;
|
|
416
|
-
}).length > 0);
|
|
417
|
-
}
|
|
418
|
-
exports.isFigmaConnectFile = isFigmaConnectFile;
|
|
419
|
-
/**
|
|
420
|
-
* Parses the `links` field of a `figma.connect()` call
|
|
421
|
-
*
|
|
422
|
-
* @param linksArray an ArrayLiteralExpression
|
|
423
|
-
* @param parserContext Parser context
|
|
424
|
-
* @returns An array of link objects
|
|
425
|
-
*/
|
|
426
|
-
function parseLinks(linksArray, parserContext) {
|
|
427
|
-
const { sourceFile } = parserContext;
|
|
428
|
-
const links = [];
|
|
429
|
-
for (const element of linksArray.elements) {
|
|
430
|
-
(0, compiler_1.assertIsObjectLiteralExpression)(element, sourceFile, `'links' must be an array literal with objects of the format { name: string, url: string }`);
|
|
431
|
-
const name = (0, compiler_1.parsePropertyOfType)({
|
|
432
|
-
objectLiteralNode: element,
|
|
433
|
-
propertyName: 'name',
|
|
434
|
-
predicate: typescript_1.default.isStringLiteral,
|
|
435
|
-
parserContext,
|
|
436
|
-
required: true,
|
|
437
|
-
errorMessage: "The 'name' property must be a string literal",
|
|
438
|
-
});
|
|
439
|
-
const url = (0, compiler_1.parsePropertyOfType)({
|
|
440
|
-
objectLiteralNode: element,
|
|
441
|
-
propertyName: 'url',
|
|
442
|
-
predicate: typescript_1.default.isStringLiteral,
|
|
443
|
-
parserContext,
|
|
444
|
-
required: true,
|
|
445
|
-
errorMessage: "The 'url' property must be a string literal",
|
|
446
|
-
});
|
|
447
|
-
if (name && url) {
|
|
448
|
-
links.push({ name: (0, compiler_1.stripQuotes)(name), url: (0, compiler_1.stripQuotes)(url) });
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
return links;
|
|
452
|
-
}
|
|
453
|
-
function parseVariant(variantMap, sourceFile, checker) {
|
|
454
|
-
return (0, compiler_1.convertObjectLiteralToJs)(variantMap, sourceFile, checker, (valueNode) => {
|
|
455
|
-
if (!typescript_1.default.isObjectLiteralElement(valueNode) &&
|
|
456
|
-
!typescript_1.default.isStringLiteral(valueNode) &&
|
|
457
|
-
!typescript_1.default.isNumericLiteral(valueNode) &&
|
|
458
|
-
valueNode.kind !== typescript_1.default.SyntaxKind.TrueKeyword &&
|
|
459
|
-
valueNode.kind !== typescript_1.default.SyntaxKind.FalseKeyword) {
|
|
460
|
-
throw new ParserError(`Invalid value for variant, got: ${valueNode.getText()}`, {
|
|
461
|
-
node: valueNode,
|
|
462
|
-
sourceFile,
|
|
463
|
-
});
|
|
464
|
-
}
|
|
465
|
-
});
|
|
466
|
-
}
|
|
467
|
-
/**
|
|
468
|
-
* Parses the `imports` field of a `figma.connect()` call
|
|
469
|
-
*
|
|
470
|
-
* @param importsArray an ArrayLiteralExpression
|
|
471
|
-
* @param parserContext Parser context
|
|
472
|
-
* @returns An array of link objects
|
|
473
|
-
*/
|
|
474
|
-
function parseImports(importsArray, parserContext) {
|
|
475
|
-
const { sourceFile } = parserContext;
|
|
476
|
-
const imports = [];
|
|
477
|
-
for (const element of importsArray.elements) {
|
|
478
|
-
(0, compiler_1.assertIsStringLiteral)(element, sourceFile, `'imports' must be an array literal with strings`);
|
|
479
|
-
imports.push((0, compiler_1.stripQuotes)(element));
|
|
480
|
-
}
|
|
481
|
-
return imports;
|
|
482
|
-
}
|
|
483
414
|
/**
|
|
484
415
|
* Parses the render function passed to `figma.connect()`, extracting the code and
|
|
485
416
|
* any import statements matching the JSX elements used in the function body
|
|
@@ -494,42 +425,23 @@ function parseRenderFunction(exp, parserContext, propMappings) {
|
|
|
494
425
|
const { sourceFile } = parserContext;
|
|
495
426
|
let exampleCode;
|
|
496
427
|
if (exp.parameters.length > 1) {
|
|
497
|
-
throw new ParserError(`Expected a single props parameter for the render function, got ${exp.parameters.length} parameters`, { sourceFile, node: exp });
|
|
428
|
+
throw new parser_common_1.ParserError(`Expected a single props parameter for the render function, got ${exp.parameters.length} parameters`, { sourceFile, node: exp });
|
|
498
429
|
}
|
|
499
430
|
const propsParameter = exp.parameters[0];
|
|
500
431
|
// Keep track of any props which are referenced in the example so that we can
|
|
501
432
|
// insert the appropriate `figma.properties` call in the JS template
|
|
502
433
|
const referencedProps = new Set();
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
if (name.includes('.')) {
|
|
509
|
-
propReferenceName = name.split('.')[0];
|
|
510
|
-
}
|
|
511
|
-
const mappedProp = propMappings && propMappings[propReferenceName];
|
|
512
|
-
if (!mappedProp) {
|
|
513
|
-
throw new ParserError(`Could not find prop mapping for ${propReferenceName} in the props object`, {
|
|
514
|
-
sourceFile,
|
|
515
|
-
node,
|
|
516
|
-
});
|
|
517
|
-
}
|
|
518
|
-
referencedProps.add(propReferenceName);
|
|
519
|
-
const callExpression = typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier('__PROP__'), undefined, [typescript_1.default.factory.createStringLiteral(name)]);
|
|
520
|
-
if (wrapInJsxExpression) {
|
|
521
|
-
return typescript_1.default.factory.createJsxExpression(undefined, callExpression);
|
|
522
|
-
}
|
|
523
|
-
else {
|
|
524
|
-
return callExpression;
|
|
525
|
-
}
|
|
526
|
-
}
|
|
434
|
+
const createPropPlaceholder = (0, parser_common_1.makeCreatePropPlaceholder)({
|
|
435
|
+
propMappings,
|
|
436
|
+
referencedProps,
|
|
437
|
+
sourceFile,
|
|
438
|
+
});
|
|
527
439
|
// Find all property access expressions in the function body and replace them
|
|
528
440
|
// with a function call like `__PROP__("propName")`, so that we can easily
|
|
529
441
|
// find them in the next step to convert them into
|
|
530
442
|
// `${_fcc_renderReactProp(...)` in the template string.
|
|
531
443
|
//
|
|
532
|
-
// Doing it this way means we can
|
|
444
|
+
// Doing it this way means we can normalize the different ways in which props
|
|
533
445
|
// can be accessed using the compiler API, which is much easier than using a
|
|
534
446
|
// regex, then in the next step we can use a simple regex to convert that into
|
|
535
447
|
// the template string.
|
|
@@ -537,33 +449,14 @@ function parseRenderFunction(exp, parserContext, propMappings) {
|
|
|
537
449
|
exp = typescript_1.default.transform(exp, [
|
|
538
450
|
(context) => (rootNode) => {
|
|
539
451
|
function visit(node) {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
}
|
|
549
|
-
const name = node.name.getText();
|
|
550
|
-
return createPropPlaceholder({ name, node });
|
|
551
|
-
}
|
|
552
|
-
// `props[""]` notation
|
|
553
|
-
if (typescript_1.default.isIdentifier(propsParameter.name) &&
|
|
554
|
-
typescript_1.default.isElementAccessExpression(node) &&
|
|
555
|
-
node.expression.getText().startsWith(propsParameter.name.getText()) &&
|
|
556
|
-
typescript_1.default.isStringLiteral(node.argumentExpression)) {
|
|
557
|
-
const name = (0, compiler_1.stripQuotes)(node.argumentExpression);
|
|
558
|
-
return createPropPlaceholder({ name, node });
|
|
559
|
-
}
|
|
560
|
-
// object destructuring references
|
|
561
|
-
if (typescript_1.default.isObjectBindingPattern(propsParameter.name) &&
|
|
562
|
-
typescript_1.default.isJsxExpression(node) &&
|
|
563
|
-
node.expression &&
|
|
564
|
-
propsParameter.name.elements.find((el) => node.expression?.getText().startsWith(el.name.getText()))) {
|
|
565
|
-
const name = node.expression.getText();
|
|
566
|
-
return createPropPlaceholder({ name, node, wrapInJsxExpression: true });
|
|
452
|
+
const visitResult = (0, parser_common_1.visitPropReferencingNode)({
|
|
453
|
+
propsParameter,
|
|
454
|
+
node,
|
|
455
|
+
createPropPlaceholder,
|
|
456
|
+
useJsx: true,
|
|
457
|
+
});
|
|
458
|
+
if (visitResult) {
|
|
459
|
+
return visitResult;
|
|
567
460
|
}
|
|
568
461
|
// object assignment using destructured reference, e.g `prop={{ key: value }}`
|
|
569
462
|
// (`{{ key: props.value }}` syntax will be captured by the `props.` notation branch above)
|
|
@@ -641,7 +534,7 @@ function parseRenderFunction(exp, parserContext, propMappings) {
|
|
|
641
534
|
exampleCode = printer.printNode(typescript_1.default.EmitHint.Unspecified, functionExpression, sourceFile);
|
|
642
535
|
}
|
|
643
536
|
else {
|
|
644
|
-
throw new ParserError(`Expected a single JSX element or a block statement in the render function, got ${exp.getText()}`, { sourceFile, node: exp });
|
|
537
|
+
throw new parser_common_1.ParserError(`Expected a single JSX element or a block statement in the render function, got ${exp.getText()}`, { sourceFile, node: exp });
|
|
645
538
|
}
|
|
646
539
|
let templateCode = '';
|
|
647
540
|
// Replace React prop placeholders we inserted above (like
|
|
@@ -671,41 +564,22 @@ function parseRenderFunction(exp, parserContext, propMappings) {
|
|
|
671
564
|
templateCode = (0, parser_template_helpers_1.getParsedTemplateHelpersString)() + '\n\n';
|
|
672
565
|
// Require the template API
|
|
673
566
|
templateCode += `const figma = require('figma')\n\n`;
|
|
674
|
-
let nestedLayerCount = 0;
|
|
675
567
|
// Then we output `const propName = figma.properties.<kind>('propName')` calls
|
|
676
568
|
// for each referenced prop, so these are accessible to the template code.
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
}
|
|
686
|
-
if (propMapping.kind === intrinsics_1.IntrinsicKind.NestedProps) {
|
|
687
|
-
// the actual layer name in figma could have a bunch of special characters in it,
|
|
688
|
-
// and if we try to normalize it to a valid JS identifier, it could conflict with
|
|
689
|
-
// other variables in the template code. So we generate a unique variable name
|
|
690
|
-
// for each nested layer reference instead.
|
|
691
|
-
const nestedLayerRef = `nestedLayer${nestedLayerCount++}`;
|
|
692
|
-
templateCode += `const ${nestedLayerRef} = figma.currentLayer.__find__("${propMapping.args.layer}")\n`;
|
|
693
|
-
templateCode += `const ${prop} = {
|
|
694
|
-
${Object.entries(propMapping.args.props).map(([key, intrinsic]) => `${key}: ${(0, intrinsics_1.intrinsicToString)(intrinsic, nestedLayerRef)}\n`)}
|
|
695
|
-
}\n`;
|
|
696
|
-
}
|
|
697
|
-
else {
|
|
698
|
-
templateCode += `const ${prop} = ${(0, intrinsics_1.intrinsicToString)(propMapping)}\n`;
|
|
699
|
-
}
|
|
700
|
-
});
|
|
701
|
-
templateCode += '\n';
|
|
702
|
-
}
|
|
569
|
+
templateCode += (0, parser_common_1.getReferencedPropsForTemplate)({
|
|
570
|
+
propMappings,
|
|
571
|
+
referencedProps,
|
|
572
|
+
exp,
|
|
573
|
+
sourceFile,
|
|
574
|
+
});
|
|
575
|
+
// Escape backticks from the example code, as otherwise those would terminate the `figma.tsx` template literal
|
|
576
|
+
exampleCode = exampleCode.replace(/`/g, '\\`');
|
|
703
577
|
// Finally, output the example code
|
|
704
578
|
templateCode += `export default figma.tsx\`${exampleCode}\`\n`;
|
|
705
579
|
// Find all JSX elements in the function body and extract their import
|
|
706
580
|
// statements
|
|
707
|
-
const jsxTags = findDescendants(exp, (element) => typescript_1.default.isJsxElement(element) || typescript_1.default.isJsxSelfClosingElement(element))
|
|
708
|
-
const imports =
|
|
581
|
+
const jsxTags = (0, parser_common_1.findDescendants)(exp, (element) => typescript_1.default.isJsxElement(element) || typescript_1.default.isJsxSelfClosingElement(element));
|
|
582
|
+
const imports = getSourceFilesOfImportedIdentifiers(parserContext, jsxTags.map(compiler_1.getTagName));
|
|
709
583
|
return {
|
|
710
584
|
code: templateCode,
|
|
711
585
|
imports,
|
|
@@ -731,7 +605,7 @@ function followIdentifierToStringLiteralDeclaration(node, parserContext, errMess
|
|
|
731
605
|
// If we followed the identifier to its declaration and it's not a string literal,
|
|
732
606
|
// throw an error
|
|
733
607
|
if (!result || !typescript_1.default.isStringLiteral(result)) {
|
|
734
|
-
throw new ParserError(errMessage, {
|
|
608
|
+
throw new parser_common_1.ParserError(errMessage, {
|
|
735
609
|
node: result,
|
|
736
610
|
sourceFile: parserContext.sourceFile,
|
|
737
611
|
});
|
|
@@ -855,17 +729,16 @@ function getDefaultTemplate(componentMetadata) {
|
|
|
855
729
|
return `const figma = require("figma")\n\nexport default figma.tsx\`${example}\``;
|
|
856
730
|
}
|
|
857
731
|
exports.getDefaultTemplate = getDefaultTemplate;
|
|
858
|
-
async function
|
|
732
|
+
async function parseReactDoc(node, parserContext, { repoUrl, silent }) {
|
|
859
733
|
const { checker, sourceFile, config } = parserContext;
|
|
860
734
|
// Parse the arguments to the `Figma.connect()` call
|
|
861
735
|
const { componentArg, figmaNodeUrlArg, configObjArg } = parseFigmaConnectArgs(node, parserContext);
|
|
862
|
-
// The ones with ! are definitely defined because their parser fn has required: true,
|
|
863
|
-
// but I couldn't work out how to model that in TypeScript
|
|
864
736
|
const { propsArg, exampleArg, variantArg, linksArg, importsArg } = parseConfigObjectArg(configObjArg, parserContext);
|
|
865
|
-
let figmaNode = (0, compiler_1.
|
|
737
|
+
let figmaNode = (0, compiler_1.stripQuotesFromNode)(figmaNodeUrlArg);
|
|
866
738
|
// TODO This logic is duplicated in connect.ts transformDocFromParser due to some type issues
|
|
867
739
|
if (config.documentUrlSubstitutions) {
|
|
868
740
|
Object.entries(config.documentUrlSubstitutions).forEach(([from, to]) => {
|
|
741
|
+
// @ts-expect-error
|
|
869
742
|
figmaNode = figmaNode.replace(from, to);
|
|
870
743
|
});
|
|
871
744
|
}
|
|
@@ -874,11 +747,11 @@ async function parseDoc(node, parserContext, { repoUrl, silent }) {
|
|
|
874
747
|
: undefined;
|
|
875
748
|
const props = propsArg ? (0, intrinsics_1.parsePropsObject)(propsArg, parserContext) : undefined;
|
|
876
749
|
const render = exampleArg ? parseRenderFunction(exampleArg, parserContext, props) : undefined;
|
|
877
|
-
const variant = variantArg ? parseVariant(variantArg, sourceFile, checker) : undefined;
|
|
878
|
-
const links = linksArg ? parseLinks(linksArg, parserContext) : undefined;
|
|
879
|
-
let
|
|
750
|
+
const variant = variantArg ? (0, parser_common_1.parseVariant)(variantArg, sourceFile, checker) : undefined;
|
|
751
|
+
const links = linksArg ? (0, parser_common_1.parseLinks)(linksArg, parserContext) : undefined;
|
|
752
|
+
let mappedImports;
|
|
880
753
|
if (importsArg) {
|
|
881
|
-
|
|
754
|
+
mappedImports = (0, parser_common_1.parseImports)(importsArg, parserContext);
|
|
882
755
|
}
|
|
883
756
|
else {
|
|
884
757
|
// If no template function was provided, construct one and add the import
|
|
@@ -886,7 +759,7 @@ async function parseDoc(node, parserContext, { repoUrl, silent }) {
|
|
|
886
759
|
let imports = render?.imports
|
|
887
760
|
? render.imports
|
|
888
761
|
: metadata !== undefined
|
|
889
|
-
?
|
|
762
|
+
? getSourceFilesOfImportedIdentifiers(parserContext, [metadata.component])
|
|
890
763
|
: [];
|
|
891
764
|
if (imports.length === 0 && metadata?.component) {
|
|
892
765
|
// If no imports were found, it might mean that the component is not imported, or
|
|
@@ -900,18 +773,18 @@ async function parseDoc(node, parserContext, { repoUrl, silent }) {
|
|
|
900
773
|
},
|
|
901
774
|
];
|
|
902
775
|
}
|
|
903
|
-
|
|
776
|
+
mappedImports =
|
|
904
777
|
imports.map((imp) => {
|
|
905
778
|
if (config) {
|
|
906
|
-
const
|
|
907
|
-
if (
|
|
908
|
-
return imp.statement.replace(/['"]([\.\/a-zA-Z0-
|
|
779
|
+
const mappedPath = (0, project_1.mapImportPath)(imp.file, config);
|
|
780
|
+
if (mappedPath) {
|
|
781
|
+
return imp.statement.replace(/['"]([\.\/a-zA-Z0-9_-]*)['"]/, `'${mappedPath}'`);
|
|
909
782
|
}
|
|
910
783
|
}
|
|
911
784
|
return imp.statement;
|
|
912
785
|
}) ?? [];
|
|
913
786
|
}
|
|
914
|
-
if (
|
|
787
|
+
if (mappedImports.length === 0 && metadata?.component) {
|
|
915
788
|
logging_1.logger.warn(`The import statement for ${metadata.component} could not be automatically resolved, make sure the component is imported (if not colocating) and that the path mappings are correct in your figma.config.json`);
|
|
916
789
|
}
|
|
917
790
|
let template;
|
|
@@ -922,7 +795,7 @@ async function parseDoc(node, parserContext, { repoUrl, silent }) {
|
|
|
922
795
|
template = getDefaultTemplate(metadata);
|
|
923
796
|
}
|
|
924
797
|
else {
|
|
925
|
-
throw new ParserError(`${intrinsics_1.FIGMA_CONNECT_CALL}() requires either a component argument or an example function`, { sourceFile, node });
|
|
798
|
+
throw new parser_common_1.ParserError(`${intrinsics_1.FIGMA_CONNECT_CALL}() requires either a component argument or an example function`, { sourceFile, node });
|
|
926
799
|
}
|
|
927
800
|
return {
|
|
928
801
|
figmaNode,
|
|
@@ -937,7 +810,7 @@ async function parseDoc(node, parserContext, { repoUrl, silent }) {
|
|
|
937
810
|
// TODO: `props` here is currently only used for validation purposes,
|
|
938
811
|
// we should eventually remove it from the JSON payload
|
|
939
812
|
props,
|
|
940
|
-
imports:
|
|
813
|
+
imports: mappedImports,
|
|
941
814
|
// If there's no render function, the default example is always nestable
|
|
942
815
|
nestable: render ? render.nestable : true,
|
|
943
816
|
},
|
|
@@ -947,36 +820,5 @@ async function parseDoc(node, parserContext, { repoUrl, silent }) {
|
|
|
947
820
|
},
|
|
948
821
|
};
|
|
949
822
|
}
|
|
950
|
-
|
|
951
|
-
const sourceFile = program.getSourceFile(file);
|
|
952
|
-
if (!sourceFile) {
|
|
953
|
-
throw new InternalError(`Could not find source file for ${file}`);
|
|
954
|
-
}
|
|
955
|
-
const parserContext = {
|
|
956
|
-
checker: program.getTypeChecker(),
|
|
957
|
-
sourceFile,
|
|
958
|
-
config,
|
|
959
|
-
absPath,
|
|
960
|
-
};
|
|
961
|
-
const codeConnectObjects = [];
|
|
962
|
-
const nodes = [parserContext.sourceFile];
|
|
963
|
-
while (nodes.length > 0) {
|
|
964
|
-
const node = nodes.shift();
|
|
965
|
-
if (isFigmaConnectCall(node, parserContext.sourceFile)) {
|
|
966
|
-
const doc = await parseDoc(node, parserContext, parseOptions);
|
|
967
|
-
if (doc) {
|
|
968
|
-
codeConnectObjects.push(doc);
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
nodes.push(...node.getChildren(parserContext.sourceFile));
|
|
972
|
-
}
|
|
973
|
-
if (codeConnectObjects.length === 0) {
|
|
974
|
-
throw new ParserError(`Didn't find any calls to figma.connect()`, {
|
|
975
|
-
sourceFile: parserContext.sourceFile,
|
|
976
|
-
node: parserContext.sourceFile,
|
|
977
|
-
});
|
|
978
|
-
}
|
|
979
|
-
return codeConnectObjects;
|
|
980
|
-
}
|
|
981
|
-
exports.parse = parse;
|
|
823
|
+
exports.parseReactDoc = parseReactDoc;
|
|
982
824
|
//# sourceMappingURL=parser.js.map
|