@figma/code-connect 1.4.3 → 1.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +61 -10
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/connect_template.d.ts +36 -0
- package/dist/commands/connect_template.d.ts.map +1 -0
- package/dist/commands/connect_template.js +324 -0
- package/dist/commands/connect_template.js.map +1 -0
- package/dist/commands/preview_utils.d.ts +49 -0
- package/dist/commands/preview_utils.d.ts.map +1 -0
- package/dist/commands/preview_utils.js +451 -0
- package/dist/commands/preview_utils.js.map +1 -0
- package/dist/connect/batch_templates.d.ts +11 -0
- package/dist/connect/batch_templates.d.ts.map +1 -0
- package/dist/connect/batch_templates.js +70 -0
- package/dist/connect/batch_templates.js.map +1 -0
- package/dist/connect/create.d.ts.map +1 -1
- package/dist/connect/create.js +13 -0
- package/dist/connect/create.js.map +1 -1
- package/dist/connect/create_template.d.ts +22 -0
- package/dist/connect/create_template.d.ts.map +1 -0
- package/dist/connect/create_template.js +195 -0
- package/dist/connect/create_template.js.map +1 -0
- package/dist/connect/delete_docs.d.ts +2 -1
- package/dist/connect/delete_docs.d.ts.map +1 -1
- package/dist/connect/delete_docs.js +2 -2
- package/dist/connect/delete_docs.js.map +1 -1
- package/dist/connect/figma_rest_api.d.ts +1 -5
- package/dist/connect/figma_rest_api.d.ts.map +1 -1
- package/dist/connect/figma_rest_api.js +9 -3
- package/dist/connect/figma_rest_api.js.map +1 -1
- package/dist/connect/project.d.ts +9 -7
- package/dist/connect/project.d.ts.map +1 -1
- package/dist/connect/project.js +39 -25
- package/dist/connect/project.js.map +1 -1
- package/dist/connect/raw_templates.d.ts +8 -1
- package/dist/connect/raw_templates.d.ts.map +1 -1
- package/dist/connect/raw_templates.js +20 -7
- package/dist/connect/raw_templates.js.map +1 -1
- package/dist/connect/upload.d.ts +3 -1
- package/dist/connect/upload.d.ts.map +1 -1
- package/dist/connect/upload.js +23 -8
- package/dist/connect/upload.js.map +1 -1
- package/dist/connect/validation.d.ts +2 -2
- package/dist/connect/validation.d.ts.map +1 -1
- package/dist/connect/validation.js +4 -4
- package/dist/connect/validation.js.map +1 -1
- package/dist/connect/wizard/helpers.js.map +1 -1
- package/dist/storybook/convert.d.ts.map +1 -1
- package/dist/storybook/convert.js +1 -1
- package/dist/storybook/convert.js.map +1 -1
- package/figma-types.d.ts +3 -0
- package/package.json +8 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/connect/upload.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodeConnectJSON } from '../connect/figma_connect'\nimport { logger, underline, highlight } from '../common/logging'\nimport { getApiUrl, getHeaders } from './figma_rest_api'\nimport { exitWithFeedbackMessage } from './helpers'\nimport { parseFigmaNode } from './validation'\nimport { isFetchError, request } from '../common/fetch'\n\nconst RETRY_DELAYS_MS = [5_000, 15_000, 30_000]\n\nasync function postWithRetry<T>(\n apiUrl: string,\n batch: CodeConnectJSON[],\n accessToken: string,\n): Promise<{ data: T }> {\n for (let attempt = 0; attempt <= RETRY_DELAYS_MS.length; attempt++) {\n try {\n return await request.post<T>(apiUrl, batch, { headers: getHeaders(accessToken) })\n } catch (err) {\n if (isFetchError(err) && (err.response.status === 429 || err.response.status >= 500)) {\n if (attempt === RETRY_DELAYS_MS.length) {\n throw err\n }\n const retryAfterSec = err.response.headers.get('Retry-After')\n const delayMs = retryAfterSec\n ? parseInt(retryAfterSec, 10) * 1_000\n : RETRY_DELAYS_MS[attempt]\n logger.warn(\n `Received ${err.response.status}, retrying in ${delayMs / 1000}s (attempt ${attempt + 1}/${RETRY_DELAYS_MS.length})...`,\n )\n await new Promise((resolve) => setTimeout(resolve, delayMs))\n } else {\n throw err\n }\n }\n }\n throw new Error('Unreachable')\n}\n\ninterface Args {\n accessToken: string\n docs: CodeConnectJSON[]\n batchSize?: number\n verbose: boolean\n apiUrl?: string\n}\n\ninterface UploadResponse {\n status: number\n error: boolean\n meta: {\n success: boolean\n published_count: number\n failed_count: number\n published_nodes: Array<{ figmaNode: string; label: string }>\n failed_nodes: Array<{ figmaNode: string; label: string; reason: string }>\n }\n}\n\n/**\n * Returns a string representation of the code connect JSON\n * @param doc - The code connect JSON\n * @returns A string representation of the code connect JSON\n */\nfunction codeConnectStr(doc: CodeConnectJSON): string {\n return `${highlight(doc.component ?? '')}${doc.variant ? `(${Object.entries(doc.variant).map(([key, value]) => `${key}=${value}`)})` : ''} ${underline(doc.figmaNode)}`\n}\n\n/**\n * Extracts the fileKey and nodeId from the Figma node URL and returns a key in the format of fileKey-nodeId\n * @param figmaNode - The Figma node URL\n * @returns The key in the format of fileKey-nodeId\n */\nfunction getKeyFromFigmaNode(figmaNode: string): string {\n const url = new URL(figmaNode)\n\n // Extract fileKey from path (after /file/ or /design/)\n const pathMatch = url.pathname.match(/\\/(file|design)\\/([A-Za-z0-9]+)/)\n const fileKey = pathMatch ? pathMatch[2] : ''\n\n // Extract nodeId from query parameter and convert format (1-24 -> 1:24)\n const nodeIdParam = url.searchParams.get('node-id') || ''\n const nodeId = nodeIdParam.replace(/-/g, ':')\n\n return `${fileKey}-${nodeId}`\n}\n\n/**\n * Creates a map from fileKey-nodeId to original docs for easy lookup\n */\nexport function createDocsMap(\n docs: CodeConnectJSON[],\n verbose: boolean,\n): Map<string, CodeConnectJSON[]> {\n const docsMap = new Map<string, CodeConnectJSON[]>()\n\n for (const doc of docs) {\n const parsedData = parseFigmaNode(verbose, doc)\n if (!parsedData) {\n continue\n }\n\n const mapKey = `${parsedData.fileKey}-${parsedData.nodeId}`\n if (!docsMap.has(mapKey)) {\n docsMap.set(mapKey, [])\n }\n\n docsMap.get(mapKey)?.push(doc)\n }\n\n return docsMap\n}\n\nexport async function upload({\n accessToken,\n docs,\n batchSize,\n verbose,\n apiUrl: apiUrlOverride,\n}: Args) {\n const apiUrl = getApiUrl(docs?.[0]?.figmaNode ?? '', apiUrlOverride) + '/code_connect'\n\n // Strip internal fields before uploading to Figma\n const cleanedDocs = docs.map((doc) => {\n const { _codeConnectFilePath, ...cleanDoc } = doc\n return cleanDoc as CodeConnectJSON\n })\n\n try {\n logger.info(`Uploading to Figma...`)\n\n // Create a map from fileKey-nodeId to original docs for detailed output\n const docsMap = createDocsMap(cleanedDocs, verbose)\n\n let allUploadedNodes = new Set<string>()\n let allFailedNodes = new Map<string, string>() // key -> failure reason\n\n if (batchSize) {\n if (typeof batchSize !== 'number') {\n logger.error('Batch size must be a number')\n exitWithFeedbackMessage(1)\n }\n\n // batch together based on fileKey + nodeId as all variants etc of the same node should be uploaded together\n // Otherwise, the server will overwrite the previous upload\n const groupedDocs = cleanedDocs.reduce(\n (acc, doc) => {\n const parsedData = parseFigmaNode(verbose, doc)\n\n if (!parsedData) {\n exitWithFeedbackMessage(1)\n }\n\n const { fileKey, nodeId } = parsedData\n const accKey = fileKey + ',' + nodeId\n if (!acc[accKey]) {\n acc[accKey] = []\n }\n acc[accKey].push(doc)\n return acc\n },\n {} as Record<string, CodeConnectJSON[]>,\n )\n\n const batchedDocs: CodeConnectJSON[][] = []\n const nodeKeys = Object.keys(groupedDocs)\n\n for (let i = 0; i < nodeKeys.length; i += batchSize) {\n const batch: CodeConnectJSON[] = []\n for (let j = i; j < i + batchSize && j < nodeKeys.length; j++) {\n const nodeKey = nodeKeys[j]\n batch.push(...groupedDocs[nodeKey])\n }\n batchedDocs.push(batch)\n }\n\n let currentBatch = 1\n const noOfBatches = batchedDocs.length\n for (const batch of batchedDocs) {\n process.stderr.write('\\x1b[2K\\x1b[0G')\n process.stderr.write(`Uploading batch ${currentBatch}/${noOfBatches}`)\n\n var size = Buffer.byteLength(JSON.stringify(batch)) / (1024 * 1024)\n\n // Server has a limit of 5mb\n if (size > 5) {\n logger.error(\n `Failed to upload to Figma: The request is too large (${size.toFixed(2)}mb).`,\n )\n logger.error(\n 'Please try reducing the size of uploads by splitting them into smaller requests by running again and decreasing the --batch-size parameter.',\n )\n exitWithFeedbackMessage(1)\n }\n\n logger.debug(`Uploading ${size.toFixed(2)}mb to Figma`)\n\n const response = await postWithRetry<UploadResponse>(apiUrl, batch, accessToken)\n\n const data = response.data\n\n if (data.meta?.published_nodes) {\n data.meta.published_nodes.forEach((node) =>\n allUploadedNodes.add(getKeyFromFigmaNode(node.figmaNode)),\n )\n }\n if (data.meta?.failed_nodes) {\n data.meta.failed_nodes.forEach((node) =>\n allFailedNodes.set(getKeyFromFigmaNode(node.figmaNode), node.reason),\n )\n }\n\n currentBatch++\n }\n process.stderr.write(`\\n`)\n } else {\n var size = Buffer.byteLength(JSON.stringify(cleanedDocs)) / (1024 * 1024)\n\n // Server has a limit of 5mb\n if (size > 5) {\n logger.error(`Failed to upload to Figma: The request is too large (${size.toFixed(2)}mb).`)\n logger.error(\n 'Please try reducing the size of uploads by splitting them into smaller requests by running again with the --batch-size parameter. You can do also this by running on different subdirectories using the --dir flag or by iteratively adjusting the includes field in the configuration.',\n )\n exitWithFeedbackMessage(1)\n }\n\n logger.debug(`Uploading ${size.toFixed(2)}mb to Figma`)\n logger.info(`uploading to ${apiUrl}`)\n\n const response = await postWithRetry<UploadResponse>(apiUrl, cleanedDocs, accessToken)\n\n const data = response.data\n\n if (data.meta?.published_nodes) {\n data.meta.published_nodes.forEach((node) =>\n allUploadedNodes.add(getKeyFromFigmaNode(node.figmaNode)),\n )\n }\n if (data.meta?.failed_nodes) {\n data.meta.failed_nodes.forEach((node) =>\n allFailedNodes.set(getKeyFromFigmaNode(node.figmaNode), node.reason),\n )\n }\n }\n\n // Separate successful and failed uploads\n const successfulDocsByLabel: Record<string, CodeConnectJSON[]> = {}\n const failedDocsByLabel: Record<string, Array<{ doc: CodeConnectJSON; reason: string }>> = {}\n\n for (const [mapKey, nodeDocs] of docsMap.entries()) {\n for (const doc of nodeDocs) {\n const label = doc.label\n const docKey = getKeyFromFigmaNode(doc.figmaNode)\n const isUploaded = allUploadedNodes.has(docKey)\n const failureReason = allFailedNodes.get(docKey)\n\n if (isUploaded) {\n if (!successfulDocsByLabel[label]) {\n successfulDocsByLabel[label] = []\n }\n successfulDocsByLabel[label].push(doc)\n } else if (failureReason) {\n if (!failedDocsByLabel[label]) {\n failedDocsByLabel[label] = []\n }\n failedDocsByLabel[label].push({ doc, reason: failureReason })\n }\n }\n }\n\n for (const [label, docs] of Object.entries(successfulDocsByLabel)) {\n logger.info(\n `Successfully uploaded to Figma, for ${label}:\\n${docs.map((doc) => `-> ${codeConnectStr(doc)}`).join('\\n')}`,\n )\n }\n\n if (Object.keys(failedDocsByLabel).length > 0) {\n for (const [label, failedItems] of Object.entries(failedDocsByLabel)) {\n logger.error(\n `Failed to upload to Figma, for ${label}:\\n${failedItems.map((item) => `-> ${codeConnectStr(item.doc)} (${item.reason})`).join('\\n')}`,\n )\n }\n }\n } catch (err) {\n if (isFetchError(err)) {\n if (err.response) {\n logger.error(\n `Failed to upload to Figma (${err.response.status}): ${err.response.status} ${err.data?.message}`,\n )\n } else {\n logger.error(`Failed to upload to Figma: ${err.message}`)\n }\n logger.debug(JSON.stringify(err?.data))\n } else {\n logger.error(`Failed to upload to Figma: ${err}`)\n }\n exitWithFeedbackMessage(1)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/connect/upload.ts"],"names":[],"mappings":"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","sourcesContent":["import { CodeConnectJSON } from '../connect/figma_connect'\nimport { logger, underline, highlight, warn } from '../common/logging'\nimport { getApiUrl, getHeaders } from './figma_rest_api'\nimport { exitWithFeedbackMessage } from './helpers'\nimport { parseFigmaNode } from './validation'\nimport { isFetchError, request } from '../common/fetch'\n\nconst COMPONENT_BROWSER_CONFLICT_REASON = 'Code Connect UI mapping already exists'\n\nconst RETRY_DELAYS_MS = [5_000, 15_000, 30_000]\n\nasync function postWithRetry<T>(\n apiUrl: string,\n batch: CodeConnectJSON[],\n accessToken: string,\n useOAuth = false,\n): Promise<{ data: T }> {\n for (let attempt = 0; attempt <= RETRY_DELAYS_MS.length; attempt++) {\n try {\n return await request.post<T>(apiUrl, batch, { headers: getHeaders(accessToken, useOAuth) })\n } catch (err) {\n if (isFetchError(err) && (err.response.status === 429 || err.response.status >= 500)) {\n if (attempt === RETRY_DELAYS_MS.length) {\n throw err\n }\n const retryAfterSec = err.response.headers.get('Retry-After')\n const delayMs = retryAfterSec\n ? parseInt(retryAfterSec, 10) * 1_000\n : RETRY_DELAYS_MS[attempt]\n logger.warn(\n `Received ${err.response.status}, retrying in ${delayMs / 1000}s (attempt ${attempt + 1}/${RETRY_DELAYS_MS.length})...`,\n )\n await new Promise((resolve) => setTimeout(resolve, delayMs))\n } else {\n throw err\n }\n }\n }\n throw new Error('Unreachable')\n}\n\ninterface Args {\n accessToken: string\n useOAuth?: boolean\n docs: CodeConnectJSON[]\n batchSize?: number\n verbose: boolean\n apiUrl?: string\n force?: boolean\n}\n\ninterface UploadResponse {\n status: number\n error: boolean\n meta: {\n success: boolean\n published_count: number\n failed_count: number\n published_nodes: Array<{ figmaNode: string; label: string }>\n failed_nodes: Array<{ figmaNode: string; label: string; reason: string }>\n }\n}\n\n/**\n * Returns a string representation of the code connect JSON\n * @param doc - The code connect JSON\n * @returns A string representation of the code connect JSON\n */\nfunction codeConnectStr(doc: CodeConnectJSON): string {\n return `${highlight(doc.component ?? '')}${doc.variant ? `(${Object.entries(doc.variant).map(([key, value]) => `${key}=${value}`)})` : ''} ${underline(doc.figmaNode)}`\n}\n\n/**\n * Extracts the fileKey and nodeId from the Figma node URL and returns a key in the format of fileKey-nodeId\n * @param figmaNode - The Figma node URL\n * @returns The key in the format of fileKey-nodeId\n */\nfunction getKeyFromFigmaNode(figmaNode: string): string {\n const url = new URL(figmaNode)\n\n // Extract fileKey from path (after /file/ or /design/)\n const pathMatch = url.pathname.match(/\\/(file|design)\\/([A-Za-z0-9]+)/)\n const fileKey = pathMatch ? pathMatch[2] : ''\n\n // Extract nodeId from query parameter and convert format (1-24 -> 1:24)\n const nodeIdParam = url.searchParams.get('node-id') || ''\n const nodeId = nodeIdParam.replace(/-/g, ':')\n\n return `${fileKey}-${nodeId}`\n}\n\n/**\n * Creates a map from fileKey-nodeId to original docs for easy lookup\n */\nexport function createDocsMap(\n docs: CodeConnectJSON[],\n verbose: boolean,\n): Map<string, CodeConnectJSON[]> {\n const docsMap = new Map<string, CodeConnectJSON[]>()\n\n for (const doc of docs) {\n const parsedData = parseFigmaNode(verbose, doc)\n if (!parsedData) {\n continue\n }\n\n const mapKey = `${parsedData.fileKey}-${parsedData.nodeId}`\n if (!docsMap.has(mapKey)) {\n docsMap.set(mapKey, [])\n }\n\n docsMap.get(mapKey)?.push(doc)\n }\n\n return docsMap\n}\n\nexport async function upload({\n accessToken,\n useOAuth = false,\n docs,\n batchSize,\n verbose,\n apiUrl: apiUrlOverride,\n force,\n}: Args) {\n const apiUrl =\n getApiUrl(docs?.[0]?.figmaNode ?? '', apiUrlOverride) +\n '/code_connect' +\n (force ? '?force=true' : '')\n\n // Strip internal fields before uploading to Figma\n const cleanedDocs = docs.map((doc) => {\n const { _codeConnectFilePath, ...cleanDoc } = doc\n return cleanDoc as CodeConnectJSON\n })\n\n try {\n logger.info(`Uploading to Figma...`)\n\n // Create a map from fileKey-nodeId to original docs for detailed output\n const docsMap = createDocsMap(cleanedDocs, verbose)\n\n let allUploadedNodes = new Set<string>()\n let allFailedNodes = new Map<string, string>() // key -> failure reason\n\n if (batchSize) {\n if (typeof batchSize !== 'number') {\n logger.error('Batch size must be a number')\n exitWithFeedbackMessage(1)\n }\n\n // batch together based on fileKey + nodeId as all variants etc of the same node should be uploaded together\n // Otherwise, the server will overwrite the previous upload\n const groupedDocs = cleanedDocs.reduce(\n (acc, doc) => {\n const parsedData = parseFigmaNode(verbose, doc)\n\n if (!parsedData) {\n exitWithFeedbackMessage(1)\n }\n\n const { fileKey, nodeId } = parsedData\n const accKey = fileKey + ',' + nodeId\n if (!acc[accKey]) {\n acc[accKey] = []\n }\n acc[accKey].push(doc)\n return acc\n },\n {} as Record<string, CodeConnectJSON[]>,\n )\n\n const batchedDocs: CodeConnectJSON[][] = []\n const nodeKeys = Object.keys(groupedDocs)\n\n for (let i = 0; i < nodeKeys.length; i += batchSize) {\n const batch: CodeConnectJSON[] = []\n for (let j = i; j < i + batchSize && j < nodeKeys.length; j++) {\n const nodeKey = nodeKeys[j]\n batch.push(...groupedDocs[nodeKey])\n }\n batchedDocs.push(batch)\n }\n\n let currentBatch = 1\n const noOfBatches = batchedDocs.length\n for (const batch of batchedDocs) {\n process.stderr.write('\\x1b[2K\\x1b[0G')\n process.stderr.write(`Uploading batch ${currentBatch}/${noOfBatches}`)\n\n var size = Buffer.byteLength(JSON.stringify(batch)) / (1024 * 1024)\n\n // Server has a limit of 5mb\n if (size > 5) {\n logger.error(\n `Failed to upload to Figma: The request is too large (${size.toFixed(2)}mb).`,\n )\n logger.error(\n 'Please try reducing the size of uploads by splitting them into smaller requests by running again and decreasing the --batch-size parameter.',\n )\n exitWithFeedbackMessage(1)\n }\n\n logger.debug(`Uploading ${size.toFixed(2)}mb to Figma`)\n\n const response = await postWithRetry<UploadResponse>(apiUrl, batch, accessToken, useOAuth)\n\n const data = response.data\n\n if (data.meta?.published_nodes) {\n data.meta.published_nodes.forEach((node) =>\n allUploadedNodes.add(getKeyFromFigmaNode(node.figmaNode)),\n )\n }\n if (data.meta?.failed_nodes) {\n data.meta.failed_nodes.forEach((node) =>\n allFailedNodes.set(getKeyFromFigmaNode(node.figmaNode), node.reason),\n )\n }\n\n currentBatch++\n }\n process.stderr.write(`\\n`)\n } else {\n var size = Buffer.byteLength(JSON.stringify(cleanedDocs)) / (1024 * 1024)\n\n // Server has a limit of 5mb\n if (size > 5) {\n logger.error(`Failed to upload to Figma: The request is too large (${size.toFixed(2)}mb).`)\n logger.error(\n 'Please try reducing the size of uploads by splitting them into smaller requests by running again with the --batch-size parameter. You can do also this by running on different subdirectories using the --dir flag or by iteratively adjusting the includes field in the configuration.',\n )\n exitWithFeedbackMessage(1)\n }\n\n logger.debug(`Uploading ${size.toFixed(2)}mb to Figma`)\n logger.info(`Uploading to ${apiUrl}`)\n\n const response = await postWithRetry<UploadResponse>(\n apiUrl,\n cleanedDocs,\n accessToken,\n useOAuth,\n )\n\n const data = response.data\n\n if (data.meta?.published_nodes) {\n data.meta.published_nodes.forEach((node) =>\n allUploadedNodes.add(getKeyFromFigmaNode(node.figmaNode)),\n )\n }\n if (data.meta?.failed_nodes) {\n data.meta.failed_nodes.forEach((node) =>\n allFailedNodes.set(getKeyFromFigmaNode(node.figmaNode), node.reason),\n )\n }\n }\n\n // Separate successful and failed uploads\n const successfulDocsByLabel: Record<string, CodeConnectJSON[]> = {}\n const failedDocsByLabel: Record<string, Array<{ doc: CodeConnectJSON; reason: string }>> = {}\n\n for (const [mapKey, nodeDocs] of docsMap.entries()) {\n for (const doc of nodeDocs) {\n const label = doc.label\n const docKey = getKeyFromFigmaNode(doc.figmaNode)\n const isUploaded = allUploadedNodes.has(docKey)\n const failureReason = allFailedNodes.get(docKey)\n\n if (isUploaded) {\n if (!successfulDocsByLabel[label]) {\n successfulDocsByLabel[label] = []\n }\n successfulDocsByLabel[label].push(doc)\n } else if (failureReason) {\n if (!failedDocsByLabel[label]) {\n failedDocsByLabel[label] = []\n }\n failedDocsByLabel[label].push({ doc, reason: failureReason })\n }\n }\n }\n\n for (const [label, docs] of Object.entries(successfulDocsByLabel)) {\n logger.info(\n `Successfully uploaded to Figma, for ${label}:\\n${docs.map((doc) => `-> ${codeConnectStr(doc)}`).join('\\n')}`,\n )\n }\n\n if (Object.keys(failedDocsByLabel).length > 0) {\n let hasComponentBrowserConflicts = false\n for (const [label, failedItems] of Object.entries(failedDocsByLabel)) {\n const conflicts = failedItems.filter((item) =>\n item.reason.includes(COMPONENT_BROWSER_CONFLICT_REASON),\n )\n const otherFailures = failedItems.filter(\n (item) => !item.reason.includes(COMPONENT_BROWSER_CONFLICT_REASON),\n )\n\n if (conflicts.length > 0) {\n hasComponentBrowserConflicts = true\n logger.warn(\n warn(\n `Warning: ${conflicts.length} node(s) already have UI-created Code Connect mappings in Figma for label \"${label}\":\\n${conflicts.map((item) => `-> ${codeConnectStr(item.doc)}`).join('\\n')}`,\n ),\n )\n }\n\n if (otherFailures.length > 0) {\n logger.error(\n `Failed to upload to Figma, for ${label}:\\n${otherFailures.map((item) => `-> ${codeConnectStr(item.doc)} (${item.reason})`).join('\\n')}`,\n )\n }\n }\n\n if (hasComponentBrowserConflicts && !force) {\n logger.warn(\n warn(\n `Re-run with --force to overwrite the existing UI-created mappings with your Code Connect files.`,\n ),\n )\n }\n }\n } catch (err) {\n if (isFetchError(err)) {\n if (err.response) {\n logger.error(\n `Failed to upload to Figma (${err.response.status}): ${err.response.status} ${err.data?.message}`,\n )\n } else {\n logger.error(`Failed to upload to Figma: ${err.message}`)\n }\n logger.debug(JSON.stringify(err?.data))\n } else {\n logger.error(`Failed to upload to Figma: ${err}`)\n }\n exitWithFeedbackMessage(1)\n }\n}\n"]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { CodeConnectJSON } from '../connect/figma_connect';
|
|
2
|
-
import { BaseCommand } from '../commands/connect';
|
|
2
|
+
import type { BaseCommand } from '../commands/connect';
|
|
3
3
|
export declare function parseFigmaNode(verbose: boolean, doc: CodeConnectJSON, silent?: boolean): {
|
|
4
4
|
fileKey: string;
|
|
5
5
|
nodeId: string;
|
|
6
6
|
} | null;
|
|
7
7
|
export declare const STATE_BOOLEAN_VALUE_PAIRS: string[][];
|
|
8
8
|
export declare function validateDoc(doc: CodeConnectJSON, figmaNode: any, nodeId: string): boolean;
|
|
9
|
-
export declare function validateDocs(cmd: BaseCommand, accessToken: string, docs: CodeConnectJSON[], apiUrlOverride?: string): Promise<boolean>;
|
|
9
|
+
export declare function validateDocs(cmd: BaseCommand, accessToken: string, docs: CodeConnectJSON[], apiUrlOverride?: string, useOAuth?: boolean): Promise<boolean>;
|
|
10
10
|
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/connect/validation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAI1D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/connect/validation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAI1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAGtD,wBAAgB,cAAc,CAC5B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,eAAe,EACpB,MAAM,GAAE,OAAe,GACtB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAoB5C;AA6HD,eAAO,MAAM,yBAAyB,YAIrC,CAAA;AAgED,wBAAgB,WAAW,CAAC,GAAG,EAAE,eAAe,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAmCzF;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,WAAW,EAChB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,eAAe,EAAE,EACvB,cAAc,CAAC,EAAE,MAAM,EACvB,QAAQ,UAAQ,GACf,OAAO,CAAC,OAAO,CAAC,CA0DlB"}
|
|
@@ -65,9 +65,9 @@ function parseFigmaNode(verbose, doc, silent = false) {
|
|
|
65
65
|
return null;
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
|
-
async function fetchNodeInfo(baseApiUrl, fileKey, nodeIdsChunk, accessToken) {
|
|
68
|
+
async function fetchNodeInfo(baseApiUrl, fileKey, nodeIdsChunk, accessToken, useOAuth = false) {
|
|
69
69
|
try {
|
|
70
|
-
const response = await fetch_1.request.get(`${baseApiUrl}${fileKey}/nodes?ids=${nodeIdsChunk.join(',')}`, { headers: (0, figma_rest_api_1.getHeaders)(accessToken) });
|
|
70
|
+
const response = await fetch_1.request.get(`${baseApiUrl}${fileKey}/nodes?ids=${nodeIdsChunk.join(',')}`, { headers: (0, figma_rest_api_1.getHeaders)(accessToken, useOAuth) });
|
|
71
71
|
if (response.response.status !== 200) {
|
|
72
72
|
logging_1.logger.error('Failed to fetch node info: ' + response.response.status + ' ' + response.data?.message);
|
|
73
73
|
return null;
|
|
@@ -228,7 +228,7 @@ function validateDoc(doc, figmaNode, nodeId) {
|
|
|
228
228
|
}
|
|
229
229
|
return true;
|
|
230
230
|
}
|
|
231
|
-
async function validateDocs(cmd, accessToken, docs, apiUrlOverride) {
|
|
231
|
+
async function validateDocs(cmd, accessToken, docs, apiUrlOverride, useOAuth = false) {
|
|
232
232
|
let baseApiUrl = (0, figma_rest_api_1.getApiUrl)(docs?.[0]?.figmaNode ?? '', apiUrlOverride) + '/files/';
|
|
233
233
|
const fileKeyToNodeIds = {};
|
|
234
234
|
let valid = true;
|
|
@@ -258,7 +258,7 @@ async function validateDocs(cmd, accessToken, docs, apiUrlOverride) {
|
|
|
258
258
|
for (let batch = 0; batch < chunks.length; batch++) {
|
|
259
259
|
const nodeIdsChunk = chunks[batch];
|
|
260
260
|
logging_1.logger.debug(`Running for ${baseApiUrl + fileKey + '/nodes?ids=' + nodeIdsChunk.join(',')}`);
|
|
261
|
-
const nodeMapRet = await fetchNodeInfo(baseApiUrl, fileKey, nodeIdsChunk, accessToken);
|
|
261
|
+
const nodeMapRet = await fetchNodeInfo(baseApiUrl, fileKey, nodeIdsChunk, accessToken, useOAuth);
|
|
262
262
|
if (!nodeMapRet) {
|
|
263
263
|
return false;
|
|
264
264
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/connect/validation.ts"],"names":[],"mappings":"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","sourcesContent":["import * as url from 'url'\nimport { chunk } from 'lodash'\n\nimport { CodeConnectJSON } from '../connect/figma_connect'\nimport { logger } from '../common/logging'\nimport { validateNodeId } from './helpers'\nimport { getApiUrl, getHeaders } from './figma_rest_api'\nimport { BaseCommand } from '../commands/connect'\nimport { isFetchError, request } from '../common/fetch'\n\nexport function parseFigmaNode(\n verbose: boolean,\n doc: CodeConnectJSON,\n silent: boolean = false,\n): { fileKey: string; nodeId: string } | null {\n const figmaNodeUrl = url.parse(doc.figmaNode, true)\n const fileKeyMatch = figmaNodeUrl.path?.match(/(file|design)\\/([a-zA-Z0-9]+)/)\n if (!fileKeyMatch) {\n if (!silent || verbose) {\n logger.error(`Failed to parse ${doc.figmaNode}`)\n }\n return null\n }\n const fileKey = fileKeyMatch[2]\n const nodeId = figmaNodeUrl.query['node-id']\n if (nodeId && typeof nodeId === 'string') {\n const figmaNodeId = validateNodeId(nodeId)\n return { fileKey, nodeId: figmaNodeId }\n } else {\n if (!silent || verbose) {\n logger.error(`Failed to get node-id from ${doc.figmaNode}`)\n }\n return null\n }\n}\n\nasync function fetchNodeInfo(\n baseApiUrl: string,\n fileKey: string,\n nodeIdsChunk: string[],\n accessToken: string,\n): Promise<any> {\n try {\n const response = await request.get<{ message: string; nodes: any }>(\n `${baseApiUrl}${fileKey}/nodes?ids=${nodeIdsChunk.join(',')}`,\n { headers: getHeaders(accessToken) },\n )\n if (response.response.status !== 200) {\n logger.error(\n 'Failed to fetch node info: ' + response.response.status + ' ' + response.data?.message,\n )\n return null\n }\n return response.data.nodes\n } catch (err) {\n if (isFetchError(err)) {\n if (err.response) {\n logger.error(\n `Failed to to fetch node info (${err.response.status}): ${err.response.status} ${err.data?.err ?? err.data?.message}`,\n )\n } else {\n logger.error(`Failed to to fetch node info: ${err.message}`)\n }\n logger.debug(JSON.stringify(err.data))\n } else {\n logger.error(`Failed to to fetch node info: ${err}`)\n }\n return null\n }\n}\n\nfunction validateProps(doc: CodeConnectJSON, document: any): boolean {\n if (doc.templateData && doc.templateData?.props) {\n let propsValid = true\n const codeConnectProps = Object.keys(doc.templateData.props ?? {})\n\n for (let i = 0; i < codeConnectProps.length; i++) {\n const codeConnectProp = doc.templateData?.props[codeConnectProps[i]]\n if (codeConnectProp.kind === 'children') {\n const codeConnectLayerNames = codeConnectProp.args.layers\n // Get all layer names in the figma doc\n const figmaLayerNames: string[] = []\n const getLayerNames = (layer: any) => {\n if (layer.name) {\n figmaLayerNames.push(layer.name)\n }\n if (layer.children) {\n layer.children.forEach((child: any) => getLayerNames(child))\n }\n }\n getLayerNames(document)\n // And make sure that the layer names in the code connect file are present in the figma doc\n for (const codeConnectLayerName of codeConnectLayerNames) {\n const regex = new RegExp('^' + codeConnectLayerName.replace('*', '.*'))\n if (figmaLayerNames.every((name) => !regex.test(name))) {\n logger.error(\n `Validation failed for ${doc.component} (${doc.figmaNode}): The layer \"${codeConnectLayerName}\" does not exist on the Figma component`,\n )\n propsValid = false\n }\n }\n continue\n }\n if (\n codeConnectProp.kind === 'boolean' ||\n codeConnectProp.kind === 'enum' ||\n codeConnectProp.kind === 'string'\n ) {\n const codeConnectFigmaPropName = codeConnectProp?.args?.figmaPropName\n\n if (\n !document.componentPropertyDefinitions ||\n !Object.keys(document.componentPropertyDefinitions).find((figmaProp) =>\n propMatches(figmaProp, codeConnectFigmaPropName, document.componentPropertyDefinitions),\n )\n ) {\n logger.error(\n `Validation failed for ${doc.component} (${doc.figmaNode}): The property \"${codeConnectFigmaPropName}\" does not exist on the Figma component`,\n )\n propsValid = false\n }\n }\n }\n\n if (!propsValid) {\n return false\n }\n }\n return true\n}\n\nfunction getPropName(componentPropertyDefinitions: any, propName: string): string {\n const prop = componentPropertyDefinitions[propName]\n if (prop.type === 'VARIANT') {\n return propName\n }\n\n // non Variant Keys are of the form \"name#id\"\n // We have to take the last one in case the name contains #'s\n const lastIndex = propName.lastIndexOf('#')\n if (lastIndex !== -1) {\n return propName.substring(0, lastIndex)\n }\n return propName\n}\n\nfunction propMatches(\n figmaProp: any,\n codeConnectPropName: string,\n componentPropertyDefinitions: any,\n): boolean {\n const figmaPropName = getPropName(componentPropertyDefinitions, figmaProp)\n return figmaPropName === codeConnectPropName\n}\n\n\n\n\nexport const STATE_BOOLEAN_VALUE_PAIRS = [\n ['yes', 'no'],\n ['true', 'false'],\n ['on', 'off'],\n]\n\nfunction isVariantBoolean(variantPossibleValues: string[]) {\n if (variantPossibleValues.length === 2) {\n const lowerCaseOptions = variantPossibleValues.map((p) => p.toLowerCase())\n for (const pair of STATE_BOOLEAN_VALUE_PAIRS) {\n const i = lowerCaseOptions.indexOf(pair[0]!)\n const j = lowerCaseOptions.indexOf(pair[1]!)\n if (i !== -1 && j !== -1) {\n return true\n }\n }\n }\n return false\n}\n\nfunction validateVariantRestrictions(doc: CodeConnectJSON, document: any): boolean {\n if (doc.variant) {\n let variantRestrictionsValid = true\n const codeConnectVariantRestrictions = Object.keys(doc.variant)\n\n for (let i = 0; i < codeConnectVariantRestrictions.length; i++) {\n const variantRestriction: any = codeConnectVariantRestrictions[i]\n\n const match = Object.keys(document.componentPropertyDefinitions ?? {}).find((figmaProp) =>\n propMatches(figmaProp, variantRestriction, document.componentPropertyDefinitions),\n )\n if (!match) {\n logger.error(\n `Validation failed for ${doc.component} (${doc.figmaNode}): The property \"${variantRestriction}\" does not exist on the Figma component`,\n )\n variantRestrictionsValid = false\n continue\n }\n\n const variantRestrictionValue = doc.variant[variantRestriction]\n const variantOrProp = document.componentPropertyDefinitions[match]\n\n // Only check `variantOptions` for Variants, and not for props, since props\n // don't have a set of possible values we can check against\n const isValidBooleanVariant =\n typeof variantRestrictionValue === 'boolean' &&\n Array.isArray(variantOrProp.variantOptions) &&\n isVariantBoolean(variantOrProp.variantOptions)\n\n const isValidVariantValue =\n variantOrProp.variantOptions?.includes(variantRestrictionValue) || isValidBooleanVariant\n\n if (variantOrProp.type === 'VARIANT' && !isValidVariantValue) {\n logger.error(\n `Validation failed for ${doc.component} (${doc.figmaNode}): The Figma Variant \"${match}\" does not have an option for ${variantRestrictionValue}`,\n )\n variantRestrictionsValid = false\n continue\n }\n }\n\n if (!variantRestrictionsValid) {\n return false\n }\n }\n return true\n}\n\nexport function validateDoc(doc: CodeConnectJSON, figmaNode: any, nodeId: string): boolean {\n if (!figmaNode || !figmaNode.document) {\n logger.error(\n `Validation failed for ${doc.component} (${doc.figmaNode}): node not found in file`,\n )\n return false\n }\n\n const document = figmaNode.document\n if (document.type !== 'COMPONENT' && document.type !== 'COMPONENT_SET') {\n logger.error(\n `Validation failed for ${doc.component} (${doc.figmaNode}): corresponding node is not a component or component set`,\n )\n return false\n }\n\n const component = figmaNode.components[nodeId]\n if (component && component.componentSetId) {\n logger.error(\n `Validation failed for ${doc.component} (${doc.figmaNode}): node is not a top level component or component set. Please check that the node is not a variant`,\n )\n return false\n }\n\n const propsValid = validateProps(doc, document)\n if (!propsValid) {\n return false\n }\n\n const variantRestrictionsValid = validateVariantRestrictions(doc, document)\n if (!variantRestrictionsValid) {\n return false\n }\n\n return true\n}\n\nexport async function validateDocs(\n cmd: BaseCommand,\n accessToken: string,\n docs: CodeConnectJSON[],\n apiUrlOverride?: string,\n): Promise<boolean> {\n let baseApiUrl = getApiUrl(docs?.[0]?.figmaNode ?? '', apiUrlOverride) + '/files/'\n\n const fileKeyToNodeIds: { [key: string]: any } = {}\n let valid = true\n docs.forEach((doc) => {\n const parsedNode = parseFigmaNode(cmd.verbose, doc)\n if (!parsedNode) {\n valid = false\n return\n }\n fileKeyToNodeIds[parsedNode.fileKey] ||= {}\n fileKeyToNodeIds[parsedNode.fileKey][parsedNode.nodeId] ||= []\n fileKeyToNodeIds[parsedNode.fileKey][parsedNode.nodeId].push(doc)\n })\n\n if (!valid) {\n return false\n }\n\n logger.debug('fileKeyToNodeIds')\n logger.debug(JSON.stringify(fileKeyToNodeIds, null, 2))\n\n const fileKeys = Object.keys(fileKeyToNodeIds)\n for (let i = 0; i < fileKeys.length; i++) {\n const fileKey = fileKeys[i]\n logger.debug(`Validating file ${fileKey}`)\n const nodeMap = fileKeyToNodeIds[fileKey]\n const nodeIds = Object.keys(nodeMap)\n logger.debug(`Validating ${nodeIds.length} nodes`)\n const chunks = chunk(nodeIds, 400)\n\n for (let batch = 0; batch < chunks.length; batch++) {\n const nodeIdsChunk = chunks[batch]\n logger.debug(`Running for ${baseApiUrl + fileKey + '/nodes?ids=' + nodeIdsChunk.join(',')}`)\n const nodeMapRet = await fetchNodeInfo(baseApiUrl, fileKey, nodeIdsChunk, accessToken)\n if (!nodeMapRet) {\n return false\n }\n\n valid =\n valid &&\n nodeIdsChunk\n .map((nodeId: string) => {\n return nodeMap[nodeId]\n .map((doc: CodeConnectJSON) => validateDoc(doc, nodeMapRet[nodeId], nodeId))\n .every(Boolean)\n })\n .every(Boolean)\n }\n }\n return valid\n}\n"]}
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/connect/validation.ts"],"names":[],"mappings":"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","sourcesContent":["import * as url from 'url'\nimport { chunk } from 'lodash'\n\nimport { CodeConnectJSON } from '../connect/figma_connect'\nimport { logger } from '../common/logging'\nimport { validateNodeId } from './helpers'\nimport { getApiUrl, getHeaders } from './figma_rest_api'\nimport type { BaseCommand } from '../commands/connect'\nimport { isFetchError, request } from '../common/fetch'\n\nexport function parseFigmaNode(\n verbose: boolean,\n doc: CodeConnectJSON,\n silent: boolean = false,\n): { fileKey: string; nodeId: string } | null {\n const figmaNodeUrl = url.parse(doc.figmaNode, true)\n const fileKeyMatch = figmaNodeUrl.path?.match(/(file|design)\\/([a-zA-Z0-9]+)/)\n if (!fileKeyMatch) {\n if (!silent || verbose) {\n logger.error(`Failed to parse ${doc.figmaNode}`)\n }\n return null\n }\n const fileKey = fileKeyMatch[2]\n const nodeId = figmaNodeUrl.query['node-id']\n if (nodeId && typeof nodeId === 'string') {\n const figmaNodeId = validateNodeId(nodeId)\n return { fileKey, nodeId: figmaNodeId }\n } else {\n if (!silent || verbose) {\n logger.error(`Failed to get node-id from ${doc.figmaNode}`)\n }\n return null\n }\n}\n\nasync function fetchNodeInfo(\n baseApiUrl: string,\n fileKey: string,\n nodeIdsChunk: string[],\n accessToken: string,\n useOAuth = false,\n): Promise<any> {\n try {\n const response = await request.get<{ message: string; nodes: any }>(\n `${baseApiUrl}${fileKey}/nodes?ids=${nodeIdsChunk.join(',')}`,\n { headers: getHeaders(accessToken, useOAuth) },\n )\n if (response.response.status !== 200) {\n logger.error(\n 'Failed to fetch node info: ' + response.response.status + ' ' + response.data?.message,\n )\n return null\n }\n return response.data.nodes\n } catch (err) {\n if (isFetchError(err)) {\n if (err.response) {\n logger.error(\n `Failed to to fetch node info (${err.response.status}): ${err.response.status} ${err.data?.err ?? err.data?.message}`,\n )\n } else {\n logger.error(`Failed to to fetch node info: ${err.message}`)\n }\n logger.debug(JSON.stringify(err.data))\n } else {\n logger.error(`Failed to to fetch node info: ${err}`)\n }\n return null\n }\n}\n\nfunction validateProps(doc: CodeConnectJSON, document: any): boolean {\n if (doc.templateData && doc.templateData?.props) {\n let propsValid = true\n const codeConnectProps = Object.keys(doc.templateData.props ?? {})\n\n for (let i = 0; i < codeConnectProps.length; i++) {\n const codeConnectProp = doc.templateData?.props[codeConnectProps[i]]\n if (codeConnectProp.kind === 'children') {\n const codeConnectLayerNames = codeConnectProp.args.layers\n // Get all layer names in the figma doc\n const figmaLayerNames: string[] = []\n const getLayerNames = (layer: any) => {\n if (layer.name) {\n figmaLayerNames.push(layer.name)\n }\n if (layer.children) {\n layer.children.forEach((child: any) => getLayerNames(child))\n }\n }\n getLayerNames(document)\n // And make sure that the layer names in the code connect file are present in the figma doc\n for (const codeConnectLayerName of codeConnectLayerNames) {\n const regex = new RegExp('^' + codeConnectLayerName.replace('*', '.*'))\n if (figmaLayerNames.every((name) => !regex.test(name))) {\n logger.error(\n `Validation failed for ${doc.component} (${doc.figmaNode}): The layer \"${codeConnectLayerName}\" does not exist on the Figma component`,\n )\n propsValid = false\n }\n }\n continue\n }\n if (\n codeConnectProp.kind === 'boolean' ||\n codeConnectProp.kind === 'enum' ||\n codeConnectProp.kind === 'string'\n ) {\n const codeConnectFigmaPropName = codeConnectProp?.args?.figmaPropName\n\n if (\n !document.componentPropertyDefinitions ||\n !Object.keys(document.componentPropertyDefinitions).find((figmaProp) =>\n propMatches(figmaProp, codeConnectFigmaPropName, document.componentPropertyDefinitions),\n )\n ) {\n logger.error(\n `Validation failed for ${doc.component} (${doc.figmaNode}): The property \"${codeConnectFigmaPropName}\" does not exist on the Figma component`,\n )\n propsValid = false\n }\n }\n }\n\n if (!propsValid) {\n return false\n }\n }\n return true\n}\n\nfunction getPropName(componentPropertyDefinitions: any, propName: string): string {\n const prop = componentPropertyDefinitions[propName]\n if (prop.type === 'VARIANT') {\n return propName\n }\n\n // non Variant Keys are of the form \"name#id\"\n // We have to take the last one in case the name contains #'s\n const lastIndex = propName.lastIndexOf('#')\n if (lastIndex !== -1) {\n return propName.substring(0, lastIndex)\n }\n return propName\n}\n\nfunction propMatches(\n figmaProp: any,\n codeConnectPropName: string,\n componentPropertyDefinitions: any,\n): boolean {\n const figmaPropName = getPropName(componentPropertyDefinitions, figmaProp)\n return figmaPropName === codeConnectPropName\n}\n\n\n\n\nexport const STATE_BOOLEAN_VALUE_PAIRS = [\n ['yes', 'no'],\n ['true', 'false'],\n ['on', 'off'],\n]\n\nfunction isVariantBoolean(variantPossibleValues: string[]) {\n if (variantPossibleValues.length === 2) {\n const lowerCaseOptions = variantPossibleValues.map((p) => p.toLowerCase())\n for (const pair of STATE_BOOLEAN_VALUE_PAIRS) {\n const i = lowerCaseOptions.indexOf(pair[0]!)\n const j = lowerCaseOptions.indexOf(pair[1]!)\n if (i !== -1 && j !== -1) {\n return true\n }\n }\n }\n return false\n}\n\nfunction validateVariantRestrictions(doc: CodeConnectJSON, document: any): boolean {\n if (doc.variant) {\n let variantRestrictionsValid = true\n const codeConnectVariantRestrictions = Object.keys(doc.variant)\n\n for (let i = 0; i < codeConnectVariantRestrictions.length; i++) {\n const variantRestriction: any = codeConnectVariantRestrictions[i]\n\n const match = Object.keys(document.componentPropertyDefinitions ?? {}).find((figmaProp) =>\n propMatches(figmaProp, variantRestriction, document.componentPropertyDefinitions),\n )\n if (!match) {\n logger.error(\n `Validation failed for ${doc.component} (${doc.figmaNode}): The property \"${variantRestriction}\" does not exist on the Figma component`,\n )\n variantRestrictionsValid = false\n continue\n }\n\n const variantRestrictionValue = doc.variant[variantRestriction]\n const variantOrProp = document.componentPropertyDefinitions[match]\n\n // Only check `variantOptions` for Variants, and not for props, since props\n // don't have a set of possible values we can check against\n const isValidBooleanVariant =\n typeof variantRestrictionValue === 'boolean' &&\n Array.isArray(variantOrProp.variantOptions) &&\n isVariantBoolean(variantOrProp.variantOptions)\n\n const isValidVariantValue =\n variantOrProp.variantOptions?.includes(variantRestrictionValue) || isValidBooleanVariant\n\n if (variantOrProp.type === 'VARIANT' && !isValidVariantValue) {\n logger.error(\n `Validation failed for ${doc.component} (${doc.figmaNode}): The Figma Variant \"${match}\" does not have an option for ${variantRestrictionValue}`,\n )\n variantRestrictionsValid = false\n continue\n }\n }\n\n if (!variantRestrictionsValid) {\n return false\n }\n }\n return true\n}\n\nexport function validateDoc(doc: CodeConnectJSON, figmaNode: any, nodeId: string): boolean {\n if (!figmaNode || !figmaNode.document) {\n logger.error(\n `Validation failed for ${doc.component} (${doc.figmaNode}): node not found in file`,\n )\n return false\n }\n\n const document = figmaNode.document\n if (document.type !== 'COMPONENT' && document.type !== 'COMPONENT_SET') {\n logger.error(\n `Validation failed for ${doc.component} (${doc.figmaNode}): corresponding node is not a component or component set`,\n )\n return false\n }\n\n const component = figmaNode.components[nodeId]\n if (component && component.componentSetId) {\n logger.error(\n `Validation failed for ${doc.component} (${doc.figmaNode}): node is not a top level component or component set. Please check that the node is not a variant`,\n )\n return false\n }\n\n const propsValid = validateProps(doc, document)\n if (!propsValid) {\n return false\n }\n\n const variantRestrictionsValid = validateVariantRestrictions(doc, document)\n if (!variantRestrictionsValid) {\n return false\n }\n\n return true\n}\n\nexport async function validateDocs(\n cmd: BaseCommand,\n accessToken: string,\n docs: CodeConnectJSON[],\n apiUrlOverride?: string,\n useOAuth = false,\n): Promise<boolean> {\n let baseApiUrl = getApiUrl(docs?.[0]?.figmaNode ?? '', apiUrlOverride) + '/files/'\n\n const fileKeyToNodeIds: { [key: string]: any } = {}\n let valid = true\n docs.forEach((doc) => {\n const parsedNode = parseFigmaNode(cmd.verbose, doc)\n if (!parsedNode) {\n valid = false\n return\n }\n fileKeyToNodeIds[parsedNode.fileKey] ||= {}\n fileKeyToNodeIds[parsedNode.fileKey][parsedNode.nodeId] ||= []\n fileKeyToNodeIds[parsedNode.fileKey][parsedNode.nodeId].push(doc)\n })\n\n if (!valid) {\n return false\n }\n\n logger.debug('fileKeyToNodeIds')\n logger.debug(JSON.stringify(fileKeyToNodeIds, null, 2))\n\n const fileKeys = Object.keys(fileKeyToNodeIds)\n for (let i = 0; i < fileKeys.length; i++) {\n const fileKey = fileKeys[i]\n logger.debug(`Validating file ${fileKey}`)\n const nodeMap = fileKeyToNodeIds[fileKey]\n const nodeIds = Object.keys(nodeMap)\n logger.debug(`Validating ${nodeIds.length} nodes`)\n const chunks = chunk(nodeIds, 400)\n\n for (let batch = 0; batch < chunks.length; batch++) {\n const nodeIdsChunk = chunks[batch]\n logger.debug(`Running for ${baseApiUrl + fileKey + '/nodes?ids=' + nodeIdsChunk.join(',')}`)\n const nodeMapRet = await fetchNodeInfo(\n baseApiUrl,\n fileKey,\n nodeIdsChunk,\n accessToken,\n useOAuth,\n )\n if (!nodeMapRet) {\n return false\n }\n\n valid =\n valid &&\n nodeIdsChunk\n .map((nodeId: string) => {\n return nodeMap[nodeId]\n .map((doc: CodeConnectJSON) => validateDoc(doc, nodeMapRet[nodeId], nodeId))\n .every(Boolean)\n })\n .every(Boolean)\n }\n }\n return valid\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/connect/wizard/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import * as prettier from 'prettier'\nimport fs from 'fs'\nimport {\n CodeConnectConfig,\n CodeConnectParser,\n DEFAULT_INCLUDE_GLOBS_BY_PARSER,\n DEFAULT_LABEL_PER_PARSER,\n ProjectInfo,\n ReactProjectInfo,\n getDefaultConfigPath,\n getEnvPath,\n} from '../project'\nimport { exitWithError, logger, success } from '../../common/logging'\nimport path from 'path'\nimport prompts, { Choice } from 'prompts'\nimport { BaseCommand } from '../../commands/connect'\nimport { isFigmaConnectFile } from '../parser_common'\nimport { parseFileKey } from '../helpers'\n\nexport function maybePrefillWizardQuestionsForTesting() {\n if (process.env.JEST_WORKER_ID && process.env.WIZARD_ANSWERS_TO_PREFILL) {\n const unescapedJson = JSON.parse(process.env.WIZARD_ANSWERS_TO_PREFILL.replace(/\\\\\"/g, '\"'))\n prompts.inject(unescapedJson)\n }\n}\n\n/**\n *\n * Gets the default include globs for config.parser with componentDirectory prepended\n * @param args\n * @param args.dir project root path\n * @param args.componentDirectory optional path to where includes should be limited to\n * @param args.config CodeConnectConfig\n * @returns array of include globs\n */\nexport function getIncludesGlob({\n dir,\n componentDirectory,\n config,\n}: {\n dir: string\n componentDirectory: string | null\n config: CodeConnectConfig\n}) {\n if (componentDirectory) {\n // use unix separators for config file globs\n const pathToComponentsDir = path.relative(dir, componentDirectory).replaceAll(path.sep, '/')\n if (config.parser === 'custom') {\n return []\n }\n return DEFAULT_INCLUDE_GLOBS_BY_PARSER[config.parser].map(\n (defaultIncludeGlob) => `${pathToComponentsDir}/${defaultIncludeGlob}`,\n )\n }\n return DEFAULT_INCLUDE_GLOBS_BY_PARSER[config.parser]\n}\n\nexport async function createEnvFile({ dir, accessToken }: { dir: string; accessToken?: string }) {\n // Create .env file\n const filePath = getDefaultConfigPath(dir)\n fs.writeFileSync(getEnvPath(dir), `FIGMA_ACCESS_TOKEN=\"${accessToken}\"`)\n logger.info(success(`Created ${filePath}`))\n}\n\nexport function addTokenToEnvFile({ dir, accessToken }: { dir: string; accessToken?: string }) {\n const filePath = getDefaultConfigPath(dir)\n fs.appendFileSync(getEnvPath(dir), `\\nFIGMA_ACCESS_TOKEN=\"${accessToken}\"`)\n logger.info(success(`Appended access token to ${filePath}`))\n}\n\nexport async function createCodeConnectConfig({\n dir,\n componentDirectory,\n config,\n figmaUrl,\n}: {\n dir: string\n componentDirectory: string | null\n config: CodeConnectConfig\n figmaUrl: string\n}) {\n const label = DEFAULT_LABEL_PER_PARSER[config.parser as CodeConnectParser]\n const includesGlob = getIncludesGlob({ dir, componentDirectory, config })\n\n const configJson = label\n ? `{\n \"codeConnect\": {\n \"include\": [\"${includesGlob}\"],\n \"label\": \"${label}\",\n \"interactiveSetupFigmaFileUrl\": \"${figmaUrl}\",\n}\n}`\n : `{\n \"codeConnect\": {\n \"include\": [\"${includesGlob}\"],\n \"interactiveSetupFigmaFileUrl\": \"${figmaUrl}\",\n }\n}`\n\n const formatted = await prettier.format(configJson, {\n parser: 'json',\n })\n const filePath = getDefaultConfigPath(dir)\n\n fs.writeFileSync(filePath, formatted)\n\n logger.info(success(`Created ${filePath}`))\n}\n\nconst FILEPATH_EXPORT_DELIMITER = '~'\n\nexport function parseFilepathExport(filepathExport: string) {\n const delimiterLastIndex = filepathExport.lastIndexOf(FILEPATH_EXPORT_DELIMITER)\n\n if (delimiterLastIndex === -1) {\n return {\n filepath: filepathExport,\n exportName: null,\n }\n }\n return {\n filepath: filepathExport.substring(0, delimiterLastIndex),\n exportName: filepathExport.substring(delimiterLastIndex + 1),\n }\n}\n\nexport function getFilepathExport(filepath: string, exp: string) {\n return `${filepath}${FILEPATH_EXPORT_DELIMITER}${exp}`\n}\n\n/**\n * Formats an array of filepathExports into a map of filepaths->exports\n *\n * @param filepathExports an array of components in the format `${filepath}~${componentName}\n * @returns a map of filepaths to an array of their exports. Array is empty if no exports found\n */\nexport function getComponentOptionsMap(filepathExports: string[]) {\n return filepathExports.reduce(\n (acc, filepathExport) => {\n const { filepath, exportName } = parseFilepathExport(filepathExport)\n acc[filepath] = acc[filepath] || []\n if (exportName) {\n acc[filepath].push({\n title: exportName,\n value: getFilepathExport(filepath, exportName),\n })\n }\n return acc\n },\n {} as Record<string, Choice[]>,\n )\n}\n\n/**\n * Parses a ProjectInfo for any TS exports (or filepaths if not a TS project)\n *\n * @param projectInfo\n * @returns an array of components in the format `${filepath}~${componentName}\n */\nexport function getFilepathExportsFromFiles(projectInfo: ProjectInfo, cmd: BaseCommand) {\n return projectInfo.files.reduce((options, filepath) => {\n if (projectInfo.config.parser === 'react') {\n const { tsProgram } = projectInfo as ReactProjectInfo\n if (!isFigmaConnectFile(tsProgram, filepath, 'tsx')) {\n const checker = tsProgram.getTypeChecker()\n const sourceFile = tsProgram.getSourceFile(filepath)\n if (!sourceFile) {\n if (cmd.verbose) {\n logger.warn(`Could not parse file for TypeScript: ${filepath}`)\n }\n } else {\n try {\n const sourceFileSymbol = checker.getSymbolAtLocation(sourceFile)!\n const exports = checker.getExportsOfModule(sourceFileSymbol)\n\n exports.forEach((exp) => {\n options.push(getFilepathExport(filepath, exp.getName()))\n })\n } catch (e) {\n if (cmd.verbose) {\n logger.warn(`Could not parse exports of file: ${filepath}`)\n }\n // ignore invalid files\n }\n }\n }\n } else {\n options.push(filepath)\n }\n return options\n }, [] as string[])\n}\n\nexport function isValidFigmaUrl(url: string) {\n try {\n const { hostname } = new URL(url)\n if (\n !hostname.includes('figma.com')\n ) {\n return false\n }\n\n return !!parseFileKey(url)\n } catch (e) {\n return false\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/connect/wizard/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import * as prettier from 'prettier'\nimport fs from 'fs'\nimport {\n CodeConnectConfig,\n CodeConnectParser,\n DEFAULT_INCLUDE_GLOBS_BY_PARSER,\n DEFAULT_LABEL_PER_PARSER,\n ProjectInfo,\n ReactProjectInfo,\n getDefaultConfigPath,\n getEnvPath,\n} from '../project'\nimport { exitWithError, logger, success } from '../../common/logging'\nimport path from 'path'\nimport prompts, { Choice } from 'prompts'\nimport { BaseCommand } from '../../commands/connect'\nimport { isFigmaConnectFile } from '../parser_common'\nimport { parseFileKey } from '../helpers'\n\nexport function maybePrefillWizardQuestionsForTesting() {\n if (process.env.JEST_WORKER_ID && process.env.WIZARD_ANSWERS_TO_PREFILL) {\n const unescapedJson = JSON.parse(process.env.WIZARD_ANSWERS_TO_PREFILL.replace(/\\\\\"/g, '\"'))\n prompts.inject(unescapedJson)\n }\n}\n\n/**\n *\n * Gets the default include globs for config.parser with componentDirectory prepended\n * @param args\n * @param args.dir project root path\n * @param args.componentDirectory optional path to where includes should be limited to\n * @param args.config CodeConnectConfig\n * @returns array of include globs\n */\nexport function getIncludesGlob({\n dir,\n componentDirectory,\n config,\n}: {\n dir: string\n componentDirectory: string | null\n config: CodeConnectConfig\n}) {\n if (componentDirectory) {\n // use unix separators for config file globs\n const pathToComponentsDir = path.relative(dir, componentDirectory).replaceAll(path.sep, '/')\n if (config.parser === 'custom') {\n return []\n }\n return DEFAULT_INCLUDE_GLOBS_BY_PARSER[config.parser!].map(\n (defaultIncludeGlob) => `${pathToComponentsDir}/${defaultIncludeGlob}`,\n )\n }\n return DEFAULT_INCLUDE_GLOBS_BY_PARSER[config.parser!]\n}\n\nexport async function createEnvFile({ dir, accessToken }: { dir: string; accessToken?: string }) {\n // Create .env file\n const filePath = getDefaultConfigPath(dir)\n fs.writeFileSync(getEnvPath(dir), `FIGMA_ACCESS_TOKEN=\"${accessToken}\"`)\n logger.info(success(`Created ${filePath}`))\n}\n\nexport function addTokenToEnvFile({ dir, accessToken }: { dir: string; accessToken?: string }) {\n const filePath = getDefaultConfigPath(dir)\n fs.appendFileSync(getEnvPath(dir), `\\nFIGMA_ACCESS_TOKEN=\"${accessToken}\"`)\n logger.info(success(`Appended access token to ${filePath}`))\n}\n\nexport async function createCodeConnectConfig({\n dir,\n componentDirectory,\n config,\n figmaUrl,\n}: {\n dir: string\n componentDirectory: string | null\n config: CodeConnectConfig\n figmaUrl: string\n}) {\n const label = DEFAULT_LABEL_PER_PARSER[config.parser as CodeConnectParser]\n const includesGlob = getIncludesGlob({ dir, componentDirectory, config })\n\n const configJson = label\n ? `{\n \"codeConnect\": {\n \"include\": [\"${includesGlob}\"],\n \"label\": \"${label}\",\n \"interactiveSetupFigmaFileUrl\": \"${figmaUrl}\",\n}\n}`\n : `{\n \"codeConnect\": {\n \"include\": [\"${includesGlob}\"],\n \"interactiveSetupFigmaFileUrl\": \"${figmaUrl}\",\n }\n}`\n\n const formatted = await prettier.format(configJson, {\n parser: 'json',\n })\n const filePath = getDefaultConfigPath(dir)\n\n fs.writeFileSync(filePath, formatted)\n\n logger.info(success(`Created ${filePath}`))\n}\n\nconst FILEPATH_EXPORT_DELIMITER = '~'\n\nexport function parseFilepathExport(filepathExport: string) {\n const delimiterLastIndex = filepathExport.lastIndexOf(FILEPATH_EXPORT_DELIMITER)\n\n if (delimiterLastIndex === -1) {\n return {\n filepath: filepathExport,\n exportName: null,\n }\n }\n return {\n filepath: filepathExport.substring(0, delimiterLastIndex),\n exportName: filepathExport.substring(delimiterLastIndex + 1),\n }\n}\n\nexport function getFilepathExport(filepath: string, exp: string) {\n return `${filepath}${FILEPATH_EXPORT_DELIMITER}${exp}`\n}\n\n/**\n * Formats an array of filepathExports into a map of filepaths->exports\n *\n * @param filepathExports an array of components in the format `${filepath}~${componentName}\n * @returns a map of filepaths to an array of their exports. Array is empty if no exports found\n */\nexport function getComponentOptionsMap(filepathExports: string[]) {\n return filepathExports.reduce(\n (acc, filepathExport) => {\n const { filepath, exportName } = parseFilepathExport(filepathExport)\n acc[filepath] = acc[filepath] || []\n if (exportName) {\n acc[filepath].push({\n title: exportName,\n value: getFilepathExport(filepath, exportName),\n })\n }\n return acc\n },\n {} as Record<string, Choice[]>,\n )\n}\n\n/**\n * Parses a ProjectInfo for any TS exports (or filepaths if not a TS project)\n *\n * @param projectInfo\n * @returns an array of components in the format `${filepath}~${componentName}\n */\nexport function getFilepathExportsFromFiles(projectInfo: ProjectInfo, cmd: BaseCommand) {\n return projectInfo.files.reduce((options, filepath) => {\n if (projectInfo.config.parser === 'react') {\n const { tsProgram } = projectInfo as ReactProjectInfo\n if (!isFigmaConnectFile(tsProgram, filepath, 'tsx')) {\n const checker = tsProgram.getTypeChecker()\n const sourceFile = tsProgram.getSourceFile(filepath)\n if (!sourceFile) {\n if (cmd.verbose) {\n logger.warn(`Could not parse file for TypeScript: ${filepath}`)\n }\n } else {\n try {\n const sourceFileSymbol = checker.getSymbolAtLocation(sourceFile)!\n const exports = checker.getExportsOfModule(sourceFileSymbol)\n\n exports.forEach((exp) => {\n options.push(getFilepathExport(filepath, exp.getName()))\n })\n } catch (e) {\n if (cmd.verbose) {\n logger.warn(`Could not parse exports of file: ${filepath}`)\n }\n // ignore invalid files\n }\n }\n }\n } else {\n options.push(filepath)\n }\n return options\n }, [] as string[])\n}\n\nexport function isValidFigmaUrl(url: string) {\n try {\n const { hostname } = new URL(url)\n if (\n !hostname.includes('figma.com')\n ) {\n return false\n }\n\n return !!parseFileKey(url)\n } catch (e) {\n return false\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/storybook/convert.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,gBAAgB,EAGjB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAc1D,UAAU,yBAAyB;IACjC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;OAEG;IACH,WAAW,EAAE,gBAAgB,CAAA;IAE7B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CAAC,EAC1C,WAAW,EACX,
|
|
1
|
+
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/storybook/convert.ts"],"names":[],"mappings":"AAaA,OAAO,EAEL,gBAAgB,EAGjB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAc1D,UAAU,yBAAyB;IACjC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;OAEG;IACH,WAAW,EAAE,gBAAgB,CAAA;IAE7B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CAAC,EAC1C,WAAW,EACX,WAA4C,EAC5C,cAAsB,GACvB,EAAE,yBAAyB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAoBxD"}
|
|
@@ -22,7 +22,7 @@ const parser_common_1 = require("../connect/parser_common");
|
|
|
22
22
|
* @param args
|
|
23
23
|
* @returns An array of Code Connect objects
|
|
24
24
|
*/
|
|
25
|
-
async function convertStorybookFiles({ projectInfo, storiesGlob = '**/*.stories.tsx', isForMigration = false, }) {
|
|
25
|
+
async function convertStorybookFiles({ projectInfo, storiesGlob = '**/*.stories.{tsx,ts,jsx,js}', isForMigration = false, }) {
|
|
26
26
|
const { remoteUrl, config, files, tsProgram } = projectInfo;
|
|
27
27
|
const storyFiles = files.filter((file) => (0, minimatch_1.minimatch)(file, storiesGlob, { matchBase: true }));
|
|
28
28
|
logging_1.logger.debug(`Story files found:\n${storyFiles.map((f) => `- ${f}`).join('\n')}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../../src/storybook/convert.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync } from 'fs'\nimport {\n bfsFindNode,\n convertObjectLiteralToJs,\n getDefaultExport,\n parsePropertyOfType,\n} from '../typescript/compiler'\nimport {\n parseComponentMetadata,\n parseJSXRenderFunction,\n getDefaultTemplate,\n findAndResolveImports,\n} from '../react/parser'\nimport {\n CodeConnectReactConfig,\n ReactProjectInfo,\n getRemoteFileUrl,\n getStorybookUrl,\n} from '../connect/project'\nimport { logger } from '../common/logging'\nimport { CodeConnectJSON } from '../connect/figma_connect'\nimport { CodeConnectLabel, SyntaxHighlightLanguage } from '../connect/label_language_mapping'\nimport ts from 'typescript'\nimport { FigmaConnectLink, FigmaConnectMeta } from '../connect/api'\nimport { minimatch } from 'minimatch'\nimport { parsePropsObject } from '../connect/intrinsics'\nimport {\n InternalError,\n parseImports,\n parseLinks,\n ParserContext,\n ParserError,\n} from '../connect/parser_common'\n\ninterface ConvertStorybookFilesArgs {\n /**\n * Optionally override the glob used to find stories. This is currently not\n * exposed in the config, but is used by the tests\n */\n storiesGlob?: string\n\n /**\n * Information about the project\n */\n projectInfo: ReactProjectInfo\n\n /**\n * Whether this conversion is for the migrate command. When true, template\n * helper function definitions are omitted from the template (they will be\n * replaced by server-side helpers during migration).\n */\n isForMigration?: boolean\n}\n\n/**\n * Converts all Storyboook files in a directory into Code Connect objects. If a file\n * cannot be converted (e.g. unsupported syntax), it is ignored and an error is\n * logged.\n *\n * @param args\n * @returns An array of Code Connect objects\n */\nexport async function convertStorybookFiles({\n projectInfo,\n storiesGlob = '**/*.stories.tsx',\n isForMigration = false,\n}: ConvertStorybookFilesArgs): Promise<CodeConnectJSON[]> {\n const { remoteUrl, config, files, tsProgram } = projectInfo\n\n const storyFiles = files.filter((file) => minimatch(file, storiesGlob, { matchBase: true }))\n logger.debug(`Story files found:\\n${storyFiles.map((f) => `- ${f}`).join('\\n')}`)\n\n return Promise.all(\n storyFiles.map((path) =>\n convertStorybookFile({\n path,\n tsProgram,\n config,\n remoteUrl,\n absPath: projectInfo.absPath,\n isForMigration,\n }),\n ),\n )\n .then((f) => f.filter((x): x is NonNullable<typeof x> => Boolean(x)))\n .then((f) => f.flat())\n}\n\ninterface FigmaStoryMetadata {\n type: string\n url: string\n}\n\ninterface ConvertStorybookFileArgs {\n path: string\n tsProgram: ts.Program\n remoteUrl: string\n config: CodeConnectReactConfig\n absPath: string\n isForMigration?: boolean\n}\n\ntype MappedPropType = 'FigmaString' | 'FigmaBoolean' | 'Mapped'\ntype MappedProps = Map<string, { figmaName: string; type: MappedPropType }> | undefined\n\nasync function convertStorybookFile({\n path,\n tsProgram,\n remoteUrl,\n config,\n absPath,\n isForMigration = false,\n}: ConvertStorybookFileArgs): Promise<CodeConnectJSON[] | undefined> {\n const checker = tsProgram.getTypeChecker()\n const sourceFile = tsProgram.getSourceFile(path)\n\n if (!sourceFile) {\n throw new InternalError(`Source file not found: ${path}`)\n }\n\n const parserContext: ParserContext = {\n checker,\n config,\n sourceFile,\n absPath,\n resolvedImports: findAndResolveImports(tsProgram, sourceFile),\n }\n\n let source = readFileSync(path).toString()\n // Replace backticks with ' as csf-tools can't parse dynamic titles\n source = source.replace(/title: `(.*)`/g, (_, title) => {\n return `title: '${title}'`\n })\n\n logger.debug(`Parsing story ${path}`)\n\n try {\n // We need to get the default export, which contains the story file meta,\n // from the TS Program rather than using `babelNodeToTsSourceFile(csf._metaNode)`,\n // because we need access to the full Program to parse it for prop types etc.\n const storyFileMetaNode = getDefaultExport(sourceFile)\n if (!storyFileMetaNode) {\n return\n }\n\n const parseResult = parseStoryMetadata(storyFileMetaNode, parserContext)\n\n if (!parseResult) {\n logger.debug(`Could not parse story metadata for ${path}`)\n return\n }\n\n const { figmaStoryMetadata, componentDeclaration, propMappings, examples, imports, links } =\n parseResult\n\n const componentMetadata = await parseComponentMetadata(componentDeclaration, parserContext)\n\n const codeConnectObjects: CodeConnectJSON[] = []\n const baseCodeConnect: CodeConnectJSON = {\n figmaNode: figmaStoryMetadata.url,\n source: config?.storybook?.url\n ? getStorybookUrl(componentMetadata.source, config.storybook.url)\n : getRemoteFileUrl(componentMetadata.source, remoteUrl, config?.defaultBranch),\n sourceLocation: { line: componentMetadata.line },\n template: '',\n templateData: {\n props: propMappings,\n imports,\n },\n links,\n component: componentMetadata.component,\n label: CodeConnectLabel.Storybook,\n language: SyntaxHighlightLanguage.TypeScript,\n metadata: {\n cliVersion: require('../../package.json').version,\n },\n }\n\n // If there are no examples, just return a default Code Connect object\n if (!examples) {\n codeConnectObjects.push({\n ...baseCodeConnect,\n template: getDefaultTemplate(componentMetadata),\n })\n return codeConnectObjects\n }\n\n for (const statement of sourceFile.statements) {\n // Find any exported function or variable declarations, which correspond to stories\n if (!(ts.isFunctionDeclaration(statement) || ts.isVariableStatement(statement))) {\n continue\n }\n\n const name = ts.isFunctionDeclaration(statement)\n ? statement.name?.text\n : statement.declarationList.declarations?.[0].name.getText(sourceFile)\n\n const example = examples?.find((example) => example.example === name)\n // This story is not in the examples array, so skip it\n if (examples && !example) {\n continue\n }\n\n let statementToParse: ts.ArrowFunction | ts.FunctionDeclaration | undefined\n\n if (ts.isFunctionDeclaration(statement)) {\n statementToParse = statement\n } else {\n const initializer = statement.declarationList.declarations[0].initializer\n if (initializer && ts.isArrowFunction(initializer)) {\n statementToParse = initializer\n } else if (initializer && ts.isObjectLiteralExpression(initializer)) {\n // Handle stories like `export const Primary = { render: () => <Button /> }`\n const renderProperty = parsePropertyOfType({\n objectLiteralNode: initializer,\n propertyName: 'render',\n predicate: ts.isArrowFunction,\n parserContext,\n required: true,\n })\n\n if (renderProperty) {\n statementToParse = renderProperty\n }\n }\n }\n\n if (!statementToParse) {\n throw new ParserError(\n 'Expected function declaration, arrow function or render function in story',\n {\n sourceFile,\n node: statement,\n },\n )\n }\n\n const exampleProps = example?.props ?? propMappings\n\n let render = parseJSXRenderFunction(\n statementToParse,\n parserContext,\n exampleProps,\n isForMigration,\n )\n\n if (!render) {\n continue\n }\n\n const template = render.code ?? `<${componentMetadata.component} />`\n\n // TODO handle JSDoc on stories\n codeConnectObjects.push({\n ...baseCodeConnect,\n template,\n variant: example?.variant,\n })\n }\n\n return codeConnectObjects\n } catch (e) {\n logger.error(`Error parsing story ${path}: ${e}`)\n throw e\n }\n}\n\n/**\n * Get the TS Node representing the component declaration from the story file\n *\n * @param objectLiteralNode Object literal containing the story file metadata\n * @returns TS Node representing the component declaration or undefined\n */\nfunction getComponentDeclaration(\n objectLiteralNode: ts.ObjectLiteralExpression,\n): ts.Expression | undefined {\n for (const property of objectLiteralNode.properties) {\n if (!ts.isPropertyAssignment(property)) continue\n const propertyName = property.name\n if (ts.isIdentifier(propertyName) && propertyName.text === 'component') {\n return property.initializer\n }\n }\n return undefined\n}\n\n/**\n * Validate and returns Figma metadata from the default export of the storybook\n * file\n *\n * @param storyFileMetaNode TS Node containing the story file metadata, i.e. the\n * default export of the file\n * @param sourceFile TS SourceFile representing a single story\n * @returns Figma metadata\n * @throws Error if no Figma metadata is found\n */\nfunction parseStoryMetadata(storyFileMetaNode: ts.Node, parserContext: ParserContext) {\n const { sourceFile, checker } = parserContext\n // Find the first object expression under tsSourceFile.statements[0],\n // which contains the story file metadata. We do it this way to allow syntax\n // like `export default ({ ... meta ... } as ComponentMeta<...>)`\n const objectLiteralNode = bfsFindNode(storyFileMetaNode, sourceFile, (node) =>\n ts.isObjectLiteralExpression(node),\n )\n\n if (!objectLiteralNode || !ts.isObjectLiteralExpression(objectLiteralNode)) {\n logger.debug(`No object literal found in story metadata`)\n return\n }\n\n const componentDeclaration = getComponentDeclaration(objectLiteralNode)\n if (!componentDeclaration) {\n logger.debug(`No component declaration found in story metadata`)\n return\n }\n\n const parametersNode = parsePropertyOfType({\n objectLiteralNode: objectLiteralNode,\n propertyName: 'parameters',\n predicate: ts.isObjectLiteralExpression,\n parserContext,\n required: false,\n })\n\n // If there's no parameters object, this file shouldn't be imported\n if (!parametersNode) {\n logger.debug(`No parameters object found in story metadata`)\n return\n }\n\n const designNode = parsePropertyOfType({\n objectLiteralNode: parametersNode,\n propertyName: 'design',\n predicate: ts.isObjectLiteralExpression,\n parserContext,\n required: false,\n })\n\n // If there's no design object, this file shouldn't be imported\n if (!designNode) {\n logger.debug(`No design object found in story metadata`)\n return\n }\n\n const typeNode = parsePropertyOfType({\n objectLiteralNode: designNode,\n propertyName: 'type',\n predicate: ts.isStringLiteral,\n parserContext,\n errorMessage: '\"type\" property not found in \"design\" object in story metadata',\n required: false,\n })\n\n // If the design is not a Figma design, this file shouldn't be imported\n if (!typeNode || typeNode.text !== 'figma') {\n logger.debug(`Design type is not figma`)\n return\n }\n\n const urlNode = parsePropertyOfType({\n objectLiteralNode: designNode,\n propertyName: 'url',\n predicate: ts.isStringLiteral,\n parserContext,\n errorMessage: '\"url\" property not found in \"design\" object in story metadata',\n required: true,\n })\n\n const figmaStoryMetadata: FigmaStoryMetadata = {\n type: typeNode.text,\n url: urlNode.text,\n }\n\n const propMappingNode = parsePropertyOfType({\n objectLiteralNode: designNode,\n propertyName: 'props',\n predicate: ts.isObjectLiteralExpression,\n parserContext,\n required: false,\n })\n\n const examplesNode = parsePropertyOfType({\n objectLiteralNode: designNode,\n propertyName: 'examples',\n predicate: ts.isArrayLiteralExpression,\n parserContext,\n required: false,\n })\n\n const importsNode = parsePropertyOfType({\n objectLiteralNode: designNode,\n propertyName: 'imports',\n predicate: ts.isArrayLiteralExpression,\n parserContext,\n required: false,\n errorMessage: `The 'imports' property must be an array literal. Example usage:\n\\`design: {\n type: 'figma',\n url: 'https://www.figma.com/file/123?node-id=1-1',\n examples: [Button],\n imports: [\n 'import { Button } from \"./Button\"'\n ],\n ...\n})\\``,\n })\n\n const linksNode = parsePropertyOfType({\n objectLiteralNode: designNode,\n propertyName: 'links',\n predicate: ts.isArrayLiteralExpression,\n parserContext,\n required: false,\n errorMessage: `The 'links' property must be an array literal. Example usage:\n\\`design: {\n type: 'figma',\n url: 'https://www.figma.com/file/123?node-id=1-1',\n examples: [Button],\n links: [\n { name: 'Storybook', url: 'https://storybook.com' }\n ],\n ...\n})\\``,\n })\n\n let links: FigmaConnectLink[] | undefined\n if (linksNode) {\n links = parseLinks(linksNode, parserContext)\n }\n\n let imports: string[] = []\n if (importsNode) {\n imports = parseImports(importsNode, parserContext)\n }\n\n let propMappings: {} | undefined\n let mappedProps: MappedProps\n\n if (propMappingNode) {\n mappedProps = new Map()\n propMappings = parsePropsObject(propMappingNode, parserContext)\n }\n\n type Example = {\n example: string\n variant?: FigmaConnectMeta['variant']\n props?: Record<string, any>\n }\n let examples: Example[] | undefined\n\n if (examplesNode) {\n examples = examplesNode.elements.map((exampleNode) => {\n if (ts.isStringLiteral(exampleNode) || ts.isIdentifier(exampleNode)) {\n return { example: exampleNode.text }\n }\n\n if (!ts.isObjectLiteralExpression(exampleNode)) {\n throw new ParserError(\n `Expected object literal in examples array, got: ${ts.SyntaxKind[exampleNode.kind]}`,\n {\n sourceFile,\n node: exampleNode,\n },\n )\n }\n\n return convertObjectLiteralToJs(exampleNode, sourceFile, checker, (node) => {\n if ((node.parent as ts.TypeParameterDeclaration)?.name?.escapedText === 'props') {\n if (ts.isObjectLiteralExpression(node)) {\n return parsePropsObject(node, parserContext)\n }\n }\n }) as Example\n })\n }\n\n return {\n figmaStoryMetadata,\n componentDeclaration,\n propMappings,\n mappedProps,\n examples,\n imports,\n links,\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"convert.js","sourceRoot":"","sources":["../../src/storybook/convert.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync } from 'fs'\nimport {\n bfsFindNode,\n convertObjectLiteralToJs,\n getDefaultExport,\n parsePropertyOfType,\n} from '../typescript/compiler'\nimport {\n parseComponentMetadata,\n parseJSXRenderFunction,\n getDefaultTemplate,\n findAndResolveImports,\n} from '../react/parser'\nimport {\n CodeConnectReactConfig,\n ReactProjectInfo,\n getRemoteFileUrl,\n getStorybookUrl,\n} from '../connect/project'\nimport { logger } from '../common/logging'\nimport { CodeConnectJSON } from '../connect/figma_connect'\nimport { CodeConnectLabel, SyntaxHighlightLanguage } from '../connect/label_language_mapping'\nimport ts from 'typescript'\nimport { FigmaConnectLink, FigmaConnectMeta } from '../connect/api'\nimport { minimatch } from 'minimatch'\nimport { parsePropsObject } from '../connect/intrinsics'\nimport {\n InternalError,\n parseImports,\n parseLinks,\n ParserContext,\n ParserError,\n} from '../connect/parser_common'\n\ninterface ConvertStorybookFilesArgs {\n /**\n * Optionally override the glob used to find stories. This is currently not\n * exposed in the config, but is used by the tests\n */\n storiesGlob?: string\n\n /**\n * Information about the project\n */\n projectInfo: ReactProjectInfo\n\n /**\n * Whether this conversion is for the migrate command. When true, template\n * helper function definitions are omitted from the template (they will be\n * replaced by server-side helpers during migration).\n */\n isForMigration?: boolean\n}\n\n/**\n * Converts all Storyboook files in a directory into Code Connect objects. If a file\n * cannot be converted (e.g. unsupported syntax), it is ignored and an error is\n * logged.\n *\n * @param args\n * @returns An array of Code Connect objects\n */\nexport async function convertStorybookFiles({\n projectInfo,\n storiesGlob = '**/*.stories.{tsx,ts,jsx,js}',\n isForMigration = false,\n}: ConvertStorybookFilesArgs): Promise<CodeConnectJSON[]> {\n const { remoteUrl, config, files, tsProgram } = projectInfo\n\n const storyFiles = files.filter((file) => minimatch(file, storiesGlob, { matchBase: true }))\n logger.debug(`Story files found:\\n${storyFiles.map((f) => `- ${f}`).join('\\n')}`)\n\n return Promise.all(\n storyFiles.map((path) =>\n convertStorybookFile({\n path,\n tsProgram,\n config,\n remoteUrl,\n absPath: projectInfo.absPath,\n isForMigration,\n }),\n ),\n )\n .then((f) => f.filter((x): x is NonNullable<typeof x> => Boolean(x)))\n .then((f) => f.flat())\n}\n\ninterface FigmaStoryMetadata {\n type: string\n url: string\n}\n\ninterface ConvertStorybookFileArgs {\n path: string\n tsProgram: ts.Program\n remoteUrl: string\n config: CodeConnectReactConfig\n absPath: string\n isForMigration?: boolean\n}\n\ntype MappedPropType = 'FigmaString' | 'FigmaBoolean' | 'Mapped'\ntype MappedProps = Map<string, { figmaName: string; type: MappedPropType }> | undefined\n\nasync function convertStorybookFile({\n path,\n tsProgram,\n remoteUrl,\n config,\n absPath,\n isForMigration = false,\n}: ConvertStorybookFileArgs): Promise<CodeConnectJSON[] | undefined> {\n const checker = tsProgram.getTypeChecker()\n const sourceFile = tsProgram.getSourceFile(path)\n\n if (!sourceFile) {\n throw new InternalError(`Source file not found: ${path}`)\n }\n\n const parserContext: ParserContext = {\n checker,\n config,\n sourceFile,\n absPath,\n resolvedImports: findAndResolveImports(tsProgram, sourceFile),\n }\n\n let source = readFileSync(path).toString()\n // Replace backticks with ' as csf-tools can't parse dynamic titles\n source = source.replace(/title: `(.*)`/g, (_, title) => {\n return `title: '${title}'`\n })\n\n logger.debug(`Parsing story ${path}`)\n\n try {\n // We need to get the default export, which contains the story file meta,\n // from the TS Program rather than using `babelNodeToTsSourceFile(csf._metaNode)`,\n // because we need access to the full Program to parse it for prop types etc.\n const storyFileMetaNode = getDefaultExport(sourceFile)\n if (!storyFileMetaNode) {\n return\n }\n\n const parseResult = parseStoryMetadata(storyFileMetaNode, parserContext)\n\n if (!parseResult) {\n logger.debug(`Could not parse story metadata for ${path}`)\n return\n }\n\n const { figmaStoryMetadata, componentDeclaration, propMappings, examples, imports, links } =\n parseResult\n\n const componentMetadata = await parseComponentMetadata(componentDeclaration, parserContext)\n\n const codeConnectObjects: CodeConnectJSON[] = []\n const baseCodeConnect: CodeConnectJSON = {\n figmaNode: figmaStoryMetadata.url,\n source: config?.storybook?.url\n ? getStorybookUrl(componentMetadata.source, config.storybook.url)\n : getRemoteFileUrl(componentMetadata.source, remoteUrl, config?.defaultBranch),\n sourceLocation: { line: componentMetadata.line },\n template: '',\n templateData: {\n props: propMappings,\n imports,\n },\n links,\n component: componentMetadata.component,\n label: CodeConnectLabel.Storybook,\n language: SyntaxHighlightLanguage.TypeScript,\n metadata: {\n cliVersion: require('../../package.json').version,\n },\n }\n\n // If there are no examples, just return a default Code Connect object\n if (!examples) {\n codeConnectObjects.push({\n ...baseCodeConnect,\n template: getDefaultTemplate(componentMetadata),\n })\n return codeConnectObjects\n }\n\n for (const statement of sourceFile.statements) {\n // Find any exported function or variable declarations, which correspond to stories\n if (!(ts.isFunctionDeclaration(statement) || ts.isVariableStatement(statement))) {\n continue\n }\n\n const name = ts.isFunctionDeclaration(statement)\n ? statement.name?.text\n : statement.declarationList.declarations?.[0].name.getText(sourceFile)\n\n const example = examples?.find((example) => example.example === name)\n // This story is not in the examples array, so skip it\n if (examples && !example) {\n continue\n }\n\n let statementToParse: ts.ArrowFunction | ts.FunctionDeclaration | undefined\n\n if (ts.isFunctionDeclaration(statement)) {\n statementToParse = statement\n } else {\n const initializer = statement.declarationList.declarations[0].initializer\n if (initializer && ts.isArrowFunction(initializer)) {\n statementToParse = initializer\n } else if (initializer && ts.isObjectLiteralExpression(initializer)) {\n // Handle stories like `export const Primary = { render: () => <Button /> }`\n const renderProperty = parsePropertyOfType({\n objectLiteralNode: initializer,\n propertyName: 'render',\n predicate: ts.isArrowFunction,\n parserContext,\n required: true,\n })\n\n if (renderProperty) {\n statementToParse = renderProperty\n }\n }\n }\n\n if (!statementToParse) {\n throw new ParserError(\n 'Expected function declaration, arrow function or render function in story',\n {\n sourceFile,\n node: statement,\n },\n )\n }\n\n const exampleProps = example?.props ?? propMappings\n\n let render = parseJSXRenderFunction(\n statementToParse,\n parserContext,\n exampleProps,\n isForMigration,\n )\n\n if (!render) {\n continue\n }\n\n const template = render.code ?? `<${componentMetadata.component} />`\n\n // TODO handle JSDoc on stories\n codeConnectObjects.push({\n ...baseCodeConnect,\n template,\n variant: example?.variant,\n })\n }\n\n return codeConnectObjects\n } catch (e) {\n logger.error(`Error parsing story ${path}: ${e}`)\n throw e\n }\n}\n\n/**\n * Get the TS Node representing the component declaration from the story file\n *\n * @param objectLiteralNode Object literal containing the story file metadata\n * @returns TS Node representing the component declaration or undefined\n */\nfunction getComponentDeclaration(\n objectLiteralNode: ts.ObjectLiteralExpression,\n): ts.Expression | undefined {\n for (const property of objectLiteralNode.properties) {\n if (!ts.isPropertyAssignment(property)) continue\n const propertyName = property.name\n if (ts.isIdentifier(propertyName) && propertyName.text === 'component') {\n return property.initializer\n }\n }\n return undefined\n}\n\n/**\n * Validate and returns Figma metadata from the default export of the storybook\n * file\n *\n * @param storyFileMetaNode TS Node containing the story file metadata, i.e. the\n * default export of the file\n * @param sourceFile TS SourceFile representing a single story\n * @returns Figma metadata\n * @throws Error if no Figma metadata is found\n */\nfunction parseStoryMetadata(storyFileMetaNode: ts.Node, parserContext: ParserContext) {\n const { sourceFile, checker } = parserContext\n // Find the first object expression under tsSourceFile.statements[0],\n // which contains the story file metadata. We do it this way to allow syntax\n // like `export default ({ ... meta ... } as ComponentMeta<...>)`\n const objectLiteralNode = bfsFindNode(storyFileMetaNode, sourceFile, (node) =>\n ts.isObjectLiteralExpression(node),\n )\n\n if (!objectLiteralNode || !ts.isObjectLiteralExpression(objectLiteralNode)) {\n logger.debug(`No object literal found in story metadata`)\n return\n }\n\n const componentDeclaration = getComponentDeclaration(objectLiteralNode)\n if (!componentDeclaration) {\n logger.debug(`No component declaration found in story metadata`)\n return\n }\n\n const parametersNode = parsePropertyOfType({\n objectLiteralNode: objectLiteralNode,\n propertyName: 'parameters',\n predicate: ts.isObjectLiteralExpression,\n parserContext,\n required: false,\n })\n\n // If there's no parameters object, this file shouldn't be imported\n if (!parametersNode) {\n logger.debug(`No parameters object found in story metadata`)\n return\n }\n\n const designNode = parsePropertyOfType({\n objectLiteralNode: parametersNode,\n propertyName: 'design',\n predicate: ts.isObjectLiteralExpression,\n parserContext,\n required: false,\n })\n\n // If there's no design object, this file shouldn't be imported\n if (!designNode) {\n logger.debug(`No design object found in story metadata`)\n return\n }\n\n const typeNode = parsePropertyOfType({\n objectLiteralNode: designNode,\n propertyName: 'type',\n predicate: ts.isStringLiteral,\n parserContext,\n errorMessage: '\"type\" property not found in \"design\" object in story metadata',\n required: false,\n })\n\n // If the design is not a Figma design, this file shouldn't be imported\n if (!typeNode || typeNode.text !== 'figma') {\n logger.debug(`Design type is not figma`)\n return\n }\n\n const urlNode = parsePropertyOfType({\n objectLiteralNode: designNode,\n propertyName: 'url',\n predicate: ts.isStringLiteral,\n parserContext,\n errorMessage: '\"url\" property not found in \"design\" object in story metadata',\n required: true,\n })\n\n const figmaStoryMetadata: FigmaStoryMetadata = {\n type: typeNode.text,\n url: urlNode.text,\n }\n\n const propMappingNode = parsePropertyOfType({\n objectLiteralNode: designNode,\n propertyName: 'props',\n predicate: ts.isObjectLiteralExpression,\n parserContext,\n required: false,\n })\n\n const examplesNode = parsePropertyOfType({\n objectLiteralNode: designNode,\n propertyName: 'examples',\n predicate: ts.isArrayLiteralExpression,\n parserContext,\n required: false,\n })\n\n const importsNode = parsePropertyOfType({\n objectLiteralNode: designNode,\n propertyName: 'imports',\n predicate: ts.isArrayLiteralExpression,\n parserContext,\n required: false,\n errorMessage: `The 'imports' property must be an array literal. Example usage:\n\\`design: {\n type: 'figma',\n url: 'https://www.figma.com/file/123?node-id=1-1',\n examples: [Button],\n imports: [\n 'import { Button } from \"./Button\"'\n ],\n ...\n})\\``,\n })\n\n const linksNode = parsePropertyOfType({\n objectLiteralNode: designNode,\n propertyName: 'links',\n predicate: ts.isArrayLiteralExpression,\n parserContext,\n required: false,\n errorMessage: `The 'links' property must be an array literal. Example usage:\n\\`design: {\n type: 'figma',\n url: 'https://www.figma.com/file/123?node-id=1-1',\n examples: [Button],\n links: [\n { name: 'Storybook', url: 'https://storybook.com' }\n ],\n ...\n})\\``,\n })\n\n let links: FigmaConnectLink[] | undefined\n if (linksNode) {\n links = parseLinks(linksNode, parserContext)\n }\n\n let imports: string[] = []\n if (importsNode) {\n imports = parseImports(importsNode, parserContext)\n }\n\n let propMappings: {} | undefined\n let mappedProps: MappedProps\n\n if (propMappingNode) {\n mappedProps = new Map()\n propMappings = parsePropsObject(propMappingNode, parserContext)\n }\n\n type Example = {\n example: string\n variant?: FigmaConnectMeta['variant']\n props?: Record<string, any>\n }\n let examples: Example[] | undefined\n\n if (examplesNode) {\n examples = examplesNode.elements.map((exampleNode) => {\n if (ts.isStringLiteral(exampleNode) || ts.isIdentifier(exampleNode)) {\n return { example: exampleNode.text }\n }\n\n if (!ts.isObjectLiteralExpression(exampleNode)) {\n throw new ParserError(\n `Expected object literal in examples array, got: ${ts.SyntaxKind[exampleNode.kind]}`,\n {\n sourceFile,\n node: exampleNode,\n },\n )\n }\n\n return convertObjectLiteralToJs(exampleNode, sourceFile, checker, (node) => {\n if ((node.parent as ts.TypeParameterDeclaration)?.name?.escapedText === 'props') {\n if (ts.isObjectLiteralExpression(node)) {\n return parsePropsObject(node, parserContext)\n }\n }\n }) as Example\n })\n }\n\n return {\n figmaStoryMetadata,\n componentDeclaration,\n propMappings,\n mappedProps,\n examples,\n imports,\n links,\n }\n}\n"]}
|
package/figma-types.d.ts
CHANGED
|
@@ -154,6 +154,9 @@ declare module 'figma' {
|
|
|
154
154
|
) => TemplateStringResult
|
|
155
155
|
|
|
156
156
|
export interface Figma {
|
|
157
|
+
/** Per-entry data from a .figma.batch.json file. Available in batch templates. */
|
|
158
|
+
readonly batch: Record<string, any>
|
|
159
|
+
|
|
157
160
|
/** The currently selected component instance */
|
|
158
161
|
readonly selectedInstance: InstanceHandle & { readonly __properties__: FigmaProperties }
|
|
159
162
|
/** Alias for selectedInstance */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@figma/code-connect",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.5",
|
|
4
4
|
"description": "A tool for connecting your design system components in code with your design system in Figma",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "Figma",
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
"types": "./dist/react/index_react.d.ts",
|
|
12
12
|
"default": "./dist/react/index_react.js"
|
|
13
13
|
},
|
|
14
|
+
"./cli-commands-template": {
|
|
15
|
+
"types": "./dist/commands/connect_template.d.ts",
|
|
16
|
+
"default": "./dist/commands/connect_template.js"
|
|
17
|
+
},
|
|
14
18
|
"./html": {
|
|
15
19
|
"types": "./dist/html/index_html.d.ts",
|
|
16
20
|
"default": "./dist/html/index_html.js"
|
|
@@ -85,7 +89,7 @@
|
|
|
85
89
|
"jest": "^29.7.0",
|
|
86
90
|
"patch-package": "^8.0.0",
|
|
87
91
|
"pkg": "^5.8.1",
|
|
88
|
-
"ts-jest": "^29.
|
|
92
|
+
"ts-jest": "^29.4.9",
|
|
89
93
|
"ts-loader": "^9.5.1",
|
|
90
94
|
"tsx": "4.21.0",
|
|
91
95
|
"webpack": "5.91.0",
|
|
@@ -106,7 +110,7 @@
|
|
|
106
110
|
"find-up": "^5.0.0",
|
|
107
111
|
"glob": "^11.0.4",
|
|
108
112
|
"jsdom": "^24.1.1",
|
|
109
|
-
"lodash": "4.
|
|
113
|
+
"lodash": "4.18.1",
|
|
110
114
|
"minimatch": "^9.0.3",
|
|
111
115
|
"ora": "^5.4.1",
|
|
112
116
|
"parse5": "^7.1.2",
|
|
@@ -114,7 +118,7 @@
|
|
|
114
118
|
"prompts": "^2.4.2",
|
|
115
119
|
"strip-ansi": "^6.0.0",
|
|
116
120
|
"ts-morph": "^27.0.0",
|
|
117
|
-
"typescript": "
|
|
121
|
+
"typescript": "6.0.3",
|
|
118
122
|
|
|
119
123
|
"undici": "^7.19.1",
|
|
120
124
|
"zod": "3.25.58",
|