[6a3a178] | 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;
|
---|
[e29cc2e] | 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 {
|
---|
[6a3a178] | 24 | try {
|
---|
[e29cc2e] | 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 | }
|
---|
[6a3a178] | 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;
|
---|