@figma/code-connect 1.4.7 → 1.4.9

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.
Files changed (47) hide show
  1. package/dist/commands/connect.d.ts +3 -0
  2. package/dist/commands/connect.d.ts.map +1 -1
  3. package/dist/commands/connect.js +140 -40
  4. package/dist/commands/connect.js.map +1 -1
  5. package/dist/commands/connect_template.d.ts.map +1 -1
  6. package/dist/commands/connect_template.js +9 -0
  7. package/dist/commands/connect_template.js.map +1 -1
  8. package/dist/common/logging.d.ts.map +1 -1
  9. package/dist/common/logging.js +13 -6
  10. package/dist/common/logging.js.map +1 -1
  11. package/dist/common/updates.d.ts.map +1 -1
  12. package/dist/common/updates.js +2 -2
  13. package/dist/common/updates.js.map +1 -1
  14. package/dist/connect/api.d.ts +34 -1
  15. package/dist/connect/api.d.ts.map +1 -1
  16. package/dist/connect/api.js.map +1 -1
  17. package/dist/connect/intrinsics.d.ts +1 -0
  18. package/dist/connect/intrinsics.d.ts.map +1 -1
  19. package/dist/connect/intrinsics.js +29 -0
  20. package/dist/connect/intrinsics.js.map +1 -1
  21. package/dist/connect/migration_batch_helpers.d.ts +45 -0
  22. package/dist/connect/migration_batch_helpers.d.ts.map +1 -0
  23. package/dist/connect/migration_batch_helpers.js +439 -0
  24. package/dist/connect/migration_batch_helpers.js.map +1 -0
  25. package/dist/connect/migration_helpers.d.ts +4 -0
  26. package/dist/connect/migration_helpers.d.ts.map +1 -1
  27. package/dist/connect/migration_helpers.js +29 -5
  28. package/dist/connect/migration_helpers.js.map +1 -1
  29. package/dist/connect/parser_executables.d.ts.map +1 -1
  30. package/dist/connect/parser_executables.js +25 -13
  31. package/dist/connect/parser_executables.js.map +1 -1
  32. package/dist/connect/project.d.ts +2 -1
  33. package/dist/connect/project.d.ts.map +1 -1
  34. package/dist/connect/project.js +26 -24
  35. package/dist/connect/project.js.map +1 -1
  36. package/dist/connect/raw_templates.d.ts +10 -0
  37. package/dist/connect/raw_templates.d.ts.map +1 -1
  38. package/dist/connect/raw_templates.js +48 -14
  39. package/dist/connect/raw_templates.js.map +1 -1
  40. package/dist/connect/wizard/helpers.d.ts.map +1 -1
  41. package/dist/connect/wizard/helpers.js +7 -2
  42. package/dist/connect/wizard/helpers.js.map +1 -1
  43. package/dist/parser_scripts/get_swift_parser_dir.js +5 -5
  44. package/dist/parser_scripts/get_swift_parser_dir.js.map +1 -1
  45. package/figma-types-no-require.d.ts +229 -0
  46. package/figma-types.d.ts +12 -3
  47. package/package.json +7 -3
