@figma/code-connect 1.0.5 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +2 -595
  2. package/dist/cli.js +2 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/client/figma_client.d.ts +1 -1
  5. package/dist/client/figma_client.js +9 -7
  6. package/dist/client/figma_client.js.map +1 -1
  7. package/dist/commands/connect.d.ts +4 -2
  8. package/dist/commands/connect.d.ts.map +1 -1
  9. package/dist/commands/connect.js +97 -49
  10. package/dist/commands/connect.js.map +1 -1
  11. package/dist/connect/api.d.ts +143 -0
  12. package/dist/connect/api.d.ts.map +1 -0
  13. package/dist/connect/api.js +3 -0
  14. package/dist/connect/api.js.map +1 -0
  15. package/dist/connect/create.d.ts.map +1 -1
  16. package/dist/connect/create.js +4 -0
  17. package/dist/connect/create.js.map +1 -1
  18. package/dist/connect/create_common.d.ts +7 -0
  19. package/dist/connect/create_common.d.ts.map +1 -0
  20. package/dist/connect/create_common.js +19 -0
  21. package/dist/connect/create_common.js.map +1 -0
  22. package/dist/connect/external_types.d.ts +8 -0
  23. package/dist/connect/external_types.d.ts.map +1 -0
  24. package/dist/connect/external_types.js +31 -0
  25. package/dist/connect/external_types.js.map +1 -0
  26. package/dist/connect/figma_connect.d.ts +26 -0
  27. package/dist/connect/figma_connect.d.ts.map +1 -0
  28. package/dist/connect/figma_connect.js +3 -0
  29. package/dist/connect/figma_connect.js.map +1 -0
  30. package/dist/connect/figma_rest_api.d.ts +7 -0
  31. package/dist/connect/figma_rest_api.d.ts.map +1 -1
  32. package/dist/connect/figma_rest_api.js.map +1 -1
  33. package/dist/connect/index_common.d.ts +3 -0
  34. package/dist/connect/index_common.d.ts.map +1 -0
  35. package/dist/connect/index_common.js +23 -0
  36. package/dist/connect/index_common.js.map +1 -0
  37. package/dist/connect/intrinsics.d.ts +94 -0
  38. package/dist/connect/intrinsics.d.ts.map +1 -0
  39. package/dist/connect/intrinsics.js +401 -0
  40. package/dist/connect/intrinsics.js.map +1 -0
  41. package/dist/connect/parser_common.d.ts +144 -0
  42. package/dist/connect/parser_common.d.ts.map +1 -0
  43. package/dist/connect/parser_common.js +297 -0
  44. package/dist/connect/parser_common.js.map +1 -0
  45. package/dist/connect/parser_executable_types.d.ts +20 -23
  46. package/dist/connect/parser_executable_types.d.ts.map +1 -1
  47. package/dist/connect/parser_executable_types.js.map +1 -1
  48. package/dist/connect/parser_executables.js +1 -1
  49. package/dist/connect/parser_executables.js.map +1 -1
  50. package/dist/connect/project.d.ts +20 -5
  51. package/dist/connect/project.d.ts.map +1 -1
  52. package/dist/connect/project.js +79 -16
  53. package/dist/connect/project.js.map +1 -1
  54. package/dist/connect/upload.d.ts +1 -1
  55. package/dist/connect/upload.d.ts.map +1 -1
  56. package/dist/connect/validation.d.ts +1 -1
  57. package/dist/connect/validation.d.ts.map +1 -1
  58. package/dist/connect/wizard/helpers.d.ts +1 -0
  59. package/dist/connect/wizard/helpers.d.ts.map +1 -1
  60. package/dist/connect/wizard/helpers.js +27 -15
  61. package/dist/connect/wizard/helpers.js.map +1 -1
  62. package/dist/connect/wizard/prop_mapping.d.ts +12 -7
  63. package/dist/connect/wizard/prop_mapping.d.ts.map +1 -1
  64. package/dist/connect/wizard/prop_mapping.js +88 -89
  65. package/dist/connect/wizard/prop_mapping.js.map +1 -1
  66. package/dist/connect/wizard/run_wizard.d.ts.map +1 -1
  67. package/dist/connect/wizard/run_wizard.js +8 -3
  68. package/dist/connect/wizard/run_wizard.js.map +1 -1
  69. package/dist/connect/wizard/signature_extraction.d.ts +7 -0
  70. package/dist/connect/wizard/signature_extraction.d.ts.map +1 -0
  71. package/dist/connect/wizard/signature_extraction.js +46 -0
  72. package/dist/connect/wizard/signature_extraction.js.map +1 -0
  73. package/dist/html/__test__/parser/examples/NoConfigObject.figma.d.ts +2 -0
  74. package/dist/html/__test__/parser/examples/NoConfigObject.figma.d.ts.map +1 -0
  75. package/dist/html/__test__/parser/examples/NoConfigObject.figma.js +9 -0
  76. package/dist/html/__test__/parser/examples/NoConfigObject.figma.js.map +1 -0
  77. package/dist/html/__test__/parser/examples/NoExample.figma.d.ts +2 -0
  78. package/dist/html/__test__/parser/examples/NoExample.figma.d.ts.map +1 -0
  79. package/dist/html/__test__/parser/examples/NoExample.figma.js +9 -0
  80. package/dist/html/__test__/parser/examples/NoExample.figma.js.map +1 -0
  81. package/dist/html/__test__/parser/examples/RegularFunctionExampleWithExtraCode.figma.d.ts +2 -0
  82. package/dist/html/__test__/parser/examples/RegularFunctionExampleWithExtraCode.figma.d.ts.map +1 -0
  83. package/dist/html/__test__/parser/examples/RegularFunctionExampleWithExtraCode.figma.js +33 -0
  84. package/dist/html/__test__/parser/examples/RegularFunctionExampleWithExtraCode.figma.js.map +1 -0
  85. package/dist/html/__test__/parser/examples/WrongSignatureJsx.figma.d.ts +2 -0
  86. package/dist/html/__test__/parser/examples/WrongSignatureJsx.figma.d.ts.map +1 -0
  87. package/dist/html/__test__/parser/examples/WrongSignatureJsx.figma.js +15 -0
  88. package/dist/html/__test__/parser/examples/WrongSignatureJsx.figma.js.map +1 -0
  89. package/dist/html/__test__/parser/examples/WrongSignatureNoHtmlTag.figma.d.ts +2 -0
  90. package/dist/html/__test__/parser/examples/WrongSignatureNoHtmlTag.figma.d.ts.map +1 -0
  91. package/dist/html/__test__/parser/examples/WrongSignatureNoHtmlTag.figma.js +15 -0
  92. package/dist/html/__test__/parser/examples/WrongSignatureNoHtmlTag.figma.js.map +1 -0
  93. package/dist/html/__test__/parser/parser.test.d.ts +2 -0
  94. package/dist/html/__test__/parser/parser.test.d.ts.map +1 -0
  95. package/dist/html/__test__/parser/parser.test.js +50 -0
  96. package/dist/html/__test__/parser/parser.test.js.map +1 -0
  97. package/dist/html/create.d.ts +4 -0
  98. package/dist/html/create.d.ts.map +1 -0
  99. package/dist/html/create.js +81 -0
  100. package/dist/html/create.js.map +1 -0
  101. package/dist/html/external.d.ts +8 -0
  102. package/dist/html/external.d.ts.map +1 -0
  103. package/dist/html/external.js +25 -0
  104. package/dist/html/external.js.map +1 -0
  105. package/dist/html/index_html.d.ts +77 -0
  106. package/dist/html/index_html.d.ts.map +1 -0
  107. package/dist/html/index_html.js +42 -0
  108. package/dist/html/index_html.js.map +1 -0
  109. package/dist/html/parser.d.ts +19 -0
  110. package/dist/html/parser.d.ts.map +1 -0
  111. package/dist/html/parser.js +487 -0
  112. package/dist/html/parser.js.map +1 -0
  113. package/dist/html/parser_template_helpers.d.ts +2 -0
  114. package/dist/html/parser_template_helpers.d.ts.map +1 -0
  115. package/dist/html/parser_template_helpers.js +68 -0
  116. package/dist/html/parser_template_helpers.js.map +1 -0
  117. package/dist/html/template_literal.d.ts +5 -0
  118. package/dist/html/template_literal.d.ts.map +1 -0
  119. package/dist/html/template_literal.js +8 -0
  120. package/dist/html/template_literal.js.map +1 -0
  121. package/dist/parser_scripts/get_swift_parser_dir.d.ts +1 -1
  122. package/dist/parser_scripts/get_swift_parser_dir.d.ts.map +1 -1
  123. package/dist/parser_scripts/get_swift_parser_dir.js +38 -10
  124. package/dist/parser_scripts/get_swift_parser_dir.js.map +1 -1
  125. package/dist/react/create.d.ts +5 -0
  126. package/dist/react/create.d.ts.map +1 -1
  127. package/dist/react/create.js +144 -42
  128. package/dist/react/create.js.map +1 -1
  129. package/dist/react/external.d.ts +9 -0
  130. package/dist/react/external.d.ts.map +1 -0
  131. package/dist/react/external.js +45 -0
  132. package/dist/react/external.js.map +1 -0
  133. package/dist/react/index_react.d.ts +94 -0
  134. package/dist/react/index_react.d.ts.map +1 -0
  135. package/dist/react/index_react.js +39 -0
  136. package/dist/react/index_react.js.map +1 -0
  137. package/dist/react/parser.d.ts +6 -38
  138. package/dist/react/parser.d.ts.map +1 -1
  139. package/dist/react/parser.js +141 -298
  140. package/dist/react/parser.js.map +1 -1
  141. package/dist/react/parser_template_helpers.d.ts +15 -15
  142. package/dist/react/parser_template_helpers.d.ts.map +1 -1
  143. package/dist/react/parser_template_helpers.js +51 -35
  144. package/dist/react/parser_template_helpers.js.map +1 -1
  145. package/dist/storybook/convert.d.ts +1 -1
  146. package/dist/storybook/convert.d.ts.map +1 -1
  147. package/dist/storybook/convert.js +6 -4
  148. package/dist/storybook/convert.js.map +1 -1
  149. package/dist/storybook/external.d.ts +1 -1
  150. package/dist/storybook/external.d.ts.map +1 -1
  151. package/dist/typescript/compiler.d.ts +2 -2
  152. package/dist/typescript/compiler.d.ts.map +1 -1
  153. package/dist/typescript/compiler.js +51 -24
  154. package/dist/typescript/compiler.js.map +1 -1
  155. package/package.json +28 -8
