Skip to content

Commit 8206e0b

Browse files
author
figma-bot
committed
Code Connect v1.3.0
1 parent bbd08d4 commit 8206e0b

File tree

63 files changed

+1900
-472
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1900
-472
lines changed

CHANGELOG.md

+27
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1+
# Code Connect v1.3.0 (28th January 2025)
2+
3+
## Features
4+
- Add support for JSX Figma connection files.
5+
- Added an option to automatically create or append the access token to the project's .env file
6+
- Add better handling of many figma components in the wizard (grouping per page)
7+
- Allow variant restrictions to use boolean-like properties
8+
9+
### General
10+
- Added support for Bitbucket, Gitlab and Azure DevOps for generated source file URLs
11+
12+
## Fixed
13+
- Don't show a red-cross when the file-matching prompt is finished in the wizard
14+
- Add default values for `@FigmaEnum` declarations in SwiftUI
15+
16+
### SwiftUI
17+
- Fixed a formatting error when running the CLI
18+
19+
### React
20+
- Fix nested objects and arrays in props not rendering properly in code snippets
21+
- Fixed a type issue when passing functions as values to `figma.boolean`
22+
- Add support for multiple exports per file in the wizard
23+
24+
### Storybook
25+
- Add support for different props per example (fixes https://github.com/figma/code-connect/issues/143)
26+
- Add support for `links` and `imports` (fixes https://github.com/figma/code-connect/issues/142)
27+
128
# Code Connect v1.2.4 (5th December 2024)
229

330
## Fixed

Package.resolved

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
"kind" : "remoteSourceControl",
2424
"location" : "https://github.com/nicklockwood/SwiftFormat",
2525
"state" : {
26-
"revision" : "9e5d0d588ab6e271fe9887ec3dde21d544d4b080",
27-
"version" : "0.53.5"
26+
"revision" : "2d5a2b6bde636c1feae2c852ab9a50f221e98c66",
27+
"version" : "0.55.3"
2828
}
2929
}
3030
],

Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ let package = Package(
1717
dependencies: [
1818
.package(url: "https://github.com/apple/swift-syntax", "510.0.3"..."600.0.0"),
1919
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"),
20-
.package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.49.0"),
20+
.package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.55.3"),
2121
],
2222
targets: [
2323
.target(

cli/package.json

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@figma/code-connect",
3-
"version": "1.2.4",
3+
"version": "1.3.0",
44
"description": "A tool for connecting your design system components in code with your design system in Figma",
55
"keywords": [],
66
"author": "Figma",
@@ -29,7 +29,8 @@
2929
"figma": "bin/figma"
3030
},
3131
"files": [
32-
"dist/**/*"
32+
"dist/**/*",
33+
"patches/**/*"
3334
],
3435
"engines": {
3536
"node": ">=18"
@@ -40,7 +41,7 @@
4041
"build:web": "pnpm build",
4142
"build:webpack": "cross-env NODE_OPTIONS=\"--max-old-space-size=4096\" webpack --mode production",
4243
"test": "npm run test:no-coverage -- --coverage",
43-
"test:no-coverage": "cross-env NODE_OPTIONS=--experimental-vm-modules npx jest",
44+
"test:no-coverage": "cross-env NODE_OPTIONS=\"--experimental-vm-modules --no-deprecation\" npx jest",
4445
"test:fast": "npm run test -- --testPathIgnorePatterns=template_rendering.test.ts --testPathIgnorePatterns=e2e_parse_command_swift.test.ts --testPathIgnorePatterns=e2e_wizard_swift.test.ts",
4546
"test:ci": "npm run test:non-mac -- --runInBand",
4647
"test:wizard": "npm run test -- --runInBand --testPathPattern=e2e_wizard_react.test.ts --testPathPattern=e2e_wizard_swift.test.ts",
@@ -58,15 +59,16 @@
5859
"bundle:cli:win": "npm run bundle:cli -- -o bundle-cli/figma-win --target node18-win-x64",
5960
"publish:npm": "npm install && npm run build && npm run bundle:npm-readme:prepare && npm publish --access public; npm run bundle:npm-readme:restore",
6061
"typecheck": "tsc --noEmit -p tsconfig-typecheck.json",
61-
"benchmarking:run": "npx tsx ./src/connect/wizard/__test__/prop_mapping/prop_mapping_benchmarking.ts"
62+
"benchmarking:run": "npx tsx ./src/connect/wizard/__test__/prop_mapping/prop_mapping_benchmarking.ts",
63+
"postinstall": "patch-package"
6264
},
6365
"devDependencies": {
6466

6567
"@types/cross-spawn": "^6.0.6",
6668
"@types/jest": "^29.5.13",
6769
"@types/jsdom": "^21.1.7",
6870
"@types/lodash": "^4.17.0",
69-
"@types/node": "^20.14.0",
71+
"@types/node": "^22.10.0",
7072
"@types/prettier": "2.7.3",
7173
"@types/prompts": "^2.4.9",
7274
"@types/react": "18.0.26",
@@ -86,7 +88,7 @@
8688
"@babel/parser": "7.26.0",
8789
"@babel/types": "7.26.0",
8890

89-
"@storybook/csf-tools": "^7.6.7",
91+
"@storybook/csf-tools": "^8.4.7",
9092
"boxen": "5.1.1",
9193
"chalk": "^4.1.2",
9294
"commander": "^11.1.0",
@@ -101,6 +103,7 @@
101103
"minimatch": "^9.0.3",
102104
"ora": "^5.4.1",
103105
"parse5": "^7.1.2",
106+
"patch-package": "^8.0.0",
104107
"prettier": "^2.8.8",
105108
"prompts": "^2.4.2",
106109
"strip-ansi": "^6.0.0",
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
diff --git a/node_modules/@types/prompts/index.d.ts b/node_modules/@types/prompts/index.d.ts
2+
index e3124b0..f4fac10 100644
3+
--- a/node_modules/@types/prompts/index.d.ts
4+
+++ b/node_modules/@types/prompts/index.d.ts
5+
@@ -91,6 +91,7 @@ declare namespace prompts {
6+
mask?: string | PrevCaller<T, string | Falsy> | undefined;
7+
stdout?: Writable | undefined;
8+
stdin?: Readable | undefined;
9+
+ submitOnEscapeKey?: boolean | undefined;
10+
}
11+
12+
type Answers<T extends string> = { [id in T]: any };

cli/patches/prompts+2.4.2.patch

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
diff --git a/node_modules/prompts/lib/elements/prompt.js b/node_modules/prompts/lib/elements/prompt.js
2+
index b793330..836de28 100644
3+
--- a/node_modules/prompts/lib/elements/prompt.js
4+
+++ b/node_modules/prompts/lib/elements/prompt.js
5+
@@ -26,6 +26,9 @@ class Prompt extends EventEmitter {
6+
const isSelect = [ 'SelectPrompt', 'MultiselectPrompt' ].indexOf(this.constructor.name) > -1;
7+
const keypress = (str, key) => {
8+
let a = action(key, isSelect);
9+
+ if (key.name === 'escape' && a === 'exit' && opts.submitOnEscapeKey) {
10+
+ a = 'submit'
11+
+ }
12+
if (a === false) {
13+
this._ && this._(str, key);
14+
} else if (typeof this[a] === 'function') {

cli/src/__test__/utils.ts

+10
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,13 @@ export function tidyStdOutput(input: string): string {
2121
.join('\n')
2222
)
2323
}
24+
25+
/**
26+
* Utility function to create a regex that matches a file in the repository.
27+
* This is necessary because the repository URLs (repository name, default branch) get changed
28+
* when publishing to different repositories
29+
*/
30+
31+
export function getFileInRepositoryRegex(filepath: string): RegExp {
32+
return new RegExp(`https://github.com/figma/code-connect/blob/[a-zA-Z/-]+${filepath}`)
33+
}

cli/src/commands/connect.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ export async function getCodeConnectObjects(
298298
type GetCodeConnectObjectsArgs = {
299299
parseFn: ParseFn
300300
resolveImportsFn?: ResolveImportsFn
301-
fileExtension: string
301+
fileExtension: string | string[]
302302
projectInfo: ProjectInfo<CodeConnectConfig>
303303
cmd: BaseCommand
304304
silent?: boolean
@@ -381,7 +381,7 @@ async function getReactCodeConnectObjects(
381381
const codeConnectObjects = await getCodeConnectObjectsFromParseFn({
382382
parseFn: parseReactDoc,
383383
resolveImportsFn: findAndResolveImports,
384-
fileExtension: 'tsx',
384+
fileExtension: ['tsx', 'jsx'],
385385
projectInfo,
386386
cmd,
387387
silent,

cli/src/connect/__test__/e2e/e2e_parse_command/dummy_api_response_for_wizard_many_components.json

+1
Large diffs are not rendered by default.

cli/src/connect/__test__/e2e/e2e_parse_command/react_storybook/ReactApiComponent.figmadoc.tsx

-5
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import figma from '../../../../../react/index_react'
2+
3+
import { ReactButtonComponent } from './ReactButtonComponent'
4+
5+
figma.connect(ReactButtonComponent, 'ui/button')

cli/src/connect/__test__/e2e/e2e_parse_command/react_storybook/ReactApiComponent.tsx renamed to cli/src/connect/__test__/e2e/e2e_parse_command/react_storybook/ReactButtonComponent.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ interface ButtonProps {
1111
* @param disabled disable the button
1212
* @returns JSX element
1313
*/
14-
export const ReactApiComponent = ({ children, disabled = false }: ButtonProps) => {
14+
export const ReactButtonComponent = ({ children, disabled = false }: ButtonProps) => {
1515
return <button disabled={disabled}>{children}</button>
1616
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import figma from '../../../../../react/index_react'
2+
import { ReactLabelComponent } from './ReactLabelComponent'
3+
4+
figma.connect(ReactLabelComponent, 'ui/label')
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react'
2+
3+
interface LabelProps {
4+
disabled: boolean
5+
children: any
6+
}
7+
8+
/**
9+
* @description This is a label
10+
* @param children text to render
11+
* @param disabled disable the button
12+
* @returns JSX element
13+
*/
14+
export const ReactLabelComponent = ({ children, disabled = false }: LabelProps) => {
15+
return <div style={{ pointerEvents: disabled ? 'none' : 'inherit' }}>{children}</div>
16+
}

cli/src/connect/__test__/e2e/e2e_parse_command/swift_package/Package.resolved

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
"kind" : "remoteSourceControl",
2525
"location" : "https://github.com/nicklockwood/SwiftFormat",
2626
"state" : {
27-
"revision" : "dd989a46d0c6f15c016484bab8afe5e7a67a4022",
28-
"version" : "0.54.0"
27+
"revision" : "2d5a2b6bde636c1feae2c852ab9a50f221e98c66",
28+
"version" : "0.55.3"
2929
}
3030
}
3131
],

cli/src/connect/__test__/e2e/e2e_parse_command/swift_parser/swift_parser.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
"kind" : "remoteSourceControl",
2424
"location" : "https://github.com/nicklockwood/SwiftFormat",
2525
"state" : {
26-
"revision" : "05cb325003a673b3d177c711b3bc909cfee07622",
27-
"version" : "0.53.9"
26+
"revision" : "2d5a2b6bde636c1feae2c852ab9a50f221e98c66",
27+
"version" : "0.55.3"
2828
}
2929
}
3030
],

cli/src/connect/__test__/e2e/e2e_parse_command/swift_wizard/swift_wizard.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
"kind" : "remoteSourceControl",
2424
"location" : "https://github.com/nicklockwood/SwiftFormat",
2525
"state" : {
26-
"revision" : "05cb325003a673b3d177c711b3bc909cfee07622",
27-
"version" : "0.53.9"
26+
"revision" : "2d5a2b6bde636c1feae2c852ab9a50f221e98c66",
27+
"version" : "0.55.3"
2828
}
2929
}
3030
],

cli/src/connect/__test__/e2e/e2e_parse_command_custom.test.ts

+22-16
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,28 @@ describe('e2e test for `parse` command custom parsers', () => {
88
const testPath = path.join(__dirname, `e2e_parse_command/${testName}`)
99
const json = JSON.parse(result.stdout)
1010

11-
expect(json).toMatchObject([
12-
{
13-
figmaNode: `${path.join(testPath, 'Test.test')}`,
14-
template:
15-
'{"config":{"parser":"custom","parserCommand":"node parser/custom_parser.js","include":["*.test"],"exclude":["Excluded.test"]},"mode":"PARSE"}',
16-
label: 'Test',
17-
source: `https://github.com/figma/code-connect/blob/main/cli/src/connect/__test__/e2e/e2e_parse_command/${testName}/Test.test`,
18-
},
19-
{
20-
figmaNode: `${path.join(testPath, 'OtherFile.test')}`,
21-
template:
22-
'{"config":{"parser":"custom","parserCommand":"node parser/custom_parser.js","include":["*.test"],"exclude":["Excluded.test"]},"mode":"PARSE"}',
23-
label: 'Test',
24-
source: `https://github.com/figma/code-connect/blob/main/cli/src/connect/__test__/e2e/e2e_parse_command/${testName}/OtherFile.test`,
25-
},
26-
])
11+
expect(json).toEqual(
12+
expect.arrayContaining([
13+
expect.objectContaining({
14+
figmaNode: `${path.join(testPath, 'Test.test')}`,
15+
template:
16+
'{"config":{"parser":"custom","parserCommand":"node parser/custom_parser.js","include":["*.test"],"exclude":["Excluded.test"]},"mode":"PARSE"}',
17+
label: 'Test',
18+
source: expect.stringMatching(
19+
/https:\/\/github\.com\/figma\/[a-z-/]+\/cli\/src\/connect\/__test__\/e2e\/e2e_parse_command\/\w+\/Test\.test/,
20+
),
21+
}),
22+
expect.objectContaining({
23+
figmaNode: `${path.join(testPath, 'OtherFile.test')}`,
24+
template:
25+
'{"config":{"parser":"custom","parserCommand":"node parser/custom_parser.js","include":["*.test"],"exclude":["Excluded.test"]},"mode":"PARSE"}',
26+
label: 'Test',
27+
source: expect.stringMatching(
28+
/https:\/\/github\.com\/figma\/[a-z-/]+\/cli\/src\/connect\/__test__\/e2e\/e2e_parse_command\/\w+\/OtherFile\.test/,
29+
),
30+
}),
31+
]),
32+
)
2733
}
2834

2935
it('successfully calls a custom parser executable', async () => {

cli/src/connect/__test__/e2e/e2e_parse_command_parser_executables.test.ts

+22-16
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,28 @@ describe('e2e test for `parse` command (parser executables)', () => {
88
const testPath = path.join(__dirname, `e2e_parse_command/${testName}`)
99
const json = JSON.parse(result.stdout)
1010

11-
expect(json).toMatchObject([
12-
{
13-
figmaNode: `${path.join(testPath, 'Test.test')}`,
14-
template:
15-
'{"config":{"parser":"__unit_test__","include":["*.test"],"exclude":["Excluded.test"]},"mode":"PARSE"}',
16-
label: 'Test',
17-
source: `https://github.com/figma/code-connect/blob/main/cli/src/connect/__test__/e2e/e2e_parse_command/${testName}/Test.test`,
18-
},
19-
{
20-
figmaNode: `${path.join(testPath, 'OtherFile.test')}`,
21-
template:
22-
'{"config":{"parser":"__unit_test__","include":["*.test"],"exclude":["Excluded.test"]},"mode":"PARSE"}',
23-
label: 'Test',
24-
source: `https://github.com/figma/code-connect/blob/main/cli/src/connect/__test__/e2e/e2e_parse_command/${testName}/OtherFile.test`,
25-
},
26-
])
11+
expect(json).toEqual(
12+
expect.arrayContaining([
13+
expect.objectContaining({
14+
figmaNode: `${path.join(testPath, 'Test.test')}`,
15+
template:
16+
'{"config":{"parser":"__unit_test__","include":["*.test"],"exclude":["Excluded.test"]},"mode":"PARSE"}',
17+
label: 'Test',
18+
source: expect.stringMatching(
19+
/https:\/\/github\.com\/figma\/[a-z-/]+\/cli\/src\/connect\/__test__\/e2e\/e2e_parse_command\/\w+\/Test\.test/,
20+
),
21+
}),
22+
expect.objectContaining({
23+
figmaNode: `${path.join(testPath, 'OtherFile.test')}`,
24+
template:
25+
'{"config":{"parser":"__unit_test__","include":["*.test"],"exclude":["Excluded.test"]},"mode":"PARSE"}',
26+
label: 'Test',
27+
source: expect.stringMatching(
28+
/https:\/\/github\.com\/figma\/[a-z-/]+\/cli\/src\/connect\/__test__\/e2e\/e2e_parse_command\/\w+\/OtherFile\.test/,
29+
),
30+
}),
31+
]),
32+
)
2733
}
2834

2935
it('successfully calls a first party parser executable', async () => {

0 commit comments

Comments
 (0)