Skip to content

Commit 76729aa

Browse files
committed
feat((tsx) add tsx option and add object converter): accepts a TSX flag for object conversion
TSX flag is accepted for all conversion types. At this point only object conversion uses the TSX flag. Other converters will follow #159
1 parent 44f4305 commit 76729aa

20 files changed

+106
-23
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,6 @@ typings/
6262
# next.js build output
6363
.next
6464
.idea
65+
.vscode
6566
dist
6667
additional

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"format:write": "prettier --write 'src/**/*.ts' && import-conductor -s 'src/**/*.ts' -i './src/bin/*.ts'",
1515
"prebuild": "npm run copy:readme",
1616
"start-object": "ts-node ./src/bin/svg-to-ts-object.ts -s './inputfiles/*.svg'",
17+
"start-object:tsx": "ts-node ./src/bin/svg-to-ts-object.ts -s './inputfiles/*.svg' --tsx true",
1718
"start-object:help": "ts-node ./src/bin/svg-to-ts-object.ts --help",
1819
"start-object:regex": "ts-node ./src/bin/svg-to-ts-object.ts -s 'inputfiles/*.svg'",
1920
"start-object:kebab": "ts-node ./src/bin/svg-to-ts-object.ts -s 'inputfiles/*.svg' -d KEBAB",

src/lib/converters/object.converter.ts

+56-18
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,43 @@ import { ObjectConversionOptions } from '../options/conversion-options/object-co
66

77
import { filesProcessor, SvgDefinition } from './shared.converter';
88