@@ -0,0 +1,487 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.parseHtmlDoc = exports.parseExampleTemplate = void 0;
27
+ const typescript_1 = __importStar(require("typescript"));
28
+ const compiler_1 = require("../typescript/compiler");
29
+ const intrinsics_1 = require("../connect/intrinsics");
30
+ const parser_template_helpers_1 = require("./parser_template_helpers");
31
+ const jsdom_1 = require("jsdom");
32
+ const parse5_1 = require("parse5");
33
+ const parser_common_1 = require("../connect/parser_common");
34
+ const prettier_1 = require("prettier");
35
+ function getHtmlTaggedTemplateNode(node) {
36
+ if (typescript_1.default.isTaggedTemplateExpression(node)) {
37
+ const tag = node.tag;
38
+ if (typescript_1.default.isIdentifier(tag) && tag.text === 'html') {
39
+ return node;
40
+ }
41
+ }
42
+ else if (typescript_1.default.isBlock(node) &&
43
+ node.statements.length === 1 &&
44
+ typescript_1.default.isReturnStatement(node.statements[0]) &&
45
+ node.statements[0].expression &&
46
+ typescript_1.default.isTaggedTemplateExpression(node.statements[0].expression) &&
47
+ typescript_1.default.isIdentifier(node.statements[0].expression.tag) &&
48
+ node.statements[0].expression.tag.text === 'html') {
49
+ return node.statements[0].expression;
50
+ }
51
+ return undefined;
52
+ }
53
+ /**
54
+ * This function converts the HTML template literal into a DOM (using JSDOM) to
55
+ * extract information which is used in generating the template:
56
+ * 1. A dictionary of template placeholders which correspond to HTML attribute
57
+ * values. The key is the placeholder index, and the value is the attribute
58
+ * name. We use this to render attribute placeholders appropriately (either
59
+ * in quotes for strings, or as either the attribute name or nothing for
60
+ * booleans).
61
+ * 2. Whether the template is "nestable" or not. A template is considered
62
+ * nestable if it has only one top level element.
63
+ *
64
+ * For finding the attribute placeholders, the algorithm is as follows:
65
+ * 1. Build up a full string from the template literal, replacing any value
66
+ * ${placeholders} with `__FIGMA_PLACEHOLDER_0`, where 0 is the placeholder
67
+ * index. This results in a valid HTML string, with placeholders we can later
68
+ * detect.
69
+ * 2. Use JSDOM to turn this into a DOM.
70
+ * 3. Iterate over every node in the DOM, and if the node has any attributes
71
+ * starting `__FIGMA_PLACEHOLDER`, store the info of these attributes.
72
+ * This allows us to know which template literal placeholders correspond to
73
+ * HTML attributes when we construct the template.
74
+ */
75
+ function getInfoFromDom(templateExp, parserContext) {
76
+ let htmlString;
77
+ if (typescript_1.default.isTemplateExpression(templateExp)) {
78
+ // If this is a template expression, build up the HTML string with
79
+ // identifiable placeholders as described above
80
+ htmlString = templateExp.head.text;
81
+ templateExp.templateSpans.forEach((part, index) => {
82
+ htmlString += `__FIGMA_PLACEHOLDER_${index}` + part.literal.text;
83
+ });
84
+ }
85
+ else if (templateExp.template.kind === typescript_1.default.SyntaxKind.FirstTemplateToken) {
86
+ // This is just a template literal with no placeholders
87
+ htmlString = templateExp.template.text;
88
+ }
89
+ else {
90
+ // This should never happen as we check the type in the calling function
91
+ throw new Error(`Unsupported template type: ${typescript_1.SyntaxKind[templateExp.template.kind]}`);
92
+ }
93
+ // First, check for HTML which we cannot handle. JSDOM is quite forgiving,
94
+ // like a browser, but we need to be stricter
95
+ //
96
+ // Duplicate attribute names are handled gracefully by JSDOM (it just keeps
97
+ // one of the attributes), but this breaks our algorithm because some of the
98
+ // placeholders are no longer in the DOM. JSDOM has no way to detect this, but
99
+ // parse5 (which is a library JSDOM uses under the hood) can detect this. We
100
+ // just thrown an error in this case as there's no use case for doing this.
101
+ (0, parse5_1.parse)(htmlString, {
102
+ onParseError: (error) => {
103
+ if (error.code === 'duplicate-attribute') {
104
+ throw new parser_common_1.ParserError(`Duplicate attribute name in example HTML`, {
105
+ node: templateExp,
106
+ sourceFile: parserContext.sourceFile,
107
+ });
108
+ }
109
+ },
110
+ });
111
+ // Try to format the HTML with prettier, to catch any errors due to invalid
112
+ // HTML which would otherwise result in broken formatting in the UI as
113
+ // prettier is less forgiving
114
+ try {
115
+ // pluginSearchDirs: false is needed as otherwise prettier picks up other
116
+ // prettier plugins in our monorepo and fails on CI
117
+ (0, prettier_1.format)(htmlString, { parser: 'html', pluginSearchDirs: false });
118
+ }
119
+ catch (e) {
120
+ throw new parser_common_1.ParserError(`Error parsing example HTML. Check the HTML is valid.`, {
121
+ node: templateExp,
122
+ sourceFile: parserContext.sourceFile,
123
+ });
124
+ }
125
+ // Create a DOM with JSDOM.
126
+ //
127
+ // JSDOM doesn't work properly in all cases if we parse a DOM without a full
128
+ // document, e.g. Vue templates - when traversing with NodeIterator, it
129
+ // doesn't find all elements. We create a Fragment then append it to a full
130
+ // DOM to work around this. The extra wrapping elements don't matter, as we're
131
+ // only interested in the attributes.
132
+ const fragment = jsdom_1.JSDOM.fragment(htmlString);
133
+ const dom = new jsdom_1.JSDOM('<!DOCTYPE html><html><body></body></html>');
134
+ dom.window.document.body.appendChild(fragment);
135
+ const document = dom.window.document;
136
+ const NodeFilter = dom.window.NodeFilter;
137
+ const attributePlaceholders = {};
138
+ function iterateNodeIterator(nodeIterator) {
139
+ let currentNode;
140
+ while ((currentNode = nodeIterator.nextNode())) {
141
+ // I couldn't work out how to do this in a way which satisfies TypeScript,
142
+ // so using a check and a cast
143
+ if (currentNode.nodeType === dom.window.Node.ELEMENT_NODE) {
144
+ // Check for any attributes which correspond to placeholders in the
145
+ // template literal, and store their index and name
146
+ for (let attr of currentNode.attributes) {
147
+ if (attr.value.startsWith('__FIGMA_PLACEHOLDER_')) {
148
+ attributePlaceholders[parseInt(attr.value.split('__FIGMA_PLACEHOLDER_')[1])] = attr.name;
149
+ }
150
+ }
151
+ }
152
+ // <TEMPLATE> nodes are not iterated over by default, as they are a way to
153
+ // store a fragment which is not rendered immediately. These are used in
154
+ // e.g. Vue templates, so we need to iterate over them explicitly.
155
+ if (currentNode.nodeName === 'TEMPLATE') {
156
+ const templateContent = currentNode.content;
157
+ const templateNodeIterator = document.createNodeIterator(templateContent, NodeFilter.SHOW_ELEMENT, null);
158
+ iterateNodeIterator(templateNodeIterator);
159
+ }
160
+ }
161
+ }
162
+ // Iterate over all the nodes in the DOM
163
+ const nodeIterator = document.createNodeIterator(document.body, NodeFilter.SHOW_ELEMENT, null);
164
+ iterateNodeIterator(nodeIterator);
165
+ // We check if there is more than one top level child, as we use this as a
166
+ // signal that the template is not "nestable" (and so we render an instance
167
+ // pill rather than render the child's code inline in the UI)
168
+ const topLevelChildrenCount = document.body.children.length;
169
+ return {
170
+ attributePlaceholders,
171
+ nestable: topLevelChildrenCount === 1,
172
+ };
173
+ }
174
+ function escapeTemplateString(code) {
175
+ return code.replace(/`/g, '\\`').replace(/\$\{/g, '\\${');
176
+ }
177
+ /**
178
+ * Parses the example template string passed to `figma.connect()`.
179
+ *
180
+ * @param exp A function or arrow function expression
181
+ * @param parserContext Parser context
182
+ * @param propMappings Prop mappings object as returned by parseProps
183
+ *
184
+ * @returns The code of the render function and a list of imports
185
+ */
186
+ function parseExampleTemplate(exp, parserContext, propMappings) {
187
+ const { sourceFile } = parserContext;
188
+ if (exp.parameters.length > 1) {
189
+ throw new parser_common_1.ParserError(`Expected a single props parameter for the render function, got ${exp.parameters.length} parameters`, { sourceFile, node: exp });
190
+ }
191
+ const propsParameter = exp.parameters[0];
192
+ if (!exp.body) {
193
+ throw new parser_common_1.ParserError(`Expected a body for the render function`, { sourceFile, node: exp });
194
+ }
195
+ const templateNode = getHtmlTaggedTemplateNode(exp.body);
196
+ if (!templateNode) {
197
+ throw new parser_common_1.ParserError(`Expected only a tagged template literal as the body of the render function`, { sourceFile, node: templateNode });
198
+ }
199
+ // Keep track of any props which are referenced in the example so that we can
200
+ // insert the appropriate `figma.properties` call in the JS template
201
+ const referencedProps = new Set();
202
+ let exampleCode = '';
203
+ let nestable = true;
204
+ if ((0, typescript_1.isTemplateExpression)(templateNode.template)) {
205
+ // This is a template expression with placeholders
206
+ const createPropPlaceholder = (0, parser_common_1.makeCreatePropPlaceholder)({
207
+ propMappings,
208
+ referencedProps,
209
+ sourceFile,
210
+ });
211
+ // Transform the template to replace any props references with placeholder
212
+ // function calls, normalising the different types of props references
213
+ const transformedTemplate = typescript_1.default.transform(templateNode.template, [
214
+ (context) => (rootNode) => {
215
+ function visit(node) {
216
+ if (typescript_1.default.isTemplateSpan(node)) {
217
+ const visitResult = (0, parser_common_1.visitPropReferencingNode)({
218
+ propsParameter,
219
+ node: node.expression,
220
+ createPropPlaceholder,
221
+ useJsx: false,
222
+ });
223
+ if (visitResult) {
224
+ return typescript_1.default.factory.createTemplateSpan(visitResult, node.literal);
225
+ }
226
+ }
227
+ return typescript_1.default.visitEachChild(node, visit, context);
228
+ }
229
+ return typescript_1.default.visitNode(rootNode, visit);
230
+ },
231
+ ]).transformed[0];
232
+ // Iterate over the template string spans (i.e. the interleaved strings and
233
+ // placeholders) to build up our example code.
234
+ //
235
+ // Each time we encounter a placeholder (which by this point has been
236
+ // normalised to a __PROP__ placeholder function call), we check if it
237
+ // corresponds to a HTML attribute based on our previous DOM analysis (see
238
+ // getInfoFromDom).
239
+ //
240
+ // If it does, we replace it with a call to
241
+ // `_fcc_renderHtmlAttribute("attributeName", propVariableName), otherwise
242
+ // we replace it with a call to `_fcc_renderHtmlValue(propVariableName)`.
243
+ //
244
+ // We have some additional logic to handle cases where the user accidentally
245
+ // writes `attribute="${props.prop}"` rather than `attribute=${props.prop}`
246
+ // (which is what we show in the docs), as it's easy to make this mistake
247
+ // when copy/pasting.
248
+ // Keep track of whether we're inside an attribute value that is wrapped in quotes,
249
+ // so that we can strip the trailing quote if we are
250
+ let insideAttributeWithQuotes = false;
251
+ const infoFromDom = getInfoFromDom(transformedTemplate, parserContext);
252
+ const { attributePlaceholders } = infoFromDom;
253
+ nestable = infoFromDom.nestable;
254
+ // Handle a chunk of HTML, i.e. a text section of the template string. If
255
+ // the next placeholder is an attribute and this chunk ends with a HTML
256
+ // attribute (i.e. matches a regex like ` text=` or ` text="`), we remove the
257
+ // attribute name so that it's not present in the low level template before the
258
+ // call to _fcc_renderHtmlAttribute.
259
+ function handleHtmlChunk(html, nextPlaceholderIsAttribute) {
260
+ // If we were previously inside an attribute value placeholder with quotes
261
+ // surrounding it, remove the leading quote. We do it like this rather
262
+ // than always removing the leading quote to avoid situations where we
263
+ // mistakenly remove a quote that is part of the actual content.
264
+ if (insideAttributeWithQuotes) {
265
+ html = html.replace(/^"/g, '');
266
+ }
267
+ // If the next placeholder is an attribute, then match the start of the
268
+ // attribute (`attribute=`) at the end of this chunk, so that we can
269
+ // remove it from the example code
270
+ const attributeMatches = html.match(/(.*\s)([^\s]+)="?$/s);
271
+ if (nextPlaceholderIsAttribute && attributeMatches) {
272
+ // attributeMatches should always have matched here, but we check it
273
+ // anyway so we can fail gracefully if not
274
+ // Add the code up to the attribute, not including the ` attribute=`
275
+ // part, as _fcc_renderHtmlAttribute is responsible for (maybe)
276
+ // rendering that
277
+ exampleCode += escapeTemplateString(attributeMatches[1]);
278
+ // If we are in this block, we know that we've matched an attribute, so
279
+ // store whether it ends with a quote
280
+ insideAttributeWithQuotes = html.endsWith('"');
281
+ }
282
+ else {
283
+ // No attribute to remove, just add the code
284
+ exampleCode += escapeTemplateString(html);
285
+ insideAttributeWithQuotes = false;
286
+ }
287
+ }
288
+ // Process the first chunk, which is a special case as it is not in templateSpans
289
+ handleHtmlChunk(transformedTemplate.head.text, attributePlaceholders[0] !== undefined);
290
+ // For each section of the template string, check that the expression is a
291
+ // prop placeholder, then add the appropriate template function call
292
+ transformedTemplate.templateSpans.forEach((part, index) => {
293
+ if (!typescript_1.default.isCallExpression(part.expression)) {
294
+ throw new parser_common_1.ParserError(`Expected an call expression as a placeholder in the template, got ${typescript_1.SyntaxKind[part.expression.kind]}`, { sourceFile, node: part.expression });
295
+ }
296
+ const propNameArg = part.expression.arguments[0];
297
+ if (!typescript_1.default.isStringLiteral(propNameArg)) {
298
+ throw new parser_common_1.ParserError(`Expected a string literal as the argument to the placeholder call, got ${typescript_1.SyntaxKind[propNameArg.kind]}`, { sourceFile, node: propNameArg });
299
+ }
300
+ const propVariableName = propNameArg.text;
301
+ referencedProps.add(propVariableName);
302
+ if (attributePlaceholders[index]) {
303
+ exampleCode += `\${_fcc_renderHtmlAttribute('${attributePlaceholders[index]}', ${propVariableName})}`;
304
+ }
305
+ else {
306
+ exampleCode += `\${_fcc_renderHtmlValue(${propVariableName})}`;
307
+ }
308
+ // Process the next chunk
309
+ handleHtmlChunk(part.literal.text, attributePlaceholders[index + 1] !== undefined);
310
+ });
311
+ }
312
+ else if (templateNode.template.kind === typescript_1.default.SyntaxKind.FirstTemplateToken) {
313
+ // Template string with no placeholders
314
+ nestable = getInfoFromDom(templateNode, parserContext).nestable;
315
+ exampleCode = escapeTemplateString(templateNode.template.text);
316
+ }
317
+ else {
318
+ throw new parser_common_1.ParserError(`Expected a template expression as the body of the render function, got ${typescript_1.SyntaxKind[templateNode.template.kind]}`, { sourceFile, node: templateNode.template });
319
+ }
320
+ let templateCode = (0, parser_template_helpers_1.getParsedTemplateHelpersString)() + '\n\n';
321
+ templateCode += `const figma = require('figma')\n\n`;
322
+ templateCode += (0, parser_common_1.getReferencedPropsForTemplate)({
323
+ propMappings,
324
+ referencedProps,
325
+ exp,
326
+ sourceFile,
327
+ });
328
+ templateCode += `export default figma.html\`${exampleCode}\`\n`;
329
+ return {
330
+ code: templateCode,
331
+ nestable,
332
+ };
333
+ }
334
+ exports.parseExampleTemplate = parseExampleTemplate;
335
+ function parseFigmaConnectArgs(node, parserContext) {
336
+ const required = true;
337
+ const figmaNodeUrlArg = (0, compiler_1.parseFunctionArgument)(node, parserContext, 0, typescript_1.default.isStringLiteral, required, `\`${intrinsics_1.FIGMA_CONNECT_CALL}\` must be called with a Figma Component URL as the first argument. Example usage:
338
+ \`${intrinsics_1.FIGMA_CONNECT_CALL}('https://www.figma.com/file/123?node-id=1-1', {
339
+ example: () => html\`<button />\`
340
+ })\``);
341
+ const configObjArg = (0, compiler_1.parseFunctionArgument)(node, parserContext, 1, typescript_1.default.isObjectLiteralExpression, true, `The second argument to ${intrinsics_1.FIGMA_CONNECT_CALL}() must be an object literal. Example usage:
342
+ \`${intrinsics_1.FIGMA_CONNECT_CALL}('https://www.figma.com/file/123?node-id=1-1', {
343
+ example: () => html\`<button />\`
344
+ })\``);
345
+ return {
346
+ figmaNodeUrlArg,
347
+ configObjArg,
348
+ };
349
+ }
350
+ function parseConfigObjectArg(configArg, parserContext) {
351
+ if (!configArg) {
352
+ return {
353
+ propsArg: undefined,
354
+ exampleArg: undefined,
355
+ variantArg: undefined,
356
+ importsArg: undefined,
357
+ linksArg: undefined,
358
+ };
359
+ }
360
+ const propsArg = (0, compiler_1.parsePropertyOfType)({
361
+ objectLiteralNode: configArg,
362
+ propertyName: 'props',
363
+ predicate: typescript_1.default.isObjectLiteralExpression,
364
+ parserContext,
365
+ required: false,
366
+ errorMessage: `The 'props' property must be an object literal. Example usage:
367
+ \`${intrinsics_1.FIGMA_CONNECT_CALL}('https://www.figma.com/file/123?node-id=1-1', {
368
+ props: {
369
+ disabled: figma.boolean('Disabled'),
370
+ text: figma.string('TextContent'),
371
+ },
372
+ example: (props) => html\`<my-button disabled=\${props.disabled} label=\${props.text} />\`
373
+ })\``,
374
+ });
375
+ const exampleArg = (0, compiler_1.parsePropertyOfType)({
376
+ objectLiteralNode: configArg,
377
+ propertyName: 'example',
378
+ predicate: typescript_1.default.isArrowFunction,
379
+ parserContext,
380
+ required: true,
381
+ errorMessage: `The 'example' property must be an arrow function which returns a html tagged template string. Example usage:
382
+ \`${intrinsics_1.FIGMA_CONNECT_CALL}('https://www.figma.com/file/123?node-id=1-1', {
383
+ example: (props) => html\`<my-button />\`
384
+ })\``,
385
+ });
386
+ const variantArg = (0, compiler_1.parsePropertyOfType)({
387
+ objectLiteralNode: configArg,
388
+ propertyName: 'variant',
389
+ predicate: typescript_1.default.isObjectLiteralExpression,
390
+ parserContext,
391
+ required: false,
392
+ errorMessage: `The 'variant' property must be an object literal. Example usage:
393
+ \`${intrinsics_1.FIGMA_CONNECT_CALL}('https://www.figma.com/file/123?node-id=1-1', {
394
+ variant: {
395
+ "Has Icon": true
396
+ },
397
+ example: (props) => html\`<my-button />\`
398
+ })\``,
399
+ });
400
+ const linksArg = (0, compiler_1.parsePropertyOfType)({
401
+ objectLiteralNode: configArg,
402
+ propertyName: 'links',
403
+ predicate: typescript_1.default.isArrayLiteralExpression,
404
+ parserContext,
405
+ required: false,
406
+ errorMessage: `The 'links' property must be an array literal. Example usage:
407
+ \`${intrinsics_1.FIGMA_CONNECT_CALL}('https://www.figma.com/file/123?node-id=1-1', {
408
+ links: [
409
+ { name: 'Storybook', url: 'https://storybook.com' }
410
+ ],
411
+ example: (props) => html\`<my-button />\`
412
+ })\``,
413
+ });
414
+ const importsArg = (0, compiler_1.parsePropertyOfType)({
415
+ objectLiteralNode: configArg,
416
+ propertyName: 'imports',
417
+ predicate: typescript_1.default.isArrayLiteralExpression,
418
+ parserContext,
419
+ required: false,
420
+ errorMessage: `The 'imports' property must be an array literal. Example usage:
421
+ \`${intrinsics_1.FIGMA_CONNECT_CALL}('https://www.figma.com/file/123?node-id=1-1', {
422
+ imports: ['import { Button } from "./Button"']
423
+ example: (props) => html\`<my-button />\`,
424
+ })\``,
425
+ });
426
+ return {
427
+ propsArg,
428
+ exampleArg,
429
+ variantArg,
430
+ linksArg,
431
+ importsArg,
432
+ };
433
+ }
434
+ async function parseHtmlDoc(node, parserContext, { repoUrl, silent }) {
435
+ const { checker, sourceFile, config } = parserContext;
436
+ // Parse the arguments to the `Figma.connect()` call
437
+ const { figmaNodeUrlArg, configObjArg } = parseFigmaConnectArgs(node, parserContext);
438
+ const { propsArg, exampleArg, variantArg, linksArg, importsArg } = parseConfigObjectArg(configObjArg, parserContext);
439
+ let figmaNode = (0, compiler_1.stripQuotesFromNode)(figmaNodeUrlArg);
440
+ // TODO This logic is duplicated in connect.ts transformDocFromParser due to some type issues
441
+ if (config.documentUrlSubstitutions) {
442
+ Object.entries(config.documentUrlSubstitutions).forEach(([from, to]) => {
443
+ // @ts-expect-error
444
+ figmaNode = figmaNode.replace(from, to);
445
+ });
446
+ }
447
+ const metadata = undefined;
448
+ const props = propsArg ? (0, intrinsics_1.parsePropsObject)(propsArg, parserContext) : undefined;
449
+ const render = exampleArg ? parseExampleTemplate(exampleArg, parserContext, props) : undefined;
450
+ const variant = variantArg ? (0, parser_common_1.parseVariant)(variantArg, sourceFile, checker) : undefined;
451
+ const links = linksArg ? (0, parser_common_1.parseLinks)(linksArg, parserContext) : undefined;
452
+ let imports = importsArg ? (0, parser_common_1.parseImports)(importsArg, parserContext) : undefined;
453
+ let template;
454
+ if (render?.code) {
455
+ template = render.code;
456
+ }
457
+ else {
458
+ throw new parser_common_1.ParserError(`${intrinsics_1.FIGMA_CONNECT_CALL}() requires an example function`, {
459
+ sourceFile,
460
+ node,
461
+ });
462
+ }
463
+ return {
464
+ figmaNode,
465
+ label: 'Web Components',
466
+ language: 'html',
467
+ component: metadata?.component,
468
+ source: '',
469
+ sourceLocation: { line: -1 },
470
+ variant,
471
+ template,
472
+ templateData: {
473
+ // TODO: `props` here is currently only used for validation purposes,
474
+ // we should eventually remove it from the JSON payload
475
+ props,
476
+ imports,
477
+ // If there's no render function, the default example is always nestable
478
+ nestable: render ? render.nestable : true,
479
+ },
480
+ links,
481
+ metadata: {
482
+ cliVersion: require('../../package.json').version,
483
+ },
484
+ };
485
+ }
486
+ exports.parseHtmlDoc = parseHtmlDoc;
487
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/html/parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function getParsedTemplateHelpersString(): string;
2
+ //# sourceMappingURL=parser_template_helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser_template_helpers.d.ts","sourceRoot":"","sources":["../../src/html/parser_template_helpers.ts"],"names":[],"mappings":"AA4DA,wBAAgB,8BAA8B,WAE7C"}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ /* istanbul ignore file */
3
+ // This file needs to be ignored from code coverage, as Istanbul adds extra calls
4
+ // to `cov_*` functions which are used to track coverage, but these functions
5
+ // can't be resolved when executing the templates from the unit tests inside
6
+ // `new Function()`
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.getParsedTemplateHelpersString = void 0;
9
+ /**
10
+ * Render a value to HTML, following sensible rules according to the type.
11
+ *
12
+ * @param value The value to render
13
+ */
14
+ function _fcc_renderHtmlValue(value) {
15
+ // If the value is an array, then it's an array of objects representing React
16
+ // children (either of type INSTANCE for pills, or CODE for inline code). The
17
+ // template string handler in the template API handles extracting the instance
18
+ // objects in a way the UI can handle.
19
+ const isComponentArray = Array.isArray(value);
20
+ if (isComponentArray) {
21
+ return figma.html `${value}`;
22
+ }
23
+ if (typeof value === 'object') {
24
+ return JSON.stringify(value);
25
+ }
26
+ else if (typeof value === 'undefined') {
27
+ return '';
28
+ }
29
+ else {
30
+ return value.toString();
31
+ }
32
+ }
33
+ /**
34
+ * Render a value as an HTML attribute. This renders as a string wrapped in
35
+ * quotes, unless the value is a boolean, in which case we output just the
36
+ * attribute name if the value is true, or nothing if the value is false or
37
+ * undefined.
38
+ *
39
+ * @param name The name of the attribute
40
+ * @param value The value of the attribute
41
+ */
42
+ function _fcc_renderHtmlAttribute(name, value) {
43
+ // figma.boolean returns undefined instead of false in some cases
44
+ if (typeof value === 'undefined') {
45
+ return '';
46
+ }
47
+ else if (typeof value === 'boolean') {
48
+ if (value) {
49
+ return name;
50
+ }
51
+ else {
52
+ return '';
53
+ }
54
+ }
55
+ else if (typeof value === 'string' || typeof value === 'number' || typeof value === 'bigint') {
56
+ // Some types might not make sense here but we'll allow anything to be stringified
57
+ return `${name}="${value.toString().replaceAll('\n', '\\n').replaceAll('"', '\\"')}"`;
58
+ }
59
+ else {
60
+ // TODO make this show a proper error in the UI
61
+ return `${name}="Code Connect Error: Unsupported type '${typeof value}' for attribute"`;
62
+ }
63
+ }
64
+ function getParsedTemplateHelpersString() {
65
+ return [_fcc_renderHtmlValue, _fcc_renderHtmlAttribute].map((fn) => fn.toString()).join('\n');
66
+ }
67
+ exports.getParsedTemplateHelpersString = getParsedTemplateHelpersString;
68
+ //# sourceMappingURL=parser_template_helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser_template_helpers.js","sourceRoot":"","sources":["../../src/html/parser_template_helpers.ts"],"names":[],"mappings":";AAAA,0BAA0B;AAC1B,iFAAiF;AACjF,6EAA6E;AAC7E,4EAA4E;AAC5E,mBAAmB;;;AAInB;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,KAAU;IACtC,6EAA6E;IAC7E,6EAA6E;IAC7E,8EAA8E;IAC9E,sCAAsC;IACtC,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC7C,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,KAAK,CAAC,IAAI,CAAA,GAAG,KAAK,EAAE,CAAA;IAC7B,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;IAC9B,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,WAAW,EAAE,CAAC;QACxC,OAAO,EAAE,CAAA;IACX,CAAC;SAAM,CAAC;QACN,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAA;IACzB,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,wBAAwB,CAAC,IAAY,EAAE,KAAU;IACxD,iEAAiE;IACjE,IAAI,OAAO,KAAK,KAAK,WAAW,EAAE,CAAC;QACjC,OAAO,EAAE,CAAA;IACX,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;QACtC,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,IAAI,CAAA;QACb,CAAC;aAAM,CAAC;YACN,OAAO,EAAE,CAAA;QACX,CAAC;IACH,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC/F,kFAAkF;QAClF,OAAO,GAAG,IAAI,KAAK,KAAK,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAA;IACvF,CAAC;SAAM,CAAC;QACN,+CAA+C;QAC/C,OAAO,GAAG,IAAI,2CAA2C,OAAO,KAAK,kBAAkB,CAAA;IACzF,CAAC;AACH,CAAC;AAED,SAAgB,8BAA8B;IAC5C,OAAO,CAAC,oBAAoB,EAAE,wBAAwB,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAC/F,CAAC;AAFD,wEAEC"}
@@ -0,0 +1,5 @@
1
+ export type HtmlTemplateString = {
2
+ __tag: 'HtmlTemplateString';
3
+ };
4
+ export declare function html(strings: TemplateStringsArray, ...values: any[]): HtmlTemplateString;
5
+ //# sourceMappingURL=template_literal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template_literal.d.ts","sourceRoot":"","sources":["../../src/html/template_literal.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,EAAE,oBAAoB,CAAA;CAC5B,CAAA;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,GAAG,kBAAkB,CAExF"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.html = void 0;
4
+ function html(strings, ...values) {
5
+ return { __tag: 'HtmlTemplateString' };
6
+ }
7
+ exports.html = html;
8
+ //# sourceMappingURL=template_literal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template_literal.js","sourceRoot":"","sources":["../../src/html/template_literal.ts"],"names":[],"mappings":";;;AAOA,SAAgB,IAAI,CAAC,OAA6B,EAAE,GAAG,MAAa;IAClE,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAA;AACxC,CAAC;AAFD,oBAEC"}
@@ -1,2 +1,2 @@
1
- export declare function getSwiftParserDir(cwd: string, xcodeprojPath?: string): Promise<string>;
1
+ export declare function getSwiftParserDir(cwd: string, xcodeprojPath?: string, swiftPackagePath?: string): Promise<string>;
2
2
  //# sourceMappingURL=get_swift_parser_dir.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get_swift_parser_dir.d.ts","sourceRoot":"","sources":["../../src/parser_scripts/get_swift_parser_dir.ts"],"names":[],"mappings":"AAYA,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,mBA0F1E"}
1
+ {"version":3,"file":"get_swift_parser_dir.d.ts","sourceRoot":"","sources":["../../src/parser_scripts/get_swift_parser_dir.ts"],"names":[],"mappings":"AAaA,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,aAAa,CAAC,EAAE,MAAM,EACtB,gBAAgB,CAAC,EAAE,MAAM,mBAuH1B"}