Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Migrate] JS to TS #104

Merged
merged 7 commits into from
Sep 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
node_modules
.env
src/svg
src/svg

built/
# TS -incremental file
tsconfig.tsbuildinfo
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ Your SVGs will be generated in `src/svg` folder
1. `yarn install`
2. Select the frame your icons are in ![Screenshot of a sample Figma project](documentation/export-svg-screenshot.png)
3. Copy the URL in the browser; it should look similar to `https://www.figma.com/file/abcASewbASmnas/Test?node-id=1%3123`
4. Run `node src/setupEnv.js` and paste in your URL copied from step 3 when prompted. This will generate a `.env` file
4. Run `ts-node src/setupEnv.ts` and paste in your URL copied from step 3 when prompted. This will generate a `.env` file
5. Generate a DEV_TOKEN a.k.a Personal Access Token by going to Help and Account > Account Settings > Personal Access Token
6. Add your DEV_TOKEN from step 5 into `.env` file
7. Run `node src/index.js` and your SVGs will be generated into `src/svg` folder
7. Run `ts-node src/index.ts` and your SVGs will be generated into `src/svg` folder

### Filtering Private Components (starting with a . or a _)
1. If you want to ignore / filter private components that start with a . or _, change the FILTER_PRIVATE_COMPONENTS variable to `true`. Thanks to [lennertVanSever for their contribution to this](https://github.com/jacobtyq/export-figma-svg/pull/27)
Expand Down
11 changes: 11 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
roots: ['<rootDir>/src'],
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest',
'^.+\\.(js|jsx)$': 'ts-jest',
},
preset: 'ts-jest',
testEnvironment: 'node',
testPathIgnorePatterns: ['node_modules/'],
}
20 changes: 14 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
{
"name": "export-figma-svg",
"version": "0.0.1",
"version": "2.0.0",
"description": "Export SVGs from Figma",
"main": "index.js",
"main": "index.ts",
"scripts": {
"test": "TZ=Asia/Singapore jest"
},
"author": "Jacob Tan <jacobtyq@gmail.com>",
"license": "MIT",
"dependencies": {
"axios": "^0.21.1",
"dotenv": "^10.0.0",
"axios": "^0.27.2",
"dotenv": "^16.0.1",
"fs": "^0.0.1-security",
"jest": "^26.6.3",
"pg": "^8.7.1"
"pg": "^8.7.1",
"ts-node": "^10.9.1",
"tsc": "^2.0.4",
"typescript": "^4.8.2"
},
"devDependencies": {
"@types/jest": "^29.0.0",
"@types/node": "^18.7.14",
"ts-jest": "^28.0.8",
"jest": "^29.0.1"
}
}
4 changes: 2 additions & 2 deletions src/util/figmaRestApi.js → src/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const axios = require('axios')
import axios from 'axios'
const figmaRestApi = axios.create({
baseURL:
process.env.FIGMA_BASE_URL,
Expand All @@ -7,4 +7,4 @@ const figmaRestApi = axios.create({
}
})

module.exports = figmaRestApi
export default figmaRestApi
4 changes: 4 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const OUTPUT_FOLDER = "./src/svg/";
export const RATE_LIMIT = 20;
export const WAIT_TIME_IN_SECONDS = 45;
export const ENV_OUTPUT_FILE = '.env'
82 changes: 0 additions & 82 deletions src/index.js

This file was deleted.

86 changes: 86 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import 'dotenv/config'
import axios from 'axios'
import figmaRestApi from './api/'
import {
writeToFile,
findAllByValue,
filterPrivateComponents,
camelCaseToDash,
createFolder,
} from './utils'
import { OUTPUT_FOLDER, RATE_LIMIT, WAIT_TIME_IN_SECONDS } from './constants'

const getProjectNode = async () => {
return await figmaRestApi.get(
'files/' +
process.env.FIGMA_PROJECT_ID +
'/nodes?ids=' +
process.env.FIGMA_PROJECT_NODE_ID
)
}

const getSVGURL = async (id: string) => {
return await figmaRestApi.get(
'images/' + process.env.FIGMA_PROJECT_ID + '/?ids=' + id + '&format=svg'
)
}

const svgExporter = async () => {
try {
const response = await getProjectNode()
const children = await response.data.nodes[
process.env.FIGMA_PROJECT_NODE_ID
].document.children

// If ignoring private components
let svgs
if (process.env.FILTER_PRIVATE_COMPONENTS === 'false') {
svgs = findAllByValue(children, 'COMPONENT')
} else {
svgs = filterPrivateComponents(findAllByValue(children, 'COMPONENT'))
}

const numOfSvgs = svgs.length

console.log('Number of SVGs', numOfSvgs)

createFolder(OUTPUT_FOLDER)

for (let i = 0; i < numOfSvgs; i += RATE_LIMIT) {
const requests = svgs.slice(i, i + RATE_LIMIT).map(async (svg) => {
// Get URL of each SVG
let svgName = await svg.name

if (svgName.includes('/')) {
const nameArr = svg.name.split('/').join('-')
svgName = nameArr
}

const svgURL = await getSVGURL(svg.id)

// Get SVG DOM
const svgDOM = await axios.get(svgURL.data.images[svg.id])
writeToFile(
OUTPUT_FOLDER + `${camelCaseToDash(svgName)}.svg`,
svgDOM.data
)
})

await Promise.all(requests)
.then(() => {
console.log(`Wait for ${WAIT_TIME_IN_SECONDS} seconds`)
return new Promise<void>(function (resolve) {
setTimeout(() => {
console.log(`${WAIT_TIME_IN_SECONDS} seconds!`)
resolve()
}, WAIT_TIME_IN_SECONDS * 1000)
})
})
.catch((err) => console.error(`Error proccessing ${i} - Error ${err}`))
}
} catch (err) {
console.error(err)
}
}

svgExporter()
11 changes: 6 additions & 5 deletions src/setupEnv.js → src/setupEnv.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
const readline = require('readline')
const fs = require('fs')
import * as readline from 'node:readline'
import * as fs from 'fs'
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
const outputFile = '.env';

const isValidURL = (url) => {
import { ENV_OUTPUT_FILE } from './constants'

const isValidURL = (url: string) => {
try {
new URL(url)
} catch (_) {
Expand Down Expand Up @@ -38,7 +39,7 @@ rl.question(`${question}`, (input) => {
'FILTER_PRIVATE_COMPONENTS=false'
]

let file = fs.createWriteStream(outputFile)
let file = fs.createWriteStream(ENV_OUTPUT_FILE)
file.on('error', function (err) {
console.log(err)
})
Expand Down
54 changes: 0 additions & 54 deletions src/util/utils.js

This file was deleted.

36 changes: 0 additions & 36 deletions src/util/utils.test.js

This file was deleted.

Loading