@figma/code-connect 1.5.1 → 1.5.3

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 +1 @@
1
- {"version":3,"file":"preview_utils.js","sourceRoot":"","sources":["../../src/commands/preview_utils.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport * as prettier from 'prettier'\nimport { BaseCommand, getCodeConnectObjects, getAccessTokenOrExit, setupHandler } from './connect'\nimport { exitWithError, logger } from '../common/logging'\nimport { CodeConnectJSON } from '../connect/figma_connect'\nimport { parseFigmaNode } from '../connect/validation'\nimport { getProjectInfo } from '../connect/project'\nimport { getApiUrl, getHeaders, FigmaRestApi } from '../connect/figma_rest_api'\nimport { request, isFetchError } from '../common/fetch'\nimport { displayPropertyList, type PropertyListItem } from './property_list_table'\nimport {\n enumeratePropertyCombinations,\n buildPropertyCombinationFromProps,\n toAvailableProperties,\n type PropertyCombination,\n type AvailableProperty,\n} from '../connect/property_combinations'\n\ntype PreviewCommand = BaseCommand & { output?: string }\n\nexport interface NodeToPreview {\n fileKey: string\n nodeId: string\n url: string\n filePath: string\n}\n\nexport interface PreviewResult {\n url: string\n nodeId: string\n filePath: string\n success: boolean\n snippet?: string\n language?: string\n component?: string\n error?: string\n /** Present when this result is one property combination of an expanded (--all) render. */\n propertyCombinationLabel?: string\n /** `kind: \"transport\"` marks a server/network failure, in which case no property vocabulary is attached. */\n errorDetails?: {\n kind?: string\n missingProperty?: string\n availableProperties?: AvailableProperty[]\n }\n /** Nested instances/slots that rendered as placeholders. Not an error — the snippet still rendered. */\n unresolvedInstances?: Array<{ guid: string; name?: string; kind: 'instance' | 'slot' }>\n}\n\ntype NodesByFileKey = Record<string, NodeToPreview[]>\n\n/**\n * Collect nodes to preview from file arguments.\n * Matches by exact path first, then by basename.\n */\nexport async function collectNodesToPreview(\n files: string[],\n allCodeConnectObjects: CodeConnectJSON[],\n dir: string,\n cmd: BaseCommand,\n): Promise<NodeToPreview[]> {\n const nodesToPreview: NodeToPreview[] = []\n\n for (const filePath of files) {\n const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(dir, filePath)\n\n // Try exact path first\n if (fs.existsSync(resolvedPath) && fs.statSync(resolvedPath).isFile()) {\n const docs = allCodeConnectObjects.filter(\n (d) => path.resolve(d._codeConnectFilePath || '') === resolvedPath,\n )\n if (docs.length > 0) {\n if (docs.length === 1) {\n logger.info(`Found: ${filePath}`)\n } else {\n logger.info(`Found ${docs.length} component definition(s) in ${filePath}`)\n }\n for (const doc of docs) {\n const parsed = parseFigmaNode(cmd.verbose, doc, true)\n if (parsed) {\n nodesToPreview.push({\n fileKey: parsed.fileKey,\n nodeId: parsed.nodeId,\n url: doc.figmaNode,\n filePath: path.relative(dir, doc._codeConnectFilePath || ''),\n })\n } else {\n logger.error(`Failed to parse figmaNode from file: ${filePath}`)\n }\n }\n } else {\n logger.error(`Not a valid Code Connect file: ${filePath}`)\n }\n continue\n }\n\n // Fall back to basename matching\n const fileName = path.basename(filePath)\n if (cmd.verbose) {\n logger.debug(`Searching for files matching: ${fileName}`)\n logger.debug(`Total Code Connect objects: ${allCodeConnectObjects.length}`)\n }\n\n const matches = allCodeConnectObjects.filter(\n (d) => path.basename(d._codeConnectFilePath || '') === fileName,\n )\n\n if (matches.length === 0) {\n logger.error(`No files found matching: ${filePath}`)\n continue\n }\n\n if (matches.length === 1) {\n logger.info(`Found: ${matches[0]._codeConnectFilePath}`)\n } else {\n const uniqueFiles = new Set(matches.map((d) => d._codeConnectFilePath))\n if (uniqueFiles.size === 1) {\n logger.info(\n `Found ${matches.length} component definition(s) in ${path.relative(dir, Array.from(uniqueFiles)[0] || '')}`,\n )\n } else {\n logger.info(`Found ${matches.length} component definition(s) in ${uniqueFiles.size} files:`)\n for (const fp of uniqueFiles) {\n const count = matches.filter((d) => d._codeConnectFilePath === fp).length\n logger.info(\n ` - ${path.relative(dir, fp || '')} (${count} definition${count > 1 ? 's' : ''})`,\n )\n }\n }\n }\n\n for (const doc of matches) {\n const parsed = parseFigmaNode(cmd.verbose, doc, true)\n if (parsed) {\n nodesToPreview.push({\n fileKey: parsed.fileKey,\n nodeId: parsed.nodeId,\n url: doc.figmaNode,\n filePath: path.relative(dir, doc._codeConnectFilePath || ''),\n })\n }\n }\n }\n\n return nodesToPreview\n}\n\n/**\n * Outcome of fetching a component's property definitions.\n * - `ok`: definitions were found (includes VARIANT axes).\n * - `empty`: the node was fetched successfully but exposes no properties/variants\n * (e.g. a component with no variant axes or component properties, or a plain\n * frame). This is not an error — there is simply nothing to vary.\n * - `error`: the fetch failed (network / non-200), e.g. the token is missing a\n * required scope (Code Connect: Write and File content: Read).\n */\nexport type ComponentPropertyDefinitionsResult =\n | { status: 'ok'; defs: Record<string, FigmaRestApi.ComponentPropertyDefinition> }\n | { status: 'empty' }\n | { status: 'error' }\n\n/** A single node's schema plus its parent COMPONENT_SET id (set only for a variant child). */\ntype NodeSchemaResult =\n | {\n status: 'ok'\n defs: Record<string, FigmaRestApi.ComponentPropertyDefinition>\n componentSetId?: string\n }\n | { status: 'empty'; componentSetId?: string }\n | { status: 'error' }\n\n/**\n * Fetch one node's property definitions from the REST `files/:key/nodes` endpoint.\n */\nasync function fetchNodeSchema(\n baseApiUrl: string,\n fileKey: string,\n nodeId: string,\n accessToken: string,\n): Promise<NodeSchemaResult> {\n try {\n const nodesUrl = `${baseApiUrl}/files/${fileKey}/nodes?ids=${nodeId}`\n const resp = await request.get<{\n nodes: Record<\n string,\n {\n document?: {\n componentPropertyDefinitions?: Record<string, FigmaRestApi.ComponentPropertyDefinition>\n }\n // Per-node component metadata; a variant member carries its parent set id here.\n components?: Record<string, { componentSetId?: string }>\n }\n >\n }>(nodesUrl, { headers: getHeaders(accessToken) })\n if (resp.response.status !== 200) {\n logger.debug(`files/nodes returned ${resp.response.status} for ${nodeId}`)\n return { status: 'error' }\n }\n const node = resp.data.nodes?.[nodeId]\n const componentSetId = node?.components?.[nodeId]?.componentSetId || undefined\n const defs = node?.document?.componentPropertyDefinitions\n if (defs && Object.keys(defs).length > 0) return { status: 'ok', defs, componentSetId }\n logger.debug(`files/nodes returned no componentPropertyDefinitions for ${nodeId}`)\n return { status: 'empty', componentSetId }\n } catch (err) {\n const detail = isFetchError(err) ? `status ${err.response?.status}` : String(err)\n logger.debug(`files/nodes fetch failed for ${nodeId} (${detail})`)\n return { status: 'error' }\n }\n}\n\n/**\n * Fetch a component's property definitions from the REST `files/:key/nodes` endpoint.\n */\nexport async function fetchComponentPropertyDefinitions(\n baseApiUrl: string,\n fileKey: string,\n nodeId: string,\n accessToken: string,\n): Promise<ComponentPropertyDefinitionsResult> {\n const node = await fetchNodeSchema(baseApiUrl, fileKey, nodeId, accessToken)\n if (node.status === 'error') return { status: 'error' }\n\n // Variant child → resolve to the parent COMPONENT_SET (whose schema carries the\n // variant axes). Fall back to the variant's own defs if the set can't be fetched.\n if (node.componentSetId) {\n const set = await fetchNodeSchema(baseApiUrl, fileKey, node.componentSetId, accessToken)\n if (set.status === 'ok') return { status: 'ok', defs: set.defs }\n logger.debug(\n `Component set ${node.componentSetId} for variant ${nodeId} had no usable schema ` +\n `(${set.status}); using the variant's own definitions`,\n )\n }\n\n return node.status === 'ok' ? { status: 'ok', defs: node.defs } : { status: 'empty' }\n}\n\n/** Case-insensitive lookup of a `ComponentPropertyType` from a `--props` prefix token. */\nfunction parsePropertyTypePrefix(token: string): FigmaRestApi.ComponentPropertyType | undefined {\n const upper = token.trim().toUpperCase()\n return (Object.values(FigmaRestApi.ComponentPropertyType) as string[]).includes(upper)\n ? (upper as FigmaRestApi.ComponentPropertyType)\n : undefined\n}\n\ntype ParsedPropertyPair = {\n name: string\n value: string\n type?: FigmaRestApi.ComponentPropertyType\n}\n\n/**\n * Parse a single `--props` argument into a name/value pair, with an optional\n * `TYPE:` prefix to disambiguate properties that share a name but differ in\n * type (e.g. a BOOLEAN and a TEXT property both named `textMsg`).\n * Example: --props Variant=Primary \"Has Icon=true\" \"BOOLEAN:textMsg=false\"\n *\n * The prefix is only recognized when the token before the first `:` matches a\n * known property type (case-insensitive); otherwise the whole name-part is kept\n * as the property name, so real names containing `:` are preserved.\n */\nexport function parsePropsArg(props: string[]): ParsedPropertyPair[] {\n return props\n .flatMap((arg) => arg.split(','))\n .map((pair) => pair.trim())\n .filter((pair) => pair.length > 0)\n .map((pair) => {\n const eq = pair.indexOf('=')\n const namePart = (eq === -1 ? pair : pair.slice(0, eq)).trim()\n const value = eq === -1 ? '' : pair.slice(eq + 1).trim()\n\n const colon = namePart.indexOf(':')\n if (colon !== -1) {\n const type = parsePropertyTypePrefix(namePart.slice(0, colon))\n if (type) {\n return { name: namePart.slice(colon + 1).trim(), value, type }\n }\n }\n return { name: namePart, value }\n })\n}\n\n/**\n * Filter templates to only those matching the requested node IDs.\n */\nexport function filterTemplatesForNodes(\n nodeIds: string[],\n allTemplates: CodeConnectJSON[],\n): CodeConnectJSON[] {\n return allTemplates.filter((template) => {\n if (!template.figmaNode) return false\n const nodeIdMatch = template.figmaNode.match(/node-id=([^&\\s]+)/)\n if (!nodeIdMatch?.[1]) return false\n const templateNodeId = nodeIdMatch[1].replace(/-/g, ':')\n return nodeIds.includes(templateNodeId)\n })\n}\n\n/**\n * Aliases for Code Connect labels that don't directly match a Prettier language name.\n */\nconst CC_LABEL_ALIASES: Record<string, string> = {\n react: 'typescript',\n code: 'typescript',\n}\n\n/**\n * Map from Code Connect language labels to Prettier parser names,\n * built lazily from Prettier's getSupportInfo() on first access.\n * Lazy to avoid triggering plugin loading at module import time.\n */\nlet _prettierParserMap: Record<string, string> | null = null\n\nexport function getPrettierParserMap(): Record<string, string> {\n if (_prettierParserMap) return _prettierParserMap\n\n const info = prettier.getSupportInfo() as {\n languages: Array<{ name: string; parsers?: string[] }>\n }\n _prettierParserMap = {}\n\n for (const lang of info.languages) {\n if (lang.parsers?.[0]) {\n _prettierParserMap[lang.name.toLowerCase()] = lang.parsers[0]\n }\n }\n\n for (const [alias, target] of Object.entries(CC_LABEL_ALIASES)) {\n if (_prettierParserMap[target]) {\n _prettierParserMap[alias] = _prettierParserMap[target]\n }\n }\n\n return _prettierParserMap\n}\n\n/**\n * Check if a snippet can be parsed by Prettier.\n * Returns true for languages without a Prettier parser (nothing to validate).\n */\nexport async function isPrettierParseable(snippet: string, language?: string): Promise<boolean> {\n const lang = language?.toLowerCase()\n const parser = lang ? getPrettierParserMap()[lang] : 'typescript'\n\n if (!parser) {\n return true\n }\n\n try {\n await prettier.format(snippet, { parser })\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Format snippet with Prettier.\n * Returns the snippet unmodified for languages Prettier doesn't support.\n */\nexport async function formatSnippet(snippet: string, language?: string): Promise<string> {\n const lang = language?.toLowerCase()\n const parser = lang ? getPrettierParserMap()[lang] : 'typescript'\n\n if (!parser) {\n return snippet\n }\n\n try {\n let formatted = await prettier.format(snippet, {\n parser,\n semi: false,\n singleQuote: true,\n printWidth: 80,\n tabWidth: 2,\n })\n formatted = formatted.replace(/^;\\s*/, '')\n return formatted\n } catch {\n logger.info(`Autoformatting couldn't be applied: language not supported or code is malformed`)\n return snippet\n }\n}\n\n/**\n * Display results with terminal colors\n */\nconst purple = chalk.ansi256(93)\nconst red = chalk.ansi256(196)\nconst gray = chalk.ansi256(243)\nconst yellow = chalk.ansi256(179)\n\nexport function displayResults(results: PreviewResult[]): void {\n console.log('')\n const successCount = results.filter((r) => r.success).length\n const errorCount = results.filter((r) => !r.success).length\n\n // A muted note when nested children rendered as placeholders (not an error).\n const printUnresolved = (result: PreviewResult) => {\n if (!result.unresolvedInstances?.length) return\n const names = result.unresolvedInstances.map((u) => u.name || u.guid).join(', ')\n console.log(\n ` ${yellow(`⚠ ${result.unresolvedInstances.length} nested instance(s) not Code Connected: ${names}`)}`,\n )\n }\n\n for (const result of results) {\n // When expanding property combinations, label the header with the specific combination.\n const combinationSuffix = result.propertyCombinationLabel\n ? ` ${gray(`— ${result.propertyCombinationLabel}`)}`\n : ''\n if (result.success && result.snippet) {\n const componentInfo = result.component ? ` ${gray(`→ ${result.component}`)}` : ''\n console.log(\n `${purple('●')} ${chalk.bold(result.filePath)}${componentInfo}${combinationSuffix}`,\n )\n console.log(` ${gray(result.url)}`)\n console.log('')\n\n const indentedSnippet = result.snippet\n .trim()\n .split('\\n')\n .map((line) => ' ' + line)\n .join('\\n')\n console.log(indentedSnippet)\n printUnresolved(result)\n console.log('')\n } else {\n const componentInfo = result.component ? ` ${gray(`(${result.component})`)}` : ''\n console.log(`${red('✕')} ${chalk.bold(result.filePath)}${componentInfo}${combinationSuffix}`)\n console.log(` ${gray(result.url)}`)\n console.log(` ${red('Error:')} ${result.error}`)\n // One-line repair hint: the offending property and the real vocabulary.\n // (Transport errors carry no vocabulary — nothing to hint.)\n const available = result.errorDetails?.availableProperties?.map((p) => p.name).join(', ')\n const missingProperty = result.errorDetails?.missingProperty\n if (missingProperty && available) {\n console.log(\n ` ${gray(`property \"${missingProperty}\" not found — available: ${available}`)}`,\n )\n } else if (available) {\n console.log(` ${gray(`available properties: ${available}`)}`)\n }\n printUnresolved(result)\n console.log('')\n }\n }\n\n const failed = errorCount > 0 ? red(`${errorCount} failed`) : gray(`${errorCount} failed`)\n console.log(`${chalk.bold('Summary:')} ${purple(`${successCount} succeeded`)}, ${failed}`)\n}\n\n// The server caps inbound request bodies at 5MB. The figmaDocs payload\n// (one Code Connect template per requested component) dominates the body size,\n// so for projects with many components we split into smaller chunks and send\n// them in parallel rather than risking a 413.\nconst PREVIEW_CHUNK_SIZE = 50\n// Bound the number of chunks in flight at once. Without this cap, large\n// libraries (~1k+ components) trigger N parallel preview requests, which\n// overwhelms upstream token validation and causes spurious 403 \"Invalid\n// token\" responses for the chunks that queue up too long.\nconst PREVIEW_MAX_CONCURRENCY = 5\n// Mirrors MAX_PROPERTY_COMBINATIONS_PER_REQUEST in pixie/code_connect_preview_handler.ts.\n// `--all` caps enumeration here and warns rather than sending a request that fails wholesale.\nconst MAX_PROPERTY_COMBINATIONS = 500\n\nexport function parseMaxCombinationsArg(value: string | undefined): number {\n if (value === undefined) {\n return MAX_PROPERTY_COMBINATIONS\n }\n const parsed = Number(value)\n if (!Number.isInteger(parsed) || parsed < 1) {\n exitWithError('--max-combinations must be a positive integer')\n }\n if (parsed > MAX_PROPERTY_COMBINATIONS) {\n exitWithError(`--max-combinations cannot exceed ${MAX_PROPERTY_COMBINATIONS}`)\n }\n return parsed\n}\n\ntype PreviewResponseData = {\n status: number\n error: boolean\n meta: {\n results: Array<{\n nodeId: string\n nodeUrl: string\n snippet?: string\n language?: string\n component?: string\n error?: string\n propertyCombinationLabel?: string\n errorKind?: string\n unresolvedInstances?: Array<{ guid: string; name?: string; kind: 'instance' | 'slot' }>\n }>\n }\n}\n\ntype ChunkOutcome = {\n chunkNodeIds: string[]\n response: Awaited<ReturnType<typeof request.post<PreviewResponseData>>> | null\n error: unknown\n}\n\nfunction chunkArray<T>(arr: T[], size: number): T[][] {\n const chunks: T[][] = []\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size))\n }\n return chunks\n}\n\n/**\n * Split node IDs into request chunks that respect BOTH the node-count cap\n * (PREVIEW_CHUNK_SIZE) and, when rendering property combinations, the server's\n * per-request combination cap (MAX_PROPERTY_COMBINATIONS).\n *\n * The server sums combinations across every node in a request and rejects the\n * whole request if the total exceeds the cap, so bundling by node count alone\n * can push several individually-valid nodes over the limit and fail them all.\n * Each node is already truncated to <= MAX_PROPERTY_COMBINATIONS upstream, so a\n * single node always fits (worst case: one node per chunk).\n */\nexport function chunkNodeIdsForPreview(\n nodeIds: string[],\n propertyCombinationsByNodeId?: Record<string, PropertyCombination[]>,\n): string[][] {\n if (!propertyCombinationsByNodeId) {\n return chunkArray(nodeIds, PREVIEW_CHUNK_SIZE)\n }\n\n const chunks: string[][] = []\n let current: string[] = []\n let currentCombinations = 0\n for (const nodeId of nodeIds) {\n const count = propertyCombinationsByNodeId[nodeId]?.length ?? 0\n // Close the current chunk before adding this node would breach either cap.\n if (\n current.length > 0 &&\n (current.length >= PREVIEW_CHUNK_SIZE ||\n currentCombinations + count > MAX_PROPERTY_COMBINATIONS)\n ) {\n chunks.push(current)\n current = []\n currentCombinations = 0\n }\n current.push(nodeId)\n currentCombinations += count\n }\n if (current.length > 0) chunks.push(current)\n return chunks\n}\n\nasync function runInWaves<T, R>(\n items: T[],\n fn: (item: T) => Promise<R>,\n maxConcurrency: number,\n): Promise<R[]> {\n const out: R[] = []\n for (let i = 0; i < items.length; i += maxConcurrency) {\n const wave = items.slice(i, i + maxConcurrency)\n const settled = await Promise.all(wave.map(fn))\n out.push(...settled)\n }\n return out\n}\n\nfunction sendPreviewChunk({\n chunkNodeIds,\n requiredTemplates,\n baseApiUrl,\n fileKey,\n accessToken,\n propertyCombinationsByNodeId,\n}: {\n chunkNodeIds: string[]\n requiredTemplates: CodeConnectJSON[]\n baseApiUrl: string\n fileKey: string\n accessToken: string\n propertyCombinationsByNodeId?: Record<string, PropertyCombination[]>\n}): Promise<ChunkOutcome> {\n const chunkTemplates = filterTemplatesForNodes(chunkNodeIds, requiredTemplates)\n // Only include property combinations for the node IDs in this chunk.\n let renderCombinations: Record<string, PropertyCombination[]> | undefined\n if (propertyCombinationsByNodeId) {\n renderCombinations = {}\n for (const nodeId of chunkNodeIds) {\n if (propertyCombinationsByNodeId[nodeId]) {\n renderCombinations[nodeId] = propertyCombinationsByNodeId[nodeId]\n }\n }\n }\n return request\n .post<PreviewResponseData>(\n `${baseApiUrl}/code_connect/preview_snippets?file_key=${fileKey}`,\n {\n nodeIds: chunkNodeIds,\n figmaDocs: { all: chunkTemplates },\n ...(renderCombinations && Object.keys(renderCombinations).length > 0\n ? { renderCombinations }\n : {}),\n },\n { headers: getHeaders(accessToken) },\n )\n .then((response) => ({ chunkNodeIds, response, error: null as unknown }))\n .catch((err: unknown) => ({ chunkNodeIds, response: null, error: err }))\n}\n\n/**\n * Parse the offending property name out of a \"property not found\" render error,\n * e.g. `PropertyNotFoundError: property 'Varient' not found` -> `Varient`.\n */\nexport function parseMissingProperty(error?: string): string | undefined {\n if (!error) return undefined\n const match =\n error.match(/propert(?:y|ies)[^'\"`]*['\"`]([^'\"`]+)['\"`]/i) ?? error.match(/['\"`]([^'\"`]+)['\"`]/)\n return match?.[1]\n}\n\n/** Build `errorDetails` for a failed result. Undefined when there's no property context (not --all). */\nfunction buildErrorDetails(\n error: string | undefined,\n errorKind: string | undefined,\n availableProperties: AvailableProperty[] | undefined,\n): PreviewResult['errorDetails'] {\n // Transport failure: network/backend problem, not a bad property — carry only the kind.\n if (errorKind === 'transport') return { kind: 'transport' }\n if (!availableProperties) return undefined\n const details: NonNullable<PreviewResult['errorDetails']> = { availableProperties }\n if (errorKind) details.kind = errorKind\n const missingProperty = parseMissingProperty(error)\n if (missingProperty) details.missingProperty = missingProperty\n return details\n}\n\nexport function chunkOutcomeToResults(\n outcome: ChunkOutcome,\n nodes: NodeToPreview[],\n fileKey: string,\n availablePropsByNodeId?: Record<string, AvailableProperty[]>,\n): PreviewResult[] {\n const { chunkNodeIds, response, error } = outcome\n const results: PreviewResult[] = []\n\n if (error) {\n const errorMsg = isFetchError(error)\n ? error.data?.message || error.response.statusText\n : String(error)\n // 503 means the server-side killswitch is on — surface the server's\n // message directly without the per-file/per-node noise so the user\n // sees a single clear line during an incident.\n if (isFetchError(error) && error.response.status === 503) {\n exitWithError(errorMsg)\n } else {\n logger.error(`Failed to preview components in file ${fileKey}: ${errorMsg}`)\n for (const nodeId of chunkNodeIds) {\n for (const node of nodes.filter((n) => n.nodeId === nodeId)) {\n results.push({\n url: node.url,\n nodeId: node.nodeId,\n filePath: node.filePath,\n success: false,\n error: errorMsg,\n // Chunk-level failure is a server/network error, not a template problem.\n errorDetails: { kind: 'transport' },\n })\n }\n }\n }\n return results\n }\n\n if (response!.response.status === 200 && response!.data.meta?.results) {\n // Track match index per nodeId so duplicate node IDs get the correct file attribution.\n // The server returns results in the same order as the templates we sent. Each chunk's\n // nodeIds are disjoint (we dedupe before chunking), so per-chunk indexing is correct.\n // Property-combination results are expanded renders of one node, not one result per\n // matching template, so they should not consume this per-template index.\n const nodeMatchIndex: Record<string, number> = {}\n for (const result of response!.data.meta.results) {\n const idx = nodeMatchIndex[result.nodeId] ?? 0\n const matchingNodes = nodes.filter((n) => n.nodeId === result.nodeId)\n const node = result.propertyCombinationLabel\n ? matchingNodes[0]\n : matchingNodes[idx] || matchingNodes[0]\n if (!result.propertyCombinationLabel) {\n nodeMatchIndex[result.nodeId] = idx + 1\n }\n const error = result.error || (!result.snippet ? 'No snippet returned by server' : undefined)\n const success = !result.error && !!result.snippet\n results.push({\n url: node?.url || result.nodeUrl,\n nodeId: result.nodeId,\n filePath: node?.filePath || '',\n success,\n snippet: result.snippet,\n language: result.language,\n component: result.component,\n error,\n ...(result.propertyCombinationLabel\n ? { propertyCombinationLabel: result.propertyCombinationLabel }\n : {}),\n ...(result.unresolvedInstances?.length\n ? { unresolvedInstances: result.unresolvedInstances }\n : {}),\n ...(success\n ? {}\n : {\n errorDetails: buildErrorDetails(\n error,\n result.errorKind,\n availablePropsByNodeId?.[result.nodeId],\n ),\n }),\n })\n }\n return results\n }\n\n for (const nodeId of chunkNodeIds) {\n for (const node of nodes.filter((n) => n.nodeId === nodeId)) {\n const error = `API request failed with status ${response!.response.status}`\n results.push({\n url: node.url,\n nodeId: node.nodeId,\n filePath: node.filePath,\n success: false,\n error,\n // Non-2xx from the endpoint is a transport-level failure, not a template problem.\n errorDetails: { kind: 'transport' },\n })\n }\n }\n return results\n}\n\nasync function previewFile({\n fileKey,\n nodes,\n baseApiUrl,\n accessToken,\n dir,\n allCodeConnectObjects,\n propertyCombinationsByNodeId,\n availablePropsByNodeId,\n}: {\n fileKey: string\n nodes: NodeToPreview[]\n baseApiUrl: string\n accessToken: string\n dir: string\n allCodeConnectObjects: CodeConnectJSON[]\n propertyCombinationsByNodeId?: Record<string, PropertyCombination[]>\n availablePropsByNodeId?: Record<string, AvailableProperty[]>\n}): Promise<PreviewResult[]> {\n const allNodeIds = nodes.map((n) => n.nodeId)\n // Deduplicate — multiple figma.connect() calls may share the same nodeId;\n // the individual templates are sent in figmaDocs and the server iterates per-template.\n const nodeIds = [...new Set(allNodeIds)]\n\n // Only send templates from the requested files — other files' templates\n // for the same nodeId exist on the server and shouldn't be rendered individually.\n const requestedFilePaths = new Set(nodes.map((n) => path.resolve(dir, n.filePath)))\n const requiredTemplates = filterTemplatesForNodes(allNodeIds, allCodeConnectObjects).filter((t) =>\n requestedFilePaths.has(path.resolve(t._codeConnectFilePath || '')),\n )\n\n const chunks = chunkNodeIdsForPreview(nodeIds, propertyCombinationsByNodeId)\n const outcomes = await runInWaves(\n chunks,\n (chunkNodeIds) =>\n sendPreviewChunk({\n chunkNodeIds,\n requiredTemplates,\n baseApiUrl,\n fileKey,\n accessToken,\n propertyCombinationsByNodeId,\n }),\n PREVIEW_MAX_CONCURRENCY,\n )\n\n return outcomes.flatMap((outcome) =>\n chunkOutcomeToResults(outcome, nodes, fileKey, availablePropsByNodeId),\n )\n}\n\nfunction collectAllLocalNodesToPreview(\n allCodeConnectObjects: CodeConnectJSON[],\n dir: string,\n cmd: BaseCommand,\n): NodeToPreview[] {\n const nodesToCheck: NodeToPreview[] = []\n for (const doc of allCodeConnectObjects) {\n const parsed = parseFigmaNode(cmd.verbose, doc, true)\n if (parsed) {\n nodesToCheck.push({\n fileKey: parsed.fileKey,\n nodeId: parsed.nodeId,\n url: doc.figmaNode,\n filePath: path.relative(dir, doc._codeConnectFilePath || ''),\n })\n }\n }\n return nodesToCheck\n}\n\nfunction groupNodesByFileKey(nodes: NodeToPreview[]): NodesByFileKey {\n const nodesByFileKey: NodesByFileKey = {}\n for (const node of nodes) {\n nodesByFileKey[node.fileKey] ??= []\n nodesByFileKey[node.fileKey].push(node)\n }\n return nodesByFileKey\n}\n\nasync function handleInspect({\n nodesByFileKey,\n configuredApiUrl,\n accessToken,\n outputFormat,\n}: {\n nodesByFileKey: NodesByFileKey\n configuredApiUrl?: string\n accessToken: string\n outputFormat: string\n}): Promise<void> {\n const items: PropertyListItem[] = []\n const seen = new Set<string>()\n for (const [fileKey, nodes] of Object.entries(nodesByFileKey)) {\n const baseApiUrl = getApiUrl(nodes[0].url, configuredApiUrl)\n for (const node of nodes) {\n const dedupeKey = `${node.filePath}::${node.nodeId}`\n if (seen.has(dedupeKey)) continue\n seen.add(dedupeKey)\n const result = await fetchComponentPropertyDefinitions(\n baseApiUrl,\n fileKey,\n node.nodeId,\n accessToken,\n )\n if (result.status === 'error') {\n logger.warn(`Couldn't fetch property definitions for node ${node.nodeId}`)\n } else if (result.status === 'empty') {\n logger.info(`Node ${node.nodeId} has no component properties or variants.`)\n }\n items.push({\n filePath: node.filePath,\n nodeId: node.nodeId,\n availableProperties: result.status === 'ok' ? toAvailableProperties(result.defs) : [],\n })\n }\n }\n\n if (outputFormat === 'json') {\n console.log(JSON.stringify(items, null, 2))\n } else {\n displayPropertyList(items)\n }\n}\n\nfunction validatePreviewOptions(cmd: PreviewCommand): void {\n if (cmd.all && cmd.props) {\n exitWithError('Cannot combine --props and --all; use one or the other')\n }\n\n if (cmd.maxCombinations !== undefined && !cmd.all) {\n exitWithError('--max-combinations can only be used with --all')\n }\n}\n\nasync function buildPropertyPreviewInputs({\n enabled,\n baseApiUrl,\n fileKey,\n nodes,\n accessToken,\n propsPairs,\n maxCombinations,\n}: {\n enabled: boolean\n baseApiUrl: string\n fileKey: string\n nodes: NodeToPreview[]\n accessToken: string\n propsPairs?: ParsedPropertyPair[]\n maxCombinations: number\n}): Promise<{\n propertyCombinationsByNodeId?: Record<string, PropertyCombination[]>\n availablePropsByNodeId?: Record<string, AvailableProperty[]>\n}> {\n if (!enabled) return {}\n\n const propertyCombinationsByNodeId: Record<string, PropertyCombination[]> = {}\n const availablePropsByNodeId: Record<string, AvailableProperty[]> = {}\n for (const nodeId of [...new Set(nodes.map((n) => n.nodeId))]) {\n const result = await fetchComponentPropertyDefinitions(baseApiUrl, fileKey, nodeId, accessToken)\n if (result.status === 'error') {\n logger.warn(\n `Couldn't fetch property definitions for node ${nodeId} (ensure your token has the ` +\n `Code Connect: Write and File content: Read scopes); rendering its default property combination only`,\n )\n continue\n }\n if (result.status === 'empty') {\n // Not an error: the component simply has no properties or variants to vary.\n if (propsPairs) {\n logger.warn(\n `Node ${nodeId} has no component properties or variants, so --props ` +\n `(${propsPairs.map((p) => p.name).join(', ')}) has no effect; rendering its only property combination.`,\n )\n } else {\n logger.info(\n `Node ${nodeId} has no component properties or variants to vary; rendering its only property combination.`,\n )\n }\n continue\n }\n\n const defs = result.defs\n if (propsPairs) {\n const { propertyCombination, availableProperties, unknown, invalid, ambiguous } =\n buildPropertyCombinationFromProps(defs, propsPairs)\n if (unknown.length > 0) {\n logger.warn(\n `Unknown propert${unknown.length > 1 ? 'ies' : 'y'} for node ${nodeId}: ${unknown.join(', ')}. ` +\n `Available: ${availableProperties.map((p) => p.name).join(', ')}`,\n )\n }\n for (const { name, value, options } of invalid) {\n logger.warn(\n `\"${value}\" is not a valid value for ${name} on node ${nodeId}. Options: ${options.join(', ')}`,\n )\n }\n for (const { name, types } of ambiguous) {\n logger.warn(\n `Property \"${name}\" on node ${nodeId} matches multiple types (${types.join(', ')}); ` +\n `prefix the value with a type to disambiguate, e.g. ${types[0]}:${name}=... . Skipping.`,\n )\n }\n availablePropsByNodeId[nodeId] = availableProperties\n propertyCombinationsByNodeId[nodeId] = [propertyCombination]\n } else {\n const { propertyCombinations, availableProperties, truncated } =\n enumeratePropertyCombinations(defs, {\n maxCombinations,\n })\n availablePropsByNodeId[nodeId] = availableProperties\n if (truncated) {\n logger.warn(\n `Node ${nodeId} has ${truncated.total} property combinations, exceeding the ${truncated.cap}-combination ` +\n `preview limit; rendering the first ${truncated.cap}. Use --props to preview a ` +\n `specific property combination.`,\n )\n }\n if (propertyCombinations.length > 0) {\n propertyCombinationsByNodeId[nodeId] = propertyCombinations\n }\n }\n }\n\n return { propertyCombinationsByNodeId, availablePropsByNodeId }\n}\n\nasync function previewNodesForFile({\n fileKey,\n nodes,\n configuredApiUrl,\n accessToken,\n dir,\n allCodeConnectObjects,\n renderPropertyCombinations,\n propsPairs,\n maxCombinations,\n}: {\n fileKey: string\n nodes: NodeToPreview[]\n configuredApiUrl?: string\n accessToken: string\n dir: string\n allCodeConnectObjects: CodeConnectJSON[]\n renderPropertyCombinations: boolean\n propsPairs?: ParsedPropertyPair[]\n maxCombinations: number\n}): Promise<PreviewResult[]> {\n const baseApiUrl = getApiUrl(nodes[0].url, configuredApiUrl)\n const { propertyCombinationsByNodeId, availablePropsByNodeId } = await buildPropertyPreviewInputs(\n {\n enabled: renderPropertyCombinations,\n baseApiUrl,\n fileKey,\n nodes,\n accessToken,\n propsPairs,\n maxCombinations,\n },\n )\n\n return previewFile({\n fileKey,\n nodes,\n baseApiUrl,\n accessToken,\n dir,\n allCodeConnectObjects,\n propertyCombinationsByNodeId,\n availablePropsByNodeId,\n })\n}\n\nasync function validateRenderedSnippets(results: PreviewResult[]): Promise<void> {\n for (const result of results) {\n if (result.success && result.snippet) {\n const prettierValid = await isPrettierParseable(result.snippet, result.language)\n if (!prettierValid) {\n // Prettier can parse this language but failed — mark as error\n result.success = false\n result.error = 'Snippet has syntax errors and may not be valid code'\n }\n }\n }\n}\n\nasync function outputPreviewResults(results: PreviewResult[], outputFormat: string): Promise<void> {\n if (outputFormat === 'json') {\n console.log(JSON.stringify(results, null, 2))\n return\n }\n\n const formattedResults: PreviewResult[] = await Promise.all(\n results.map(async (result) => {\n if (result.success && result.snippet) {\n const formattedSnippet = await formatSnippet(result.snippet, result.language)\n return { ...result, snippet: formattedSnippet }\n }\n return result\n }),\n )\n displayResults(formattedResults)\n}\n\n/**\n * Handle the preview command\n */\nexport async function handlePreview(files: string[], cmd: PreviewCommand) {\n setupHandler(cmd)\n\n const dir = cmd.dir ?? process.cwd()\n const projectInfo = await getProjectInfo(dir, cmd.config)\n const accessToken = getAccessTokenOrExit(cmd)\n const outputFormat = cmd.output || 'table'\n const configuredApiUrl = cmd.apiUrl || projectInfo.config.apiUrl\n\n if (cmd.all && (!files || files.length === 0)) {\n exitWithError(\n '--all requires a specific component, e.g. `figma connect preview Button.figma.ts --all`',\n )\n }\n\n const allCodeConnectObjects = await getCodeConnectObjects(cmd, projectInfo, true)\n\n const nodesToCheck =\n files && files.length > 0\n ? await collectNodesToPreview(files, allCodeConnectObjects, dir, cmd)\n : collectAllLocalNodesToPreview(allCodeConnectObjects, dir, cmd)\n if (!files || files.length === 0) {\n logger.info('Previewing all local Code Connect files...')\n }\n\n if (nodesToCheck.length === 0) {\n exitWithError('No valid Code Connect files found to preview')\n }\n\n logger.info(`Previewing ${nodesToCheck.length} component(s)...`)\n const nodesByFileKey = groupNodesByFileKey(nodesToCheck)\n\n if (cmd.inspect) {\n await handleInspect({\n nodesByFileKey,\n configuredApiUrl,\n accessToken,\n outputFormat,\n })\n return\n }\n\n validatePreviewOptions(cmd)\n const maxCombinations = parseMaxCombinationsArg(cmd.maxCombinations)\n const propsPairs = cmd.props ? parsePropsArg(cmd.props) : undefined\n\n const results: PreviewResult[] = []\n for (const [fileKey, nodes] of Object.entries(nodesByFileKey)) {\n const fileResults = await previewNodesForFile({\n fileKey,\n nodes,\n configuredApiUrl,\n accessToken,\n dir,\n allCodeConnectObjects,\n renderPropertyCombinations: cmd.all || !!propsPairs,\n propsPairs,\n maxCombinations,\n })\n results.push(...fileResults)\n }\n\n await validateRenderedSnippets(results)\n await outputPreviewResults(results, outputFormat)\n\n if (results.every((r) => !r.success)) {\n process.exit(1)\n }\n}\n"]}
1
+ {"version":3,"file":"preview_utils.js","sourceRoot":"","sources":["../../src/commands/preview_utils.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport chalk from 'chalk'\nimport * as prettier from 'prettier'\nimport { BaseCommand, getCodeConnectObjects, getAccessTokenOrExit, setupHandler } from './connect'\nimport { exitWithError, logger } from '../common/logging'\nimport { CodeConnectJSON } from '../connect/figma_connect'\nimport { parseFigmaNode } from '../connect/validation'\nimport { getProjectInfo } from '../connect/project'\nimport { getApiUrl, getHeaders, FigmaRestApi } from '../connect/figma_rest_api'\nimport { request, isFetchError } from '../common/fetch'\nimport { displayPropertyList, type PropertyListItem } from './property_list_table'\nimport {\n enumeratePropertyCombinations,\n buildPropertyCombinationFromProps,\n toAvailableProperties,\n type PropertyCombination,\n type AvailableProperty,\n} from '../connect/property_combinations'\nimport { collapsePreviewResults } from './preview_collapse'\n\ntype PreviewCommand = BaseCommand & { output?: string }\n\nexport interface NodeToPreview {\n fileKey: string\n nodeId: string\n url: string\n filePath: string\n}\n\nexport interface PreviewResult {\n url: string\n nodeId: string\n filePath: string\n success: boolean\n snippet?: string\n language?: string\n component?: string\n error?: string\n /** Present when this result is one property combination of an expanded (--all) render. */\n propertyCombinationLabel?: string\n /**\n * With `--unique`, the labels of all property combinations that produced this\n * identical output (the full `--all` cartesian often collapses to far fewer\n * distinct snippets).\n */\n propertyCombinationLabels?: string[]\n /** With `--unique`, how many property combinations produced this identical output. */\n propertyCombinationCount?: number\n /** `kind: \"transport\"` marks a server/network failure, in which case no property vocabulary is attached. */\n errorDetails?: {\n kind?: string\n missingProperty?: string\n availableProperties?: AvailableProperty[]\n }\n /** Nested instances/slots that rendered as placeholders. Not an error — the snippet still rendered. */\n unresolvedInstances?: Array<{ guid: string; name?: string; kind: 'instance' | 'slot' }>\n}\n\ntype NodesByFileKey = Record<string, NodeToPreview[]>\n\n/**\n * Collect nodes to preview from file arguments.\n * Matches by exact path first, then by basename.\n */\nexport async function collectNodesToPreview(\n files: string[],\n allCodeConnectObjects: CodeConnectJSON[],\n dir: string,\n cmd: BaseCommand,\n): Promise<NodeToPreview[]> {\n const nodesToPreview: NodeToPreview[] = []\n\n for (const filePath of files) {\n const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(dir, filePath)\n\n // Try exact path first\n if (fs.existsSync(resolvedPath) && fs.statSync(resolvedPath).isFile()) {\n const docs = allCodeConnectObjects.filter(\n (d) => path.resolve(d._codeConnectFilePath || '') === resolvedPath,\n )\n if (docs.length > 0) {\n if (docs.length === 1) {\n logger.info(`Found: ${filePath}`)\n } else {\n logger.info(`Found ${docs.length} component definition(s) in ${filePath}`)\n }\n for (const doc of docs) {\n const parsed = parseFigmaNode(cmd.verbose, doc, true)\n if (parsed) {\n nodesToPreview.push({\n fileKey: parsed.fileKey,\n nodeId: parsed.nodeId,\n url: doc.figmaNode,\n filePath: path.relative(dir, doc._codeConnectFilePath || ''),\n })\n } else {\n logger.error(`Failed to parse figmaNode from file: ${filePath}`)\n }\n }\n } else {\n logger.error(`Not a valid Code Connect file: ${filePath}`)\n }\n continue\n }\n\n // Fall back to basename matching\n const fileName = path.basename(filePath)\n if (cmd.verbose) {\n logger.debug(`Searching for files matching: ${fileName}`)\n logger.debug(`Total Code Connect objects: ${allCodeConnectObjects.length}`)\n }\n\n const matches = allCodeConnectObjects.filter(\n (d) => path.basename(d._codeConnectFilePath || '') === fileName,\n )\n\n if (matches.length === 0) {\n logger.error(`No files found matching: ${filePath}`)\n continue\n }\n\n if (matches.length === 1) {\n logger.info(`Found: ${matches[0]._codeConnectFilePath}`)\n } else {\n const uniqueFiles = new Set(matches.map((d) => d._codeConnectFilePath))\n if (uniqueFiles.size === 1) {\n logger.info(\n `Found ${matches.length} component definition(s) in ${path.relative(dir, Array.from(uniqueFiles)[0] || '')}`,\n )\n } else {\n logger.info(`Found ${matches.length} component definition(s) in ${uniqueFiles.size} files:`)\n for (const fp of uniqueFiles) {\n const count = matches.filter((d) => d._codeConnectFilePath === fp).length\n logger.info(\n ` - ${path.relative(dir, fp || '')} (${count} definition${count > 1 ? 's' : ''})`,\n )\n }\n }\n }\n\n for (const doc of matches) {\n const parsed = parseFigmaNode(cmd.verbose, doc, true)\n if (parsed) {\n nodesToPreview.push({\n fileKey: parsed.fileKey,\n nodeId: parsed.nodeId,\n url: doc.figmaNode,\n filePath: path.relative(dir, doc._codeConnectFilePath || ''),\n })\n }\n }\n }\n\n return nodesToPreview\n}\n\n/**\n * Outcome of fetching a component's property definitions.\n * - `ok`: definitions were found (includes VARIANT axes).\n * - `empty`: the node was fetched successfully but exposes no properties/variants\n * (e.g. a component with no variant axes or component properties, or a plain\n * frame). This is not an error — there is simply nothing to vary.\n * - `error`: the fetch failed (network / non-200), e.g. the token is missing a\n * required scope (Code Connect: Write and File content: Read).\n */\nexport type ComponentPropertyDefinitionsResult =\n | { status: 'ok'; defs: Record<string, FigmaRestApi.ComponentPropertyDefinition> }\n | { status: 'empty' }\n | { status: 'error' }\n\n/** A single node's schema plus its parent COMPONENT_SET id (set only for a variant child). */\ntype NodeSchemaResult =\n | {\n status: 'ok'\n defs: Record<string, FigmaRestApi.ComponentPropertyDefinition>\n componentSetId?: string\n }\n | { status: 'empty'; componentSetId?: string }\n | { status: 'error' }\n\n/**\n * Fetch one node's property definitions from the REST `files/:key/nodes` endpoint.\n */\nasync function fetchNodeSchema(\n baseApiUrl: string,\n fileKey: string,\n nodeId: string,\n accessToken: string,\n): Promise<NodeSchemaResult> {\n try {\n const nodesUrl = `${baseApiUrl}/files/${fileKey}/nodes?ids=${nodeId}`\n const resp = await request.get<{\n nodes: Record<\n string,\n {\n document?: {\n componentPropertyDefinitions?: Record<string, FigmaRestApi.ComponentPropertyDefinition>\n }\n // Per-node component metadata; a variant member carries its parent set id here.\n components?: Record<string, { componentSetId?: string }>\n }\n >\n }>(nodesUrl, { headers: getHeaders(accessToken) })\n if (resp.response.status !== 200) {\n logger.debug(`files/nodes returned ${resp.response.status} for ${nodeId}`)\n return { status: 'error' }\n }\n const node = resp.data.nodes?.[nodeId]\n const componentSetId = node?.components?.[nodeId]?.componentSetId || undefined\n const defs = node?.document?.componentPropertyDefinitions\n if (defs && Object.keys(defs).length > 0) return { status: 'ok', defs, componentSetId }\n logger.debug(`files/nodes returned no componentPropertyDefinitions for ${nodeId}`)\n return { status: 'empty', componentSetId }\n } catch (err) {\n const detail = isFetchError(err) ? `status ${err.response?.status}` : String(err)\n logger.debug(`files/nodes fetch failed for ${nodeId} (${detail})`)\n return { status: 'error' }\n }\n}\n\n/**\n * Fetch a component's property definitions from the REST `files/:key/nodes` endpoint.\n */\nexport async function fetchComponentPropertyDefinitions(\n baseApiUrl: string,\n fileKey: string,\n nodeId: string,\n accessToken: string,\n): Promise<ComponentPropertyDefinitionsResult> {\n const node = await fetchNodeSchema(baseApiUrl, fileKey, nodeId, accessToken)\n if (node.status === 'error') return { status: 'error' }\n\n // Variant child → resolve to the parent COMPONENT_SET (whose schema carries the\n // variant axes). Fall back to the variant's own defs if the set can't be fetched.\n if (node.componentSetId) {\n const set = await fetchNodeSchema(baseApiUrl, fileKey, node.componentSetId, accessToken)\n if (set.status === 'ok') return { status: 'ok', defs: set.defs }\n logger.debug(\n `Component set ${node.componentSetId} for variant ${nodeId} had no usable schema ` +\n `(${set.status}); using the variant's own definitions`,\n )\n }\n\n return node.status === 'ok' ? { status: 'ok', defs: node.defs } : { status: 'empty' }\n}\n\n/** Case-insensitive lookup of a `ComponentPropertyType` from a `--props` prefix token. */\nfunction parsePropertyTypePrefix(token: string): FigmaRestApi.ComponentPropertyType | undefined {\n const upper = token.trim().toUpperCase()\n return (Object.values(FigmaRestApi.ComponentPropertyType) as string[]).includes(upper)\n ? (upper as FigmaRestApi.ComponentPropertyType)\n : undefined\n}\n\ntype ParsedPropertyPair = {\n name: string\n value: string\n type?: FigmaRestApi.ComponentPropertyType\n}\n\n/**\n * Parse a single `--props` argument into a name/value pair, with an optional\n * `TYPE:` prefix to disambiguate properties that share a name but differ in\n * type (e.g. a BOOLEAN and a TEXT property both named `textMsg`).\n * Example: --props Variant=Primary \"Has Icon=true\" \"BOOLEAN:textMsg=false\"\n *\n * The prefix is only recognized when the token before the first `:` matches a\n * known property type (case-insensitive); otherwise the whole name-part is kept\n * as the property name, so real names containing `:` are preserved.\n */\nexport function parsePropsArg(props: string[]): ParsedPropertyPair[] {\n return props\n .flatMap((arg) => arg.split(','))\n .map((pair) => pair.trim())\n .filter((pair) => pair.length > 0)\n .map((pair) => {\n const eq = pair.indexOf('=')\n const namePart = (eq === -1 ? pair : pair.slice(0, eq)).trim()\n const value = eq === -1 ? '' : pair.slice(eq + 1).trim()\n\n const colon = namePart.indexOf(':')\n if (colon !== -1) {\n const type = parsePropertyTypePrefix(namePart.slice(0, colon))\n if (type) {\n return { name: namePart.slice(colon + 1).trim(), value, type }\n }\n }\n return { name: namePart, value }\n })\n}\n\n/**\n * Filter templates to only those matching the requested node IDs.\n */\nexport function filterTemplatesForNodes(\n nodeIds: string[],\n allTemplates: CodeConnectJSON[],\n): CodeConnectJSON[] {\n return allTemplates.filter((template) => {\n if (!template.figmaNode) return false\n const nodeIdMatch = template.figmaNode.match(/node-id=([^&\\s]+)/)\n if (!nodeIdMatch?.[1]) return false\n const templateNodeId = nodeIdMatch[1].replace(/-/g, ':')\n return nodeIds.includes(templateNodeId)\n })\n}\n\n/**\n * Aliases for Code Connect labels that don't directly match a Prettier language name.\n */\nconst CC_LABEL_ALIASES: Record<string, string> = {\n react: 'typescript',\n code: 'typescript',\n}\n\n/**\n * Map from Code Connect language labels to Prettier parser names,\n * built lazily from Prettier's getSupportInfo() on first access.\n * Lazy to avoid triggering plugin loading at module import time.\n */\nlet _prettierParserMap: Record<string, string> | null = null\n\nexport function getPrettierParserMap(): Record<string, string> {\n if (_prettierParserMap) return _prettierParserMap\n\n const info = prettier.getSupportInfo() as {\n languages: Array<{ name: string; parsers?: string[] }>\n }\n _prettierParserMap = {}\n\n for (const lang of info.languages) {\n if (lang.parsers?.[0]) {\n _prettierParserMap[lang.name.toLowerCase()] = lang.parsers[0]\n }\n }\n\n for (const [alias, target] of Object.entries(CC_LABEL_ALIASES)) {\n if (_prettierParserMap[target]) {\n _prettierParserMap[alias] = _prettierParserMap[target]\n }\n }\n\n return _prettierParserMap\n}\n\n/**\n * Check if a snippet can be parsed by Prettier.\n * Returns true for languages without a Prettier parser (nothing to validate).\n */\nexport async function isPrettierParseable(snippet: string, language?: string): Promise<boolean> {\n const lang = language?.toLowerCase()\n const parser = lang ? getPrettierParserMap()[lang] : 'typescript'\n\n if (!parser) {\n return true\n }\n\n try {\n await prettier.format(snippet, { parser })\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Format snippet with Prettier.\n * Returns the snippet unmodified for languages Prettier doesn't support.\n */\nexport async function formatSnippet(snippet: string, language?: string): Promise<string> {\n const lang = language?.toLowerCase()\n const parser = lang ? getPrettierParserMap()[lang] : 'typescript'\n\n if (!parser) {\n return snippet\n }\n\n try {\n let formatted = await prettier.format(snippet, {\n parser,\n semi: false,\n singleQuote: true,\n printWidth: 80,\n tabWidth: 2,\n })\n formatted = formatted.replace(/^;\\s*/, '')\n return formatted\n } catch {\n logger.info(`Autoformatting couldn't be applied: language not supported or code is malformed`)\n return snippet\n }\n}\n\n/**\n * Display results with terminal colors\n */\nconst purple = chalk.ansi256(93)\nconst red = chalk.ansi256(196)\nconst gray = chalk.ansi256(243)\nconst yellow = chalk.ansi256(179)\n\nexport function displayResults(results: PreviewResult[]): void {\n console.log('')\n const successCount = results.filter((r) => r.success).length\n const errorCount = results.filter((r) => !r.success).length\n\n // A muted note when nested children rendered as placeholders (not an error).\n const printUnresolved = (result: PreviewResult) => {\n if (!result.unresolvedInstances?.length) return\n const names = result.unresolvedInstances.map((u) => u.name || u.guid).join(', ')\n console.log(\n ` ${yellow(`⚠ ${result.unresolvedInstances.length} nested instance(s) not Code Connected: ${names}`)}`,\n )\n }\n\n for (const result of results) {\n const otherCombinations = (result.propertyCombinationCount ?? 1) - 1\n const moreCombinations =\n otherCombinations > 0\n ? ` (+${otherCombinations} more property combination${otherCombinations > 1 ? 's' : ''})`\n : ''\n const combinationSuffix = result.propertyCombinationLabel\n ? ` ${gray(`— ${result.propertyCombinationLabel}${moreCombinations}`)}`\n : ''\n if (result.success && result.snippet) {\n const componentInfo = result.component ? ` ${gray(`→ ${result.component}`)}` : ''\n console.log(\n `${purple('●')} ${chalk.bold(result.filePath)}${componentInfo}${combinationSuffix}`,\n )\n console.log(` ${gray(result.url)}`)\n console.log('')\n\n const indentedSnippet = result.snippet\n .trim()\n .split('\\n')\n .map((line) => ' ' + line)\n .join('\\n')\n console.log(indentedSnippet)\n printUnresolved(result)\n console.log('')\n } else {\n const componentInfo = result.component ? ` ${gray(`(${result.component})`)}` : ''\n console.log(`${red('✕')} ${chalk.bold(result.filePath)}${componentInfo}${combinationSuffix}`)\n console.log(` ${gray(result.url)}`)\n console.log(` ${red('Error:')} ${result.error}`)\n // One-line repair hint: the offending property and the real vocabulary.\n // (Transport errors carry no vocabulary — nothing to hint.)\n const available = result.errorDetails?.availableProperties?.map((p) => p.name).join(', ')\n const missingProperty = result.errorDetails?.missingProperty\n if (missingProperty && available) {\n console.log(\n ` ${gray(`property \"${missingProperty}\" not found — available: ${available}`)}`,\n )\n } else if (available) {\n console.log(` ${gray(`available properties: ${available}`)}`)\n }\n printUnresolved(result)\n console.log('')\n }\n }\n\n const failed = errorCount > 0 ? red(`${errorCount} failed`) : gray(`${errorCount} failed`)\n console.log(`${chalk.bold('Summary:')} ${purple(`${successCount} succeeded`)}, ${failed}`)\n}\n\n// The server caps inbound request bodies at 5MB. The figmaDocs payload\n// (one Code Connect template per requested component) dominates the body size,\n// so for projects with many components we split into smaller chunks and send\n// them in parallel rather than risking a 413.\nconst PREVIEW_CHUNK_SIZE = 50\n// Bound the number of chunks in flight at once. Without this cap, large\n// libraries (~1k+ components) trigger N parallel preview requests, which\n// overwhelms upstream token validation and causes spurious 403 \"Invalid\n// token\" responses for the chunks that queue up too long.\nconst PREVIEW_MAX_CONCURRENCY = 5\n// Mirrors MAX_PROPERTY_COMBINATIONS_PER_REQUEST in pixie/code_connect_preview_handler.ts.\n// `--all` caps enumeration here and warns rather than sending a request that fails wholesale.\nconst MAX_PROPERTY_COMBINATIONS = 500\n\nexport function parseMaxCombinationsArg(value: string | undefined): number {\n if (value === undefined) {\n return MAX_PROPERTY_COMBINATIONS\n }\n const parsed = Number(value)\n if (!Number.isInteger(parsed) || parsed < 1) {\n exitWithError('--max-combinations must be a positive integer')\n }\n if (parsed > MAX_PROPERTY_COMBINATIONS) {\n exitWithError(`--max-combinations cannot exceed ${MAX_PROPERTY_COMBINATIONS}`)\n }\n return parsed\n}\n\ntype PreviewResponseData = {\n status: number\n error: boolean\n meta: {\n results: Array<{\n nodeId: string\n nodeUrl: string\n snippet?: string\n language?: string\n component?: string\n error?: string\n propertyCombinationLabel?: string\n errorKind?: string\n unresolvedInstances?: Array<{ guid: string; name?: string; kind: 'instance' | 'slot' }>\n }>\n }\n}\n\ntype ChunkOutcome = {\n chunkNodeIds: string[]\n response: Awaited<ReturnType<typeof request.post<PreviewResponseData>>> | null\n error: unknown\n}\n\nfunction chunkArray<T>(arr: T[], size: number): T[][] {\n const chunks: T[][] = []\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size))\n }\n return chunks\n}\n\n/**\n * Split node IDs into request chunks that respect BOTH the node-count cap\n * (PREVIEW_CHUNK_SIZE) and, when rendering property combinations, the server's\n * per-request combination cap (MAX_PROPERTY_COMBINATIONS).\n *\n * The server sums combinations across every node in a request and rejects the\n * whole request if the total exceeds the cap, so bundling by node count alone\n * can push several individually-valid nodes over the limit and fail them all.\n * Each node is already truncated to <= MAX_PROPERTY_COMBINATIONS upstream, so a\n * single node always fits (worst case: one node per chunk).\n */\nexport function chunkNodeIdsForPreview(\n nodeIds: string[],\n propertyCombinationsByNodeId?: Record<string, PropertyCombination[]>,\n): string[][] {\n if (!propertyCombinationsByNodeId) {\n return chunkArray(nodeIds, PREVIEW_CHUNK_SIZE)\n }\n\n const chunks: string[][] = []\n let current: string[] = []\n let currentCombinations = 0\n for (const nodeId of nodeIds) {\n const count = propertyCombinationsByNodeId[nodeId]?.length ?? 0\n // Close the current chunk before adding this node would breach either cap.\n if (\n current.length > 0 &&\n (current.length >= PREVIEW_CHUNK_SIZE ||\n currentCombinations + count > MAX_PROPERTY_COMBINATIONS)\n ) {\n chunks.push(current)\n current = []\n currentCombinations = 0\n }\n current.push(nodeId)\n currentCombinations += count\n }\n if (current.length > 0) chunks.push(current)\n return chunks\n}\n\nasync function runInWaves<T, R>(\n items: T[],\n fn: (item: T) => Promise<R>,\n maxConcurrency: number,\n): Promise<R[]> {\n const out: R[] = []\n for (let i = 0; i < items.length; i += maxConcurrency) {\n const wave = items.slice(i, i + maxConcurrency)\n const settled = await Promise.all(wave.map(fn))\n out.push(...settled)\n }\n return out\n}\n\nfunction sendPreviewChunk({\n chunkNodeIds,\n requiredTemplates,\n baseApiUrl,\n fileKey,\n accessToken,\n propertyCombinationsByNodeId,\n}: {\n chunkNodeIds: string[]\n requiredTemplates: CodeConnectJSON[]\n baseApiUrl: string\n fileKey: string\n accessToken: string\n propertyCombinationsByNodeId?: Record<string, PropertyCombination[]>\n}): Promise<ChunkOutcome> {\n const chunkTemplates = filterTemplatesForNodes(chunkNodeIds, requiredTemplates)\n // Only include property combinations for the node IDs in this chunk.\n let renderCombinations: Record<string, PropertyCombination[]> | undefined\n if (propertyCombinationsByNodeId) {\n renderCombinations = {}\n for (const nodeId of chunkNodeIds) {\n if (propertyCombinationsByNodeId[nodeId]) {\n renderCombinations[nodeId] = propertyCombinationsByNodeId[nodeId]\n }\n }\n }\n return request\n .post<PreviewResponseData>(\n `${baseApiUrl}/code_connect/preview_snippets?file_key=${fileKey}`,\n {\n nodeIds: chunkNodeIds,\n figmaDocs: { all: chunkTemplates },\n ...(renderCombinations && Object.keys(renderCombinations).length > 0\n ? { renderCombinations }\n : {}),\n },\n { headers: getHeaders(accessToken) },\n )\n .then((response) => ({ chunkNodeIds, response, error: null as unknown }))\n .catch((err: unknown) => ({ chunkNodeIds, response: null, error: err }))\n}\n\n/**\n * Parse the offending property name out of a \"property not found\" render error,\n * e.g. `PropertyNotFoundError: property 'Varient' not found` -> `Varient`.\n */\nexport function parseMissingProperty(error?: string): string | undefined {\n if (!error) return undefined\n const match =\n error.match(/propert(?:y|ies)[^'\"`]*['\"`]([^'\"`]+)['\"`]/i) ?? error.match(/['\"`]([^'\"`]+)['\"`]/)\n return match?.[1]\n}\n\n/** Build `errorDetails` for a failed result. Undefined when there's no property context (not --all). */\nfunction buildErrorDetails(\n error: string | undefined,\n errorKind: string | undefined,\n availableProperties: AvailableProperty[] | undefined,\n): PreviewResult['errorDetails'] {\n // Transport failure: network/backend problem, not a bad property — carry only the kind.\n if (errorKind === 'transport') return { kind: 'transport' }\n if (!availableProperties) return undefined\n const details: NonNullable<PreviewResult['errorDetails']> = { availableProperties }\n if (errorKind) details.kind = errorKind\n const missingProperty = parseMissingProperty(error)\n if (missingProperty) details.missingProperty = missingProperty\n return details\n}\n\nexport function chunkOutcomeToResults(\n outcome: ChunkOutcome,\n nodes: NodeToPreview[],\n fileKey: string,\n availablePropsByNodeId?: Record<string, AvailableProperty[]>,\n): PreviewResult[] {\n const { chunkNodeIds, response, error } = outcome\n const results: PreviewResult[] = []\n\n if (error) {\n const errorMsg = isFetchError(error)\n ? error.data?.message || error.response.statusText\n : String(error)\n // 503 means the server-side killswitch is on — surface the server's\n // message directly without the per-file/per-node noise so the user\n // sees a single clear line during an incident.\n if (isFetchError(error) && error.response.status === 503) {\n exitWithError(errorMsg)\n } else {\n logger.error(`Failed to preview components in file ${fileKey}: ${errorMsg}`)\n for (const nodeId of chunkNodeIds) {\n for (const node of nodes.filter((n) => n.nodeId === nodeId)) {\n results.push({\n url: node.url,\n nodeId: node.nodeId,\n filePath: node.filePath,\n success: false,\n error: errorMsg,\n // Chunk-level failure is a server/network error, not a template problem.\n errorDetails: { kind: 'transport' },\n })\n }\n }\n }\n return results\n }\n\n if (response!.response.status === 200 && response!.data.meta?.results) {\n // Track match index per nodeId so duplicate node IDs get the correct file attribution.\n // The server returns results in the same order as the templates we sent. Each chunk's\n // nodeIds are disjoint (we dedupe before chunking), so per-chunk indexing is correct.\n // Property-combination results are expanded renders of one node, not one result per\n // matching template, so they should not consume this per-template index.\n const nodeMatchIndex: Record<string, number> = {}\n for (const result of response!.data.meta.results) {\n const idx = nodeMatchIndex[result.nodeId] ?? 0\n const matchingNodes = nodes.filter((n) => n.nodeId === result.nodeId)\n const node = result.propertyCombinationLabel\n ? matchingNodes[0]\n : matchingNodes[idx] || matchingNodes[0]\n if (!result.propertyCombinationLabel) {\n nodeMatchIndex[result.nodeId] = idx + 1\n }\n const error = result.error || (!result.snippet ? 'No snippet returned by server' : undefined)\n const success = !result.error && !!result.snippet\n results.push({\n url: node?.url || result.nodeUrl,\n nodeId: result.nodeId,\n filePath: node?.filePath || '',\n success,\n snippet: result.snippet,\n language: result.language,\n component: result.component,\n error,\n ...(result.propertyCombinationLabel\n ? { propertyCombinationLabel: result.propertyCombinationLabel }\n : {}),\n ...(result.unresolvedInstances?.length\n ? { unresolvedInstances: result.unresolvedInstances }\n : {}),\n ...(success\n ? {}\n : {\n errorDetails: buildErrorDetails(\n error,\n result.errorKind,\n availablePropsByNodeId?.[result.nodeId],\n ),\n }),\n })\n }\n return results\n }\n\n for (const nodeId of chunkNodeIds) {\n for (const node of nodes.filter((n) => n.nodeId === nodeId)) {\n const error = `API request failed with status ${response!.response.status}`\n results.push({\n url: node.url,\n nodeId: node.nodeId,\n filePath: node.filePath,\n success: false,\n error,\n // Non-2xx from the endpoint is a transport-level failure, not a template problem.\n errorDetails: { kind: 'transport' },\n })\n }\n }\n return results\n}\n\nasync function previewFile({\n fileKey,\n nodes,\n baseApiUrl,\n accessToken,\n dir,\n allCodeConnectObjects,\n propertyCombinationsByNodeId,\n availablePropsByNodeId,\n}: {\n fileKey: string\n nodes: NodeToPreview[]\n baseApiUrl: string\n accessToken: string\n dir: string\n allCodeConnectObjects: CodeConnectJSON[]\n propertyCombinationsByNodeId?: Record<string, PropertyCombination[]>\n availablePropsByNodeId?: Record<string, AvailableProperty[]>\n}): Promise<PreviewResult[]> {\n const allNodeIds = nodes.map((n) => n.nodeId)\n // Deduplicate — multiple figma.connect() calls may share the same nodeId;\n // the individual templates are sent in figmaDocs and the server iterates per-template.\n const nodeIds = [...new Set(allNodeIds)]\n\n // Only send templates from the requested files — other files' templates\n // for the same nodeId exist on the server and shouldn't be rendered individually.\n const requestedFilePaths = new Set(nodes.map((n) => path.resolve(dir, n.filePath)))\n const requiredTemplates = filterTemplatesForNodes(allNodeIds, allCodeConnectObjects).filter((t) =>\n requestedFilePaths.has(path.resolve(t._codeConnectFilePath || '')),\n )\n\n const chunks = chunkNodeIdsForPreview(nodeIds, propertyCombinationsByNodeId)\n const outcomes = await runInWaves(\n chunks,\n (chunkNodeIds) =>\n sendPreviewChunk({\n chunkNodeIds,\n requiredTemplates,\n baseApiUrl,\n fileKey,\n accessToken,\n propertyCombinationsByNodeId,\n }),\n PREVIEW_MAX_CONCURRENCY,\n )\n\n return outcomes.flatMap((outcome) =>\n chunkOutcomeToResults(outcome, nodes, fileKey, availablePropsByNodeId),\n )\n}\n\nfunction collectAllLocalNodesToPreview(\n allCodeConnectObjects: CodeConnectJSON[],\n dir: string,\n cmd: BaseCommand,\n): NodeToPreview[] {\n const nodesToCheck: NodeToPreview[] = []\n for (const doc of allCodeConnectObjects) {\n const parsed = parseFigmaNode(cmd.verbose, doc, true)\n if (parsed) {\n nodesToCheck.push({\n fileKey: parsed.fileKey,\n nodeId: parsed.nodeId,\n url: doc.figmaNode,\n filePath: path.relative(dir, doc._codeConnectFilePath || ''),\n })\n }\n }\n return nodesToCheck\n}\n\nfunction groupNodesByFileKey(nodes: NodeToPreview[]): NodesByFileKey {\n const nodesByFileKey: NodesByFileKey = {}\n for (const node of nodes) {\n nodesByFileKey[node.fileKey] ??= []\n nodesByFileKey[node.fileKey].push(node)\n }\n return nodesByFileKey\n}\n\nasync function handleInspect({\n nodesByFileKey,\n configuredApiUrl,\n accessToken,\n outputFormat,\n}: {\n nodesByFileKey: NodesByFileKey\n configuredApiUrl?: string\n accessToken: string\n outputFormat: string\n}): Promise<void> {\n const items: PropertyListItem[] = []\n const seen = new Set<string>()\n for (const [fileKey, nodes] of Object.entries(nodesByFileKey)) {\n const baseApiUrl = getApiUrl(nodes[0].url, configuredApiUrl)\n for (const node of nodes) {\n const dedupeKey = `${node.filePath}::${node.nodeId}`\n if (seen.has(dedupeKey)) continue\n seen.add(dedupeKey)\n const result = await fetchComponentPropertyDefinitions(\n baseApiUrl,\n fileKey,\n node.nodeId,\n accessToken,\n )\n if (result.status === 'error') {\n logger.warn(`Couldn't fetch property definitions for node ${node.nodeId}`)\n } else if (result.status === 'empty') {\n logger.info(`Node ${node.nodeId} has no component properties or variants.`)\n }\n items.push({\n filePath: node.filePath,\n nodeId: node.nodeId,\n availableProperties: result.status === 'ok' ? toAvailableProperties(result.defs) : [],\n })\n }\n }\n\n if (outputFormat === 'json') {\n console.log(JSON.stringify(items, null, 2))\n } else {\n displayPropertyList(items)\n }\n}\n\n/**\n * `--unique` implies `--all`, so errors about combination expansion should name\n * the flag the user actually typed rather than the one commander set on their\n * behalf.\n */\nfunction expandFlagName(cmd: PreviewCommand): '--all' | '--unique' {\n return cmd.unique ? '--unique' : '--all'\n}\n\nexport function validatePreviewOptions(cmd: PreviewCommand): void {\n if (cmd.all && cmd.props) {\n const implied = cmd.unique ? ' (which implies --all)' : ''\n exitWithError(\n `Cannot combine --props and ${expandFlagName(cmd)}${implied}; use one or the other`,\n )\n }\n\n if (cmd.maxCombinations !== undefined && !cmd.all) {\n exitWithError('--max-combinations can only be used with --all or --unique')\n }\n}\n\nasync function buildPropertyPreviewInputs({\n enabled,\n baseApiUrl,\n fileKey,\n nodes,\n accessToken,\n propsPairs,\n maxCombinations,\n}: {\n enabled: boolean\n baseApiUrl: string\n fileKey: string\n nodes: NodeToPreview[]\n accessToken: string\n propsPairs?: ParsedPropertyPair[]\n maxCombinations: number\n}): Promise<{\n propertyCombinationsByNodeId?: Record<string, PropertyCombination[]>\n availablePropsByNodeId?: Record<string, AvailableProperty[]>\n}> {\n if (!enabled) return {}\n\n const propertyCombinationsByNodeId: Record<string, PropertyCombination[]> = {}\n const availablePropsByNodeId: Record<string, AvailableProperty[]> = {}\n for (const nodeId of [...new Set(nodes.map((n) => n.nodeId))]) {\n const result = await fetchComponentPropertyDefinitions(baseApiUrl, fileKey, nodeId, accessToken)\n if (result.status === 'error') {\n logger.warn(\n `Couldn't fetch property definitions for node ${nodeId} (ensure your token has the ` +\n `Code Connect: Write and File content: Read scopes); rendering its default property combination only`,\n )\n continue\n }\n if (result.status === 'empty') {\n // Not an error: the component simply has no properties or variants to vary.\n if (propsPairs) {\n logger.warn(\n `Node ${nodeId} has no component properties or variants, so --props ` +\n `(${propsPairs.map((p) => p.name).join(', ')}) has no effect; rendering its only property combination.`,\n )\n } else {\n logger.info(\n `Node ${nodeId} has no component properties or variants to vary; rendering its only property combination.`,\n )\n }\n continue\n }\n\n const defs = result.defs\n if (propsPairs) {\n const { propertyCombination, availableProperties, unknown, invalid, ambiguous } =\n buildPropertyCombinationFromProps(defs, propsPairs)\n if (unknown.length > 0) {\n logger.warn(\n `Unknown propert${unknown.length > 1 ? 'ies' : 'y'} for node ${nodeId}: ${unknown.join(', ')}. ` +\n `Available: ${availableProperties.map((p) => p.name).join(', ')}`,\n )\n }\n for (const { name, value, options } of invalid) {\n logger.warn(\n `\"${value}\" is not a valid value for ${name} on node ${nodeId}. Options: ${options.join(', ')}`,\n )\n }\n for (const { name, types } of ambiguous) {\n logger.warn(\n `Property \"${name}\" on node ${nodeId} matches multiple types (${types.join(', ')}); ` +\n `prefix the value with a type to disambiguate, e.g. ${types[0]}:${name}=... . Skipping.`,\n )\n }\n availablePropsByNodeId[nodeId] = availableProperties\n propertyCombinationsByNodeId[nodeId] = [propertyCombination]\n } else {\n const { propertyCombinations, availableProperties, truncated } =\n enumeratePropertyCombinations(defs, {\n maxCombinations,\n })\n availablePropsByNodeId[nodeId] = availableProperties\n if (truncated) {\n logger.warn(\n `Node ${nodeId} has ${truncated.total} property combinations, exceeding the ${truncated.cap}-combination ` +\n `preview limit; rendering the first ${truncated.cap}. Use --props to preview a ` +\n `specific property combination.`,\n )\n }\n if (propertyCombinations.length > 0) {\n propertyCombinationsByNodeId[nodeId] = propertyCombinations\n }\n }\n }\n\n return { propertyCombinationsByNodeId, availablePropsByNodeId }\n}\n\nasync function previewNodesForFile({\n fileKey,\n nodes,\n configuredApiUrl,\n accessToken,\n dir,\n allCodeConnectObjects,\n renderPropertyCombinations,\n propsPairs,\n maxCombinations,\n}: {\n fileKey: string\n nodes: NodeToPreview[]\n configuredApiUrl?: string\n accessToken: string\n dir: string\n allCodeConnectObjects: CodeConnectJSON[]\n renderPropertyCombinations: boolean\n propsPairs?: ParsedPropertyPair[]\n maxCombinations: number\n}): Promise<PreviewResult[]> {\n const baseApiUrl = getApiUrl(nodes[0].url, configuredApiUrl)\n const { propertyCombinationsByNodeId, availablePropsByNodeId } = await buildPropertyPreviewInputs(\n {\n enabled: renderPropertyCombinations,\n baseApiUrl,\n fileKey,\n nodes,\n accessToken,\n propsPairs,\n maxCombinations,\n },\n )\n\n return previewFile({\n fileKey,\n nodes,\n baseApiUrl,\n accessToken,\n dir,\n allCodeConnectObjects,\n propertyCombinationsByNodeId,\n availablePropsByNodeId,\n })\n}\n\nasync function validateRenderedSnippets(results: PreviewResult[]): Promise<void> {\n for (const result of results) {\n if (result.success && result.snippet) {\n const prettierValid = await isPrettierParseable(result.snippet, result.language)\n if (!prettierValid) {\n // Prettier can parse this language but failed — mark as error\n result.success = false\n result.error = 'Snippet has syntax errors and may not be valid code'\n }\n }\n }\n}\n\nasync function outputPreviewResults(results: PreviewResult[], outputFormat: string): Promise<void> {\n if (outputFormat === 'json') {\n console.log(JSON.stringify(results, null, 2))\n return\n }\n\n const formattedResults: PreviewResult[] = await Promise.all(\n results.map(async (result) => {\n if (result.success && result.snippet) {\n const formattedSnippet = await formatSnippet(result.snippet, result.language)\n return { ...result, snippet: formattedSnippet }\n }\n return result\n }),\n )\n displayResults(formattedResults)\n}\n\n/**\n * Handle the preview command\n */\nexport async function handlePreview(files: string[], cmd: PreviewCommand) {\n setupHandler(cmd)\n\n const dir = cmd.dir ?? process.cwd()\n const projectInfo = await getProjectInfo(dir, cmd.config)\n const accessToken = getAccessTokenOrExit(cmd)\n const outputFormat = cmd.output || 'table'\n const configuredApiUrl = cmd.apiUrl || projectInfo.config.apiUrl\n\n if (cmd.all && (!files || files.length === 0)) {\n const flag = expandFlagName(cmd)\n exitWithError(\n `${flag} requires a specific component, e.g. \\`figma connect preview Button.figma.ts ${flag}\\``,\n )\n }\n\n const allCodeConnectObjects = await getCodeConnectObjects(cmd, projectInfo, true)\n\n const nodesToCheck =\n files && files.length > 0\n ? await collectNodesToPreview(files, allCodeConnectObjects, dir, cmd)\n : collectAllLocalNodesToPreview(allCodeConnectObjects, dir, cmd)\n if (!files || files.length === 0) {\n logger.info('Previewing all local Code Connect files...')\n }\n\n if (nodesToCheck.length === 0) {\n exitWithError('No valid Code Connect files found to preview')\n }\n\n logger.info(`Previewing ${nodesToCheck.length} component(s)...`)\n const nodesByFileKey = groupNodesByFileKey(nodesToCheck)\n\n if (cmd.inspect) {\n await handleInspect({\n nodesByFileKey,\n configuredApiUrl,\n accessToken,\n outputFormat,\n })\n return\n }\n\n validatePreviewOptions(cmd)\n const maxCombinations = parseMaxCombinationsArg(cmd.maxCombinations)\n const propsPairs = cmd.props ? parsePropsArg(cmd.props) : undefined\n\n const results: PreviewResult[] = []\n for (const [fileKey, nodes] of Object.entries(nodesByFileKey)) {\n const fileResults = await previewNodesForFile({\n fileKey,\n nodes,\n configuredApiUrl,\n accessToken,\n dir,\n allCodeConnectObjects,\n renderPropertyCombinations: cmd.all || !!propsPairs,\n propsPairs,\n maxCombinations,\n })\n results.push(...fileResults)\n }\n\n await validateRenderedSnippets(results)\n\n const outputResults = cmd.unique ? collapsePreviewResults(results) : results\n if (cmd.unique && outputResults.length !== results.length) {\n logger.info(\n `${outputResults.length} distinct of ${results.length} rendered property combinations`,\n )\n }\n\n await outputPreviewResults(outputResults, outputFormat)\n\n if (outputResults.every((r) => !r.success)) {\n process.exit(1)\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"raw_templates.d.ts","sourceRoot":"","sources":["../../src/connect/raw_templates.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAY7C;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAatD;AA2JD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9B,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,CAAC,EAAE,iBAAiB,EAC1B,GAAG,CAAC,EAAE,MAAM,EACZ,cAAc,CAAC,EAAE,cAAc,GAC9B,OAAO,CAAC,eAAe,CAAC,CA+G1B"}
1
+ {"version":3,"file":"raw_templates.d.ts","sourceRoot":"","sources":["../../src/connect/raw_templates.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAY7C;;;;;;GAMG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAatD;AA6JD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC9B,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,CAAC,EAAE,iBAAiB,EAC1B,GAAG,CAAC,EAAE,MAAM,EACZ,cAAc,CAAC,EAAE,cAAc,GAC9B,OAAO,CAAC,eAAe,CAAC,CA+G1B"}
@@ -46,8 +46,9 @@ function isRawTemplate(content) {
46
46
  }
47
47
  return false;
48
48
  }
49
- // Convert ESM import of 'figma' to require syntax. Supports: import figma from 'figma'
50
- const figmaImportRegex = /^import\s+figma\s+from\s+['"]figma['"]\s*;?\s*$/m;
49
+ // Convert the supported ESM Figma import to the runtime's require syntax when
50
+ // the template does not otherwise need bundling.
51
+ const figmaImportRegex = /^import[ \t]+figma[ \t]+from[ \t]+['"]figma['"][ \t]*;?[ \t]*(?:\/\/[^\r\n]*)?$/m;
51
52
  // Matches the backend's max template size; we fail here rather than let the
52
53
  // server reject the publish request.
53
54
  const MAX_TEMPLATE_SIZE_MB = 1;
@@ -66,9 +67,9 @@ function isRawTemplateSourceFile(filePath) {
66
67
  /**
67
68
  * Validates a template entry's imports: only the default `figma` import,
68
69
  * type-only imports and relative helper imports are allowed. Returns whether
69
- * the entry imports helpers, so the caller knows whether to bundle.
70
+ * the entry imports helpers, so the caller knows whether to bundle it.
70
71
  */
71
- function validateTypeScriptTemplateImports(filePath, fileContent) {
72
+ function validateTemplateImports(filePath, fileContent) {
72
73
  const sourceFile = typescript_1.default.createSourceFile(filePath, fileContent, typescript_1.default.ScriptTarget.Latest, true);
73
74
  let hasRelativeHelperImports = false;
74
75
  for (const statement of sourceFile.statements) {
@@ -118,10 +119,10 @@ function validateTypeScriptTemplateImports(filePath, fileContent) {
118
119
  visitRequire(sourceFile);
119
120
  return { hasRelativeHelperImports };
120
121
  }
121
- function transpileTypeScriptTemplate(filePath, fileContent) {
122
- if (figmaImportRegex.test(fileContent)) {
123
- fileContent = fileContent.replace(figmaImportRegex, "const figma = require('figma')");
124
- }
122
+ function rewriteFigmaImport(fileContent) {
123
+ return fileContent.replace(figmaImportRegex, "const figma = require('figma')");
124
+ }
125
+ function transpileTypeScriptTemplate(fileContent) {
125
126
  const result = typescript_1.default.transpileModule(fileContent, {
126
127
  compilerOptions: {
127
128
  module: typescript_1.default.ModuleKind.ESNext,
@@ -168,7 +169,7 @@ function extractMetadataFields(fileContent) {
168
169
  }
169
170
  async function parseRawFile(filePath, label, config, dir, batchOverrides) {
170
171
  let fileContent = fs_1.default.readFileSync(filePath, 'utf-8');
171
- let shouldBundleTypeScriptTemplate = false;
172
+ let shouldBundleTemplate = false;
172
173
  // Extract metadata fields BEFORE transpilation to avoid losing comments
173
174
  // that appear before type-only imports (which TypeScript erases)
174
175
  const { fields, templateStartLine } = extractMetadataFields(fileContent);
@@ -176,7 +177,7 @@ async function parseRawFile(filePath, label, config, dir, batchOverrides) {
176
177
  // Validate imports first, before the `codeProperties` skip guard below, so an
177
178
  // unsupported import is always a hard error rather than silently swallowed.
178
179
  if (isRawTemplateSourceFile(filePath)) {
179
- shouldBundleTypeScriptTemplate = validateTypeScriptTemplateImports(filePath, fileContent).hasRelativeHelperImports;
180
+ shouldBundleTemplate = validateTemplateImports(filePath, fileContent).hasRelativeHelperImports;
180
181
  }
181
182
  // A file with no // url= directive that contains the string `codeProperties`
182
183
  // is not Code Connect (e.g. Make's code component property definitions). Skip
@@ -185,15 +186,18 @@ async function parseRawFile(filePath, label, config, dir, batchOverrides) {
185
186
  if (!figmaUrl && fileContent.includes('codeProperties')) {
186
187
  throw new CodePropertiesError(`Skipping ${filePath}: file has no // url= directive and contains "codeProperties", so it is not treated as a Code Connect file.`);
187
188
  }
188
- // Bundle when helpers are present; otherwise transpile TS and emit JS verbatim.
189
- // Bundling takes some extra time.
190
- if (shouldBundleTypeScriptTemplate) {
189
+ // Bundle templates with helper imports. Helper-free templates stay on the
190
+ // faster path and rewrite the Figma import directly to require syntax.
191
+ if (shouldBundleTemplate) {
191
192
  // Confining resolution to the project dir
192
193
  const projectRoot = dir ? path_1.default.resolve(dir) : path_1.default.dirname(path_1.default.resolve(filePath));
193
194
  fileContent = await (0, raw_template_bundler_1.bundleTemplateWithHelpers)(filePath, projectRoot);
194
195
  }
195
- else if (filePath.endsWith('.ts')) {
196
- fileContent = transpileTypeScriptTemplate(filePath, fileContent);
196
+ else {
197
+ fileContent = rewriteFigmaImport(fileContent);
198
+ if (filePath.endsWith('.ts')) {
199
+ fileContent = transpileTypeScriptTemplate(fileContent);
200
+ }
197
201
  }
198
202
  // For batch templates, metadata comes from the batch entry instead of comments
199
203
  const component = batchOverrides?.component || fields.component;
@@ -1 +1 @@
1
- {"version":3,"file":"raw_templates.js","sourceRoot":"","sources":["../../src/connect/raw_templates.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport ts from 'typescript'\nimport { CodeConnectJSON } from './figma_connect'\nimport { CodeConnectConfig } from './project'\nimport { CodeConnectLabel, getInferredLanguageForRaw } from './label_language_mapping'\nimport { applyDocumentUrlSubstitutions } from './helpers'\nimport {\n bundleTemplateWithHelpers,\n allowedHelperExtensions,\n isRelativeImportPath,\n unsupportedImportError,\n relativeRequireError,\n getRequireCallRequest,\n} from './raw_template_bundler'\n\n/**\n * Thrown when a raw template file has no `// url=` directive but contains the\n * string `codeProperties`. These files (e.g. Make's code component property\n * definitions) are not Code Connect, so callers skip them with a log instead of\n * failing. Every other file is handled exactly as before — a missing url is\n * still a hard error.\n */\nexport class CodePropertiesError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'CodePropertiesError'\n }\n}\n\n/**\n * Returns true if the file content looks like a raw template file, i.e. its\n * leading comment block contains a `// url=`, `// component=`, or `// source=`\n * directive. Used to distinguish raw `.figma.ts` templates from React/HTML\n * Code Connect files that share the same extension.\n */\nexport function isRawTemplate(content: string): boolean {\n for (const line of content.split('\\n')) {\n const trimmed = line.trim()\n if (trimmed === '' || trimmed.startsWith('//')) {\n if (/^\\/\\/\\s*(url|component|source)=/.test(trimmed)) {\n return true\n }\n continue\n }\n // First non-comment, non-blank line reached without finding a known directive — not a raw template\n break\n }\n return false\n}\n\n// Convert ESM import of 'figma' to require syntax. Supports: import figma from 'figma'\nconst figmaImportRegex = /^import\\s+figma\\s+from\\s+['\"]figma['\"]\\s*;?\\s*$/m\n\n// Matches the backend's max template size; we fail here rather than let the\n// server reject the publish request.\nconst MAX_TEMPLATE_SIZE_MB = 1\n\nfunction assertTemplateWithinSizeLimit(filePath: string, template: string): void {\n const sizeMb = Buffer.byteLength(template, 'utf-8') / (1024 * 1024)\n if (sizeMb > MAX_TEMPLATE_SIZE_MB) {\n throw new Error(\n `Template \"${filePath}\" is ${sizeMb.toFixed(2)}mb, which exceeds the ` +\n `${MAX_TEMPLATE_SIZE_MB}mb maximum template size. ` +\n `Reduce the template size, for example by removing unneeded helper imports.`,\n )\n }\n}\n\ninterface TypeScriptImportValidationResult {\n hasRelativeHelperImports: boolean\n}\n\n// Parserless entry templates may be authored in TypeScript or JavaScript.\nfunction isRawTemplateSourceFile(filePath: string): boolean {\n return allowedHelperExtensions.some((ext) => filePath.endsWith(ext))\n}\n\n/**\n * Validates a template entry's imports: only the default `figma` import,\n * type-only imports and relative helper imports are allowed. Returns whether\n * the entry imports helpers, so the caller knows whether to bundle.\n */\nfunction validateTypeScriptTemplateImports(\n filePath: string,\n fileContent: string,\n): TypeScriptImportValidationResult {\n const sourceFile = ts.createSourceFile(filePath, fileContent, ts.ScriptTarget.Latest, true)\n let hasRelativeHelperImports = false\n\n for (const statement of sourceFile.statements) {\n if (ts.isImportDeclaration(statement)) {\n if (statement.importClause?.isTypeOnly) {\n continue\n }\n\n const moduleSpecifierText = ts.isStringLiteral(statement.moduleSpecifier)\n ? statement.moduleSpecifier.text\n : ''\n const importLine = statement.getText(sourceFile).split('\\n')[0]?.trim() ?? 'import ...'\n\n if (moduleSpecifierText === 'figma') {\n const hasDefaultImport = !!statement.importClause?.name\n const hasNamedOrNamespaceImport = !!statement.importClause?.namedBindings\n if (!hasDefaultImport || hasNamedOrNamespaceImport) {\n throw unsupportedImportError(filePath, importLine)\n }\n continue\n }\n\n if (isRelativeImportPath(moduleSpecifierText)) {\n hasRelativeHelperImports = true\n continue\n }\n\n throw unsupportedImportError(filePath, importLine)\n }\n\n // Re-exports aren't supported: the runtime only reads the default export.\n if (ts.isExportDeclaration(statement) && statement.moduleSpecifier && !statement.isTypeOnly) {\n const exportLine = statement.getText(sourceFile).split('\\n')[0]?.trim() ?? 'export ...'\n throw new Error(\n `Template files do not support re-exports ('export ... from ...').\\n` +\n `Found in ${filePath}:\\n` +\n ` ${exportLine}\\n\\n` +\n `Import the helper instead (for example: import { helper } from './helpers').`,\n )\n }\n }\n\n // `require` is for the Figma API only: a pure ESM graph is what lets the\n // bundler emit a flat, tree-shaken template. Walking the AST (not the raw\n // text) keeps a `require(...)` inside an emitted snippet from matching.\n const visitRequire = (node: ts.Node): void => {\n const request = getRequireCallRequest(node)\n if (request && request !== 'figma') {\n throw isRelativeImportPath(request)\n ? relativeRequireError(filePath, request)\n : unsupportedImportError(filePath, `require('${request}')`)\n }\n ts.forEachChild(node, visitRequire)\n }\n visitRequire(sourceFile)\n\n return { hasRelativeHelperImports }\n}\n\nfunction transpileTypeScriptTemplate(filePath: string, fileContent: string): string {\n if (figmaImportRegex.test(fileContent)) {\n fileContent = fileContent.replace(figmaImportRegex, \"const figma = require('figma')\")\n }\n\n const result = ts.transpileModule(fileContent, {\n compilerOptions: {\n module: ts.ModuleKind.ESNext,\n target: ts.ScriptTarget.ES2021,\n removeComments: false,\n },\n })\n\n return result.outputText\n}\n\n/**\n * Extracts metadata fields (url, component, source) from the leading comments\n * of a raw template file. This must be done before transpilation because\n * TypeScript can remove comments that appear before type-only imports.\n */\nfunction extractMetadataFields(fileContent: string): {\n fields: { url?: string; component?: string; source?: string }\n templateStartLine: number\n} {\n const lines = fileContent.split('\\n')\n const fields: { url?: string; component?: string; source?: string } = {}\n let templateStartLine = 0\n\n // Parse consecutive comment lines at the start of the file\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim()\n // Match pattern: // fieldName=value\n const match = line.match(/^\\/\\/\\s*(\\w+)=(.+)$/)\n if (match) {\n const [, fieldName, fieldValue] = match\n const normalizedFieldName = fieldName.toLowerCase()\n if (\n normalizedFieldName === 'url' ||\n normalizedFieldName === 'component' ||\n normalizedFieldName === 'source'\n ) {\n fields[normalizedFieldName] = fieldValue.trim()\n }\n templateStartLine = i + 1\n } else if (line === '' || line.startsWith('//')) {\n // Allow blank lines or other comments, but don't increment template start\n continue\n } else {\n // First non-comment line found\n break\n }\n }\n\n return { fields, templateStartLine }\n}\n\nexport interface BatchOverrides {\n url: string\n source?: string\n component?: string\n batchData: Record<string, any>\n batchFilePath: string\n}\n\nexport async function parseRawFile(\n filePath: string,\n label: string | undefined,\n config?: CodeConnectConfig,\n dir?: string,\n batchOverrides?: BatchOverrides,\n): Promise<CodeConnectJSON> {\n let fileContent = fs.readFileSync(filePath, 'utf-8')\n let shouldBundleTypeScriptTemplate = false\n\n // Extract metadata fields BEFORE transpilation to avoid losing comments\n // that appear before type-only imports (which TypeScript erases)\n const { fields, templateStartLine } = extractMetadataFields(fileContent)\n\n const figmaUrl = batchOverrides?.url || fields.url\n\n // Validate imports first, before the `codeProperties` skip guard below, so an\n // unsupported import is always a hard error rather than silently swallowed.\n if (isRawTemplateSourceFile(filePath)) {\n shouldBundleTypeScriptTemplate = validateTypeScriptTemplateImports(\n filePath,\n fileContent,\n ).hasRelativeHelperImports\n }\n\n // A file with no // url= directive that contains the string `codeProperties`\n // is not Code Connect (e.g. Make's code component property definitions). Skip\n // it (callers log and continue) instead of failing. Every other file is\n // handled exactly as before.\n if (!figmaUrl && fileContent.includes('codeProperties')) {\n throw new CodePropertiesError(\n `Skipping ${filePath}: file has no // url= directive and contains \"codeProperties\", so it is not treated as a Code Connect file.`,\n )\n }\n\n // Bundle when helpers are present; otherwise transpile TS and emit JS verbatim.\n // Bundling takes some extra time.\n if (shouldBundleTypeScriptTemplate) {\n // Confining resolution to the project dir\n const projectRoot = dir ? path.resolve(dir) : path.dirname(path.resolve(filePath))\n fileContent = await bundleTemplateWithHelpers(filePath, projectRoot)\n } else if (filePath.endsWith('.ts')) {\n fileContent = transpileTypeScriptTemplate(filePath, fileContent)\n }\n\n // For batch templates, metadata comes from the batch entry instead of comments\n const component = batchOverrides?.component || fields.component\n const source = batchOverrides?.source || fields.source || ''\n\n if (!figmaUrl) {\n throw new Error(\n batchOverrides\n ? `Missing required \"url\" field in ${batchOverrides.batchFilePath}. Please add \"url\" to each entry in your .figma.batch.json file.`\n : `Missing required url field in ${filePath}. Please add a // url=... comment to the top of the file.`,\n )\n }\n let figmaNodeUrl = figmaUrl\n\n // Extract template from the transpiled content, starting at the line\n // where the metadata comments ended in the original source\n const transpiledLines = fileContent.split('\\n')\n let templateStartIndex = 0\n\n // Skip lines until we've passed the original metadata comment section\n for (let i = 0; i < transpiledLines.length; i++) {\n const line = transpiledLines[i].trim()\n // Skip blank lines and comments at the start\n if (line === '' || line.startsWith('//')) {\n continue\n }\n // First non-comment line in transpiled output\n templateStartIndex = i\n break\n }\n\n let template = transpiledLines.slice(templateStartIndex).join('\\n')\n\n // For batch templates, set globalThis['__FIGMA_BATCH'] so the runtime exposes it as\n // figma.batch. Using globalThis rather than a const so it's accessible from\n // __FIGMA_CODE_CONNECT_REQUIRE's closure regardless of where require('figma') is called.\n // (globalThis works in both browser and Node.js, unlike window.)\n if (batchOverrides) {\n template = `globalThis['__FIGMA_BATCH'] = ${JSON.stringify(\n batchOverrides.batchData,\n )}\\n${template}`\n }\n\n // Check the final template (incl. any bundled helpers and batch data) against\n // the backend's size cap so an oversized template fails here, not on upload.\n assertTemplateWithinSizeLimit(filePath, template)\n\n // Apply documentUrlSubstitutions if provided\n if (config?.documentUrlSubstitutions) {\n figmaNodeUrl = applyDocumentUrlSubstitutions(figmaNodeUrl, config.documentUrlSubstitutions)\n }\n\n // Determine effective label from parameter, config, or default\n const effectiveLabel = label || config?.label || CodeConnectLabel.Code\n\n const language = config?.language || getInferredLanguageForRaw(effectiveLabel)\n\n return {\n figmaNode: figmaNodeUrl,\n component,\n template,\n // nestable by default unless user specifies in template\n // (templateData.nestable AND template.metadata.nestable need to\n // be true for instance to be nested)\n templateData: { nestable: true, isParserless: true },\n language,\n label: effectiveLabel,\n source,\n sourceLocation: { line: -1 },\n metadata: {\n cliVersion: require('../../package.json').version,\n },\n }\n}\n"]}
1
+ {"version":3,"file":"raw_templates.js","sourceRoot":"","sources":["../../src/connect/raw_templates.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from 'fs'\nimport path from 'path'\nimport ts from 'typescript'\nimport { CodeConnectJSON } from './figma_connect'\nimport { CodeConnectConfig } from './project'\nimport { CodeConnectLabel, getInferredLanguageForRaw } from './label_language_mapping'\nimport { applyDocumentUrlSubstitutions } from './helpers'\nimport {\n bundleTemplateWithHelpers,\n allowedHelperExtensions,\n isRelativeImportPath,\n unsupportedImportError,\n relativeRequireError,\n getRequireCallRequest,\n} from './raw_template_bundler'\n\n/**\n * Thrown when a raw template file has no `// url=` directive but contains the\n * string `codeProperties`. These files (e.g. Make's code component property\n * definitions) are not Code Connect, so callers skip them with a log instead of\n * failing. Every other file is handled exactly as before — a missing url is\n * still a hard error.\n */\nexport class CodePropertiesError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'CodePropertiesError'\n }\n}\n\n/**\n * Returns true if the file content looks like a raw template file, i.e. its\n * leading comment block contains a `// url=`, `// component=`, or `// source=`\n * directive. Used to distinguish raw `.figma.ts` templates from React/HTML\n * Code Connect files that share the same extension.\n */\nexport function isRawTemplate(content: string): boolean {\n for (const line of content.split('\\n')) {\n const trimmed = line.trim()\n if (trimmed === '' || trimmed.startsWith('//')) {\n if (/^\\/\\/\\s*(url|component|source)=/.test(trimmed)) {\n return true\n }\n continue\n }\n // First non-comment, non-blank line reached without finding a known directive — not a raw template\n break\n }\n return false\n}\n\n// Convert the supported ESM Figma import to the runtime's require syntax when\n// the template does not otherwise need bundling.\nconst figmaImportRegex =\n /^import[ \\t]+figma[ \\t]+from[ \\t]+['\"]figma['\"][ \\t]*;?[ \\t]*(?:\\/\\/[^\\r\\n]*)?$/m\n\n// Matches the backend's max template size; we fail here rather than let the\n// server reject the publish request.\nconst MAX_TEMPLATE_SIZE_MB = 1\n\nfunction assertTemplateWithinSizeLimit(filePath: string, template: string): void {\n const sizeMb = Buffer.byteLength(template, 'utf-8') / (1024 * 1024)\n if (sizeMb > MAX_TEMPLATE_SIZE_MB) {\n throw new Error(\n `Template \"${filePath}\" is ${sizeMb.toFixed(2)}mb, which exceeds the ` +\n `${MAX_TEMPLATE_SIZE_MB}mb maximum template size. ` +\n `Reduce the template size, for example by removing unneeded helper imports.`,\n )\n }\n}\n\ninterface TemplateImportValidationResult {\n hasRelativeHelperImports: boolean\n}\n\n// Parserless entry templates may be authored in TypeScript or JavaScript.\nfunction isRawTemplateSourceFile(filePath: string): boolean {\n return allowedHelperExtensions.some((ext) => filePath.endsWith(ext))\n}\n\n/**\n * Validates a template entry's imports: only the default `figma` import,\n * type-only imports and relative helper imports are allowed. Returns whether\n * the entry imports helpers, so the caller knows whether to bundle it.\n */\nfunction validateTemplateImports(\n filePath: string,\n fileContent: string,\n): TemplateImportValidationResult {\n const sourceFile = ts.createSourceFile(filePath, fileContent, ts.ScriptTarget.Latest, true)\n let hasRelativeHelperImports = false\n\n for (const statement of sourceFile.statements) {\n if (ts.isImportDeclaration(statement)) {\n if (statement.importClause?.isTypeOnly) {\n continue\n }\n\n const moduleSpecifierText = ts.isStringLiteral(statement.moduleSpecifier)\n ? statement.moduleSpecifier.text\n : ''\n const importLine = statement.getText(sourceFile).split('\\n')[0]?.trim() ?? 'import ...'\n\n if (moduleSpecifierText === 'figma') {\n const hasDefaultImport = !!statement.importClause?.name\n const hasNamedOrNamespaceImport = !!statement.importClause?.namedBindings\n if (!hasDefaultImport || hasNamedOrNamespaceImport) {\n throw unsupportedImportError(filePath, importLine)\n }\n continue\n }\n\n if (isRelativeImportPath(moduleSpecifierText)) {\n hasRelativeHelperImports = true\n continue\n }\n\n throw unsupportedImportError(filePath, importLine)\n }\n\n // Re-exports aren't supported: the runtime only reads the default export.\n if (ts.isExportDeclaration(statement) && statement.moduleSpecifier && !statement.isTypeOnly) {\n const exportLine = statement.getText(sourceFile).split('\\n')[0]?.trim() ?? 'export ...'\n throw new Error(\n `Template files do not support re-exports ('export ... from ...').\\n` +\n `Found in ${filePath}:\\n` +\n ` ${exportLine}\\n\\n` +\n `Import the helper instead (for example: import { helper } from './helpers').`,\n )\n }\n }\n\n // `require` is for the Figma API only: a pure ESM graph is what lets the\n // bundler emit a flat, tree-shaken template. Walking the AST (not the raw\n // text) keeps a `require(...)` inside an emitted snippet from matching.\n const visitRequire = (node: ts.Node): void => {\n const request = getRequireCallRequest(node)\n if (request && request !== 'figma') {\n throw isRelativeImportPath(request)\n ? relativeRequireError(filePath, request)\n : unsupportedImportError(filePath, `require('${request}')`)\n }\n ts.forEachChild(node, visitRequire)\n }\n visitRequire(sourceFile)\n\n return { hasRelativeHelperImports }\n}\n\nfunction rewriteFigmaImport(fileContent: string): string {\n return fileContent.replace(figmaImportRegex, \"const figma = require('figma')\")\n}\n\nfunction transpileTypeScriptTemplate(fileContent: string): string {\n const result = ts.transpileModule(fileContent, {\n compilerOptions: {\n module: ts.ModuleKind.ESNext,\n target: ts.ScriptTarget.ES2021,\n removeComments: false,\n },\n })\n\n return result.outputText\n}\n\n/**\n * Extracts metadata fields (url, component, source) from the leading comments\n * of a raw template file. This must be done before transpilation because\n * TypeScript can remove comments that appear before type-only imports.\n */\nfunction extractMetadataFields(fileContent: string): {\n fields: { url?: string; component?: string; source?: string }\n templateStartLine: number\n} {\n const lines = fileContent.split('\\n')\n const fields: { url?: string; component?: string; source?: string } = {}\n let templateStartLine = 0\n\n // Parse consecutive comment lines at the start of the file\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim()\n // Match pattern: // fieldName=value\n const match = line.match(/^\\/\\/\\s*(\\w+)=(.+)$/)\n if (match) {\n const [, fieldName, fieldValue] = match\n const normalizedFieldName = fieldName.toLowerCase()\n if (\n normalizedFieldName === 'url' ||\n normalizedFieldName === 'component' ||\n normalizedFieldName === 'source'\n ) {\n fields[normalizedFieldName] = fieldValue.trim()\n }\n templateStartLine = i + 1\n } else if (line === '' || line.startsWith('//')) {\n // Allow blank lines or other comments, but don't increment template start\n continue\n } else {\n // First non-comment line found\n break\n }\n }\n\n return { fields, templateStartLine }\n}\n\nexport interface BatchOverrides {\n url: string\n source?: string\n component?: string\n batchData: Record<string, any>\n batchFilePath: string\n}\n\nexport async function parseRawFile(\n filePath: string,\n label: string | undefined,\n config?: CodeConnectConfig,\n dir?: string,\n batchOverrides?: BatchOverrides,\n): Promise<CodeConnectJSON> {\n let fileContent = fs.readFileSync(filePath, 'utf-8')\n let shouldBundleTemplate = false\n\n // Extract metadata fields BEFORE transpilation to avoid losing comments\n // that appear before type-only imports (which TypeScript erases)\n const { fields, templateStartLine } = extractMetadataFields(fileContent)\n\n const figmaUrl = batchOverrides?.url || fields.url\n\n // Validate imports first, before the `codeProperties` skip guard below, so an\n // unsupported import is always a hard error rather than silently swallowed.\n if (isRawTemplateSourceFile(filePath)) {\n shouldBundleTemplate = validateTemplateImports(filePath, fileContent).hasRelativeHelperImports\n }\n\n // A file with no // url= directive that contains the string `codeProperties`\n // is not Code Connect (e.g. Make's code component property definitions). Skip\n // it (callers log and continue) instead of failing. Every other file is\n // handled exactly as before.\n if (!figmaUrl && fileContent.includes('codeProperties')) {\n throw new CodePropertiesError(\n `Skipping ${filePath}: file has no // url= directive and contains \"codeProperties\", so it is not treated as a Code Connect file.`,\n )\n }\n\n // Bundle templates with helper imports. Helper-free templates stay on the\n // faster path and rewrite the Figma import directly to require syntax.\n if (shouldBundleTemplate) {\n // Confining resolution to the project dir\n const projectRoot = dir ? path.resolve(dir) : path.dirname(path.resolve(filePath))\n fileContent = await bundleTemplateWithHelpers(filePath, projectRoot)\n } else {\n fileContent = rewriteFigmaImport(fileContent)\n if (filePath.endsWith('.ts')) {\n fileContent = transpileTypeScriptTemplate(fileContent)\n }\n }\n\n // For batch templates, metadata comes from the batch entry instead of comments\n const component = batchOverrides?.component || fields.component\n const source = batchOverrides?.source || fields.source || ''\n\n if (!figmaUrl) {\n throw new Error(\n batchOverrides\n ? `Missing required \"url\" field in ${batchOverrides.batchFilePath}. Please add \"url\" to each entry in your .figma.batch.json file.`\n : `Missing required url field in ${filePath}. Please add a // url=... comment to the top of the file.`,\n )\n }\n let figmaNodeUrl = figmaUrl\n\n // Extract template from the transpiled content, starting at the line\n // where the metadata comments ended in the original source\n const transpiledLines = fileContent.split('\\n')\n let templateStartIndex = 0\n\n // Skip lines until we've passed the original metadata comment section\n for (let i = 0; i < transpiledLines.length; i++) {\n const line = transpiledLines[i].trim()\n // Skip blank lines and comments at the start\n if (line === '' || line.startsWith('//')) {\n continue\n }\n // First non-comment line in transpiled output\n templateStartIndex = i\n break\n }\n\n let template = transpiledLines.slice(templateStartIndex).join('\\n')\n\n // For batch templates, set globalThis['__FIGMA_BATCH'] so the runtime exposes it as\n // figma.batch. Using globalThis rather than a const so it's accessible from\n // __FIGMA_CODE_CONNECT_REQUIRE's closure regardless of where require('figma') is called.\n // (globalThis works in both browser and Node.js, unlike window.)\n if (batchOverrides) {\n template = `globalThis['__FIGMA_BATCH'] = ${JSON.stringify(\n batchOverrides.batchData,\n )}\\n${template}`\n }\n\n // Check the final template (incl. any bundled helpers and batch data) against\n // the backend's size cap so an oversized template fails here, not on upload.\n assertTemplateWithinSizeLimit(filePath, template)\n\n // Apply documentUrlSubstitutions if provided\n if (config?.documentUrlSubstitutions) {\n figmaNodeUrl = applyDocumentUrlSubstitutions(figmaNodeUrl, config.documentUrlSubstitutions)\n }\n\n // Determine effective label from parameter, config, or default\n const effectiveLabel = label || config?.label || CodeConnectLabel.Code\n\n const language = config?.language || getInferredLanguageForRaw(effectiveLabel)\n\n return {\n figmaNode: figmaNodeUrl,\n component,\n template,\n // nestable by default unless user specifies in template\n // (templateData.nestable AND template.metadata.nestable need to\n // be true for instance to be nested)\n templateData: { nestable: true, isParserless: true },\n language,\n label: effectiveLabel,\n source,\n sourceLocation: { line: -1 },\n metadata: {\n cliVersion: require('../../package.json').version,\n },\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/react/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAA;AAmB3B,OAAO,EAAsB,YAAY,EAAoB,MAAM,uBAAuB,CAAA;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE1D,OAAO,EAIL,aAAa,EAQb,YAAY,EACb,MAAM,0BAA0B,CAAA;AAEjC;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,EAAE,CAAC,IAAI,GACZ,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,qBAAqB,GAAG,EAAE,CAAC,WAAW,GAAG,SAAS,CAMvE;AAiED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,0BAanF;AA0ED,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAE3D;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,EAAE,CAAC,wBAAwB,GAAG,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,UAAU,EACjE,aAAa,EAAE,aAAa,EAC5B,MAAM,CAAC,EAAE,OAAO;;;;GA4GjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,kBAAkB,GAAG,EAAE,CAAC,mBAAmB,EACtE,aAAa,EAAE,aAAa,EAC5B,YAAY,CAAC,EAAE,YAAY;;;mBAvMd,MAAM;cACX,MAAM;yBACK,MAAM;;;;EA+X1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,kBAAkB,GAAG,EAAE,CAAC,mBAAmB,EACtE,aAAa,EAAE,aAAa,EAC5B,YAAY,CAAC,EAAE,YAAY,EAC3B,cAAc,CAAC,EAAE,OAAO;;;mBAjZX,MAAM;cACX,MAAM;yBACK,MAAM;;;EAyb1B;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,kBAAkB,GAAG,EAAE,CAAC,mBAAmB,EACtE,aAAa,EAAE,aAAa,EAC5B,YAAY,CAAC,EAAE,YAAY,EAC3B,cAAc,CAAC,EAAE,OAAO;;;mBAqCX,MAAM;cACX,MAAM;yBACK,MAAM;;;EAyB1B;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,UA+B1D;AA+LD,wBAAgB,kBAAkB,CAChC,iBAAiB,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,UAItE;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,EAAE,CAAC,cAAc,EACvB,aAAa,EAAE,aAAa,EAC5B,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,YAAY,GAChD,OAAO,CAAC,eAAe,CAAC,CA6H1B"}
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/react/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAA;AAmB3B,OAAO,EAAsB,YAAY,EAAoB,MAAM,uBAAuB,CAAA;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE1D,OAAO,EAIL,aAAa,EAQb,YAAY,EACb,MAAM,0BAA0B,CAAA;AAEjC;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,EAAE,CAAC,IAAI,GACZ,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,qBAAqB,GAAG,EAAE,CAAC,WAAW,GAAG,SAAS,CAMvE;AAyDD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,UAAU,0BAanF;AA0ED,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAE3D;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,EAAE,CAAC,wBAAwB,GAAG,EAAE,CAAC,UAAU,GAAG,EAAE,CAAC,UAAU,EACjE,aAAa,EAAE,aAAa,EAC5B,MAAM,CAAC,EAAE,OAAO;;;;GA4GjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,kBAAkB,GAAG,EAAE,CAAC,mBAAmB,EACtE,aAAa,EAAE,aAAa,EAC5B,YAAY,CAAC,EAAE,YAAY;;;mBAvMd,MAAM;cACX,MAAM;yBACK,MAAM;;;;EAoY1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,kBAAkB,GAAG,EAAE,CAAC,mBAAmB,EACtE,aAAa,EAAE,aAAa,EAC5B,YAAY,CAAC,EAAE,YAAY,EAC3B,cAAc,CAAC,EAAE,OAAO;;;mBAtZX,MAAM;cACX,MAAM;yBACK,MAAM;;;EA8b1B;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,kBAAkB,GAAG,EAAE,CAAC,mBAAmB,EACtE,aAAa,EAAE,aAAa,EAC5B,YAAY,CAAC,EAAE,YAAY,EAC3B,cAAc,CAAC,EAAE,OAAO;;;mBAqCX,MAAM;cACX,MAAM;yBACK,MAAM;;;EAyB1B;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,UA+B1D;AA+LD,wBAAgB,kBAAkB,CAChC,iBAAiB,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,UAItE;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,EAAE,CAAC,cAAc,EACvB,aAAa,EAAE,aAAa,EAC5B,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,YAAY,GAChD,OAAO,CAAC,eAAe,CAAC,CA6H1B"}
@@ -34,14 +34,6 @@ function findJSXElement(node) {
34
34
  return typescript_1.default.forEachChild(node, findJSXElement);
35
35
  }
36
36
  }
37
- function findBlock(node) {
38
- if (typescript_1.default.isBlock(node)) {
39
- return node;
40
- }
41
- else {
42
- return typescript_1.default.forEachChild(node, findBlock);
43
- }
44
- }
45
37
  /**
46
38
  * Walks up the AST from an assignment to find the import declaration
47
39
  */
@@ -348,7 +340,12 @@ function parseRenderFunctionExpression(exp, parserContext, propMappings) {
348
340
  ]).transformed[0];
349
341
  }
350
342
  const printer = typescript_1.default.createPrinter();
351
- const block = findBlock(exp);
343
+ // Only consider the render function's *own* body block, not any block nested
344
+ // deeper in the tree. Using a tree-walking search here would incorrectly pick
345
+ // up blocks belonging to nested functions (e.g. an event handler passed as a
346
+ // JSX prop like `onValidateFile={file => { ... }}`), causing us to render that
347
+ // handler's body instead of the returned JSX.
348
+ const block = exp.body && typescript_1.default.isBlock(exp.body) ? exp.body : undefined;
352
349
  let nestable = false;
353
350
  let jsx = findJSXElement(exp);
354
351
  if (jsx && (!block || (block && block.statements.length <= 1))) {