@figma/code-connect 1.4.0 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"convert.js","sourceRoot":"","sources":["../../src/storybook/convert.ts"],"names":[],"mappings":";;;;;AAuDA,sDAgBC;AAvED,2BAAiC;AACjC,qDAK+B;AAC/B,4CAKwB;AACxB,gDAK2B;AAC3B,+CAA0C;AAE1C,8EAA6F;AAC7F,4DAA2B;AAE3B,yCAAqC;AACrC,sDAAwD;AACxD,4DAMiC;AAejC;;;;;;;GAOG;AACI,KAAK,UAAU,qBAAqB,CAAC,EAC1C,WAAW,EACX,WAAW,GAAG,kBAAkB,GACN;IAC1B,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,WAAW,CAAA;IAE3D,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,qBAAS,EAAC,IAAI,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAC5F,gBAAM,CAAC,KAAK,CAAC,uBAAuB,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAEjF,OAAO,OAAO,CAAC,GAAG,CAChB,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACtB,oBAAoB,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC,CAC3F,CACF;SACE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAA8B,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;SACpE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;AAC1B,CAAC;AAkBD,KAAK,UAAU,oBAAoB,CAAC,EAClC,IAAI,EACJ,SAAS,EACT,SAAS,EACT,MAAM,EACN,OAAO,GACkB;IACzB,MAAM,OAAO,GAAG,SAAS,CAAC,cAAc,EAAE,CAAA;IAC1C,MAAM,UAAU,GAAG,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;IAEhD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,6BAAa,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAA;IAC3D,CAAC;IAED,MAAM,aAAa,GAAkB;QACnC,OAAO;QACP,MAAM;QACN,UAAU;QACV,OAAO;QACP,eAAe,EAAE,IAAA,8BAAqB,EAAC,SAAS,EAAE,UAAU,CAAC;KAC9D,CAAA;IAED,IAAI,MAAM,GAAG,IAAA,iBAAY,EAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAA;IAC1C,mEAAmE;IACnE,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;QACrD,OAAO,WAAW,KAAK,GAAG,CAAA;IAC5B,CAAC,CAAC,CAAA;IAEF,gBAAM,CAAC,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAA;IAErC,IAAI,CAAC;QACH,yEAAyE;QACzE,kFAAkF;QAClF,6EAA6E;QAC7E,MAAM,iBAAiB,GAAG,IAAA,2BAAgB,EAAC,UAAU,CAAC,CAAA;QACtD,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,OAAM;QACR,CAAC;QAED,MAAM,WAAW,GAAG,kBAAkB,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAA;QAExE,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,gBAAM,CAAC,KAAK,CAAC,sCAAsC,IAAI,EAAE,CAAC,CAAA;YAC1D,OAAM;QACR,CAAC;QAED,MAAM,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,GACxF,WAAW,CAAA;QAEb,MAAM,iBAAiB,GAAG,MAAM,IAAA,+BAAsB,EAAC,oBAAoB,EAAE,aAAa,CAAC,CAAA;QAE3F,MAAM,kBAAkB,GAAsB,EAAE,CAAA;QAChD,MAAM,eAAe,GAAoB;YACvC,SAAS,EAAE,kBAAkB,CAAC,GAAG;YACjC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG;gBAC5B,CAAC,CAAC,IAAA,yBAAe,EAAC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC;gBACjE,CAAC,CAAC,IAAA,0BAAgB,EAAC,iBAAiB,CAAC,MAAM,EAAE,SAAS,CAAC;YACzD,cAAc,EAAE,EAAE,IAAI,EAAE,iBAAiB,CAAC,IAAI,EAAE;YAChD,QAAQ,EAAE,EAAE;YACZ,YAAY,EAAE;gBACZ,KAAK,EAAE,YAAY;gBACnB,OAAO;aACR;YACD,KAAK;YACL,SAAS,EAAE,iBAAiB,CAAC,SAAS;YACtC,KAAK,EAAE,yCAAgB,CAAC,SAAS;YACjC,QAAQ,EAAE,gDAAuB,CAAC,UAAU;YAC5C,QAAQ,EAAE;gBACR,UAAU,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC,OAAO;aAClD;SACF,CAAA;QAED,sEAAsE;QACtE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,kBAAkB,CAAC,IAAI,CAAC;gBACtB,GAAG,eAAe;gBAClB,QAAQ,EAAE,IAAA,2BAAkB,EAAC,iBAAiB,CAAC;aAChD,CAAC,CAAA;YACF,OAAO,kBAAkB,CAAA;QAC3B,CAAC;QAED,KAAK,MAAM,SAAS,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;YAC9C,mFAAmF;YACnF,IAAI,CAAC,CAAC,oBAAE,CAAC,qBAAqB,CAAC,SAAS,CAAC,IAAI,oBAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;gBAChF,SAAQ;YACV,CAAC;YAED,MAAM,IAAI,GAAG,oBAAE,CAAC,qBAAqB,CAAC,SAAS,CAAC;gBAC9C,CAAC,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI;gBACtB,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;YAExE,MAAM,OAAO,GAAG,QAAQ,EAAE,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,CAAA;YACrE,sDAAsD;YACtD,IAAI,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC;gBACzB,SAAQ;YACV,CAAC;YAED,IAAI,gBAAuE,CAAA;YAE3E,IAAI,oBAAE,CAAC,qBAAqB,CAAC,SAAS,CAAC,EAAE,CAAC;gBACxC,gBAAgB,GAAG,SAAS,CAAA;YAC9B,CAAC;iBAAM,CAAC;gBACN,MAAM,WAAW,GAAG,SAAS,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,WAAW,CAAA;gBACzE,IAAI,WAAW,IAAI,oBAAE,CAAC,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC;oBACnD,gBAAgB,GAAG,WAAW,CAAA;gBAChC,CAAC;qBAAM,IAAI,WAAW,IAAI,oBAAE,CAAC,yBAAyB,CAAC,WAAW,CAAC,EAAE,CAAC;oBACpE,4EAA4E;oBAC5E,MAAM,cAAc,GAAG,IAAA,8BAAmB,EAAC;wBACzC,iBAAiB,EAAE,WAAW;wBAC9B,YAAY,EAAE,QAAQ;wBACtB,SAAS,EAAE,oBAAE,CAAC,eAAe;wBAC7B,aAAa;wBACb,QAAQ,EAAE,IAAI;qBACf,CAAC,CAAA;oBAEF,IAAI,cAAc,EAAE,CAAC;wBACnB,gBAAgB,GAAG,cAAc,CAAA;oBACnC,CAAC;gBACH,CAAC;YACH,CAAC;YAED,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACtB,MAAM,IAAI,2BAAW,CACnB,2EAA2E,EAC3E;oBACE,UAAU;oBACV,IAAI,EAAE,SAAS;iBAChB,CACF,CAAA;YACH,CAAC;YAED,MAAM,YAAY,GAAG,OAAO,EAAE,KAAK,IAAI,YAAY,CAAA;YAEnD,IAAI,MAAM,GAAG,IAAA,+BAAsB,EAAC,gBAAgB,EAAE,aAAa,EAAE,YAAY,CAAC,CAAA;YAElF,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,SAAQ;YACV,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,iBAAiB,CAAC,SAAS,KAAK,CAAA;YAEpE,+BAA+B;YAC/B,kBAAkB,CAAC,IAAI,CAAC;gBACtB,GAAG,eAAe;gBAClB,QAAQ;gBACR,OAAO,EAAE,OAAO,EAAE,OAAO;aAC1B,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,kBAAkB,CAAA;IAC3B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,gBAAM,CAAC,KAAK,CAAC,uBAAuB,IAAI,KAAK,CAAC,EAAE,CAAC,CAAA;QACjD,MAAM,CAAC,CAAA;IACT,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,uBAAuB,CAC9B,iBAA6C;IAE7C,KAAK,MAAM,QAAQ,IAAI,iBAAiB,CAAC,UAAU,EAAE,CAAC;QACpD,IAAI,CAAC,oBAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC;YAAE,SAAQ;QAChD,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAA;QAClC,IAAI,oBAAE,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,YAAY,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACvE,OAAO,QAAQ,CAAC,WAAW,CAAA;QAC7B,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,kBAAkB,CAAC,iBAA0B,EAAE,aAA4B;IAClF,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,aAAa,CAAA;IAC7C,qEAAqE;IACrE,4EAA4E;IAC5E,iEAAiE;IACjE,MAAM,iBAAiB,GAAG,IAAA,sBAAW,EAAC,iBAAiB,EAAE,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAC5E,oBAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,CACnC,CAAA;IAED,IAAI,CAAC,iBAAiB,IAAI,CAAC,oBAAE,CAAC,yBAAyB,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAC3E,gBAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAA;QACzD,OAAM;IACR,CAAC;IAED,MAAM,oBAAoB,GAAG,uBAAuB,CAAC,iBAAiB,CAAC,CAAA;IACvE,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC1B,gBAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAA;QAChE,OAAM;IACR,CAAC;IAED,MAAM,cAAc,GAAG,IAAA,8BAAmB,EAAC;QACzC,iBAAiB,EAAE,iBAAiB;QACpC,YAAY,EAAE,YAAY;QAC1B,SAAS,EAAE,oBAAE,CAAC,yBAAyB;QACvC,aAAa;QACb,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAA;IAEF,mEAAmE;IACnE,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,gBAAM,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAA;QAC5D,OAAM;IACR,CAAC;IAED,MAAM,UAAU,GAAG,IAAA,8BAAmB,EAAC;QACrC,iBAAiB,EAAE,cAAc;QACjC,YAAY,EAAE,QAAQ;QACtB,SAAS,EAAE,oBAAE,CAAC,yBAAyB;QACvC,aAAa;QACb,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAA;IAEF,+DAA+D;IAC/D,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,gBAAM,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAA;QACxD,OAAM;IACR,CAAC;IAED,MAAM,QAAQ,GAAG,IAAA,8BAAmB,EAAC;QACnC,iBAAiB,EAAE,UAAU;QAC7B,YAAY,EAAE,MAAM;QACpB,SAAS,EAAE,oBAAE,CAAC,eAAe;QAC7B,aAAa;QACb,YAAY,EAAE,gEAAgE;QAC9E,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAA;IAEF,uEAAuE;IACvE,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC3C,gBAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAA;QACxC,OAAM;IACR,CAAC;IAED,MAAM,OAAO,GAAG,IAAA,8BAAmB,EAAC;QAClC,iBAAiB,EAAE,UAAU;QAC7B,YAAY,EAAE,KAAK;QACnB,SAAS,EAAE,oBAAE,CAAC,eAAe;QAC7B,aAAa;QACb,YAAY,EAAE,+DAA+D;QAC7E,QAAQ,EAAE,IAAI;KACf,CAAC,CAAA;IAEF,MAAM,kBAAkB,GAAuB;QAC7C,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,GAAG,EAAE,OAAO,CAAC,IAAI;KAClB,CAAA;IAED,MAAM,eAAe,GAAG,IAAA,8BAAmB,EAAC;QAC1C,iBAAiB,EAAE,UAAU;QAC7B,YAAY,EAAE,OAAO;QACrB,SAAS,EAAE,oBAAE,CAAC,yBAAyB;QACvC,aAAa;QACb,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAA;IAEF,MAAM,YAAY,GAAG,IAAA,8BAAmB,EAAC;QACvC,iBAAiB,EAAE,UAAU;QAC7B,YAAY,EAAE,UAAU;QACxB,SAAS,EAAE,oBAAE,CAAC,wBAAwB;QACtC,aAAa;QACb,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAA;IAEF,MAAM,WAAW,GAAG,IAAA,8BAAmB,EAAC;QACtC,iBAAiB,EAAE,UAAU;QAC7B,YAAY,EAAE,SAAS;QACvB,SAAS,EAAE,oBAAE,CAAC,wBAAwB;QACtC,aAAa;QACb,QAAQ,EAAE,KAAK;QACf,YAAY,EAAE;;;;;;;;;KASb;KACF,CAAC,CAAA;IAEF,MAAM,SAAS,GAAG,IAAA,8BAAmB,EAAC;QACpC,iBAAiB,EAAE,UAAU;QAC7B,YAAY,EAAE,OAAO;QACrB,SAAS,EAAE,oBAAE,CAAC,wBAAwB;QACtC,aAAa;QACb,QAAQ,EAAE,KAAK;QACf,YAAY,EAAE;;;;;;;;;KASb;KACF,CAAC,CAAA;IAEF,IAAI,KAAqC,CAAA;IACzC,IAAI,SAAS,EAAE,CAAC;QACd,KAAK,GAAG,IAAA,0BAAU,EAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAC9C,CAAC;IAED,IAAI,OAAO,GAAa,EAAE,CAAA;IAC1B,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,GAAG,IAAA,4BAAY,EAAC,WAAW,EAAE,aAAa,CAAC,CAAA;IACpD,CAAC;IAED,IAAI,YAA4B,CAAA;IAChC,IAAI,WAAwB,CAAA;IAE5B,IAAI,eAAe,EAAE,CAAC;QACpB,WAAW,GAAG,IAAI,GAAG,EAAE,CAAA;QACvB,YAAY,GAAG,IAAA,6BAAgB,EAAC,eAAe,EAAE,aAAa,CAAC,CAAA;IACjE,CAAC;IAOD,IAAI,QAA+B,CAAA;IAEnC,IAAI,YAAY,EAAE,CAAC;QACjB,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE;YACnD,IAAI,oBAAE,CAAC,eAAe,CAAC,WAAW,CAAC,IAAI,oBAAE,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC;gBACpE,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,IAAI,EAAE,CAAA;YACtC,CAAC;YAED,IAAI,CAAC,oBAAE,CAAC,yBAAyB,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC/C,MAAM,IAAI,2BAAW,CACnB,mDAAmD,oBAAE,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,EACpF;oBACE,UAAU;oBACV,IAAI,EAAE,WAAW;iBAClB,CACF,CAAA;YACH,CAAC;YAED,OAAO,IAAA,mCAAwB,EAAC,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBACzE,IAAK,IAAI,CAAC,MAAsC,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,EAAE,CAAC;oBAChF,IAAI,oBAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,EAAE,CAAC;wBACvC,OAAO,IAAA,6BAAgB,EAAC,IAAI,EAAE,aAAa,CAAC,CAAA;oBAC9C,CAAC;gBACH,CAAC;YACH,CAAC,CAAY,CAAA;QACf,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO;QACL,kBAAkB;QAClB,oBAAoB;QACpB,YAAY;QACZ,WAAW;QACX,QAAQ;QACR,OAAO;QACP,KAAK;KACN,CAAA;AACH,CAAC","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/**\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}: 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({ path, tsProgram, config, remoteUrl, absPath: projectInfo.absPath }),\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}\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}: 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),\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(statementToParse, parserContext, exampleProps)\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/**\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}: 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({ path, tsProgram, config, remoteUrl, absPath: projectInfo.absPath }),\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}\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}: 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(statementToParse, parserContext, exampleProps)\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"]}
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Type definitions for the `figma` module available in Code Connect template files
3
+ * (.figma.ts).
4
+ * Usage: add to your tsconfig.json:
5
+ * { "compilerOptions": { "types": ["@figma/code-connect/figma-types"] } }
6
+ */
7
+ // Declare require() for the 'figma' module so that template files can use
8
+ // `const figma = require('figma')` without needing @types/node installed.
9
+ declare function require(module: 'figma'): typeof import('figma')
10
+ declare function require(module: string): any
11
+ declare module 'figma' {
12
+ export type CodeSection = { type: 'CODE'; code: string; nestedImports?: string[] }
13
+ export type InstanceSection = {
14
+ type: 'INSTANCE'
15
+ guid: string
16
+ symbolId: string
17
+ resultSections?: ResultSection[]
18
+ nestedImports?: string[]
19
+ }
20
+ export type SlotSection = { type: 'SLOT'; guid?: string; propertyName: string }
21
+ export type ErrorSection = { type: 'ERROR'; message: string; errorObject?: unknown }
22
+ export type ResultSection = CodeSection | InstanceSection | SlotSection | ErrorSection
23
+
24
+ export interface TemplateStringResult {
25
+ sections: ResultSection[]
26
+ language: string
27
+ type: 'SECTIONS'
28
+ }
29
+
30
+ export interface SelectorOptions {
31
+ path?: string[]
32
+ traverseInstances?: boolean
33
+ }
34
+
35
+ type ObjectValue = Record<string, FCCValue>
36
+
37
+ export type FCCValue =
38
+ | string
39
+ | number
40
+ | boolean
41
+ | undefined
42
+ | { $value: string; $type: 'jsx-element' }
43
+ | { $value: string; $type: 'function' }
44
+ | { $value: string; $type: 'identifier' }
45
+ | { $value: ObjectValue; $type: 'object' }
46
+ | { $value: string; $type: 'template-string' }
47
+ | { $value: string; $type: 'react-component' }
48
+ | { $value: FCCValue[]; $type: 'array' }
49
+
50
+ export interface TextHandle {
51
+ readonly type: 'TEXT'
52
+ readonly name: string
53
+ __render__(): string
54
+ }
55
+
56
+ export interface TemplateMetadata {
57
+ nestable?: boolean
58
+ props?: Record<string, unknown>
59
+ __props: Record<string, unknown>
60
+ [key: string]: unknown
61
+ }
62
+
63
+ export interface ErrorHandle {
64
+ readonly type: 'ERROR'
65
+ __render__(): ResultSection[]
66
+ executeTemplate(): {
67
+ example: ResultSection[]
68
+ metadata?: TemplateMetadata
69
+ }
70
+ }
71
+
72
+ export interface InstanceHandle {
73
+ readonly type: 'INSTANCE'
74
+ readonly symbolId: string
75
+ readonly name: string
76
+ readonly children: (InstanceHandle | TextHandle | ErrorHandle)[]
77
+ readonly properties: Record<string, { value: string | boolean }>
78
+ readonly path?: string[]
79
+ readonly slots?: Record<string, { guid: string }>
80
+
81
+ codeConnectId(): string | null
82
+
83
+ __find__(name: string): InstanceHandle | ErrorHandle | null
84
+ __findChildWithCriteria__(criteria: {
85
+ type: 'INSTANCE' | 'TEXT'
86
+ name: string
87
+ }): InstanceHandle | TextHandle | ErrorHandle | null
88
+ __getPropertyValue__(name: string): string | boolean | ErrorHandle
89
+ __render__(): ResultSection[]
90
+ __getProps__(): ResultSection[] | Record<string, unknown> | undefined
91
+ __renderWithFn__(
92
+ renderFn: (props: Record<string, unknown>) => TemplateStringResult,
93
+ ): ResultSection[] | ErrorHandle | undefined
94
+
95
+ getString(propName: string): string
96
+ getBoolean(propName: string): boolean
97
+ getBoolean<O extends Record<string, unknown>>(
98
+ propName: string,
99
+ options: O,
100
+ ): EnumOptionsValues<O>
101
+ getEnum<O extends Record<string, unknown>>(
102
+ propName: string,
103
+ options: O,
104
+ ): EnumOptionsValues<O> | undefined
105
+ getInstanceSwap(propName: string): InstanceHandle | undefined
106
+ getSlot(propName: string): ResultSection[] | undefined
107
+ hasCodeConnect(): boolean
108
+ getPropertyValue(name: string): string | boolean | ErrorHandle
109
+ findInstance(layerName: string, opts?: SelectorOptions): InstanceHandle | ErrorHandle
110
+ findText(layerName: string, opts?: SelectorOptions): TextHandle | ErrorHandle
111
+ findConnectedInstance(
112
+ codeConnectId: string,
113
+ opts?: SelectorOptions,
114
+ ): InstanceHandle | ErrorHandle | null
115
+ findConnectedInstances(
116
+ selectorFn: (node: InstanceHandle) => boolean,
117
+ opts?: SelectorOptions,
118
+ ): (InstanceHandle | ErrorHandle)[]
119
+ findLayers(
120
+ selectorFn: (node: InstanceHandle) => boolean,
121
+ opts?: SelectorOptions,
122
+ ): (InstanceHandle | TextHandle | ErrorHandle)[]
123
+ executeTemplate(): {
124
+ example: ResultSection[]
125
+ metadata?: TemplateMetadata
126
+ }
127
+ }
128
+
129
+ export type LayerHandle = InstanceHandle | TextHandle | ErrorHandle
130
+
131
+ export type EnumOptionsValues<O extends Record<string, unknown>> = O[keyof O]
132
+
133
+ export interface FigmaProperties {
134
+ string(propName: string): string
135
+ boolean(propName: string): boolean
136
+ boolean<O extends Record<string, unknown>>(propName: string, options: O): EnumOptionsValues<O>
137
+ enum<O extends Record<string, unknown>>(
138
+ propName: string,
139
+ options: O,
140
+ ): EnumOptionsValues<O> | undefined
141
+ // In error cases the implementation may return string (from TextHandle.__render__)
142
+ instance(propName: string): ResultSection[] | string | undefined
143
+ __instance__(
144
+ propName: string,
145
+ ): InstanceHandle | TextHandle | ErrorHandle | ResultSection[] | undefined
146
+ slot(propName: string): ResultSection[] | undefined
147
+ children(layerNames: string[]): ResultSection[]
148
+ }
149
+
150
+ export type TemplateLiteral = (
151
+ strings: TemplateStringsArray,
152
+ ...values: unknown[]
153
+ ) => TemplateStringResult
154
+
155
+ export interface Figma {
156
+ /** The currently selected component instance */
157
+ readonly selectedInstance: InstanceHandle & { readonly __properties__: FigmaProperties }
158
+ /** Alias for selectedInstance */
159
+ readonly currentLayer: InstanceHandle & { readonly __properties__: FigmaProperties }
160
+ /** Access component properties via the properties API */
161
+ readonly properties: FigmaProperties
162
+
163
+ /** Template literal tag for custom/plaintext code */
164
+ code: TemplateLiteral
165
+ /** Template literal tag for JSX/TSX code */
166
+ tsx: TemplateLiteral
167
+ /** Template literal tag for HTML code */
168
+ html: TemplateLiteral
169
+ /** Template literal tag for Swift code */
170
+ swift: TemplateLiteral
171
+ /** Template literal tag for Kotlin/Compose code */
172
+ kotlin: TemplateLiteral
173
+
174
+ /** Return a raw value (not rendered as a template string) */
175
+ value(raw: unknown, preview?: unknown): { type: string; value: unknown; preview: unknown }
176
+
177
+ helpers: {
178
+ react: {
179
+ renderProp(name: string, prop: FCCValue | ResultSection[]): TemplateStringResult | string
180
+ renderChildren(
181
+ prop: FCCValue | ResultSection[],
182
+ ): ResultSection[] | string | number | boolean | TemplateStringResult
183
+ renderPropValue(
184
+ prop: FCCValue | ResultSection[],
185
+ ): string | number | boolean | ResultSection[]
186
+ stringifyObject(obj: unknown): string
187
+ jsxElement(value: string): { $value: string; $type: 'jsx-element' }
188
+ function(value: string): { $value: string; $type: 'function' }
189
+ identifier(value: string): { $value: string; $type: 'identifier' }
190
+ object(value: ObjectValue): { $value: ObjectValue; $type: 'object' }
191
+ templateString(value: string): { $value: string; $type: 'template-string' }
192
+ reactComponent(value: string): { $value: string; $type: 'react-component' }
193
+ array(value: FCCValue[]): { $value: FCCValue[]; $type: 'array' }
194
+ isReactComponentArray(prop: unknown): boolean
195
+ }
196
+ swift: {
197
+ renderChildren(children: ResultSection[], prefix: string): ResultSection[]
198
+ }
199
+ kotlin: {
200
+ renderChildren(children: ResultSection[], prefix: string): ResultSection[]
201
+ }
202
+ }
203
+ }
204
+
205
+ const figma: Figma
206
+ export = figma
207
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@figma/code-connect",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
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",
@@ -18,6 +18,9 @@
18
18
  "./react": {
19
19
  "types": "./dist/react/index_react.d.ts",
20
20
  "default": "./dist/react/index_react.js"
21
+ },
22
+ "./figma-types": {
23
+ "types": "./figma-module.d.ts"
21
24
  }
22
25
  },
23
26
  "repository": {
@@ -29,7 +32,8 @@
29
32
  "figma": "bin/figma"
30
33
  },
31
34
  "files": [
32
- "dist/**/*"
35
+ "dist/**/*",
36
+ "figma-module.d.ts"
33
37
  ],
34
38
  "engines": {
35
39
  "node": ">=18"
@@ -83,7 +87,7 @@
83
87
  "pkg": "^5.8.1",
84
88
  "ts-jest": "^29.2.5",
85
89
  "ts-loader": "^9.5.1",
86
- "tsx": "^4.11.0",
90
+ "tsx": "4.21.0",
87
91
  "webpack": "5.91.0",
88
92
  "webpack-cli": "5.1.4"
89
93
  },