1#!/usr/bin/env node
2import fastGlob from 'fast-glob';
3import {optimize} from 'svgo';
4import {parse} from 'node:path';
5import {readFile, writeFile, mkdir} from 'node:fs/promises';
6import {fileURLToPath} from 'node:url';
7import {exit} from 'node:process';
8
9const glob = (pattern) => fastGlob.sync(pattern, {
10 cwd: fileURLToPath(new URL('..', import.meta.url)),
11 absolute: true,
12});
13
14function doExit(err) {
15 if (err) console.error(err);
16 exit(err ? 1 : 0);
17}
18
19async function processFile(file, {prefix, fullName} = {}) {
20 let name;
21 if (fullName) {
22 name = fullName;
23 } else {
24 name = parse(file).name;
25 if (prefix) name = `${prefix}-${name}`;
26 if (prefix === 'octicon') name = name.replace(/-[0-9]+$/, ''); // chop of '-16' on octicons
27 }
28
29 // Set the `xmlns` attribute so that the files are displayable in standalone documents
30 // The svg backend module will strip the attribute during startup for inline display
31 const {data} = optimize(await readFile(file, 'utf8'), {
32 plugins: [
33 {name: 'preset-default'},
34 {name: 'removeDimensions'},
35 {name: 'prefixIds', params: {prefix: () => name}},
36 {name: 'addClassesToSVGElement', params: {classNames: ['svg', name]}},
37 {
38 name: 'addAttributesToSVGElement', params: {
39 attributes: [
40 {'xmlns': 'http://www.w3.org/2000/svg'},
41 {'width': '16'}, {'height': '16'}, {'aria-hidden': 'true'},
42 ],
43 },
44 },
45 ],
46 });
47
48 await writeFile(fileURLToPath(new URL(`../public/assets/img/svg/${name}.svg`, import.meta.url)), data);
49}
50
51function processFiles(pattern, opts) {
52 return glob(pattern).map((file) => processFile(file, opts));
53}
54
55async function main() {
56 try {
57 await mkdir(fileURLToPath(new URL('../public/assets/img/svg', import.meta.url)), {recursive: true});
58 } catch {}
59
60 await Promise.all([
61 ...processFiles('node_modules/@primer/octicons/build/svg/*-16.svg', {prefix: 'octicon'}),
62 ...processFiles('web_src/svg/*.svg'),
63 ]);
64}
65
66try {
67 doExit(await main());
68} catch (err) {
69 doExit(err);
70}