Skip to content

Commit

Permalink
[Migrate] JS to TS (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobtyq authored Sep 2, 2022
1 parent cca57cd commit aee04fa
Show file tree
Hide file tree
Showing 15 changed files with 1,618 additions and 2,708 deletions.
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 <[email protected]>",
"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

0 comments on commit aee04fa

Please sign in to comment.