Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

postcss-cli

Package Overview
Dependencies
Maintainers
4
Versions
57
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

postcss-cli - npm Package Compare versions

Comparing version 2.6.0 to 3.0.0-beta

.travis.yml

555

index.js

@@ -1,280 +0,357 @@

var globby = require("globby");
var resolve = require("resolve");
var argv = require("yargs")
.usage('Usage: $0 [--use|-u] plugin [--config|-c config.json] [--output|-o output.css] [input.css]')
.example('postcss --use autoprefixer -c options.json -o screen.css screen.css',
'Use autoprefixer as a postcss plugin')
.example('postcss --use autoprefixer --autoprefixer.browsers "> 5%" -o screen.css screen.css',
'Pass plugin parameters in plugin.option notation')
.example('postcss -u postcss-cachify -u autoprefixer -d build *.css',
'Use multiple plugins and multiple input files')
.config('c')
.alias('c', 'config')
.describe('c', 'JSON file with plugin configuration')
.alias('u', 'use')
.describe('u', 'postcss plugin name (can be used multiple times)')
.option('local-plugins', {
describe: 'lookup plugins in current node_modules directory'
'use strict'
const fs = require('fs-promise')
const path = require('path')
const stdin = require('get-stdin')
const chalk = require('chalk')
const ora = require('ora')
const globber = require('globby')
const chokidar = require('chokidar')
const postcss = require('postcss')
const postcssrc = require('postcss-load-config')
const reporter = require('postcss-reporter/lib/formatter')()
const logo = `
/|\\
// //
// //
//___*___*___//
//--*---------*--//
/|| * * ||/
// ||* *|| //
// || * * || //
//_____||___*_________*___||_____//
`
const version = () => {
const cli = require('./package.json').version
return chalk.bold.red(`
/|\\
// //
// //
//___*___*___//
//--*---------*--//
/|| * * ||/
// ||* v${cli} *|| //
// || * * || //
//_____||___*_________*___||_____//
`)
}
const argv = require('yargs')
.usage(
`${chalk.bold.red(logo)}
Usage:
$0 [input.css] [OPTIONS] [--output|-o output.css] [--watch]`
)
.option('o', {
alias: 'output',
desc: 'Output file',
type: 'string'
})
.alias('i', 'input')
.alias('o', 'output')
.describe('o', 'Output file (stdout if not provided)')
.alias('d', 'dir')
.describe('d', 'Output directory')
.alias('m', 'map')
.describe('m', 'Source map')
.boolean('r')
.alias('r', 'replace')
.describe('r', 'Replace input file(s) with generated output')
.alias('s', 'syntax')
.describe('s', 'Alternative input syntax parser')
.alias('p', 'parser')
.describe('p', 'Alternative CSS parser')
.option('poll', {
describe: 'Use polling to monitor for changes.',
default: false,
.option('d', {
alias: 'dir',
desc: 'Output directory',
type: 'string'
})
.alias('t', 'stringifier')
.describe('t', 'Alternative output stringifier')
.alias('l', 'log')
.describe('l', 'Log when file is written')
.alias('w', 'watch')
.describe('w', 'auto-recompile when detecting source changes')
.requiresArg(['u', 'c', 'i', 'o', 'd', 's', 'p', 't'])
.version(function() {
return [
'postcss version',
require('./node_modules/postcss/package.json').version
].join(' ');
.option('r', {
alias: 'replace',
desc: 'Replace (overwrite) the input file',
type: 'boolean'
})
.alias('v', 'version')
.help('h')
.alias('h', 'help')
.check(function(argv) {
if (argv._.length && argv.input) {
throw 'Both positional arguments and --input option used for `input file`: please only use one of them.';
.option('u', {
alias: 'use',
desc: 'List of postcss plugins to use',
type: 'array'
})
.option('p', {
alias: 'parser',
desc: 'Custom postcss parser',
type: 'string'
})
.option('t', {
alias: 'stringifier',
desc: 'Custom postcss stringifier',
type: 'string'
})
.option('s', {
alias: 'syntax',
desc: 'Custom postcss syntax',
type: 'string'
})
.option('w', {
alias: 'watch',
desc: 'Watch files for changes and recompile as needed',
type: 'boolean'
})
.option('x', {
alias: 'ext',
desc: 'Override the output file extension',
type: 'string',
coerce (ext) {
if (ext.indexOf('.') !== 0) return '.' + ext
return ext
}
if (argv.output && argv.dir && argv.replace) {
throw '`output file`, `output directory` and `replace` provided: please use either --output, --dir or --replace option only.';
}
if (argv.output && argv.dir) {
throw 'Both `output file` and `output directory` provided: please use either --output or --dir option.';
}
if (argv.output && argv.replace) {
throw 'Both `output file` and `replace` provided: please use either --output or --replace option.';
}
if (argv.dir && argv.replace) {
throw 'Both `output directory` and `replace` provided: please use either --dir or --replace option.';
}
return true;
})
.argv;
.option('e', {
alias: 'env',
desc: 'A shortcut for setting NODE_ENV',
type: 'string'
})
.option('c', {
alias: 'config',
desc: 'Set a custom path to look for a config file',
type: 'string'
})
.alias('m', 'map')
.describe('m', 'Create an external sourcemap')
.describe('no-map', 'Disable the default inline sourcemaps')
.version(version).alias('v', 'version')
.help('h').alias('h', 'help')
.example('$0 input.css -o output.css', 'Basic usage')
.example('cat input.css | $0 -u autoprefixer > output.css', 'Piping input & output')
.epilog(
`If no input files are passed, it reads from stdin. If neither -o, --dir, or --replace is passed, it writes to stdout.
if (!Array.isArray(argv.use)) {
argv.use = [argv.use];
}
If there are multiple input files, the --dir or --replace option must be passed.
// support for postcss-import
if (argv.use.indexOf("postcss-import") !== -1) {
var importConfig = argv["postcss-import"] || {};
argv["postcss-import"] = importConfig;
// auto-configure watch update hook
if(!importConfig.onImport) {
importConfig.onImport = function(sources) {
global.watchCSS(sources, this.from);
};
}
}
For more details, please see https://github.com/postcss/postcss-cli`
)
.argv
var inputFiles = argv._.length ? argv._ : argv.input;
inputFiles = globby.sync(inputFiles);
if (!inputFiles.length) {
// use stdin if nothing else is specified
inputFiles = [undefined];
let dir = argv.dir
let input = argv._
let output = argv.output
if (argv.map) argv.map = { inline: false }
console.warn(chalk.bold.red(logo))
let config = {
options: {
map: argv.map !== undefined ? argv.map : { inline: true },
parser: argv.parser ? require(argv.parser) : undefined,
syntax: argv.syntax ? require(argv.syntax) : undefined,
stringifier: argv.stringifier ? require(argv.stringifier) : undefined
},
plugins: argv.use
? argv.use.map((plugin) => {
try {
return require(plugin)()
} catch (e) {
error(`PluginError: Cannot find module '${plugin}'`)
}
})
: []
}
if (inputFiles.length > 1 && !argv.dir && !argv.replace) {
throw 'Please specify either --replace or --dir [output directory] for your files';
}
// load and configure plugin array
var plugins = argv.use.map(function(name) {
var local = argv['local-plugins'];
var plugin;
if (local) {
var resolved = resolve.sync(name, {basedir: process.cwd()});
plugin = require(resolved);
} else if (name) {
plugin = require(name);
} else {
return null;
}
if (plugin.default && typeof plugin.default === 'function') {
plugin = plugin.default;
}
if (name in argv) {
plugin = plugin(argv[name]);
} else {
plugin = plugin.postcss || plugin();
}
return plugin;
});
if (argv.env) process.env.NODE_ENV = argv.env
if (argv.config) argv.config = path.resolve(argv.config)
var customSyntaxOptions = ['syntax', 'parser', 'stringifier']
.reduce(function(cso, opt) {
if (argv[opt]) {
cso[opt] = require(argv[opt]);
Promise.resolve()
.then(() => {
if (input && input.length) return globber(input)
console.warn(chalk.bold.yellow('Warning: No files passed, reading from stdin\n'))
if (argv.replace || argv.dir) error('Cannot use --dir or --replace when reading from stdin')
if (argv.watch) {
error('Cannot run in watch mode when reading from stdin')
}
return cso;
}, Object.create(null));
return ['stdin']
})
.then((i) => {
if (!i || !i.length) {
error('You must pass a valid list of files to parse')
}
var mapOptions = argv.map;
// treat `--map file` as `--no-map.inline`
if (mapOptions === 'file') {
mapOptions = { inline: false };
if (i.length > 1 && !argv.dir && !argv.replace) {
error('Must use --dir or --replace with multiple input files')
}
return files(i)
})
.then((results) => {
if (argv.watch) {
const watcher = chokidar.watch(input.concat(dependencies(results)))
if (config.file) watcher.add(config.file)
watcher
.on('ready', (file) => console.warn(chalk.bold.cyan('Waiting for file changes...')))
.on('change', (file) => {
if (input.indexOf(file) === -1) {
return files(input)
.then((results) => watcher.add(dependencies(results)))
.then(() => console.warn(chalk.bold.cyan('Waiting for file changes...')))
.catch(error)
}
files(file)
.then((result) => watcher.add(dependencies(result)))
.then(() => console.warn(chalk.bold.cyan('Waiting for file changes...')))
.catch(error)
})
}
})
.catch(error)
function rc (ctx, path) {
if (argv.use) return Promise.resolve()
return postcssrc(ctx, path)
.then((rc) => { config = rc })
.catch((err) => {
if (err.message.indexOf('No PostCSS Config found') === -1) throw err
})
}
var async = require('neo-async');
var fs = require('fs');
var path = require('path');
var readFile = require('read-file-stdin');
var path = require('path');
var postcss = require('postcss');
var processor = plugins[0] ? postcss(plugins) : postcss();
var mkdirp = require('mkdirp');
function files (files) {
if (typeof files === 'string') files = [ files ]
// hook for dynamically updating the list of watched files
global.watchCSS = function() {};
if (argv.watch) {
global.watchCSS = fsWatcher(inputFiles);
return Promise.all(files.map((file) => {
if (file === 'stdin') {
return stdin()
.then((content) => {
if (!content) return error('Error: Did not receive any stdin')
css(content, 'stdin')
})
}
return fs.readFile(file)
.then((content) => css(content, file))
}))
}
async.forEach(inputFiles, compile, onError);
function css (css, file) {
const ctx = { options: config.options }
function fsWatcher(entryPoints) {
var watchedFiles = entryPoints;
var index = {}; // source files by entry point
var opts = {};
if (file !== 'stdin') {
ctx.file = {
dirname: path.dirname(file),
basename: path.basename(file),
extname: path.extname(file)
}
if (argv.poll) {
opts.usePolling = true;
if (!argv.config) argv.config = path.dirname(file)
}
if (typeof argv.poll === 'number') {
opts.interval = argv.poll;
}
var watcher = require('chokidar').watch(watchedFiles, opts);
// recompile if any watched file is modified
// TODO: only recompile relevant entry point
watcher.on('change', function() {
async.forEach(entryPoints, compile, function(err) {
return onError.call(this, err, true);
});
});
if (!argv.config) argv.config = process.cwd()
return function updateWatchedFiles(files, entryPoint) {
// update source files for current entry point
entryPoint = entryPoint || null;
index[entryPoint] = files;
// aggregate source files across entry points
var entryPoints = Object.keys(index);
var sources = entryPoints.reduce(function(files, entryPoint) {
return files.concat(index[entryPoint]);
}, []);
// update watch list
watcher.unwatch(watchedFiles);
watcher.add(sources);
watchedFiles = sources;
};
}
const time = process.hrtime()
function compile(input, fn) {
var output = argv.output;
if (argv.dir) {
output = path.join(argv.dir, path.basename(input));
} else if (argv.replace) {
output = input;
}
const spinner = ora(`Processing ${file}`).start()
processCSS(processor, input, output, fn);
}
return rc(ctx, argv.config)
.then(() => {
let options = config.options
function processCSS(processor, input, output, fn) {
function doProcess(css, fn) {
function onResult(result) {
if (typeof result.warnings === 'function') {
result.warnings().forEach(function(w) { console.warn(w.toString()); });
if (file === 'stdin' && output) file = output
if (file !== 'stdin' && output || output || dir || argv.replace) {
options = Object.assign(
{
from: file,
to: output || (
argv.replace
? file
: path.join(dir, path.basename(file))
)
},
config.options
)
if (argv.ext) {
options.to = options.to
.replace(path.extname(options.to), argv.ext)
}
options.to = path.resolve(options.to)
}
fn(null, result);
}
var options = {
from: input,
to: output
};
// Can't use external sourcemaps when writing to stdout:
if (!options.to && config.options.map && !config.options.map.inline) {
spinner.fail()
error('Cannot output external sourcemaps when writing to stdout')
}
Object.keys(customSyntaxOptions).forEach(function(opt) {
options[opt] = customSyntaxOptions[opt];
});
return postcss(config.plugins)
.process(css, options)
.then((result) => {
const tasks = []
if (typeof mapOptions !== 'undefined') {
options.map = mapOptions;
}
if (options.to) {
tasks.push(fs.outputFile(options.to, result.css))
var result = processor.process(css, options);
if (result.map) {
tasks.push(
fs.outputFile(
options.to
.replace(
path.extname(options.to),
path.extname(options.to) + '.map'
),
result.map
)
)
}
} else process.stdout.write(result.css, 'utf8')
if (typeof result.then === 'function') {
result.then(onResult).catch(fn);
} else {
process.nextTick(onResult.bind(null, result));
}
}
return Promise.all(tasks)
.then(() => {
spinner.text = chalk.bold.green(
`Finished ${file} (${Math.round(process.hrtime(time)[1] / 1e6)}ms)`
)
if (result.warnings().length) {
spinner.fail()
console.warn(reporter(result))
} else spinner.succeed()
async.waterfall([
async.apply(readFile, input),
doProcess,
async.apply(writeResult, output)
], fn);
return result
})
})
})
}
function onError(err, keepAlive) { // XXX: avoid overloaded signature?
if (err) {
if (err.message && typeof err.showSourceCode === 'function') {
console.error(err.message, err.showSourceCode());
} else {
console.error(err);
}
if (!keepAlive) {
process.exit(1);
}
}
}
function dependencies (results) {
if (!Array.isArray(results)) results = [ results ]
function writeResult (name, content, fn) {
var funcs = [
async.apply(writeFile, name, content.css)
];
if (content.map && name) {
funcs.push(async.apply(writeFile, name + '.map', content.map.toString()));
}
async.parallel(funcs, fn);
}
const messages = []
function writeFile(name, content, fn) {
if (!name) {
process.stdout.write(content);
return fn();
}
results.forEach((result) => {
if (result.messages <= 0) return
mkdirp(path.dirname(name), function (err) {
if (err) {
fn(err);
} else {
fs.writeFile(name, content, fn);
result.messages
.filter((msg) => msg.type === 'dependency' ? msg : '')
.forEach((dependency) => messages.push(dependency.file))
})
if (argv.log) {
console.log('Generated file: ' + name);
}
}
});
return messages
}
function error (err) {
if (typeof err === 'string') {
// Manual error
console.error(chalk.bold.red(err))
} else if (err.name === 'CssSyntaxError') {
// CSS Syntax Error
console.error(chalk.bold.red(`${err.file}`))
err.message = err.message
.substr(err.file.length + 1)
.replace(/:\s/, '] ')
console.error('\n', chalk.bold.red(`[${err.message}`))
console.error('\n', err.showSourceCode(), '\n')
} else {
// JS Error
// Don't use chalk here; we want a JS stack trace:
console.error(err)
}
process.exit(1)
}
{
"name": "postcss-cli",
"version": "2.6.0",
"description": "CLI for postcss",
"version": "3.0.0-beta",
"description": "CLI for PostCSS",
"main": "index.js",
"engines": { "node": ">=4" },
"bin": {

@@ -10,29 +11,52 @@ "postcss": "./bin/postcss"

"scripts": {
"test": "make"
"clean": "node test/helpers/clean.js",
"lint": "standard",
"pretest": "npm run clean && npm run lint",
"test": "nyc ava -v"
},
"repository": "https://github.com/postcss/postcss-cli.git",
"dependencies": {
"chalk": "^1.1.3",
"chokidar": "^1.6.1",
"fs-promise": "^1.0.0",
"get-stdin": "^5.0.1",
"globby": "^6.1.0",
"ora": "^1.1.0",
"postcss": "^5.2.11",
"postcss-load-config": "^1.1.0",
"postcss-reporter": "^3.0.0",
"yargs": "^6.6.0"
},
"devDependencies": {
"ava": "^0.18.1",
"coveralls": "^2.11.15",
"nyc": "^10.1.2",
"postcss-import": "^9.1.0",
"standard": "^8.6.0",
"sugarss": "^0.2.0",
"uuid": "^3.0.1"
},
"keywords": [
"cli",
"postcss",
"postcss-runner",
"cli"
"postcss-runner"
],
"author": "Damian Krzeminski <pirxpilot@code42day.com>",
"license": "MIT",
"dependencies": {
"globby": "^4.1.0",
"mkdirp": "^0.5.1",
"neo-async": "^1.0.0",
"postcss": "^5.0.0",
"read-file-stdin": "^0.2.0",
"resolve": "^1.1.6",
"yargs": "^4.7.1"
"authors": [
{
"name": "Michael Ciniawky",
"email": "michael.ciniawsky@gmail.com"
},
{
"name": "Ryan Zimmermann",
"email": "opensrc@ryanzim.com"
}
],
"repository": {
"type": "git",
"url": "https://github.com/postcss/postcss-cli.git"
},
"optionalDependencies": {
"chokidar": "^1.5.1"
"bugs": {
"url": "https://github.com/postcss/postcss-cli/issues"
},
"devDependencies": {
"jshint": "^2.9.2",
"postcss-import": "^8.1.2",
"postcss-url": "^5.1.2"
}
"homepage": "https://github.com/postcss/postcss-cli#readme",
"license": "MIT"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc