-
Notifications
You must be signed in to change notification settings - Fork 163
/
Copy pathfetchSVG.js
126 lines (115 loc) · 3.29 KB
/
fetchSVG.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
const got = require('got')
const {ensureDir, writeFile} = require('fs-extra')
const {join, resolve} = require('path')
const Figma = require('figma-js')
const PQueue = require('p-queue')
require('dotenv').config()
const {FIGMA_TOKEN, FIGMA_FILE_URL} = process.env
const options = {
format: 'svg',
outputDir: './src/',
scale: '1'
}
for(const arg of process.argv.slice(2)) {
const [param, value] = arg.split('=')
if(options[param]) {
options[param] = value
}
}
if(!FIGMA_TOKEN) {
throw Error('Cannot find FIGMA_TOKEN in process!')
}
const client = Figma.Client({
personalAccessToken: FIGMA_TOKEN
})
// Fail if there's no figma file key
let fileId = null
if (!fileId) {
try {
fileId = FIGMA_FILE_URL.match(/file\/([a-z0-9]+)\//i)[1]
} catch (e) {
throw Error('Cannot find FIGMA_FILE_URL key in process!')
}
}
console.log(`Exporting ${FIGMA_FILE_URL} components`)
client.file(fileId)
.then(({ data }) => {
console.log('Processing response')
const components = {}
function check(c) {
if (c.type === 'COMPONENT') {
const {name, id} = c
const {description = '', key} = data.components[c.id]
const {width, height} = c.absoluteBoundingBox
components[id] = {
name,
id,
key,
file: fileId,
description,
width,
height
}
} else if (c.children) {
// eslint-disable-next-line github/array-foreach
c.children.forEach(check)
}
}
data.document.children.forEach(check)
if (Object.values(components).length === 0) {
throw Error('No components found!')
}
console.log(`${Object.values(components).length} components found in the figma file`)
return components
})
.then(components => {
console.log('Getting export urls')
return client.fileImages(
fileId,
{
format: options.format,
ids: Object.keys(components),
scale: options.scale
}
).then(({data}) => {
for(const id of Object.keys(data.images)) {
components[id].image = data.images[id]
}
return components
})
})
.then(components => {
return ensureDir(join(options.outputDir))
.then(() => writeFile(resolve(options.outputDir, 'data.json'), JSON.stringify(components), 'utf8'))
.then(() => components)
})
.then(components => {
const contentTypes = {
'svg': 'image/svg+xml',
'png': 'image/png',
'jpg': 'image/jpeg'
}
return queueTasks(Object.values(components).map(component => () => {
return got.get(component.image, {
headers: {
'Content-Type': contentTypes[options.format]
},
encoding: (options.format === 'svg' ? 'utf8' : null)
})
.then(response => {
return ensureDir(join(options.outputDir, options.format))
.then(() => writeFile(join(options.outputDir, options.format, `${component.name}.${options.format}`), response.body, (options.format === 'svg' ? 'utf8' : 'binary')))
})
}))
})
.catch(error => {
throw Error(`Error fetching components from Figma: ${error}`)
})
function queueTasks(tasks, options) {
const queue = new PQueue(Object.assign({concurrency: 3}, options))
for (const task of tasks) {
queue.add(task)
}
queue.start()
return queue.onIdle()
}