9-
const generateSVGObject = async (
10-
svgDefinitions: SvgDefinition[],
11-
objectName: string,
12-
conversionOptions: ObjectConversionOptions
13-
): Promise<string> => {
14-
const svgObject = {};
15-
svgDefinitions.forEach((svgDefinition: SvgDefinition) => (svgObject[svgDefinition.typeName] = svgDefinition.data));
16-
const typePatch = generateObjectInterface(!objectName, conversionOptions);
17-
18-
return !objectName
19-
? `export default ${JSON.stringify(svgObject)}${typePatch}`
20-
: `export const ${objectName}${typePatch} = ${JSON.stringify(svgObject)}`;
21-
};
22-
23-
export const convertToSingleObject = async (conversionOptions: ObjectConversionOptions): Promise<void> => {
24-
const { outputDirectory, fileName, objectName } = conversionOptions;
9+
export async function convertToSingleObject(conversionOptions: ObjectConversionOptions): Promise<void> {
10+
const { tsx } = conversionOptions;
2511
const svgDefinitions = await callAndMonitorAsync<SvgDefinition[]>(
2612
filesProcessor.bind({}, conversionOptions),
2713
'Processing SVG files'
2814
);
15+
16+
if (tsx) {
17+
await generateTSXFile(svgDefinitions, conversionOptions);
18+
} else {
19+
await generateTSFile(svgDefinitions, conversionOptions);
20+
}
21+
}
22+
23+
async function generateTSXFile(svgDefinitions: SvgDefinition[], conversionOptions: ObjectConversionOptions) {
24+
const { outputDirectory, fileName, objectName } = conversionOptions;
25+
2926
const fileContent = await callAndMonitorAsync<string>(
30-
generateSVGObject.bind({}, svgDefinitions, objectName, conversionOptions),
27+
generateTSXObject.bind({}, svgDefinitions, objectName, conversionOptions),
28+
'Generate TSX Object'
29+
);
30+
31+
await callAndMonitorAsync<void>(
32+
writeFile.bind({}, outputDirectory, fileName, `${fileContent}`, 'tsx'),
33+
'Write content to file'
34+
);
35+
Logger.generationSuccess(outputDirectory);
36+
}
37+
38+
async function generateTSFile(svgDefinitions: SvgDefinition[], conversionOptions: ObjectConversionOptions) {
39+
const { outputDirectory, objectName, fileName } = conversionOptions;
40+
41+
const fileContent = await callAndMonitorAsync<string>(
42+
generateTSObject.bind({}, svgDefinitions, objectName, conversionOptions),
3143
'Generate SVG Object'
3244
);
45+
3346
const typeDefinition = callAndMonitor<string>(
3447
generateTypeDefinition.bind({}, conversionOptions, svgDefinitions),
3548
'Generate type definitions'
@@ -40,4 +53,29 @@ export const convertToSingleObject = async (conversionOptions: ObjectConversionO
4053
'Write content to file'
4154
);
4255
Logger.generationSuccess(outputDirectory);
43-
};
56+
}
57+
58+
async function generateTSObject(
59+
svgDefinitions: SvgDefinition[],
60+
objectName: string,
61+
conversionOptions: ObjectConversionOptions
62+
): Promise<string> {
63+
const svgObject = {};
64+
svgDefinitions.forEach((svgDefinition: SvgDefinition) => (svgObject[svgDefinition.typeName] = svgDefinition.data));
65+
const typePatch = generateObjectInterface(!objectName, conversionOptions);
66+
67+
return !objectName
68+
? `export default ${JSON.stringify(svgObject)}${typePatch}`
69+
: `export const ${objectName}${typePatch} = ${JSON.stringify(svgObject)}`;
70+
}
71+
72+
async function generateTSXObject(svgDefinitions: SvgDefinition[], conversionOptions: ObjectConversionOptions) {
73+
const { objectName } = conversionOptions;
74+
let svgObject = '';
75+
svgDefinitions.forEach((svgDefinition: SvgDefinition) => {
76+
const capitalizedTypeName = svgDefinition.typeName.charAt(0).toUpperCase() + svgDefinition.typeName.slice(1);
77+
svgObject += `${capitalizedTypeName}: () => (${svgDefinition.data}),\n`;
78+
});
79+
80+
return !objectName ? `export default {${svgObject}}` : `export const ${objectName} = ${svgObject.toString()}`;
81+
}

src/lib/converters/shared.converter.ts

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export const filesProcessor = async (conversionOptions): Promise<SvgDefinition[]
3737
const variableName = generateVariableName(prefix, filenameWithoutEnding);
3838

3939
const typeName = generateTypeName(filenameWithoutEnding, delimiter);
40+
4041
svgDefinition = {
4142
typeName,
4243
prefix,

src/lib/helpers/file-helpers.ts

+15-4
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,29 @@ const writeFileToFS = util.promisify(fs.writeFile);
1212

1313
const fileComment = '/* 🤖 this file was generated by svg-to-ts */\n';
1414

15+
export enum FILE_TYPE {
16+
TS = 'ts',
17+
TSX = 'tsx'
18+
}
19+
1520
export const extractSvgContent = async (filePath: string): Promise<string> => {
1621
const fileContentRaw = await readfileFromFS(filePath, 'utf-8');
1722
return fileContentRaw.replace(/\r?\n|\r/g, ' ');
1823
};
1924

20-
export const writeFile = async (outputDirectory: string, fileName: string, fileContent: string): Promise<void> => {
21-
const formattedFileContent = formatContent(`${fileComment}${fileContent}`);
25+
export async function writeFile(
26+
outputDirectory: string,
27+
fileName: string,
28+
fileContent: string,
29+
fileType = FILE_TYPE.TS
30+
): Promise<void> {
31+
const formattedFileContent =
32+
fileType === FILE_TYPE.TS ? formatContent(`${fileComment}${fileContent}`) : `${fileComment}${fileContent}`;
2233
if (!fs.existsSync(outputDirectory)) {
2334
fs.mkdirSync(outputDirectory, { recursive: true });
2435
}
25-
await writeFileToFS(path.join(outputDirectory, `${fileName}.ts`), formattedFileContent);
26-
};
36+
await writeFileToFS(path.join(outputDirectory, `${fileName}.${fileType}`), formattedFileContent);
37+
}
2738

2839
export const readFile = async (filePath: string): Promise<string> => {
2940
return readfileFromFS(filePath, 'utf-8');

src/lib/options/commander/constant-options.commander.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const setupConstantOptionsCommander = () => {
99
commander
1010
.version(packgeJSON.version)
1111
.option('--config <string>', 'path to the configuration file')
12+
.option('--tsx <boolean>', 'generate tsx files', false)
1213
.option(
1314
'-t --typeName <string>',
1415
'name of the generated enumeration type',

src/lib/options/commander/file-options.commander.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const setupFilesOptionsCommander = () => {
99
commander
1010
.version(packgeJSON.version)
1111
.option('--config <string>', 'path to the configuration file')
12+
.option('--tsx <boolean>', 'generate tsx files', false)
1213
.option(
1314
'-t --typeName <string>',
1415
'name of the generated enumeration type',

src/lib/options/commander/object-options.commander.ts

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const setupObjectOptionsCommander = () => {
99
commander
1010
.version(packgeJSON.version)
1111
.option('--config <string>', 'path to the configuration file')
12+
.option('--tsx <boolean>', 'generate tsx files', false)
1213
.option(
1314
'-d --delimiter <Delimiter>',
1415
`delimiter which is used to generate the types and name properties (${Object.values(Delimiter).join(',')})`,

src/lib/options/conversion-options/constant-conversion-options.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Delimiter } from '../../generators/code-snippet-generators';
22

33
export interface ConstantsConversionOptions {
4+
tsx: boolean;
45
config?: string;
56
srcFiles?: string[];
67
outputDirectory?: string;

src/lib/options/conversion-options/files-conversion-options.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Delimiter } from '../../generators/code-snippet-generators';
22

33
export interface FilesConversionOptions {
4+
tsx: boolean;
45
config?: string;
56
srcFiles?: string[];
67
outputDirectory?: string;

src/lib/options/conversion-options/object-conversion-options.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Delimiter } from '../../generators/code-snippet-generators';
22

33
export interface ObjectConversionOptions {
4+
tsx: boolean;
45
config?: string;
56
srcFiles?: string[];
67
outputDirectory?: string;

src/lib/options/default-options/default-constants-conversion-options.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Delimiter } from '../../generators/code-snippet-generators';
22
import { ConstantsConversionOptions } from '../conversion-options/constant-conversion-options';
33

44
export const DEFAULT_CONST_CONVERSION_OPTIONS: ConstantsConversionOptions = {
5+
tsx: false,
56
fileName: 'my-icons',
67
outputDirectory: './dist',
78
prefix: 'myIcon',

src/lib/options/default-options/default-files-conversion-options.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Delimiter } from '../../generators/code-snippet-generators';
22
import { FilesConversionOptions } from '../conversion-options/files-conversion-options';
33

44
export const DEFAULT_FILES_CONVERSION_OPTIONS: FilesConversionOptions = {
5+
tsx: false,
56
interfaceName: 'MyIcon',
67
outputDirectory: './dist',
78
prefix: 'myIcon',

src/lib/options/default-options/default-object-conversion-options.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Delimiter } from '../../generators/code-snippet-generators';
22
import { ObjectConversionOptions } from '../conversion-options/object-conversion-options';
33

44
export const DEFAULT_OBJECT_CONVERSION_OPTIONS: ObjectConversionOptions = {
5+
tsx: false,
56
srcFiles: ['*.svg'],
67
outputDirectory: './dist',
78
delimiter: Delimiter.CAMEL,

src/lib/options/options-collector/command-line-options-collectors/commandline-consts-options.collector.ts

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { toBoolean } from './command-line-collector.helpers';
88

99
export const collectCommandLineConstantOptions = async (): Promise<ConstantsConversionOptions> => {
1010
let {
11+
tsx,
1112
delimiter,
1213
fileName,
1314
interfaceName,
@@ -23,6 +24,7 @@ export const collectCommandLineConstantOptions = async (): Promise<ConstantsConv
2324
verbose
2425
} = commander;
2526
let svgoConfig = commander.svgoConfig;
27+
tsx = toBoolean(tsx, DEFAULT_CONST_CONVERSION_OPTIONS.tsx);
2628
generateType = toBoolean(generateType, DEFAULT_CONST_CONVERSION_OPTIONS.generateType);
2729
generateTypeObject = toBoolean(generateTypeObject, DEFAULT_CONST_CONVERSION_OPTIONS.generateTypeObject);
2830
generateEnum = toBoolean(generateEnum, DEFAULT_CONST_CONVERSION_OPTIONS.generateTypeObject);
@@ -38,6 +40,7 @@ export const collectCommandLineConstantOptions = async (): Promise<ConstantsConv
3840
svgoConfig = await getSvgoConfig(svgoConfig);
3941

4042
return {
43+
tsx,
4144
delimiter,
4245
fileName,
4346
enumName,

src/lib/options/options-collector/command-line-options-collectors/commandline-files-options.collector.ts

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { toBoolean } from './command-line-collector.helpers';
88

99
export const collectCommandLineFileOptions = async (): Promise<FilesConversionOptions> => {
1010
let {
11+
tsx,
1112
delimiter,
1213
barrelFileName,
1314
interfaceName,
@@ -29,6 +30,7 @@ export const collectCommandLineFileOptions = async (): Promise<FilesConversionOp
2930
let svgoConfig = commander.svgoConfig;
3031

3132
// Parse boolean values
33+
tsx = toBoolean(tsx, DEFAULT_FILES_CONVERSION_OPTIONS.tsx);
3234
generateType = toBoolean(generateType, DEFAULT_FILES_CONVERSION_OPTIONS.generateType);
3335
generateTypeObject = toBoolean(generateTypeObject, DEFAULT_FILES_CONVERSION_OPTIONS.generateTypeObject);
3436
exportCompleteIconSet = toBoolean(exportCompleteIconSet, DEFAULT_FILES_CONVERSION_OPTIONS.exportCompleteIconSet);
@@ -44,6 +46,7 @@ export const collectCommandLineFileOptions = async (): Promise<FilesConversionOp
4446
svgoConfig = await getSvgoConfig(svgoConfig);
4547

4648
return {
49+
tsx,
4750
delimiter,
4851
interfaceName,
4952
srcFiles,

src/lib/options/options-collector/command-line-options-collectors/commandline-object-options.collector.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { DEFAULT_OBJECT_CONVERSION_OPTIONS } from '../../default-options/default
77
import { toBoolean } from './command-line-collector.helpers';
88

99
export const collectCommandLineObjectOptions = async (): Promise<ObjectConversionOptions> => {
10-
let { objectName, delimiter, fileName, outputDirectory, verbose, generateType, typeName } = commander;
10+
let { tsx, objectName, delimiter, fileName, outputDirectory, verbose, generateType, typeName } = commander;
1111
let svgoConfig = commander.svgoConfig;
1212

1313
generateType = toBoolean(generateType, DEFAULT_OBJECT_CONVERSION_OPTIONS.generateType);
@@ -22,6 +22,7 @@ export const collectCommandLineObjectOptions = async (): Promise<ObjectConversio
2222
svgoConfig = await getSvgoConfig(svgoConfig);
2323

2424
return {
25+
tsx,
2526
delimiter,
2627
srcFiles,
2728
outputDirectory,

src/lib/options/options-collector/config-file-options-collector/config-file-constants-options.collector.ts

+5
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ export const mergeWithDefaultConstantOptions = async (
3636
): Promise<ConstantsConversionOptions> => {
3737
const configOptions = { ...options };
3838

39+
if (configOptions.tsx === undefined) {
40+
configOptions.tsx = DEFAULT_CONST_CONVERSION_OPTIONS.tsx;
41+
Logger.verboseInfo(`No 'tsx' property provided, "${DEFAULT_CONST_CONVERSION_OPTIONS.tsx}" will be used`);
42+
}
43+
3944
if (configOptions.verbose === undefined) {
4045
configOptions.verbose = DEFAULT_CONST_CONVERSION_OPTIONS.verbose;
4146
Logger.verboseInfo(`No 'verbose' property provided, "${DEFAULT_CONST_CONVERSION_OPTIONS.verbose}" will be used`);

src/lib/options/options-collector/config-file-options-collector/config-file-files-options.collector.ts

+5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ export const collectConfigFileFileOptions = async (): Promise<
2929
export const mergeWithDefaults = async (options): Promise<FilesConversionOptions> => {
3030
const configOptions = { ...options };
3131

32+
if (configOptions.tsx === undefined) {
33+
configOptions.tsx = DEFAULT_FILES_CONVERSION_OPTIONS.tsx;
34+
Logger.verboseInfo(`No 'tsx' property provided, "${DEFAULT_FILES_CONVERSION_OPTIONS.tsx}" will be used`);
35+
}
36+
3237
if (configOptions.verbose === undefined) {
3338
configOptions.verbose = DEFAULT_FILES_CONVERSION_OPTIONS.verbose;
3439
Logger.verboseInfo(`No "verbose" property provided, "${DEFAULT_FILES_CONVERSION_OPTIONS.verbose}" will be used`);

src/lib/options/options-collector/config-file-options-collector/config-file-object-options.collector.ts

+5
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ export const collectConfigFileObjectOptions = async (): Promise<
2929
export const mergeWithDefaults = async (options: ObjectConversionOptions): Promise<ObjectConversionOptions> => {
3030
const configOptions = { ...options };
3131

32+
if (configOptions.tsx === undefined) {
33+
configOptions.tsx = DEFAULT_OBJECT_CONVERSION_OPTIONS.tsx;
34+
Logger.verboseInfo(`No 'tsx' property provided, "${DEFAULT_OBJECT_CONVERSION_OPTIONS.tsx}" will be used`);
35+
}
36+
3237
if (configOptions.verbose === undefined) {
3338
configOptions.verbose = DEFAULT_OBJECT_CONVERSION_OPTIONS.verbose;
3439
Logger.verboseInfo(`No 'verbose' property provided, "${DEFAULT_OBJECT_CONVERSION_OPTIONS.verbose}" will be used`);

0 commit comments

Comments
 (0)