Skip to content

Commit b2466e2

Browse files
committed
feat(svgoconfig): accept svgo config as parameter
1 parent f8e547b commit b2466e2

File tree

7 files changed

+205
-61
lines changed

7 files changed

+205
-61
lines changed

src/bin/svg-to-ts.ts

+12-52
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,21 @@
11
#!/usr/bin/env node
2-
import commander from 'commander';
32

4-
import * as packgeJSON from '../../package.json';
5-
import { Delimiter } from '../lib/generators/code-snippet-generators';
63
import { convertToSingleFile } from '../lib/converters/single-file.converter';
74
import { convertToMultipleFiles } from '../lib/converters/multiple-files.converter';
8-
import { DEFAULT_OPTIONS } from '../lib/options/default-options';
95
import { getOptions, MultiFileConvertionOptions, SingleFileConvertionOptions } from '../lib/options/convertion-options';
106
import { printLogo } from '../lib/helpers/log-helper';
7+
import { setupCommander } from '../lib/options/args-collector';
118

12-
const collect = (value, previous) => previous.concat([value]);
9+
const start = async () => {
10+
setupCommander();
11+
printLogo();
12+
const convertionOptions = await getOptions();
1313

14-
commander
15-
.version(packgeJSON.version)
16-
.option('-t --typeName <string>', 'name of the generated enumeration type', DEFAULT_OPTIONS.typeName)
17-
.option('-f --fileName <string>', 'name of the generated file', DEFAULT_OPTIONS.fileName)
18-
.option(
19-
'-d --delimiter <Delimiter>',
20-
`delimiter which is used to generate the types and name properties (${Object.values(Delimiter).join(',')})`,
21-
DEFAULT_OPTIONS.delimiter
22-
)
23-
.option('-p --prefix <string>', 'prefix for the generated svg constants', DEFAULT_OPTIONS.prefix)
24-
.option('-i --interfaceName <string>', 'name for the generated interface', DEFAULT_OPTIONS.interfaceName)
25-
.option('-s --srcFiles <value>', 'name of the source directory', collect, [])
26-
.option('-o --outputDirectory <string>', 'name of the output directory', DEFAULT_OPTIONS.outputDirectory)
27-
.option(
28-
'--optimizeForLazyLoading <boolean>',
29-
'optimize the output for lazyloading',
30-
DEFAULT_OPTIONS.optimizeForLazyLoading
31-
)
32-
.option(
33-
'--modelFileName <string>',
34-
'FileName of the model file (only necessary when optimizeForLazyLoading option is enabled)',
35-
DEFAULT_OPTIONS.modelFileName
36-
)
37-
.option(
38-
'--iconsFolderName <string>',
39-
'Name of the folder the icons will be generated to (only necessary when optimizeForLazyLoading option is enabled)',
40-
DEFAULT_OPTIONS.iconsFolderName
41-
)
42-
.option(
43-
'--additionalModelOutputPath <string>',
44-
'Additional outputpath for the models file (only helpful when optimizeForLazyLoading option is enabled)',
45-
DEFAULT_OPTIONS.additionalModelOutputPath
46-
)
47-
.option(
48-
'--preCompileSources <boolean>',
49-
'Tells if the sources should be precompiled with the TypeScript compiler. If true, you will only end up with d.ts and js files (only necessary when optimizeForLazyLoading option is enabled)',
50-
DEFAULT_OPTIONS.compileSources
51-
)
52-
.parse(process.argv);
14+
if (convertionOptions.optimizeForLazyLoading) {
15+
convertToMultipleFiles(convertionOptions as MultiFileConvertionOptions);
16+
} else {
17+
convertToSingleFile(convertionOptions as SingleFileConvertionOptions);
18+
}
19+
};
5320

