Skip to content

Commit 524655f

Browse files
committed
feat(config): read config from package.json, rc file and args
1 parent 697fece commit 524655f

8 files changed

+218
-96
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"format:write": "prettier --write 'src/**/*.ts'",
1313
"prebuild": "npm run copy:readme",
1414
"start": "ts-node ./src/bin/svg-to-ts.ts -s './inputfiles/*.svg'",
15+
"start:ofl": "ts-node ./src/bin/svg-to-ts.ts -s './inputfiles/*.svg' --optimizeForLazyLoading true",
1516
"start:help": "ts-node ./src/bin/svg-to-ts.ts -h",
1617
"start:regex": "ts-node ./src/bin/svg-to-ts.ts -s './inputfilesRegex/**/*.svg'",
1718
"start:kebap": "ts-node ./src/bin/svg-to-ts.ts -s './inputfiles/*.svg' -d KEBAB",
@@ -53,6 +54,7 @@
5354
"chalk": "^3.0.0",
5455
"commander": "^4.0.1",
5556
"cosmiconfig": "^6.0.0",
57+
"glob": "^7.1.6",
5658
"lodash.camelcase": "^4.3.0",
5759
"lodash.kebabcase": "^4.1.1",
5860
"lodash.snakecase": "^4.1.1",
@@ -66,7 +68,6 @@
6668
"@types/jest": "^24.0.23",
6769
"@types/node": "^12.12.8",
6870
"copyfiles": "^2.1.1",
69-
"glob": "^7.1.6",
7071
"husky": "^3.1.0",
7172
"jest": "^24.9.0",
7273
"pretty-quick": "^2.0.1",

src/bin/svg-to-ts.ts

+34-77
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,54 @@
11
#!/usr/bin/env node
22
import commander from 'commander';
3-
import { cosmiconfig, cosmiconfigSync } from 'cosmiconfig';
43

4+
import * as packgeJSON from '../../package.json';
55
import { Delimiter } from '../lib/generators/code-snippet-generators';
66
import { convertToSingleFile } from '../lib/converters/single-file.converter';
77
import { convertToMultipleFiles } from '../lib/converters/multiple-files.converter';
8+
import { DEFAULT_OPTIONS } from '../lib/options/default-options';
9+
import { getOptions, MultiFileConvertionOptions, SingleFileConvertionOptions } from '../lib/options/convertion-options';
810

9-
import * as packgeJSON from '../../package.json';
10-
11-
export interface ConvertionOptions {
12-
delimiter: Delimiter;
13-
typeName: string;
14-
prefix: string;
15-
fileName: string;
16-
interfaceName: string;
17-
srcFiles: string[];
18-
outputDirectory: string;
19-
modelOutputPath: string;
20-
modelFileName: string;
21-
}
22-
23-
const DEFAULTS = {
24-
fileName: 'my-icons',
25-
delimiter: Delimiter.SNAKE,
26-
interfaceName: 'MyIcon',
27-
outputDirectory: './dist',
28-
prefix: 'myIcon',
29-
sourceFilesRegex: ['*.svg'],
30-
typeName: 'myIcons',
31-
optimizeForLazyLoading: false
32-
};
33-
34-
function collect(value, previous) {
35-
return previous.concat([value]);
36-
}
37-
38-
const moduleName = 'svg-to-ts';
39-
const explorerSync = cosmiconfigSync(moduleName);
40-
41-
const searchedFor = explorerSync.search();
42-
console.log('Searchedfor', searchedFor);
11+
const collect = (value, previous) => previous.concat([value]);
4312

