style.min.css
Advanced tools
Comparing version 0.0.3 to 0.0.4
@@ -1,10 +0,10 @@ | ||
declare type CssLanguage = 'css' | 'scss' | 'less' | 'stylus'; | ||
export declare const CssExtensions: { | ||
css: string; | ||
scss: string[]; | ||
less: string; | ||
stylus: string; | ||
}; | ||
declare interface MinifierOptions { | ||
import { CssLanguage, MinifierOptions } from './lib/minify'; | ||
export declare interface OnErrorOptions { | ||
/** | ||
* Call function when an exception occurs | ||
*/ | ||
onError?: (err: Error) => void; | ||
} | ||
export declare interface LanguageOptions { | ||
/** | ||
* Use if the input is use a different CSS | ||
@@ -15,66 +15,129 @@ * language such as SCSS | ||
*/ | ||
lang?: CssLanguage; | ||
lang?: CssLanguage | 'auto'; | ||
} | ||
export declare interface MinifierResult { | ||
/** | ||
* Set `true` if comments may be keept | ||
* | ||
* ```css | ||
* a { color: blue; (I cant use css comments here) } /* => a{color:blue} | ||
* | ||
* @default false | ||
* The CSS output | ||
*/ | ||
comments?: boolean; | ||
code: string; | ||
} | ||
export declare interface WatchOptions { | ||
/** | ||
* Set `true` for remove zero unit | ||
* | ||
* ```css | ||
* a { margin: 0rem; } /* => a{margin:0} | ||
* ``` | ||
* | ||
* @default true | ||
* The input dir to watch for changes (recursive) | ||
*/ | ||
removeZeroUnits?: boolean; | ||
dir: string; | ||
/** | ||
* Define if empty selectors block are | ||
* deleted (useless if you use SCSS, | ||
* node-sass auto remove theses) | ||
* Pattern for check file name (require only one match), if file name dont match, | ||
* changes are ignored. It can be a array of RegExp or a function that accept only | ||
* one argument, the file name to check and returns a boolean | ||
* | ||
* ```css | ||
* a { } /* => nothing | ||
* ``` | ||
* | ||
* @default true | ||
* @param file The file name to check | ||
* @returns `true` if file name match | ||
*/ | ||
removeEmpty?: boolean; | ||
} | ||
declare interface OnErrorOptions { | ||
onError?: (err: Error) => void; | ||
} | ||
declare interface MinifierResult { | ||
code: string; | ||
} | ||
declare interface WatchOptions { | ||
dir: string; | ||
pattern?: RegExp[] | ((file: string) => boolean); | ||
/** | ||
* The output dir for place file after minimization | ||
*/ | ||
outDir: string; | ||
/** | ||
* Call for set file name in destination | ||
* | ||
* @param file The input file name | ||
* @returns The output file name (may ends with `.css`) | ||
*/ | ||
outPattern?: (file: string) => string; | ||
/** | ||
* Call function when a file changed | ||
*/ | ||
onChange?: (oldFile: [string, string], newFile: [string, string]) => void; | ||
/** | ||
* Set `true` for minify dir on call | ||
*/ | ||
now?: boolean; | ||
} | ||
declare interface DirectoryOptions { | ||
dir: string; | ||
export declare interface DirOptions { | ||
/** | ||
* Pattern for check file name (require only one match), if file name dont match, | ||
* file ignored. It can be a array of RegExp or a function that accept only | ||
* one argument, the file name to check and returns a boolean | ||
* | ||
* @param file The file name to check | ||
* @returns `true` if file name match | ||
*/ | ||
pattern?: RegExp[] | ((file: string) => boolean); | ||
/** | ||
* Call for set file name in destination | ||
* | ||
* @param file The input file name | ||
* @returns The output file name (may ends with `.css`) | ||
*/ | ||
outPattern?: (file: string) => string; | ||
/** | ||
* The output dir for place file after minimization | ||
*/ | ||
outDir: string; | ||
/** | ||
* Set `true` for recursively | ||
* | ||
* @default true | ||
*/ | ||
recursive?: boolean; | ||
} | ||
declare interface FileOptions { | ||
export declare interface DirectoryOptions extends DirOptions { | ||
/** | ||
* The input dir | ||
* | ||
* @default '.' | ||
*/ | ||
dir?: string; | ||
} | ||
export declare interface FileOptions { | ||
/** | ||
* The file to minify | ||
*/ | ||
file: string; | ||
/** | ||
* The output path | ||
*/ | ||
outFile: string; | ||
} | ||
declare interface SourceOptions { | ||
export declare interface SourceOptions { | ||
/** | ||
* The source string | ||
*/ | ||
source: string; | ||
/** | ||
* Used for custom languages for includes files | ||
*/ | ||
path?: string; | ||
} | ||
export declare function minify(options: MinifierOptions & SourceOptions): Promise<MinifierResult>; | ||
export declare function watch(options: MinifierOptions & WatchOptions & OnErrorOptions): void; | ||
export declare function directory(options: MinifierOptions & DirectoryOptions & OnErrorOptions): Promise<void>; | ||
export declare function file(options: MinifierOptions & FileOptions & OnErrorOptions): Promise<void>; | ||
export {}; | ||
export declare interface FilesOptions { | ||
/** | ||
* Files to minify | ||
*/ | ||
files: string[]; | ||
/** | ||
* Directory for output | ||
*/ | ||
outDir: string; | ||
/** | ||
* Define the output files names | ||
*/ | ||
outPattern?: (file: string) => string; | ||
} | ||
export declare interface DirectoriesOptions extends DirOptions { | ||
/** | ||
* Directories to minify | ||
*/ | ||
dirs: string[]; | ||
/** | ||
* Directory for output | ||
*/ | ||
outDir: string; | ||
} | ||
export declare function minify(options: MinifierOptions & SourceOptions & LanguageOptions & OnErrorOptions): Promise<MinifierResult>; | ||
export declare function watch(options: MinifierOptions & LanguageOptions & WatchOptions & OnErrorOptions): void; | ||
export declare function directory(options: MinifierOptions & LanguageOptions & DirectoryOptions & OnErrorOptions): Promise<void>; | ||
export declare function file(options: MinifierOptions & LanguageOptions & FileOptions & OnErrorOptions): Promise<void>; | ||
export declare function files(options: MinifierOptions & LanguageOptions & FilesOptions & OnErrorOptions): Promise<void>; | ||
export declare function directories(options: MinifierOptions & LanguageOptions & DirectoriesOptions & OnErrorOptions): Promise<void>; |
@@ -12,108 +12,95 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.file = exports.directory = exports.watch = exports.minify = exports.CssExtensions = void 0; | ||
exports.directories = exports.files = exports.file = exports.directory = exports.watch = exports.minify = void 0; | ||
const minify_1 = require("./lib/minify"); | ||
const fs = require("fs/promises"); | ||
const path = require("path"); | ||
function clone(obj) { | ||
return Object.assign({}, obj); | ||
} | ||
exports.CssExtensions = { | ||
css: '.css', | ||
scss: ['.scss', '.sass'], | ||
less: '.less', | ||
stylus: '.styl', | ||
}; | ||
; | ||
; | ||
; | ||
; | ||
; | ||
; | ||
; | ||
function minify(options) { | ||
var _a, _b, _c; | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let opts = clone(options); | ||
(_a = opts.lang) !== null && _a !== void 0 ? _a : (opts.lang = 'css'); | ||
(_b = opts.comments) !== null && _b !== void 0 ? _b : (opts.comments = false); | ||
(_c = opts.removeZeroUnits) !== null && _c !== void 0 ? _c : (opts.removeZeroUnits = true); | ||
if (opts.lang === 'scss') { | ||
try { | ||
opts.source = (yield Promise.resolve().then(() => require('node-sass'))).renderSync({ | ||
data: opts.source, | ||
file: options.path | ||
}).css.toString(); | ||
opts.lang = 'css'; | ||
try { | ||
let opts = clone(options); | ||
(_a = opts.lang) !== null && _a !== void 0 ? _a : (opts.lang = 'css'); | ||
if (opts.lang == 'auto') { | ||
if (opts.path) | ||
switch (path.extname(opts.path)) { | ||
case '.scss': | ||
case '.sass': | ||
opts.lang = 'scss'; | ||
break; | ||
case '.less': | ||
opts.lang = 'less'; | ||
break; | ||
case '.styl': | ||
opts.lang = 'stylus'; | ||
break; | ||
case '.css': | ||
opts.lang = 'css'; | ||
break; | ||
default: | ||
throw new Error(`Unknow language for file ${opts.path}`); | ||
} | ||
else { | ||
console.warn('⚠️ Auto language detection need "path" option to work, setting "lang" to "css"'); | ||
opts.lang = 'css'; | ||
} | ||
} | ||
catch (e) { | ||
if (e.code == 'MODULE_NOT_FOUND') | ||
throw new Error('Please install node-sass for use scss language: `npm i node-sass\' or `yarn add node-sass\''); | ||
else | ||
throw e; | ||
if (opts.lang == 'scss') { | ||
try { | ||
opts.source = (yield Promise.resolve().then(() => require('node-sass'))).renderSync({ | ||
data: opts.source, | ||
file: options.path | ||
}).css.toString(); | ||
opts.lang = 'css'; | ||
} | ||
catch (e) { | ||
if (e.code == 'MODULE_NOT_FOUND') | ||
throw new Error('Please install node-sass for use scss language: `npm i node-sass\' or `yarn add node-sass\''); | ||
else | ||
throw e; | ||
} | ||
} | ||
} | ||
else if (opts.lang === 'less') { | ||
try { | ||
opts.source = (yield (yield Promise.resolve().then(() => require('less'))).render(opts.source)).css; | ||
opts.lang = 'css'; | ||
else if (opts.lang == 'less') { | ||
try { | ||
opts.source = (yield (yield Promise.resolve().then(() => require('less'))).render(opts.source)).css; | ||
opts.lang = 'css'; | ||
} | ||
catch (e) { | ||
if (e.code == 'MODULE_NOT_FOUND') | ||
throw new Error('Please install less for use less language: `npm i less\' or `yarn add less\''); | ||
else | ||
throw e; | ||
} | ||
} | ||
catch (e) { | ||
if (e.code == 'MODULE_NOT_FOUND') | ||
throw new Error('Please install less for use less language: `npm i less\' or `yarn add less\''); | ||
else | ||
throw e; | ||
else if (opts.lang == 'stylus') { | ||
try { | ||
opts.source = yield new Promise((r, re) => __awaiter(this, void 0, void 0, function* () { | ||
return (yield Promise.resolve().then(() => require('stylus'))).render(opts.source, (err, css) => { | ||
if (err) | ||
re(err); | ||
else | ||
r(css); | ||
}); | ||
})); | ||
opts.lang = 'css'; | ||
} | ||
catch (e) { | ||
if (e.code == 'MODULE_NOT_FOUND') | ||
throw new Error('Please install stylus for use stylus language: `npm i stylus\' or `yarn add stylus\''); | ||
else | ||
throw e; | ||
} | ||
} | ||
else if (opts.lang != 'css') | ||
throw new Error(`Unknown or unsupported language: '${opts.lang}'`); | ||
return (0, minify_1.minify)(opts); | ||
} | ||
else if (opts.lang === 'stylus') { | ||
try { | ||
opts.source = yield new Promise((r, re) => __awaiter(this, void 0, void 0, function* () { | ||
return (yield Promise.resolve().then(() => require('stylus'))).render(opts.source, (err, css) => { | ||
if (err) | ||
re(err); | ||
else | ||
r(css); | ||
}); | ||
})); | ||
opts.lang = 'css'; | ||
} | ||
catch (e) { | ||
if (e.code == 'MODULE_NOT_FOUND') | ||
throw new Error('Please install stylus for use stylus language: `npm i stylus\' or `yarn add stylus\''); | ||
else | ||
throw e; | ||
} | ||
catch (e) { | ||
if (options.onError) | ||
options.onError(e); | ||
else | ||
throw e; | ||
} | ||
else if (opts.lang !== 'css') | ||
throw new Error(`Unknown or unsupported language: '${opts.lang}'`); | ||
opts.source = opts.source | ||
.replace(/(\s*)?['"](\s*)?/g, '"') | ||
.replace(/\n/g, '') | ||
.replace(/\t/g, '') | ||
.replace(/\s{2,}/g, '') | ||
.replace(/\:(\s*)?/g, ':') | ||
.replace(/(\s*)?\;(\s*)?/g, ';') | ||
.replace(/(\s*)?\,(\s*)?/g, ',') | ||
.replace(/(\s*)?\{(\s*)?/g, '{') | ||
.replace(/(\s*)?;(\s*)?\}/g, '}') | ||
.replace(/(\s*)?!(\s*)?/g, '!') | ||
.replace(/(\s*)?\?(\s*)?/g, '?') | ||
.replace(/(\s*)?\((\s*)?/g, '(') | ||
.replace(/(\s*)?\)(\s*)?/g, ')') | ||
.replace(/(\s*)?\+(\s*)?/g, '+') | ||
.replace(/(\s*)?\*(\s*)?/g, '*') | ||
.replace(/(\s*)?\-(\s*)?/g, '-') | ||
.replace(/(\s*)?\/(\s*)?/g, '/') | ||
.replace(/(\s*)?\>(\s*)?/g, '>') | ||
.replace(/(\s*)?\<(\s*)?/g, '<') | ||
.replace(/(\s*)?\=(\s*)?/g, '=') | ||
.replace(/(\s*)?\:(\s*)?/g, ':') | ||
.replace(/(\s*)?\;(\s*)?/g, ';') | ||
.replace(/(\s*)?\,(\s*)?/g, ',') | ||
.replace(/(\s*)?\{(\s*)?/g, '{') | ||
.replace(/(\s*)?\>(\s*)?/g, '>'); | ||
if (opts.removeZeroUnits) | ||
opts.source = opts.source.replace(/[^\d]0(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|hz|khz|dpi|dpcm|dppx)/gi, '0'); | ||
if (!opts.comments) | ||
opts.source = opts.source.replace(/\/\*.*?\*\//g, ''); | ||
if (opts.removeEmpty) | ||
opts.source = opts.source.replace(/[\w\.\#\:\[\]\>\s]*\{(\s*)?\}(\s*)?/g, ''); | ||
return { code: opts.source }; | ||
}); | ||
@@ -144,3 +131,7 @@ } | ||
try { | ||
let extension = exports.CssExtensions[opts.lang || 'css']; | ||
let extension; | ||
if (opts.lang != 'auto') | ||
extension = minify_1.CssExtensions[opts.lang || 'css']; | ||
else | ||
extension = minify_1.CssExtensions[file.toString().split('.').pop()]; | ||
let match = Array.isArray(extension) ? | ||
@@ -159,4 +150,6 @@ extension.some(e => file.toString().endsWith(e)) : | ||
lang: opts.lang, | ||
path: file.toString(), | ||
comments: opts.comments, | ||
removeZeroUnits: opts.removeZeroUnits | ||
removeZeroUnits: opts.removeZeroUnits, | ||
removeEmpty: opts.removeEmpty | ||
}); | ||
@@ -177,13 +170,37 @@ if (!opts.outPattern || typeof opts.outPattern != 'function') | ||
})); | ||
if (opts.now) | ||
directory(Object.assign({}, opts)); | ||
return; | ||
} | ||
exports.watch = watch; | ||
function isDirectoryExists(path) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
try { | ||
let stat = yield fs.stat(path); | ||
return stat.isDirectory(); | ||
} | ||
catch (e) { | ||
return false; | ||
} | ||
}); | ||
} | ||
function directory(options) { | ||
var _a, _b; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let opts = clone(options); | ||
(_a = opts.recursive) !== null && _a !== void 0 ? _a : (opts.recursive = true); | ||
(_b = opts.dir) !== null && _b !== void 0 ? _b : (opts.dir = '.'); | ||
if (!opts.outPattern || typeof opts.outPattern != 'function') | ||
opts.outPattern = (file) => file.replace(new RegExp(`${exports.CssExtensions[opts.lang || 'css']}$`), '.css'); | ||
let files = yield fs.readdir(opts.dir || '.'); | ||
opts.outPattern = (file) => file.replace(/\.(css|scss|sass|less|styl)$/, '.css'); | ||
let files = yield fs.readdir(opts.dir); | ||
for (let file of files) { | ||
let extension = exports.CssExtensions[opts.lang || 'css']; | ||
if (opts.recursive && (yield fs.stat(opts.dir + '/' + file)).isDirectory()) { | ||
yield directory(Object.assign(Object.assign({}, opts), { dir: opts.dir + '/' + file, outDir: opts.outDir + '/' + file })); | ||
continue; | ||
} | ||
let extension; | ||
if (opts.lang != 'auto') | ||
extension = minify_1.CssExtensions[opts.lang || 'css']; | ||
else | ||
extension = minify_1.CssExtensions[file.split('.').pop()]; | ||
let match = Array.isArray(extension) ? | ||
@@ -207,11 +224,16 @@ extension.some(e => file.toString().endsWith(e)) : | ||
if (isMatch(file) && | ||
(yield fs.stat((opts.dir || '.') + '/' + file)).isFile() && | ||
(yield fs.stat(opts.dir + '/' + file)).isFile() && | ||
match) { | ||
let code = yield fs.readFile((opts.dir || '.') + '/' + file, 'utf8'); | ||
let code = yield fs.readFile(opts.dir + '/' + file, 'utf8'); | ||
const { code: c } = yield minify({ | ||
source: code, | ||
lang: opts.lang, | ||
path: file, | ||
comments: opts.comments, | ||
removeZeroUnits: opts.removeZeroUnits | ||
removeZeroUnits: opts.removeZeroUnits, | ||
removeEmpty: opts.removeEmpty | ||
}); | ||
console.log(opts.outDir); | ||
if (!(yield isDirectoryExists(opts.outDir))) | ||
yield fs.mkdir(opts.outDir); | ||
yield fs.writeFile(opts.outDir + '/' + opts.outPattern(file), c); | ||
@@ -232,3 +254,4 @@ } | ||
comments: opts.comments, | ||
removeZeroUnits: opts.removeZeroUnits | ||
removeZeroUnits: opts.removeZeroUnits, | ||
path: opts.file | ||
}); | ||
@@ -246,1 +269,23 @@ yield fs.writeFile(opts.outFile, c); | ||
exports.file = file; | ||
function files(options) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let opts = clone(options); | ||
if (!opts.outPattern || typeof opts.outPattern != 'function') | ||
opts.outPattern = (file) => file.replace(/\.(css|scss|sass|less|styl)$/, '.css'); | ||
for (let f of opts.files) { | ||
file(Object.assign(Object.assign({}, opts), { file: f, outFile: opts.outDir + '/' + opts.outPattern(f.split('/').pop()) })); | ||
} | ||
}); | ||
} | ||
exports.files = files; | ||
function directories(options) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let opts = clone(options); | ||
if (!opts.outPattern || typeof opts.outPattern != 'function') | ||
opts.outPattern = (file) => file.replace(/\.(css|scss|sass|less|styl)$/, '.css'); | ||
for (let d of opts.dirs) { | ||
directory(Object.assign(Object.assign({}, opts), { dir: d, outDir: opts.outDir + '/' + d.split('/').pop() })); | ||
} | ||
}); | ||
} | ||
exports.directories = directories; |
{ | ||
"name": "style.min.css", | ||
"version": "0.0.3", | ||
"description": "Super CSS minifier and support for SCSS, LESS, and Stylus", | ||
"version": "0.0.4", | ||
"main": "dist", | ||
@@ -12,9 +13,6 @@ "types": "dist", | ||
"devDependencies": { | ||
"@types/less": "^3.0.3", | ||
"@types/node-sass": "^4.11.2", | ||
"@types/stylus": "^0.48.36", | ||
"less": "^4.1.2", | ||
"node-sass": "^7.0.0", | ||
"stylus": "^0.55.0" | ||
"@types/less": "latest", | ||
"@types/node-sass": "latest", | ||
"@types/stylus": "latest" | ||
} | ||
} |
@@ -61,2 +61,6 @@ # style.min.css | ||
## v0.0.3-min | ||
*I forgot to build TypeScript files...* | ||
## v0.0.3 | ||
@@ -63,0 +67,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
22327
3
11
535
79
1