@@ -1 +1 @@
1
- {"version":3,"file":"get_swift_parser_dir.js","sourceRoot":"","sources":["../../src/parser_scripts/get_swift_parser_dir.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawnSync } from 'child_process'\nimport { exitWithError, logger } from '../common/logging'\nimport { getFileIfExists } from './get_file_if_exists'\nimport path from 'path'\nimport { readdirSync, existsSync } from 'fs'\n\n// Find the location of the Code Connect Swift package on disk, so that we can\n// call `swift run figma-swift` from the correct location. This requires parsing\n// the output of xcodebuild for .xcodeproj projects, or parsing Package.swift\n// for SPM projects.\n//\n// As this is a first party parser, we do this in TypeScript and call it as part\n// of our code. For third party parsers, logic like this would need to be\n// implemented in a script/binary which the user points Code Connect to.\nexport async function getSwiftParserDir(\n cwd: string,\n xcodeprojPath?: string,\n swiftPackagePath?: string,\n sourcePackagesPath?: string,\n) {\n let figmaPackageDir: string | undefined\n let xcodeprojFile: string | undefined\n let packageSwiftFile: string | undefined\n\n // // Check for the supported project types giving precedence top the user provided path\n if (xcodeprojPath) {\n xcodeprojFile = xcodeprojPath.replace(/\\s/g, '\\\\ ')\n } else if (swiftPackagePath) {\n packageSwiftFile = path.dirname(swiftPackagePath).replace(/\\s/g, '\\\\ ')\n } else {\n xcodeprojFile = getFileIfExists(cwd, '*.xcodeproj').replace(/\\s/g, '\\\\ ')\n packageSwiftFile = getFileIfExists(cwd, 'Package.swift').replace(/\\s/g, '\\\\ ')\n }\n\n if (!(xcodeprojFile || packageSwiftFile)) {\n exitWithError(\n 'No supported project found. Supported project types are .xcodeproj or Package.swift. You can specify the location of your .xcodeproj file with the `xcodeprojPath` config option.',\n )\n }\n\n if (xcodeprojFile) {\n // Use xcodebuild to get the build settings, so we can find where the Code\n // Connect Swift package is installed\n const result = spawnSync('xcodebuild', ['-project', xcodeprojFile, '-showBuildSettings'], {\n cwd,\n encoding: 'utf-8',\n })\n\n if (result.error) {\n throw result.error\n }\n\n const buildSettings = result.stdout\n\n // Extract the source and version of the Code Connect Swift package from the\n // xcodebuild output, which can be in any of the following formats depending\n // on how it is installed:\n // - Figma: https://github.com/figma/code-connect @ 0.1.2\n // - Figma: /path/to/code-connect @ local\n // - Figma: /path/to/code-connect\n const figmaPackageMatch = buildSettings.match(/\\s+Figma: ([^\\s]*)(?: @ (.*))?/)\n if (!figmaPackageMatch) {\n exitWithError(\n 'Code Connect Swift package not found. Please add a dependency to the Code Connect package at https://github.com/figma/code-connect to your project.',\n )\n }\n\n // Find the package's location on disk, to compile and run the parser binary from\n const [_, figmaPackageSource, figmaPackageVersion] = figmaPackageMatch\n // The package version is `local` if installed via the \"Add package\" dialog,\n // or undefined if installed via the \"Frameworks\" section directly (which we\n // do for our test project, because the dialog won't allow ancestors to be\n // added)\n const isLocalFigmaPackage = figmaPackageVersion === 'local' || figmaPackageVersion === undefined\n\n if (isLocalFigmaPackage) {\n // If the version is 'local', the package is installed from a local checkout,\n // and the path on disk is the source output by xcodebuild.\n figmaPackageDir = figmaPackageSource\n } else if (sourcePackagesPath) {\n logger.info(`Using custom DerivedData path: ${sourcePackagesPath}`)\n\n // If a custom path is supplied, use it.\n figmaPackageDir = `${sourcePackagesPath}/checkouts/code-connect`\n } else {\n // Otherwise the SourcePackages will typically be located in Xcode's DerivedData directory,\n // at ~/Users/{username}/Library/Developer/Xcode/DerivedData/{project}-{xxx}/SourcePackages, or in the Project's root\n // at {project}/DerivedData/{project}/SourcePackages (depending on how the user's project is configured).\n let hasFoundSourcePackagesDir = false\n\n // 1. First look in the USER_LIBRARY_DIR (e.g. /Users/{username}/Library)\n const userLibraryDirectoryMatch = buildSettings.match(/\\s+USER_LIBRARY_DIR = (.*)/)\n const userLibraryDirectory = userLibraryDirectoryMatch\n ? userLibraryDirectoryMatch[1]\n : undefined\n\n logger.info('Finding Code Connect Swift package')\n\n // Find the project's name using the build settings\n const projectNameMatch = buildSettings.match(/\\s+PROJECT_NAME = (.*)/)\n const projectName = projectNameMatch ? projectNameMatch[1] : undefined\n\n // We can't proceed without the project name (however, this should always exist)\n if (!projectName) {\n exitWithError('PROJECT_NAME not found in xcodebuild output')\n }\n\n // 1. From the folders in the user library directory use a regex to determine the folder name of the project defined by \"ProjectName-\" and a 28 character hash\n // e.g. project-fbybcbnivxfbfeefownexgukzwxd\n if (userLibraryDirectory) {\n // Default to Xcode's default Dervied Data location (e.g. ~/Users/{username}/Library/Developer/Xcode/DerivedData/project-fbybcbnivxfbfeefownexgukzwxd/SourcePackages)\n const root = `${userLibraryDirectory}/Developer/Xcode/DerivedData`\n\n const projectFolderRegex = new RegExp(`${projectName}-[a-zA-Z0-9]{28}`)\n const derivedDataFolders = readdirSync(root)\n const projectFolder = derivedDataFolders.find((folder: string) =>\n projectFolderRegex.test(folder),\n )\n\n // If the project folder is found, use it to find the Code Connect package\n if (projectFolder) {\n figmaPackageDir = `${root}/${projectFolder}/SourcePackages/checkouts/code-connect`\n hasFoundSourcePackagesDir = true\n } else {\n logger.warn('Package not found in user library directory')\n }\n }\n\n // 2. If SourcePackages couldn't be found in ~/Users/{username}/Library/Developer/Xcode/DerivedData/{project}-{xxx}/SourcePackages, attempt\n // to find it in the project root {project}/DerivedData/{project}/SourcePackages\n if (!hasFoundSourcePackagesDir) {\n const rootDir = buildSettings.match(/\\s+LOCROOT = (.*)/)\n\n if (rootDir) {\n figmaPackageDir = `${rootDir[1]}/DerivedData/${projectName}/SourcePackages/checkouts/code-connect`\n hasFoundSourcePackagesDir = true\n } else {\n logger.warn('Package not found in project root')\n }\n }\n\n // 3. Otherwise, the package may be installed to\n // <DerviedData>/SourcePackages/checkouts/code-connect. We find the\n // DerivedData location from the BUILD_DIR (which points to\n // <DerivedData>/Build/Products).\n if (!hasFoundSourcePackagesDir) {\n const buildDir = buildSettings.match(/\\s+BUILD_DIR = (.*)/)\n\n if (buildDir) {\n figmaPackageDir = `${buildDir[1]}/../../SourcePackages/checkouts/code-connect`\n } else {\n logger.warn('Package not found in build directory')\n }\n }\n }\n } else if (packageSwiftFile) {\n const swiftPackageDir = swiftPackagePath ? path.dirname(swiftPackagePath) : undefined\n const packageDir = swiftPackageDir || cwd\n // Use the Swift command to determine if the package is installed locally or from Git\n try {\n const result = spawnSync(\n 'swift',\n ['package', '--package-path', packageDir, 'describe', '--type', 'json'],\n {\n cwd,\n encoding: 'utf-8',\n },\n )\n\n if (result.error) {\n throw result.error\n }\n\n const packageInfo = JSON.parse(result.stdout)\n\n const codeConnectPackage =\n packageInfo.dependencies.find((p: any) => p.identity === 'code-connect') ??\n // Our local directory is called figmadoc, so this is what swift outputs as the identity\n packageInfo.dependencies.find((p: any) => p.identity === 'figmadoc')\n\n if (!codeConnectPackage) {\n exitWithError(\n 'Code Connect Swift package not found in Package.swift. Please add a dependency to https://github.com/figma/code-connect to your Package.swift file.',\n )\n }\n\n // We can run directly from the directory of the package swift file\n figmaPackageDir = packageDir\n } catch (e) {\n exitWithError(`Error calling Swift command: ${e}`)\n }\n }\n\n if (!figmaPackageDir) {\n exitWithError('Figma package could not be found')\n }\n\n // Check if the figmaPackageDir exists, otherwise we can't proceed,\n // as we require the code-connect package to continue\n if (!existsSync(figmaPackageDir)) {\n exitWithError(`Figma package directory not found at ${figmaPackageDir}`)\n }\n\n // We need to ensure that the directory is writable, so we can run the swift run command\n // otherwise an \"invalid access\" error will be thrown by swift.\n try {\n const packageFile = path.join(figmaPackageDir, 'Package.resolved')\n\n const accessCheck = spawnSync('test', ['-w', packageFile])\n if (accessCheck.status !== 0) {\n // Directory is not writable, attempt to make it writable\n spawnSync('chmod', ['-R', '755', packageFile])\n }\n logger.info(`Directory enabled for swift run command`)\n } catch (e) {\n logger.warn(`Unable to verify or modify directory permissions: ${e}`)\n }\n\n logger.info(\n `Found Code Connect Swift package at ${figmaPackageDir}, building parser binary. This may take a few minutes if this is the first time you've run Code Connect.`,\n )\n\n return figmaPackageDir\n}\n"]}
1
+ {"version":3,"file":"get_swift_parser_dir.js","sourceRoot":"","sources":["../../src/parser_scripts/get_swift_parser_dir.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawnSync } from 'child_process'\nimport { exitWithError, logger } from '../common/logging'\nimport { getFileIfExists } from './get_file_if_exists'\nimport path from 'path'\nimport { readdirSync, existsSync } from 'fs'\n\n// Find the location of the Code Connect Swift package on disk, so that we can\n// call `swift run figma-swift` from the correct location. This requires parsing\n// the output of xcodebuild for .xcodeproj projects, or parsing Package.swift\n// for SPM projects.\n//\n// As this is a first party parser, we do this in TypeScript and call it as part\n// of our code. For third party parsers, logic like this would need to be\n// implemented in a script/binary which the user points Code Connect to.\nexport async function getSwiftParserDir(\n cwd: string,\n xcodeprojPath?: string,\n swiftPackagePath?: string,\n sourcePackagesPath?: string,\n) {\n let figmaPackageDir: string | undefined\n let xcodeprojFile: string | undefined\n let packageSwiftFile: string | undefined\n\n // Keep raw paths; argv-form spawn handles spaces without shell escaping.\n if (xcodeprojPath) {\n xcodeprojFile = xcodeprojPath\n } else if (swiftPackagePath) {\n packageSwiftFile = path.dirname(swiftPackagePath)\n } else {\n xcodeprojFile = getFileIfExists(cwd, '*.xcodeproj')\n packageSwiftFile = getFileIfExists(cwd, 'Package.swift')\n }\n\n if (!(xcodeprojFile || packageSwiftFile)) {\n exitWithError(\n 'No supported project found. Supported project types are .xcodeproj or Package.swift. You can specify the location of your .xcodeproj file with the `xcodeprojPath` config option.',\n )\n }\n\n if (xcodeprojFile) {\n // Use xcodebuild to get the build settings, so we can find where the Code\n // Connect Swift package is installed\n const result = spawnSync('xcodebuild', ['-project', xcodeprojFile, '-showBuildSettings'], {\n cwd,\n encoding: 'utf-8',\n })\n\n if (result.error) {\n throw result.error\n }\n\n const buildSettings = result.stdout\n\n // Extract the source and version of the Code Connect Swift package from the\n // xcodebuild output, which can be in any of the following formats depending\n // on how it is installed:\n // - Figma: https://github.com/figma/code-connect @ 0.1.2\n // - Figma: /path/to/code-connect @ local\n // - Figma: /path/to/code-connect\n const figmaPackageMatch = buildSettings.match(/\\s+Figma: ([^\\s]*)(?: @ (.*))?/)\n if (!figmaPackageMatch) {\n exitWithError(\n 'Code Connect Swift package not found. Please add a dependency to the Code Connect package at https://github.com/figma/code-connect to your project.',\n )\n }\n\n // Find the package's location on disk, to compile and run the parser binary from\n const [_, figmaPackageSource, figmaPackageVersion] = figmaPackageMatch\n // The package version is `local` if installed via the \"Add package\" dialog,\n // or undefined if installed via the \"Frameworks\" section directly (which we\n // do for our test project, because the dialog won't allow ancestors to be\n // added)\n const isLocalFigmaPackage = figmaPackageVersion === 'local' || figmaPackageVersion === undefined\n\n if (isLocalFigmaPackage) {\n // If the version is 'local', the package is installed from a local checkout,\n // and the path on disk is the source output by xcodebuild.\n figmaPackageDir = figmaPackageSource\n } else if (sourcePackagesPath) {\n logger.info(`Using custom DerivedData path: ${sourcePackagesPath}`)\n\n // If a custom path is supplied, use it.\n figmaPackageDir = `${sourcePackagesPath}/checkouts/code-connect`\n } else {\n // Otherwise the SourcePackages will typically be located in Xcode's DerivedData directory,\n // at ~/Users/{username}/Library/Developer/Xcode/DerivedData/{project}-{xxx}/SourcePackages, or in the Project's root\n // at {project}/DerivedData/{project}/SourcePackages (depending on how the user's project is configured).\n let hasFoundSourcePackagesDir = false\n\n // 1. First look in the USER_LIBRARY_DIR (e.g. /Users/{username}/Library)\n const userLibraryDirectoryMatch = buildSettings.match(/\\s+USER_LIBRARY_DIR = (.*)/)\n const userLibraryDirectory = userLibraryDirectoryMatch\n ? userLibraryDirectoryMatch[1]\n : undefined\n\n logger.info('Finding Code Connect Swift package')\n\n // Find the project's name using the build settings\n const projectNameMatch = buildSettings.match(/\\s+PROJECT_NAME = (.*)/)\n const projectName = projectNameMatch ? projectNameMatch[1] : undefined\n\n // We can't proceed without the project name (however, this should always exist)\n if (!projectName) {\n exitWithError('PROJECT_NAME not found in xcodebuild output')\n }\n\n // 1. From the folders in the user library directory use a regex to determine the folder name of the project defined by \"ProjectName-\" and a 28 character hash\n // e.g. project-fbybcbnivxfbfeefownexgukzwxd\n if (userLibraryDirectory) {\n // Default to Xcode's default Dervied Data location (e.g. ~/Users/{username}/Library/Developer/Xcode/DerivedData/project-fbybcbnivxfbfeefownexgukzwxd/SourcePackages)\n const root = `${userLibraryDirectory}/Developer/Xcode/DerivedData`\n\n const projectFolderRegex = new RegExp(`${projectName}-[a-zA-Z0-9]{28}`)\n const derivedDataFolders = readdirSync(root)\n const projectFolder = derivedDataFolders.find((folder: string) =>\n projectFolderRegex.test(folder),\n )\n\n // If the project folder is found, use it to find the Code Connect package\n if (projectFolder) {\n figmaPackageDir = `${root}/${projectFolder}/SourcePackages/checkouts/code-connect`\n hasFoundSourcePackagesDir = true\n } else {\n logger.warn('Package not found in user library directory')\n }\n }\n\n // 2. If SourcePackages couldn't be found in ~/Users/{username}/Library/Developer/Xcode/DerivedData/{project}-{xxx}/SourcePackages, attempt\n // to find it in the project root {project}/DerivedData/{project}/SourcePackages\n if (!hasFoundSourcePackagesDir) {\n const rootDir = buildSettings.match(/\\s+LOCROOT = (.*)/)\n\n if (rootDir) {\n figmaPackageDir = `${rootDir[1]}/DerivedData/${projectName}/SourcePackages/checkouts/code-connect`\n hasFoundSourcePackagesDir = true\n } else {\n logger.warn('Package not found in project root')\n }\n }\n\n // 3. Otherwise, the package may be installed to\n // <DerviedData>/SourcePackages/checkouts/code-connect. We find the\n // DerivedData location from the BUILD_DIR (which points to\n // <DerivedData>/Build/Products).\n if (!hasFoundSourcePackagesDir) {\n const buildDir = buildSettings.match(/\\s+BUILD_DIR = (.*)/)\n\n if (buildDir) {\n figmaPackageDir = `${buildDir[1]}/../../SourcePackages/checkouts/code-connect`\n } else {\n logger.warn('Package not found in build directory')\n }\n }\n }\n } else if (packageSwiftFile) {\n const swiftPackageDir = swiftPackagePath ? path.dirname(swiftPackagePath) : undefined\n const packageDir = swiftPackageDir || cwd\n // Use the Swift command to determine if the package is installed locally or from Git\n try {\n const result = spawnSync(\n 'swift',\n ['package', '--package-path', packageDir, 'describe', '--type', 'json'],\n {\n cwd,\n encoding: 'utf-8',\n },\n )\n\n if (result.error) {\n throw result.error\n }\n\n const packageInfo = JSON.parse(result.stdout)\n\n const codeConnectPackage =\n packageInfo.dependencies.find((p: any) => p.identity === 'code-connect') ??\n // Our local directory is called figmadoc, so this is what swift outputs as the identity\n packageInfo.dependencies.find((p: any) => p.identity === 'figmadoc')\n\n if (!codeConnectPackage) {\n exitWithError(\n 'Code Connect Swift package not found in Package.swift. Please add a dependency to https://github.com/figma/code-connect to your Package.swift file.',\n )\n }\n\n // We can run directly from the directory of the package swift file\n figmaPackageDir = packageDir\n } catch (e) {\n exitWithError(`Error calling Swift command: ${e}`)\n }\n }\n\n if (!figmaPackageDir) {\n exitWithError('Figma package could not be found')\n }\n\n // Check if the figmaPackageDir exists, otherwise we can't proceed,\n // as we require the code-connect package to continue\n if (!existsSync(figmaPackageDir)) {\n exitWithError(`Figma package directory not found at ${figmaPackageDir}`)\n }\n\n // We need to ensure that the directory is writable, so we can run the swift run command\n // otherwise an \"invalid access\" error will be thrown by swift.\n try {\n const packageFile = path.join(figmaPackageDir, 'Package.resolved')\n\n const accessCheck = spawnSync('test', ['-w', packageFile])\n if (accessCheck.status !== 0) {\n // Directory is not writable, attempt to make it writable\n spawnSync('chmod', ['-R', '755', packageFile])\n }\n logger.info(`Directory enabled for swift run command`)\n } catch (e) {\n logger.warn(`Unable to verify or modify directory permissions: ${e}`)\n }\n\n logger.info(\n `Found Code Connect Swift package at ${figmaPackageDir}, building parser binary. This may take a few minutes if this is the first time you've run Code Connect.`,\n )\n\n return figmaPackageDir\n}\n"]}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Type definitions for the `figma` module available in Code Connect template files
3
+ * (.figma.ts) — variant WITHOUT the global `require('figma')` shim.
4
+ *
5
+ * Use this instead of `@figma/code-connect/figma-types` if your project has
6
+ * @types/node installed. The default entry declares a global `require`, which
7
+ * overrides Node's `NodeRequire` type and breaks `require.resolve` (and similar)
8
+ * elsewhere in your project. This variant omits that declaration so the figma
9
+ * types can be added to your main tsconfig.json without a conflict. It types the
10
+ * recommended `import figma from 'figma'` syntax; `require('figma')` is typed by
11
+ * @types/node's own `require`.
12
+ * { "compilerOptions": { "types": ["@figma/code-connect/figma-types-no-require"] } }
13
+ */
14
+ declare module 'figma' {
15
+ export type CodeSection = { type: 'CODE'; code: string; nestedImports?: string[] }
16
+ export type InstanceSection = {
17
+ type: 'INSTANCE'
18
+ guid: string
19
+ symbolId: string
20
+ resultSections?: ResultSection[]
21
+ nestedImports?: string[]
22
+ }
23
+ export type SlotSection = { type: 'SLOT'; guid?: string; propertyName: string }
24
+ export type ErrorSection = { type: 'ERROR'; message: string; errorObject?: unknown }
25
+ export type ResultSection = CodeSection | InstanceSection | SlotSection | ErrorSection
26
+
27
+ export interface TemplateStringResult {
28
+ sections: ResultSection[]
29
+ language: string
30
+ type: 'SECTIONS'
31
+ }
32
+
33
+ export interface SelectorOptions {
34
+ path?: string[]
35
+ traverseInstances?: boolean
36
+ }
37
+
38
+ export type SlotResult = ResultSection[] & {
39
+ /** Connected instances directly in the slot (shallow). */
40
+ readonly connectedInstances: InstanceHandle[]
41
+ }
42
+
43
+ type ObjectValue = Record<string, FCCValue>
44
+
45
+ export type FCCValue =
46
+ | string
47
+ | number
48
+ | boolean
49
+ | undefined
50
+ | { $value: string; $type: 'jsx-element' }
51
+ | { $value: string; $type: 'function' }
52
+ | { $value: string; $type: 'identifier' }
53
+ | { $value: ObjectValue; $type: 'object' }
54
+ | { $value: string; $type: 'template-string' }
55
+ | { $value: string; $type: 'react-component' }
56
+ | { $value: FCCValue[]; $type: 'array' }
57
+
58
+ export interface TextHandle {
59
+ readonly type: 'TEXT'
60
+ readonly name: string
61
+ readonly textContent: string
62
+ readonly __containingSlotName__?: string
63
+ __render__(): string
64
+ }
65
+
66
+ export interface TemplateMetadata {
67
+ nestable?: boolean
68
+ props?: Record<string, unknown>
69
+ __props: Record<string, unknown>
70
+ [key: string]: unknown
71
+ }
72
+
73
+ export interface ErrorHandle {
74
+ readonly type: 'ERROR'
75
+ readonly __containingSlotName__?: string
76
+ __render__(): ResultSection[]
77
+ executeTemplate(): {
78
+ example: ResultSection[]
79
+ metadata?: TemplateMetadata
80
+ }
81
+ }
82
+
83
+ export interface InstanceHandle {
84
+ readonly type: 'INSTANCE'
85
+ readonly symbolId: string
86
+ readonly name: string
87
+ readonly children: (InstanceHandle | TextHandle | ErrorHandle)[]
88
+ readonly properties: Record<string, { value: string | boolean }>
89
+ readonly path?: string[]
90
+ readonly slots?: Record<string, { guid: string }>
91
+ /** Internal: the property name of the slot this node is content of, if any. */
92
+ readonly __containingSlotName__?: string
93
+
94
+ codeConnectId(): string | null
95
+
96
+ __find__(name: string): InstanceHandle | ErrorHandle | null
97
+ __findChildWithCriteria__(criteria: {
98
+ type: 'INSTANCE' | 'TEXT'
99
+ name: string
100
+ }): InstanceHandle | TextHandle | ErrorHandle | null
101
+ __getPropertyValue__(name: string): string | boolean | ErrorHandle
102
+ __render__(): ResultSection[]
103
+ __getProps__(): ResultSection[] | Record<string, unknown> | undefined
104
+ __renderWithFn__(
105
+ renderFn: (props: Record<string, unknown>) => TemplateStringResult,
106
+ ): ResultSection[] | ErrorHandle | undefined
107
+
108
+ getString(propName: string): string
109
+ getBoolean(propName: string): boolean
110
+ getBoolean<O extends Record<string, unknown>>(
111
+ propName: string,
112
+ options: O,
113
+ ): EnumOptionsValues<O>
114
+ getEnum<O extends Record<string, unknown>>(
115
+ propName: string,
116
+ options: O,
117
+ ): EnumOptionsValues<O> | undefined
118
+ getInstanceSwap(propName: string): InstanceHandle | ErrorHandle | undefined
119
+ getSlot(propName: string): SlotResult | undefined
120
+ hasCodeConnect(): boolean
121
+ getPropertyValue(name: string): string | boolean | ErrorHandle
122
+ findInstance(layerName: string, opts?: SelectorOptions): InstanceHandle | ErrorHandle
123
+ findText(layerName: string, opts?: SelectorOptions): TextHandle | ErrorHandle
124
+ findConnectedInstance(
125
+ codeConnectId: string,
126
+ opts?: SelectorOptions,
127
+ ): InstanceHandle | ErrorHandle | null
128
+ findConnectedInstances(
129
+ selectorFn: (node: InstanceHandle) => boolean,
130
+ opts?: SelectorOptions,
131
+ ): (InstanceHandle | ErrorHandle)[]
132
+ findLayers(
133
+ selectorFn: (node: InstanceHandle | TextHandle) => boolean,
134
+ opts?: SelectorOptions,
135
+ ): (InstanceHandle | TextHandle | ErrorHandle)[]
136
+ executeTemplate(): {
137
+ example: ResultSection[]
138
+ metadata?: TemplateMetadata
139
+ }
140
+ }
141
+
142
+ export type LayerHandle = InstanceHandle | TextHandle | ErrorHandle
143
+
144
+ export type EnumOptionsValues<O extends Record<string, unknown>> = O[keyof O]
145
+
146
+ export interface FigmaProperties {
147
+ string(propName: string): string
148
+ boolean(propName: string): boolean
149
+ boolean<O extends Record<string, unknown>>(propName: string, options: O): EnumOptionsValues<O>
150
+ enum<O extends Record<string, unknown>>(
151
+ propName: string,
152
+ options: O,
153
+ ): EnumOptionsValues<O> | undefined
154
+ // In error cases the implementation may return string (from TextHandle.__render__)
155
+ instance(propName: string): ResultSection[] | string | undefined
156
+ __instance__(
157
+ propName: string,
158
+ ): InstanceHandle | TextHandle | ErrorHandle | ResultSection[] | undefined
159
+ slot(propName: string): SlotResult | undefined
160
+ children(layerNames: string[]): ResultSection[]
161
+ }
162
+
163
+ export type TemplateLiteral = (
164
+ strings: TemplateStringsArray,
165
+ ...values: unknown[]
166
+ ) => TemplateStringResult
167
+
168
+ export interface Figma {
169
+ /** Per-entry data from a .figma.batch.json file. Available in batch templates. */
170
+ readonly batch: Record<string, any>
171
+
172
+ /** The currently selected component instance */
173
+ readonly selectedInstance: InstanceHandle & { readonly __properties__: FigmaProperties }
174
+ /** Alias for selectedInstance */
175
+ readonly currentLayer: InstanceHandle & { readonly __properties__: FigmaProperties }
176
+ /** Access component properties via the properties API */
177
+ readonly properties: FigmaProperties
178
+
179
+ /** Template literal tag for custom/plaintext code */
180
+ code: TemplateLiteral
181
+ /** Template literal tag for JSX/TSX code */
182
+ tsx: TemplateLiteral
183
+ /** Template literal tag for HTML code */
184
+ html: TemplateLiteral
185
+ /** Template literal tag for Swift code */
186
+ swift: TemplateLiteral
187
+ /** Template literal tag for Kotlin/Compose code */
188
+ kotlin: TemplateLiteral
189
+
190
+ /** Return a raw value (not rendered as a template string) */
191
+ value(raw: unknown, preview?: unknown): { type: string; value: unknown; preview: unknown }
192
+
193
+ helpers: {
194
+ react: {
195
+ renderProp(name: string, prop: FCCValue | ResultSection[]): TemplateStringResult | string
196
+ renderChildren(
197
+ prop: FCCValue | ResultSection[],
198
+ ): ResultSection[] | string | number | boolean | TemplateStringResult
199
+ renderPropValue(
200
+ prop: FCCValue | ResultSection[],
201
+ ): string | number | boolean | ResultSection[]
202
+ stringifyObject(obj: unknown): string
203
+ jsxElement(value: string): { $value: string; $type: 'jsx-element' }
204
+ function(value: string): { $value: string; $type: 'function' }
205
+ identifier(value: string): { $value: string; $type: 'identifier' }
206
+ object(value: ObjectValue): { $value: ObjectValue; $type: 'object' }
207
+ templateString(value: string): { $value: string; $type: 'template-string' }
208
+ reactComponent(value: string): { $value: string; $type: 'react-component' }
209
+ array(value: FCCValue[]): { $value: FCCValue[]; $type: 'array' }
210
+ isReactComponentArray(prop: unknown): boolean
211
+ }
212
+ swift: {
213
+ renderChildren(
214
+ children: ResultSection[] | string | undefined,
215
+ prefix: string,
216
+ ): ResultSection[]
217
+ }
218
+ kotlin: {
219
+ renderChildren(
220
+ children: ResultSection[] | string | undefined,
221
+ prefix: string,
222
+ ): ResultSection[]
223
+ }
224
+ }
225
+ }
226
+
227
+ const figma: Figma
228
+ export = figma
229
+ }
package/figma-types.d.ts CHANGED
@@ -32,6 +32,11 @@ declare module 'figma' {
32
32
  traverseInstances?: boolean
33
33
  }