4413
commander
4514
.version(packgeJSON.version)
46-
.option('-t --typeName <string>', 'name of the generated enumeration type', DEFAULTS.typeName)
47-
.option('-f --fileName <string>', 'name of the generated file', DEFAULTS.fileName)
15+
.option('-t --typeName <string>', 'name of the generated enumeration type', DEFAULT_OPTIONS.typeName)
16+
.option('-f --fileName <string>', 'name of the generated file', DEFAULT_OPTIONS.fileName)
4817
.option(
4918
'-d --delimiter <Delimiter>',
5019
`delimiter which is used to generate the types and name properties (${Object.values(Delimiter).join(',')})`,
51-
DEFAULTS.delimiter
20+
DEFAULT_OPTIONS.delimiter
5221
)
53-
.option('-p --prefix <string>', 'prefix for the generated svg constants', DEFAULTS.prefix)
54-
.option('-i --interfaceName <string>', 'name for the generated interface', DEFAULTS.interfaceName)
22+
.option('-p --prefix <string>', 'prefix for the generated svg constants', DEFAULT_OPTIONS.prefix)
23+
.option('-i --interfaceName <string>', 'name for the generated interface', DEFAULT_OPTIONS.interfaceName)
5524
.option('-s --srcFiles <value>', 'name of the source directory', collect, [])
56-
.option('-o --outputDirectory <string>', 'name of the output directory', DEFAULTS.outputDirectory)
57-
.option('--optimizeForLazyLoading <boolean>', 'optimize the output for lazyloading', DEFAULTS.optimizeForLazyLoading)
58-
.option('--modelOutputPath <string>', 'Output path for the types file')
59-
.option('--modelFileName <string>', 'FileName of the model file')
25+
.option('-o --outputDirectory <string>', 'name of the output directory', DEFAULT_OPTIONS.outputDirectory)
26+
.option(
27+
'--optimizeForLazyLoading <boolean>',
28+
'optimize the output for lazyloading',
29+
DEFAULT_OPTIONS.optimizeForLazyLoading
30+
)
31+
.option(
32+
'--modelOutputPath <string>',
33+
'Output path for the types file (only necessary when optimizeForLazyLoading option is enabled)',
34+
DEFAULT_OPTIONS.modelOutputPath
35+
)
36+
.option(
37+
'--modelFileName <string>',
38+
'FileName of the model file (only necessary when optimizeForLazyLoading option is enabled)',
39+
DEFAULT_OPTIONS.modelFileName
40+
)
41+
.option(
42+
'--iconsFolderName <string>',
43+
'Name of the folder the icons will be generated to (only necessary when optimizeForLazyLoading option is enabled)',
44+
DEFAULT_OPTIONS.iconsFolderName
45+
)
6046
.parse(process.argv);
6147

62-
const {
63-
delimiter,
64-
fileName,
65-
interfaceName,
66-
outputDirectory,
67-
prefix,
68-
typeName,
69-
modelFileName,
70-
modelOutputPath
71-
} = commander;
72-
73-
// Because of commander adding default value to params
74-
// See: https://stackoverflow.com/questions/30238654/commander-js-collect-multiple-options-always-include-default
75-
let srcFiles = commander.srcFiles;
76-
if (srcFiles.length === 0) {
77-
srcFiles = DEFAULTS.sourceFilesRegex;
78-
}
79-
const optimizeForLazyLoading = commander.optimizeForLazyLoading;
80-
81-
const convertionOptions = {
82-
delimiter,
83-
typeName,
84-
fileName,
85-
prefix,
86-
interfaceName,
87-
srcFiles,
88-
outputDirectory,
89-
modelOutputPath,
90-
modelFileName
91-
};
48+
const convertionOptions = getOptions();
9249

