@figma/code-connect 1.4.0 → 1.4.2

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.
@@ -1,5 +1,5 @@
1
1
  import * as commander from 'commander';
2
- import { CodeConnectConfig, ProjectInfo } from '../connect/project';
2
+ import { ProjectInfo } from '../connect/project';
3
3
  import { CodeConnectJSON } from '../connect/figma_connect';
4
4
  export type BaseCommand = commander.Command & {
5
5
  token: string;
@@ -18,7 +18,6 @@ export type BaseCommand = commander.Command & {
18
18
  export declare function addConnectCommandToProgram(program: commander.Command): void;
19
19
  export declare function getAccessToken(cmd: BaseCommand): string;
20
20
  export declare function getDir(cmd: BaseCommand): string;
21
- export declare function parseRawFile(filePath: string, label: string | undefined, config?: CodeConnectConfig, dir?: string): CodeConnectJSON;
22
21
  export declare function getCodeConnectObjects(cmd: BaseCommand & {
23
22
  label?: string;
24
23
  }, projectInfo: ProjectInfo, silent?: boolean, skipTemplateHelpers?: boolean): Promise<CodeConnectJSON[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AAKtC,OAAO,EACL,iBAAiB,EAIjB,WAAW,EAKZ,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AA0B1D,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,GAAG;IAC5C,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,EAAE,OAAO,CAAA;IACxB,qBAAqB,EAAE,OAAO,CAAA;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AA0BD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,QAiEpE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,UAE9C;AAcD,wBAAgB,MAAM,CAAC,GAAG,EAAE,WAAW,UAEtC;AA0CD,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,CAAC,EAAE,iBAAiB,EAC1B,GAAG,CAAC,EAAE,MAAM,GACX,eAAe,CAoEjB;AAED,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,WAAW,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EACrC,WAAW,EAAE,WAAW,EACxB,MAAM,UAAQ,EACd,mBAAmB,UAAQ,GAC1B,OAAO,CAAC,eAAe,EAAE,CAAC,CAkH5B"}
1
+ {"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,WAAW,CAAA;AAKtC,OAAO,EAKL,WAAW,EAKZ,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AA+B1D,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,GAAG;IAC5C,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,EAAE,OAAO,CAAA;IACxB,qBAAqB,EAAE,OAAO,CAAA;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AA0BD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,QA6EpE;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,UAE9C;AAcD,wBAAgB,MAAM,CAAC,GAAG,EAAE,WAAW,UAEtC;AAwCD,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,WAAW,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EACrC,WAAW,EAAE,WAAW,EACxB,MAAM,UAAQ,EACd,mBAAmB,UAAQ,GAC1B,OAAO,CAAC,eAAe,EAAE,CAAC,CA6H5B"}
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.addConnectCommandToProgram = addConnectCommandToProgram;
7
7
  exports.getAccessToken = getAccessToken;
8
8
  exports.getDir = getDir;
9
- exports.parseRawFile = parseRawFile;
10
9
  exports.getCodeConnectObjects = getCodeConnectObjects;
11
10
  const fs_1 = __importDefault(require("fs"));
12
11
  const upload_1 = require("../connect/upload");
@@ -28,6 +27,7 @@ const parser_common_1 = require("../connect/parser_common");
28
27
  const parser_2 = require("../react/parser");
29
28
  const label_language_mapping_1 = require("../connect/label_language_mapping");
30
29
  const migration_helpers_1 = require("../connect/migration_helpers");
30
+ const raw_templates_1 = require("../connect/raw_templates");
31
31
  const run_wizard_2 = require("../connect/wizard/run_wizard");
32
32
  const project_2 = require("../connect/project");
33
33
  function addBaseCommand(command, name, description) {
@@ -57,6 +57,7 @@ function addConnectCommandToProgram(program) {
57
57
  .option('--skip-validation', 'skip validation of Code Connect docs')
58
58
  .option('-l --label <label>', 'label to apply to the published files')
59
59
  .option('-b --batch-size <batch_size>', 'optional batch size (in number of documents) to use when uploading. Use this if you hit "request too large" errors. See README for more information.')
60
+ .option('--include-template-files', '(Deprecated) No longer needed - template files are included by default. Will be removed in a future version.')
60
61
  .action((0, updates_1.withUpdateCheck)(handlePublish));
61
62
  addBaseCommand(connectCommand, 'unpublish', 'Run to find any files that have figma connections and unpublish them from Figma. ' +
62
63
  'By default this looks for a config file named "figma.config.json", and uses the `include` and `exclude` fields to determine which files to parse. ' +
@@ -66,6 +67,7 @@ function addConnectCommandToProgram(program) {
66
67
  .action((0, updates_1.withUpdateCheck)(handleUnpublish));
67
68
  addBaseCommand(connectCommand, 'parse', 'Run Code Connect locally to find any files that have figma connections, then converts them to JSON and outputs to stdout.')
68
69
  .option('-l --label <label>', 'label to apply to the parsed files')
70
+ .option('--include-template-files', '(Deprecated) No longer needed - template files are included by default. Will be removed in a future version.')
69
71
  .action((0, updates_1.withUpdateCheck)(handleParse));
70
72
  addBaseCommand(connectCommand, 'create', 'Generate a Code Connect file with boilerplate in the current directory for a Figma node URL')
71
73
  .argument('<figma-node-url>', 'Figma node URL to create the Code Connect file from')
@@ -75,6 +77,7 @@ function addConnectCommandToProgram(program) {
75
77
  .option('-l --label <label>', 'label to apply to the migrated templates')
76
78
  .option('--output-dir <dir>', 'directory to write template files (default: same directory as source file)')
77
79
  .option('--remove-props', 'remove __props metadata blocks from migrated templates')
80
+ .option('--typescript', 'output migrated templates as TypeScript (.figma.ts) instead of JavaScript (.figma.js)')
78
81
  .action((0, updates_1.withUpdateCheck)(handleMigrate));
79
82
  }
80
83
  function getAccessToken(cmd) {
@@ -105,15 +108,13 @@ function transformDocFromParser(doc, remoteUrl, config) {
105
108
  }
106
109
  }
107
110
  catch (e) {
108
- source = (0, project_1.getRemoteFileUrl)(source, remoteUrl);
111
+ source = (0, project_1.getRemoteFileUrl)(source, remoteUrl, config.defaultBranch);
109
112
  }
110
113
  }
111
114
  // TODO This logic is duplicated in parser.ts parseDoc due to some type issues
112
115
  let figmaNode = doc.figmaNode;
113
116
  if (config.documentUrlSubstitutions) {
114
- Object.entries(config.documentUrlSubstitutions).forEach(([from, to]) => {
115
- figmaNode = figmaNode.replace(from, to);
116
- });
117
+ figmaNode = (0, helpers_1.applyDocumentUrlSubstitutions)(figmaNode, config.documentUrlSubstitutions);
117
118
  }
118
119
  return {
119
120
  ...doc,
@@ -121,66 +122,6 @@ function transformDocFromParser(doc, remoteUrl, config) {
121
122
  figmaNode,
122
123
  };
123
124
  }
124
- function parseRawFile(filePath, label, config, dir) {
125
- const fileContent = fs_1.default.readFileSync(filePath, 'utf-8');
126
- const lines = fileContent.split('\n');
127
- const fields = {};
128
- let templateStartIndex = 0;
129
- // Parse consecutive comment lines at the start of the file
130
- for (let i = 0; i < lines.length; i++) {
131
- const line = lines[i].trim();
132
- // Match pattern: // fieldName=value
133
- const match = line.match(/^\/\/\s*(\w+)=(.+)$/);
134
- if (match) {
135
- const [, fieldName, fieldValue] = match;
136
- const normalizedFieldName = fieldName.toLowerCase();
137
- if (normalizedFieldName === 'url' ||
138
- normalizedFieldName === 'component' ||
139
- normalizedFieldName === 'source') {
140
- fields[normalizedFieldName] = fieldValue.trim();
141
- }
142
- templateStartIndex = i + 1;
143
- }
144
- else if (line === '' || line.startsWith('//')) {
145
- // Allow blank lines or other comments, but don't increment template start
146
- continue;
147
- }
148
- else {
149
- // First non-comment line found
150
- break;
151
- }
152
- }
153
- if (!fields.url) {
154
- throw new Error(`Missing required url field in ${filePath}. Please add a // url=... comment to the top of the file.`);
155
- }
156
- let figmaNodeUrl = fields.url;
157
- const template = lines.slice(templateStartIndex).join('\n');
158
- // Apply documentUrlSubstitutions if provided
159
- if (config?.documentUrlSubstitutions) {
160
- Object.entries(config.documentUrlSubstitutions).forEach(([from, to]) => {
161
- figmaNodeUrl = figmaNodeUrl.replace(from, to);
162
- });
163
- }
164
- // Determine effective label from parameter, config, or default
165
- const effectiveLabel = label || config?.label || label_language_mapping_1.CodeConnectLabel.Code;
166
- const language = config?.language || (0, label_language_mapping_1.getInferredLanguageForRaw)(effectiveLabel);
167
- return {
168
- figmaNode: figmaNodeUrl,
169
- component: fields.component,
170
- template,
171
- // nestable by default unless user specifies in template
172
- // (templateData.nestable AND template.metadata.nestable need to
173
- // be true for instance to be nested)
174
- templateData: { nestable: true, isParserless: true },
175
- language,
176
- label: effectiveLabel,
177
- source: fields.source,
178
- sourceLocation: { line: -1 },
179
- metadata: {
180
- cliVersion: require('../../package.json').version,
181
- },
182
- };
183
- }
184
125
  async function getCodeConnectObjects(cmd, projectInfo, silent = false, skipTemplateHelpers = false) {
185
126
  if (cmd.jsonFile) {
186
127
  try {
@@ -244,12 +185,26 @@ async function getCodeConnectObjects(cmd, projectInfo, silent = false, skipTempl
244
185
  }
245
186
  }
246
187
  }
247
- const rawTemplateFiles = projectInfo.files.filter((f) => f.endsWith('.figma.js') || f.endsWith('.figma.template.js'));
188
+ const rawTemplateFiles = projectInfo.files.filter((f) => {
189
+ // Suffix may be used by HTML / custom parsers
190
+ const isPotentialRawTemplate = f.endsWith('.figma.js') ||
191
+ f.endsWith('.figma.template.js') ||
192
+ f.endsWith('.figma.ts') ||
193
+ f.endsWith('.figma.template.ts');
194
+ if (!isPotentialRawTemplate)
195
+ return false;
196
+ try {
197
+ return (0, raw_templates_1.isRawTemplate)(fs_1.default.readFileSync(f, 'utf-8'));
198
+ }
199
+ catch {
200
+ return false;
201
+ }
202
+ });
248
203
  if (rawTemplateFiles.length > 0) {
249
204
  // Resolve the label before parsing so language inference works correctly
250
205
  const resolvedLabel = cmd.label || projectInfo.config.label;
251
206
  const rawTemplateDocs = rawTemplateFiles.map((file) => {
252
- const doc = parseRawFile(file, resolvedLabel, projectInfo.config, projectInfo.absPath);
207
+ const doc = (0, raw_templates_1.parseRawFile)(file, resolvedLabel, projectInfo.config, projectInfo.absPath);
253
208
  // Store the Code Connect file path for migration purposes
254
209
  doc._codeConnectFilePath = file;
255
210
  if (!silent || cmd.verbose) {
@@ -361,6 +316,11 @@ async function getReactCodeConnectObjects(projectInfo, cmd, silent = false, skip
361
316
  }
362
317
  async function handlePublish(cmd) {
363
318
  setupHandler(cmd);
319
+ // Show deprecation warning if the flag is used
320
+ if (cmd.includeTemplateFiles !== undefined) {
321
+ logging_1.logger.warn('[Deprecated] The --include-template-files flag is no longer needed because template files are now included by default. ' +
322
+ "Please don't use this flag - it will be removed in a future version.");
323
+ }
364
324
  let dir = getDir(cmd);
365
325
  const projectInfo = await (0, project_1.getProjectInfo)(dir, cmd.config);
366
326
  const codeConnectObjects = await getCodeConnectObjects(cmd, projectInfo);
@@ -446,6 +406,11 @@ async function handleUnpublish(cmd) {
446
406
  }
447
407
  async function handleParse(cmd) {
448
408
  setupHandler(cmd);
409
+ // Show deprecation warning if the flag is used
410
+ if (cmd.includeTemplateFiles !== undefined) {
411
+ logging_1.logger.warn('[Deprecated] The --include-template-files flag is no longer needed because template files are now included by default. ' +
412
+ "Please don't use this flag - it will be removed in a future version.");
413
+ }
449
414
  const dir = cmd.dir ?? process.cwd();
450
415
  const projectInfo = await (0, project_1.getProjectInfo)(dir, cmd.config);
451
416
  const codeConnectObjects = await getCodeConnectObjects(cmd, projectInfo);
@@ -522,59 +487,57 @@ async function handleMigrate(pattern, cmd) {
522
487
  // Parse the files to get Code Connect objects
523
488
  const allCodeConnectObjects = await getCodeConnectObjects(cmd, projectInfo, false, true);
524
489
  const codeConnectObjectsByFigmaUrl = (0, migration_helpers_1.groupCodeConnectObjectsByFigmaUrl)(allCodeConnectObjects);
525
- const totalVariants = Object.values(codeConnectObjectsByFigmaUrl).reduce((acc, obj) => acc + obj.variants.length, 0);
526
- // TODO support variants (for now filtering on non-variants)
527
- const codeConnectObjects = Object.values(codeConnectObjectsByFigmaUrl).flatMap((obj) => obj.main ? [obj.main] : []);
528
- if (codeConnectObjects.length === 0) {
490
+ const groupCount = Object.keys(codeConnectObjectsByFigmaUrl).length;
491
+ if (groupCount === 0) {
529
492
  (0, logging_1.exitWithError)('No Code Connect objects found to migrate');
530
493
  }
531
- logging_1.logger.info(`Found ${codeConnectObjects.length} Code Connect object(s) to migrate`);
494
+ logging_1.logger.info(`Found ${groupCount} component(s) to migrate`);
532
495
  let migratedCount = 0;
533
496
  let skippedCount = 0;
534
497
  const errors = [];
535
- // Track file paths created during this migration run
536
498
  const filePathsCreated = new Set();
537
- // Get git root path for converting remote URLs to local paths
538
499
  const gitRootPath = (0, project_2.getGitRepoAbsolutePath)(dir);
539
- // Migrate each Code Connect object to a template file
540
- for (const doc of codeConnectObjects) {
500
+ const useTypeScript = !!cmd.typescript;
501
+ for (const [figmaUrl, group] of Object.entries(codeConnectObjectsByFigmaUrl)) {
541
502
  try {
542
- // Skip if no template (shouldn't happen, but be safe)
543
- if (!doc.template) {
544
- logging_1.logger.warn(`Skipping ${doc.figmaNode}: no template found`);
503
+ const hasVariants = group.variants.length > 0;
504
+ const representativeDoc = group.main ?? group.variants[0];
505
+ if (!representativeDoc?.template) {
506
+ logging_1.logger.warn(`Skipping ${figmaUrl}: no template found`);
545
507
  skippedCount++;
546
508
  continue;
547
509
  }
548
510
  // Determine local source path for output location
549
511
  let localSourcePath;
550
- if (doc._codeConnectFilePath) {
512
+ if (representativeDoc._codeConnectFilePath) {
551
513
  // Use the Code Connect file path directly (preferred)
552
- localSourcePath = doc._codeConnectFilePath;
514
+ localSourcePath = representativeDoc._codeConnectFilePath;
553
515
  }
554
- else if (doc.source && gitRootPath) {
516
+ else if (representativeDoc?.source && gitRootPath) {
555
517
  // Fallback: Convert remote file URL to local path
556
518
  const relativePath = (0, run_wizard_2.convertRemoteFileUrlToRelativePath)({
557
- remoteFileUrl: doc.source,
519
+ remoteFileUrl: representativeDoc.source,
558
520
  gitRootPath,
559
521
  dir,
560
522
  });
561
523
  if (relativePath) {
562
- // Convert relative path to absolute path for writeTemplateFile
563
524
  localSourcePath = path_1.default.resolve(dir, relativePath);
564
525
  }
565
526
  }
566
- const { outputPath, skipped } = (0, migration_helpers_1.writeTemplateFile)(doc, cmd.outDir, dir, localSourcePath, filePathsCreated, cmd.removeProps);
527
+ const { outputPath, skipped } = hasVariants
528
+ ? (0, migration_helpers_1.writeVariantTemplateFile)(group, figmaUrl, cmd.outDir, dir, localSourcePath, filePathsCreated, useTypeScript)
529
+ : (0, migration_helpers_1.writeTemplateFile)(representativeDoc, cmd.outDir, dir, localSourcePath, filePathsCreated, cmd.removeProps, useTypeScript);
567
530
  if (skipped) {
568
531
  logging_1.logger.warn(`Skipping ${outputPath}: file already exists`);
569
532
  skippedCount++;
570
533
  }
571
534
  else {
572
- logging_1.logger.info(`${(0, logging_1.success)('✓')} Migrated to ${(0, logging_1.highlight)(outputPath)}`);
535
+ logging_1.logger.info(`${(0, logging_1.success)('✓')} Migrated${hasVariants ? ' (with variants)' : ''} to ${(0, logging_1.highlight)(outputPath)}`);
573
536
  migratedCount++;
574
537
  }
575
538
  }
576
539
  catch (error) {
577
- const errorMsg = `Failed to migrate ${doc.figmaNode}: ${error}`;
540
+ const errorMsg = `Failed to migrate ${figmaUrl}: ${error}`;
578
541
  logging_1.logger.error(errorMsg);
579
542
  errors.push(errorMsg);
580
543
  }
@@ -586,10 +549,10 @@ async function handleMigrate(pattern, cmd) {
586
549
  logging_1.logger.warn(`Config file already exists at ${(0, logging_1.highlight)(configFilePath)}`);
587
550
  }
588
551
  else {
589
- const { language: docLanguage, label } = codeConnectObjects[0];
552
+ const { language: docLanguage, label } = allCodeConnectObjects[0];
590
553
  const language = (0, label_language_mapping_1.getInferredLanguageForRaw)(label, docLanguage);
591
554
  const config = {
592
- include: ['**/*.figma.js'],
555
+ include: [useTypeScript ? '**/*.figma.ts' : '**/*.figma.js'],
593
556
  language,
594
557
  label,
595
558
  ...(documentUrlSubstitutions && Object.keys(documentUrlSubstitutions).length > 0
@@ -604,9 +567,6 @@ async function handleMigrate(pattern, cmd) {
604
567
  // Summary
605
568
  console.log('');
606
569
  logging_1.logger.info(`Migration complete: ${(0, logging_1.success)(`${migratedCount} migrated`)}, ${skippedCount} skipped`);
607
- if (totalVariants > 0) {
608
- logging_1.logger.error(`${(0, logging_1.error)(`${totalVariants} variant restriction(s)`)} found, but not supported by the migration script yet`);
609
- }
610
570
  if (errors.length > 0) {
611
571
  console.log('');
612
572
  logging_1.logger.error(`Encountered ${errors.length} error(s):`);
@@ -1 +1 @@
1
- {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":";;;;;AAkFA,gEAiEC;AAED,wCAEC;AAcD,wBAEC;AA0CD,oCAyEC;AAED,sDAuHC;AAlZD,4CAAmB;AACnB,8CAA0C;AAC1C,sDAAoD;AACpD,8CAA4D;AAC5D,gDAU2B;AAC3B,+CAA8F;AAE9F,kDAA4D;AAC5D,wDAAoD;AACpD,6DAAwD;AACxD,sEAA0E;AAC1E,+DAAgD;AAChD,gFAA8F;AAE9F,gDAAuB;AACvB,+CAAmD;AACnD,gDAA4D;AAC5D,2CAA6C;AAC7C,4DAOiC;AACjC,4CAAsE;AACtE,8EAA+F;AAC/F,oEAAmG;AACnG,6DAAiF;AACjF,gDAA2D;AAiB3D,SAAS,cAAc,CAAC,OAA0B,EAAE,IAAY,EAAE,WAAmB;IACnF,OAAO,OAAO;SACX,OAAO,CAAC,IAAI,CAAC;SACb,WAAW,CAAC,WAAW,CAAC;SACxB,KAAK,CAAC,WAAW,CAAC;SAClB,MAAM,CAAC,gBAAgB,EAAE,oBAAoB,CAAC;SAC9C,MAAM,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;SAClD,MAAM,CAAC,cAAc,EAAE,sCAAsC,CAAC;SAC9D,MAAM,CAAC,qBAAqB,EAAE,iDAAiD,CAAC;SAChF,MAAM,CAAC,mBAAmB,EAAE,sDAAsD,CAAC;SACnF,MAAM,CAAC,oBAAoB,EAAE,6BAA6B,CAAC;SAC3D,MAAM,CAAC,oBAAoB,EAAE,iEAAiE,CAAC;SAC/F,MAAM,CAAC,qBAAqB,EAAE,wDAAwD,CAAC;SACvF,MAAM,CACL,4BAA4B,EAC5B,4FAA4F,CAC7F;SACA,MAAM,CAAC,WAAW,EAAE,8CAA8C,CAAC;SACnE,WAAW,CACV,QAAQ,EACR,2FAA2F,CAC5F,CAAA;AACL,CAAC;AAED,SAAgB,0BAA0B,CAAC,OAA0B;IACnE,6CAA6C;IAC7C,MAAM,cAAc,GAAG,cAAc,CAAC,OAAO,EAAE,SAAS,EAAE,oBAAoB,CAAC,CAAC,MAAM,CACpF,IAAA,yBAAe,EAAC,sBAAS,CAAC,CAC3B,CAAA;IAED,0DAA0D;IAC1D,cAAc,CACZ,cAAc,EACd,SAAS,EACT,oGAAoG;QAClG,oJAAoJ;QACpJ,sIAAsI,CACzI;SACE,MAAM,CAAC,mBAAmB,EAAE,sCAAsC,CAAC;SACnE,MAAM,CAAC,oBAAoB,EAAE,uCAAuC,CAAC;SACrE,MAAM,CACL,8BAA8B,EAC9B,sJAAsJ,CACvJ;SACA,MAAM,CAAC,IAAA,yBAAe,EAAC,aAAa,CAAC,CAAC,CAAA;IAEzC,cAAc,CACZ,cAAc,EACd,WAAW,EACX,mFAAmF;QACjF,oJAAoJ;QACpJ,sIAAsI,CACzI;SACE,MAAM,CACL,uBAAuB,EACvB,6EAA6E,CAC9E;SACA,MAAM,CAAC,oBAAoB,EAAE,wBAAwB,CAAC;SACtD,MAAM,CAAC,IAAA,yBAAe,EAAC,eAAe,CAAC,CAAC,CAAA;IAE3C,cAAc,CACZ,cAAc,EACd,OAAO,EACP,2HAA2H,CAC5H;SACE,MAAM,CAAC,oBAAoB,EAAE,oCAAoC,CAAC;SAClE,MAAM,CAAC,IAAA,yBAAe,EAAC,WAAW,CAAC,CAAC,CAAA;IAEvC,cAAc,CACZ,cAAc,EACd,QAAQ,EACR,6FAA6F,CAC9F;SACE,QAAQ,CAAC,kBAAkB,EAAE,qDAAqD,CAAC;SACnF,MAAM,CAAC,IAAA,yBAAe,EAAC,YAAY,CAAC,CAAC,CAAA;IAExC,cAAc,CACZ,cAAc,EACd,SAAS,EACT,2HAA2H,CAC5H;SACE,QAAQ,CAAC,WAAW,EAAE,qEAAqE,CAAC;SAC5F,MAAM,CAAC,oBAAoB,EAAE,0CAA0C,CAAC;SACxE,MAAM,CACL,oBAAoB,EACpB,4EAA4E,CAC7E;SACA,MAAM,CAAC,gBAAgB,EAAE,wDAAwD,CAAC;SAClF,MAAM,CAAC,IAAA,yBAAe,EAAC,aAAa,CAAC,CAAC,CAAA;AAC3C,CAAC;AAED,SAAgB,cAAc,CAAC,GAAgB;IAC7C,OAAO,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAA;AACpD,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAgB;IAC5C,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAA;IAEjC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAA,uBAAa,EACX,2IAA2I,CAC5I,CAAA;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAgB,MAAM,CAAC,GAAgB;IACrC,OAAO,GAAG,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;AACjC,CAAC;AAED,SAAS,YAAY,CAAC,GAAgB;IACpC,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,gBAAM,CAAC,WAAW,CAAC,kBAAQ,CAAC,KAAK,CAAC,CAAA;IACpC,CAAC;AACH,CAAC;AAID,SAAS,sBAAsB,CAC7B,GAAc,EACd,SAAiB,EACjB,MAAyB;IAEzB,IAAI,MAAM,GAAG,GAAG,CAAC,MAAM,CAAA;IACvB,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAA;YAC3B,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC1D,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAA;YACvC,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,GAAG,IAAA,0BAAgB,EAAC,MAAM,EAAE,SAAS,CAAC,CAAA;QAC9C,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,IAAI,SAAS,GAAG,GAAG,CAAC,SAAS,CAAA;IAC7B,IAAI,MAAM,CAAC,wBAAwB,EAAE,CAAC;QACpC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;YACrE,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QACzC,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO;QACL,GAAG,GAAG;QACN,MAAM;QACN,SAAS;KACV,CAAA;AACH,CAAC;AAED,SAAgB,YAAY,CAC1B,QAAgB,EAChB,KAAyB,EACzB,MAA0B,EAC1B,GAAY;IAEZ,MAAM,WAAW,GAAG,YAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IACtD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACrC,MAAM,MAAM,GAA0D,EAAE,CAAA;IACxE,IAAI,kBAAkB,GAAG,CAAC,CAAA;IAE1B,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,kBAAkB,GAAG,CAAC,GAAG,CAAC,CAAA;QAC5B,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,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,iCAAiC,QAAQ,2DAA2D,CACrG,CAAA;IACH,CAAC;IACD,IAAI,YAAY,GAAG,MAAM,CAAC,GAAG,CAAA;IAE7B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAE3D,6CAA6C;IAC7C,IAAI,MAAM,EAAE,wBAAwB,EAAE,CAAC;QACrC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;YACrE,YAAY,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;QAC/C,CAAC,CAAC,CAAA;IACJ,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,EAAE,MAAM,CAAC,SAAS;QAC3B,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,EAAE,MAAM,CAAC,MAAM;QACrB,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;AAEM,KAAK,UAAU,qBAAqB,CACzC,GAAqC,EACrC,WAAwB,EACxB,MAAM,GAAG,KAAK,EACd,mBAAmB,GAAG,KAAK;IAE3B,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjB,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,YAAE,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAA;YACtE,wCAAwC;YACxC,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,GAAoB,EAAE,EAAE;gBAC/C,MAAM,EAAE,oBAAoB,EAAE,GAAG,QAAQ,EAAE,GAAG,GAAG,CAAA;gBACjD,OAAO,QAA2B,CAAA;YACpC,CAAC,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,gBAAM,CAAC,KAAK,CAAC,4BAA4B,EAAE,CAAC,CAAC,CAAA;QAC/C,CAAC;IACH,CAAC;IAED,IAAI,kBAAkB,GAAsB,EAAE,CAAA;IAE9C,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;QAC1C,kBAAkB,GAAG,MAAM,0BAA0B,CACnD,WAAkD,EAClD,GAAG,EACH,MAAM,EACN,mBAAmB,CACpB,CAAA;IACH,CAAC;SAAM,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAChD,kBAAkB,GAAG,MAAM,gCAAgC,CAAC;YAC1D,OAAO,EAAE,qBAAY;YACrB,aAAa,EAAE,IAAI;YACnB,WAAW;YACX,GAAG;YACH,MAAM;YACN,mBAAmB;SACpB,CAAC,CAAA;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,GAAwB;YACnC,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,WAAW,CAAC,KAAK;YACxB,MAAM,EAAE,EAAE,GAAG,WAAW,CAAC,MAAM,EAAE,mBAAmB,EAAE;YACtD,OAAO,EAAE,GAAG,CAAC,OAAO;SACrB,CAAA;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAA,+BAAU;YAC7B,iEAAiE;YACjE,iDAAiD;YACjD,WAAW,CAAC,MAA2C,EACvD,OAAO,EACP,WAAW,CAAC,OAAO,CACpB,CAAA;YAED,MAAM,MAAM,GAAG,8CAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;YAEjD,MAAM,EAAE,SAAS,EAAE,GAAG,IAAA,mCAAc,EAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;YAErD,IAAI,SAAS,EAAE,CAAC;gBACd,IAAA,uBAAa,EAAC,4CAA4C,CAAC,CAAA;YAC7D,CAAC;YAED,kBAAkB,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAC7C,GAAG,sBAAsB,CAAC,GAAG,EAAE,WAAW,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC;gBACzE,QAAQ,EAAE;oBACR,UAAU,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC,OAAO;iBAClD;aACF,CAAC,CAAC,CAAA;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAChB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;gBAEhB,kEAAkE;gBAClE,IAAA,uBAAa,EAAC,yBAAyB,CAAC,GAAG,CAAC,CAAA;YAC9C,CAAC;iBAAM,CAAC;gBACN,IAAA,uBAAa,EACX,+BAA+B,IAAA,gCAAS,EAAC,CAAC,CAAC,mEAAmE,CAC/G,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,gBAAgB,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAC/C,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAC3E,CAAA;IAED,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,yEAAyE;QACzE,MAAM,aAAa,GAAG,GAAG,CAAC,KAAK,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,CAAA;QAE3D,MAAM,eAAe,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACpD,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,aAAa,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;YACtF,0DAA0D;YAC1D,GAAG,CAAC,oBAAoB,GAAG,IAAI,CAAA;YAE/B,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAC3B,gBAAM,CAAC,IAAI,CAAC,IAAA,iBAAO,EAAC,IAAI,CAAC,CAAC,CAAA;YAC5B,CAAC;YACD,OAAO,GAAG,CAAA;QACZ,CAAC,CAAC,CAAA;QAEF,kBAAkB,GAAG,kBAAkB,CAAC,MAAM,CAAC,eAAe,CAAC,CAAA;IACjE,CAAC;IAED,IAAI,GAAG,CAAC,KAAK,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC1C,gBAAM,CAAC,IAAI,CAAC,gBAAgB,GAAG,CAAC,KAAK,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAA;QACrE,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACjC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,CAAA;QAChE,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,WAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,gBAAM,CAAC,IAAI,CAAC,mBAAmB,WAAW,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAA;QAC9D,kBAAkB,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;YACjC,GAAG,CAAC,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAA;QAC5D,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,kBAAkB,CAAA;AAC3B,CAAC;AAYD,8EAA8E;AAC9E,8EAA8E;AAC9E,4EAA4E;AAC5E,KAAK,UAAU,gCAAgC,CAAC;AAC9C,0EAA0E;AAC1E,OAAO;AACP,iEAAiE;AACjE,gBAAgB;AAChB,+EAA+E;AAC/E,aAAa;AACb,mBAAmB;AACnB,WAAW;AACX,mCAAmC;AACnC,GAAG;AACH,8BAA8B;AAC9B,MAAM,GAAG,KAAK;AACd,uDAAuD;AACvD,mBAAmB,GAAG,KAAK,GACD;IAC1B,MAAM,kBAAkB,GAAsB,EAAE,CAAA;IAEhD,MAAM,SAAS,GAAG,IAAA,sBAAY,EAAC,WAAW,CAAC,CAAA;IAC3C,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAAA;IAEzD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,IAAA,kCAAkB,EAAC,SAAS,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC;QAChG,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAA,gCAAgB,EAAC;gBAClC,OAAO,EAAE,SAAS;gBAClB,IAAI;gBACJ,MAAM;gBACN,OAAO;gBACP,gBAAgB;gBAChB,OAAO;gBACP,YAAY,EAAE;oBACZ,OAAO,EAAE,SAAS;oBAClB,KAAK,EAAE,GAAG,CAAC,OAAO;oBAClB,MAAM;oBACN,mBAAmB;iBACpB;aACF,CAAC,CAAA;YAEF,kBAAkB,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;YAChC,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAC3B,gBAAM,CAAC,IAAI,CAAC,IAAA,iBAAO,EAAC,IAAI,CAAC,CAAC,CAAA;YAC5B,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAC3B,gBAAM,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;gBACzB,IAAI,CAAC,YAAY,2BAAW,EAAE,CAAC;oBAC7B,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;wBAChB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;oBAClB,CAAC;yBAAM,CAAC;wBACN,gBAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;oBAC5B,CAAC;oBACD,IAAI,GAAG,CAAC,qBAAqB,EAAE,CAAC;wBAC9B,gBAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAA;wBAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;oBACjB,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;wBAChB,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;oBAClB,CAAC;yBAAM,CAAC;wBACN,gBAAM,CAAC,KAAK,CAAC,IAAI,6BAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;oBACvD,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,kBAAkB,CAAA;AAC3B,CAAC;AAED,KAAK,UAAU,0BAA0B,CACvC,WAAgD,EAChD,GAAgB,EAChB,MAAM,GAAG,KAAK,EACd,mBAAmB,GAAG,KAAK;IAE3B,MAAM,kBAAkB,GAAG,MAAM,gCAAgC,CAAC;QAChE,OAAO,EAAE,sBAAa;QACtB,gBAAgB,EAAE,8BAAqB;QACvC,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;QAC7B,WAAW;QACX,GAAG;QACH,MAAM;QACN,mBAAmB;KACpB,CAAC,CAAA;IAEF,MAAM,2BAA2B,GAAG,MAAM,IAAA,+BAAqB,EAAC;QAC9D,WAAW,EAAE,IAAA,6BAAmB,EAAC,WAAW,CAAC;KAC9C,CAAC,CAAA;IAEF,MAAM,qBAAqB,GAAG,kBAAkB,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAA;IAEpF,OAAO,qBAAqB,CAAA;AAC9B,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,GAIC;IAED,YAAY,CAAC,GAAG,CAAC,CAAA;IAEjB,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IACrB,MAAM,WAAW,GAAG,MAAM,IAAA,wBAAc,EAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAEzD,MAAM,kBAAkB,GAAG,MAAM,qBAAqB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;IAExE,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,gBAAM,CAAC,IAAI,CACT,kCAAkC,GAAG,iLAAiL,CACvN,CAAA;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,gBAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAA;QAC7C,gBAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;IAC5F,CAAC;IAED,MAAM,WAAW,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;IAE7C,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;QACvB,gBAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAA;IACnC,CAAC;SAAM,CAAC;QACN,gBAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAA;QAC/C,IAAI,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAA;QAChC,MAAM,KAAK,GAAG,MAAM,IAAA,yBAAY,EAC9B,GAAG,EACH,WAAW,EACX,kBAAkB,EAClB,GAAG,CAAC,MAAM,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,CACxC,CAAA;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAA,iCAAuB,EAAC,CAAC,CAAC,CAAA;QAC5B,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAA;YAC9B,IAAI,IAAI,GAAG,GAAG,GAAG,KAAK,CAAA;YACtB,gBAAM,CAAC,IAAI,CAAC,qCAAqC,IAAI,KAAK,CAAC,CAAA;QAC7D,CAAC;IACH,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,gBAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,SAAS,CAAA;IACb,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;QACvC,IAAI,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;YACrB,gBAAM,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAA;YACrF,IAAA,iCAAuB,EAAC,CAAC,CAAC,CAAA;QAC5B,CAAC;IACH,CAAC;IAED,IAAA,eAAM,EAAC;QACL,WAAW;QACX,IAAI,EAAE,kBAAkB;QACxB,SAAS,EAAE,SAAS;QACpB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM;KAChD,CAAC,CAAA;AACJ,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAkD;IAC/E,YAAY,CAAC,GAAG,CAAC,CAAA;IAEjB,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IAErB,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,gBAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAA;IACjD,CAAC;IAED,IAAI,yBAAyB,CAAA;IAE7B,MAAM,WAAW,GAAG,MAAM,IAAA,wBAAc,EAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAEzD,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YACf,IAAA,uBAAa,EAAC,0CAA0C,CAAC,CAAA;QAC3D,CAAC;QACD,yBAAyB,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAA;IACzE,CAAC;SAAM,CAAC;QACN,MAAM,kBAAkB,GAAG,MAAM,qBAAqB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;QAExE,yBAAyB,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAC3D,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK;SAC1D,CAAC,CAAC,CAAA;QAEH,IAAI,GAAG,CAAC,KAAK,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAC1C,gBAAM,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,KAAK,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;QACrE,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,gBAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;YAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;IAE7C,IAAA,yBAAW,EAAC;QACV,WAAW;QACX,IAAI,EAAE,yBAAyB;QAC/B,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM;KAChD,CAAC,CAAA;AACJ,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,GAAoC;IAC7D,YAAY,CAAC,GAAG,CAAC,CAAA;IAEjB,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IACpC,MAAM,WAAW,GAAG,MAAM,IAAA,wBAAc,EAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAEzD,MAAM,kBAAkB,GAAG,MAAM,qBAAqB,CAAC,GAAG,EAAE,WAAW,CAAC,CAAA;IAExE,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,gBAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;QAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,YAAE,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QAC1E,gBAAM,CAAC,IAAI,CAAC,8BAA8B,IAAA,mBAAS,EAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IACrE,CAAC;SAAM,CAAC;QACN,gEAAgE;QAChE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAA;IAC/D,CAAC;AACH,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,OAAe,EAAE,GAAgB;IAC3D,YAAY,CAAC,GAAG,CAAC,CAAA;IAEjB,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IACpC,MAAM,WAAW,GAAG,MAAM,IAAA,wBAAc,EAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAEzD,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,WAAW,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAA;IAE7C,OAAO,IAAA,iCAAwB,EAAC;QAC9B,WAAW;QACX,yEAAyE;QACzE,2EAA2E;QAC3E,yCAAyC;QACzC,YAAY,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QACxC,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,WAAW;QACX,GAAG;KACJ,CAAC,CAAA;AACJ,CAAC;AACD;;;;;;GAMG;AACH,KAAK,UAAU,aAAa,CAAC,OAA2B,EAAE,GAAgB;IACxE,YAAY,CAAC,GAAG,CAAC,CAAA;IAEjB,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IACpC,IAAI,WAAW,GAAG,MAAM,IAAA,wBAAc,EAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IACvD,MAAM,wBAAwB,GAAG,WAAW,CAAC,MAAM,CAAC,wBAAwB,CAAA;IAE5E,oFAAoF;IACpF,WAAW,GAAG;QACZ,GAAG,WAAW;QACd,MAAM,EAAE;YACN,GAAG,WAAW,CAAC,MAAM;YACrB,wBAAwB,EAAE,EAAE;SAC7B;KACF,CAAA;IAED,4DAA4D;IAC5D,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;QACpC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE;YAC9B,GAAG,EAAE,GAAG;YACR,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,IAAI;SACZ,CAAC,CAAA;QAEF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,IAAA,uBAAa,EAAC,oCAAoC,OAAO,EAAE,CAAC,CAAA;QAC9D,CAAC;QAED,gBAAM,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,MAAM,8BAA8B,OAAO,EAAE,CAAC,CAAA;QACzE,WAAW,GAAG;YACZ,GAAG,WAAW;YACd,KAAK;SACN,CAAA;IACH,CAAC;IAED,8CAA8C;IAC9C,MAAM,qBAAqB,GAAG,MAAM,qBAAqB,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;IAExF,MAAM,4BAA4B,GAAG,IAAA,qDAAiC,EAAC,qBAAqB,CAAC,CAAA;IAE7F,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,MAAM,CACtE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,EACvC,CAAC,CACF,CAAA;IAED,4DAA4D;IAC5D,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC,4BAA4B,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CACrF,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAC3B,CAAA;IAED,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpC,IAAA,uBAAa,EAAC,0CAA0C,CAAC,CAAA;IAC3D,CAAC;IAED,gBAAM,CAAC,IAAI,CAAC,SAAS,kBAAkB,CAAC,MAAM,oCAAoC,CAAC,CAAA;IACnF,IAAI,aAAa,GAAG,CAAC,CAAA;IACrB,IAAI,YAAY,GAAG,CAAC,CAAA;IACpB,MAAM,MAAM,GAAa,EAAE,CAAA;IAE3B,qDAAqD;IACrD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAA;IAE1C,8DAA8D;IAC9D,MAAM,WAAW,GAAG,IAAA,gCAAsB,EAAC,GAAG,CAAC,CAAA;IAE/C,sDAAsD;IACtD,KAAK,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,sDAAsD;YACtD,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;gBAClB,gBAAM,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,SAAS,qBAAqB,CAAC,CAAA;gBAC3D,YAAY,EAAE,CAAA;gBACd,SAAQ;YACV,CAAC;YAED,kDAAkD;YAClD,IAAI,eAAmC,CAAA;YAEvC,IAAI,GAAG,CAAC,oBAAoB,EAAE,CAAC;gBAC7B,sDAAsD;gBACtD,eAAe,GAAG,GAAG,CAAC,oBAAoB,CAAA;YAC5C,CAAC;iBAAM,IAAI,GAAG,CAAC,MAAM,IAAI,WAAW,EAAE,CAAC;gBACrC,kDAAkD;gBAClD,MAAM,YAAY,GAAG,IAAA,+CAAkC,EAAC;oBACtD,aAAa,EAAE,GAAG,CAAC,MAAM;oBACzB,WAAW;oBACX,GAAG;iBACJ,CAAC,CAAA;gBACF,IAAI,YAAY,EAAE,CAAC;oBACjB,+DAA+D;oBAC/D,eAAe,GAAG,cAAI,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAA;gBACnD,CAAC;YACH,CAAC;YAED,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,IAAA,qCAAiB,EAC/C,GAAG,EACH,GAAG,CAAC,MAAM,EACV,GAAG,EACH,eAAe,EACf,gBAAgB,EAChB,GAAG,CAAC,WAAW,CAChB,CAAA;YAED,IAAI,OAAO,EAAE,CAAC;gBACZ,gBAAM,CAAC,IAAI,CAAC,YAAY,UAAU,uBAAuB,CAAC,CAAA;gBAC1D,YAAY,EAAE,CAAA;YAChB,CAAC;iBAAM,CAAC;gBACN,gBAAM,CAAC,IAAI,CAAC,GAAG,IAAA,iBAAO,EAAC,GAAG,CAAC,gBAAgB,IAAA,mBAAS,EAAC,UAAU,CAAC,EAAE,CAAC,CAAA;gBACnE,aAAa,EAAE,CAAA;YACjB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,QAAQ,GAAG,qBAAqB,GAAG,CAAC,SAAS,KAAK,KAAK,EAAE,CAAA;YAC/D,gBAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;YACtB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACvB,CAAC;IACH,CAAC;IAED,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;QACtB,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,MAAM,cAAc,GAAG,cAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;YACjE,IAAI,YAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;gBAClC,gBAAM,CAAC,IAAI,CAAC,iCAAiC,IAAA,mBAAS,EAAC,cAAc,CAAC,EAAE,CAAC,CAAA;YAC3E,CAAC;iBAAM,CAAC;gBACN,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAA;gBAE9D,MAAM,QAAQ,GAAG,IAAA,kDAAyB,EAAC,KAAK,EAAE,WAAW,CAAC,CAAA;gBAC9D,MAAM,MAAM,GAAgC;oBAC1C,OAAO,EAAE,CAAC,eAAe,CAAC;oBAC1B,QAAQ;oBACR,KAAK;oBACL,GAAG,CAAC,wBAAwB,IAAI,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,MAAM,GAAG,CAAC;wBAC9E,CAAC,CAAC,EAAE,wBAAwB,EAAE;wBAC9B,CAAC,CAAC,EAAE,CAAC;iBACR,CAAA;gBACD,YAAE,CAAC,aAAa,CAAC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;gBAClF,gBAAM,CAAC,IAAI,CAAC,GAAG,IAAA,iBAAO,EAAC,GAAG,CAAC,0BAA0B,IAAA,mBAAS,EAAC,cAAc,CAAC,EAAE,CAAC,CAAA;YACnF,CAAC;QACH,CAAC;IACH,CAAC;IAED,UAAU;IACV,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,gBAAM,CAAC,IAAI,CACT,uBAAuB,IAAA,iBAAO,EAAC,GAAG,aAAa,WAAW,CAAC,KAAK,YAAY,UAAU,CACvF,CAAA;IAED,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;QACtB,gBAAM,CAAC,KAAK,CACV,GAAG,IAAA,eAAK,EAAC,GAAG,aAAa,yBAAyB,CAAC,uDAAuD,CAC3G,CAAA;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACf,gBAAM,CAAC,KAAK,CAAC,eAAe,MAAM,CAAC,MAAM,YAAY,CAAC,CAAA;QACtD,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAM,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAA;QACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;QACxB,IAAA,uBAAa,EAAC,wBAAwB,CAAC,CAAA;IACzC,CAAC;AACH,CAAC","sourcesContent":["import * as commander from 'commander'\nimport fs from 'fs'\nimport { upload } from '../connect/upload'\nimport { validateDocs } from '../connect/validation'\nimport { createCodeConnectFromUrl } from '../connect/create'\nimport {\n CodeConnectConfig,\n CodeConnectExecutableParserConfig,\n CodeConnectParserlessConfig,\n CodeConnectReactConfig,\n ProjectInfo,\n getProjectInfo,\n getReactProjectInfo,\n getRemoteFileUrl,\n getTsProgram,\n} from '../connect/project'\nimport { LogLevel, error, exitWithError, highlight, logger, success } from '../common/logging'\nimport { CodeConnectJSON } from '../connect/figma_connect'\nimport { convertStorybookFiles } from '../storybook/convert'\nimport { delete_docs } from '../connect/delete_docs'\nimport { runWizard } from '../connect/wizard/run_wizard'\nimport { callParser, handleMessages } from '../connect/parser_executables'\nimport { fromError } from 'zod-validation-error'\nimport { ParseRequestPayload, ParseResponsePayload } from '../connect/parser_executable_types'\nimport z from 'zod'\nimport path from 'path'\nimport { withUpdateCheck } from '../common/updates'\nimport { exitWithFeedbackMessage } from '../connect/helpers'\nimport { parseHtmlDoc } from '../html/parser'\nimport {\n InternalError,\n isFigmaConnectFile,\n parseCodeConnect,\n ParseFn,\n ParserError,\n ResolveImportsFn,\n} from '../connect/parser_common'\nimport { findAndResolveImports, parseReactDoc } from '../react/parser'\nimport { CodeConnectLabel, getInferredLanguageForRaw } from '../connect/label_language_mapping'\nimport { groupCodeConnectObjectsByFigmaUrl, writeTemplateFile } from '../connect/migration_helpers'\nimport { convertRemoteFileUrlToRelativePath } from '../connect/wizard/run_wizard'\nimport { getGitRepoAbsolutePath } from '../connect/project'\n\nexport type BaseCommand = commander.Command & {\n token: string\n verbose: boolean\n outFile: string\n outDir: string\n config: string\n dryRun: boolean\n dir: string\n jsonFile: string\n skipUpdateCheck: boolean\n exitOnUnreadableFiles: boolean\n apiUrl?: string\n removeProps?: boolean\n}\n\nfunction addBaseCommand(command: commander.Command, name: string, description: string) {\n return command\n .command(name)\n .description(description)\n .usage('[options]')\n .option('-r --dir <dir>', 'directory to parse')\n .option('-t --token <token>', 'figma access token')\n .option('-v --verbose', 'enable verbose logging for debugging')\n .option('-o --outFile <file>', 'specify a file to output generated Code Connect')\n .option('-o --outDir <dir>', 'specify a directory to output generated Code Connect')\n .option('-c --config <path>', 'path to a figma config file')\n .option('-a --api-url <url>', 'custom Figma API URL to use instead of https://api.figma.com/v1')\n .option('--skip-update-check', 'skips checking for an updated version of the Figma CLI')\n .option(\n '--exit-on-unreadable-files',\n 'exit if any Code Connect files cannot be parsed. We recommend using this option for CI/CD.',\n )\n .option('--dry-run', 'tests publishing without actually publishing')\n .addHelpText(\n 'before',\n 'For feedback or bugs, please raise an issue: https://github.com/figma/code-connect/issues',\n )\n}\n\nexport function addConnectCommandToProgram(program: commander.Command) {\n // Main command, invoked with `figma connect`\n const connectCommand = addBaseCommand(program, 'connect', 'Figma Code Connect').action(\n withUpdateCheck(runWizard),\n )\n\n // Sub-commands, invoked with e.g. `figma connect publish`\n addBaseCommand(\n connectCommand,\n 'publish',\n 'Run Code Connect locally to find any files that have figma connections and publish them to Figma. ' +\n 'By default this looks for a config file named \"figma.config.json\", and uses the `include` and `exclude` fields to determine which files to parse. ' +\n 'If no config file is found, this parses the current directory. An optional `--dir` flag can be used to specify a directory to parse.',\n )\n .option('--skip-validation', 'skip validation of Code Connect docs')\n .option('-l --label <label>', 'label to apply to the published files')\n .option(\n '-b --batch-size <batch_size>',\n 'optional batch size (in number of documents) to use when uploading. Use this if you hit \"request too large\" errors. See README for more information.',\n )\n .action(withUpdateCheck(handlePublish))\n\n addBaseCommand(\n connectCommand,\n 'unpublish',\n 'Run to find any files that have figma connections and unpublish them from Figma. ' +\n 'By default this looks for a config file named \"figma.config.json\", and uses the `include` and `exclude` fields to determine which files to parse. ' +\n 'If no config file is found, this parses the current directory. An optional `--dir` flag can be used to specify a directory to parse.',\n )\n .option(\n '--node <link_to_node>',\n 'specify the node to unpublish. This will unpublish for the specified label.',\n )\n .option('-l --label <label>', 'label to unpublish for')\n .action(withUpdateCheck(handleUnpublish))\n\n addBaseCommand(\n connectCommand,\n 'parse',\n 'Run Code Connect locally to find any files that have figma connections, then converts them to JSON and outputs to stdout.',\n )\n .option('-l --label <label>', 'label to apply to the parsed files')\n .action(withUpdateCheck(handleParse))\n\n addBaseCommand(\n connectCommand,\n 'create',\n 'Generate a Code Connect file with boilerplate in the current directory for a Figma node URL',\n )\n .argument('<figma-node-url>', 'Figma node URL to create the Code Connect file from')\n .action(withUpdateCheck(handleCreate))\n\n addBaseCommand(\n connectCommand,\n 'migrate',\n 'Parse Code Connect files and migrate their templates into .figma.js files that can be published directly without parsing.',\n )\n .argument('[pattern]', 'glob pattern to match files (optional, uses config if not provided)')\n .option('-l --label <label>', 'label to apply to the migrated templates')\n .option(\n '--output-dir <dir>',\n 'directory to write template files (default: same directory as source file)',\n )\n .option('--remove-props', 'remove __props metadata blocks from migrated templates')\n .action(withUpdateCheck(handleMigrate))\n}\n\nexport function getAccessToken(cmd: BaseCommand) {\n return cmd.token ?? process.env.FIGMA_ACCESS_TOKEN\n}\n\nfunction getAccessTokenOrExit(cmd: BaseCommand) {\n const token = getAccessToken(cmd)\n\n if (!token) {\n exitWithError(\n `Couldn't find a Figma access token. Please provide one with \\`--token <access_token>\\` or set the FIGMA_ACCESS_TOKEN environment variable`,\n )\n }\n\n return token\n}\n\nexport function getDir(cmd: BaseCommand) {\n return cmd.dir ?? process.cwd()\n}\n\nfunction setupHandler(cmd: BaseCommand) {\n if (cmd.verbose) {\n logger.setLogLevel(LogLevel.Debug)\n }\n}\n\ntype ParserDoc = z.infer<typeof ParseResponsePayload>['docs'][0]\n\nfunction transformDocFromParser(\n doc: ParserDoc,\n remoteUrl: string,\n config: CodeConnectConfig,\n): ParserDoc {\n let source = doc.source\n if (source) {\n try {\n const url = new URL(source)\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new Error('Invalid URL scheme')\n }\n } catch (e) {\n source = getRemoteFileUrl(source, remoteUrl)\n }\n }\n\n // TODO This logic is duplicated in parser.ts parseDoc due to some type issues\n let figmaNode = doc.figmaNode\n if (config.documentUrlSubstitutions) {\n Object.entries(config.documentUrlSubstitutions).forEach(([from, to]) => {\n figmaNode = figmaNode.replace(from, to)\n })\n }\n\n return {\n ...doc,\n source,\n figmaNode,\n }\n}\n\nexport function parseRawFile(\n filePath: string,\n label: string | undefined,\n config?: CodeConnectConfig,\n dir?: string,\n): CodeConnectJSON {\n const fileContent = fs.readFileSync(filePath, 'utf-8')\n const lines = fileContent.split('\\n')\n const fields: { url?: string; component?: string; source?: string } = {}\n let templateStartIndex = 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 templateStartIndex = 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 if (!fields.url) {\n throw new Error(\n `Missing required url field in ${filePath}. Please add a // url=... comment to the top of the file.`,\n )\n }\n let figmaNodeUrl = fields.url\n\n const template = lines.slice(templateStartIndex).join('\\n')\n\n // Apply documentUrlSubstitutions if provided\n if (config?.documentUrlSubstitutions) {\n Object.entries(config.documentUrlSubstitutions).forEach(([from, to]) => {\n figmaNodeUrl = figmaNodeUrl.replace(from, to)\n })\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: fields.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: fields.source,\n sourceLocation: { line: -1 },\n metadata: {\n cliVersion: require('../../package.json').version,\n },\n }\n}\n\nexport async function getCodeConnectObjects(\n cmd: BaseCommand & { label?: string },\n projectInfo: ProjectInfo,\n silent = false,\n skipTemplateHelpers = false,\n): Promise<CodeConnectJSON[]> {\n if (cmd.jsonFile) {\n try {\n const docsFromJson = JSON.parse(fs.readFileSync(cmd.jsonFile, 'utf8'))\n // Strip internal fields from JSON input\n return docsFromJson.map((doc: CodeConnectJSON) => {\n const { _codeConnectFilePath, ...cleanDoc } = doc\n return cleanDoc as CodeConnectJSON\n })\n } catch (e) {\n logger.error('Failed to parse JSON file:', e)\n }\n }\n\n let codeConnectObjects: CodeConnectJSON[] = []\n\n if (projectInfo.config.parser === 'react') {\n codeConnectObjects = await getReactCodeConnectObjects(\n projectInfo as ProjectInfo<CodeConnectReactConfig>,\n cmd,\n silent,\n skipTemplateHelpers,\n )\n } else if (projectInfo.config.parser === 'html') {\n codeConnectObjects = await getCodeConnectObjectsFromParseFn({\n parseFn: parseHtmlDoc,\n fileExtension: 'ts',\n projectInfo,\n cmd,\n silent,\n skipTemplateHelpers,\n })\n } else {\n const payload: ParseRequestPayload = {\n mode: 'PARSE',\n paths: projectInfo.files,\n config: { ...projectInfo.config, skipTemplateHelpers },\n verbose: cmd.verbose,\n }\n\n try {\n const stdout = await callParser(\n // We use `as` because the React parser makes the types difficult\n // TODO remove once React is an executable parser\n projectInfo.config as CodeConnectExecutableParserConfig,\n payload,\n projectInfo.absPath,\n )\n\n const parsed = ParseResponsePayload.parse(stdout)\n\n const { hasErrors } = handleMessages(parsed.messages)\n\n if (hasErrors) {\n exitWithError('Errors encountered calling parser, exiting')\n }\n\n codeConnectObjects = parsed.docs.map((doc) => ({\n ...transformDocFromParser(doc, projectInfo.remoteUrl, projectInfo.config),\n metadata: {\n cliVersion: require('../../package.json').version,\n },\n }))\n } catch (e) {\n if (cmd.verbose) {\n console.trace(e)\n\n // Don't say to enable verbose if the user has already enabled it.\n exitWithError(`Error calling parser: ${e}.`)\n } else {\n exitWithError(\n `Error returned from parser: ${fromError(e)}. Try re-running the command with --verbose for more information.`,\n )\n }\n }\n }\n\n const rawTemplateFiles = projectInfo.files.filter(\n (f: string) => f.endsWith('.figma.js') || f.endsWith('.figma.template.js'),\n )\n\n if (rawTemplateFiles.length > 0) {\n // Resolve the label before parsing so language inference works correctly\n const resolvedLabel = cmd.label || projectInfo.config.label\n\n const rawTemplateDocs = rawTemplateFiles.map((file) => {\n const doc = parseRawFile(file, resolvedLabel, projectInfo.config, projectInfo.absPath)\n // Store the Code Connect file path for migration purposes\n doc._codeConnectFilePath = file\n\n if (!silent || cmd.verbose) {\n logger.info(success(file))\n }\n return doc\n })\n\n codeConnectObjects = codeConnectObjects.concat(rawTemplateDocs)\n }\n\n if (cmd.label || projectInfo.config.label) {\n logger.info(`Using label \"${cmd.label || projectInfo.config.label}\"`)\n codeConnectObjects.forEach((doc) => {\n doc.label = cmd.label || projectInfo.config.label || doc.label\n })\n }\n\n if (projectInfo.config.language) {\n logger.info(`Using language \"${projectInfo.config.language}\"`)\n codeConnectObjects.forEach((doc) => {\n doc.language = projectInfo.config.language || doc.language\n })\n }\n\n return codeConnectObjects\n}\n\ntype GetCodeConnectObjectsArgs = {\n parseFn: ParseFn\n resolveImportsFn?: ResolveImportsFn\n fileExtension: string | string[]\n projectInfo: ProjectInfo<CodeConnectConfig>\n cmd: BaseCommand\n silent?: boolean\n skipTemplateHelpers?: boolean\n}\n\n// React/Storybook and HTML parsers are handled as special cases for now, they\n// do not use the parser executable model but instead directly call a function\n// in the code base. We may want to transition them to that model in future.\nasync function getCodeConnectObjectsFromParseFn({\n /** The function used to parse a source file into a Code Connect object */\n parseFn,\n /** Optional function used to resolve imports in a source file */\n resolveImportsFn,\n /** The file extension to filter for when checking if files should be parsed */\n fileExtension,\n /** Project info */\n projectInfo,\n /** The commander command object */\n cmd,\n /** Silences console output */\n silent = false,\n /** Skip template helpers (used for extract command) */\n skipTemplateHelpers = false,\n}: GetCodeConnectObjectsArgs) {\n const codeConnectObjects: CodeConnectJSON[] = []\n\n const tsProgram = getTsProgram(projectInfo)\n const { files, remoteUrl, config, absPath } = projectInfo\n\n for (const file of files.filter((f: string) => isFigmaConnectFile(tsProgram, f, fileExtension))) {\n try {\n const docs = await parseCodeConnect({\n program: tsProgram,\n file,\n config,\n parseFn,\n resolveImportsFn,\n absPath,\n parseOptions: {\n repoUrl: remoteUrl,\n debug: cmd.verbose,\n silent,\n skipTemplateHelpers,\n },\n })\n\n codeConnectObjects.push(...docs)\n if (!silent || cmd.verbose) {\n logger.info(success(file))\n }\n } catch (e) {\n if (!silent || cmd.verbose) {\n logger.error(`❌ ${file}`)\n if (e instanceof ParserError) {\n if (cmd.verbose) {\n console.trace(e)\n } else {\n logger.error(e.toString())\n }\n if (cmd.exitOnUnreadableFiles) {\n logger.info('Exiting due to unreadable files')\n process.exit(1)\n }\n } else {\n if (cmd.verbose) {\n console.trace(e)\n } else {\n logger.error(new InternalError(String(e)).toString())\n }\n }\n }\n }\n }\n\n return codeConnectObjects\n}\n\nasync function getReactCodeConnectObjects(\n projectInfo: ProjectInfo<CodeConnectReactConfig>,\n cmd: BaseCommand,\n silent = false,\n skipTemplateHelpers = false,\n) {\n const codeConnectObjects = await getCodeConnectObjectsFromParseFn({\n parseFn: parseReactDoc,\n resolveImportsFn: findAndResolveImports,\n fileExtension: ['tsx', 'jsx'],\n projectInfo,\n cmd,\n silent,\n skipTemplateHelpers,\n })\n\n const storybookCodeConnectObjects = await convertStorybookFiles({\n projectInfo: getReactProjectInfo(projectInfo),\n })\n\n const allCodeConnectObjects = codeConnectObjects.concat(storybookCodeConnectObjects)\n\n return allCodeConnectObjects\n}\n\nasync function handlePublish(\n cmd: BaseCommand & {\n skipValidation: boolean\n label: string\n batchSize: string\n },\n) {\n setupHandler(cmd)\n\n let dir = getDir(cmd)\n const projectInfo = await getProjectInfo(dir, cmd.config)\n\n const codeConnectObjects = await getCodeConnectObjects(cmd, projectInfo)\n\n if (codeConnectObjects.length === 0) {\n logger.warn(\n `No Code Connect files found in ${dir} - Make sure you have configured \\`include\\` and \\`exclude\\` in your figma.config.json file correctly, or that you are running in a directory that contains Code Connect files.`,\n )\n process.exit(0)\n }\n\n if (cmd.dryRun) {\n logger.info(`Files that would be published:`)\n logger.info(codeConnectObjects.map((o) => `- ${o.component} (${o.figmaNode})`).join('\\n'))\n }\n\n const accessToken = getAccessTokenOrExit(cmd)\n\n if (cmd.skipValidation) {\n logger.info('Validation skipped')\n } else {\n logger.info('Validating Code Connect files...')\n var start = new Date().getTime()\n const valid = await validateDocs(\n cmd,\n accessToken,\n codeConnectObjects,\n cmd.apiUrl || projectInfo.config.apiUrl,\n )\n if (!valid) {\n exitWithFeedbackMessage(1)\n } else {\n var end = new Date().getTime()\n var time = end - start\n logger.info(`All Code Connect files are valid (${time}ms)`)\n }\n }\n\n if (cmd.dryRun) {\n logger.info(`Dry run complete`)\n process.exit(0)\n }\n\n let batchSize\n if (cmd.batchSize) {\n batchSize = parseInt(cmd.batchSize, 10)\n if (isNaN(batchSize)) {\n logger.error('Error: failed to parse batch-size. batch-size passed must be a number')\n exitWithFeedbackMessage(1)\n }\n }\n\n upload({\n accessToken,\n docs: codeConnectObjects,\n batchSize: batchSize,\n verbose: cmd.verbose,\n apiUrl: cmd.apiUrl || projectInfo.config.apiUrl,\n })\n}\n\nasync function handleUnpublish(cmd: BaseCommand & { node: string; label: string }) {\n setupHandler(cmd)\n\n let dir = getDir(cmd)\n\n if (cmd.dryRun) {\n logger.info(`Files that would be unpublished:`)\n }\n\n let nodesToDeleteRelevantInfo\n\n const projectInfo = await getProjectInfo(dir, cmd.config)\n\n if (cmd.node) {\n if (!cmd.label) {\n exitWithError('Label is required when specifying a node')\n }\n nodesToDeleteRelevantInfo = [{ figmaNode: cmd.node, label: cmd.label }]\n } else {\n const codeConnectObjects = await getCodeConnectObjects(cmd, projectInfo)\n\n nodesToDeleteRelevantInfo = codeConnectObjects.map((doc) => ({\n figmaNode: doc.figmaNode,\n label: cmd.label || projectInfo.config.label || doc.label,\n }))\n\n if (cmd.label || projectInfo.config.label) {\n logger.info(`Using label ${cmd.label || projectInfo.config.label}`)\n }\n\n if (cmd.dryRun) {\n logger.info(`Dry run complete`)\n process.exit(0)\n }\n }\n\n const accessToken = getAccessTokenOrExit(cmd)\n\n delete_docs({\n accessToken,\n docs: nodesToDeleteRelevantInfo,\n apiUrl: cmd.apiUrl || projectInfo.config.apiUrl,\n })\n}\n\nasync function handleParse(cmd: BaseCommand & { label: string }) {\n setupHandler(cmd)\n\n const dir = cmd.dir ?? process.cwd()\n const projectInfo = await getProjectInfo(dir, cmd.config)\n\n const codeConnectObjects = await getCodeConnectObjects(cmd, projectInfo)\n\n if (cmd.dryRun) {\n logger.info(`Dry run complete`)\n process.exit(0)\n }\n\n if (cmd.outFile) {\n fs.writeFileSync(cmd.outFile, JSON.stringify(codeConnectObjects, null, 2))\n logger.info(`Wrote Code Connect JSON to ${highlight(cmd.outFile)}`)\n } else {\n // don't format the output, so it can be piped to other commands\n console.log(JSON.stringify(codeConnectObjects, undefined, 2))\n }\n}\n\nasync function handleCreate(nodeUrl: string, cmd: BaseCommand) {\n setupHandler(cmd)\n\n const dir = cmd.dir ?? process.cwd()\n const projectInfo = await getProjectInfo(dir, cmd.config)\n\n if (cmd.dryRun) {\n process.exit(0)\n }\n\n const accessToken = getAccessTokenOrExit(cmd)\n\n return createCodeConnectFromUrl({\n accessToken,\n // We remove \\s to allow users to paste URLs inside quotes - the terminal\n // paste will add backslashes, which the quotes preserve, but expected user\n // behaviour would be to strip the quotes\n figmaNodeUrl: nodeUrl.replace(/\\\\/g, ''),\n outFile: cmd.outFile,\n outDir: cmd.outDir,\n projectInfo,\n cmd,\n })\n}\n/**\n * Migrate native parser Code Connect files to parserless. For each found doc:\n * - Replace helpers with figma.* versions\n * - Migrate v1 syntax to v2 (equivalent but more readable)\n * - Format as valid parserless file w/ url=\"\" comment\n * - Name collisions are skipped, unless file is from migration (in which case add \"_1\")\n */\nasync function handleMigrate(pattern: string | undefined, cmd: BaseCommand) {\n setupHandler(cmd)\n\n const dir = cmd.dir ?? process.cwd()\n let projectInfo = await getProjectInfo(dir, cmd.config)\n const documentUrlSubstitutions = projectInfo.config.documentUrlSubstitutions\n\n // Clear documentUrlSubstitutions so we preserve original URLs in migrated templates\n projectInfo = {\n ...projectInfo,\n config: {\n ...projectInfo.config,\n documentUrlSubstitutions: {},\n },\n }\n\n // If a glob pattern is provided, override the project files\n if (pattern) {\n const { globSync } = require('glob')\n const files = globSync(pattern, {\n cwd: dir,\n absolute: true,\n nodir: true,\n })\n\n if (files.length === 0) {\n exitWithError(`No files found matching pattern: ${pattern}`)\n }\n\n logger.info(`Found ${files.length} file(s) matching pattern: ${pattern}`)\n projectInfo = {\n ...projectInfo,\n files,\n }\n }\n\n // Parse the files to get Code Connect objects\n const allCodeConnectObjects = await getCodeConnectObjects(cmd, projectInfo, false, true)\n\n const codeConnectObjectsByFigmaUrl = groupCodeConnectObjectsByFigmaUrl(allCodeConnectObjects)\n\n const totalVariants = Object.values(codeConnectObjectsByFigmaUrl).reduce(\n (acc, obj) => acc + obj.variants.length,\n 0,\n )\n\n // TODO support variants (for now filtering on non-variants)\n const codeConnectObjects = Object.values(codeConnectObjectsByFigmaUrl).flatMap((obj) =>\n obj.main ? [obj.main] : [],\n )\n\n if (codeConnectObjects.length === 0) {\n exitWithError('No Code Connect objects found to migrate')\n }\n\n logger.info(`Found ${codeConnectObjects.length} Code Connect object(s) to migrate`)\n let migratedCount = 0\n let skippedCount = 0\n const errors: string[] = []\n\n // Track file paths created during this migration run\n const filePathsCreated = new Set<string>()\n\n // Get git root path for converting remote URLs to local paths\n const gitRootPath = getGitRepoAbsolutePath(dir)\n\n // Migrate each Code Connect object to a template file\n for (const doc of codeConnectObjects) {\n try {\n // Skip if no template (shouldn't happen, but be safe)\n if (!doc.template) {\n logger.warn(`Skipping ${doc.figmaNode}: no template found`)\n skippedCount++\n continue\n }\n\n // Determine local source path for output location\n let localSourcePath: string | undefined\n\n if (doc._codeConnectFilePath) {\n // Use the Code Connect file path directly (preferred)\n localSourcePath = doc._codeConnectFilePath\n } else if (doc.source && gitRootPath) {\n // Fallback: Convert remote file URL to local path\n const relativePath = convertRemoteFileUrlToRelativePath({\n remoteFileUrl: doc.source,\n gitRootPath,\n dir,\n })\n if (relativePath) {\n // Convert relative path to absolute path for writeTemplateFile\n localSourcePath = path.resolve(dir, relativePath)\n }\n }\n\n const { outputPath, skipped } = writeTemplateFile(\n doc,\n cmd.outDir,\n dir,\n localSourcePath,\n filePathsCreated,\n cmd.removeProps,\n )\n\n if (skipped) {\n logger.warn(`Skipping ${outputPath}: file already exists`)\n skippedCount++\n } else {\n logger.info(`${success('✓')} Migrated to ${highlight(outputPath)}`)\n migratedCount++\n }\n } catch (error) {\n const errorMsg = `Failed to migrate ${doc.figmaNode}: ${error}`\n logger.error(errorMsg)\n errors.push(errorMsg)\n }\n }\n\n if (migratedCount > 0) {\n if (cmd.outDir) {\n const configFilePath = path.join(cmd.outDir, 'figma.config.json')\n if (fs.existsSync(configFilePath)) {\n logger.warn(`Config file already exists at ${highlight(configFilePath)}`)\n } else {\n const { language: docLanguage, label } = codeConnectObjects[0]\n\n const language = getInferredLanguageForRaw(label, docLanguage)\n const config: CodeConnectParserlessConfig = {\n include: ['**/*.figma.js'],\n language,\n label,\n ...(documentUrlSubstitutions && Object.keys(documentUrlSubstitutions).length > 0\n ? { documentUrlSubstitutions }\n : {}),\n }\n fs.writeFileSync(configFilePath, JSON.stringify({ codeConnect: config }, null, 2))\n logger.info(`${success('✓')} Wrote Figma config to ${highlight(configFilePath)}`)\n }\n }\n }\n\n // Summary\n console.log('')\n logger.info(\n `Migration complete: ${success(`${migratedCount} migrated`)}, ${skippedCount} skipped`,\n )\n\n if (totalVariants > 0) {\n logger.error(\n `${error(`${totalVariants} variant restriction(s)`)} found, but not supported by the migration script yet`,\n )\n }\n\n if (errors.length > 0) {\n console.log('')\n logger.error(`Encountered ${errors.length} error(s):`)\n errors.forEach((err) => logger.error(` ${err}`))\n process.exit(1)\n }\n\n if (migratedCount === 0) {\n exitWithError('No files were migrated')\n }\n}\n"]}
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../src/commands/connect.ts"],"names":[],"mappings":"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","sourcesContent":["import * as commander from 'commander'\nimport fs from 'fs'\nimport { upload } from '../connect/upload'\nimport { validateDocs } from '../connect/validation'\nimport { createCodeConnectFromUrl } from '../connect/create'\nimport {\n CodeConnectConfig,\n CodeConnectExecutableParserConfig,\n CodeConnectParserlessConfig,\n CodeConnectReactConfig,\n ProjectInfo,\n getProjectInfo,\n getReactProjectInfo,\n getRemoteFileUrl,\n getTsProgram,\n} from '../connect/project'\nimport { LogLevel, error, exitWithError, highlight, logger, success } from '../common/logging'\nimport { CodeConnectJSON } from '../connect/figma_connect'\nimport { convertStorybookFiles } from '../storybook/convert'\nimport { delete_docs } from '../connect/delete_docs'\nimport { runWizard } from '../connect/wizard/run_wizard'\nimport { callParser, handleMessages } from '../connect/parser_executables'\nimport { fromError } from 'zod-validation-error'\nimport { ParseRequestPayload, ParseResponsePayload } from '../connect/parser_executable_types'\nimport z from 'zod'\nimport path from 'path'\nimport { withUpdateCheck } from '../common/updates'\nimport { applyDocumentUrlSubstitutions, exitWithFeedbackMessage } from '../connect/helpers'\nimport { parseHtmlDoc } from '../html/parser'\nimport {\n InternalError,\n isFigmaConnectFile,\n parseCodeConnect,\n ParseFn,\n ParserError,\n ResolveImportsFn,\n} from '../connect/parser_common'\nimport { findAndResolveImports, parseReactDoc } from '../react/parser'\nimport { getInferredLanguageForRaw } from '../connect/label_language_mapping'\nimport {\n groupCodeConnectObjectsByFigmaUrl,\n writeTemplateFile,\n writeVariantTemplateFile,\n} from '../connect/migration_helpers'\nimport { isRawTemplate, parseRawFile } from '../connect/raw_templates'\nimport { convertRemoteFileUrlToRelativePath } from '../connect/wizard/run_wizard'\nimport { getGitRepoAbsolutePath } from '../connect/project'\n\nexport type BaseCommand = commander.Command & {\n token: string\n verbose: boolean\n outFile: string\n outDir: string\n config: string\n dryRun: boolean\n dir: string\n jsonFile: string\n skipUpdateCheck: boolean\n exitOnUnreadableFiles: boolean\n apiUrl?: string\n removeProps?: boolean\n}\n\nfunction addBaseCommand(command: commander.Command, name: string, description: string) {\n return command\n .command(name)\n .description(description)\n .usage('[options]')\n .option('-r --dir <dir>', 'directory to parse')\n .option('-t --token <token>', 'figma access token')\n .option('-v --verbose', 'enable verbose logging for debugging')\n .option('-o --outFile <file>', 'specify a file to output generated Code Connect')\n .option('-o --outDir <dir>', 'specify a directory to output generated Code Connect')\n .option('-c --config <path>', 'path to a figma config file')\n .option('-a --api-url <url>', 'custom Figma API URL to use instead of https://api.figma.com/v1')\n .option('--skip-update-check', 'skips checking for an updated version of the Figma CLI')\n .option(\n '--exit-on-unreadable-files',\n 'exit if any Code Connect files cannot be parsed. We recommend using this option for CI/CD.',\n )\n .option('--dry-run', 'tests publishing without actually publishing')\n .addHelpText(\n 'before',\n 'For feedback or bugs, please raise an issue: https://github.com/figma/code-connect/issues',\n )\n}\n\nexport function addConnectCommandToProgram(program: commander.Command) {\n // Main command, invoked with `figma connect`\n const connectCommand = addBaseCommand(program, 'connect', 'Figma Code Connect').action(\n withUpdateCheck(runWizard),\n )\n\n // Sub-commands, invoked with e.g. `figma connect publish`\n addBaseCommand(\n connectCommand,\n 'publish',\n 'Run Code Connect locally to find any files that have figma connections and publish them to Figma. ' +\n 'By default this looks for a config file named \"figma.config.json\", and uses the `include` and `exclude` fields to determine which files to parse. ' +\n 'If no config file is found, this parses the current directory. An optional `--dir` flag can be used to specify a directory to parse.',\n )\n .option('--skip-validation', 'skip validation of Code Connect docs')\n .option('-l --label <label>', 'label to apply to the published files')\n .option(\n '-b --batch-size <batch_size>',\n 'optional batch size (in number of documents) to use when uploading. Use this if you hit \"request too large\" errors. See README for more information.',\n )\n .option(\n '--include-template-files',\n '(Deprecated) No longer needed - template files are included by default. Will be removed in a future version.',\n )\n .action(withUpdateCheck(handlePublish))\n\n addBaseCommand(\n connectCommand,\n 'unpublish',\n 'Run to find any files that have figma connections and unpublish them from Figma. ' +\n 'By default this looks for a config file named \"figma.config.json\", and uses the `include` and `exclude` fields to determine which files to parse. ' +\n 'If no config file is found, this parses the current directory. An optional `--dir` flag can be used to specify a directory to parse.',\n )\n .option(\n '--node <link_to_node>',\n 'specify the node to unpublish. This will unpublish for the specified label.',\n )\n .option('-l --label <label>', 'label to unpublish for')\n .action(withUpdateCheck(handleUnpublish))\n\n addBaseCommand(\n connectCommand,\n 'parse',\n 'Run Code Connect locally to find any files that have figma connections, then converts them to JSON and outputs to stdout.',\n )\n .option('-l --label <label>', 'label to apply to the parsed files')\n .option(\n '--include-template-files',\n '(Deprecated) No longer needed - template files are included by default. Will be removed in a future version.',\n )\n .action(withUpdateCheck(handleParse))\n\n addBaseCommand(\n connectCommand,\n 'create',\n 'Generate a Code Connect file with boilerplate in the current directory for a Figma node URL',\n )\n .argument('<figma-node-url>', 'Figma node URL to create the Code Connect file from')\n .action(withUpdateCheck(handleCreate))\n\n addBaseCommand(\n connectCommand,\n 'migrate',\n 'Parse Code Connect files and migrate their templates into .figma.js files that can be published directly without parsing.',\n )\n .argument('[pattern]', 'glob pattern to match files (optional, uses config if not provided)')\n .option('-l --label <label>', 'label to apply to the migrated templates')\n .option(\n '--output-dir <dir>',\n 'directory to write template files (default: same directory as source file)',\n )\n .option('--remove-props', 'remove __props metadata blocks from migrated templates')\n .option(\n '--typescript',\n 'output migrated templates as TypeScript (.figma.ts) instead of JavaScript (.figma.js)',\n )\n .action(withUpdateCheck(handleMigrate))\n}\n\nexport function getAccessToken(cmd: BaseCommand) {\n return cmd.token ?? process.env.FIGMA_ACCESS_TOKEN\n}\n\nfunction getAccessTokenOrExit(cmd: BaseCommand) {\n const token = getAccessToken(cmd)\n\n if (!token) {\n exitWithError(\n `Couldn't find a Figma access token. Please provide one with \\`--token <access_token>\\` or set the FIGMA_ACCESS_TOKEN environment variable`,\n )\n }\n\n return token\n}\n\nexport function getDir(cmd: BaseCommand) {\n return cmd.dir ?? process.cwd()\n}\n\nfunction setupHandler(cmd: BaseCommand) {\n if (cmd.verbose) {\n logger.setLogLevel(LogLevel.Debug)\n }\n}\n\ntype ParserDoc = z.infer<typeof ParseResponsePayload>['docs'][0]\n\nfunction transformDocFromParser(\n doc: ParserDoc,\n remoteUrl: string,\n config: CodeConnectConfig,\n): ParserDoc {\n let source = doc.source\n if (source) {\n try {\n const url = new URL(source)\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new Error('Invalid URL scheme')\n }\n } catch (e) {\n source = getRemoteFileUrl(source, remoteUrl, config.defaultBranch)\n }\n }\n\n // TODO This logic is duplicated in parser.ts parseDoc due to some type issues\n let figmaNode = doc.figmaNode\n if (config.documentUrlSubstitutions) {\n figmaNode = applyDocumentUrlSubstitutions(figmaNode, config.documentUrlSubstitutions)\n }\n\n return {\n ...doc,\n source,\n figmaNode,\n }\n}\n\nexport async function getCodeConnectObjects(\n cmd: BaseCommand & { label?: string },\n projectInfo: ProjectInfo,\n silent = false,\n skipTemplateHelpers = false,\n): Promise<CodeConnectJSON[]> {\n if (cmd.jsonFile) {\n try {\n const docsFromJson = JSON.parse(fs.readFileSync(cmd.jsonFile, 'utf8'))\n // Strip internal fields from JSON input\n return docsFromJson.map((doc: CodeConnectJSON) => {\n const { _codeConnectFilePath, ...cleanDoc } = doc\n return cleanDoc as CodeConnectJSON\n })\n } catch (e) {\n logger.error('Failed to parse JSON file:', e)\n }\n }\n\n let codeConnectObjects: CodeConnectJSON[] = []\n\n if (projectInfo.config.parser === 'react') {\n codeConnectObjects = await getReactCodeConnectObjects(\n projectInfo as ProjectInfo<CodeConnectReactConfig>,\n cmd,\n silent,\n skipTemplateHelpers,\n )\n } else if (projectInfo.config.parser === 'html') {\n codeConnectObjects = await getCodeConnectObjectsFromParseFn({\n parseFn: parseHtmlDoc,\n fileExtension: 'ts',\n projectInfo,\n cmd,\n silent,\n skipTemplateHelpers,\n })\n } else {\n const payload: ParseRequestPayload = {\n mode: 'PARSE',\n paths: projectInfo.files,\n config: { ...projectInfo.config, skipTemplateHelpers },\n verbose: cmd.verbose,\n }\n\n try {\n const stdout = await callParser(\n // We use `as` because the React parser makes the types difficult\n // TODO remove once React is an executable parser\n projectInfo.config as CodeConnectExecutableParserConfig,\n payload,\n projectInfo.absPath,\n )\n\n const parsed = ParseResponsePayload.parse(stdout)\n\n const { hasErrors } = handleMessages(parsed.messages)\n\n if (hasErrors) {\n exitWithError('Errors encountered calling parser, exiting')\n }\n\n codeConnectObjects = parsed.docs.map((doc) => ({\n ...transformDocFromParser(doc, projectInfo.remoteUrl, projectInfo.config),\n metadata: {\n cliVersion: require('../../package.json').version,\n },\n }))\n } catch (e) {\n if (cmd.verbose) {\n console.trace(e)\n\n // Don't say to enable verbose if the user has already enabled it.\n exitWithError(`Error calling parser: ${e}.`)\n } else {\n exitWithError(\n `Error returned from parser: ${fromError(e)}. Try re-running the command with --verbose for more information.`,\n )\n }\n }\n }\n\n const rawTemplateFiles = projectInfo.files.filter((f: string) => {\n // Suffix may be used by HTML / custom parsers\n const isPotentialRawTemplate =\n f.endsWith('.figma.js') ||\n f.endsWith('.figma.template.js') ||\n f.endsWith('.figma.ts') ||\n f.endsWith('.figma.template.ts')\n if (!isPotentialRawTemplate) return false\n try {\n return isRawTemplate(fs.readFileSync(f, 'utf-8'))\n } catch {\n return false\n }\n })\n\n if (rawTemplateFiles.length > 0) {\n // Resolve the label before parsing so language inference works correctly\n const resolvedLabel = cmd.label || projectInfo.config.label\n\n const rawTemplateDocs = rawTemplateFiles.map((file) => {\n const doc = parseRawFile(file, resolvedLabel, projectInfo.config, projectInfo.absPath)\n // Store the Code Connect file path for migration purposes\n doc._codeConnectFilePath = file\n\n if (!silent || cmd.verbose) {\n logger.info(success(file))\n }\n return doc\n })\n\n codeConnectObjects = codeConnectObjects.concat(rawTemplateDocs)\n }\n\n if (cmd.label || projectInfo.config.label) {\n logger.info(`Using label \"${cmd.label || projectInfo.config.label}\"`)\n codeConnectObjects.forEach((doc) => {\n doc.label = cmd.label || projectInfo.config.label || doc.label\n })\n }\n\n if (projectInfo.config.language) {\n logger.info(`Using language \"${projectInfo.config.language}\"`)\n codeConnectObjects.forEach((doc) => {\n doc.language = projectInfo.config.language || doc.language\n })\n }\n\n return codeConnectObjects\n}\n\ntype GetCodeConnectObjectsArgs = {\n parseFn: ParseFn\n resolveImportsFn?: ResolveImportsFn\n fileExtension: string | string[]\n projectInfo: ProjectInfo<CodeConnectConfig>\n cmd: BaseCommand\n silent?: boolean\n skipTemplateHelpers?: boolean\n}\n\n// React/Storybook and HTML parsers are handled as special cases for now, they\n// do not use the parser executable model but instead directly call a function\n// in the code base. We may want to transition them to that model in future.\nasync function getCodeConnectObjectsFromParseFn({\n /** The function used to parse a source file into a Code Connect object */\n parseFn,\n /** Optional function used to resolve imports in a source file */\n resolveImportsFn,\n /** The file extension to filter for when checking if files should be parsed */\n fileExtension,\n /** Project info */\n projectInfo,\n /** The commander command object */\n cmd,\n /** Silences console output */\n silent = false,\n /** Skip template helpers (used for extract command) */\n skipTemplateHelpers = false,\n}: GetCodeConnectObjectsArgs) {\n const codeConnectObjects: CodeConnectJSON[] = []\n\n const tsProgram = getTsProgram(projectInfo)\n const { files, remoteUrl, config, absPath } = projectInfo\n\n for (const file of files.filter((f: string) => isFigmaConnectFile(tsProgram, f, fileExtension))) {\n try {\n const docs = await parseCodeConnect({\n program: tsProgram,\n file,\n config,\n parseFn,\n resolveImportsFn,\n absPath,\n parseOptions: {\n repoUrl: remoteUrl,\n debug: cmd.verbose,\n silent,\n skipTemplateHelpers,\n },\n })\n\n codeConnectObjects.push(...docs)\n if (!silent || cmd.verbose) {\n logger.info(success(file))\n }\n } catch (e) {\n if (!silent || cmd.verbose) {\n logger.error(`❌ ${file}`)\n if (e instanceof ParserError) {\n if (cmd.verbose) {\n console.trace(e)\n } else {\n logger.error(e.toString())\n }\n if (cmd.exitOnUnreadableFiles) {\n logger.info('Exiting due to unreadable files')\n process.exit(1)\n }\n } else {\n if (cmd.verbose) {\n console.trace(e)\n } else {\n logger.error(new InternalError(String(e)).toString())\n }\n }\n }\n }\n }\n\n return codeConnectObjects\n}\n\nasync function getReactCodeConnectObjects(\n projectInfo: ProjectInfo<CodeConnectReactConfig>,\n cmd: BaseCommand,\n silent = false,\n skipTemplateHelpers = false,\n) {\n const codeConnectObjects = await getCodeConnectObjectsFromParseFn({\n parseFn: parseReactDoc,\n resolveImportsFn: findAndResolveImports,\n fileExtension: ['tsx', 'jsx'],\n projectInfo,\n cmd,\n silent,\n skipTemplateHelpers,\n })\n\n const storybookCodeConnectObjects = await convertStorybookFiles({\n projectInfo: getReactProjectInfo(projectInfo),\n })\n\n const allCodeConnectObjects = codeConnectObjects.concat(storybookCodeConnectObjects)\n\n return allCodeConnectObjects\n}\n\nasync function handlePublish(\n cmd: BaseCommand & {\n skipValidation: boolean\n label: string\n batchSize: string\n includeTemplateFiles?: boolean\n },\n) {\n setupHandler(cmd)\n\n // Show deprecation warning if the flag is used\n if (cmd.includeTemplateFiles !== undefined) {\n logger.warn(\n '[Deprecated] The --include-template-files flag is no longer needed because template files are now included by default. ' +\n \"Please don't use this flag - it will be removed in a future version.\",\n )\n }\n\n let dir = getDir(cmd)\n const projectInfo = await getProjectInfo(dir, cmd.config)\n\n const codeConnectObjects = await getCodeConnectObjects(cmd, projectInfo)\n\n if (codeConnectObjects.length === 0) {\n logger.warn(\n `No Code Connect files found in ${dir} - Make sure you have configured \\`include\\` and \\`exclude\\` in your figma.config.json file correctly, or that you are running in a directory that contains Code Connect files.`,\n )\n process.exit(0)\n }\n\n if (cmd.dryRun) {\n logger.info(`Files that would be published:`)\n logger.info(codeConnectObjects.map((o) => `- ${o.component} (${o.figmaNode})`).join('\\n'))\n }\n\n const accessToken = getAccessTokenOrExit(cmd)\n\n if (cmd.skipValidation) {\n logger.info('Validation skipped')\n } else {\n logger.info('Validating Code Connect files...')\n var start = new Date().getTime()\n const valid = await validateDocs(\n cmd,\n accessToken,\n codeConnectObjects,\n cmd.apiUrl || projectInfo.config.apiUrl,\n )\n if (!valid) {\n exitWithFeedbackMessage(1)\n } else {\n var end = new Date().getTime()\n var time = end - start\n logger.info(`All Code Connect files are valid (${time}ms)`)\n }\n }\n\n if (cmd.dryRun) {\n logger.info(`Dry run complete`)\n process.exit(0)\n }\n\n let batchSize\n if (cmd.batchSize) {\n batchSize = parseInt(cmd.batchSize, 10)\n if (isNaN(batchSize)) {\n logger.error('Error: failed to parse batch-size. batch-size passed must be a number')\n exitWithFeedbackMessage(1)\n }\n }\n\n upload({\n accessToken,\n docs: codeConnectObjects,\n batchSize: batchSize,\n verbose: cmd.verbose,\n apiUrl: cmd.apiUrl || projectInfo.config.apiUrl,\n })\n}\n\nasync function handleUnpublish(cmd: BaseCommand & { node: string; label: string }) {\n setupHandler(cmd)\n\n let dir = getDir(cmd)\n\n if (cmd.dryRun) {\n logger.info(`Files that would be unpublished:`)\n }\n\n let nodesToDeleteRelevantInfo\n\n const projectInfo = await getProjectInfo(dir, cmd.config)\n\n if (cmd.node) {\n if (!cmd.label) {\n exitWithError('Label is required when specifying a node')\n }\n nodesToDeleteRelevantInfo = [{ figmaNode: cmd.node, label: cmd.label }]\n } else {\n const codeConnectObjects = await getCodeConnectObjects(cmd, projectInfo)\n\n nodesToDeleteRelevantInfo = codeConnectObjects.map((doc) => ({\n figmaNode: doc.figmaNode,\n label: cmd.label || projectInfo.config.label || doc.label,\n }))\n\n if (cmd.label || projectInfo.config.label) {\n logger.info(`Using label ${cmd.label || projectInfo.config.label}`)\n }\n\n if (cmd.dryRun) {\n logger.info(`Dry run complete`)\n process.exit(0)\n }\n }\n\n const accessToken = getAccessTokenOrExit(cmd)\n\n delete_docs({\n accessToken,\n docs: nodesToDeleteRelevantInfo,\n apiUrl: cmd.apiUrl || projectInfo.config.apiUrl,\n })\n}\n\nasync function handleParse(cmd: BaseCommand & { label: string; includeTemplateFiles?: boolean }) {\n setupHandler(cmd)\n\n // Show deprecation warning if the flag is used\n if (cmd.includeTemplateFiles !== undefined) {\n logger.warn(\n '[Deprecated] The --include-template-files flag is no longer needed because template files are now included by default. ' +\n \"Please don't use this flag - it will be removed in a future version.\",\n )\n }\n\n const dir = cmd.dir ?? process.cwd()\n const projectInfo = await getProjectInfo(dir, cmd.config)\n\n const codeConnectObjects = await getCodeConnectObjects(cmd, projectInfo)\n\n if (cmd.dryRun) {\n logger.info(`Dry run complete`)\n process.exit(0)\n }\n\n if (cmd.outFile) {\n fs.writeFileSync(cmd.outFile, JSON.stringify(codeConnectObjects, null, 2))\n logger.info(`Wrote Code Connect JSON to ${highlight(cmd.outFile)}`)\n } else {\n // don't format the output, so it can be piped to other commands\n console.log(JSON.stringify(codeConnectObjects, undefined, 2))\n }\n}\n\nasync function handleCreate(nodeUrl: string, cmd: BaseCommand) {\n setupHandler(cmd)\n\n const dir = cmd.dir ?? process.cwd()\n const projectInfo = await getProjectInfo(dir, cmd.config)\n\n if (cmd.dryRun) {\n process.exit(0)\n }\n\n const accessToken = getAccessTokenOrExit(cmd)\n\n return createCodeConnectFromUrl({\n accessToken,\n // We remove \\s to allow users to paste URLs inside quotes - the terminal\n // paste will add backslashes, which the quotes preserve, but expected user\n // behaviour would be to strip the quotes\n figmaNodeUrl: nodeUrl.replace(/\\\\/g, ''),\n outFile: cmd.outFile,\n outDir: cmd.outDir,\n projectInfo,\n cmd,\n })\n}\n/**\n * Migrate native parser Code Connect files to parserless. For each found doc:\n * - Replace helpers with figma.* versions\n * - Migrate v1 syntax to v2 (equivalent but more readable)\n * - Format as valid parserless file w/ url=\"\" comment\n * - Name collisions are skipped, unless file is from migration (in which case add \"_1\")\n */\nasync function handleMigrate(\n pattern: string | undefined,\n cmd: BaseCommand & { typescript?: boolean },\n) {\n setupHandler(cmd)\n\n const dir = cmd.dir ?? process.cwd()\n let projectInfo = await getProjectInfo(dir, cmd.config)\n const documentUrlSubstitutions = projectInfo.config.documentUrlSubstitutions\n\n // Clear documentUrlSubstitutions so we preserve original URLs in migrated templates\n projectInfo = {\n ...projectInfo,\n config: {\n ...projectInfo.config,\n documentUrlSubstitutions: {},\n },\n }\n\n // If a glob pattern is provided, override the project files\n if (pattern) {\n const { globSync } = require('glob')\n const files = globSync(pattern, {\n cwd: dir,\n absolute: true,\n nodir: true,\n })\n\n if (files.length === 0) {\n exitWithError(`No files found matching pattern: ${pattern}`)\n }\n\n logger.info(`Found ${files.length} file(s) matching pattern: ${pattern}`)\n projectInfo = {\n ...projectInfo,\n files,\n }\n }\n\n // Parse the files to get Code Connect objects\n const allCodeConnectObjects = await getCodeConnectObjects(cmd, projectInfo, false, true)\n\n const codeConnectObjectsByFigmaUrl = groupCodeConnectObjectsByFigmaUrl(allCodeConnectObjects)\n\n const groupCount = Object.keys(codeConnectObjectsByFigmaUrl).length\n if (groupCount === 0) {\n exitWithError('No Code Connect objects found to migrate')\n }\n\n logger.info(`Found ${groupCount} component(s) to migrate`)\n let migratedCount = 0\n let skippedCount = 0\n const errors: string[] = []\n\n const filePathsCreated = new Set<string>()\n const gitRootPath = getGitRepoAbsolutePath(dir)\n const useTypeScript = !!cmd.typescript\n\n for (const [figmaUrl, group] of Object.entries(codeConnectObjectsByFigmaUrl)) {\n try {\n const hasVariants = group.variants.length > 0\n const representativeDoc = group.main ?? group.variants[0]\n if (!representativeDoc?.template) {\n logger.warn(`Skipping ${figmaUrl}: no template found`)\n skippedCount++\n continue\n }\n\n // Determine local source path for output location\n let localSourcePath: string | undefined\n\n if (representativeDoc._codeConnectFilePath) {\n // Use the Code Connect file path directly (preferred)\n localSourcePath = representativeDoc._codeConnectFilePath\n } else if (representativeDoc?.source && gitRootPath) {\n // Fallback: Convert remote file URL to local path\n const relativePath = convertRemoteFileUrlToRelativePath({\n remoteFileUrl: representativeDoc.source,\n gitRootPath,\n dir,\n })\n if (relativePath) {\n localSourcePath = path.resolve(dir, relativePath)\n }\n }\n\n const { outputPath, skipped } = hasVariants\n ? writeVariantTemplateFile(\n group,\n figmaUrl,\n cmd.outDir,\n dir,\n localSourcePath,\n filePathsCreated,\n useTypeScript,\n )\n : writeTemplateFile(\n representativeDoc,\n cmd.outDir,\n dir,\n localSourcePath,\n filePathsCreated,\n cmd.removeProps,\n useTypeScript,\n )\n\n if (skipped) {\n logger.warn(`Skipping ${outputPath}: file already exists`)\n skippedCount++\n } else {\n logger.info(\n `${success('✓')} Migrated${hasVariants ? ' (with variants)' : ''} to ${highlight(outputPath)}`,\n )\n migratedCount++\n }\n } catch (error) {\n const errorMsg = `Failed to migrate ${figmaUrl}: ${error}`\n logger.error(errorMsg)\n errors.push(errorMsg)\n }\n }\n\n if (migratedCount > 0) {\n if (cmd.outDir) {\n const configFilePath = path.join(cmd.outDir, 'figma.config.json')\n if (fs.existsSync(configFilePath)) {\n logger.warn(`Config file already exists at ${highlight(configFilePath)}`)\n } else {\n const { language: docLanguage, label } = allCodeConnectObjects[0]\n\n const language = getInferredLanguageForRaw(label, docLanguage)\n const config: CodeConnectParserlessConfig = {\n include: [useTypeScript ? '**/*.figma.ts' : '**/*.figma.js'],\n language,\n label,\n ...(documentUrlSubstitutions && Object.keys(documentUrlSubstitutions).length > 0\n ? { documentUrlSubstitutions }\n : {}),\n }\n fs.writeFileSync(configFilePath, JSON.stringify({ codeConnect: config }, null, 2))\n logger.info(`${success('✓')} Wrote Figma config to ${highlight(configFilePath)}`)\n }\n }\n }\n\n // Summary\n console.log('')\n logger.info(\n `Migration complete: ${success(`${migratedCount} migrated`)}, ${skippedCount} skipped`,\n )\n\n if (errors.length > 0) {\n console.log('')\n logger.error(`Encountered ${errors.length} error(s):`)\n errors.forEach((err) => logger.error(` ${err}`))\n process.exit(1)\n }\n\n if (migratedCount === 0) {\n exitWithError('No files were migrated')\n }\n}\n"]}
@@ -21,6 +21,12 @@ export declare function figmaUrlOfComponent(component: FigmaRestApi.Component, f
21
21
  * removes the ID part of a component property name
22
22
  */
23
23
  export declare function normalizePropName(name: string): string;
24
+ /**
25
+ * Applies documentUrlSubstitutions to a value. Processes longer keys first so that
26
+ * when one key is a prefix of another (e.g. "Input" and "InputMenu"),
27
+ * the longer match wins and avoids corrupting the result.
28
+ */
29
+ export declare function applyDocumentUrlSubstitutions(value: string, substitutions: Record<string, string>): string;
24
30
  /**
25
31
  * Displays a feedback/bugs issues link before exiting
26
32
  */
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/connect/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAM/C,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,GAAG,IAAI,IAAI,YAAY,CAAC,SAAS,CAEnF;AAED,eAAO,MAAM,cAAc,GAAa,IAAI,MAAM,KAAG,MAOpD,CAAA;AAED,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAgB9D;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,sBAEhD;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,YAAY,CAAC,IAAI,EAC3B,OAAO,CAAC,EAAE,MAAM,EAAE,GACjB,YAAY,CAAC,SAAS,EAAE,CAgC1B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,UAKrF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,UAE7C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAG/D"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/connect/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAM/C,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,GAAG,IAAI,IAAI,YAAY,CAAC,SAAS,CAEnF;AAED,eAAO,MAAM,cAAc,GAAa,IAAI,MAAM,KAAG,MAOpD,CAAA;AAED,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAgB9D;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,sBAEhD;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,YAAY,CAAC,IAAI,EAC3B,OAAO,CAAC,EAAE,MAAM,EAAE,GACjB,YAAY,CAAC,SAAS,EAAE,CAgC1B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,UAKrF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,UAE7C;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,MAAM,CAUR;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAG/D"}
@@ -40,6 +40,7 @@ exports.parseFileKey = parseFileKey;
40
40
  exports.findComponentsInDocument = findComponentsInDocument;
41
41
  exports.figmaUrlOfComponent = figmaUrlOfComponent;
42
42
  exports.normalizePropName = normalizePropName;
43
+ exports.applyDocumentUrlSubstitutions = applyDocumentUrlSubstitutions;
43
44
  exports.exitWithFeedbackMessage = exitWithFeedbackMessage;
44
45
  const url = __importStar(require("url"));
45
46
  const logging_1 = require("../common/logging");
@@ -130,6 +131,23 @@ function figmaUrlOfComponent(component, fileKey) {
130
131
  function normalizePropName(name) {
131
132
  return name.replace(/#[0-9:]*/g, '');
132
133
  }
134
+ /**
135
+ * Applies documentUrlSubstitutions to a value. Processes longer keys first so that
136
+ * when one key is a prefix of another (e.g. "Input" and "InputMenu"),
137
+ * the longer match wins and avoids corrupting the result.
138
+ */
139
+ function applyDocumentUrlSubstitutions(value, substitutions) {
140
+ const entries = Object.entries(substitutions);
141
+ if (entries.length === 0)
142
+ return value;
143
+ // Sort by key length descending so "InputMenu" is applied before "Input"
144
+ const sorted = [...entries].sort(([a], [b]) => b.length - a.length);
145
+ let result = value;
146
+ for (const [from, to] of sorted) {
147
+ result = result.replace(from, to);
148
+ }
149
+ return result;
150
+ }
133
151
  /**
134
152
  * Displays a feedback/bugs issues link before exiting
135
153
  */
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/connect/helpers.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,kCAEC;AAWD,oCAgBC;AAED,oCAEC;AAQD,4DAmCC;AAQD,kDAKC;AAKD,8CAEC;AAKD,0DAGC;AA7GD,yCAA0B;AAC1B,+CAA0C;AAE1C,MAAM,SAAS,GAAG,oCAAoC,CAAA;AAEtD,SAAgB,WAAW,CAAC,IAAuB;IACjD,OAAO,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,CAAA;AACnE,CAAC;AAEM,MAAM,cAAc,GAAG,UAAU,EAAU;IAChD,MAAM,KAAK,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAClC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,gBAAM,CAAC,KAAK,CAAC,iDAAiD,EAAE,cAAc,CAAC,CAAA;QAC/E,uBAAuB,CAAC,CAAC,CAAC,CAAA;IAC5B,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAPY,QAAA,cAAc,kBAO1B;AAED,SAAgB,YAAY,CAAC,aAAuB;IAClD,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;QACpC,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QAC7C,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAC5C,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YACzC,MAAM,WAAW,GAAG,IAAA,sBAAc,EAAC,MAAM,CAAC,CAAA;YAC1C,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAC3B,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;gBACxB,MAAM,WAAW,GAAG,IAAA,sBAAc,EAAC,EAAE,CAAC,CAAA;gBACtC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAgB,YAAY,CAAC,YAAoB;IAC/C,OAAO,YAAY,CAAC,KAAK,CAAC,iCAAiC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;AACnE,CAAC;AAED;;;;;GAKG;AACH,SAAgB,wBAAwB,CACtC,QAA2B,EAC3B,OAAkB;IAElB,MAAM,UAAU,GAA6B,EAAE,CAAA;IAC/C,MAAM,KAAK,GAAwB,QAAQ,CAAC,QAAQ,CAAA;IAEpD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3B,SAAQ;QACV,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAA;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAA;QAE1B,MAAM,KAAK,GAAwB,IAAI,CAAC,QAAQ,CAAA;QAEhD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAG,CAAA;YACzB,IAAI,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;gBACzC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;oBACvB,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAA;gBACzE,CAAC;gBACD,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;YAChD,CAAC;YACD,IAAI,CAAC,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClC,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAA;YAChD,CAAC;YACD,qCAAqC;YACrC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvD,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAA;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,mBAAmB,CAAC,SAAiC,EAAE,OAAe;IACpF,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,yBAAyB,CAAA;IACjE,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACtC,OAAO,GAAG,OAAO,GAAG,OAAO,aAAa,KAAK,EAAE,CAAA;AACjD,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,IAAY;IAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;AACtC,CAAC;AAED;;GAEG;AACH,SAAgB,uBAAuB,CAAC,QAAgB;IACtD,gBAAM,CAAC,IAAI,CAAC,oFAAoF,CAAC,CAAA;IACjG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;AACxB,CAAC","sourcesContent":["import { FigmaRestApi } from './figma_rest_api'\nimport * as url from 'url'\nimport { logger } from '../common/logging'\n\nconst guidRegex = /^I?[0-9]+:[0-9]+(;[0-9]+:[0-9]+)*$/\n\nexport function isComponent(node: FigmaRestApi.Node): node is FigmaRestApi.Component {\n return node.type === 'COMPONENT' || node.type === 'COMPONENT_SET'\n}\n\nexport const validateNodeId = function (id: string): string {\n const newId = id.replace('-', ':')\n if (!guidRegex.test(newId)) {\n logger.error(`Invalid figma node URL: the provided node-id \"${id}\" is invalid`)\n exitWithFeedbackMessage(1)\n }\n return newId\n}\n\nexport function parseNodeIds(figmaNodeUrls: string[]): string[] {\n const nodeIds: string[] = []\n for (const nodeURL of figmaNodeUrls) {\n const figmaNodeUrl = url.parse(nodeURL, true)\n const nodeId = figmaNodeUrl.query['node-id']\n if (nodeId && typeof nodeId === 'string') {\n const figmaNodeId = validateNodeId(nodeId)\n nodeIds.push(figmaNodeId)\n } else if (Array.isArray(nodeId)) {\n for (const id of nodeId) {\n const figmaNodeId = validateNodeId(id)\n nodeIds.push(figmaNodeId)\n }\n }\n }\n return nodeIds\n}\n\nexport function parseFileKey(figmaNodeUrl: string) {\n return figmaNodeUrl.match(/(?:file|design)\\/([a-zA-Z0-9]+)/)?.[1]\n}\n\n/**\n * Parses components from a Rest API response\n * @param document\n * @param nodeIds\n * @returns\n */\nexport function findComponentsInDocument(\n document: FigmaRestApi.Node,\n nodeIds?: string[],\n): FigmaRestApi.Component[] {\n const components: FigmaRestApi.Component[] = []\n const pages: FigmaRestApi.Node[] = document.children\n\n for (const page of pages) {\n if (page.type !== 'CANVAS') {\n continue\n }\n const pageId = page.id\n const pageName = page.name\n\n const stack: FigmaRestApi.Node[] = page.children\n\n while (stack.length > 0) {\n const node = stack.pop()!\n if (nodeIds && nodeIds.includes(node.id)) {\n if (!isComponent(node)) {\n throw new Error('Specified node is not a component or a component set')\n }\n components.push({ ...node, pageId, pageName })\n }\n if (!nodeIds && isComponent(node)) {\n components.push({ ...node, pageId, pageName })\n }\n // don't traverse into component sets\n if (Array.isArray(node.children) && !isComponent(node)) {\n stack.push(...node.children)\n }\n }\n }\n\n return components\n}\n\n/**\n * Gets the URL of a figma component\n *\n * @param component a published figma component\n * @returns a URL to the figma component\n */\nexport function figmaUrlOfComponent(component: FigmaRestApi.Component, fileKey: string) {\n const fileUrl = process.env.FILE_URL || `https://figma.com/file/`\n const nodeId = component.id.replace(':', '-')\n const urlId = nodeId.replace(':', '-')\n return `${fileUrl}${fileKey}/?node-id=${urlId}`\n}\n\n/**\n * removes the ID part of a component property name\n */\nexport function normalizePropName(name: string) {\n return name.replace(/#[0-9:]*/g, '')\n}\n\n/**\n * Displays a feedback/bugs issues link before exiting\n */\nexport function exitWithFeedbackMessage(exitCode: number): never {\n logger.info('Please raise any bugs or feedback at https://github.com/figma/code-connect/issues.')\n process.exit(exitCode)\n}\n"]}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/connect/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import { FigmaRestApi } from './figma_rest_api'\nimport * as url from 'url'\nimport { logger } from '../common/logging'\n\nconst guidRegex = /^I?[0-9]+:[0-9]+(;[0-9]+:[0-9]+)*$/\n\nexport function isComponent(node: FigmaRestApi.Node): node is FigmaRestApi.Component {\n return node.type === 'COMPONENT' || node.type === 'COMPONENT_SET'\n}\n\nexport const validateNodeId = function (id: string): string {\n const newId = id.replace('-', ':')\n if (!guidRegex.test(newId)) {\n logger.error(`Invalid figma node URL: the provided node-id \"${id}\" is invalid`)\n exitWithFeedbackMessage(1)\n }\n return newId\n}\n\nexport function parseNodeIds(figmaNodeUrls: string[]): string[] {\n const nodeIds: string[] = []\n for (const nodeURL of figmaNodeUrls) {\n const figmaNodeUrl = url.parse(nodeURL, true)\n const nodeId = figmaNodeUrl.query['node-id']\n if (nodeId && typeof nodeId === 'string') {\n const figmaNodeId = validateNodeId(nodeId)\n nodeIds.push(figmaNodeId)\n } else if (Array.isArray(nodeId)) {\n for (const id of nodeId) {\n const figmaNodeId = validateNodeId(id)\n nodeIds.push(figmaNodeId)\n }\n }\n }\n return nodeIds\n}\n\nexport function parseFileKey(figmaNodeUrl: string) {\n return figmaNodeUrl.match(/(?:file|design)\\/([a-zA-Z0-9]+)/)?.[1]\n}\n\n/**\n * Parses components from a Rest API response\n * @param document\n * @param nodeIds\n * @returns\n */\nexport function findComponentsInDocument(\n document: FigmaRestApi.Node,\n nodeIds?: string[],\n): FigmaRestApi.Component[] {\n const components: FigmaRestApi.Component[] = []\n const pages: FigmaRestApi.Node[] = document.children\n\n for (const page of pages) {\n if (page.type !== 'CANVAS') {\n continue\n }\n const pageId = page.id\n const pageName = page.name\n\n const stack: FigmaRestApi.Node[] = page.children\n\n while (stack.length > 0) {\n const node = stack.pop()!\n if (nodeIds && nodeIds.includes(node.id)) {\n if (!isComponent(node)) {\n throw new Error('Specified node is not a component or a component set')\n }\n components.push({ ...node, pageId, pageName })\n }\n if (!nodeIds && isComponent(node)) {\n components.push({ ...node, pageId, pageName })\n }\n // don't traverse into component sets\n if (Array.isArray(node.children) && !isComponent(node)) {\n stack.push(...node.children)\n }\n }\n }\n\n return components\n}\n\n/**\n * Gets the URL of a figma component\n *\n * @param component a published figma component\n * @returns a URL to the figma component\n */\nexport function figmaUrlOfComponent(component: FigmaRestApi.Component, fileKey: string) {\n const fileUrl = process.env.FILE_URL || `https://figma.com/file/`\n const nodeId = component.id.replace(':', '-')\n const urlId = nodeId.replace(':', '-')\n return `${fileUrl}${fileKey}/?node-id=${urlId}`\n}\n\n/**\n * removes the ID part of a component property name\n */\nexport function normalizePropName(name: string) {\n return name.replace(/#[0-9:]*/g, '')\n}\n\n/**\n * Applies documentUrlSubstitutions to a value. Processes longer keys first so that\n * when one key is a prefix of another (e.g. \"Input\" and \"InputMenu\"),\n * the longer match wins and avoids corrupting the result.\n */\nexport function applyDocumentUrlSubstitutions(\n value: string,\n substitutions: Record<string, string>,\n): string {\n const entries = Object.entries(substitutions)\n if (entries.length === 0) return value\n // Sort by key length descending so \"InputMenu\" is applied before \"Input\"\n const sorted = [...entries].sort(([a], [b]) => b.length - a.length)\n let result = value\n for (const [from, to] of sorted) {\n result = result.replace(from, to)\n }\n return result\n}\n\n/**\n * Displays a feedback/bugs issues link before exiting\n */\nexport function exitWithFeedbackMessage(exitCode: number): never {\n logger.info('Please raise any bugs or feedback at https://github.com/figma/code-connect/issues.')\n process.exit(exitCode)\n}\n"]}