From a911b7cfe78e58afeb0ca3db6cb0cf2f046f9c9a Mon Sep 17 00:00:00 2001 From: kreuzerk Date: Wed, 4 Mar 2020 08:27:00 +0100 Subject: [PATCH] feat(compiler): compile ts files --- package-lock.json | 27 ++++++++----- src/lib/compiler/typescript-compiler.ts | 35 +++++++++++++++++ .../converters/multiple-files.converter.ts | 38 +++++++++---------- src/lib/generators/generators.ts | 23 +++++++++++ src/lib/{ => helpers}/file-helpers.ts | 18 +++++++-- src/lib/{ => helpers}/regex-helpers.ts | 0 6 files changed, 110 insertions(+), 31 deletions(-) create mode 100644 src/lib/compiler/typescript-compiler.ts rename src/lib/{ => helpers}/file-helpers.ts (67%) rename src/lib/{ => helpers}/regex-helpers.ts (100%) diff --git a/package-lock.json b/package-lock.json index 819ceb9..0c7d3a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "svg-to-ts", - "version": "2.2.0", + "version": "3.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -186,9 +186,9 @@ } }, "@babel/types": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", - "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.6.tgz", + "integrity": "sha512-wqz7pgWMIrht3gquyEFPVXeXCti72Rm8ep9b5tQKz9Yg9LzJA3HxosF1SB3Kc81KD1A3XBkkVYtJvCKS2Z/QrA==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -3495,12 +3495,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3521,7 +3523,8 @@ "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", @@ -3672,6 +3675,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3679,12 +3683,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3703,6 +3709,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3882,7 +3889,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3988,7 +3996,8 @@ "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/src/lib/compiler/typescript-compiler.ts b/src/lib/compiler/typescript-compiler.ts new file mode 100644 index 0000000..cf3680c --- /dev/null +++ b/src/lib/compiler/typescript-compiler.ts @@ -0,0 +1,35 @@ +import * as ts from 'typescript'; + +const compile = (filePaths: string[], compilerOptions: ts.CompilerOptions): void => { + let program = ts.createProgram(filePaths, compilerOptions); + let emitResult = program.emit(); + + reportDiagnostics(ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics)); + + let exitCode = emitResult.emitSkipped ? 1 : 0; + process.exit(exitCode); +}; + +function reportDiagnostics(diagnostics: ts.Diagnostic[]): void { + diagnostics.forEach(diagnostic => { + let message = 'Error'; + if (diagnostic.file) { + let { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); + message += ` ${diagnostic.file.fileName} (${line + 1},${character + 1})`; + } + message += ': ' + ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); + console.log(message); + }); +} + +export const compileSources = (filePaths: string[]): void => { + const tsOptions = { + noEmitOnError: true, + noImplicitAny: true, + declaration: true, + moduleResolution: ts.ModuleResolutionKind.NodeJs, + target: ts.ScriptTarget.ESNext, + module: ts.ModuleKind.ESNext + }; + compile(filePaths, tsOptions); +}; diff --git a/src/lib/converters/multiple-files.converter.ts b/src/lib/converters/multiple-files.converter.ts index 643aaca..c4861e0 100644 --- a/src/lib/converters/multiple-files.converter.ts +++ b/src/lib/converters/multiple-files.converter.ts @@ -7,21 +7,22 @@ import { generateSvgConstant, generateTypeDefinition, generateTypeName, + generateUntypedSvgConstant, generateVariableName } from '../generators/generators'; -import { getFilePathsFromRegex } from '../regex-helpers'; -import { extractSvgContent, writeIconsFile } from '../file-helpers'; +import { getFilePathsFromRegex } from '../helpers/regex-helpers'; +import { deleteFolder, extractSvgContent, writeIconsFile } from '../helpers/file-helpers'; import { ConvertionOptions } from '../../bin/svg-to-ts'; +import { compileSources } from '../compiler/typescript-compiler'; const typesDelimitor = ' | '; export const convertToMultipleFiles = async (convertionOptions: ConvertionOptions): Promise => { const { typeName, prefix, delimiter, interfaceName, outputDirectory, srcFiles, fileName } = convertionOptions; - let svgConstants = ''; - let types = generateTypeDefinition(typeName); try { const filePaths = await getFilePathsFromRegex(srcFiles); + await deleteFolder(`${outputDirectory}/icons`); for (let i = 0; i < filePaths.length; i++) { const fileNameWithEnding = path.basename(filePaths[i]); const [filenameWithoutEnding, extension] = fileNameWithEnding.split('.'); @@ -31,26 +32,25 @@ export const convertToMultipleFiles = async (convertionOptions: ConvertionOption const optimizedSvg = await svgo.optimize(rawSvg); const variableName = generateVariableName(prefix, filenameWithoutEnding); const typeName = generateTypeName(filenameWithoutEnding, delimiter); - const svgConstant = generateSvgConstant(variableName, interfaceName, typeName, optimizedSvg.data); + const svgConstant = generateUntypedSvgConstant(variableName, typeName, optimizedSvg.data); - await writeIconsFile(outputDirectory, `${prefix}-${filenameWithoutEnding}.icon`, svgConstant); - - svgConstants += svgConstant; - types += i === filePaths.length - 1 ? `'${typeName}';` : `'${typeName}'${typesDelimitor}`; + await writeIconsFile(`${outputDirectory}/icons`, `${prefix}-${filenameWithoutEnding}.icon`, svgConstant); } } + const outputFiles = await getFilePathsFromRegex([`${outputDirectory}/icons/*.ts`]); + compileSources(outputFiles); /* - if (svgConstants !== '') { - const fileContent = (svgConstants += types += generateInterfaceDefinition(interfaceName, typeName)); - await writeIconsFile(outputDirectory, fileName, fileContent); - console.log( - chalk.blue.bold('svg-to-ts:'), - chalk.green('Icons file successfully generated under'), - chalk.green.underline(outputDirectory) - ); - } - */ + if (svgConstants !== '') { + const fileContent = (svgConstants += types += generateInterfaceDefinition(interfaceName, typeName)); + await writeIconsFile(outputDirectory, fileName, fileContent); + console.log( + chalk.blue.bold('svg-to-ts:'), + chalk.green('Icons file successfully generated under'), + chalk.green.underline(outputDirectory) + ); + } + */ } catch (error) { console.log(chalk.blue.bold('svg-to-ts:'), chalk.red('Something went wrong', error)); } diff --git a/src/lib/generators/generators.ts b/src/lib/generators/generators.ts index b71c8cf..88a962c 100644 --- a/src/lib/generators/generators.ts +++ b/src/lib/generators/generators.ts @@ -30,6 +30,29 @@ export const generateSvgConstant = ( };`; }; +export const generateUntypedSvgConstant = ( + variableName: string, + filenameWithoutEnding: string, + data: string +): string => { + return `export const ${variableName} = { + name: '${filenameWithoutEnding}', + data: '${data}' + };`; +}; + +export const generateSvgStandaloneFile = ( + 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)}`; diff --git a/src/lib/file-helpers.ts b/src/lib/helpers/file-helpers.ts similarity index 67% rename from src/lib/file-helpers.ts rename to src/lib/helpers/file-helpers.ts index 48e477b..a9794bd 100644 --- a/src/lib/file-helpers.ts +++ b/src/lib/helpers/file-helpers.ts @@ -4,8 +4,6 @@ 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); @@ -17,11 +15,25 @@ export const extractSvgContent = async (filePath: string): Promise => { export const writeIconsFile = async (outputDirectory: string, fileName: string, fileContent: string): Promise => { const formatedFileContent = formatContent(fileContent); if (!fs.existsSync(outputDirectory)) { - fs.mkdirSync(outputDirectory); + fs.mkdirSync(outputDirectory, { recursive: true }); } await writeFile(path.join(outputDirectory, `${fileName}.ts`), formatedFileContent); }; +export const deleteFolder = async (directoryPath: string) => { + if (fs.existsSync(directoryPath)) { + fs.readdirSync(directoryPath).forEach((filePath: string) => { + const curPath = directoryPath + '/' + filePath; + if (fs.lstatSync(curPath).isDirectory()) { + deleteFolder(curPath); + } else { + fs.unlinkSync(curPath); + } + }); + fs.rmdirSync(directoryPath); + } +}; + const formatContent = (fileContent: string) => prettier.format(fileContent, { parser: 'typescript', diff --git a/src/lib/regex-helpers.ts b/src/lib/helpers/regex-helpers.ts similarity index 100% rename from src/lib/regex-helpers.ts rename to src/lib/helpers/regex-helpers.ts