From 86f5944704b438c8df76e0981832b6b3fbdff650 Mon Sep 17 00:00:00 2001 From: kreuzerk Date: Tue, 3 Mar 2020 15:50:41 +0100 Subject: [PATCH] chore(structure): restructure library --- src/bin/svg-to-ts.ts | 13 +- src/lib/convert.ts | 115 ++++-------------- src/lib/definitions.ts | 21 ---- src/lib/file-helpers.ts | 33 +++++ .../generators.spec.ts} | 10 +- src/lib/generators/generators.ts | 49 ++++++++ src/lib/regex-helpers.ts | 22 ++++ 7 files changed, 143 insertions(+), 120 deletions(-) delete mode 100644 src/lib/definitions.ts create mode 100644 src/lib/file-helpers.ts rename src/lib/{definitions.spec.ts => generators/generators.spec.ts} (66%) create mode 100644 src/lib/generators/generators.ts create mode 100644 src/lib/regex-helpers.ts diff --git a/src/bin/svg-to-ts.ts b/src/bin/svg-to-ts.ts index c31e70e..0f72abc 100755 --- a/src/bin/svg-to-ts.ts +++ b/src/bin/svg-to-ts.ts @@ -1,7 +1,18 @@ #!/usr/bin/env node import * as packgeJSON from '../../package.json'; import commander from 'commander'; -import { convert, Delimiter } from '../lib/convert'; +import { convert } from '../lib/convert'; +import { Delimiter } from '../lib/generators/generators'; + +export interface ConvertionOptions { + delimiter: Delimiter; + typeName: string; + prefix: string; + fileName: string; + interfaceName: string; + srcFiles: string[]; + outputDirectory: string; +} const DEFAULTS = { fileName: 'my-icons', diff --git a/src/lib/convert.ts b/src/lib/convert.ts index cb87eab..f7f5f48 100644 --- a/src/lib/convert.ts +++ b/src/lib/convert.ts @@ -1,57 +1,27 @@ -import snakeCase from 'lodash.snakecase'; -import camelCase from 'lodash.camelcase'; -import kebapCase from 'lodash.kebabcase'; -import * as prettier from 'prettier/standalone'; import chalk from 'chalk'; -import typescriptParser from 'prettier/parser-typescript'; -import { Glob } from 'glob'; -import * as util from 'util'; import * as path from 'path'; -import * as fs from 'fs'; - import { svgo } from './svgo'; -import { getInterfaceDefinition, getSvgConstant, getTypeDefinition } from './definitions'; - -const readfile = util.promisify(fs.readFile); -const writeFile = util.promisify(fs.writeFile); -const getFilesFromRegex = util.promisify(Glob); -export interface ConvertionOptions { - delimiter: Delimiter; - typeName: string; - prefix: string; - fileName: string; - interfaceName: string; - srcFiles: string[]; - outputDirectory: string; -} +import { + generateInterfaceDefinition, + generateSvgConstant, + generateTypeDefinition, + generateTypeName, + generateVariableName +} from './generators/generators'; +import { getFilePathsFromRegex } from './regex-helpers'; +import { extractSvgContent, writeIconsFile } from './file-helpers'; +import { ConvertionOptions } from '../bin/svg-to-ts'; -export enum Delimiter { - CAMEL = 'CAMEL', - KEBAB = 'KEBAB', - SNAKE = 'SNAKE' -} +const typesDelimitor = ' | '; export const convert = async (convertionOptions: ConvertionOptions): Promise => { + const { typeName, prefix, delimiter, interfaceName, outputDirectory, srcFiles } = convertionOptions; let svgConstants = ''; - let types = getTypeDefinition(convertionOptions.typeName); + let types = generateTypeDefinition(typeName); try { - const typesDelimitor = ' | '; - const srcFilesRegexExpressions = convertionOptions.srcFiles; - const filePaths: string[] = []; - - for (const regex of srcFilesRegexExpressions) { - const directoryFiles = await getFilesFromRegex(regex, { - nodir: true - }); - if (directoryFiles.length === 0) { - console.log(chalk.blue.bold('svg-to-ts:'), chalk.yellow(`No matching files for regex: "${regex}"`)); - } else { - filePaths.push(...directoryFiles); - } - } - + const filePaths = await getFilePathsFromRegex(srcFiles); for (let i = 0; i < filePaths.length; i++) { const fileNameWithEnding = path.basename(filePaths[i]); const [filenameWithoutEnding, extension] = fileNameWithEnding.split('.'); @@ -59,66 +29,25 @@ export const convert = async (convertionOptions: ConvertionOptions): Promise { - if (delimiter === Delimiter.CAMEL) { - return `${camelCase(filenameWithoutEnding)}`; - } - if (delimiter === Delimiter.KEBAB) { - return `${kebapCase(filenameWithoutEnding)}`; - } - return `${snakeCase(filenameWithoutEnding)}`; -}; - -const generateFileContent = (svgContstants: string, types: string, convertionOptions: ConvertionOptions): string => { - const fileContent = (svgContstants += types += getInterfaceDefinition( - convertionOptions.interfaceName, - convertionOptions.typeName - )); - return prettier.format(fileContent, { - parser: 'typescript', - plugins: [typescriptParser], - singleQuote: true - }); -}; - -const writeIconsFile = async (convertionOptions: ConvertionOptions, fileContent: string): Promise => { - if (!fs.existsSync(convertionOptions.outputDirectory)) { - fs.mkdirSync(convertionOptions.outputDirectory); - } - await writeFile(path.join(convertionOptions.outputDirectory, `${convertionOptions.fileName}.ts`), fileContent); -}; - -const getVariableName = (convertionOptions: ConvertionOptions, filenameWithoutEnding): string => { - return `${convertionOptions.prefix}${capitalize(camelCase(filenameWithoutEnding))}`; -}; - -const extractSvgContent = async (filePath: string): Promise => { - const fileContentRaw = await readfile(filePath, 'utf-8'); - return fileContentRaw.replace(/\r?\n|\r/g, ' '); -}; - -const capitalize = (value: string): string => { - return value.charAt(0).toUpperCase() + value.slice(1); -}; diff --git a/src/lib/definitions.ts b/src/lib/definitions.ts deleted file mode 100644 index 0e6b0f1..0000000 --- a/src/lib/definitions.ts +++ /dev/null @@ -1,21 +0,0 @@ -export const getInterfaceDefinition = (interfaceName: string, typeName: string) => { - return `export interface ${interfaceName}{ - name: ${typeName}; - data: string;}`; -}; - -export const getTypeDefinition = (typeName: string): string => { - return `export type ${typeName} = `; -}; - -export const getSvgConstant = ( - variableName: string, - interfaceName: string, - filenameWithoutEnding: string, - data: string -): string => { - return `export const ${variableName}: ${interfaceName} = { - name: '${filenameWithoutEnding}', - data: '${data}' - };`; -}; diff --git a/src/lib/file-helpers.ts b/src/lib/file-helpers.ts new file mode 100644 index 0000000..b2bf772 --- /dev/null +++ b/src/lib/file-helpers.ts @@ -0,0 +1,33 @@ +import * as util from 'util'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as prettier from 'prettier/standalone'; +import typescriptParser from 'prettier/parser-typescript'; + +import { ConvertionOptions } from '../bin/svg-to-ts'; + +const readfile = util.promisify(fs.readFile); +const writeFile = util.promisify(fs.writeFile); + +export const extractSvgContent = async (filePath: string): Promise => { + const fileContentRaw = await readfile(filePath, 'utf-8'); + return fileContentRaw.replace(/\r?\n|\r/g, ' '); +}; + +export const writeIconsFile = async (convertionOptions: ConvertionOptions, fileContent: string): Promise => { + const formatedFileContent = formatContent(fileContent); + if (!fs.existsSync(convertionOptions.outputDirectory)) { + fs.mkdirSync(convertionOptions.outputDirectory); + } + await writeFile( + path.join(convertionOptions.outputDirectory, `${convertionOptions.fileName}.ts`), + formatedFileContent + ); +}; + +const formatContent = (fileContent: string) => + prettier.format(fileContent, { + parser: 'typescript', + plugins: [typescriptParser], + singleQuote: true + }); diff --git a/src/lib/definitions.spec.ts b/src/lib/generators/generators.spec.ts similarity index 66% rename from src/lib/definitions.spec.ts rename to src/lib/generators/generators.spec.ts index 9cfceeb..ecdd789 100644 --- a/src/lib/definitions.spec.ts +++ b/src/lib/generators/generators.spec.ts @@ -1,19 +1,19 @@ -import { getInterfaceDefinition, getSvgConstant, getTypeDefinition } from './definitions'; +import { generateInterfaceDefinition, generateSvgConstant, generateTypeDefinition } from './generators'; -describe('Definitions', () => { +describe('Generators', () => { it('should return the correct interface definition', () => { const interfaceName = 'TestIcons'; const typeName = 'myAwesomeIcons'; const expectedDefinition = `export interface ${interfaceName}{ name: ${typeName}; data: string;}`; - expect(getInterfaceDefinition(interfaceName, typeName)).toEqual(expectedDefinition); + expect(generateInterfaceDefinition(interfaceName, typeName)).toEqual(expectedDefinition); }); it('should return the correct type definition', () => { const typeName = 'awesomeType'; const expectedTypeDefinition = `type ${typeName} = `; - expect(getTypeDefinition(typeName)).toEqual(expectedTypeDefinition); + expect(generateTypeDefinition(typeName)).toEqual(expectedTypeDefinition); }); it('should return the correct svg constant definition', () => { @@ -26,6 +26,6 @@ describe('Definitions', () => { name: '${filenameWithoutEnding}', data: '${data}' };`; - expect(getSvgConstant(variableName, interfaceName, filenameWithoutEnding, data)).toEqual(expectedSVGConstant); + expect(generateSvgConstant(variableName, interfaceName, filenameWithoutEnding, data)).toEqual(expectedSVGConstant); }); }); diff --git a/src/lib/generators/generators.ts b/src/lib/generators/generators.ts new file mode 100644 index 0000000..b71c8cf --- /dev/null +++ b/src/lib/generators/generators.ts @@ -0,0 +1,49 @@ +import snakeCase from 'lodash.snakecase'; +import camelCase from 'lodash.camelcase'; +import kebapCase from 'lodash.kebabcase'; + +export enum Delimiter { + CAMEL = 'CAMEL', + KEBAB = 'KEBAB', + SNAKE = 'SNAKE' +} + +export const generateInterfaceDefinition = (interfaceName: string, typeName: string) => { + return `export interface ${interfaceName}{ + name: ${typeName}; + data: string;}`; +}; + +export const generateTypeDefinition = (typeName: string): string => { + return `export type ${typeName} = `; +}; + +export const generateSvgConstant = ( + variableName: string, + interfaceName: string, + filenameWithoutEnding: string, + data: string +): string => { + return `export const ${variableName}: ${interfaceName} = { + name: '${filenameWithoutEnding}', + data: '${data}' + };`; +}; + +export const generateTypeName = (filenameWithoutEnding, delimiter: Delimiter): string => { + if (delimiter === Delimiter.CAMEL) { + return `${camelCase(filenameWithoutEnding)}`; + } + if (delimiter === Delimiter.KEBAB) { + return `${kebapCase(filenameWithoutEnding)}`; + } + return `${snakeCase(filenameWithoutEnding)}`; +}; + +export const generateVariableName = (prefix: string, filenameWithoutEnding): string => { + return `${prefix}${capitalize(camelCase(filenameWithoutEnding))}`; +}; + +const capitalize = (value: string): string => { + return value.charAt(0).toUpperCase() + value.slice(1); +}; diff --git a/src/lib/regex-helpers.ts b/src/lib/regex-helpers.ts new file mode 100644 index 0000000..d74f505 --- /dev/null +++ b/src/lib/regex-helpers.ts @@ -0,0 +1,22 @@ +import chalk from 'chalk'; +import * as util from 'util'; +import { Glob } from 'glob'; + +const getFilesFromRegex = util.promisify(Glob); + +export const getFilePathsFromRegex = async (srcFiles: string[]) => { + const srcFilesRegexExpressions = srcFiles; + const filePaths: string[] = []; + + for (const regex of srcFilesRegexExpressions) { + const directoryFiles = await getFilesFromRegex(regex, { + nodir: true + }); + if (directoryFiles.length === 0) { + console.log(chalk.blue.bold('svg-to-ts:'), chalk.yellow(`No matching files for regex: "${regex}"`)); + } else { + filePaths.push(...directoryFiles); + } + } + return filePaths; +};