54-
printLogo();
55-
const convertionOptions = getOptions();
56-
57-
if (convertionOptions.optimizeForLazyLoading) {
58-
convertToMultipleFiles(convertionOptions as MultiFileConvertionOptions);
59-
} else {
60-
convertToSingleFile(convertionOptions as SingleFileConvertionOptions);
61-
}
21+
start();

src/lib/helpers/file-helpers.ts

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ export const writeFile = async (outputDirectory: string, fileName: string, fileC
2020
await writeFileToFS(path.join(outputDirectory, `${fileName}.ts`), formatedFileContent);
2121
};
2222

23+
export const readFile = async (filePath: string): Promise<any> => {
24+
return await readfileFromFS(filePath, 'utf-8');
25+
};
26+
2327
export const deleteFolder = async (directoryPath: string) => {
2428
if (fs.existsSync(directoryPath)) {
2529
fs.readdirSync(directoryPath).forEach((filePath: string) => {

src/lib/helpers/svg-optimization.ts

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { readFile } from './file-helpers';
2+
13
const svgo = require('svgo');
24

35
export const svgOptimizer = new svgo({
@@ -103,3 +105,10 @@ export const svgOptimizer = new svgo({
103105
}
104106
]
105107
});
108+
109+
export const getSvgoConfig = async (svgoConfig: any): Promise<string> => {
110+
if (typeof svgoConfig === 'string') {
111+
return await readFile(svgoConfig);
112+
}
113+
return svgoConfig;
114+
};

src/lib/options/args-collector.ts

+58-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,59 @@
11
import commander from 'commander';
22
import { MultiFileConvertionOptions, SingleFileConvertionOptions } from './convertion-options';
33
import { DEFAULT_OPTIONS } from './default-options';
4+
import * as packgeJSON from '../../../package.json';
5+
import { Delimiter } from '../generators/code-snippet-generators';
6+
import { getSvgoConfig } from '../helpers/svg-optimization';
47

5-
export const collectArgumentOptions = (): SingleFileConvertionOptions | MultiFileConvertionOptions => {
8+
export const setupCommander = () => {
9+
const collect = (value, previous) => previous.concat([value]);
10+
commander
11+
.version(packgeJSON.version)
12+
.option('-t --typeName <string>', 'name of the generated enumeration type', DEFAULT_OPTIONS.typeName)
13+
.option('-f --fileName <string>', 'name of the generated file', DEFAULT_OPTIONS.fileName)
14+
.option(
15+
'-d --delimiter <Delimiter>',
16+
`delimiter which is used to generate the types and name properties (${Object.values(Delimiter).join(',')})`,
17+
DEFAULT_OPTIONS.delimiter
18+
)
19+
.option('-p --prefix <string>', 'prefix for the generated svg constants', DEFAULT_OPTIONS.prefix)
20+
.option('-i --interfaceName <string>', 'name for the generated interface', DEFAULT_OPTIONS.interfaceName)
21+
.option('-s --srcFiles <value>', 'name of the source directory', collect, [])
22+
.option('-o --outputDirectory <string>', 'name of the output directory', DEFAULT_OPTIONS.outputDirectory)
23+
.option(
24+
'--svgoConfig <any>',
25+
'Path to svgo configuration JSON or inline svgo configuration object',
26+
DEFAULT_OPTIONS.svgoConfig
27+
)
28+
.option(
29+
'--optimizeForLazyLoading <boolean>',
30+
'optimize the output for lazyloading',
31+
DEFAULT_OPTIONS.optimizeForLazyLoading
32+
)
33+
.option(
34+
'--modelFileName <string>',
35+
'FileName of the model file (only necessary when optimizeForLazyLoading option is enabled)',
36+
DEFAULT_OPTIONS.modelFileName
37+
)
38+
.option(
39+
'--iconsFolderName <string>',
40+
'Name of the folder the icons will be generated to (only necessary when optimizeForLazyLoading option is enabled)',
41+
DEFAULT_OPTIONS.iconsFolderName
42+
)
43+
.option(
44+
'--additionalModelOutputPath <string>',
45+
'Additional outputpath for the models file (only helpful when optimizeForLazyLoading option is enabled)',
46+
DEFAULT_OPTIONS.additionalModelOutputPath
47+
)
48+
.option(
49+
'--preCompileSources <boolean>',
50+
'Tells if the sources should be precompiled with the TypeScript compiler. If true, you will only end up with d.ts and js files (only necessary when optimizeForLazyLoading option is enabled)',
51+
DEFAULT_OPTIONS.compileSources
52+
)
53+
.parse(process.argv);
54+
};
55+
56+
export const collectArgumentOptions = async (): Promise<SingleFileConvertionOptions | MultiFileConvertionOptions> => {
657
const {
758
delimiter,
859
fileName,
@@ -16,6 +67,7 @@ export const collectArgumentOptions = (): SingleFileConvertionOptions | MultiFil
1667
additionalModelOutputPath,
1768
compileSources
1869
} = commander;
70+
let svgoConfig = commander.svgoConfig;
1971

2072
// Because of commander adding default value to params
2173
// See: https://stackoverflow.com/questions/30238654/commander-js-collect-multiple-options-always-include-default
@@ -24,6 +76,10 @@ export const collectArgumentOptions = (): SingleFileConvertionOptions | MultiFil
2476
srcFiles = DEFAULT_OPTIONS.srcFiles;
2577
}
2678

79+
if (svgoConfig) {
80+
svgoConfig = await getSvgoConfig(svgoConfig);
81+
}
82+
2783
return {
2884
delimiter,
2985
fileName,
@@ -34,6 +90,7 @@ export const collectArgumentOptions = (): SingleFileConvertionOptions | MultiFil
3490
typeName,
3591
modelFileName,
3692
iconsFolderName,
93+
svgoConfig,
3794
optimizeForLazyLoading,
3895
additionalModelOutputPath,
3996
compileSources

src/lib/options/config-collector.ts

+14-4
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,20 @@ import { info } from '../helpers/log-helper';
55

66
import { MultiFileConvertionOptions, SingleFileConvertionOptions } from './convertion-options';
77
import { DEFAULT_OPTIONS } from './default-options';
8+
import { getSvgoConfig } from '../helpers/svg-optimization';
89

9-
export const collectConfigurationOptions = (): SingleFileConvertionOptions | MultiFileConvertionOptions | null => {
10+
export const collectConfigurationOptions = async (): Promise<
11+
SingleFileConvertionOptions | MultiFileConvertionOptions | null
12+
> => {
1013
const explorerSync = cosmiconfigSync(packgeJSON.name);
1114
const cosmiConfigResult = explorerSync.search();
1215
cosmiConfigResult ? info(`Configuration found under: ${cosmiConfigResult.filepath}`) : info('No config found');
13-
return cosmiConfigResult ? mergeWithDefaults(cosmiConfigResult.config) : null;
16+
return cosmiConfigResult ? await mergeWithDefaults(cosmiConfigResult.config) : null;
1417
};
1518

16-
const mergeWithDefaults = (
19+
const mergeWithDefaults = async (
1720
options: MultiFileConvertionOptions | SingleFileConvertionOptions
18-
): MultiFileConvertionOptions | SingleFileConvertionOptions => {
21+
): Promise<MultiFileConvertionOptions | SingleFileConvertionOptions> => {
1922
const configOptions = { ...options };
2023
if (!configOptions.typeName) {
2124
configOptions.typeName = DEFAULT_OPTIONS.typeName;
@@ -47,6 +50,13 @@ const mergeWithDefaults = (
4750
info(`No srcFiles provided, "${DEFAULT_OPTIONS.srcFiles}" will be used`);
4851
}
4952

53+
if (!configOptions.svgoConfig) {
54+
configOptions.svgoConfig = DEFAULT_OPTIONS.svgoConfig;
55+
info(`No svgoConfig provided, "${DEFAULT_OPTIONS.svgoConfig}" will be used`);
56+
} else {
57+
configOptions.svgoConfig = await getSvgoConfig(configOptions.svgoConfig);
58+
}
59+
5060
if (configOptions.optimizeForLazyLoading) {
5161
if (!(configOptions as MultiFileConvertionOptions).modelFileName) {
5262
(configOptions as MultiFileConvertionOptions).modelFileName = DEFAULT_OPTIONS.modelFileName;

src/lib/options/convertion-options.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface ConvertionOptions {
99
prefix: string;
1010
interfaceName: string;
1111
srcFiles: string[];
12+
svgoConfig: any;
1213
outputDirectory: string;
1314
optimizeForLazyLoading: string;
1415
}
@@ -24,14 +25,14 @@ export interface MultiFileConvertionOptions extends ConvertionOptions {
2425
compileSources: boolean;
2526
}
2627

27-
export const getOptions = (): MultiFileConvertionOptions | SingleFileConvertionOptions => {
28-
const configOptions = collectConfigurationOptions();
28+
export const getOptions = async (): Promise<MultiFileConvertionOptions | SingleFileConvertionOptions> => {
29+
const configOptions = await collectConfigurationOptions();
2930

3031
if (configOptions) {
3132
return configOptions;
3233
}
3334
info(
3435
'No configuration found in package.json nor rc file - checking for arguments and applying defaults (see --help)'
3536
);
36-
return collectArgumentOptions();
37+
return await collectArgumentOptions();
3738
};

src/lib/options/default-options.ts

+104-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,108 @@ export const DEFAULT_OPTIONS = {
1212
additionalModelOutputPath: null,
1313
modelFileName: 'my-icons.model',
1414
iconsFolderName: 'build',
15-
compileSources: false
15+
compileSources: false,
16+
svgoConfig: {
17+
plugins: [
18+
{
19+
cleanupAttrs: true
20+
},
21+
{
22+
removeDoctype: true
23+
},
24+
{
25+
removeXMLProcInst: true
26+
},
27+
{
28+
removeComments: true
29+
},
30+
{
31+
removeMetadata: true
32+
},
33+
{
34+
removeTitle: true
35+
},
36+
{
37+
removeDesc: true
38+
},
39+
{
40+
removeUselessDefs: true
41+
},
42+
{
43+
removeEditorsNSData: true
44+
},
45+
{
46+
removeEmptyAttrs: true
47+
},
48+
{
49+
removeHiddenElems: true
50+
},
51+
{
52+
removeEmptyText: true
53+
},
54+
{
55+
removeEmptyContainers: true
56+
},
57+
{
58+
removeViewBox: false
59+
},
60+
{
61+
cleanupEnableBackground: true
62+
},
63+
{
64+
convertStyleToAttrs: true
65+
},
66+
{
67+
convertColors: true
68+
},
69+
{
70+
convertPathData: true
71+
},
72+
{
73+
convertTransform: true
74+
},
75+
{
76+
removeUnknownsAndDefaults: true
77+
},
78+
{
79+
removeNonInheritableGroupAttrs: true
80+
},
81+
{
82+
removeUselessStrokeAndFill: true
83+
},
84+
{
85+
removeUnusedNS: true
86+
},
87+
{
88+
cleanupIDs: true
89+
},
90+
{
91+
cleanupNumericValues: true
92+
},
93+
{
94+
moveElemsAttrsToGroup: true
95+
},
96+
{
97+
moveGroupAttrsToElems: true
98+
},
99+
{
100+
collapseGroups: true
101+
},
102+
{
103+
removeRasterImages: false
104+
},
105+
{
106+
mergePaths: true
107+
},
108+
{
109+
convertShapeToPath: true
110+
},
111+
{
112+
sortAttrs: true
113+
},
114+
{
115+
removeDimensions: true
116+
}
117+
]
118+
}
16119
};

0 commit comments

Comments
 (0)