Skip to content

Commit

Permalink
feat((tsx)): add tsx constants conversion
Browse files Browse the repository at this point in the history
Add the functionality to generate TSX SVG constants

#159
  • Loading branch information
nivekcode committed Apr 24, 2022
1 parent 76729aa commit 5baac39
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 41 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"start-object:generateType": "ts-node ./src/bin/svg-to-ts-object -s './inputfiles/*.svg' -o ./dist --objectName awesomeIcons --typeName MyIconType",
"start-object:export-const": "ts-node ./src/bin/svg-to-ts-object.ts -s './inputfiles/*.svg' -o ./dist --objectName myIcons",
"start-constants": "ts-node ./src/bin/svg-to-ts-constants.ts -s './inputfiles/*.svg'",
"start-constants:tsx": "ts-node ./src/bin/svg-to-ts-constants.ts -s './inputfiles/*.svg' --tsx true",
"start-constants:help": "ts-node ./src/bin/svg-to-ts-constants.ts --help'",
"start-constants:regex": "ts-node ./src/bin/svg-to-ts-constants.ts -s './inputfilesRegex/**/*.svg'",
"start-constants:kebab": "ts-node ./src/bin/svg-to-ts-constants.ts -s './inputfiles/*.svg' -d KEBAB",
Expand Down
109 changes: 77 additions & 32 deletions src/lib/converters/constants.converter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
generateInterfaceDefinition,
generateSvgConstant,
generateTSXConstant,
generateTypeDefinition,
generateTypeHelper
} from '../generators/code-snippet-generators';
Expand All @@ -9,49 +10,93 @@ import { writeFile } from '../helpers/file-helpers';
import { Logger } from '../helpers/logger';
import { callAndMonitor, callAndMonitorAsync } from '../helpers/monitor';
import { ConstantsConversionOptions } from '../options/conversion-options/constant-conversion-options';
import { FILE_TYPE } from '../shared/file-type.model';

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

