diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2023-10-14 15:50:21 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2023-10-14 15:50:21 +0800 |
| commit | 0379526e20e1ff212df23e6326741aa9c06df204 (patch) | |
| tree | 340143b0c4dc4280c88ba1591d137b53477005b3 /node_modules/doiuse/bin/cli.js | |
| parent | 7aba14fb7c970c6e6af82c805db2aef6d70bfe2b (diff) | |
added doiuse plugin for postcss
Diffstat (limited to 'node_modules/doiuse/bin/cli.js')
| -rwxr-xr-x | node_modules/doiuse/bin/cli.js | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/node_modules/doiuse/bin/cli.js b/node_modules/doiuse/bin/cli.js new file mode 100755 index 00000000..d07d159b --- /dev/null +++ b/node_modules/doiuse/bin/cli.js @@ -0,0 +1,161 @@ +#!/usr/bin/env node + +import fs from 'node:fs'; +import path from 'node:path'; +import { PassThrough } from 'node:stream'; + +import browserslist from 'browserslist'; +import ldjson from 'ldjson-stream'; +import yargs from 'yargs'; + +import DoIUse from '../lib/DoIUse.js'; +import CssUsageDuplex from '../lib/stream/CssUsageDuplex.js'; +import { formatBrowserName } from '../utils/util.js'; + +const FILE_NOT_FOUND = 'ENOENT'; +const argv = await yargs(process.argv.slice(2)) + .usage('Lint your CSS for browser support.') + .example('cat FILE | $0 -b "ios >= 6"', '') + .example('$0 --browsers "ie >= 9, > 1%, last 3 versions" [FILE] [FILE] ...', '') + .example('$0 -b "ie >= 8" -b "> 1%" -b "last 3 versions" [FILE] [FILE] ...', '') + .options({ + browsers: { + type: 'string', + alias: 'b', + description: 'Autoprefixer-like browser criteria.', + default: /** @type {string} */ (null), + string: true, + }, + ignore: { + type: 'string', + alias: 'i', + description: 'List of features to ignore.', + default: '', + string: true, + }, + l: { + type: 'boolean', + alias: 'list-only', + description: 'Just show the browsers and features that would be tested by' + + 'the specified browser criteria, without actually processing any CSS.', + }, + config: { + type: 'string', + alias: 'c', + description: 'Provide options through config file', + }, + verbose: { + type: 'number', + alias: 'v', + description: 'Verbose output. Multiple levels available.', + }, + json: { + type: 'boolean', + alias: 'j', + description: 'Output JSON instead of string linter-like messages.', + }, + }) + .count('verbose') + .help('h', 'Show help message.') + .alias('h', 'help') + .argv; + +// Config file reading +if (argv.config) { + try { + const fileData = fs.readFileSync(path.resolve(argv.config)); + const config = JSON.parse(fileData.toString()); + + for (const [key, value] of Object.entries(config)) { + argv[key] = (key === 'browsers' && Array.isArray(value)) + ? value.join(',') + : value; + } + } catch (error) { + if (error && error.code === FILE_NOT_FOUND) { + process.stderr.write('Config file not found\n'); + } + throw error; + } +} + +const browsers = argv.browsers ? argv.browsers.split(',') + .map((/** @type {string} */ s) => s.trim()) : null; + +const ignore = argv.ignore.split(',').map((s) => s.trim()); + +// Informational output +if (argv.l || argv.verbose >= 1) { + const formattedBrowsers = browserslist(browsers) + .map((b) => { + const [name, version] = b.split(' '); + /** @type {[string, number]} */ + const formatted = [formatBrowserName(name), Number.parseInt(version, 10)]; + return formatted; + }) + .sort((a, b) => b[1] - a[1]) + .map((b) => b.join(' ')) + .join(', '); + process.stdout.write(`[doiuse] Browsers: ${formattedBrowsers}\n`); +} + +if (argv.verbose >= 2) { + const { features } = new DoIUse({ browsers }).info(); + process.stdout.write('[doiuse] Unsupported features:\n'); + for (const feature of Object.values(features)) { + process.stdout.write(`${feature.caniuseData.title}\n`); + if (argv.verbose >= 3) { + process.stdout.write(`\n${feature.missing}\n`); + } + } +} + +if (argv.l) { + // eslint-disable-next-line n/no-process-exit + process.exit(0); +} + +// Process the CSS +if (argv.help || (argv._.length === 0 && process.stdin.isTTY)) { + yargs.showHelp(); + // eslint-disable-next-line n/no-process-exit + process.exit(0); +} + +/** @type {import("stream").Writable} */ +let outStream; +if (argv.json) { + outStream = ldjson.serialize(); +} else { + outStream = new PassThrough({ + objectMode: true, + transform(usage, enc, next) { + next(null, `${usage.message}\n`); + }, + }); +} +outStream.pipe(process.stdout); + +/** + * @param {import('stream').Stream} stream + * @param {string} [file] + */ +function processStream(stream, file) { + stream.pipe(new CssUsageDuplex({ + browsers: argv.browsers, + // @ts-expect-error Skip cast + ignore, + }, file)) + .on('error', (error) => { + process.stderr.write('Error parsing file\n'); + throw error; + }) + .pipe(outStream); +} +if (argv._.length > 0) { + for (const file of argv._) { + processStream(fs.createReadStream(file.toString()), file.toString()); + } +} else { + processStream(process.stdin); +} |
