From edbae3854d239ddc457a1d5d711c4011403c6784 Mon Sep 17 00:00:00 2001 From: Lars van Vianen Date: Wed, 3 Jan 2024 00:45:43 +0100 Subject: [PATCH] v0.0.8 --- VERSION | 2 +- dist/js/class/FontGenerator.d.ts | 4 + dist/js/class/FontGenerator.js | 92 +++++++ dist/js/class/JavaScriptMinifier.d.ts | 19 ++ dist/js/class/JavaScriptMinifier.js | 63 +++++ dist/js/class/PackageCreator.d.ts | 18 ++ dist/js/class/PackageCreator.js | 50 ++++ dist/js/class/StyleProcessor.d.ts | 24 ++ dist/js/class/StyleProcessor.js | 94 +++++++ dist/js/class/SvgPackager.d.ts | 56 +++++ dist/js/class/SvgPackager.js | 197 +++++++++++++++ dist/js/class/SvgSpriteGenerator.d.ts | 18 ++ dist/js/class/SvgSpriteGenerator.js | 74 ++++++ dist/js/class/TypeScriptCompiler.d.ts | 25 ++ dist/js/class/TypeScriptCompiler.js | 92 +++++++ dist/js/class/VersionWriter.d.ts | 12 + dist/js/class/VersionWriter.js | 43 ++++ dist/js/config/postcss.config.compressed.d.ts | 5 + dist/js/config/postcss.config.compressed.js | 37 +++ dist/js/config/postcss.config.expanded.d.ts | 5 + dist/js/config/postcss.config.expanded.js | 33 +++ dist/js/index.d.ts | 10 +- dist/js/index.js | 19 +- dist/js/interface/PackageJson.d.ts | 67 +++++ dist/js/interface/PackageJson.js | 5 + dist/package.json | 2 +- dist/ts/class/FontGenerator.ts | 136 +++++++++++ dist/ts/class/JavaScriptMinifier.ts | 82 +++++++ dist/ts/class/PackageCreator.ts | 65 +++++ dist/ts/class/StyleProcessor.ts | 98 ++++++++ dist/ts/class/SvgPackager.ts | 229 ++++++++++++++++++ dist/ts/class/SvgSpriteGenerator.ts | 99 ++++++++ dist/ts/class/TypeScriptCompiler.ts | 112 +++++++++ dist/ts/class/VersionWriter.ts | 57 +++++ dist/ts/index.ts | 32 +-- dist/ts/{interfaces => interface}/File.ts | 2 +- .../ts/interface}/PackageJson.ts | 2 +- .../interfaces => dist/ts/interface}/SVG.ts | 2 +- package.json | 2 +- src/ts/class/FontGenerator.ts | 136 +++++++++++ src/ts/class/JavaScriptMinifier.ts | 82 +++++++ src/ts/class/PackageCreator.ts | 65 +++++ src/ts/class/StyleProcessor.ts | 98 ++++++++ src/ts/class/SvgPackager.ts | 229 ++++++++++++++++++ src/ts/class/SvgSpriteGenerator.ts | 99 ++++++++ src/ts/class/TypeScriptCompiler.ts | 112 +++++++++ src/ts/class/VersionWriter.ts | 57 +++++ src/ts/index.ts | 32 +-- src/ts/{interfaces => interface}/File.ts | 2 +- .../ts/interface}/PackageJson.ts | 2 +- .../ts/interfaces => src/ts/interface}/SVG.ts | 2 +- 51 files changed, 2857 insertions(+), 43 deletions(-) create mode 100644 dist/js/class/FontGenerator.d.ts create mode 100644 dist/js/class/FontGenerator.js create mode 100644 dist/js/class/JavaScriptMinifier.d.ts create mode 100644 dist/js/class/JavaScriptMinifier.js create mode 100644 dist/js/class/PackageCreator.d.ts create mode 100644 dist/js/class/PackageCreator.js create mode 100644 dist/js/class/StyleProcessor.d.ts create mode 100644 dist/js/class/StyleProcessor.js create mode 100644 dist/js/class/SvgPackager.d.ts create mode 100644 dist/js/class/SvgPackager.js create mode 100644 dist/js/class/SvgSpriteGenerator.d.ts create mode 100644 dist/js/class/SvgSpriteGenerator.js create mode 100644 dist/js/class/TypeScriptCompiler.d.ts create mode 100644 dist/js/class/TypeScriptCompiler.js create mode 100644 dist/js/class/VersionWriter.d.ts create mode 100644 dist/js/class/VersionWriter.js create mode 100644 dist/js/config/postcss.config.compressed.d.ts create mode 100644 dist/js/config/postcss.config.compressed.js create mode 100644 dist/js/config/postcss.config.expanded.d.ts create mode 100644 dist/js/config/postcss.config.expanded.js create mode 100644 dist/js/interface/PackageJson.d.ts create mode 100644 dist/js/interface/PackageJson.js create mode 100644 dist/ts/class/FontGenerator.ts create mode 100644 dist/ts/class/JavaScriptMinifier.ts create mode 100644 dist/ts/class/PackageCreator.ts create mode 100644 dist/ts/class/StyleProcessor.ts create mode 100644 dist/ts/class/SvgPackager.ts create mode 100644 dist/ts/class/SvgSpriteGenerator.ts create mode 100644 dist/ts/class/TypeScriptCompiler.ts create mode 100644 dist/ts/class/VersionWriter.ts rename dist/ts/{interfaces => interface}/File.ts (64%) rename {src/ts/interfaces => dist/ts/interface}/PackageJson.ts (98%) rename {src/ts/interfaces => dist/ts/interface}/SVG.ts (91%) create mode 100644 src/ts/class/FontGenerator.ts create mode 100644 src/ts/class/JavaScriptMinifier.ts create mode 100644 src/ts/class/PackageCreator.ts create mode 100644 src/ts/class/StyleProcessor.ts create mode 100644 src/ts/class/SvgPackager.ts create mode 100644 src/ts/class/SvgSpriteGenerator.ts create mode 100644 src/ts/class/TypeScriptCompiler.ts create mode 100644 src/ts/class/VersionWriter.ts rename src/ts/{interfaces => interface}/File.ts (64%) rename {dist/ts/interfaces => src/ts/interface}/PackageJson.ts (98%) rename {dist/ts/interfaces => src/ts/interface}/SVG.ts (91%) diff --git a/VERSION b/VERSION index 99d85ec..5c4511c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.6 \ No newline at end of file +0.0.7 \ No newline at end of file diff --git a/dist/js/class/FontGenerator.d.ts b/dist/js/class/FontGenerator.d.ts new file mode 100644 index 0000000..64c1576 --- /dev/null +++ b/dist/js/class/FontGenerator.d.ts @@ -0,0 +1,4 @@ +declare class FontGenerator { + generateFonts(sourceDirectory: string, outputDiectory: string): Promise; +} +export default FontGenerator; diff --git a/dist/js/class/FontGenerator.js b/dist/js/class/FontGenerator.js new file mode 100644 index 0000000..007146a --- /dev/null +++ b/dist/js/class/FontGenerator.js @@ -0,0 +1,92 @@ +"use strict"; +// class/FontGenerator.ts +Object.defineProperty(exports, "__esModule", { value: true }); +// Copyright 2023 Scape Agency BV +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================ +// Import +// ============================================================================ +var fantasticon_1 = require("fantasticon"); +// ============================================================================ +// Classes +// ============================================================================ +class FontGenerator { + async generateFonts(sourceDirectory, outputDiectory) { + const config = { + // RunnerMandatoryOptions + inputDir: sourceDirectory, // (required) + outputDir: outputDiectory, // (required) + // RunnerOptionalOptions + name: 'icon.gl', + fontTypes: [ + fantasticon_1.FontAssetType.TTF, // TTF = "ttf" + fantasticon_1.FontAssetType.WOFF, // WOFF = "woff" + fantasticon_1.FontAssetType.WOFF2, // WOFF2 = "woff2" + fantasticon_1.FontAssetType.EOT, // EOT = "eot" + fantasticon_1.FontAssetType.SVG, // SVG = "svg" + ], + assetTypes: [ + fantasticon_1.OtherAssetType.CSS, // CSS = "css", + fantasticon_1.OtherAssetType.SCSS, // SCSS = "scss", + fantasticon_1.OtherAssetType.SASS, // SASS = "sass", + fantasticon_1.OtherAssetType.HTML, // HTML = "html", + fantasticon_1.OtherAssetType.JSON, // JSON = "json", + fantasticon_1.OtherAssetType.TS, // TS = "ts" + ], + formatOptions: { + // woff: { + // // Woff Extended Metadata Block - see https://www.w3.org/TR/WOFF/#Metadata + // metadata: '...' + // }, + // ttf?: TtfOptions; // type TtfOptions = svg2ttf.FontOptions; + // svg?: SvgOptions; // type SvgOptions = Omit; + json: { indent: 4 } + }, + pathOptions: { + json: './dist/font/icon.gl.json', + css: './dist/font/icon.gl.css', + scss: './dist/font/icon.gl.scss', + woff: './dist/font/icon.gl.woff', + woff2: './dist/font/icon.gl.woff2' + }, + // codepoints: { + // 'chevron-left': 57344, // decimal representation of 0xe000 + // 'chevron-right': 57345, + // 'thumbs-up': 57358, + // 'thumbs-down': 57359, + // }, + // fontHeight: number; + // descent: number; + // normalize: boolean; + // round: number; + selector: '.igl', + // tag: string; + // Use our custom Handlebars templates + // templates: { + // css: './build/font/icon.gl.css.hbs', + // scss: './build/font/icon.gl.scss.hbs' + // }, + prefix: 'igl', + fontsUrl: './fonts' + }; + try { + await (0, fantasticon_1.generateFonts)(config); + console.log('Fonts generated successfully.'); + } + catch (error) { + console.error('Error generating fonts:', error); + } + } +} +// ============================================================================ +// Export +// ============================================================================ +exports.default = FontGenerator; diff --git a/dist/js/class/JavaScriptMinifier.d.ts b/dist/js/class/JavaScriptMinifier.d.ts new file mode 100644 index 0000000..d25176f --- /dev/null +++ b/dist/js/class/JavaScriptMinifier.d.ts @@ -0,0 +1,19 @@ +/** + * Class to minify JavaScript files using Terser. + */ +declare class JavaScriptMinifier { + private config; + /** + * Constructs an instance with the provided configuration. + * @param {any} config - Configuration object - minification options for Terser. + */ + constructor(config: any); + /** + * Minifies a JavaScript file. + * @param {string} inputPath - Path to the input JavaScript file. + * @param {string} outputPath - Path to save the minified output file. + * @returns {Promise} - A promise that resolves when minification is complete. + */ + minifyFile(inputPath: string, outputPath: string): Promise; +} +export default JavaScriptMinifier; diff --git a/dist/js/class/JavaScriptMinifier.js b/dist/js/class/JavaScriptMinifier.js new file mode 100644 index 0000000..1e09568 --- /dev/null +++ b/dist/js/class/JavaScriptMinifier.js @@ -0,0 +1,63 @@ +"use strict"; +// class/JavaScriptMinifier.ts +Object.defineProperty(exports, "__esModule", { value: true }); +// Copyright 2023 Scape Agency BV +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================ +// Import +// ============================================================================ +var terser_1 = require("terser"); +var fs_1 = require("fs"); +// ============================================================================ +// Classes +// ============================================================================ +/** + * Class to minify JavaScript files using Terser. + */ +class JavaScriptMinifier { + /** + * Constructs an instance with the provided configuration. + * @param {any} config - Configuration object - minification options for Terser. + */ + constructor(config) { + this.config = config; + } + /** + * Minifies a JavaScript file. + * @param {string} inputPath - Path to the input JavaScript file. + * @param {string} outputPath - Path to save the minified output file. + * @returns {Promise} - A promise that resolves when minification is complete. + */ + async minifyFile(inputPath, outputPath) { + try { + // Read the input file + const inputCode = await fs_1.promises.readFile(inputPath, 'utf8'); + // Minify the file using Terser + // const result = await minify(inputCode, options); + const result = await (0, terser_1.minify)(inputCode, this.config); + // If minification is successful, write the output + if (result.code) { + await fs_1.promises.writeFile(outputPath, result.code); + } + else { + throw new Error('Minification resulted in empty output.'); + } + } + catch (error) { + console.error(`Error minifying JavaScript file ${inputPath}:`, error); + throw error; + } + } +} +// ============================================================================ +// Export +// ============================================================================ +exports.default = JavaScriptMinifier; diff --git a/dist/js/class/PackageCreator.d.ts b/dist/js/class/PackageCreator.d.ts new file mode 100644 index 0000000..432a212 --- /dev/null +++ b/dist/js/class/PackageCreator.d.ts @@ -0,0 +1,18 @@ +import { PackageJson } from '../interface/PackageJson.js'; +/** + * A class for creating a package.json file for a project. + */ +declare class PackageCreator { + private packageJson; + /** + * Initializes a new instance of the PackageCreator class. + * @param {PackageJson} packageJson - The content to be written into package.json. + */ + constructor(packageJson: PackageJson); + /** + * Creates a package.json file in the specified directory. + * @param {string} outputDir - The directory where package.json will be created. + */ + createPackageJson(outputDir: string): Promise; +} +export default PackageCreator; diff --git a/dist/js/class/PackageCreator.js b/dist/js/class/PackageCreator.js new file mode 100644 index 0000000..51e802f --- /dev/null +++ b/dist/js/class/PackageCreator.js @@ -0,0 +1,50 @@ +"use strict"; +// class/PackageCreator.ts +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// Copyright 2023 Scape Agency BV +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================ +// Import +// ============================================================================ +var fs_1 = __importDefault(require("fs")); +var path_1 = __importDefault(require("path")); +// ============================================================================ +// Classes +// ============================================================================ +/** + * A class for creating a package.json file for a project. + */ +class PackageCreator { + /** + * Initializes a new instance of the PackageCreator class. + * @param {PackageJson} packageJson - The content to be written into package.json. + */ + constructor(packageJson) { + this.packageJson = packageJson; + } + /** + * Creates a package.json file in the specified directory. + * @param {string} outputDir - The directory where package.json will be created. + */ + async createPackageJson(outputDir) { + const filePath = path_1.default.join(outputDir, 'package.json'); + const data = JSON.stringify(this.packageJson, null, 2); + fs_1.default.writeFileSync(filePath, data, 'utf-8'); + console.log(`package.json created at ${filePath}`); + } +} +// ============================================================================ +// Export +// ============================================================================ +exports.default = PackageCreator; diff --git a/dist/js/class/StyleProcessor.d.ts b/dist/js/class/StyleProcessor.d.ts new file mode 100644 index 0000000..22556b8 --- /dev/null +++ b/dist/js/class/StyleProcessor.d.ts @@ -0,0 +1,24 @@ +/// +import postcss from 'postcss'; +import fs from 'fs'; +/** + * Class responsible for processing styles, including compiling SCSS and + * applying PostCSS transformations. + */ +declare class StyleProcessor { + /** + * Processes the given CSS with PostCSS based on the provided style option. + * @param css The CSS string to process. + * @param styleOption The style option, either 'expanded' or 'compressed'. + * @returns Processed CSS string. + */ + processPostCSS(css: string, styleOption: 'expanded' | 'compressed'): Promise>; + /** + * Compiles SCSS to CSS and processes it using PostCSS. + * @param inputFile Path to the input SCSS file. + * @param outputFile Path to the output CSS file. + * @param styleOption Style option for the output. + */ + processStyles(inputFile: string, outputFile: fs.PathOrFileDescriptor, styleOption: 'expanded' | 'compressed'): Promise; +} +export default StyleProcessor; diff --git a/dist/js/class/StyleProcessor.js b/dist/js/class/StyleProcessor.js new file mode 100644 index 0000000..af41c47 --- /dev/null +++ b/dist/js/class/StyleProcessor.js @@ -0,0 +1,94 @@ +"use strict"; +// class/StyleProcessor.ts +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// Copyright 2023 Scape Agency BV +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================ +// Import +// ============================================================================ +var sass = __importStar(require("sass")); +var postcss_1 = __importDefault(require("postcss")); +var fs_1 = __importDefault(require("fs")); +var postcss_config_expanded_js_1 = __importDefault(require("../config/postcss.config.expanded.js")); +var postcss_config_compressed_js_1 = __importDefault(require("../config/postcss.config.compressed.js")); +// ============================================================================ +// Classes +// ============================================================================ +/** + * Class responsible for processing styles, including compiling SCSS and + * applying PostCSS transformations. + */ +class StyleProcessor { + /** + * Processes the given CSS with PostCSS based on the provided style option. + * @param css The CSS string to process. + * @param styleOption The style option, either 'expanded' or 'compressed'. + * @returns Processed CSS string. + */ + async processPostCSS(css, styleOption) { + const config = styleOption === 'expanded' ? postcss_config_expanded_js_1.default : postcss_config_compressed_js_1.default; + return (0, postcss_1.default)(config.plugins).process(css, { from: undefined, map: { inline: false } }); + } + /** + * Compiles SCSS to CSS and processes it using PostCSS. + * @param inputFile Path to the input SCSS file. + * @param outputFile Path to the output CSS file. + * @param styleOption Style option for the output. + */ + async processStyles(inputFile, outputFile, styleOption) { + try { + // Compile SCSS to CSS + const result = await sass.compileAsync(inputFile, { style: styleOption }); + // Process the compiled CSS with PostCSS and Autoprefixer + const processed = await this.processPostCSS(result.css, styleOption); + // Write the processed CSS to a file + fs_1.default.writeFileSync(outputFile, processed.css); + // Write the source map file + if (processed.map) { + fs_1.default.writeFileSync(`${outputFile}.map`, processed.map.toString()); + } + } + catch (err) { + // Handle errors in the compilation or processing + console.error(`Error processing styles from ${inputFile}:`, err); + } + } +} +// ============================================================================ +// Export +// ============================================================================ +exports.default = StyleProcessor; diff --git a/dist/js/class/SvgPackager.d.ts b/dist/js/class/SvgPackager.d.ts new file mode 100644 index 0000000..c8c146f --- /dev/null +++ b/dist/js/class/SvgPackager.d.ts @@ -0,0 +1,56 @@ +/** + * Class for packaging SVG files. + * This class reads SVG files from a specified directory, optimizes them, + * and creates corresponding TypeScript files. + */ +declare class SvgPackager { + /** + * Processes all SVG files in a given directory. + * @param directory The directory containing SVG files to process. + * @param outputDirectory The directory where optimized SVGs will be output as TypeScript files. + */ + processSvgFiles(directory: string, outputDirectory: string, ts_output_directory: string, json_output_directory: string): Promise; + /** + * Reads the content of an SVG file. + * @param filePath The path to the SVG file. + * @returns The content of the SVG file. + */ + private readSvgFile; + /** + * Sanitizes a file name to be a valid TypeScript identifier. + * @param fileName The original file name. + * @returns A sanitized version of the file name. + */ + private sanitizeFileName; + /** + * Optimizes SVG content using SVGO. + * @param svgContent The raw SVG content. + * @returns The optimized SVG content. + */ + private optimizeSvg; + /** + * Creates a TypeScript file from SVG content. + * @param filePath The path of the SVG file. + * @param svgContent The optimized SVG content. + * @param outputDirectory The directory to output the TypeScript file. + */ + private writeTypeScriptFile; + /** + * Writes the SVG content to a file. + * @param filePath The original file path of the SVG. + * @param svgContent The SVG content to be written. + * @param outputDirectory The directory to output the SVG file. + */ + private writeSvgFile; + /** + * Writes a JSON file containing the names of processed icons. + * This method creates a JSON file that lists all icon names which have + * been processed, making it easier to reference or index these icons in + * other parts of an application. + * + * @param iconNames An array of strings containing the names of the icons. + * @param outputDirectory The directory where the JSON file will be saved. + */ + private writeIconsJson; +} +export default SvgPackager; diff --git a/dist/js/class/SvgPackager.js b/dist/js/class/SvgPackager.js new file mode 100644 index 0000000..36e3f19 --- /dev/null +++ b/dist/js/class/SvgPackager.js @@ -0,0 +1,197 @@ +"use strict"; +// class/SvgPackager.ts +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// Copyright 2023 Scape Agency BV +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================ +// Import +// ============================================================================ +// import * as fs from 'fs'; +var fs_extra = __importStar(require("fs-extra")); +var fs_1 = require("fs"); +var glob = __importStar(require("glob")); +var path = __importStar(require("path")); +var url_1 = require("url"); +var svgo_1 = __importDefault(require("svgo")); +var svgo_2 = require("svgo"); +// Convert the current file's URL to a file path +const __filename = (0, url_1.fileURLToPath)(import.meta.url); +// Derive the directory name of the current module +const __dirname = path.dirname(__filename); +// ============================================================================ +// Classes +// ============================================================================ +/** + * Class for packaging SVG files. + * This class reads SVG files from a specified directory, optimizes them, + * and creates corresponding TypeScript files. + */ +class SvgPackager { + /** + * Processes all SVG files in a given directory. + * @param directory The directory containing SVG files to process. + * @param outputDirectory The directory where optimized SVGs will be output as TypeScript files. + */ + async processSvgFiles(directory, outputDirectory, ts_output_directory, json_output_directory) { + const iconNames = []; + try { + console.log(`Processing directory: ${directory}`); + const svgFiles = glob.sync(`${directory}/**/*.svg`); + for (const file of svgFiles) { + console.log(`Processing file: ${file}`); + const iconName = this.sanitizeFileName(path.basename(file, '.svg')); + iconNames.push(iconName); + console.log(`Processing icon: ${iconName}`); + const svgContent = await this.readSvgFile(file); + const optimizedSvg = await this.optimizeSvg(file, svgContent); + // svgo will always add a final newline when in pretty mode + const resultSvg = optimizedSvg.trim(); + // Write the optimized SVG file + await this.writeSvgFile(file, iconName, resultSvg, outputDirectory); + // Write the optimized TypeScript file + await this.writeTypeScriptFile(file, iconName, resultSvg, ts_output_directory); + } + await this.writeIconsJson(iconNames, json_output_directory); + console.log(`Successfully processed ${svgFiles.length} SVG files.`); + } + catch (error) { + console.error('Error processing SVG files:', error); + throw error; + } + } + /** + * Reads the content of an SVG file. + * @param filePath The path to the SVG file. + * @returns The content of the SVG file. + */ + async readSvgFile(filePath) { + try { + const absolutePath = path.resolve(filePath); + const svgContent = await fs_1.promises.readFile(absolutePath, 'utf8'); + return svgContent; + } + catch (error) { + console.error('Error reading file:', filePath, error); + throw error; + } + } + /** + * Sanitizes a file name to be a valid TypeScript identifier. + * @param fileName The original file name. + * @returns A sanitized version of the file name. + */ + sanitizeFileName(fileName) { + // Implement more robust sanitization logic if necessary + return fileName.replace(/[^a-zA-Z0-9_]/g, '_'); + } + /** + * Optimizes SVG content using SVGO. + * @param svgContent The raw SVG content. + * @returns The optimized SVG content. + */ + async optimizeSvg(filePath, svgContent) { + try { + const config = await (0, svgo_2.loadConfig)(path.join(__dirname, '../config/svgo.config.js')); + const result = await svgo_1.default.optimize(svgContent, { path: filePath, ...config } // Add SVGO options if needed + ); + return result.data; + } + catch (error) { + console.error('Error optimizing SVG:', error); + throw error; + } + } + /** + * Creates a TypeScript file from SVG content. + * @param filePath The path of the SVG file. + * @param svgContent The optimized SVG content. + * @param outputDirectory The directory to output the TypeScript file. + */ + async writeTypeScriptFile(filePath, iconName, svgContent, outputDirectory) { + try { + const tsContent = `export const icon_${iconName} = \`${svgContent}\`;\n`; + const outputPath = path.join(outputDirectory, `${iconName}.ts`); + await fs_extra.outputFile(outputPath, tsContent); + } + catch (error) { + console.error(`Error creating TypeScript file for ${filePath}:`, error); + throw error; + } + } + /** + * Writes the SVG content to a file. + * @param filePath The original file path of the SVG. + * @param svgContent The SVG content to be written. + * @param outputDirectory The directory to output the SVG file. + */ + async writeSvgFile(filePath, iconName, svgContent, outputDirectory) { + try { + const outputPath = path.join(outputDirectory, `${iconName}.svg`); + await fs_extra.outputFile(outputPath, svgContent); + console.log(`SVG file written successfully for ${iconName}`); + } + catch (error) { + console.error(`Error writing SVG file for ${iconName}:`, error); + throw error; + } + } + /** + * Writes a JSON file containing the names of processed icons. + * This method creates a JSON file that lists all icon names which have + * been processed, making it easier to reference or index these icons in + * other parts of an application. + * + * @param iconNames An array of strings containing the names of the icons. + * @param outputDirectory The directory where the JSON file will be saved. + */ + async writeIconsJson(iconNames, outputDirectory) { + try { + const jsonContent = JSON.stringify(iconNames, null, 2); + const outputPath = path.join(outputDirectory, 'icons.json'); + await fs_extra.outputFile(outputPath, jsonContent); + console.log('Icons JSON file created successfully'); + } + catch (error) { + console.error('Error writing icons JSON file:', error); + throw error; + } + } +} +// ============================================================================ +// Export +// ============================================================================ +exports.default = SvgPackager; diff --git a/dist/js/class/SvgSpriteGenerator.d.ts b/dist/js/class/SvgSpriteGenerator.d.ts new file mode 100644 index 0000000..6ec5cb0 --- /dev/null +++ b/dist/js/class/SvgSpriteGenerator.d.ts @@ -0,0 +1,18 @@ +/** + * A class for generating SVG sprites from individual SVG files. + */ +declare class SvgSpriteGenerator { + private config; + /** + * Constructs an instance of SvgSpriteGenerator with the provided configuration. + * @param {any} config - Configuration object for svg-sprite. + */ + constructor(config: any); + /** + * Generates an SVG sprite from SVG files in a specified directory. + * @param {string} sourceDir - Directory containing source SVG files. + * @param {string} outputDir - Directory where the generated sprite will be saved. + */ + generateSprite(sourceDir: string, outputDir: string): Promise; +} +export default SvgSpriteGenerator; diff --git a/dist/js/class/SvgSpriteGenerator.js b/dist/js/class/SvgSpriteGenerator.js new file mode 100644 index 0000000..14ef2b7 --- /dev/null +++ b/dist/js/class/SvgSpriteGenerator.js @@ -0,0 +1,74 @@ +"use strict"; +// class/SvgSpriteGenerator.ts +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// Copyright 2023 Scape Agency BV +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================ +// Import +// ============================================================================ +var svg_sprite_1 = __importDefault(require("svg-sprite")); +var fs_1 = __importDefault(require("fs")); +var path_1 = __importDefault(require("path")); +// ============================================================================ +// Classes +// ============================================================================ +/** + * A class for generating SVG sprites from individual SVG files. + */ +class SvgSpriteGenerator { + /** + * Constructs an instance of SvgSpriteGenerator with the provided configuration. + * @param {any} config - Configuration object for svg-sprite. + */ + constructor(config) { + this.config = config; + } + /** + * Generates an SVG sprite from SVG files in a specified directory. + * @param {string} sourceDir - Directory containing source SVG files. + * @param {string} outputDir - Directory where the generated sprite will be saved. + */ + async generateSprite(sourceDir, outputDir) { + try { + const files = fs_1.default.readdirSync(sourceDir); + const sprite = new svg_sprite_1.default(this.config); + files.forEach(file => { + if (path_1.default.extname(file) === '.svg') { + const svgPath = path_1.default.resolve(sourceDir, file); + const content = fs_1.default.readFileSync(svgPath, 'utf8'); + sprite.add(svgPath, null, content); + } + }); + sprite.compile((error, result) => { + if (error) { + throw error; + } + for (const mode in result) { + for (const resource in result[mode]) { + const outputPath = path_1.default.resolve(outputDir, result[mode][resource].path); + fs_1.default.mkdirSync(path_1.default.dirname(outputPath), { recursive: true }); + fs_1.default.writeFileSync(outputPath, result[mode][resource].contents); + } + } + }); + } + catch (err) { + console.error('Error generating SVG sprite:', err); + } + } +} +// ============================================================================ +// Export +// ============================================================================ +exports.default = SvgSpriteGenerator; diff --git a/dist/js/class/TypeScriptCompiler.d.ts b/dist/js/class/TypeScriptCompiler.d.ts new file mode 100644 index 0000000..da76fbc --- /dev/null +++ b/dist/js/class/TypeScriptCompiler.d.ts @@ -0,0 +1,25 @@ +/** + * TypeScriptCompiler class for compiling TypeScript files to JavaScript. + */ +declare class TypeScriptCompiler { + private config; + /** + * Constructs an instance with the provided configuration. + * @param {any} config - Configuration object + */ + constructor(config: any); + /** + * Compiles TypeScript files to JavaScript. + * + * @param {string[]} filePaths - The paths of TypeScript files to be compiled. + * @param {string} outDir - The directory where the compiled JavaScript files will be saved. + * @param {ts.CompilerOptions} customOptions - Optional custom TypeScript compiler options. + * + * This method sets up a TypeScript program with given file paths and compiler options. + * It handles the compilation of TypeScript files into JavaScript, considering any provided custom options. + * Compilation errors and diagnostics are logged for debugging purposes. + * The method returns a promise that resolves when compilation is successful or rejects in case of errors. + */ + compile(filePaths: string[], outDir: string): Promise; +} +export default TypeScriptCompiler; diff --git a/dist/js/class/TypeScriptCompiler.js b/dist/js/class/TypeScriptCompiler.js new file mode 100644 index 0000000..f462515 --- /dev/null +++ b/dist/js/class/TypeScriptCompiler.js @@ -0,0 +1,92 @@ +"use strict"; +// class/TypeScriptCompiler.ts +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// Copyright 2023 Scape Agency BV +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================ +// Import +// ============================================================================ +// import * as ts from 'typescript'; +var typescript_1 = __importDefault(require("typescript")); +// ============================================================================ +// Classes +// ============================================================================ +/** + * TypeScriptCompiler class for compiling TypeScript files to JavaScript. + */ +class TypeScriptCompiler { + /** + * Constructs an instance with the provided configuration. + * @param {any} config - Configuration object + */ + constructor(config) { + this.config = config; + } + /** + * Compiles TypeScript files to JavaScript. + * + * @param {string[]} filePaths - The paths of TypeScript files to be compiled. + * @param {string} outDir - The directory where the compiled JavaScript files will be saved. + * @param {ts.CompilerOptions} customOptions - Optional custom TypeScript compiler options. + * + * This method sets up a TypeScript program with given file paths and compiler options. + * It handles the compilation of TypeScript files into JavaScript, considering any provided custom options. + * Compilation errors and diagnostics are logged for debugging purposes. + * The method returns a promise that resolves when compilation is successful or rejects in case of errors. + */ + compile(filePaths, outDir) { + return new Promise((resolve, reject) => { + // Merge default options with custom options + const options = { + module: typescript_1.default.ModuleKind.CommonJS, + target: typescript_1.default.ScriptTarget.ES2015, + outDir, + // ...customOptions, // Merges custom compiler options + ...this.config + }; + // Create a TypeScript compiler host + const host = typescript_1.default.createCompilerHost(options); + // Create a program with the specified files and options + const program = typescript_1.default.createProgram(filePaths, options, host); + // Emit the compiled JavaScript files + const emitResult = program.emit(); + // Check for compilation errors + const allDiagnostics = typescript_1.default.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); + allDiagnostics.forEach(diagnostic => { + // Handle and print diagnostics + if (diagnostic.file) { + const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); + const message = typescript_1.default.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); + console.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); + } + else { + console.error(typescript_1.default.flattenDiagnosticMessageText(diagnostic.messageText, '\n')); + } + }); + const exitCode = emitResult.emitSkipped ? 1 : 0; + if (exitCode === 0) { + console.log('Compilation completed successfully.'); + resolve(); + } + else { + console.error('Compilation failed.'); + reject(new Error('TypeScript compilation failed')); + } + }); + } +} +// ============================================================================ +// Export +// ============================================================================ +exports.default = TypeScriptCompiler; diff --git a/dist/js/class/VersionWriter.d.ts b/dist/js/class/VersionWriter.d.ts new file mode 100644 index 0000000..7650627 --- /dev/null +++ b/dist/js/class/VersionWriter.d.ts @@ -0,0 +1,12 @@ +/** + * A class for writing version information to a file. + */ +declare class VersionWriter { + /** + * Writes the specified version string to a file. + * @param {string} filePath - The file path where the version will be written. + * @param {string} version - The version string to write to the file. + */ + writeVersionToFile(filePath: string, version: string): Promise; +} +export default VersionWriter; diff --git a/dist/js/class/VersionWriter.js b/dist/js/class/VersionWriter.js new file mode 100644 index 0000000..e8d0827 --- /dev/null +++ b/dist/js/class/VersionWriter.js @@ -0,0 +1,43 @@ +"use strict"; +// class/VersionWriter.ts +Object.defineProperty(exports, "__esModule", { value: true }); +// Copyright 2023 Scape Agency BV +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================ +// Import +// ============================================================================ +var fs_1 = require("fs"); +// ============================================================================ +// Classes +// ============================================================================ +/** + * A class for writing version information to a file. + */ +class VersionWriter { + /** + * Writes the specified version string to a file. + * @param {string} filePath - The file path where the version will be written. + * @param {string} version - The version string to write to the file. + */ + async writeVersionToFile(filePath, version) { + try { + await fs_1.promises.writeFile(filePath, version, 'utf8'); + console.log(`Version ${version} written to ${filePath}`); + } + catch (error) { + console.error(`Error writing version to file: ${error}`); + } + } +} +// ============================================================================ +// Export +// ============================================================================ +exports.default = VersionWriter; diff --git a/dist/js/config/postcss.config.compressed.d.ts b/dist/js/config/postcss.config.compressed.d.ts new file mode 100644 index 0000000..8fb398c --- /dev/null +++ b/dist/js/config/postcss.config.compressed.d.ts @@ -0,0 +1,5 @@ +import autoprefixer from 'autoprefixer'; +declare const postcssConfigCompressed: { + plugins: (typeof autoprefixer | import("postcss/lib/processor").default)[]; +}; +export default postcssConfigCompressed; diff --git a/dist/js/config/postcss.config.compressed.js b/dist/js/config/postcss.config.compressed.js new file mode 100644 index 0000000..2d9be8a --- /dev/null +++ b/dist/js/config/postcss.config.compressed.js @@ -0,0 +1,37 @@ +"use strict"; +// config/postcss.config.compressed.ts +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// Copyright 2023 Scape Agency BV +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================ +// Import +// ============================================================================ +var autoprefixer_1 = __importDefault(require("autoprefixer")); +var cssnano_1 = __importDefault(require("cssnano")); +// ============================================================================ +// Constants +// ============================================================================ +const postcssConfigCompressed = { + plugins: [ + autoprefixer_1.default, + // Minification for compressed output + (0, cssnano_1.default)({ + preset: 'default' + }), + ] +}; +// ============================================================================ +// Export +// ============================================================================ +exports.default = postcssConfigCompressed; diff --git a/dist/js/config/postcss.config.expanded.d.ts b/dist/js/config/postcss.config.expanded.d.ts new file mode 100644 index 0000000..87e1a69 --- /dev/null +++ b/dist/js/config/postcss.config.expanded.d.ts @@ -0,0 +1,5 @@ +import autoprefixer from 'autoprefixer'; +declare const postcssConfigExpanded: { + plugins: (typeof autoprefixer)[]; +}; +export default postcssConfigExpanded; diff --git a/dist/js/config/postcss.config.expanded.js b/dist/js/config/postcss.config.expanded.js new file mode 100644 index 0000000..db1bf70 --- /dev/null +++ b/dist/js/config/postcss.config.expanded.js @@ -0,0 +1,33 @@ +"use strict"; +// config/postcss.config.expanded.ts +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// Copyright 2023 Scape Agency BV +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================ +// Import +// ============================================================================ +var autoprefixer_1 = __importDefault(require("autoprefixer")); +// ============================================================================ +// Constants +// ============================================================================ +const postcssConfigExpanded = { + plugins: [ + autoprefixer_1.default, + // Include other plugins suited for the expanded output + ] +}; +// ============================================================================ +// Export +// ============================================================================ +exports.default = postcssConfigExpanded; diff --git a/dist/js/index.d.ts b/dist/js/index.d.ts index 1008fd5..205cdff 100644 --- a/dist/js/index.d.ts +++ b/dist/js/index.d.ts @@ -3,4 +3,12 @@ import DirectoryCopier from './class/DirectoryCopier'; import DirectoryCreator from './class/DirectoryCreator'; import FileCopier from './class/FileCopier'; import FileRenamer from './class/FileRenamer'; -export { DirectoryCleaner, DirectoryCopier, DirectoryCreator, FileCopier, FileRenamer, }; +import FontGenerator from './class/FontGenerator.js'; +import PackageCreator from './class/PackageCreator.js'; +import SvgPackager from "./class/SvgPackager.js"; +import StyleProcessor from "./class/StyleProcessor.js"; +import SvgSpriteGenerator from "./class/SvgSpriteGenerator.js"; +import VersionWriter from './class/VersionWriter.js'; +import TypeScriptCompiler from './class/TypeScriptCompiler.js'; +import JavaScriptMinifier from './class/JavaScriptMinifier.js'; +export { DirectoryCleaner, DirectoryCopier, DirectoryCreator, FileCopier, FileRenamer, FontGenerator, PackageCreator, SvgPackager, StyleProcessor, SvgSpriteGenerator, VersionWriter, TypeScriptCompiler, JavaScriptMinifier, }; diff --git a/dist/js/index.js b/dist/js/index.js index 0b9c302..6234d50 100644 --- a/dist/js/index.js +++ b/dist/js/index.js @@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.FileRenamer = exports.FileCopier = exports.DirectoryCreator = exports.DirectoryCopier = exports.DirectoryCleaner = void 0; +exports.JavaScriptMinifier = exports.TypeScriptCompiler = exports.VersionWriter = exports.SvgSpriteGenerator = exports.StyleProcessor = exports.SvgPackager = exports.PackageCreator = exports.FontGenerator = exports.FileRenamer = exports.FileCopier = exports.DirectoryCreator = exports.DirectoryCopier = exports.DirectoryCleaner = void 0; // Copyright 2023 Scape Agency BV // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -29,3 +29,20 @@ var FileCopier_1 = __importDefault(require("./class/FileCopier")); exports.FileCopier = FileCopier_1.default; var FileRenamer_1 = __importDefault(require("./class/FileRenamer")); exports.FileRenamer = FileRenamer_1.default; +// // Import | Internal Classes +var FontGenerator_js_1 = __importDefault(require("./class/FontGenerator.js")); +exports.FontGenerator = FontGenerator_js_1.default; +var PackageCreator_js_1 = __importDefault(require("./class/PackageCreator.js")); +exports.PackageCreator = PackageCreator_js_1.default; +var SvgPackager_js_1 = __importDefault(require("./class/SvgPackager.js")); +exports.SvgPackager = SvgPackager_js_1.default; +var StyleProcessor_js_1 = __importDefault(require("./class/StyleProcessor.js")); +exports.StyleProcessor = StyleProcessor_js_1.default; +var SvgSpriteGenerator_js_1 = __importDefault(require("./class/SvgSpriteGenerator.js")); +exports.SvgSpriteGenerator = SvgSpriteGenerator_js_1.default; +var VersionWriter_js_1 = __importDefault(require("./class/VersionWriter.js")); +exports.VersionWriter = VersionWriter_js_1.default; +var TypeScriptCompiler_js_1 = __importDefault(require("./class/TypeScriptCompiler.js")); +exports.TypeScriptCompiler = TypeScriptCompiler_js_1.default; +var JavaScriptMinifier_js_1 = __importDefault(require("./class/JavaScriptMinifier.js")); +exports.JavaScriptMinifier = JavaScriptMinifier_js_1.default; diff --git a/dist/js/interface/PackageJson.d.ts b/dist/js/interface/PackageJson.d.ts new file mode 100644 index 0000000..0942d41 --- /dev/null +++ b/dist/js/interface/PackageJson.d.ts @@ -0,0 +1,67 @@ +export interface PackageJson { + name: string; + version: string; + description?: string; + main?: string; + scripts?: Record; + dependencies?: Record; + devDependencies?: Record; + repository?: { + type: string; + url: string; + }; + keywords?: string[]; + author?: string | { + name: string; + email?: string; + url?: string; + }; + license?: string; + bugs?: { + url?: string; + email?: string; + }; + homepage?: string; + private?: boolean; + peerDependencies?: Record; + engines?: { + node?: string; + npm?: string; + }; + bin?: Record; + types?: string; + contributors?: Array; + funding?: string | { + type: string; + url: string; + }; + files?: string[]; + browserslist?: string[] | Record; + publishConfig?: Record; + config?: Record; + typings?: string; + exports?: Record; + module?: string; + sideEffects?: boolean | string[]; + optionalDependencies?: Record; + bundledDependencies?: string[]; + peerDependenciesMeta?: Record; + resolutions?: Record; + workspaces?: string[] | { + packages: string[]; + }; + eslintConfig?: Record; + babel?: Record; + prettier?: Record; + husky?: Record; + jest?: Record; + enginesStrict?: boolean; + os?: string[]; + cpu?: string[]; +} diff --git a/dist/js/interface/PackageJson.js b/dist/js/interface/PackageJson.js new file mode 100644 index 0000000..7f5f816 --- /dev/null +++ b/dist/js/interface/PackageJson.js @@ -0,0 +1,5 @@ +"use strict"; +// ============================================================================ +// Interfaces +// ============================================================================ +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/dist/package.json b/dist/package.json index 8931e5c..704e920 100644 --- a/dist/package.json +++ b/dist/package.json @@ -1,6 +1,6 @@ { "name": "pack.gl", - "version": "0.0.6", + "version": "0.0.7", "description": "Package Builder.", "keywords": [ "pack.gl", diff --git a/dist/ts/class/FontGenerator.ts b/dist/ts/class/FontGenerator.ts new file mode 100644 index 0000000..1c45671 --- /dev/null +++ b/dist/ts/class/FontGenerator.ts @@ -0,0 +1,136 @@ +// class/FontGenerator.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +import { generateFonts, FontAssetType, OtherAssetType } from 'fantasticon'; + + +// ============================================================================ +// Classes +// ============================================================================ + +class FontGenerator { + + async generateFonts( + sourceDirectory: string, + outputDiectory: string, + ) { + + const config = { + + + // RunnerMandatoryOptions + inputDir: sourceDirectory, // (required) + outputDir: outputDiectory, // (required) + + // RunnerOptionalOptions + name: 'icon.gl', + fontTypes: [ + FontAssetType.TTF, // TTF = "ttf" + FontAssetType.WOFF, // WOFF = "woff" + FontAssetType.WOFF2, // WOFF2 = "woff2" + FontAssetType.EOT, // EOT = "eot" + FontAssetType.SVG, // SVG = "svg" + ], + assetTypes: [ + OtherAssetType.CSS, // CSS = "css", + OtherAssetType.SCSS, // SCSS = "scss", + OtherAssetType.SASS, // SASS = "sass", + OtherAssetType.HTML, // HTML = "html", + OtherAssetType.JSON, // JSON = "json", + OtherAssetType.TS, // TS = "ts" + ], + + + + formatOptions: { + // woff: { + // // Woff Extended Metadata Block - see https://www.w3.org/TR/WOFF/#Metadata + // metadata: '...' + // }, + // ttf?: TtfOptions; // type TtfOptions = svg2ttf.FontOptions; + // svg?: SvgOptions; // type SvgOptions = Omit; + json: { indent: 4 } , + // ts: { + // // select what kind of types you want to generate + // // (default `['enum', 'constant', 'literalId', 'literalKey']`) + // types: ['enum', 'constant', 'literalId', 'literalKey'], + // // render the types with `'` instead of `"` (default is `"`) + // singleQuotes: false, + // // customise names used for the generated types and constants + // enumName: 'icon_gl', + // constantName: 'MY_CODEPOINTS' + // // literalIdName: 'IconId', + // // literalKeyName: 'IconKey' + // } + }, + pathOptions: { + json: './dist/font/icon.gl.json', + css: './dist/font/icon.gl.css', + scss: './dist/font/icon.gl.scss', + woff: './dist/font/icon.gl.woff', + woff2: './dist/font/icon.gl.woff2', + }, + // codepoints: { + // 'chevron-left': 57344, // decimal representation of 0xe000 + // 'chevron-right': 57345, + // 'thumbs-up': 57358, + // 'thumbs-down': 57359, + // }, + // fontHeight: number; + // descent: number; + // normalize: boolean; + // round: number; + selector: '.igl', + // tag: string; + // Use our custom Handlebars templates + // templates: { + // css: './build/font/icon.gl.css.hbs', + // scss: './build/font/icon.gl.scss.hbs' + // }, + prefix: 'igl', + fontsUrl: './fonts', + + // Customize generated icon IDs (unavailable with `.json` config file) + // getIconId: ({ + // basename, // `string` - Example: 'foo'; + // relativeDirPath, // `string` - Example: 'sub/dir/foo.svg' + // absoluteFilePath, // `string` - Example: '/var/icons/sub/dir/foo.svg' + // relativeFilePath, // `string` - Example: 'foo.svg' + // index // `number` - Example: `0` + // }) => [index, basename].join('_') // '0_foo' + + }; + + try { + await generateFonts(config); + console.log('Fonts generated successfully.'); + } catch (error) { + console.error('Error generating fonts:', error); + } + } +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default FontGenerator; diff --git a/dist/ts/class/JavaScriptMinifier.ts b/dist/ts/class/JavaScriptMinifier.ts new file mode 100644 index 0000000..9cc485f --- /dev/null +++ b/dist/ts/class/JavaScriptMinifier.ts @@ -0,0 +1,82 @@ +// class/JavaScriptMinifier.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +import { minify } from 'terser'; +import { promises as fs } from 'fs'; + + +// ============================================================================ +// Classes +// ============================================================================ + +/** + * Class to minify JavaScript files using Terser. + */ + class JavaScriptMinifier { + + private config: any; + + /** + * Constructs an instance with the provided configuration. + * @param {any} config - Configuration object - minification options for Terser. + */ + constructor(config: any) { + this.config = config; + } + + /** + * Minifies a JavaScript file. + * @param {string} inputPath - Path to the input JavaScript file. + * @param {string} outputPath - Path to save the minified output file. + * @returns {Promise} - A promise that resolves when minification is complete. + */ + async minifyFile( + inputPath: string, + outputPath: string, + // options: object = {} + ): Promise { + + try { + // Read the input file + const inputCode = await fs.readFile(inputPath, 'utf8'); + // Minify the file using Terser + // const result = await minify(inputCode, options); + const result = await minify(inputCode, this.config); + // If minification is successful, write the output + if (result.code) { + await fs.writeFile(outputPath, result.code); + } else { + throw new Error('Minification resulted in empty output.'); + } + } catch (error) { + console.error(`Error minifying JavaScript file ${inputPath}:`, error); + throw error; + } + } + +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default JavaScriptMinifier; diff --git a/dist/ts/class/PackageCreator.ts b/dist/ts/class/PackageCreator.ts new file mode 100644 index 0000000..9c87cd8 --- /dev/null +++ b/dist/ts/class/PackageCreator.ts @@ -0,0 +1,65 @@ +// class/PackageCreator.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +import fs from 'fs'; +import path from 'path'; +// import * as pack from '../../package.json' assert { type: 'json' }; +import { PackageJson } from '../interface/PackageJson.js' + +// ============================================================================ +// Classes +// ============================================================================ + +/** + * A class for creating a package.json file for a project. + */ + class PackageCreator { + + private packageJson: PackageJson; + + /** + * Initializes a new instance of the PackageCreator class. + * @param {PackageJson} packageJson - The content to be written into package.json. + */ + constructor(packageJson: PackageJson) { + this.packageJson = packageJson; + } + + /** + * Creates a package.json file in the specified directory. + * @param {string} outputDir - The directory where package.json will be created. + */ + async createPackageJson(outputDir: string): Promise { + const filePath = path.join(outputDir, 'package.json'); + const data = JSON.stringify(this.packageJson, null, 2); + + fs.writeFileSync(filePath, data, 'utf-8'); + console.log(`package.json created at ${filePath}`); + } + +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default PackageCreator; \ No newline at end of file diff --git a/dist/ts/class/StyleProcessor.ts b/dist/ts/class/StyleProcessor.ts new file mode 100644 index 0000000..ce8c781 --- /dev/null +++ b/dist/ts/class/StyleProcessor.ts @@ -0,0 +1,98 @@ +// class/StyleProcessor.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +import * as sass from 'sass' +import postcss from 'postcss'; +import fs from 'fs'; +import { promises as fsPromises } from 'fs'; + +import postcssConfigExpanded from '../config/postcss.config.expanded.js'; +import postcssConfigCompressed from '../config/postcss.config.compressed.js'; + + +// ============================================================================ +// Classes +// ============================================================================ + +/** + * Class responsible for processing styles, including compiling SCSS and + * applying PostCSS transformations. + */ +class StyleProcessor { + + /** + * Processes the given CSS with PostCSS based on the provided style option. + * @param css The CSS string to process. + * @param styleOption The style option, either 'expanded' or 'compressed'. + * @returns Processed CSS string. + */ + async processPostCSS( + css: string, + styleOption: 'expanded' | 'compressed' + ) { + const config = styleOption === 'expanded' ? postcssConfigExpanded : postcssConfigCompressed; + return postcss(config.plugins).process(css, { from: undefined, map: { inline: false } }); + } + + /** + * Compiles SCSS to CSS and processes it using PostCSS. + * @param inputFile Path to the input SCSS file. + * @param outputFile Path to the output CSS file. + * @param styleOption Style option for the output. + */ + async processStyles( + inputFile: string, + outputFile: fs.PathOrFileDescriptor, + styleOption: 'expanded' | 'compressed' + ) { + try { + + // Compile SCSS to CSS + const result = await sass.compileAsync( + inputFile, { style: styleOption } + ); + + // Process the compiled CSS with PostCSS and Autoprefixer + const processed = await this.processPostCSS( + result.css, + styleOption + ); + + // Write the processed CSS to a file + fs.writeFileSync(outputFile, processed.css); + + // Write the source map file + if (processed.map) { + fs.writeFileSync(`${outputFile}.map`, processed.map.toString()); + } + } catch (err) { + // Handle errors in the compilation or processing + console.error(`Error processing styles from ${inputFile}:`, err); + } + } +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default StyleProcessor; diff --git a/dist/ts/class/SvgPackager.ts b/dist/ts/class/SvgPackager.ts new file mode 100644 index 0000000..0803d29 --- /dev/null +++ b/dist/ts/class/SvgPackager.ts @@ -0,0 +1,229 @@ +// class/SvgPackager.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +// import * as fs from 'fs'; +import * as fs_extra from 'fs-extra'; +import { promises as fs } from 'fs'; +import * as glob from 'glob'; +import * as path from 'path'; +import { fileURLToPath } from "url"; +import SVGO from 'svgo'; +import { loadConfig } from 'svgo'; + +// Convert the current file's URL to a file path +const __filename = fileURLToPath(import.meta.url); + +// Derive the directory name of the current module +const __dirname = path.dirname(__filename); + +// ============================================================================ +// Classes +// ============================================================================ + +/** + * Class for packaging SVG files. + * This class reads SVG files from a specified directory, optimizes them, + * and creates corresponding TypeScript files. + */ +class SvgPackager { + + /** + * Processes all SVG files in a given directory. + * @param directory The directory containing SVG files to process. + * @param outputDirectory The directory where optimized SVGs will be output as TypeScript files. + */ + public async processSvgFiles( + directory: string, + outputDirectory: string, + ts_output_directory: string, + json_output_directory: string, + ): Promise { + + const iconNames: string[] = []; + + try { + console.log(`Processing directory: ${directory}`); + + const svgFiles = glob.sync(`${directory}/**/*.svg`); + + for (const file of svgFiles) { + console.log(`Processing file: ${file}`); + const iconName = this.sanitizeFileName(path.basename(file, '.svg')); + iconNames.push(iconName); + console.log(`Processing icon: ${iconName}`); + const svgContent = await this.readSvgFile(file); + const optimizedSvg = await this.optimizeSvg(file, svgContent); + // svgo will always add a final newline when in pretty mode + const resultSvg = optimizedSvg.trim() + // Write the optimized SVG file + await this.writeSvgFile( + file, + iconName, + resultSvg, + outputDirectory + ); + // Write the optimized TypeScript file + await this.writeTypeScriptFile( + file, + iconName, + resultSvg, + ts_output_directory + ); + } + await this.writeIconsJson(iconNames, json_output_directory); + console.log(`Successfully processed ${svgFiles.length} SVG files.`); + } catch (error) { + console.error('Error processing SVG files:', error); + throw error; + } + } + + /** + * Reads the content of an SVG file. + * @param filePath The path to the SVG file. + * @returns The content of the SVG file. + */ + private async readSvgFile(filePath: string): Promise { + try { + const absolutePath = path.resolve(filePath); + const svgContent = await fs.readFile(absolutePath, 'utf8'); + return svgContent; + } catch (error) { + console.error('Error reading file:', filePath, error); + throw error; + } + } + + /** + * Sanitizes a file name to be a valid TypeScript identifier. + * @param fileName The original file name. + * @returns A sanitized version of the file name. + */ + private sanitizeFileName(fileName: string): string { + // Implement more robust sanitization logic if necessary + return fileName.replace(/[^a-zA-Z0-9_]/g, '_'); + } + + /** + * Optimizes SVG content using SVGO. + * @param svgContent The raw SVG content. + * @returns The optimized SVG content. + */ + private async optimizeSvg( + filePath: string, + svgContent: string + ): Promise { + + try { + + const config = await loadConfig( + path.join(__dirname, '../config/svgo.config.js') + ) + + const result = await SVGO.optimize( + svgContent, + { path: filePath, ...config } // Add SVGO options if needed + ); + + return result.data; + } catch (error) { + console.error('Error optimizing SVG:', error); + throw error; + } + } + + /** + * Creates a TypeScript file from SVG content. + * @param filePath The path of the SVG file. + * @param svgContent The optimized SVG content. + * @param outputDirectory The directory to output the TypeScript file. + */ + private async writeTypeScriptFile( + filePath: string, + iconName: string, + svgContent: string, + outputDirectory: string + ): Promise { + try { + const tsContent = `export const icon_${iconName} = \`${svgContent}\`;\n`; + const outputPath = path.join(outputDirectory, `${iconName}.ts`); + await fs_extra.outputFile(outputPath, tsContent); + } catch (error) { + console.error(`Error creating TypeScript file for ${filePath}:`, error); + throw error; + } + } + + /** + * Writes the SVG content to a file. + * @param filePath The original file path of the SVG. + * @param svgContent The SVG content to be written. + * @param outputDirectory The directory to output the SVG file. + */ + private async writeSvgFile( + filePath: string, + iconName: string, + svgContent: string, + outputDirectory: string + ): Promise { + try { + const outputPath = path.join(outputDirectory, `${iconName}.svg`); + await fs_extra.outputFile(outputPath, svgContent); + console.log(`SVG file written successfully for ${iconName}`); + } catch (error) { + console.error(`Error writing SVG file for ${iconName}:`, error); + throw error; + } + } + + /** + * Writes a JSON file containing the names of processed icons. + * This method creates a JSON file that lists all icon names which have + * been processed, making it easier to reference or index these icons in + * other parts of an application. + * + * @param iconNames An array of strings containing the names of the icons. + * @param outputDirectory The directory where the JSON file will be saved. + */ + private async writeIconsJson( + iconNames: string[], + outputDirectory: string + ): Promise { + + try { + const jsonContent = JSON.stringify(iconNames, null, 2); + const outputPath = path.join(outputDirectory, 'icons.json'); + await fs_extra.outputFile(outputPath, jsonContent); + console.log('Icons JSON file created successfully'); + } catch (error) { + console.error('Error writing icons JSON file:', error); + throw error; + } + } + +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default SvgPackager; diff --git a/dist/ts/class/SvgSpriteGenerator.ts b/dist/ts/class/SvgSpriteGenerator.ts new file mode 100644 index 0000000..4e00225 --- /dev/null +++ b/dist/ts/class/SvgSpriteGenerator.ts @@ -0,0 +1,99 @@ +// class/SvgSpriteGenerator.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +import svgSprite from 'svg-sprite'; +import fs from 'fs'; +import path from 'path'; + + +// ============================================================================ +// Classes +// ============================================================================ + +/** + * A class for generating SVG sprites from individual SVG files. + */ +class SvgSpriteGenerator { + + private config: any; + + /** + * Constructs an instance of SvgSpriteGenerator with the provided configuration. + * @param {any} config - Configuration object for svg-sprite. + */ + constructor(config: any) { + this.config = config; + } + + /** + * Generates an SVG sprite from SVG files in a specified directory. + * @param {string} sourceDir - Directory containing source SVG files. + * @param {string} outputDir - Directory where the generated sprite will be saved. + */ + async generateSprite(sourceDir: string, outputDir: string) { + try { + const files = fs.readdirSync(sourceDir); + const sprite = new svgSprite(this.config); + + files.forEach(file => { + if (path.extname(file) === '.svg') { + const svgPath = path.resolve(sourceDir, file); + const content = fs.readFileSync(svgPath, 'utf8'); + sprite.add(svgPath, null, content); + } + }); + + sprite.compile((error, result) => { + if (error) { + throw error; + } + + for (const mode in result) { + for (const resource in result[mode]) { + const outputPath = path.resolve( + outputDir, + result[mode][resource].path + ); + fs.mkdirSync( + path.dirname(outputPath), + { recursive: true } + ); + fs.writeFileSync( + outputPath, + result[mode][resource].contents + ); + } + } + }); + + } catch (err) { + console.error('Error generating SVG sprite:', err); + } + } + +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default SvgSpriteGenerator; diff --git a/dist/ts/class/TypeScriptCompiler.ts b/dist/ts/class/TypeScriptCompiler.ts new file mode 100644 index 0000000..8d58683 --- /dev/null +++ b/dist/ts/class/TypeScriptCompiler.ts @@ -0,0 +1,112 @@ +// class/TypeScriptCompiler.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +// import * as ts from 'typescript'; +import ts from 'typescript'; + + +// ============================================================================ +// Classes +// ============================================================================ + +/** + * TypeScriptCompiler class for compiling TypeScript files to JavaScript. + */ + class TypeScriptCompiler { + + private config: any; + + /** + * Constructs an instance with the provided configuration. + * @param {any} config - Configuration object + */ + constructor(config: any) { + this.config = config; + } + + /** + * Compiles TypeScript files to JavaScript. + * + * @param {string[]} filePaths - The paths of TypeScript files to be compiled. + * @param {string} outDir - The directory where the compiled JavaScript files will be saved. + * @param {ts.CompilerOptions} customOptions - Optional custom TypeScript compiler options. + * + * This method sets up a TypeScript program with given file paths and compiler options. + * It handles the compilation of TypeScript files into JavaScript, considering any provided custom options. + * Compilation errors and diagnostics are logged for debugging purposes. + * The method returns a promise that resolves when compilation is successful or rejects in case of errors. + */ + compile( + filePaths: string[], + outDir: string, + // customOptions: ts.CompilerOptions = {} + ): Promise { + return new Promise((resolve, reject) => { + + // Merge default options with custom options + const options: ts.CompilerOptions = { + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES2015, + outDir, + // ...customOptions, // Merges custom compiler options + ...this.config, // Merges custom compiler options + }; + + // Create a TypeScript compiler host + const host = ts.createCompilerHost(options); + + // Create a program with the specified files and options + const program = ts.createProgram(filePaths, options, host); + + // Emit the compiled JavaScript files + const emitResult = program.emit(); + + // Check for compilation errors + const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); + allDiagnostics.forEach(diagnostic => { + // Handle and print diagnostics + if (diagnostic.file) { + const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); + const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); + console.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); + } else { + console.error(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')); + } + }); + + const exitCode = emitResult.emitSkipped ? 1 : 0; + if (exitCode === 0) { + console.log('Compilation completed successfully.'); + resolve(); + } else { + console.error('Compilation failed.'); + reject(new Error('TypeScript compilation failed')); + } + }); + } +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default TypeScriptCompiler; diff --git a/dist/ts/class/VersionWriter.ts b/dist/ts/class/VersionWriter.ts new file mode 100644 index 0000000..9eda588 --- /dev/null +++ b/dist/ts/class/VersionWriter.ts @@ -0,0 +1,57 @@ +// class/VersionWriter.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +import { promises as fs } from 'fs'; + + +// ============================================================================ +// Classes +// ============================================================================ + +/** + * A class for writing version information to a file. + */ + class VersionWriter { + + /** + * Writes the specified version string to a file. + * @param {string} filePath - The file path where the version will be written. + * @param {string} version - The version string to write to the file. + */ + async writeVersionToFile( + filePath: string, + version: string, + ): Promise { + try { + await fs.writeFile(filePath, version, 'utf8'); + console.log(`Version ${version} written to ${filePath}`); + } catch (error) { + console.error(`Error writing version to file: ${error}`); + } + } +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default VersionWriter; diff --git a/dist/ts/index.ts b/dist/ts/index.ts index 569d70d..5f6da8b 100644 --- a/dist/ts/index.ts +++ b/dist/ts/index.ts @@ -28,14 +28,14 @@ import FileCopier from './class/FileCopier'; import FileRenamer from './class/FileRenamer'; // // Import | Internal Classes -// import FontGenerator from './class/FontGenerator.js'; -// import PackageCreator from './class/PackageCreator.js'; -// import SvgPackager from "./class/SvgPackager.js"; -// import StyleProcessor from "./class/StyleProcessor.js"; -// import SvgSpriteGenerator from "./class/SvgSpriteGenerator.js"; -// import VersionWriter from './class/VersionWriter.js'; -// import TypeScriptCompiler from './class/TypeScriptCompiler.js'; -// import JavaScriptMinifier from './class/JavaScriptMinifier.js'; +import FontGenerator from './class/FontGenerator.js'; +import PackageCreator from './class/PackageCreator.js'; +import SvgPackager from "./class/SvgPackager.js"; +import StyleProcessor from "./class/StyleProcessor.js"; +import SvgSpriteGenerator from "./class/SvgSpriteGenerator.js"; +import VersionWriter from './class/VersionWriter.js'; +import TypeScriptCompiler from './class/TypeScriptCompiler.js'; +import JavaScriptMinifier from './class/JavaScriptMinifier.js'; // // Import | Cconfigurations // import { CONFIG } from './config/config.js'; @@ -59,12 +59,12 @@ export { FileRenamer, // // Export | Internal Classes - // FontGenerator, - // PackageCreator, - // SvgPackager, - // StyleProcessor, - // SvgSpriteGenerator, - // VersionWriter, - // TypeScriptCompiler, - // JavaScriptMinifier, + FontGenerator, + PackageCreator, + SvgPackager, + StyleProcessor, + SvgSpriteGenerator, + VersionWriter, + TypeScriptCompiler, + JavaScriptMinifier, }; diff --git a/dist/ts/interfaces/File.ts b/dist/ts/interface/File.ts similarity index 64% rename from dist/ts/interfaces/File.ts rename to dist/ts/interface/File.ts index 4f47dc8..14e2f7d 100644 --- a/dist/ts/interfaces/File.ts +++ b/dist/ts/interface/File.ts @@ -1,4 +1,4 @@ -interface File { +export interface File { filepath: string; source: string; } \ No newline at end of file diff --git a/src/ts/interfaces/PackageJson.ts b/dist/ts/interface/PackageJson.ts similarity index 98% rename from src/ts/interfaces/PackageJson.ts rename to dist/ts/interface/PackageJson.ts index 15078de..6e56cb2 100644 --- a/src/ts/interfaces/PackageJson.ts +++ b/dist/ts/interface/PackageJson.ts @@ -2,7 +2,7 @@ // Interfaces // ============================================================================ -interface PackageJson { +export interface PackageJson { name: string; version: string; description?: string; diff --git a/src/ts/interfaces/SVG.ts b/dist/ts/interface/SVG.ts similarity index 91% rename from src/ts/interfaces/SVG.ts rename to dist/ts/interface/SVG.ts index 6067064..f9a25fc 100644 --- a/src/ts/interfaces/SVG.ts +++ b/dist/ts/interface/SVG.ts @@ -2,7 +2,7 @@ // Assuming the structure of your SVG object, you might need to adjust these types -interface Svg { +export interface Svg { metadata: { name: string; // ... other metadata properties diff --git a/package.json b/package.json index a4c65c1..4de222c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pack.gl", "description": "Package Builder.", - "version": "0.0.7", + "version": "0.0.8", "config": { "version_short": "0.0" }, diff --git a/src/ts/class/FontGenerator.ts b/src/ts/class/FontGenerator.ts new file mode 100644 index 0000000..1c45671 --- /dev/null +++ b/src/ts/class/FontGenerator.ts @@ -0,0 +1,136 @@ +// class/FontGenerator.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +import { generateFonts, FontAssetType, OtherAssetType } from 'fantasticon'; + + +// ============================================================================ +// Classes +// ============================================================================ + +class FontGenerator { + + async generateFonts( + sourceDirectory: string, + outputDiectory: string, + ) { + + const config = { + + + // RunnerMandatoryOptions + inputDir: sourceDirectory, // (required) + outputDir: outputDiectory, // (required) + + // RunnerOptionalOptions + name: 'icon.gl', + fontTypes: [ + FontAssetType.TTF, // TTF = "ttf" + FontAssetType.WOFF, // WOFF = "woff" + FontAssetType.WOFF2, // WOFF2 = "woff2" + FontAssetType.EOT, // EOT = "eot" + FontAssetType.SVG, // SVG = "svg" + ], + assetTypes: [ + OtherAssetType.CSS, // CSS = "css", + OtherAssetType.SCSS, // SCSS = "scss", + OtherAssetType.SASS, // SASS = "sass", + OtherAssetType.HTML, // HTML = "html", + OtherAssetType.JSON, // JSON = "json", + OtherAssetType.TS, // TS = "ts" + ], + + + + formatOptions: { + // woff: { + // // Woff Extended Metadata Block - see https://www.w3.org/TR/WOFF/#Metadata + // metadata: '...' + // }, + // ttf?: TtfOptions; // type TtfOptions = svg2ttf.FontOptions; + // svg?: SvgOptions; // type SvgOptions = Omit; + json: { indent: 4 } , + // ts: { + // // select what kind of types you want to generate + // // (default `['enum', 'constant', 'literalId', 'literalKey']`) + // types: ['enum', 'constant', 'literalId', 'literalKey'], + // // render the types with `'` instead of `"` (default is `"`) + // singleQuotes: false, + // // customise names used for the generated types and constants + // enumName: 'icon_gl', + // constantName: 'MY_CODEPOINTS' + // // literalIdName: 'IconId', + // // literalKeyName: 'IconKey' + // } + }, + pathOptions: { + json: './dist/font/icon.gl.json', + css: './dist/font/icon.gl.css', + scss: './dist/font/icon.gl.scss', + woff: './dist/font/icon.gl.woff', + woff2: './dist/font/icon.gl.woff2', + }, + // codepoints: { + // 'chevron-left': 57344, // decimal representation of 0xe000 + // 'chevron-right': 57345, + // 'thumbs-up': 57358, + // 'thumbs-down': 57359, + // }, + // fontHeight: number; + // descent: number; + // normalize: boolean; + // round: number; + selector: '.igl', + // tag: string; + // Use our custom Handlebars templates + // templates: { + // css: './build/font/icon.gl.css.hbs', + // scss: './build/font/icon.gl.scss.hbs' + // }, + prefix: 'igl', + fontsUrl: './fonts', + + // Customize generated icon IDs (unavailable with `.json` config file) + // getIconId: ({ + // basename, // `string` - Example: 'foo'; + // relativeDirPath, // `string` - Example: 'sub/dir/foo.svg' + // absoluteFilePath, // `string` - Example: '/var/icons/sub/dir/foo.svg' + // relativeFilePath, // `string` - Example: 'foo.svg' + // index // `number` - Example: `0` + // }) => [index, basename].join('_') // '0_foo' + + }; + + try { + await generateFonts(config); + console.log('Fonts generated successfully.'); + } catch (error) { + console.error('Error generating fonts:', error); + } + } +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default FontGenerator; diff --git a/src/ts/class/JavaScriptMinifier.ts b/src/ts/class/JavaScriptMinifier.ts new file mode 100644 index 0000000..9cc485f --- /dev/null +++ b/src/ts/class/JavaScriptMinifier.ts @@ -0,0 +1,82 @@ +// class/JavaScriptMinifier.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +import { minify } from 'terser'; +import { promises as fs } from 'fs'; + + +// ============================================================================ +// Classes +// ============================================================================ + +/** + * Class to minify JavaScript files using Terser. + */ + class JavaScriptMinifier { + + private config: any; + + /** + * Constructs an instance with the provided configuration. + * @param {any} config - Configuration object - minification options for Terser. + */ + constructor(config: any) { + this.config = config; + } + + /** + * Minifies a JavaScript file. + * @param {string} inputPath - Path to the input JavaScript file. + * @param {string} outputPath - Path to save the minified output file. + * @returns {Promise} - A promise that resolves when minification is complete. + */ + async minifyFile( + inputPath: string, + outputPath: string, + // options: object = {} + ): Promise { + + try { + // Read the input file + const inputCode = await fs.readFile(inputPath, 'utf8'); + // Minify the file using Terser + // const result = await minify(inputCode, options); + const result = await minify(inputCode, this.config); + // If minification is successful, write the output + if (result.code) { + await fs.writeFile(outputPath, result.code); + } else { + throw new Error('Minification resulted in empty output.'); + } + } catch (error) { + console.error(`Error minifying JavaScript file ${inputPath}:`, error); + throw error; + } + } + +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default JavaScriptMinifier; diff --git a/src/ts/class/PackageCreator.ts b/src/ts/class/PackageCreator.ts new file mode 100644 index 0000000..9c87cd8 --- /dev/null +++ b/src/ts/class/PackageCreator.ts @@ -0,0 +1,65 @@ +// class/PackageCreator.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +import fs from 'fs'; +import path from 'path'; +// import * as pack from '../../package.json' assert { type: 'json' }; +import { PackageJson } from '../interface/PackageJson.js' + +// ============================================================================ +// Classes +// ============================================================================ + +/** + * A class for creating a package.json file for a project. + */ + class PackageCreator { + + private packageJson: PackageJson; + + /** + * Initializes a new instance of the PackageCreator class. + * @param {PackageJson} packageJson - The content to be written into package.json. + */ + constructor(packageJson: PackageJson) { + this.packageJson = packageJson; + } + + /** + * Creates a package.json file in the specified directory. + * @param {string} outputDir - The directory where package.json will be created. + */ + async createPackageJson(outputDir: string): Promise { + const filePath = path.join(outputDir, 'package.json'); + const data = JSON.stringify(this.packageJson, null, 2); + + fs.writeFileSync(filePath, data, 'utf-8'); + console.log(`package.json created at ${filePath}`); + } + +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default PackageCreator; \ No newline at end of file diff --git a/src/ts/class/StyleProcessor.ts b/src/ts/class/StyleProcessor.ts new file mode 100644 index 0000000..ce8c781 --- /dev/null +++ b/src/ts/class/StyleProcessor.ts @@ -0,0 +1,98 @@ +// class/StyleProcessor.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +import * as sass from 'sass' +import postcss from 'postcss'; +import fs from 'fs'; +import { promises as fsPromises } from 'fs'; + +import postcssConfigExpanded from '../config/postcss.config.expanded.js'; +import postcssConfigCompressed from '../config/postcss.config.compressed.js'; + + +// ============================================================================ +// Classes +// ============================================================================ + +/** + * Class responsible for processing styles, including compiling SCSS and + * applying PostCSS transformations. + */ +class StyleProcessor { + + /** + * Processes the given CSS with PostCSS based on the provided style option. + * @param css The CSS string to process. + * @param styleOption The style option, either 'expanded' or 'compressed'. + * @returns Processed CSS string. + */ + async processPostCSS( + css: string, + styleOption: 'expanded' | 'compressed' + ) { + const config = styleOption === 'expanded' ? postcssConfigExpanded : postcssConfigCompressed; + return postcss(config.plugins).process(css, { from: undefined, map: { inline: false } }); + } + + /** + * Compiles SCSS to CSS and processes it using PostCSS. + * @param inputFile Path to the input SCSS file. + * @param outputFile Path to the output CSS file. + * @param styleOption Style option for the output. + */ + async processStyles( + inputFile: string, + outputFile: fs.PathOrFileDescriptor, + styleOption: 'expanded' | 'compressed' + ) { + try { + + // Compile SCSS to CSS + const result = await sass.compileAsync( + inputFile, { style: styleOption } + ); + + // Process the compiled CSS with PostCSS and Autoprefixer + const processed = await this.processPostCSS( + result.css, + styleOption + ); + + // Write the processed CSS to a file + fs.writeFileSync(outputFile, processed.css); + + // Write the source map file + if (processed.map) { + fs.writeFileSync(`${outputFile}.map`, processed.map.toString()); + } + } catch (err) { + // Handle errors in the compilation or processing + console.error(`Error processing styles from ${inputFile}:`, err); + } + } +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default StyleProcessor; diff --git a/src/ts/class/SvgPackager.ts b/src/ts/class/SvgPackager.ts new file mode 100644 index 0000000..0803d29 --- /dev/null +++ b/src/ts/class/SvgPackager.ts @@ -0,0 +1,229 @@ +// class/SvgPackager.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +// import * as fs from 'fs'; +import * as fs_extra from 'fs-extra'; +import { promises as fs } from 'fs'; +import * as glob from 'glob'; +import * as path from 'path'; +import { fileURLToPath } from "url"; +import SVGO from 'svgo'; +import { loadConfig } from 'svgo'; + +// Convert the current file's URL to a file path +const __filename = fileURLToPath(import.meta.url); + +// Derive the directory name of the current module +const __dirname = path.dirname(__filename); + +// ============================================================================ +// Classes +// ============================================================================ + +/** + * Class for packaging SVG files. + * This class reads SVG files from a specified directory, optimizes them, + * and creates corresponding TypeScript files. + */ +class SvgPackager { + + /** + * Processes all SVG files in a given directory. + * @param directory The directory containing SVG files to process. + * @param outputDirectory The directory where optimized SVGs will be output as TypeScript files. + */ + public async processSvgFiles( + directory: string, + outputDirectory: string, + ts_output_directory: string, + json_output_directory: string, + ): Promise { + + const iconNames: string[] = []; + + try { + console.log(`Processing directory: ${directory}`); + + const svgFiles = glob.sync(`${directory}/**/*.svg`); + + for (const file of svgFiles) { + console.log(`Processing file: ${file}`); + const iconName = this.sanitizeFileName(path.basename(file, '.svg')); + iconNames.push(iconName); + console.log(`Processing icon: ${iconName}`); + const svgContent = await this.readSvgFile(file); + const optimizedSvg = await this.optimizeSvg(file, svgContent); + // svgo will always add a final newline when in pretty mode + const resultSvg = optimizedSvg.trim() + // Write the optimized SVG file + await this.writeSvgFile( + file, + iconName, + resultSvg, + outputDirectory + ); + // Write the optimized TypeScript file + await this.writeTypeScriptFile( + file, + iconName, + resultSvg, + ts_output_directory + ); + } + await this.writeIconsJson(iconNames, json_output_directory); + console.log(`Successfully processed ${svgFiles.length} SVG files.`); + } catch (error) { + console.error('Error processing SVG files:', error); + throw error; + } + } + + /** + * Reads the content of an SVG file. + * @param filePath The path to the SVG file. + * @returns The content of the SVG file. + */ + private async readSvgFile(filePath: string): Promise { + try { + const absolutePath = path.resolve(filePath); + const svgContent = await fs.readFile(absolutePath, 'utf8'); + return svgContent; + } catch (error) { + console.error('Error reading file:', filePath, error); + throw error; + } + } + + /** + * Sanitizes a file name to be a valid TypeScript identifier. + * @param fileName The original file name. + * @returns A sanitized version of the file name. + */ + private sanitizeFileName(fileName: string): string { + // Implement more robust sanitization logic if necessary + return fileName.replace(/[^a-zA-Z0-9_]/g, '_'); + } + + /** + * Optimizes SVG content using SVGO. + * @param svgContent The raw SVG content. + * @returns The optimized SVG content. + */ + private async optimizeSvg( + filePath: string, + svgContent: string + ): Promise { + + try { + + const config = await loadConfig( + path.join(__dirname, '../config/svgo.config.js') + ) + + const result = await SVGO.optimize( + svgContent, + { path: filePath, ...config } // Add SVGO options if needed + ); + + return result.data; + } catch (error) { + console.error('Error optimizing SVG:', error); + throw error; + } + } + + /** + * Creates a TypeScript file from SVG content. + * @param filePath The path of the SVG file. + * @param svgContent The optimized SVG content. + * @param outputDirectory The directory to output the TypeScript file. + */ + private async writeTypeScriptFile( + filePath: string, + iconName: string, + svgContent: string, + outputDirectory: string + ): Promise { + try { + const tsContent = `export const icon_${iconName} = \`${svgContent}\`;\n`; + const outputPath = path.join(outputDirectory, `${iconName}.ts`); + await fs_extra.outputFile(outputPath, tsContent); + } catch (error) { + console.error(`Error creating TypeScript file for ${filePath}:`, error); + throw error; + } + } + + /** + * Writes the SVG content to a file. + * @param filePath The original file path of the SVG. + * @param svgContent The SVG content to be written. + * @param outputDirectory The directory to output the SVG file. + */ + private async writeSvgFile( + filePath: string, + iconName: string, + svgContent: string, + outputDirectory: string + ): Promise { + try { + const outputPath = path.join(outputDirectory, `${iconName}.svg`); + await fs_extra.outputFile(outputPath, svgContent); + console.log(`SVG file written successfully for ${iconName}`); + } catch (error) { + console.error(`Error writing SVG file for ${iconName}:`, error); + throw error; + } + } + + /** + * Writes a JSON file containing the names of processed icons. + * This method creates a JSON file that lists all icon names which have + * been processed, making it easier to reference or index these icons in + * other parts of an application. + * + * @param iconNames An array of strings containing the names of the icons. + * @param outputDirectory The directory where the JSON file will be saved. + */ + private async writeIconsJson( + iconNames: string[], + outputDirectory: string + ): Promise { + + try { + const jsonContent = JSON.stringify(iconNames, null, 2); + const outputPath = path.join(outputDirectory, 'icons.json'); + await fs_extra.outputFile(outputPath, jsonContent); + console.log('Icons JSON file created successfully'); + } catch (error) { + console.error('Error writing icons JSON file:', error); + throw error; + } + } + +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default SvgPackager; diff --git a/src/ts/class/SvgSpriteGenerator.ts b/src/ts/class/SvgSpriteGenerator.ts new file mode 100644 index 0000000..4e00225 --- /dev/null +++ b/src/ts/class/SvgSpriteGenerator.ts @@ -0,0 +1,99 @@ +// class/SvgSpriteGenerator.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +import svgSprite from 'svg-sprite'; +import fs from 'fs'; +import path from 'path'; + + +// ============================================================================ +// Classes +// ============================================================================ + +/** + * A class for generating SVG sprites from individual SVG files. + */ +class SvgSpriteGenerator { + + private config: any; + + /** + * Constructs an instance of SvgSpriteGenerator with the provided configuration. + * @param {any} config - Configuration object for svg-sprite. + */ + constructor(config: any) { + this.config = config; + } + + /** + * Generates an SVG sprite from SVG files in a specified directory. + * @param {string} sourceDir - Directory containing source SVG files. + * @param {string} outputDir - Directory where the generated sprite will be saved. + */ + async generateSprite(sourceDir: string, outputDir: string) { + try { + const files = fs.readdirSync(sourceDir); + const sprite = new svgSprite(this.config); + + files.forEach(file => { + if (path.extname(file) === '.svg') { + const svgPath = path.resolve(sourceDir, file); + const content = fs.readFileSync(svgPath, 'utf8'); + sprite.add(svgPath, null, content); + } + }); + + sprite.compile((error, result) => { + if (error) { + throw error; + } + + for (const mode in result) { + for (const resource in result[mode]) { + const outputPath = path.resolve( + outputDir, + result[mode][resource].path + ); + fs.mkdirSync( + path.dirname(outputPath), + { recursive: true } + ); + fs.writeFileSync( + outputPath, + result[mode][resource].contents + ); + } + } + }); + + } catch (err) { + console.error('Error generating SVG sprite:', err); + } + } + +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default SvgSpriteGenerator; diff --git a/src/ts/class/TypeScriptCompiler.ts b/src/ts/class/TypeScriptCompiler.ts new file mode 100644 index 0000000..8d58683 --- /dev/null +++ b/src/ts/class/TypeScriptCompiler.ts @@ -0,0 +1,112 @@ +// class/TypeScriptCompiler.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +// import * as ts from 'typescript'; +import ts from 'typescript'; + + +// ============================================================================ +// Classes +// ============================================================================ + +/** + * TypeScriptCompiler class for compiling TypeScript files to JavaScript. + */ + class TypeScriptCompiler { + + private config: any; + + /** + * Constructs an instance with the provided configuration. + * @param {any} config - Configuration object + */ + constructor(config: any) { + this.config = config; + } + + /** + * Compiles TypeScript files to JavaScript. + * + * @param {string[]} filePaths - The paths of TypeScript files to be compiled. + * @param {string} outDir - The directory where the compiled JavaScript files will be saved. + * @param {ts.CompilerOptions} customOptions - Optional custom TypeScript compiler options. + * + * This method sets up a TypeScript program with given file paths and compiler options. + * It handles the compilation of TypeScript files into JavaScript, considering any provided custom options. + * Compilation errors and diagnostics are logged for debugging purposes. + * The method returns a promise that resolves when compilation is successful or rejects in case of errors. + */ + compile( + filePaths: string[], + outDir: string, + // customOptions: ts.CompilerOptions = {} + ): Promise { + return new Promise((resolve, reject) => { + + // Merge default options with custom options + const options: ts.CompilerOptions = { + module: ts.ModuleKind.CommonJS, + target: ts.ScriptTarget.ES2015, + outDir, + // ...customOptions, // Merges custom compiler options + ...this.config, // Merges custom compiler options + }; + + // Create a TypeScript compiler host + const host = ts.createCompilerHost(options); + + // Create a program with the specified files and options + const program = ts.createProgram(filePaths, options, host); + + // Emit the compiled JavaScript files + const emitResult = program.emit(); + + // Check for compilation errors + const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); + allDiagnostics.forEach(diagnostic => { + // Handle and print diagnostics + if (diagnostic.file) { + const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); + const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); + console.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); + } else { + console.error(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')); + } + }); + + const exitCode = emitResult.emitSkipped ? 1 : 0; + if (exitCode === 0) { + console.log('Compilation completed successfully.'); + resolve(); + } else { + console.error('Compilation failed.'); + reject(new Error('TypeScript compilation failed')); + } + }); + } +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default TypeScriptCompiler; diff --git a/src/ts/class/VersionWriter.ts b/src/ts/class/VersionWriter.ts new file mode 100644 index 0000000..9eda588 --- /dev/null +++ b/src/ts/class/VersionWriter.ts @@ -0,0 +1,57 @@ +// class/VersionWriter.ts + +// Copyright 2023 Scape Agency BV + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// ============================================================================ +// Import +// ============================================================================ + +import { promises as fs } from 'fs'; + + +// ============================================================================ +// Classes +// ============================================================================ + +/** + * A class for writing version information to a file. + */ + class VersionWriter { + + /** + * Writes the specified version string to a file. + * @param {string} filePath - The file path where the version will be written. + * @param {string} version - The version string to write to the file. + */ + async writeVersionToFile( + filePath: string, + version: string, + ): Promise { + try { + await fs.writeFile(filePath, version, 'utf8'); + console.log(`Version ${version} written to ${filePath}`); + } catch (error) { + console.error(`Error writing version to file: ${error}`); + } + } +} + + +// ============================================================================ +// Export +// ============================================================================ + +export default VersionWriter; diff --git a/src/ts/index.ts b/src/ts/index.ts index 569d70d..5f6da8b 100644 --- a/src/ts/index.ts +++ b/src/ts/index.ts @@ -28,14 +28,14 @@ import FileCopier from './class/FileCopier'; import FileRenamer from './class/FileRenamer'; // // Import | Internal Classes -// import FontGenerator from './class/FontGenerator.js'; -// import PackageCreator from './class/PackageCreator.js'; -// import SvgPackager from "./class/SvgPackager.js"; -// import StyleProcessor from "./class/StyleProcessor.js"; -// import SvgSpriteGenerator from "./class/SvgSpriteGenerator.js"; -// import VersionWriter from './class/VersionWriter.js'; -// import TypeScriptCompiler from './class/TypeScriptCompiler.js'; -// import JavaScriptMinifier from './class/JavaScriptMinifier.js'; +import FontGenerator from './class/FontGenerator.js'; +import PackageCreator from './class/PackageCreator.js'; +import SvgPackager from "./class/SvgPackager.js"; +import StyleProcessor from "./class/StyleProcessor.js"; +import SvgSpriteGenerator from "./class/SvgSpriteGenerator.js"; +import VersionWriter from './class/VersionWriter.js'; +import TypeScriptCompiler from './class/TypeScriptCompiler.js'; +import JavaScriptMinifier from './class/JavaScriptMinifier.js'; // // Import | Cconfigurations // import { CONFIG } from './config/config.js'; @@ -59,12 +59,12 @@ export { FileRenamer, // // Export | Internal Classes - // FontGenerator, - // PackageCreator, - // SvgPackager, - // StyleProcessor, - // SvgSpriteGenerator, - // VersionWriter, - // TypeScriptCompiler, - // JavaScriptMinifier, + FontGenerator, + PackageCreator, + SvgPackager, + StyleProcessor, + SvgSpriteGenerator, + VersionWriter, + TypeScriptCompiler, + JavaScriptMinifier, }; diff --git a/src/ts/interfaces/File.ts b/src/ts/interface/File.ts similarity index 64% rename from src/ts/interfaces/File.ts rename to src/ts/interface/File.ts index 4f47dc8..14e2f7d 100644 --- a/src/ts/interfaces/File.ts +++ b/src/ts/interface/File.ts @@ -1,4 +1,4 @@ -interface File { +export interface File { filepath: string; source: string; } \ No newline at end of file diff --git a/dist/ts/interfaces/PackageJson.ts b/src/ts/interface/PackageJson.ts similarity index 98% rename from dist/ts/interfaces/PackageJson.ts rename to src/ts/interface/PackageJson.ts index 15078de..6e56cb2 100644 --- a/dist/ts/interfaces/PackageJson.ts +++ b/src/ts/interface/PackageJson.ts @@ -2,7 +2,7 @@ // Interfaces // ============================================================================ -interface PackageJson { +export interface PackageJson { name: string; version: string; description?: string; diff --git a/dist/ts/interfaces/SVG.ts b/src/ts/interface/SVG.ts similarity index 91% rename from dist/ts/interfaces/SVG.ts rename to src/ts/interface/SVG.ts index 6067064..f9a25fc 100644 --- a/dist/ts/interfaces/SVG.ts +++ b/src/ts/interface/SVG.ts @@ -2,7 +2,7 @@ // Assuming the structure of your SVG object, you might need to adjust these types -interface Svg { +export interface Svg { metadata: { name: string; // ... other metadata properties