-
-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16 from kreuzerk/feature/restructuring
chore(structure): restructure library
- Loading branch information
Showing
7 changed files
with
143 additions
and
120 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,124 +1,53 @@ | ||
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<void> => { | ||
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('.'); | ||
|
||
if (extension === 'svg') { | ||
const rawSvg = await extractSvgContent(filePaths[i]); | ||
const optimizedSvg = await svgo.optimize(rawSvg); | ||
const variableName = getVariableName(convertionOptions, filenameWithoutEnding); | ||
const typeName = getTypeName(filenameWithoutEnding, convertionOptions.delimiter); | ||
types += `'${typeName}'${typesDelimitor}`; | ||
svgConstants += getSvgConstant(variableName, convertionOptions.interfaceName, typeName, optimizedSvg.data); | ||
const variableName = generateVariableName(prefix, filenameWithoutEnding); | ||
const typeName = generateTypeName(filenameWithoutEnding, delimiter); | ||
const svgConstant = generateSvgConstant(variableName, interfaceName, typeName, optimizedSvg.data); | ||
|
||
svgConstants += svgConstant; | ||
types += i === filePaths.length - 1 ? `'${typeName}';` : `'${typeName}'${typesDelimitor}`; | ||
} | ||
} | ||
|
||
if (svgConstants !== '') { | ||
types = types.substring(0, types.length - typesDelimitor.length) + ';'; | ||
const fileContent = generateFileContent(svgConstants, types, convertionOptions); | ||
const fileContent = (svgConstants += types += generateInterfaceDefinition(interfaceName, typeName)); | ||
await writeIconsFile(convertionOptions, fileContent); | ||
console.log( | ||
chalk.blue.bold('svg-to-ts:'), | ||
chalk.green('Icons file successfully generated under'), | ||
chalk.green.underline(convertionOptions.outputDirectory) | ||
chalk.green.underline(outputDirectory) | ||
); | ||
} | ||
} catch (error) { | ||
console.log(chalk.blue.bold('svg-to-ts:'), chalk.red('Something went wrong', error)); | ||
} | ||
}; | ||
|
||
const getTypeName = (filenameWithoutEnding, delimiter: Delimiter): string => { | ||
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<void> => { | ||
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<string> => { | ||
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); | ||
}; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<string> => { | ||
const fileContentRaw = await readfile(filePath, 'utf-8'); | ||
return fileContentRaw.replace(/\r?\n|\r/g, ' '); | ||
}; | ||
|
||
export const writeIconsFile = async (convertionOptions: ConvertionOptions, fileContent: string): Promise<void> => { | ||
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 | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
}; |