1 | 'use strict';
|
---|
2 |
|
---|
3 | const os = require('os');
|
---|
4 | const fs = require('fs');
|
---|
5 | const { pathToFileURL } = require('url');
|
---|
6 | const path = require('path');
|
---|
7 | const {
|
---|
8 | extendDefaultPlugins,
|
---|
9 | optimize: optimizeAgnostic,
|
---|
10 | createContentItem,
|
---|
11 | } = require('./svgo.js');
|
---|
12 |
|
---|
13 | exports.extendDefaultPlugins = extendDefaultPlugins;
|
---|
14 | exports.createContentItem = createContentItem;
|
---|
15 |
|
---|
16 | const importConfig = async (configFile) => {
|
---|
17 | let config;
|
---|
18 | // at the moment dynamic import may randomly fail with segfault
|
---|
19 | // to workaround this for some users .cjs extension is loaded
|
---|
20 | // exclusively with require
|
---|
21 | if (configFile.endsWith('.cjs')) {
|
---|
22 | config = require(configFile);
|
---|
23 | } else {
|
---|
24 | try {
|
---|
25 | // dynamic import expects file url instead of path and may fail
|
---|
26 | // when windows path is provided
|
---|
27 | const { default: imported } = await import(pathToFileURL(configFile));
|
---|
28 | config = imported;
|
---|
29 | } catch (importError) {
|
---|
30 | // TODO remove require in v3
|
---|
31 | try {
|
---|
32 | config = require(configFile);
|
---|
33 | } catch (requireError) {
|
---|
34 | // throw original error if es module is detected
|
---|
35 | if (requireError.code === 'ERR_REQUIRE_ESM') {
|
---|
36 | throw importError;
|
---|
37 | } else {
|
---|
38 | throw requireError;
|
---|
39 | }
|
---|
40 | }
|
---|
41 | }
|
---|
42 | }
|
---|
43 | if (config == null || typeof config !== 'object' || Array.isArray(config)) {
|
---|
44 | throw Error(`Invalid config file "${configFile}"`);
|
---|
45 | }
|
---|
46 | return config;
|
---|
47 | };
|
---|
48 |
|
---|
49 | const isFile = async (file) => {
|
---|
50 | try {
|
---|
51 | const stats = await fs.promises.stat(file);
|
---|
52 | return stats.isFile();
|
---|
53 | } catch {
|
---|
54 | return false;
|
---|
55 | }
|
---|
56 | };
|
---|
57 |
|
---|
58 | const loadConfig = async (configFile, cwd = process.cwd()) => {
|
---|
59 | if (configFile != null) {
|
---|
60 | if (path.isAbsolute(configFile)) {
|
---|
61 | return await importConfig(configFile);
|
---|
62 | } else {
|
---|
63 | return await importConfig(path.join(cwd, configFile));
|
---|
64 | }
|
---|
65 | }
|
---|
66 | let dir = cwd;
|
---|
67 | // eslint-disable-next-line no-constant-condition
|
---|
68 | while (true) {
|
---|
69 | const js = path.join(dir, 'svgo.config.js');
|
---|
70 | if (await isFile(js)) {
|
---|
71 | return await importConfig(js);
|
---|
72 | }
|
---|
73 | const mjs = path.join(dir, 'svgo.config.mjs');
|
---|
74 | if (await isFile(mjs)) {
|
---|
75 | return await importConfig(mjs);
|
---|
76 | }
|
---|
77 | const cjs = path.join(dir, 'svgo.config.cjs');
|
---|
78 | if (await isFile(cjs)) {
|
---|
79 | return await importConfig(cjs);
|
---|
80 | }
|
---|
81 | const parent = path.dirname(dir);
|
---|
82 | if (dir === parent) {
|
---|
83 | return null;
|
---|
84 | }
|
---|
85 | dir = parent;
|
---|
86 | }
|
---|
87 | };
|
---|
88 | exports.loadConfig = loadConfig;
|
---|
89 |
|
---|
90 | const optimize = (input, config) => {
|
---|
91 | if (config == null) {
|
---|
92 | config = {};
|
---|
93 | }
|
---|
94 | if (typeof config !== 'object') {
|
---|
95 | throw Error('Config should be an object');
|
---|
96 | }
|
---|
97 | return optimizeAgnostic(input, {
|
---|
98 | ...config,
|
---|
99 | js2svg: {
|
---|
100 | // platform specific default for end of line
|
---|
101 | eol: os.EOL === '\r\n' ? 'crlf' : 'lf',
|
---|
102 | ...config.js2svg,
|
---|
103 | },
|
---|
104 | });
|
---|
105 | };
|
---|
106 | exports.optimize = optimize;
|
---|