{"version":3,"file":"prop_mapping.js","sourceRoot":"","sources":["../../../src/connect/wizard/prop_mapping.ts"],"names":[],"mappings":"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","sourcesContent":["import { ComponentTypeSignature } from '../../react/parser'\nimport { FigmaRestApi } from '../figma_rest_api'\nimport { PropMapping } from '../parser_executable_types'\nimport { Searcher } from 'fast-fuzzy'\nimport { Intrinsic, IntrinsicKind, ValueMapping } from '../../connect/intrinsics'\nimport { isBooleanKind } from '../../react/create'\nimport { ComponentMatchResults, MatchableNamesMap, PropMatchResult } from './prop_mapping_helpers'\n\n/**\n * These thresholds were come up with by running the benchmarking\n * and tweaking until high positives + acceptable false positives\n * were achieved. It's worth repeating this process whenever making\n * changes to the mapping algorithm.\n */\nconst MININUM_MATCH_SCORES = {\n fuzzy: {\n property: 0.65,\n variantValue: 0.8,\n },\n embeddings: {\n property: 0.84,\n variantValue: 0.87,\n },\n}\n\n/**\n * Used when we should output a placeholder for an unknown value in prop mapping.\n */\nexport const PROPERTY_PLACEHOLDER = 'PROPERTY_PLACEHOLDER'\n\nexport function generateValueMapping(\n propSignature: string,\n figmaPropDef: FigmaRestApi.ComponentPropertyDefinition,\n): ValueMapping {\n const searchableCodeEnumOptions: Record = {}\n propSignature.split(' | ').forEach((str) => {\n if (str.startsWith('\"') && str.endsWith('\"')) {\n const withoutQuotes = str.substring(1, str.length - 1)\n searchableCodeEnumOptions[withoutQuotes] = withoutQuotes\n } else if (str === 'true') {\n searchableCodeEnumOptions[str] = true\n } else if (str === 'false') {\n searchableCodeEnumOptions[str] = false\n } else if (!isNaN(Number(str))) {\n searchableCodeEnumOptions[str] = Number(str)\n }\n })\n const searcher = new Searcher(figmaPropDef.variantOptions)\n return Object.entries(searchableCodeEnumOptions).reduce(\n (valueMapping, [codeEnumValue, mappedValue]) => {\n const results = searcher.search(codeEnumValue, { returnMatchData: true })\n if (results.length && results[0].score > 0.5) {\n valueMapping[results[0].item] = mappedValue\n }\n return valueMapping\n },\n {} as ValueMapping,\n )\n}\n\nfunction signatureIsJsxLike(signature: string) {\n return (\n signature.includes('ElementType') ||\n signature.includes('ReactElement') ||\n signature.includes('ReactNode')\n )\n}\n\n/**\n * Attempts to create a mapping between a code prop and figma prop.\n * These props have been matched by name and aren't guaranteed to\n * actually be related, so we return null if no suitable mapping\n */\nfunction generateIntrinsic({\n propSignature,\n figmaPropName: figmaPropNameWithNodeId,\n figmaPropDef,\n}: {\n propSignature: string\n figmaPropName: string\n figmaPropDef: FigmaRestApi.ComponentPropertyDefinition\n}): Intrinsic | null {\n const figmaPropName = stripNodeIdFromPropertyName(figmaPropNameWithNodeId)\n if (propSignature === 'string' && figmaPropDef.type === FigmaRestApi.ComponentPropertyType.Text) {\n return {\n kind: IntrinsicKind.String,\n args: {\n figmaPropName,\n },\n }\n }\n if (\n propSignature === 'false | true' &&\n (figmaPropDef.type === FigmaRestApi.ComponentPropertyType.Boolean ||\n (figmaPropDef.type === FigmaRestApi.ComponentPropertyType.Variant &&\n figmaPropDef.variantOptions?.length === 2 &&\n figmaPropDef.variantOptions?.every(isBooleanKind)))\n ) {\n return {\n kind: IntrinsicKind.Boolean,\n args: {\n figmaPropName,\n },\n }\n }\n if (\n propSignature.includes(' | ') &&\n figmaPropDef.type === FigmaRestApi.ComponentPropertyType.Variant\n ) {\n const valueMapping = generateValueMapping(propSignature, figmaPropDef)\n // Only valuable if some values were mapped\n if (Object.keys(valueMapping).length > 0) {\n return {\n kind: IntrinsicKind.Enum,\n args: {\n figmaPropName,\n valueMapping,\n },\n }\n }\n }\n if (\n signatureIsJsxLike(propSignature) &&\n figmaPropDef.type === FigmaRestApi.ComponentPropertyType.InstanceSwap\n ) {\n return {\n kind: IntrinsicKind.Instance,\n args: {\n figmaPropName,\n },\n }\n }\n return null\n}\n\nfunction stripNodeIdFromPropertyName(propertyName: string) {\n return propertyName.replace(/#\\d+:\\d+/, '')\n}\n\nexport enum MatchableNameTypes {\n Property,\n VariantValue,\n // ChildLayer, // TODO\n}\n\nconst MATCHABLE_NAME_TYPES_PRIORITY = [\n MatchableNameTypes.Property,\n MatchableNameTypes.VariantValue,\n] as const\n\nexport type MatchableName = {\n type: MatchableNameTypes\n name: string\n variantProperty?: string // Only for VariantValue\n}\n\n/**\n * Builds a map of all properties and enum values, indexed by name.\n * @param componentPropertyDefinitions\n * @returns A map of {name: values[]}. Each value is an array to avoid\n * collisions between properties / enum values\n */\nexport function buildMatchableNamesMap(\n componentPropertyDefinitions?: FigmaRestApi.Component['componentPropertyDefinitions'],\n) {\n const matchableValues: MatchableNamesMap = {}\n\n function add(name: string, definition: MatchableName) {\n matchableValues[name] = matchableValues[name] || []\n matchableValues[name].push(definition)\n }\n\n Object.entries(componentPropertyDefinitions || {}).forEach(([propName, propDef]) => {\n const name = stripNodeIdFromPropertyName(propName)\n\n add(name, {\n type: MatchableNameTypes.Property,\n name: propName,\n })\n\n if (propDef.type === FigmaRestApi.ComponentPropertyType.Variant) {\n propDef.variantOptions?.forEach((variantValue) => {\n add(variantValue, {\n type: MatchableNameTypes.VariantValue,\n name: variantValue,\n variantProperty: propName,\n })\n })\n }\n })\n\n return matchableValues\n}\n\nexport function generatePropMapping({\n componentPropertyDefinitions,\n signature,\n componentMatchResults,\n matchableNamesMap,\n}: {\n componentPropertyDefinitions: FigmaRestApi.Component['componentPropertyDefinitions']\n signature: ComponentTypeSignature\n componentMatchResults?: ComponentMatchResults\n matchableNamesMap: MatchableNamesMap\n}): PropMapping {\n const propMapping: PropMapping = {}\n\n const searchSpace = Object.keys(matchableNamesMap)\n const searcher = new Searcher(searchSpace)\n\n let minimumMatchScores = MININUM_MATCH_SCORES.fuzzy\n\n const useEmbeddings = !!componentMatchResults\n if (useEmbeddings) {\n minimumMatchScores = MININUM_MATCH_SCORES.embeddings\n }\n\n function attemptGetIntrinsicForProp({\n propMatch,\n propSignature,\n }: {\n propMatch: PropMatchResult\n propSignature: string\n }) {\n const itemsInPriorityOrder = [...matchableNamesMap[propMatch.item]].sort(\n (a, b) =>\n MATCHABLE_NAME_TYPES_PRIORITY.indexOf(a.type) -\n MATCHABLE_NAME_TYPES_PRIORITY.indexOf(b.type),\n )\n\n for (const item of itemsInPriorityOrder) {\n /**\n * First, look for matching property names with compatible types\n */\n if (\n item.type === MatchableNameTypes.Property &&\n propMatch.score > minimumMatchScores.property\n ) {\n const intrinsic = generateIntrinsic({\n propSignature,\n figmaPropName: item.name,\n figmaPropDef: componentPropertyDefinitions[item.name],\n })\n if (intrinsic) {\n return intrinsic\n }\n /**\n * Then if no match AND a boolean prop, look for matching variant values, e.g:\n *\n * disabled: figma.enum('State', {\n * Disabled: true,\n * })\n */\n } else if (\n item.type === MatchableNameTypes.VariantValue &&\n propSignature === 'false | true' &&\n propMatch.score > minimumMatchScores.variantValue\n ) {\n return {\n kind: IntrinsicKind.Enum,\n args: {\n figmaPropName: item.variantProperty,\n valueMapping: {\n [item.name]: true,\n },\n },\n } as Intrinsic\n }\n }\n\n return null\n }\n\n /**\n * Attempt to generate an intrinsic for a given property name by looking\n * for name matches with a minimum threshold\n *\n * Embeddings are priorized over fuzzy matching if present (they\n * may be missing if gated or missing permissions).\n */\n for (const [propName, propSignatureWithOptionalModifier] of Object.entries(signature)) {\n const propSignature = propSignatureWithOptionalModifier.startsWith('?')\n ? propSignatureWithOptionalModifier.substring(1)\n : propSignatureWithOptionalModifier\n\n let matches = searcher.search(propName, { returnMatchData: true }) as PropMatchResult[]\n\n if (useEmbeddings) {\n matches = componentMatchResults[propName]\n }\n\n if (matches.length === 0) {\n continue\n }\n\n for (const match of matches) {\n const intrinsic = attemptGetIntrinsicForProp({\n propMatch: match,\n propSignature,\n })\n if (intrinsic) {\n propMapping[propName] = intrinsic\n break\n }\n }\n }\n\n return propMapping\n}\n"]}