34
34
 
35
+ export type SlotResult = ResultSection[] & {
36
+ /** Connected instances directly in the slot (shallow). */
37
+ readonly connectedInstances: InstanceHandle[]
38
+ }
39
+
35
40
  type ObjectValue = Record<string, FCCValue>
36
41
 
37
42
  export type FCCValue =
@@ -51,6 +56,7 @@ declare module 'figma' {
51
56
  readonly type: 'TEXT'
52
57
  readonly name: string
53
58
  readonly textContent: string
59
+ readonly __containingSlotName__?: string
54
60
  __render__(): string
55
61
  }
56
62
 
@@ -63,6 +69,7 @@ declare module 'figma' {
63
69
 
64
70
  export interface ErrorHandle {
65
71
  readonly type: 'ERROR'
72
+ readonly __containingSlotName__?: string
66
73
  __render__(): ResultSection[]
67
74
  executeTemplate(): {
68
75
  example: ResultSection[]
@@ -78,6 +85,8 @@ declare module 'figma' {
78
85
  readonly properties: Record<string, { value: string | boolean }>
79
86
  readonly path?: string[]
80
87
  readonly slots?: Record<string, { guid: string }>
88
+ /** Internal: the property name of the slot this node is content of, if any. */
89
+ readonly __containingSlotName__?: string
81
90
 
82
91
  codeConnectId(): string | null
83
92
 
@@ -103,8 +112,8 @@ declare module 'figma' {
103
112
  propName: string,
104
113
  options: O,
105
114
  ): EnumOptionsValues<O> | undefined
106
- getInstanceSwap(propName: string): InstanceHandle | undefined
107
- getSlot(propName: string): ResultSection[] | undefined
115
+ getInstanceSwap(propName: string): InstanceHandle | ErrorHandle | undefined
116
+ getSlot(propName: string): SlotResult | undefined
108
117
  hasCodeConnect(): boolean
109
118
  getPropertyValue(name: string): string | boolean | ErrorHandle
110
119
  findInstance(layerName: string, opts?: SelectorOptions): InstanceHandle | ErrorHandle
@@ -144,7 +153,7 @@ declare module 'figma' {
144
153
  __instance__(
145
154
  propName: string,
146
155
  ): InstanceHandle | TextHandle | ErrorHandle | ResultSection[] | undefined
147
- slot(propName: string): ResultSection[] | undefined
156
+ slot(propName: string): SlotResult | undefined
148
157
  children(layerNames: string[]): ResultSection[]
149
158
  }
150
159
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@figma/code-connect",
3
- "version": "1.4.7",
3
+ "version": "1.4.9",
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",
@@ -25,6 +25,9 @@
25
25
  },
26
26
  "./figma-types": {
27
27
  "types": "./figma-types.d.ts"
28
+ },
29
+ "./figma-types-no-require": {
30
+ "types": "./figma-types-no-require.d.ts"
28
31
  }
29
32
  },
30
33
  "repository": {
@@ -37,7 +40,8 @@
37
40
  },
38
41
  "files": [
39
42
  "dist/**/*",
40
- "figma-types.d.ts"
43
+ "figma-types.d.ts",
44
+ "figma-types-no-require.d.ts"
41
45
  ],
42
46
  "engines": {
43
47
  "node": ">=18"
@@ -83,7 +87,7 @@
83
87
  "@types/jest": "^29.5.13",
84
88
  "@types/jsdom": "^21.1.7",
85
89
  "@types/lodash": "4.17.20",
86
- "@types/node": "22.17.2",
90
+ "@types/node": "22.19.21",
87
91
  "@types/prettier": "2.7.3",
88
92
  "@types/prompts": "^2.4.9",
89
93
  "@types/react": "18.3.27",