@figma/code-connect 1.4.7 → 1.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/connect.d.ts +3 -0
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +101 -24
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/connect_template.d.ts.map +1 -1
- package/dist/commands/connect_template.js +9 -0
- package/dist/commands/connect_template.js.map +1 -1
- package/dist/common/logging.d.ts.map +1 -1
- package/dist/common/logging.js +13 -6
- package/dist/common/logging.js.map +1 -1
- package/dist/common/updates.d.ts.map +1 -1
- package/dist/common/updates.js +2 -2
- package/dist/common/updates.js.map +1 -1
- package/dist/connect/migration_batch_helpers.d.ts +45 -0
- package/dist/connect/migration_batch_helpers.d.ts.map +1 -0
- package/dist/connect/migration_batch_helpers.js +439 -0
- package/dist/connect/migration_batch_helpers.js.map +1 -0
- package/dist/connect/migration_helpers.d.ts +4 -0
- package/dist/connect/migration_helpers.d.ts.map +1 -1
- package/dist/connect/migration_helpers.js +29 -5
- package/dist/connect/migration_helpers.js.map +1 -1
- package/dist/connect/project.d.ts +2 -1
- package/dist/connect/project.d.ts.map +1 -1
- package/dist/connect/project.js +26 -24
- package/dist/connect/project.js.map +1 -1
- package/dist/connect/raw_templates.d.ts +10 -0
- package/dist/connect/raw_templates.d.ts.map +1 -1
- package/dist/connect/raw_templates.js +48 -14
- package/dist/connect/raw_templates.js.map +1 -1
- package/dist/connect/wizard/helpers.d.ts.map +1 -1
- package/dist/connect/wizard/helpers.js +7 -2
- package/dist/connect/wizard/helpers.js.map +1 -1
- package/figma-types.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { CodeConnectJSON } from './figma_connect';
|
|
2
2
|
import { CodeConnectConfig } from './project';
|
|
3
|
+
/**
|
|
4
|
+
* Thrown when a raw template file has no `// url=` directive but contains the
|
|
5
|
+
* string `codeProperties`. These files (e.g. Make's code component property
|
|
6
|
+
* definitions) are not Code Connect, so callers skip them with a log instead of
|
|
7
|
+
* failing. Every other file is handled exactly as before — a missing url is
|
|
8
|
+
* still a hard error.
|
|
9
|
+
*/
|
|
10
|
+
export declare class CodePropertiesError extends Error {
|
|
11
|
+
constructor(message: string);
|
|
12
|
+
}
|
|
3
13
|
/**
|
|
4
14
|
* Returns true if the file content looks like a raw template file, i.e. its
|
|
5
15
|
* leading comment block contains a `// url=`, `// component=`, or `// source=`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raw_templates.d.ts","sourceRoot":"","sources":["../../src/connect/raw_templates.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAI7C;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAatD;
|
|
1
|
+
{"version":3,"file":"raw_templates.d.ts","sourceRoot":"","sources":["../../src/connect/raw_templates.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAI7C;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAatD;AAsFD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9B,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,CAAC,EAAE,iBAAiB,EAC1B,GAAG,CAAC,EAAE,MAAM,EACZ,cAAc,CAAC,EAAE,cAAc,GAC9B,eAAe,CAgGjB"}
|
|
@@ -3,12 +3,27 @@ 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.CodePropertiesError = void 0;
|
|
6
7
|
exports.isRawTemplate = isRawTemplate;
|
|
7
8
|
exports.parseRawFile = parseRawFile;
|
|
8
9
|
const fs_1 = __importDefault(require("fs"));
|
|
9
10
|
const typescript_1 = __importDefault(require("typescript"));
|
|
10
11
|
const label_language_mapping_1 = require("./label_language_mapping");
|
|
11
12
|
const helpers_1 = require("./helpers");
|
|
13
|
+
/**
|
|
14
|
+
* Thrown when a raw template file has no `// url=` directive but contains the
|
|
15
|
+
* string `codeProperties`. These files (e.g. Make's code component property
|
|
16
|
+
* definitions) are not Code Connect, so callers skip them with a log instead of
|
|
17
|
+
* failing. Every other file is handled exactly as before — a missing url is
|
|
18
|
+
* still a hard error.
|
|
19
|
+
*/
|
|
20
|
+
class CodePropertiesError extends Error {
|
|
21
|
+
constructor(message) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = 'CodePropertiesError';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.CodePropertiesError = CodePropertiesError;
|
|
12
27
|
/**
|
|
13
28
|
* Returns true if the file content looks like a raw template file, i.e. its
|
|
14
29
|
* leading comment block contains a `// url=`, `// component=`, or `// source=`
|
|
@@ -29,20 +44,21 @@ function isRawTemplate(content) {
|
|
|
29
44
|
}
|
|
30
45
|
return false;
|
|
31
46
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
//
|
|
47
|
+
// Convert ESM import of 'figma' to require syntax. Supports: import figma from 'figma'
|
|
48
|
+
const figmaImportRegex = /^import\s+figma\s+from\s+['"]figma['"]\s*;?\s*$/m;
|
|
49
|
+
/**
|
|
50
|
+
* Throws if the file imports from anything other than 'figma'. Type-only imports
|
|
51
|
+
* (`import type`) are erased by the TS compiler and are fine; the `figma` default
|
|
52
|
+
* import is the one supported module (no bundling in Phase 1). This runs BEFORE
|
|
53
|
+
* the `codeProperties` skip guard so an unsupported import is always a hard error,
|
|
54
|
+
* even in a file that would otherwise be skipped.
|
|
55
|
+
*/
|
|
56
|
+
function assertOnlyFigmaImports(filePath, fileContent) {
|
|
57
|
+
// Ignore the supported `import figma from 'figma'` form before scanning.
|
|
58
|
+
const withoutFigmaImport = fileContent.replace(figmaImportRegex, '');
|
|
43
59
|
const importRegex = /^import\s+(?!type\s)/m;
|
|
44
|
-
if (importRegex.test(
|
|
45
|
-
const match =
|
|
60
|
+
if (importRegex.test(withoutFigmaImport)) {
|
|
61
|
+
const match = withoutFigmaImport.match(/^(import\s+.+)$/m);
|
|
46
62
|
const importLine = match ? match[1] : 'import ...';
|
|
47
63
|
throw new Error(`TypeScript template files only support importing from 'figma'.\n` +
|
|
48
64
|
`Found in ${filePath}:\n` +
|
|
@@ -50,6 +66,11 @@ function transpileTypeScriptTemplate(filePath, fileContent) {
|
|
|
50
66
|
`Use "const figma = require('figma')" or "import figma from 'figma'" to access the Figma API.\n` +
|
|
51
67
|
`Other module imports will be supported in a future version.`);
|
|
52
68
|
}
|
|
69
|
+
}
|
|
70
|
+
function transpileTypeScriptTemplate(filePath, fileContent) {
|
|
71
|
+
if (figmaImportRegex.test(fileContent)) {
|
|
72
|
+
fileContent = fileContent.replace(figmaImportRegex, "const figma = require('figma')");
|
|
73
|
+
}
|
|
53
74
|
const result = typescript_1.default.transpileModule(fileContent, {
|
|
54
75
|
compilerOptions: {
|
|
55
76
|
module: typescript_1.default.ModuleKind.ESNext,
|
|
@@ -99,13 +120,26 @@ function parseRawFile(filePath, label, config, dir, batchOverrides) {
|
|
|
99
120
|
// Extract metadata fields BEFORE transpilation to avoid losing comments
|
|
100
121
|
// that appear before type-only imports (which TypeScript erases)
|
|
101
122
|
const { fields, templateStartLine } = extractMetadataFields(fileContent);
|
|
123
|
+
const figmaUrl = batchOverrides?.url || fields.url;
|
|
124
|
+
// An unsupported (non-figma) import is always a hard error, even in a file that
|
|
125
|
+
// would otherwise be skipped as a `codeProperties` file below. Checked first so
|
|
126
|
+
// an import mistake is never silently swallowed by the skip guard.
|
|
127
|
+
if (filePath.endsWith('.ts')) {
|
|
128
|
+
assertOnlyFigmaImports(filePath, fileContent);
|
|
129
|
+
}
|
|
130
|
+
// A file with no // url= directive that contains the string `codeProperties`
|
|
131
|
+
// is not Code Connect (e.g. Make's code component property definitions). Skip
|
|
132
|
+
// it (callers log and continue) instead of failing. Every other file is
|
|
133
|
+
// handled exactly as before.
|
|
134
|
+
if (!figmaUrl && fileContent.includes('codeProperties')) {
|
|
135
|
+
throw new CodePropertiesError(`Skipping ${filePath}: file has no // url= directive and contains "codeProperties", so it is not treated as a Code Connect file.`);
|
|
136
|
+
}
|
|
102
137
|
if (filePath.endsWith('.ts')) {
|
|
103
138
|
fileContent = transpileTypeScriptTemplate(filePath, fileContent);
|
|
104
139
|
}
|
|
105
140
|
// For batch templates, metadata comes from the batch entry instead of comments
|
|
106
141
|
const component = batchOverrides?.component || fields.component;
|
|
107
142
|
const source = batchOverrides?.source || fields.source || '';
|
|
108
|
-
const figmaUrl = batchOverrides?.url || fields.url;
|
|
109
143
|
if (!figmaUrl) {
|
|
110
144
|
throw new Error(batchOverrides
|
|
111
145
|
? `Missing required "url" field in ${batchOverrides.batchFilePath}. Please add "url" to each entry in your .figma.batch.json file.`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raw_templates.js","sourceRoot":"","sources":["../../src/connect/raw_templates.ts"],"names":[],"mappings":";;;;;AAaA,sCAaC;AAuFD,oCAoFC;AArMD,4CAAmB;AACnB,4DAA2B;AAG3B,qEAAsF;AACtF,uCAAyD;AAEzD;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,OAAe;IAC3C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAC3B,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/C,IAAI,iCAAiC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBACpD,OAAO,IAAI,CAAA;YACb,CAAC;YACD,SAAQ;QACV,CAAC;QACD,mGAAmG;QACnG,MAAK;IACP,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,2BAA2B,CAAC,QAAgB,EAAE,WAAmB;IACxE,kDAAkD;IAClD,sCAAsC;IACtC,MAAM,gBAAgB,GAAG,kDAAkD,CAAA;IAC3E,IAAI,gBAAgB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QACvC,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,gBAAgB,EAAE,gCAAgC,CAAC,CAAA;IACvF,CAAC;IAED,qFAAqF;IACrF,gFAAgF;IAChF,mFAAmF;IACnF,mBAAmB;IACnB,MAAM,WAAW,GAAG,uBAAuB,CAAA;IAC3C,IAAI,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAA;QACnD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAA;QAClD,MAAM,IAAI,KAAK,CACb,kEAAkE;YAChE,YAAY,QAAQ,KAAK;YACzB,KAAK,UAAU,MAAM;YACrB,gGAAgG;YAChG,6DAA6D,CAChE,CAAA;IACH,CAAC;IAED,MAAM,MAAM,GAAG,oBAAE,CAAC,eAAe,CAAC,WAAW,EAAE;QAC7C,eAAe,EAAE;YACf,MAAM,EAAE,oBAAE,CAAC,UAAU,CAAC,MAAM;YAC5B,MAAM,EAAE,oBAAE,CAAC,YAAY,CAAC,MAAM;YAC9B,cAAc,EAAE,KAAK;SACtB;KACF,CAAC,CAAA;IAEF,OAAO,MAAM,CAAC,UAAU,CAAA;AAC1B,CAAC;AAED;;;;GAIG;AACH,SAAS,qBAAqB,CAAC,WAAmB;IAIhD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACrC,MAAM,MAAM,GAA0D,EAAE,CAAA;IACxE,IAAI,iBAAiB,GAAG,CAAC,CAAA;IAEzB,2DAA2D;IAC3D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QAC5B,oCAAoC;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAA;QAC/C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,GAAG,KAAK,CAAA;YACvC,MAAM,mBAAmB,GAAG,SAAS,CAAC,WAAW,EAAE,CAAA;YACnD,IACE,mBAAmB,KAAK,KAAK;gBAC7B,mBAAmB,KAAK,WAAW;gBACnC,mBAAmB,KAAK,QAAQ,EAChC,CAAC;gBACD,MAAM,CAAC,mBAAmB,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,CAAA;YACjD,CAAC;YACD,iBAAiB,GAAG,CAAC,GAAG,CAAC,CAAA;QAC3B,CAAC;aAAM,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,0EAA0E;YAC1E,SAAQ;QACV,CAAC;aAAM,CAAC;YACN,+BAA+B;YAC/B,MAAK;QACP,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAA;AACtC,CAAC;AAUD,SAAgB,YAAY,CAC1B,QAAgB,EAChB,KAAyB,EACzB,MAA0B,EAC1B,GAAY,EACZ,cAA+B;IAE/B,IAAI,WAAW,GAAG,YAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IAEpD,wEAAwE;IACxE,iEAAiE;IACjE,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAA;IAExE,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7B,WAAW,GAAG,2BAA2B,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAA;IAClE,CAAC;IAED,+EAA+E;IAC/E,MAAM,SAAS,GAAG,cAAc,EAAE,SAAS,IAAI,MAAM,CAAC,SAAS,CAAA;IAC/D,MAAM,MAAM,GAAG,cAAc,EAAE,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,CAAA;IAE5D,MAAM,QAAQ,GAAG,cAAc,EAAE,GAAG,IAAI,MAAM,CAAC,GAAG,CAAA;IAClD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,cAAc;YACZ,CAAC,CAAC,mCAAmC,cAAc,CAAC,aAAa,kEAAkE;YACnI,CAAC,CAAC,iCAAiC,QAAQ,2DAA2D,CACzG,CAAA;IACH,CAAC;IACD,IAAI,YAAY,GAAG,QAAQ,CAAA;IAE3B,qEAAqE;IACrE,2DAA2D;IAC3D,MAAM,eAAe,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC/C,IAAI,kBAAkB,GAAG,CAAC,CAAA;IAE1B,sEAAsE;IACtE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QACtC,6CAA6C;QAC7C,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,SAAQ;QACV,CAAC;QACD,8CAA8C;QAC9C,kBAAkB,GAAG,CAAC,CAAA;QACtB,MAAK;IACP,CAAC;IAED,IAAI,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAEnE,oFAAoF;IACpF,4EAA4E;IAC5E,yFAAyF;IACzF,iEAAiE;IACjE,IAAI,cAAc,EAAE,CAAC;QACnB,QAAQ,GAAG,iCAAiC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,SAAS,CAAC,KAAK,QAAQ,EAAE,CAAA;IACrG,CAAC;IAED,6CAA6C;IAC7C,IAAI,MAAM,EAAE,wBAAwB,EAAE,CAAC;QACrC,YAAY,GAAG,IAAA,uCAA6B,EAAC,YAAY,EAAE,MAAM,CAAC,wBAAwB,CAAC,CAAA;IAC7F,CAAC;IAED,+DAA+D;IAC/D,MAAM,cAAc,GAAG,KAAK,IAAI,MAAM,EAAE,KAAK,IAAI,yCAAgB,CAAC,IAAI,CAAA;IAEtE,MAAM,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,IAAA,kDAAyB,EAAC,cAAc,CAAC,CAAA;IAE9E,OAAO;QACL,SAAS,EAAE,YAAY;QACvB,SAAS;QACT,QAAQ;QACR,wDAAwD;QACxD,gEAAgE;QAChE,qCAAqC;QACrC,YAAY,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE;QACpD,QAAQ;QACR,KAAK,EAAE,cAAc;QACrB,MAAM;QACN,cAAc,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QAC5B,QAAQ,EAAE;YACR,UAAU,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC,OAAO;SAClD;KACF,CAAA;AACH,CAAC","sourcesContent":["import fs from 'fs'\nimport ts from 'typescript'\nimport { CodeConnectJSON } from './figma_connect'\nimport { CodeConnectConfig } from './project'\nimport { CodeConnectLabel, getInferredLanguageForRaw } from './label_language_mapping'\nimport { applyDocumentUrlSubstitutions } from './helpers'\n\n/**\n * Returns true if the file content looks like a raw template file, i.e. its\n * leading comment block contains a `// url=`, `// component=`, or `// source=`\n * directive. Used to distinguish raw `.figma.ts` templates from React/HTML\n * Code Connect files that share the same extension.\n */\nexport function isRawTemplate(content: string): boolean {\n for (const line of content.split('\\n')) {\n const trimmed = line.trim()\n if (trimmed === '' || trimmed.startsWith('//')) {\n if (/^\\/\\/\\s*(url|component|source)=/.test(trimmed)) {\n return true\n }\n continue\n }\n // First non-comment, non-blank line reached without finding a known directive — not a raw template\n break\n }\n return false\n}\n\nfunction transpileTypeScriptTemplate(filePath: string, fileContent: string): string {\n // Convert ESM import of 'figma' to require syntax\n // Supports: import figma from 'figma'\n const figmaImportRegex = /^import\\s+figma\\s+from\\s+['\"]figma['\"]\\s*;?\\s*$/m\n if (figmaImportRegex.test(fileContent)) {\n fileContent = fileContent.replace(figmaImportRegex, \"const figma = require('figma')\")\n }\n\n // Detect any remaining non-type import statements. Type-only imports (`import type`)\n // are erased by the TS compiler and are fine. Regular imports (except the figma\n // import we just converted) are not supported in Phase 1 (no bundling), so we show\n // a helpful error.\n const importRegex = /^import\\s+(?!type\\s)/m\n if (importRegex.test(fileContent)) {\n const match = fileContent.match(/^(import\\s+.+)$/m)\n const importLine = match ? match[1] : 'import ...'\n throw new Error(\n `TypeScript template files only support importing from 'figma'.\\n` +\n `Found in ${filePath}:\\n` +\n ` ${importLine}\\n\\n` +\n `Use \"const figma = require('figma')\" or \"import figma from 'figma'\" to access the Figma API.\\n` +\n `Other module imports will be supported in a future version.`,\n )\n }\n\n const result = ts.transpileModule(fileContent, {\n compilerOptions: {\n module: ts.ModuleKind.ESNext,\n target: ts.ScriptTarget.ES2021,\n removeComments: false,\n },\n })\n\n return result.outputText\n}\n\n/**\n * Extracts metadata fields (url, component, source) from the leading comments\n * of a raw template file. This must be done before transpilation because\n * TypeScript can remove comments that appear before type-only imports.\n */\nfunction extractMetadataFields(fileContent: string): {\n fields: { url?: string; component?: string; source?: string }\n templateStartLine: number\n} {\n const lines = fileContent.split('\\n')\n const fields: { url?: string; component?: string; source?: string } = {}\n let templateStartLine = 0\n\n // Parse consecutive comment lines at the start of the file\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim()\n // Match pattern: // fieldName=value\n const match = line.match(/^\\/\\/\\s*(\\w+)=(.+)$/)\n if (match) {\n const [, fieldName, fieldValue] = match\n const normalizedFieldName = fieldName.toLowerCase()\n if (\n normalizedFieldName === 'url' ||\n normalizedFieldName === 'component' ||\n normalizedFieldName === 'source'\n ) {\n fields[normalizedFieldName] = fieldValue.trim()\n }\n templateStartLine = i + 1\n } else if (line === '' || line.startsWith('//')) {\n // Allow blank lines or other comments, but don't increment template start\n continue\n } else {\n // First non-comment line found\n break\n }\n }\n\n return { fields, templateStartLine }\n}\n\nexport interface BatchOverrides {\n url: string\n source?: string\n component?: string\n batchData: Record<string, any>\n batchFilePath: string\n}\n\nexport function parseRawFile(\n filePath: string,\n label: string | undefined,\n config?: CodeConnectConfig,\n dir?: string,\n batchOverrides?: BatchOverrides,\n): CodeConnectJSON {\n let fileContent = fs.readFileSync(filePath, 'utf-8')\n\n // Extract metadata fields BEFORE transpilation to avoid losing comments\n // that appear before type-only imports (which TypeScript erases)\n const { fields, templateStartLine } = extractMetadataFields(fileContent)\n\n if (filePath.endsWith('.ts')) {\n fileContent = transpileTypeScriptTemplate(filePath, fileContent)\n }\n\n // For batch templates, metadata comes from the batch entry instead of comments\n const component = batchOverrides?.component || fields.component\n const source = batchOverrides?.source || fields.source || ''\n\n const figmaUrl = batchOverrides?.url || fields.url\n if (!figmaUrl) {\n throw new Error(\n batchOverrides\n ? `Missing required \"url\" field in ${batchOverrides.batchFilePath}. Please add \"url\" to each entry in your .figma.batch.json file.`\n : `Missing required url field in ${filePath}. Please add a // url=... comment to the top of the file.`,\n )\n }\n let figmaNodeUrl = figmaUrl\n\n // Extract template from the transpiled content, starting at the line\n // where the metadata comments ended in the original source\n const transpiledLines = fileContent.split('\\n')\n let templateStartIndex = 0\n\n // Skip lines until we've passed the original metadata comment section\n for (let i = 0; i < transpiledLines.length; i++) {\n const line = transpiledLines[i].trim()\n // Skip blank lines and comments at the start\n if (line === '' || line.startsWith('//')) {\n continue\n }\n // First non-comment line in transpiled output\n templateStartIndex = i\n break\n }\n\n let template = transpiledLines.slice(templateStartIndex).join('\\n')\n\n // For batch templates, set globalThis['__FIGMA_BATCH'] so the runtime exposes it as\n // figma.batch. Using globalThis rather than a const so it's accessible from\n // __FIGMA_CODE_CONNECT_REQUIRE's closure regardless of where require('figma') is called.\n // (globalThis works in both browser and Node.js, unlike window.)\n if (batchOverrides) {\n template = `globalThis['__FIGMA_BATCH'] = ${JSON.stringify(batchOverrides.batchData)}\\n${template}`\n }\n\n // Apply documentUrlSubstitutions if provided\n if (config?.documentUrlSubstitutions) {\n figmaNodeUrl = applyDocumentUrlSubstitutions(figmaNodeUrl, config.documentUrlSubstitutions)\n }\n\n // Determine effective label from parameter, config, or default\n const effectiveLabel = label || config?.label || CodeConnectLabel.Code\n\n const language = config?.language || getInferredLanguageForRaw(effectiveLabel)\n\n return {\n figmaNode: figmaNodeUrl,\n component,\n template,\n // nestable by default unless user specifies in template\n // (templateData.nestable AND template.metadata.nestable need to\n // be true for instance to be nested)\n templateData: { nestable: true, isParserless: true },\n language,\n label: effectiveLabel,\n source,\n sourceLocation: { line: -1 },\n metadata: {\n cliVersion: require('../../package.json').version,\n },\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"raw_templates.js","sourceRoot":"","sources":["../../src/connect/raw_templates.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs'\nimport ts from 'typescript'\nimport { CodeConnectJSON } from './figma_connect'\nimport { CodeConnectConfig } from './project'\nimport { CodeConnectLabel, getInferredLanguageForRaw } from './label_language_mapping'\nimport { applyDocumentUrlSubstitutions } from './helpers'\n\n/**\n * Thrown when a raw template file has no `// url=` directive but contains the\n * string `codeProperties`. These files (e.g. Make's code component property\n * definitions) are not Code Connect, so callers skip them with a log instead of\n * failing. Every other file is handled exactly as before — a missing url is\n * still a hard error.\n */\nexport class CodePropertiesError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'CodePropertiesError'\n }\n}\n\n/**\n * Returns true if the file content looks like a raw template file, i.e. its\n * leading comment block contains a `// url=`, `// component=`, or `// source=`\n * directive. Used to distinguish raw `.figma.ts` templates from React/HTML\n * Code Connect files that share the same extension.\n */\nexport function isRawTemplate(content: string): boolean {\n for (const line of content.split('\\n')) {\n const trimmed = line.trim()\n if (trimmed === '' || trimmed.startsWith('//')) {\n if (/^\\/\\/\\s*(url|component|source)=/.test(trimmed)) {\n return true\n }\n continue\n }\n // First non-comment, non-blank line reached without finding a known directive — not a raw template\n break\n }\n return false\n}\n\n// Convert ESM import of 'figma' to require syntax. Supports: import figma from 'figma'\nconst figmaImportRegex = /^import\\s+figma\\s+from\\s+['\"]figma['\"]\\s*;?\\s*$/m\n\n/**\n * Throws if the file imports from anything other than 'figma'. Type-only imports\n * (`import type`) are erased by the TS compiler and are fine; the `figma` default\n * import is the one supported module (no bundling in Phase 1). This runs BEFORE\n * the `codeProperties` skip guard so an unsupported import is always a hard error,\n * even in a file that would otherwise be skipped.\n */\nfunction assertOnlyFigmaImports(filePath: string, fileContent: string): void {\n // Ignore the supported `import figma from 'figma'` form before scanning.\n const withoutFigmaImport = fileContent.replace(figmaImportRegex, '')\n const importRegex = /^import\\s+(?!type\\s)/m\n if (importRegex.test(withoutFigmaImport)) {\n const match = withoutFigmaImport.match(/^(import\\s+.+)$/m)\n const importLine = match ? match[1] : 'import ...'\n throw new Error(\n `TypeScript template files only support importing from 'figma'.\\n` +\n `Found in ${filePath}:\\n` +\n ` ${importLine}\\n\\n` +\n `Use \"const figma = require('figma')\" or \"import figma from 'figma'\" to access the Figma API.\\n` +\n `Other module imports will be supported in a future version.`,\n )\n }\n}\n\nfunction transpileTypeScriptTemplate(filePath: string, fileContent: string): string {\n if (figmaImportRegex.test(fileContent)) {\n fileContent = fileContent.replace(figmaImportRegex, \"const figma = require('figma')\")\n }\n\n const result = ts.transpileModule(fileContent, {\n compilerOptions: {\n module: ts.ModuleKind.ESNext,\n target: ts.ScriptTarget.ES2021,\n removeComments: false,\n },\n })\n\n return result.outputText\n}\n\n/**\n * Extracts metadata fields (url, component, source) from the leading comments\n * of a raw template file. This must be done before transpilation because\n * TypeScript can remove comments that appear before type-only imports.\n */\nfunction extractMetadataFields(fileContent: string): {\n fields: { url?: string; component?: string; source?: string }\n templateStartLine: number\n} {\n const lines = fileContent.split('\\n')\n const fields: { url?: string; component?: string; source?: string } = {}\n let templateStartLine = 0\n\n // Parse consecutive comment lines at the start of the file\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim()\n // Match pattern: // fieldName=value\n const match = line.match(/^\\/\\/\\s*(\\w+)=(.+)$/)\n if (match) {\n const [, fieldName, fieldValue] = match\n const normalizedFieldName = fieldName.toLowerCase()\n if (\n normalizedFieldName === 'url' ||\n normalizedFieldName === 'component' ||\n normalizedFieldName === 'source'\n ) {\n fields[normalizedFieldName] = fieldValue.trim()\n }\n templateStartLine = i + 1\n } else if (line === '' || line.startsWith('//')) {\n // Allow blank lines or other comments, but don't increment template start\n continue\n } else {\n // First non-comment line found\n break\n }\n }\n\n return { fields, templateStartLine }\n}\n\nexport interface BatchOverrides {\n url: string\n source?: string\n component?: string\n batchData: Record<string, any>\n batchFilePath: string\n}\n\nexport function parseRawFile(\n filePath: string,\n label: string | undefined,\n config?: CodeConnectConfig,\n dir?: string,\n batchOverrides?: BatchOverrides,\n): CodeConnectJSON {\n let fileContent = fs.readFileSync(filePath, 'utf-8')\n\n // Extract metadata fields BEFORE transpilation to avoid losing comments\n // that appear before type-only imports (which TypeScript erases)\n const { fields, templateStartLine } = extractMetadataFields(fileContent)\n\n const figmaUrl = batchOverrides?.url || fields.url\n\n // An unsupported (non-figma) import is always a hard error, even in a file that\n // would otherwise be skipped as a `codeProperties` file below. Checked first so\n // an import mistake is never silently swallowed by the skip guard.\n if (filePath.endsWith('.ts')) {\n assertOnlyFigmaImports(filePath, fileContent)\n }\n\n // A file with no // url= directive that contains the string `codeProperties`\n // is not Code Connect (e.g. Make's code component property definitions). Skip\n // it (callers log and continue) instead of failing. Every other file is\n // handled exactly as before.\n if (!figmaUrl && fileContent.includes('codeProperties')) {\n throw new CodePropertiesError(\n `Skipping ${filePath}: file has no // url= directive and contains \"codeProperties\", so it is not treated as a Code Connect file.`,\n )\n }\n\n if (filePath.endsWith('.ts')) {\n fileContent = transpileTypeScriptTemplate(filePath, fileContent)\n }\n\n // For batch templates, metadata comes from the batch entry instead of comments\n const component = batchOverrides?.component || fields.component\n const source = batchOverrides?.source || fields.source || ''\n\n if (!figmaUrl) {\n throw new Error(\n batchOverrides\n ? `Missing required \"url\" field in ${batchOverrides.batchFilePath}. Please add \"url\" to each entry in your .figma.batch.json file.`\n : `Missing required url field in ${filePath}. Please add a // url=... comment to the top of the file.`,\n )\n }\n let figmaNodeUrl = figmaUrl\n\n // Extract template from the transpiled content, starting at the line\n // where the metadata comments ended in the original source\n const transpiledLines = fileContent.split('\\n')\n let templateStartIndex = 0\n\n // Skip lines until we've passed the original metadata comment section\n for (let i = 0; i < transpiledLines.length; i++) {\n const line = transpiledLines[i].trim()\n // Skip blank lines and comments at the start\n if (line === '' || line.startsWith('//')) {\n continue\n }\n // First non-comment line in transpiled output\n templateStartIndex = i\n break\n }\n\n let template = transpiledLines.slice(templateStartIndex).join('\\n')\n\n // For batch templates, set globalThis['__FIGMA_BATCH'] so the runtime exposes it as\n // figma.batch. Using globalThis rather than a const so it's accessible from\n // __FIGMA_CODE_CONNECT_REQUIRE's closure regardless of where require('figma') is called.\n // (globalThis works in both browser and Node.js, unlike window.)\n if (batchOverrides) {\n template = `globalThis['__FIGMA_BATCH'] = ${JSON.stringify(batchOverrides.batchData)}\\n${template}`\n }\n\n // Apply documentUrlSubstitutions if provided\n if (config?.documentUrlSubstitutions) {\n figmaNodeUrl = applyDocumentUrlSubstitutions(figmaNodeUrl, config.documentUrlSubstitutions)\n }\n\n // Determine effective label from parameter, config, or default\n const effectiveLabel = label || config?.label || CodeConnectLabel.Code\n\n const language = config?.language || getInferredLanguageForRaw(effectiveLabel)\n\n return {\n figmaNode: figmaNodeUrl,\n component,\n template,\n // nestable by default unless user specifies in template\n // (templateData.nestable AND template.metadata.nestable need to\n // be true for instance to be nested)\n templateData: { nestable: true, isParserless: true },\n language,\n label: effectiveLabel,\n source,\n sourceLocation: { line: -1 },\n metadata: {\n cliVersion: require('../../package.json').version,\n },\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/connect/wizard/helpers.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,iBAAiB,
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/connect/wizard/helpers.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,iBAAiB,EAKjB,WAAW,EAIZ,MAAM,YAAY,CAAA;AAGnB,OAAO,OAAmB,MAAM,SAAS,CAAA;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAIpD,wBAAgB,qCAAqC,SAKpD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,kBAAkB,EAClB,MAAM,GACP,EAAE;IACD,GAAG,EAAE,MAAM,CAAA;IACX,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,MAAM,EAAE,iBAAiB,CAAA;CAC1B,wBAiBA;AAED,wBAAsB,aAAa,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,iBAK9F;AAED,wBAAgB,iBAAiB,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,QAI5F;AAED,wBAAsB,uBAAuB,CAAC,EAC5C,GAAG,EACH,kBAAkB,EAClB,MAAM,EACN,QAAQ,GACT,EAAE;IACD,GAAG,EAAE,MAAM,CAAA;IACX,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,MAAM,EAAE,iBAAiB,CAAA;IACzB,QAAQ,EAAE,MAAM,CAAA;CACjB,iBA2BA;AAID,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,MAAM;;;;;;EAazD;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,UAE9D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,eAAe,EAAE,MAAM,EAAE,oCAe/D;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,YAgCrF;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,WAa1C"}
|
|
@@ -76,9 +76,14 @@ function getIncludesGlob({ dir, componentDirectory, config, }) {
|
|
|
76
76
|
if (config.parser === 'custom') {
|
|
77
77
|
return [];
|
|
78
78
|
}
|
|
79
|
-
|
|
79
|
+
const defaultIncludeGlobs = config.parser
|
|
80
|
+
? project_1.DEFAULT_INCLUDE_GLOBS_BY_PARSER[config.parser]
|
|
81
|
+
: project_1.DEFAULT_PARSERLESS_INCLUDE_GLOBS;
|
|
82
|
+
return defaultIncludeGlobs?.map((defaultIncludeGlob) => `${pathToComponentsDir}/${defaultIncludeGlob}`);
|
|
80
83
|
}
|
|
81
|
-
return
|
|
84
|
+
return config.parser
|
|
85
|
+
? project_1.DEFAULT_INCLUDE_GLOBS_BY_PARSER[config.parser]
|
|
86
|
+
: project_1.DEFAULT_PARSERLESS_INCLUDE_GLOBS;
|
|
82
87
|
}
|
|
83
88
|
async function createEnvFile({ dir, accessToken }) {
|
|
84
89
|
// Create .env file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/connect/wizard/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import * as prettier from 'prettier'\nimport fs from 'fs'\nimport {\n CodeConnectConfig,\n CodeConnectParser,\n DEFAULT_INCLUDE_GLOBS_BY_PARSER,\n DEFAULT_LABEL_PER_PARSER,\n ProjectInfo,\n ReactProjectInfo,\n getDefaultConfigPath,\n getEnvPath,\n} from '../project'\nimport { exitWithError, logger, success } from '../../common/logging'\nimport path from 'path'\nimport prompts, { Choice } from 'prompts'\nimport { BaseCommand } from '../../commands/connect'\nimport { isFigmaConnectFile } from '../parser_common'\nimport { parseFileKey } from '../helpers'\n\nexport function maybePrefillWizardQuestionsForTesting() {\n if (process.env.JEST_WORKER_ID && process.env.WIZARD_ANSWERS_TO_PREFILL) {\n const unescapedJson = JSON.parse(process.env.WIZARD_ANSWERS_TO_PREFILL.replace(/\\\\\"/g, '\"'))\n prompts.inject(unescapedJson)\n }\n}\n\n/**\n *\n * Gets the default include globs for config.parser with componentDirectory prepended\n * @param args\n * @param args.dir project root path\n * @param args.componentDirectory optional path to where includes should be limited to\n * @param args.config CodeConnectConfig\n * @returns array of include globs\n */\nexport function getIncludesGlob({\n dir,\n componentDirectory,\n config,\n}: {\n dir: string\n componentDirectory: string | null\n config: CodeConnectConfig\n}) {\n if (componentDirectory) {\n // use unix separators for config file globs\n const pathToComponentsDir = path.relative(dir, componentDirectory).replaceAll(path.sep, '/')\n if (config.parser === 'custom') {\n return []\n }\n return DEFAULT_INCLUDE_GLOBS_BY_PARSER[config.parser!].map(\n (defaultIncludeGlob) => `${pathToComponentsDir}/${defaultIncludeGlob}`,\n )\n }\n return DEFAULT_INCLUDE_GLOBS_BY_PARSER[config.parser!]\n}\n\nexport async function createEnvFile({ dir, accessToken }: { dir: string; accessToken?: string }) {\n // Create .env file\n const filePath = getDefaultConfigPath(dir)\n fs.writeFileSync(getEnvPath(dir), `FIGMA_ACCESS_TOKEN=\"${accessToken}\"`)\n logger.info(success(`Created ${filePath}`))\n}\n\nexport function addTokenToEnvFile({ dir, accessToken }: { dir: string; accessToken?: string }) {\n const filePath = getDefaultConfigPath(dir)\n fs.appendFileSync(getEnvPath(dir), `\\nFIGMA_ACCESS_TOKEN=\"${accessToken}\"`)\n logger.info(success(`Appended access token to ${filePath}`))\n}\n\nexport async function createCodeConnectConfig({\n dir,\n componentDirectory,\n config,\n figmaUrl,\n}: {\n dir: string\n componentDirectory: string | null\n config: CodeConnectConfig\n figmaUrl: string\n}) {\n const label = DEFAULT_LABEL_PER_PARSER[config.parser as CodeConnectParser]\n const includesGlob = getIncludesGlob({ dir, componentDirectory, config })\n\n const configJson = label\n ? `{\n \"codeConnect\": {\n \"include\": [\"${includesGlob}\"],\n \"label\": \"${label}\",\n \"interactiveSetupFigmaFileUrl\": \"${figmaUrl}\",\n}\n}`\n : `{\n \"codeConnect\": {\n \"include\": [\"${includesGlob}\"],\n \"interactiveSetupFigmaFileUrl\": \"${figmaUrl}\",\n }\n}`\n\n const formatted = await prettier.format(configJson, {\n parser: 'json',\n })\n const filePath = getDefaultConfigPath(dir)\n\n fs.writeFileSync(filePath, formatted)\n\n logger.info(success(`Created ${filePath}`))\n}\n\nconst FILEPATH_EXPORT_DELIMITER = '~'\n\nexport function parseFilepathExport(filepathExport: string) {\n const delimiterLastIndex = filepathExport.lastIndexOf(FILEPATH_EXPORT_DELIMITER)\n\n if (delimiterLastIndex === -1) {\n return {\n filepath: filepathExport,\n exportName: null,\n }\n }\n return {\n filepath: filepathExport.substring(0, delimiterLastIndex),\n exportName: filepathExport.substring(delimiterLastIndex + 1),\n }\n}\n\nexport function getFilepathExport(filepath: string, exp: string) {\n return `${filepath}${FILEPATH_EXPORT_DELIMITER}${exp}`\n}\n\n/**\n * Formats an array of filepathExports into a map of filepaths->exports\n *\n * @param filepathExports an array of components in the format `${filepath}~${componentName}\n * @returns a map of filepaths to an array of their exports. Array is empty if no exports found\n */\nexport function getComponentOptionsMap(filepathExports: string[]) {\n return filepathExports.reduce(\n (acc, filepathExport) => {\n const { filepath, exportName } = parseFilepathExport(filepathExport)\n acc[filepath] = acc[filepath] || []\n if (exportName) {\n acc[filepath].push({\n title: exportName,\n value: getFilepathExport(filepath, exportName),\n })\n }\n return acc\n },\n {} as Record<string, Choice[]>,\n )\n}\n\n/**\n * Parses a ProjectInfo for any TS exports (or filepaths if not a TS project)\n *\n * @param projectInfo\n * @returns an array of components in the format `${filepath}~${componentName}\n */\nexport function getFilepathExportsFromFiles(projectInfo: ProjectInfo, cmd: BaseCommand) {\n return projectInfo.files.reduce((options, filepath) => {\n if (projectInfo.config.parser === 'react') {\n const { tsProgram } = projectInfo as ReactProjectInfo\n if (!isFigmaConnectFile(tsProgram, filepath, 'tsx')) {\n const checker = tsProgram.getTypeChecker()\n const sourceFile = tsProgram.getSourceFile(filepath)\n if (!sourceFile) {\n if (cmd.verbose) {\n logger.warn(`Could not parse file for TypeScript: ${filepath}`)\n }\n } else {\n try {\n const sourceFileSymbol = checker.getSymbolAtLocation(sourceFile)!\n const exports = checker.getExportsOfModule(sourceFileSymbol)\n\n exports.forEach((exp) => {\n options.push(getFilepathExport(filepath, exp.getName()))\n })\n } catch (e) {\n if (cmd.verbose) {\n logger.warn(`Could not parse exports of file: ${filepath}`)\n }\n // ignore invalid files\n }\n }\n }\n } else {\n options.push(filepath)\n }\n return options\n }, [] as string[])\n}\n\nexport function isValidFigmaUrl(url: string) {\n try {\n const { hostname } = new URL(url)\n if (\n !hostname.includes('figma.com')\n ) {\n return false\n }\n\n return !!parseFileKey(url)\n } catch (e) {\n return false\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/connect/wizard/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import * as prettier from 'prettier'\nimport fs from 'fs'\nimport {\n CodeConnectConfig,\n CodeConnectParser,\n DEFAULT_INCLUDE_GLOBS_BY_PARSER,\n DEFAULT_LABEL_PER_PARSER,\n DEFAULT_PARSERLESS_INCLUDE_GLOBS,\n ProjectInfo,\n ReactProjectInfo,\n getDefaultConfigPath,\n getEnvPath,\n} from '../project'\nimport { exitWithError, logger, success } from '../../common/logging'\nimport path from 'path'\nimport prompts, { Choice } from 'prompts'\nimport { BaseCommand } from '../../commands/connect'\nimport { isFigmaConnectFile } from '../parser_common'\nimport { parseFileKey } from '../helpers'\n\nexport function maybePrefillWizardQuestionsForTesting() {\n if (process.env.JEST_WORKER_ID && process.env.WIZARD_ANSWERS_TO_PREFILL) {\n const unescapedJson = JSON.parse(process.env.WIZARD_ANSWERS_TO_PREFILL.replace(/\\\\\"/g, '\"'))\n prompts.inject(unescapedJson)\n }\n}\n\n/**\n *\n * Gets the default include globs for config.parser with componentDirectory prepended\n * @param args\n * @param args.dir project root path\n * @param args.componentDirectory optional path to where includes should be limited to\n * @param args.config CodeConnectConfig\n * @returns array of include globs\n */\nexport function getIncludesGlob({\n dir,\n componentDirectory,\n config,\n}: {\n dir: string\n componentDirectory: string | null\n config: CodeConnectConfig\n}) {\n if (componentDirectory) {\n // use unix separators for config file globs\n const pathToComponentsDir = path.relative(dir, componentDirectory).replaceAll(path.sep, '/')\n if (config.parser === 'custom') {\n return []\n }\n const defaultIncludeGlobs = config.parser\n ? DEFAULT_INCLUDE_GLOBS_BY_PARSER[config.parser]\n : DEFAULT_PARSERLESS_INCLUDE_GLOBS\n return defaultIncludeGlobs?.map(\n (defaultIncludeGlob) => `${pathToComponentsDir}/${defaultIncludeGlob}`,\n )\n }\n return config.parser\n ? DEFAULT_INCLUDE_GLOBS_BY_PARSER[config.parser]\n : DEFAULT_PARSERLESS_INCLUDE_GLOBS\n}\n\nexport async function createEnvFile({ dir, accessToken }: { dir: string; accessToken?: string }) {\n // Create .env file\n const filePath = getDefaultConfigPath(dir)\n fs.writeFileSync(getEnvPath(dir), `FIGMA_ACCESS_TOKEN=\"${accessToken}\"`)\n logger.info(success(`Created ${filePath}`))\n}\n\nexport function addTokenToEnvFile({ dir, accessToken }: { dir: string; accessToken?: string }) {\n const filePath = getDefaultConfigPath(dir)\n fs.appendFileSync(getEnvPath(dir), `\\nFIGMA_ACCESS_TOKEN=\"${accessToken}\"`)\n logger.info(success(`Appended access token to ${filePath}`))\n}\n\nexport async function createCodeConnectConfig({\n dir,\n componentDirectory,\n config,\n figmaUrl,\n}: {\n dir: string\n componentDirectory: string | null\n config: CodeConnectConfig\n figmaUrl: string\n}) {\n const label = DEFAULT_LABEL_PER_PARSER[config.parser as CodeConnectParser]\n const includesGlob = getIncludesGlob({ dir, componentDirectory, config })\n\n const configJson = label\n ? `{\n \"codeConnect\": {\n \"include\": [\"${includesGlob}\"],\n \"label\": \"${label}\",\n \"interactiveSetupFigmaFileUrl\": \"${figmaUrl}\",\n}\n}`\n : `{\n \"codeConnect\": {\n \"include\": [\"${includesGlob}\"],\n \"interactiveSetupFigmaFileUrl\": \"${figmaUrl}\",\n }\n}`\n\n const formatted = await prettier.format(configJson, {\n parser: 'json',\n })\n const filePath = getDefaultConfigPath(dir)\n\n fs.writeFileSync(filePath, formatted)\n\n logger.info(success(`Created ${filePath}`))\n}\n\nconst FILEPATH_EXPORT_DELIMITER = '~'\n\nexport function parseFilepathExport(filepathExport: string) {\n const delimiterLastIndex = filepathExport.lastIndexOf(FILEPATH_EXPORT_DELIMITER)\n\n if (delimiterLastIndex === -1) {\n return {\n filepath: filepathExport,\n exportName: null,\n }\n }\n return {\n filepath: filepathExport.substring(0, delimiterLastIndex),\n exportName: filepathExport.substring(delimiterLastIndex + 1),\n }\n}\n\nexport function getFilepathExport(filepath: string, exp: string) {\n return `${filepath}${FILEPATH_EXPORT_DELIMITER}${exp}`\n}\n\n/**\n * Formats an array of filepathExports into a map of filepaths->exports\n *\n * @param filepathExports an array of components in the format `${filepath}~${componentName}\n * @returns a map of filepaths to an array of their exports. Array is empty if no exports found\n */\nexport function getComponentOptionsMap(filepathExports: string[]) {\n return filepathExports.reduce(\n (acc, filepathExport) => {\n const { filepath, exportName } = parseFilepathExport(filepathExport)\n acc[filepath] = acc[filepath] || []\n if (exportName) {\n acc[filepath].push({\n title: exportName,\n value: getFilepathExport(filepath, exportName),\n })\n }\n return acc\n },\n {} as Record<string, Choice[]>,\n )\n}\n\n/**\n * Parses a ProjectInfo for any TS exports (or filepaths if not a TS project)\n *\n * @param projectInfo\n * @returns an array of components in the format `${filepath}~${componentName}\n */\nexport function getFilepathExportsFromFiles(projectInfo: ProjectInfo, cmd: BaseCommand) {\n return projectInfo.files.reduce((options, filepath) => {\n if (projectInfo.config.parser === 'react') {\n const { tsProgram } = projectInfo as ReactProjectInfo\n if (!isFigmaConnectFile(tsProgram, filepath, 'tsx')) {\n const checker = tsProgram.getTypeChecker()\n const sourceFile = tsProgram.getSourceFile(filepath)\n if (!sourceFile) {\n if (cmd.verbose) {\n logger.warn(`Could not parse file for TypeScript: ${filepath}`)\n }\n } else {\n try {\n const sourceFileSymbol = checker.getSymbolAtLocation(sourceFile)!\n const exports = checker.getExportsOfModule(sourceFileSymbol)\n\n exports.forEach((exp) => {\n options.push(getFilepathExport(filepath, exp.getName()))\n })\n } catch (e) {\n if (cmd.verbose) {\n logger.warn(`Could not parse exports of file: ${filepath}`)\n }\n // ignore invalid files\n }\n }\n }\n } else {\n options.push(filepath)\n }\n return options\n }, [] as string[])\n}\n\nexport function isValidFigmaUrl(url: string) {\n try {\n const { hostname } = new URL(url)\n if (\n !hostname.includes('figma.com')\n ) {\n return false\n }\n\n return !!parseFileKey(url)\n } catch (e) {\n return false\n }\n}\n"]}
|
package/figma-types.d.ts
CHANGED
|
@@ -103,7 +103,7 @@ declare module 'figma' {
|
|
|
103
103
|
propName: string,
|
|
104
104
|
options: O,
|
|
105
105
|
): EnumOptionsValues<O> | undefined
|
|
106
|
-
getInstanceSwap(propName: string): InstanceHandle | undefined
|
|
106
|
+
getInstanceSwap(propName: string): InstanceHandle | ErrorHandle | undefined
|
|
107
107
|
getSlot(propName: string): ResultSection[] | undefined
|
|
108
108
|
hasCodeConnect(): boolean
|
|
109
109
|
getPropertyValue(name: string): string | boolean | ErrorHandle
|