{"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 {\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 {\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"]}