93-
if (optimizeForLazyLoading) {
94-
convertToMultipleFiles(convertionOptions);
50+
if (convertionOptions.optimizeForLazyLoading) {
51+
convertToMultipleFiles(convertionOptions as MultiFileConvertionOptions);
9552
} else {
96-
convertToSingleFile(convertionOptions);
53+
convertToSingleFile(convertionOptions as SingleFileConvertionOptions);
9754
}

src/lib/converters/multiple-files.converter.ts

+11-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import * as path from 'path';
22

3-
import { ConvertionOptions } from '../../bin/svg-to-ts';
4-
53
import {
64
generateExportStatement,
75
generateInterfaceDefinition,
@@ -15,11 +13,11 @@ import { deleteFiles, deleteFolder, extractSvgContent, writeFile } from '../help
1513
import { compileSources } from '../compiler/typescript-compiler';
1614
import { info, success } from '../helpers/log-helper';
1715
import { svgOptimizer } from '../helpers/svg-optimization';
16+
import { MultiFileConvertionOptions } from '../options/convertion-options';
1817

19-
const generateIconsFolderName = 'build';
2018
const typesDelimitor = ' | ';
2119

22-
export const convertToMultipleFiles = async (convertionOptions: ConvertionOptions): Promise<void> => {
20+
export const convertToMultipleFiles = async (convertionOptions: MultiFileConvertionOptions): Promise<void> => {
2321
const {
2422
typeName,
2523
interfaceName,
@@ -28,15 +26,16 @@ export const convertToMultipleFiles = async (convertionOptions: ConvertionOption
2826
outputDirectory,
2927
srcFiles,
3028
modelOutputPath,
31-
modelFileName
29+
modelFileName,
30+
iconsFolderName
3231
} = convertionOptions;
3332
let indexFileContent = '';
3433
let types = generateTypeDefinition(typeName);
3534

3635
try {
3736
const filePaths = await getFilePathsFromRegex(srcFiles);
38-
await deleteFolder(`${outputDirectory}/${generateIconsFolderName}`);
39-
info(`deleting output directory: ${outputDirectory}/${generateIconsFolderName}`);
37+
await deleteFolder(`${outputDirectory}/${iconsFolderName}`);
38+
info(`deleting output directory: ${outputDirectory}/${iconsFolderName}`);
4039

4140
for (let i = 0; i < filePaths.length; i++) {
4241
const fileNameWithEnding = path.basename(filePaths[i]);
@@ -50,17 +49,17 @@ export const convertToMultipleFiles = async (convertionOptions: ConvertionOption
5049
const typeName = generateTypeName(filenameWithoutEnding, delimiter);
5150
const svgConstant = generateUntypedSvgConstant(variableName, typeName, optimizedSvg.data);
5251
const generatedFileName = `${prefix}-${filenameWithoutEnding}.icon`;
53-
indexFileContent += generateExportStatement(generatedFileName, generateIconsFolderName);
54-
await writeFile(`${outputDirectory}/${generateIconsFolderName}`, generatedFileName, svgConstant);
55-
info(`write file svg: ${outputDirectory}/${generateIconsFolderName}/${generatedFileName}.ts`);
52+
indexFileContent += generateExportStatement(generatedFileName, iconsFolderName);
53+
await writeFile(`${outputDirectory}/${iconsFolderName}`, generatedFileName, svgConstant);
54+
info(`write file svg: ${outputDirectory}/${iconsFolderName}/${generatedFileName}.ts`);
5655

5756
types += i === filePaths.length - 1 ? `'${typeName}';` : `'${typeName}'${typesDelimitor}`;
5857
}
5958
}
6059
await writeFile(outputDirectory, 'index', indexFileContent);
6160
info(`write index.ts`);
6261
const generatedTypeScriptFilePaths = await getFilePathsFromRegex([
63-
`${outputDirectory}/${generateIconsFolderName}/*.ts`,
62+
`${outputDirectory}/${iconsFolderName}/*.ts`,
6463
`${outputDirectory}/index.ts`
6564
]);
6665
compileSources(generatedTypeScriptFilePaths);
@@ -70,7 +69,7 @@ export const convertToMultipleFiles = async (convertionOptions: ConvertionOption
7069

7170
if (modelOutputPath && modelFileName) {
7271
const modelFile = (types += generateInterfaceDefinition(interfaceName, typeName));
73-
await writeFile(modelOutputPath, `${modelFileName}.model`, modelFile);
72+
await writeFile(modelOutputPath, modelFileName, modelFile);
7473
info(`model-file successfully generated under ${modelOutputPath}/${modelFileName}.model.ts`);
7574
}
7675

src/lib/converters/single-file.converter.ts

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import * as path from 'path';
22

3-
import { ConvertionOptions } from '../../bin/svg-to-ts';
4-
53
import {
64
generateInterfaceDefinition,
75
generateSvgConstant,
@@ -11,12 +9,13 @@ import {
119
} from '../generators/code-snippet-generators';
1210
import { getFilePathsFromRegex } from '../helpers/regex-helpers';
1311
import { extractSvgContent, writeFile } from '../helpers/file-helpers';
14-
import { success, underlineSuccess } from '../helpers/log-helper';
12+
import { error, success, underlineSuccess } from '../helpers/log-helper';
1513
import { svgOptimizer } from '../helpers/svg-optimization';
14+
import { SingleFileConvertionOptions } from '../options/convertion-options';
1615

1716
const typesDelimitor = ' | ';
1817

19-
export const convertToSingleFile = async (convertionOptions: ConvertionOptions): Promise<void> => {
18+
export const convertToSingleFile = async (convertionOptions: SingleFileConvertionOptions): Promise<void> => {
2019
const { typeName, prefix, delimiter, interfaceName, outputDirectory, srcFiles, fileName } = convertionOptions;
2120
let svgConstants = '';
2221
let types = generateTypeDefinition(typeName);
@@ -44,7 +43,7 @@ export const convertToSingleFile = async (convertionOptions: ConvertionOptions):
4443
await writeFile(outputDirectory, fileName, fileContent);
4544
success(`Icons file successfully generated under ${underlineSuccess(outputDirectory)}`);
4645
}
47-
} catch (error) {
48-
error('Something went wrong', error);
46+
} catch (exception) {
47+
error(`Something went wrong: ${exception}`);
4948
}
5049
};

src/lib/options/args-collector.ts

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import commander from 'commander';
2+
import { MultiFileConvertionOptions, SingleFileConvertionOptions } from './convertion-options';
3+
import { DEFAULT_OPTIONS } from './default-options';
4+
5+
export const collectArgumentOptions = (): SingleFileConvertionOptions | MultiFileConvertionOptions => {
6+
const {
7+
delimiter,
8+
fileName,
9+
interfaceName,
10+
outputDirectory,
11+
prefix,
12+
typeName,
13+
modelFileName,
14+
modelOutputPath,
15+
iconsFolderName,
16+
optimizeForLazyLoading
17+
} = commander;
18+
19+
// Because of commander adding default value to params
20+
// See: https://stackoverflow.com/questions/30238654/commander-js-collect-multiple-options-always-include-default
21+
let srcFiles = commander.srcFiles;
22+
if (srcFiles.length === 0) {
23+
srcFiles = DEFAULT_OPTIONS.srcFiles;
24+
}
25+
26+
return {
27+
delimiter,
28+
fileName,
29+
interfaceName,
30+
srcFiles,
31+
outputDirectory,
32+
prefix,
33+
typeName,
34+
modelFileName,
35+
modelOutputPath,
36+
iconsFolderName,
37+
optimizeForLazyLoading
38+
};
39+
};

src/lib/options/config-collector.ts

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { cosmiconfigSync } from 'cosmiconfig';
2+
3+
import * as packgeJSON from '../../../package.json';
4+
import { info } from '../helpers/log-helper';
5+
6+
import { MultiFileConvertionOptions, SingleFileConvertionOptions } from './convertion-options';
7+
import { DEFAULT_OPTIONS } from './default-options';
8+
9+
export const collectConfigurationOptions = (): SingleFileConvertionOptions | MultiFileConvertionOptions | null => {
10+
const explorerSync = cosmiconfigSync(packgeJSON.name);
11+
const cosmiConfigResult = explorerSync.search();
12+
cosmiConfigResult ? info(`Configuration found under: ${cosmiConfigResult.filepath}`) : info('No config found');
13+
return cosmiConfigResult ? mergeWithDefaults(cosmiConfigResult.config) : null;
14+
};
15+
16+
const mergeWithDefaults = (
17+
options: MultiFileConvertionOptions | SingleFileConvertionOptions
18+
): MultiFileConvertionOptions | SingleFileConvertionOptions => {
19+
const configOptions = { ...options };
20+
if (!configOptions.typeName) {
21+
configOptions.typeName = DEFAULT_OPTIONS.typeName;
22+
info(`No typeName provided, "${DEFAULT_OPTIONS.typeName}" will be used`);
23+
}
24+
25+
if (!configOptions.interfaceName) {
26+
configOptions.interfaceName = DEFAULT_OPTIONS.interfaceName;
27+
info(`No interfaceName provided, "${DEFAULT_OPTIONS.interfaceName}" will be used`);
28+
}
29+
30+
if (!configOptions.prefix) {
31+
configOptions.prefix = DEFAULT_OPTIONS.prefix;
32+
info(`No prefix provided, "${DEFAULT_OPTIONS.prefix}" will be used`);
33+
}
34+
35+
if (!configOptions.delimiter) {
36+
configOptions.delimiter = DEFAULT_OPTIONS.delimiter;
37+
info(`No delimiter provided, "${DEFAULT_OPTIONS.delimiter}" will be used`);
38+
}
39+
40+
if (!configOptions.outputDirectory) {
41+
configOptions.outputDirectory = DEFAULT_OPTIONS.outputDirectory;
42+
info(`No outputDirectory provided, "${DEFAULT_OPTIONS.outputDirectory}" will be used`);
43+
}
44+
45+
if (!configOptions.srcFiles) {
46+
configOptions.srcFiles = DEFAULT_OPTIONS.srcFiles;
47+
info(`No srcFiles provided, "${DEFAULT_OPTIONS.srcFiles}" will be used`);
48+
}
49+
50+
if (configOptions.optimizeForLazyLoading) {
51+
if (!(configOptions as MultiFileConvertionOptions).modelOutputPath) {
52+
(configOptions as MultiFileConvertionOptions).modelOutputPath = DEFAULT_OPTIONS.modelOutputPath;
53+
info(`No modelOutputPath provided, "${DEFAULT_OPTIONS.modelOutputPath}" will be used`);
54+
}
55+
56+
if (!(configOptions as MultiFileConvertionOptions).modelFileName) {
57+
(configOptions as MultiFileConvertionOptions).modelFileName = DEFAULT_OPTIONS.modelFileName;
58+
info(`No modelFileName provided, "${DEFAULT_OPTIONS.modelFileName}" will be used`);
59+
}
60+
61+
if (!(configOptions as MultiFileConvertionOptions).iconsFolderName) {
62+
(configOptions as MultiFileConvertionOptions).iconsFolderName = DEFAULT_OPTIONS.iconsFolderName;
63+
info(`No iconsFolderName provided, "${DEFAULT_OPTIONS.iconsFolderName}" will be used`);
64+
}
65+
66+
return configOptions as MultiFileConvertionOptions;
67+
} else {
68+
if (!(configOptions as SingleFileConvertionOptions).fileName) {
69+
(configOptions as SingleFileConvertionOptions).fileName = DEFAULT_OPTIONS.modelFileName;
70+
info(`No fileName provided, "${DEFAULT_OPTIONS.modelFileName}" will be used`);
71+
}
72+
return configOptions as SingleFileConvertionOptions;
73+
}
74+
};

0 commit comments

Comments
 (0)