@node-minify/utils
Version:
utils for @node-minify
1 lines • 10.7 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/*!\n * node-minify\n * Copyright(c) 2011-2024 Rodolphe Stoclin\n * MIT Licensed\n */\n\n/**\n * Module dependencies.\n */\nimport {\n createReadStream,\n existsSync,\n lstatSync,\n readFileSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport type {\n MinifierOptions,\n OptionsPossible,\n Settings,\n} from \"@node-minify/types\";\nimport gzipSize from \"gzip-size\";\n\ntype Utils = {\n readFile: (file: string) => string;\n writeFile: ({ file, content, index }: WriteFile) => string;\n deleteFile: (file: string) => void;\n buildArgs: (options: Record<string, OptionsPossible>) => any;\n clone: (obj: object) => object;\n getFilesizeInBytes: (file: string) => string;\n getFilesizeGzippedInBytes: (file: string) => Promise<string>;\n prettyBytes: (num: number) => string;\n setFileNameMin: (\n file: string,\n output: string,\n publicFolder?: string,\n replaceInPlace?: boolean\n ) => string;\n compressSingleFile: (settings: Settings) => string | Promise<string>;\n getContentFromFiles: (input: string | string[]) => string;\n runSync: ({ settings, content, index }: MinifierOptions) => string;\n runAsync: ({\n settings,\n content,\n index,\n }: MinifierOptions) => Promise<string>;\n};\n\ntype WriteFile = {\n file: string;\n content: any;\n index?: number;\n};\n\nconst utils = {} as Utils;\n\n/**\n * Read content from file.\n * @param file File name\n */\nutils.readFile = (file: string): string => readFileSync(file, \"utf8\");\n\n/**\n * Write content into file.\n * @param file File name\n * @param content Content to write\n * @param index Index of the file being processed\n */\nutils.writeFile = ({ file, content, index }: WriteFile): string => {\n const _file = index !== undefined ? file[index] : file;\n if (\n !existsSync(_file) ||\n (existsSync(_file) && !lstatSync(_file).isDirectory())\n ) {\n writeFileSync(_file, content, \"utf8\");\n }\n\n return content;\n};\n\n/**\n * Delete file.\n * @param file File name\n */\nutils.deleteFile = (file: string) => unlinkSync(file);\n\n/**\n * Builds arguments array based on an object.\n * @param options\n */\nutils.buildArgs = (\n options: Record<string, OptionsPossible>\n): OptionsPossible[] => {\n const args: OptionsPossible[] = [];\n Object.keys(options).forEach((key: string) => {\n if (options[key] && (options[key] as unknown) !== false) {\n args.push(`--${key}`);\n }\n\n if (options[key] && options[key] !== true) {\n args.push(options[key]);\n }\n });\n\n return args;\n};\n\n/**\n * Clone an object.\n * @param obj Object\n */\nutils.clone = (obj: object): object => JSON.parse(JSON.stringify(obj));\n\n/**\n * Get the file size in bytes.\n * @param file File name\n */\nutils.getFilesizeInBytes = (file: string): string => {\n const stats = statSync(file);\n const fileSizeInBytes = stats.size;\n return utils.prettyBytes(fileSizeInBytes);\n};\n\n/**\n * Get the gzipped file size in bytes.\n * @param file File name\n */\nutils.getFilesizeGzippedInBytes = (file: string): Promise<string> => {\n return new Promise((resolve) => {\n const source = createReadStream(file);\n source.pipe(gzipSize.stream()).on(\"gzip-size\", (size) => {\n resolve(utils.prettyBytes(size));\n });\n });\n};\n\n/**\n * Get the size in human readable.\n * From https://github.com/sindresorhus/pretty-bytes\n * @param num Number\n */\nutils.prettyBytes = (num: number): string => {\n const UNITS = [\"B\", \"kB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"];\n\n if (!Number.isFinite(num)) {\n throw new TypeError(\n `Expected a finite number, got ${typeof num}: ${num}`\n );\n }\n\n const neg = num < 0;\n\n if (neg) {\n num = -num;\n }\n\n if (num < 1) {\n return `${(neg ? \"-\" : \"\") + num} B`;\n }\n\n const exponent = Math.min(\n Math.floor(Math.log(num) / Math.log(1000)),\n UNITS.length - 1\n );\n const numStr = Number((num / 1000 ** exponent).toPrecision(3));\n const unit = UNITS[exponent];\n\n return `${(neg ? \"-\" : \"\") + numStr} ${unit}`;\n};\n\n/**\n * Set the file name as minified.\n * eg. file.js returns file.min.js\n * @param file File name\n * @param output Output file name\n * @param publicFolder Public folder\n * @param replaceInPlace Replace in place\n */\nutils.setFileNameMin = (\n file: string,\n output: string,\n publicFolder?: string,\n replaceInPlace?: boolean\n): string => {\n const filePath = file.substr(0, file.lastIndexOf(\"/\") + 1);\n const fileWithoutPath = file.substr(file.lastIndexOf(\"/\") + 1);\n let fileWithoutExtension = fileWithoutPath.substr(\n 0,\n fileWithoutPath.lastIndexOf(\".\")\n );\n if (publicFolder) {\n fileWithoutExtension = publicFolder + fileWithoutExtension;\n }\n if (replaceInPlace) {\n fileWithoutExtension = filePath + fileWithoutExtension;\n }\n return output.replace(\"$1\", fileWithoutExtension);\n};\n\n/**\n * Compress a single file.\n * @param settings Settings\n */\nutils.compressSingleFile = (settings: Settings): Promise<string> | string => {\n const content = settings.content\n ? settings.content\n : settings.input\n ? utils.getContentFromFiles(settings.input)\n : \"\";\n return settings.sync\n ? utils.runSync({ settings, content })\n : utils.runAsync({ settings, content });\n};\n\n/**\n * Concatenate all input files and get the data.\n * @param input Input files\n */\nutils.getContentFromFiles = (input: string | string[]): string => {\n if (!Array.isArray(input)) {\n return readFileSync(input, \"utf8\");\n }\n\n return input\n .map((path) =>\n !existsSync(path) ||\n (existsSync(path) && !lstatSync(path).isDirectory())\n ? readFileSync(path, \"utf8\")\n : \"\"\n )\n .join(\"\\n\");\n};\n\n/**\n * Run compressor in sync.\n * @param settings Settings\n * @param content Content to minify\n * @param index Index of the file being processed\n */\nutils.runSync = ({ settings, content, index }: MinifierOptions): string =>\n settings && typeof settings.compressor !== \"string\"\n ? typeof settings.compressor === \"function\"\n ? String(\n settings.compressor({\n settings,\n content,\n callback: null,\n index,\n }) || \"\"\n )\n : \"\"\n : \"\";\n\n/**\n * Run compressor in async.\n * @param settings Settings\n * @param content Content to minify\n * @param index Index of the file being processed\n */\nutils.runAsync = ({\n settings,\n content,\n index,\n}: MinifierOptions): Promise<string> => {\n return new Promise((resolve, reject) => {\n settings?.compressor && typeof settings.compressor !== \"string\"\n ? settings.compressor({\n settings,\n content,\n callback: (err: unknown, result?: string) => {\n if (err) {\n return reject(err);\n }\n resolve(result || \"\");\n },\n index,\n })\n : null;\n });\n};\n\n/**\n * Expose `utils`.\n */\nexport { utils };\n"],"mappings":"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","names":[]}