const getSvgConstants = (svgDefinitions): string => {
const svgConstants = svgDefinitions.map(svgDefinition =>
generateSvgConstant(svgDefinition.variableName, svgDefinition.typeName, svgDefinition.data)
export async function convertToConstants(conversionOptions: ConstantsConversionOptions): Promise<void> {
const { tsx } = conversionOptions;

const svgDefinitions = await callAndMonitorAsync<SvgDefinition[]>(
filesProcessor.bind({}, conversionOptions),
'Processing SVG files'
);
return svgConstants.join('');
};

export const convertToConstants = async (conversionOptions: ConstantsConversionOptions): Promise<void> => {
if (!svgDefinitions.length) {
Logger.error('No SVG files found under ${outputDirectory}');
return;
}

if (tsx) {
await convertToTSXConstants(conversionOptions, svgDefinitions);
} else {
await convertToTSConstants(conversionOptions, svgDefinitions);
}
}

async function convertToTSConstants(conversionOptions: ConstantsConversionOptions, svgDefinitions: SvgDefinition[]) {
const { outputDirectory, fileName, interfaceName, exportCompleteIconSet, completeIconSetName } = conversionOptions;
let exportAllStatement = '';

const svgDefinitions = await callAndMonitorAsync<SvgDefinition[]>(
filesProcessor.bind({}, conversionOptions),
'Processing SVG files'
const svgContants = callAndMonitor<string>(getTSConstants.bind({}, svgDefinitions), 'Generate SVG constants');

const typeDefinition = callAndMonitor<string>(
generateTypeDefinition.bind({}, conversionOptions, svgDefinitions),
'Generate type definitions'
);
const interfaceDefinition = callAndMonitor<string>(
generateInterfaceDefinition.bind({}, conversionOptions),
'Generate Interface Definition'
);

if (svgDefinitions.length) {
const svgContants = callAndMonitor<string>(getSvgConstants.bind({}, svgDefinitions), 'Generate SVG constants');
const typeDefinition = callAndMonitor<string>(
generateTypeDefinition.bind({}, conversionOptions, svgDefinitions),
'Generate type definitions'
);
const interfaceDefinition = callAndMonitor<string>(
generateInterfaceDefinition.bind({}, conversionOptions),
'Generate Interface Definition'
if (exportCompleteIconSet) {
exportAllStatement = callAndMonitor<string>(
generateExportSection.bind({}, svgDefinitions, completeIconSetName),
'Exporting all constants'
);
}

const typeHelper = callAndMonitor<string>(generateTypeHelper.bind({}, interfaceName), 'Generate Type Helper');
const fileContent = `${svgContants}${typeDefinition}${interfaceDefinition}${typeHelper}${exportAllStatement}`;
await callAndMonitorAsync<void>(
writeFile.bind({}, outputDirectory, fileName, fileContent),
`Writing files to ${outputDirectory}`
);
Logger.generationSuccess(outputDirectory);
}

async function convertToTSXConstants(conversionOptions: ConstantsConversionOptions, svgDefinitions: SvgDefinition[]) {
const { exportCompleteIconSet, completeIconSetName, outputDirectory, fileName } = conversionOptions;

if (exportCompleteIconSet) {
exportAllStatement = callAndMonitor<string>(
generateExportSection.bind({}, svgDefinitions, completeIconSetName),
'Exporting all constants'
);
}

const typeHelper = callAndMonitor<string>(generateTypeHelper.bind({}, interfaceName), 'Generate Type Helper');
const fileContent = `${svgContants}${typeDefinition}${interfaceDefinition}${typeHelper}${exportAllStatement}`;
await callAndMonitorAsync<void>(
writeFile.bind({}, outputDirectory, fileName, fileContent),
`Writing files to ${outputDirectory}`
const tsxContants = callAndMonitor<string>(getTSXConstants.bind({}, svgDefinitions), 'Generate TSX constants');
let exportAllStatement = '';

if (exportCompleteIconSet) {
exportAllStatement = callAndMonitor<string>(
generateExportSection.bind({}, svgDefinitions, completeIconSetName, FILE_TYPE.TSX),
'Exporting all TSX constants as ${completeIconSetName}'
);
Logger.generationSuccess(outputDirectory);
}
};

const fileContent = `${tsxContants}${exportAllStatement}`;

await callAndMonitorAsync<void>(
writeFile.bind({}, outputDirectory, fileName, fileContent, FILE_TYPE.TSX),
`Writing files to ${outputDirectory}`
);
Logger.generationSuccess(outputDirectory);
}

function getTSConstants(svgDefinitions): string {
const svgConstants = svgDefinitions.map(svgDefinition =>
generateSvgConstant(svgDefinition.variableName, svgDefinition.typeName, svgDefinition.data)
);
return svgConstants.join('');
}

function getTSXConstants(svgDefinitions): string {
const tsxConstants = svgDefinitions.map(svgDefinition =>
generateTSXConstant(svgDefinition.variableName, svgDefinition.data)
);
return tsxConstants.join('');
}
3 changes: 2 additions & 1 deletion src/lib/converters/object.converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { writeFile } from '../helpers/file-helpers';
import { Logger } from '../helpers/logger';
import { callAndMonitor, callAndMonitorAsync } from '../helpers/monitor';
import { ObjectConversionOptions } from '../options/conversion-options/object-conversion-options';
import { FILE_TYPE } from '../shared/file-type.model';

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

Expand All @@ -29,7 +30,7 @@ async function generateTSXFile(svgDefinitions: SvgDefinition[], conversionOption
);

await callAndMonitorAsync<void>(
writeFile.bind({}, outputDirectory, fileName, `${fileContent}`, 'tsx'),
writeFile.bind({}, outputDirectory, fileName, `${fileContent}`, FILE_TYPE.TSX),
'Write content to file'
);
Logger.generationSuccess(outputDirectory);
Expand Down
5 changes: 5 additions & 0 deletions src/lib/generators/code-snippet-generators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ export const generateSvgConstant = (variableName: string, filenameWithoutEnding:
};`;
};

export function generateTSXConstant(variableName: string, svg: string) {
const variableNameCapitalized = variableName.charAt(0).toUpperCase() + variableName.slice(1);
return `export const ${variableNameCapitalized} = () => (${svg});`;
}

export const generateExportStatement = (fileName: string, generatedIconsFolderName?: string): string => {
if (generatedIconsFolderName) {
return `export * from './${generatedIconsFolderName}/${fileName}';`;
Expand Down
16 changes: 13 additions & 3 deletions src/lib/helpers/complete-icon-set.helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import camelCase from 'lodash.camelcase';

import { SvgDefinition } from '../converters/shared.converter';
import { generateNamedImportStatement } from '../generators/code-snippet-generators';
import { FILE_TYPE } from '../shared/file-type.model';

export const generateCompleteIconSetContent = (
svgDefinitions: SvgDefinition[],
Expand All @@ -21,12 +22,21 @@ const generateImportSection = (svgDefinitions: SvgDefinition[]): string =>
return acc;
}, '');

export const generateExportSection = (svgDefinitions: SvgDefinition[], completeIconSetName: string): string =>
export const generateExportSection = (
svgDefinitions: SvgDefinition[],
completeIconSetName: string,
fileType = FILE_TYPE.TS
): string =>
svgDefinitions.reduce((acc: string, svgDefinition: SvgDefinition, index: number) => {
const variableName =
fileType === FILE_TYPE.TSX
? svgDefinition.variableName.charAt(0).toUpperCase() + svgDefinition.variableName.slice(1)
: svgDefinition.variableName;

if (index === svgDefinitions.length - 1) {
acc += `${svgDefinition.variableName}];`;
acc += `${variableName}];`;
} else {
acc += `${svgDefinition.variableName},`;
acc += `${variableName},`;
}
return acc;
}, `export const ${camelCase(completeIconSetName)} = [`);
7 changes: 2 additions & 5 deletions src/lib/helpers/file-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,15 @@ import typescriptParser from 'prettier/parser-typescript';
import prettier from 'prettier/standalone';
import util from 'util';

import { FILE_TYPE } from '../shared/file-type.model';

gfs.gracefulify(fs);

const readfileFromFS = util.promisify(fs.readFile);
const writeFileToFS = util.promisify(fs.writeFile);

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

export enum FILE_TYPE {
TS = 'ts',
TSX = 'tsx'
}

export const extractSvgContent = async (filePath: string): Promise<string> => {
const fileContentRaw = await readfileFromFS(filePath, 'utf-8');
return fileContentRaw.replace(/\r?\n|\r/g, ' ');
Expand Down
4 changes: 4 additions & 0 deletions src/lib/shared/file-type.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum FILE_TYPE {
TS = 'ts',
TSX = 'tsx'
}

0 comments on commit 5baac39

Please sign in to comment.