mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
add @jsdoc/cli and @jsdoc/util modules
`@jsdoc/cli` deals with command-line arguments, and `@jsdoc/util` casts values to appropriate types.
This commit is contained in:
parent
4badaef5fd
commit
25c37411d9
4
cli.js
4
cli.js
@ -47,7 +47,7 @@ module.exports = (() => {
|
||||
// TODO: docs
|
||||
cli.loadConfig = () => {
|
||||
const _ = require('lodash');
|
||||
const args = require('jsdoc/opts/args');
|
||||
const args = require('@jsdoc/cli').args;
|
||||
let conf;
|
||||
const config = require('@jsdoc/config');
|
||||
|
||||
@ -166,7 +166,7 @@ module.exports = (() => {
|
||||
// TODO: docs
|
||||
cli.printHelp = () => {
|
||||
cli.printVersion();
|
||||
console.log( `\n${require('jsdoc/opts/args').help()}\n` );
|
||||
console.log( `\n${require('@jsdoc/cli').help}\n` );
|
||||
console.log('Visit http://usejsdoc.org for more information.');
|
||||
|
||||
return Promise.resolve(0);
|
||||
|
||||
@ -1,301 +0,0 @@
|
||||
/**
|
||||
* Parse the command line arguments.
|
||||
* @module jsdoc/opts/argparser
|
||||
*/
|
||||
const _ = require('lodash');
|
||||
|
||||
const hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
|
||||
function padLeft(str, length) {
|
||||
return str.padStart(str.length + length);
|
||||
}
|
||||
|
||||
function padRight(str, length) {
|
||||
return str.padEnd(str.length + length);
|
||||
}
|
||||
|
||||
function findMaxLength(arr) {
|
||||
let max = 0;
|
||||
|
||||
arr.forEach(({length}) => {
|
||||
if (length > max) {
|
||||
max = length;
|
||||
}
|
||||
});
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
function concatWithMaxLength(items, maxLength) {
|
||||
let result = '';
|
||||
|
||||
// to prevent endless loops, always use the first item, regardless of length
|
||||
result += items.shift();
|
||||
|
||||
while (items.length && (result.length + items[0].length < maxLength)) {
|
||||
result += ` ${items.shift()}`;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// we want to format names and descriptions like this:
|
||||
// | -f, --foo Very long description very long description very long |
|
||||
// | description very long description. |
|
||||
function formatHelpInfo({names, descriptions}) {
|
||||
const MARGIN_LENGTH = 4;
|
||||
const results = [];
|
||||
|
||||
const maxLength = process.stdout.columns;
|
||||
const maxNameLength = findMaxLength(names);
|
||||
const wrapDescriptionAt = maxLength - (MARGIN_LENGTH * 3) - maxNameLength;
|
||||
|
||||
// build the string for each option
|
||||
names.forEach((name, i) => {
|
||||
let result;
|
||||
let partialDescription;
|
||||
let words;
|
||||
|
||||
// add a left margin to the name
|
||||
result = padLeft(names[i], MARGIN_LENGTH);
|
||||
// and a right margin, with extra padding so the descriptions line up with one another
|
||||
result = padRight(result, maxNameLength - names[i].length + MARGIN_LENGTH);
|
||||
|
||||
// split the description on spaces
|
||||
words = descriptions[i].split(' ');
|
||||
// add as much of the description as we can fit on the first line
|
||||
result += concatWithMaxLength(words, wrapDescriptionAt);
|
||||
// if there's anything left, keep going until we've consumed the description
|
||||
while (words.length) {
|
||||
partialDescription = padLeft('', maxNameLength + (MARGIN_LENGTH * 2));
|
||||
partialDescription += concatWithMaxLength(words, wrapDescriptionAt);
|
||||
result += `\n${partialDescription}`;
|
||||
}
|
||||
|
||||
results.push(result);
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* A parser to interpret the key-value pairs entered on the command line.
|
||||
*
|
||||
* @alias module:jsdoc/opts/argparser
|
||||
*/
|
||||
class ArgParser {
|
||||
/**
|
||||
* Create an instance of the parser.
|
||||
*/
|
||||
constructor() {
|
||||
this._options = [];
|
||||
this._shortNameIndex = {};
|
||||
this._longNameIndex = {};
|
||||
}
|
||||
|
||||
_getOptionByShortName(name) {
|
||||
if (hasOwnProp.call(this._shortNameIndex, name)) {
|
||||
return this._options[this._shortNameIndex[name]];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
_getOptionByLongName(name) {
|
||||
if (hasOwnProp.call(this._longNameIndex, name)) {
|
||||
return this._options[this._longNameIndex[name]];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
_addOption(option) {
|
||||
let currentIndex;
|
||||
|
||||
const longName = option.longName;
|
||||
const shortName = option.shortName;
|
||||
|
||||
this._options.push(option);
|
||||
currentIndex = this._options.length - 1;
|
||||
|
||||
if (shortName) {
|
||||
this._shortNameIndex[shortName] = currentIndex;
|
||||
}
|
||||
if (longName) {
|
||||
this._longNameIndex[longName] = currentIndex;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide information about a legal option.
|
||||
*
|
||||
* @param {character} shortName - The short name of the option, entered like: -T.
|
||||
* @param {string} longName - The equivalent long name of the option, entered like: --test.
|
||||
* @param {boolean} hasValue - Does this option require a value? Like: -t templatename
|
||||
* @param {string} helpText - A brief description of the option.
|
||||
* @param {boolean} [canHaveMultiple=false] - Set to `true` if the option can be provided more
|
||||
* than once.
|
||||
* @param {function} [coercer] - A function to coerce the given value to a specific type.
|
||||
* @return {this}
|
||||
* @example
|
||||
* myParser.addOption('t', 'template', true, 'The path to the template.');
|
||||
* myParser.addOption('h', 'help', false, 'Show the help message.');
|
||||
*/
|
||||
addOption(shortName, longName, hasValue, helpText, canHaveMultiple = false, coercer) {
|
||||
return this._addOption({
|
||||
shortName: shortName,
|
||||
longName: longName,
|
||||
hasValue: hasValue,
|
||||
helpText: helpText,
|
||||
canHaveMultiple: canHaveMultiple,
|
||||
coercer: coercer
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: refactor addOption to accept objects, then get rid of this method
|
||||
/**
|
||||
* Provide information about an option that should not cause an error if present, but that is always
|
||||
* ignored (for example, an option that was used in previous versions but is no longer supported).
|
||||
*
|
||||
* @private
|
||||
* @param {string} shortName - The short name of the option with a leading hyphen (for example,
|
||||
* `-v`).
|
||||
* @param {string} longName - The long name of the option with two leading hyphens (for example,
|
||||
* `--version`).
|
||||
*/
|
||||
addIgnoredOption(shortName, longName) {
|
||||
return this._addOption({
|
||||
shortName: shortName,
|
||||
longName: longName,
|
||||
ignore: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a summary of all the options with corresponding help text.
|
||||
* @returns {string}
|
||||
*/
|
||||
help() {
|
||||
const options = {
|
||||
names: [],
|
||||
descriptions: []
|
||||
};
|
||||
|
||||
this._options.forEach(option => {
|
||||
let name = '';
|
||||
|
||||
// don't show ignored options
|
||||
if (option.ignore) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (option.shortName) {
|
||||
name += `-${option.shortName}${option.longName ? ', ' : ''}`;
|
||||
}
|
||||
|
||||
if (option.longName) {
|
||||
name += `--${option.longName}`;
|
||||
}
|
||||
|
||||
if (option.hasValue) {
|
||||
name += ' <value>';
|
||||
}
|
||||
|
||||
options.names.push(name);
|
||||
options.descriptions.push(option.helpText);
|
||||
});
|
||||
|
||||
return `Options:\n${formatHelpInfo(options).join('\n')}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the options.
|
||||
* @param {Array.<string>} args An array, like ['-x', 'hello']
|
||||
* @param {Object} [defaults={}] An optional collection of default values.
|
||||
* @returns {Object} The keys will be the longNames, or the shortName if no longName is defined for
|
||||
* that option. The values will be the values provided, or `true` if the option accepts no value.
|
||||
*/
|
||||
parse(args, defaults) {
|
||||
let arg;
|
||||
let next;
|
||||
let option;
|
||||
const result = (defaults && _.defaults({}, defaults)) || {};
|
||||
let shortName;
|
||||
let longName;
|
||||
let name;
|
||||
let value;
|
||||
|
||||
result._ = [];
|
||||
for (let i = 0, l = args.length; i < l; i++) {
|
||||
arg = String(args[i]);
|
||||
next = (i < l - 1) ? String(args[i + 1]) : null;
|
||||
shortName = null;
|
||||
value = null;
|
||||
|
||||
// like -t
|
||||
if (arg.charAt(0) === '-') {
|
||||
// like --template
|
||||
if (arg.charAt(1) === '-') {
|
||||
name = longName = arg.slice(2);
|
||||
option = this._getOptionByLongName(longName);
|
||||
}
|
||||
else {
|
||||
name = shortName = arg.slice(1);
|
||||
option = this._getOptionByShortName(shortName);
|
||||
}
|
||||
|
||||
if (option === null) {
|
||||
throw new Error(`Unknown command-line option "${name}".`);
|
||||
}
|
||||
|
||||
if (option.hasValue) {
|
||||
value = next;
|
||||
i++;
|
||||
|
||||
if (value === null || value.charAt(0) === '-') {
|
||||
throw new Error(`The command-line option "${name}" requires a value.`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
value = true;
|
||||
}
|
||||
|
||||
// skip ignored options now that we've consumed the option text
|
||||
if (option.ignore) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (option.longName && shortName) {
|
||||
name = option.longName;
|
||||
}
|
||||
|
||||
if (typeof option.coercer === 'function') {
|
||||
value = option.coercer(value);
|
||||
}
|
||||
|
||||
// Allow for multiple options of the same type to be present
|
||||
if (option.canHaveMultiple && hasOwnProp.call(result, name)) {
|
||||
const val = result[name];
|
||||
|
||||
if (val instanceof Array) {
|
||||
val.push(value);
|
||||
} else {
|
||||
result[name] = [val, value];
|
||||
}
|
||||
}
|
||||
else {
|
||||
result[name] = value;
|
||||
}
|
||||
}
|
||||
else {
|
||||
result._.push(arg);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ArgParser;
|
||||
@ -1,82 +0,0 @@
|
||||
/**
|
||||
* @module jsdoc/opts/args
|
||||
* @requires jsdoc/opts/argparser
|
||||
*/
|
||||
const ArgParser = require('jsdoc/opts/argparser');
|
||||
const cast = require('jsdoc/util/cast').cast;
|
||||
const querystring = require('querystring');
|
||||
|
||||
let ourOptions;
|
||||
|
||||
const argParser = new ArgParser();
|
||||
const hasOwnProp = Object.prototype.hasOwnProperty;
|
||||
|
||||
function parseQuery(str) {
|
||||
return cast( querystring.parse(str) );
|
||||
}
|
||||
|
||||
/* eslint-disable no-multi-spaces */
|
||||
argParser.addOption('a', 'access', true, 'Only display symbols with the given access: "package", public", "protected", "private" or "undefined", or "all" for all access levels. Default: all except "private"', true);
|
||||
argParser.addOption('c', 'configure', true, 'The path to the configuration file. Default: path/to/jsdoc/conf.json');
|
||||
argParser.addOption('d', 'destination', true, 'The path to the output folder. Default: ./out/');
|
||||
argParser.addOption('', 'debug', false, 'Log information for debugging JSDoc.');
|
||||
argParser.addOption('e', 'encoding', true, 'Assume this encoding when reading all source files. Default: utf8');
|
||||
argParser.addOption('h', 'help', false, 'Print this message and quit.');
|
||||
argParser.addOption('', 'match', true, 'When running tests, only use specs whose names contain <value>.', true);
|
||||
argParser.addOption('', 'nocolor', false, 'When running tests, do not use color in console output.');
|
||||
argParser.addOption('p', 'private', false, 'Display symbols marked with the @private tag. Equivalent to "--access all". Default: false');
|
||||
argParser.addOption('P', 'package', true, 'The path to the project\'s package file. Default: path/to/sourcefiles/package.json');
|
||||
argParser.addOption('', 'pedantic', false, 'Treat errors as fatal errors, and treat warnings as errors. Default: false');
|
||||
argParser.addOption('q', 'query', true, 'A query string to parse and store in jsdoc.env.opts.query. Example: foo=bar&baz=true', false, parseQuery);
|
||||
argParser.addOption('r', 'recurse', false, 'Recurse into subdirectories when scanning for source files and tutorials.');
|
||||
argParser.addOption('R', 'readme', true, 'The path to the project\'s README file. Default: path/to/sourcefiles/README.md');
|
||||
argParser.addOption('t', 'template', true, 'The path to the template to use. Default: path/to/jsdoc/templates/default');
|
||||
argParser.addOption('T', 'test', false, 'Run all tests and quit.');
|
||||
argParser.addOption('u', 'tutorials', true, 'Directory in which JSDoc should search for tutorials.');
|
||||
argParser.addOption('v', 'version', false, 'Display the version number and quit.');
|
||||
argParser.addOption('', 'verbose', false, 'Log detailed information to the console as JSDoc runs.');
|
||||
argParser.addOption('X', 'explain', false, 'Dump all found doclet internals to console and quit.');
|
||||
/* eslint-enable no-multi-spaces */
|
||||
|
||||
// Options that are no longer supported and should be ignored
|
||||
argParser.addIgnoredOption('l', 'lenient'); // removed in JSDoc 3.3.0
|
||||
|
||||
/**
|
||||
* Set the options for this app.
|
||||
* @throws {Error} Illegal arguments will throw errors.
|
||||
* @param {string|String[]} args The command line arguments for this app.
|
||||
*/
|
||||
exports.parse = (args = []) => {
|
||||
if (typeof args === 'string' || args.constructor === String) {
|
||||
args = String(args).split(/\s+/g);
|
||||
}
|
||||
|
||||
ourOptions = argParser.parse(args);
|
||||
|
||||
return ourOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve help message for options.
|
||||
*/
|
||||
exports.help = () => argParser.help();
|
||||
|
||||
/**
|
||||
* Get a named option.
|
||||
* @variation name
|
||||
* @param {string} name The name of the option.
|
||||
* @return {string} The value associated with the given name.
|
||||
*//**
|
||||
* Get all the options for this app.
|
||||
* @return {Object} A collection of key/values representing all the options.
|
||||
*/
|
||||
exports.get = name => {
|
||||
if (typeof name === 'undefined') {
|
||||
return ourOptions;
|
||||
}
|
||||
else if ( hasOwnProp.call(ourOptions, name) ) {
|
||||
return ourOptions[name];
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
// TODO: docs
|
||||
/** @module jsdoc/src/astnode */
|
||||
const cast = require('jsdoc/util/cast').cast;
|
||||
const cast = require('@jsdoc/util').cast;
|
||||
const env = require('jsdoc/env');
|
||||
const name = require('jsdoc/name');
|
||||
const Syntax = require('@jsdoc/syntax');
|
||||
|
||||
@ -1,14 +1,12 @@
|
||||
/**
|
||||
* @module jsdoc/tag/type
|
||||
*/
|
||||
const cast = require('@jsdoc/util').cast;
|
||||
const catharsis = require('catharsis');
|
||||
const jsdoc = {
|
||||
name: require('jsdoc/name'),
|
||||
tag: {
|
||||
inline: require('jsdoc/tag/inline')
|
||||
},
|
||||
util: {
|
||||
cast: require('jsdoc/util/cast')
|
||||
}
|
||||
};
|
||||
const util = require('util');
|
||||
@ -161,7 +159,7 @@ function parseName(tagInfo) {
|
||||
// like 'foo=bar' or 'foo = bar'
|
||||
if ( /^(.+?)\s*=\s*(.+)$/.test(tagInfo.name) ) {
|
||||
tagInfo.name = RegExp.$1;
|
||||
tagInfo.defaultvalue = jsdoc.util.cast.cast(RegExp.$2);
|
||||
tagInfo.defaultvalue = cast(RegExp.$2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
193
package-lock.json
generated
193
package-lock.json
generated
@ -127,6 +127,97 @@
|
||||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@jsdoc/cli": {
|
||||
"version": "file:packages/jsdoc-cli",
|
||||
"requires": {
|
||||
"@jsdoc/util": "file:packages/jsdoc-util",
|
||||
"lodash": "^4.17.11",
|
||||
"yargs-parser": "^11.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "3.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"cliui": {
|
||||
"version": "4.1.0",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"string-width": "^2.1.1",
|
||||
"strip-ansi": "^4.0.0",
|
||||
"wrap-ansi": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"find-up": {
|
||||
"version": "3.0.0",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"locate-path": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"invert-kv": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"lcid": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"invert-kv": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"os-locale": {
|
||||
"version": "3.1.0",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"execa": "^1.0.0",
|
||||
"lcid": "^2.0.0",
|
||||
"mem": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "4.0.0",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"which-module": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "12.0.5",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"cliui": "^4.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^3.0.0",
|
||||
"get-caller-file": "^1.0.1",
|
||||
"os-locale": "^3.0.0",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^1.0.1",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^2.0.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^3.2.1 || ^4.0.0",
|
||||
"yargs-parser": "^11.1.1"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "11.1.1",
|
||||
"bundled": true,
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@jsdoc/config": {
|
||||
"version": "file:packages/jsdoc-config",
|
||||
"requires": {
|
||||
@ -260,6 +351,9 @@
|
||||
"@jsdoc/template-silent": {
|
||||
"version": "file:packages/jsdoc-template-silent"
|
||||
},
|
||||
"@jsdoc/util": {
|
||||
"version": "file:packages/jsdoc-util"
|
||||
},
|
||||
"@lerna/add": {
|
||||
"version": "3.10.6",
|
||||
"resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.10.6.tgz",
|
||||
@ -1338,8 +1432,7 @@
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
@ -2186,8 +2279,7 @@
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||
"dev": true
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
|
||||
},
|
||||
"collection-map": {
|
||||
"version": "1.0.0",
|
||||
@ -2653,7 +2745,6 @@
|
||||
"version": "6.0.5",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
|
||||
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"nice-try": "^1.0.4",
|
||||
"path-key": "^2.0.1",
|
||||
@ -2728,8 +2819,7 @@
|
||||
"decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
|
||||
"dev": true
|
||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
|
||||
},
|
||||
"decamelize-keys": {
|
||||
"version": "1.1.0",
|
||||
@ -3037,7 +3127,6 @@
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
||||
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.4.0"
|
||||
},
|
||||
@ -3046,7 +3135,6 @@
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@ -3287,7 +3375,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
|
||||
"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cross-spawn": "^6.0.0",
|
||||
"get-stream": "^4.0.0",
|
||||
@ -4387,8 +4474,7 @@
|
||||
"get-caller-file": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
|
||||
"integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w=="
|
||||
},
|
||||
"get-pkg-repo": {
|
||||
"version": "1.4.0",
|
||||
@ -4501,7 +4587,6 @@
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
||||
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pump": "^3.0.0"
|
||||
},
|
||||
@ -4510,7 +4595,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
@ -5346,8 +5430,7 @@
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
|
||||
},
|
||||
"is-glob": {
|
||||
"version": "4.0.0",
|
||||
@ -5423,8 +5506,7 @@
|
||||
"is-stream": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
|
||||
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
|
||||
"dev": true
|
||||
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
|
||||
},
|
||||
"is-subset": {
|
||||
"version": "0.1.1",
|
||||
@ -5483,8 +5565,7 @@
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
||||
"dev": true
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
|
||||
},
|
||||
"isobject": {
|
||||
"version": "3.0.1",
|
||||
@ -6002,7 +6083,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
|
||||
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-locate": "^3.0.0",
|
||||
"path-exists": "^3.0.0"
|
||||
@ -6011,8 +6091,7 @@
|
||||
"path-exists": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
|
||||
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
|
||||
"dev": true
|
||||
"integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -6143,7 +6222,6 @@
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
|
||||
"integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-defer": "^1.0.0"
|
||||
}
|
||||
@ -6212,7 +6290,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz",
|
||||
"integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"map-age-cleaner": "^0.1.1",
|
||||
"mimic-fn": "^1.0.0",
|
||||
@ -6402,8 +6479,7 @@
|
||||
"mimic-fn": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
|
||||
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
@ -6618,8 +6694,7 @@
|
||||
"nice-try": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
|
||||
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
|
||||
},
|
||||
"node-fetch-npm": {
|
||||
"version": "2.0.2",
|
||||
@ -6807,7 +6882,6 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
|
||||
"integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-key": "^2.0.0"
|
||||
}
|
||||
@ -6827,8 +6901,7 @@
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||
"dev": true
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
|
||||
},
|
||||
"nyc": {
|
||||
"version": "13.1.0",
|
||||
@ -8084,7 +8157,6 @@
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz",
|
||||
"integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@ -8211,26 +8283,22 @@
|
||||
"p-defer": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
|
||||
"integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
|
||||
"dev": true
|
||||
"integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww="
|
||||
},
|
||||
"p-finally": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
|
||||
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
|
||||
"dev": true
|
||||
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
|
||||
},
|
||||
"p-is-promise": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
|
||||
"integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=",
|
||||
"dev": true
|
||||
"integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4="
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz",
|
||||
"integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-try": "^2.0.0"
|
||||
}
|
||||
@ -8239,7 +8307,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
|
||||
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"p-limit": "^2.0.0"
|
||||
}
|
||||
@ -8274,8 +8341,7 @@
|
||||
"p-try": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz",
|
||||
"integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ=="
|
||||
},
|
||||
"p-waterfall": {
|
||||
"version": "1.0.0",
|
||||
@ -8459,8 +8525,7 @@
|
||||
"path-key": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
|
||||
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
|
||||
"dev": true
|
||||
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.6",
|
||||
@ -9008,14 +9073,12 @@
|
||||
"require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
|
||||
"dev": true
|
||||
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
|
||||
},
|
||||
"require-main-filename": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
|
||||
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
|
||||
"dev": true
|
||||
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
|
||||
},
|
||||
"requizzle": {
|
||||
"version": "0.2.1",
|
||||
@ -9171,8 +9234,7 @@
|
||||
"semver": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
|
||||
"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="
|
||||
},
|
||||
"semver-greatest-satisfied-range": {
|
||||
"version": "1.1.0",
|
||||
@ -9186,8 +9248,7 @@
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
||||
"dev": true
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
|
||||
},
|
||||
"set-value": {
|
||||
"version": "2.0.0",
|
||||
@ -9216,7 +9277,6 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
|
||||
"integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"shebang-regex": "^1.0.0"
|
||||
}
|
||||
@ -9224,8 +9284,7 @@
|
||||
"shebang-regex": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
|
||||
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
|
||||
"dev": true
|
||||
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
|
||||
},
|
||||
"sigmund": {
|
||||
"version": "1.0.1",
|
||||
@ -9236,8 +9295,7 @@
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
||||
"dev": true
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
|
||||
},
|
||||
"slash": {
|
||||
"version": "1.0.0",
|
||||
@ -9578,7 +9636,6 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
|
||||
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-fullwidth-code-point": "^2.0.0",
|
||||
"strip-ansi": "^4.0.0"
|
||||
@ -9587,14 +9644,12 @@
|
||||
"ansi-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
|
||||
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
|
||||
"dev": true
|
||||
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
|
||||
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^3.0.0"
|
||||
}
|
||||
@ -9620,7 +9675,6 @@
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
@ -9637,8 +9691,7 @@
|
||||
"strip-eof": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
|
||||
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
|
||||
},
|
||||
"strip-indent": {
|
||||
"version": "2.0.0",
|
||||
@ -10439,7 +10492,6 @@
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
@ -10469,7 +10521,6 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
|
||||
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^1.0.1",
|
||||
"strip-ansi": "^3.0.1"
|
||||
@ -10479,7 +10530,6 @@
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@ -10488,7 +10538,6 @@
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
@ -10500,8 +10549,7 @@
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"write": {
|
||||
"version": "0.2.1",
|
||||
@ -10569,8 +10617,7 @@
|
||||
"y18n": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
|
||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
|
||||
"dev": true
|
||||
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "2.1.2",
|
||||
|
||||
@ -14,11 +14,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/parser": "~7.2.3",
|
||||
"@jsdoc/cli": "file:packages/jsdoc-cli",
|
||||
"@jsdoc/config": "file:packages/jsdoc-config",
|
||||
"@jsdoc/logger": "file:packages/jsdoc-logger",
|
||||
"@jsdoc/syntax": "file:packages/jsdoc-syntax",
|
||||
"@jsdoc/template-original": "file:packages/jsdoc-template-original",
|
||||
"@jsdoc/template-silent": "file:packages/jsdoc-template-silent",
|
||||
"@jsdoc/util": "file:packages/jsdoc-util",
|
||||
"bluebird": "~3.5.0",
|
||||
"catharsis": "~0.8.9",
|
||||
"escape-string-regexp": "~1.0.5",
|
||||
|
||||
11
packages/jsdoc-cli/README.md
Normal file
11
packages/jsdoc-cli/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# @jsdoc/cli
|
||||
|
||||
The code that powers JSDoc's command-line interface.
|
||||
|
||||
## Installing the package
|
||||
|
||||
Using npm:
|
||||
|
||||
```shell
|
||||
npm install --save @jsdoc/cli
|
||||
```
|
||||
9
packages/jsdoc-cli/index.js
Normal file
9
packages/jsdoc-cli/index.js
Normal file
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @module @jsdoc/cli
|
||||
*/
|
||||
|
||||
const args = require('./lib/args');
|
||||
const help = require('./lib/help');
|
||||
|
||||
exports.args = args;
|
||||
exports.help = help;
|
||||
176
packages/jsdoc-cli/lib/args.js
Normal file
176
packages/jsdoc-cli/lib/args.js
Normal file
@ -0,0 +1,176 @@
|
||||
/**
|
||||
* @module @jsdoc/cli/lib/args
|
||||
*/
|
||||
|
||||
const _ = require('lodash');
|
||||
const cast = require('@jsdoc/util').cast;
|
||||
const querystring = require('querystring');
|
||||
const yargs = require('yargs-parser');
|
||||
|
||||
const ARGS = exports.ARGS = {
|
||||
access: {
|
||||
alias: 'a',
|
||||
array: true,
|
||||
choices: ['all', 'package', 'private', 'protected', 'public', 'undefined'],
|
||||
defaultDescription: 'All except `private`',
|
||||
description: 'Document only symbols with the specified access level.',
|
||||
requiresArg: true
|
||||
},
|
||||
configure: {
|
||||
alias: 'c',
|
||||
description: 'The configuration file to use.',
|
||||
normalize: true,
|
||||
requiresArg: true
|
||||
},
|
||||
debug: {
|
||||
boolean: true,
|
||||
description: 'Log information to help with debugging.'
|
||||
},
|
||||
destination: {
|
||||
alias: 'd',
|
||||
default: './out',
|
||||
description: 'The output directory.',
|
||||
normalize: true,
|
||||
requiresArg: true
|
||||
},
|
||||
encoding: {
|
||||
alias: 'e',
|
||||
default: 'utf8',
|
||||
description: 'The encoding to assume when reading source files.',
|
||||
requiresArg: true
|
||||
},
|
||||
explain: {
|
||||
alias: 'X',
|
||||
boolean: true,
|
||||
description: 'Print the parse results to the console and exit.'
|
||||
},
|
||||
help: {
|
||||
alias: 'h',
|
||||
boolean: true,
|
||||
description: 'Print help information and exit.'
|
||||
},
|
||||
match: {
|
||||
description: 'Run only tests whose names contain this value.',
|
||||
requiresArg: true
|
||||
},
|
||||
package: {
|
||||
alias: 'P',
|
||||
description: 'The path to the `package.json` file to use.',
|
||||
normalize: true,
|
||||
requiresArg: true
|
||||
},
|
||||
pedantic: {
|
||||
boolean: true,
|
||||
description: 'Treat errors as fatal errors, and treat warnings as errors.'
|
||||
},
|
||||
private: {
|
||||
alias: 'p',
|
||||
boolean: true,
|
||||
description: 'Document private symbols (equivalent to `--access all`).'
|
||||
},
|
||||
query: {
|
||||
alias: 'q',
|
||||
coerce: ((str) => cast(querystring.parse(str))),
|
||||
description: 'A query string to parse and store (for example, `foo=bar&baz=true`).',
|
||||
requiresArg: true
|
||||
},
|
||||
readme: {
|
||||
alias: 'R',
|
||||
boolean: true,
|
||||
description: 'The `README` file to include in the documentation.',
|
||||
normalize: true,
|
||||
requiresArg: true
|
||||
},
|
||||
recurse: {
|
||||
alias: 'r',
|
||||
boolean: true,
|
||||
description: 'Recurse into subdirectories to find source files.'
|
||||
},
|
||||
template: {
|
||||
alias: 't',
|
||||
description: 'The template package to use.',
|
||||
requiresArg: true
|
||||
},
|
||||
test: {
|
||||
alias: 'T',
|
||||
boolean: true,
|
||||
description: 'Run all tests and exit.'
|
||||
},
|
||||
tutorials: {
|
||||
alias: 'u',
|
||||
description: 'The directory to search for tutorials.',
|
||||
normalize: true,
|
||||
requiresArg: true
|
||||
},
|
||||
verbose: {
|
||||
boolean: true,
|
||||
description: 'Log detailed information to the console.'
|
||||
},
|
||||
version: {
|
||||
alias: 'v',
|
||||
boolean: true,
|
||||
description: 'Display the version number and exit.'
|
||||
}
|
||||
};
|
||||
|
||||
function validateValue(arg, choices, values) {
|
||||
for (let value of values) {
|
||||
if (!choices.includes(value)) {
|
||||
throw new Error(`The argument --${arg} accepts only these values: ${choices}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const YARGS_OPTS = (() => {
|
||||
const opts = {
|
||||
alias: {},
|
||||
array: [],
|
||||
boolean: [],
|
||||
coerce: {},
|
||||
narg: {},
|
||||
normalize: []
|
||||
};
|
||||
|
||||
Object.keys(ARGS).forEach(arg => {
|
||||
const value = ARGS[arg];
|
||||
|
||||
if (value.alias) {
|
||||
opts.alias[arg] = [value.alias];
|
||||
}
|
||||
|
||||
if (value.array) {
|
||||
opts.array.push(arg);
|
||||
}
|
||||
|
||||
if (value.boolean) {
|
||||
opts.boolean.push(arg);
|
||||
}
|
||||
|
||||
if (value.coerce) {
|
||||
opts.coerce[arg] = value.coerce;
|
||||
}
|
||||
|
||||
if (value.normalize) {
|
||||
opts.normalize.push(arg);
|
||||
}
|
||||
|
||||
if (value.requiresArg) {
|
||||
opts.narg[arg] = 1;
|
||||
}
|
||||
});
|
||||
|
||||
return opts;
|
||||
})();
|
||||
|
||||
exports.parse = (args => {
|
||||
const knownArgs = Object.keys(ARGS);
|
||||
const parsed = yargs(args, YARGS_OPTS);
|
||||
|
||||
knownArgs.forEach(arg => {
|
||||
if (parsed[arg] && ARGS[arg].choices) {
|
||||
validateValue(arg, ARGS[arg].choices, parsed[arg]);
|
||||
}
|
||||
});
|
||||
|
||||
return _.pick(parsed, knownArgs.concat(['_']));
|
||||
});
|
||||
115
packages/jsdoc-cli/lib/help.js
Normal file
115
packages/jsdoc-cli/lib/help.js
Normal file
@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @module @jsdoc/cli/lib/help
|
||||
*/
|
||||
|
||||
const ARGS = require('./args').ARGS;
|
||||
|
||||
function padLeft(str, length) {
|
||||
return str.padStart(str.length + length);
|
||||
}
|
||||
|
||||
function padRight(str, length) {
|
||||
return str.padEnd(str.length + length);
|
||||
}
|
||||
|
||||
function findMaxLength(arr) {
|
||||
let max = 0;
|
||||
|
||||
arr.forEach(({length}) => {
|
||||
max = Math.max(max, length);
|
||||
});
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
function concatWithMaxLength(items, maxLength) {
|
||||
let result = '';
|
||||
|
||||
// to prevent endless loops, always use the first item, regardless of length
|
||||
result += items.shift();
|
||||
|
||||
while (items.length && (result.length + items[0].length < maxLength)) {
|
||||
result += ` ${items.shift()}`;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// We want to format names and descriptions like this:
|
||||
// | -f, --foo Very long description very long description very long |
|
||||
// | description very long description. |
|
||||
function formatHelpInfo({names, descriptions}) {
|
||||
const MARGIN_LENGTH = 4;
|
||||
const results = [];
|
||||
|
||||
const maxLength = process.stdout.columns;
|
||||
const maxNameLength = findMaxLength(names);
|
||||
const wrapDescriptionAt = maxLength - (MARGIN_LENGTH * 3) - maxNameLength;
|
||||
|
||||
// build the string for each option
|
||||
names.forEach((name, i) => {
|
||||
let result;
|
||||
let partialDescription;
|
||||
let words;
|
||||
|
||||
// add a left margin to the name
|
||||
result = padLeft(names[i], MARGIN_LENGTH);
|
||||
// and a right margin, with extra padding so the descriptions line up with one another
|
||||
result = padRight(result, maxNameLength - names[i].length + MARGIN_LENGTH);
|
||||
|
||||
// split the description on spaces
|
||||
words = descriptions[i].split(' ');
|
||||
// add as much of the description as we can fit on the first line
|
||||
result += concatWithMaxLength(words, wrapDescriptionAt);
|
||||
// if there's anything left, keep going until we've consumed the description
|
||||
while (words.length) {
|
||||
partialDescription = padLeft('', maxNameLength + (MARGIN_LENGTH * 2));
|
||||
partialDescription += concatWithMaxLength(words, wrapDescriptionAt);
|
||||
result += `\n${partialDescription}`;
|
||||
}
|
||||
|
||||
results.push(result);
|
||||
});
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
module.exports = (() => {
|
||||
const options = {
|
||||
names: [],
|
||||
descriptions: []
|
||||
};
|
||||
|
||||
Object.keys(ARGS)
|
||||
.sort()
|
||||
.forEach(arg => {
|
||||
const opts = ARGS[arg];
|
||||
let description = '';
|
||||
let name = '';
|
||||
|
||||
if (opts.alias) {
|
||||
name += `-${opts.alias}, `;
|
||||
}
|
||||
|
||||
name += `--${arg}`;
|
||||
|
||||
if (opts.requiresArg) {
|
||||
name += ' <value>';
|
||||
}
|
||||
|
||||
description += opts.description;
|
||||
|
||||
if (opts.array) {
|
||||
description += ' Can be specified more than once.';
|
||||
}
|
||||
|
||||
if (opts.choices) {
|
||||
description += ` Accepts these values: ${opts.choices.join(', ')}`;
|
||||
}
|
||||
|
||||
options.names.push(name);
|
||||
options.descriptions.push(description);
|
||||
});
|
||||
|
||||
return `Options:\n${formatHelpInfo(options).join('\n')}`;
|
||||
})();
|
||||
35
packages/jsdoc-cli/package-lock.json
generated
Normal file
35
packages/jsdoc-cli/package-lock.json
generated
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "@jsdoc/cli",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@jsdoc/util": {
|
||||
"version": "file:../jsdoc-util"
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz",
|
||||
"integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA=="
|
||||
},
|
||||
"decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.11",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
|
||||
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "11.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz",
|
||||
"integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==",
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
27
packages/jsdoc-cli/package.json
Normal file
27
packages/jsdoc-cli/package.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "@jsdoc/cli",
|
||||
"version": "1.0.0",
|
||||
"description": "The code that powers JSDoc's command-line interface.",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jsdoc3/jsdoc"
|
||||
},
|
||||
"keywords": [
|
||||
"jsdoc"
|
||||
],
|
||||
"author": {
|
||||
"name": "Jeff Williams",
|
||||
"email": "jeffrey.l.williams@gmail.com"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/jsdoc3/jsdoc/issues"
|
||||
},
|
||||
"homepage": "https://github.com/jsdoc3/jsdoc#readme",
|
||||
"dependencies": {
|
||||
"@jsdoc/util": "file:../jsdoc-util",
|
||||
"lodash": "^4.17.11",
|
||||
"yargs-parser": "^11.1.1"
|
||||
}
|
||||
}
|
||||
31
packages/jsdoc-cli/test/specs/index.js
Normal file
31
packages/jsdoc-cli/test/specs/index.js
Normal file
@ -0,0 +1,31 @@
|
||||
const cli = require('../../index');
|
||||
|
||||
describe('@jsdoc/cli', () => {
|
||||
it('is an object', () => {
|
||||
expect(cli).toBeObject();
|
||||
});
|
||||
|
||||
it('has an args object', () => {
|
||||
expect(cli.args).toBeObject();
|
||||
});
|
||||
|
||||
it('has a help string', () => {
|
||||
expect(cli.help).toBeString();
|
||||
});
|
||||
|
||||
describe('args', () => {
|
||||
it('is ./lib/args', () => {
|
||||
const args = require('../../lib/args');
|
||||
|
||||
expect(cli.args).toBe(args);
|
||||
});
|
||||
});
|
||||
|
||||
describe('help', () => {
|
||||
it('is ./lib/help', () => {
|
||||
const help = require('../../lib/help');
|
||||
|
||||
expect(cli.help).toBe(help);
|
||||
});
|
||||
});
|
||||
});
|
||||
99
packages/jsdoc-cli/test/specs/lib/args.js
Normal file
99
packages/jsdoc-cli/test/specs/lib/args.js
Normal file
@ -0,0 +1,99 @@
|
||||
const args = require('../../../lib/args');
|
||||
const ARGS = args.ARGS;
|
||||
|
||||
describe('@jsdoc/cli/lib/args', () => {
|
||||
it('exists', () => {
|
||||
expect(args).toBeObject();
|
||||
});
|
||||
|
||||
it('has an `ARGS` object', () => {
|
||||
expect(args.ARGS).toBeObject();
|
||||
});
|
||||
|
||||
it('has a `parse` function', () => {
|
||||
expect(args.parse).toBeFunction();
|
||||
});
|
||||
|
||||
describe('ARGS', () => {
|
||||
// No need to test this object directly.
|
||||
});
|
||||
|
||||
describe('parse', () => {
|
||||
it('accepts an array and returns an object', () => {
|
||||
const parsed = args.parse([]);
|
||||
|
||||
expect(parsed).toBeObject();
|
||||
});
|
||||
|
||||
it('parses all known options', () => {
|
||||
const argv = [];
|
||||
|
||||
Object.keys(ARGS).forEach(arg => {
|
||||
argv.push(`--${arg}`);
|
||||
|
||||
if (ARGS[arg].requiresArg) {
|
||||
argv.push(ARGS[arg].choices ? ARGS[arg].choices[0] : `value-for-${arg}`);
|
||||
}
|
||||
});
|
||||
|
||||
const parsed = args.parse(argv);
|
||||
|
||||
expect(Object.keys(parsed).sort())
|
||||
.toEqual(Object.keys(ARGS).concat(['_']).sort());
|
||||
});
|
||||
|
||||
it('puts extra arguments in the `_` array', () => {
|
||||
const parsed = args.parse(['foo.js']);
|
||||
|
||||
expect(parsed._).toEqual(['foo.js']);
|
||||
});
|
||||
|
||||
it('ignores unknown options', () => {
|
||||
const parsed = args.parse(['--foo']);
|
||||
|
||||
expect(parsed.foo).toBeUndefined();
|
||||
});
|
||||
|
||||
describe('--access', () => {
|
||||
it('is returned as an array even when specified only once', () => {
|
||||
const parsed = args.parse(['--access', 'public']);
|
||||
|
||||
expect(parsed.access).toEqual(['public']);
|
||||
});
|
||||
|
||||
it('accepts the argument more than once', () => {
|
||||
const parsed = args.parse([
|
||||
'--access',
|
||||
'protected',
|
||||
'--access',
|
||||
'public'
|
||||
]);
|
||||
|
||||
expect(parsed.access.sort()).toEqual(['protected', 'public']);
|
||||
});
|
||||
|
||||
it('throws on unknown values', () => {
|
||||
function badArg() {
|
||||
return args.parse(['--access', 'ibility']);
|
||||
}
|
||||
|
||||
expect(badArg).toThrowError();
|
||||
});
|
||||
});
|
||||
|
||||
describe('--query', () => {
|
||||
it('is returned as an object', () => {
|
||||
const parsed = args.parse(['--query', 'foo=bar']);
|
||||
|
||||
expect(parsed.query).toEqual({foo: 'bar'});
|
||||
});
|
||||
|
||||
it('coerces values to the appropriate types', () => {
|
||||
const parsed = args.parse(['--query', 'foo=true&bar=17']);
|
||||
|
||||
expect(parsed.query.foo).toBeTrue();
|
||||
expect(parsed.query.bar).toBe(17);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
14
packages/jsdoc-cli/test/specs/lib/help.js
Normal file
14
packages/jsdoc-cli/test/specs/lib/help.js
Normal file
@ -0,0 +1,14 @@
|
||||
const ARGS = require('../../../lib/args').ARGS;
|
||||
const help = require('../../../lib/help');
|
||||
|
||||
describe('@jsdoc/cli/lib/help', () => {
|
||||
it('is a string', () => {
|
||||
expect(help).toBeString();
|
||||
});
|
||||
|
||||
it('covers all known command-line arguments', () => {
|
||||
Object.keys(ARGS).forEach(arg => {
|
||||
expect(help.includes(arg)).toBeTrue();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
const _ = require('lodash');
|
||||
const cosmiconfig = require('cosmiconfig');
|
||||
const defaults = require('./defaults');
|
||||
const defaults = require('./lib/defaults');
|
||||
const stripBom = require('strip-bom');
|
||||
const stripJsonComments = require('strip-json-comments');
|
||||
|
||||
@ -44,6 +44,8 @@ const explorer = cosmiconfig(MODULE_NAME, {
|
||||
]
|
||||
});
|
||||
|
||||
exports.defaults = defaults;
|
||||
|
||||
exports.loadSync = (filepath) => {
|
||||
let loaded;
|
||||
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
/**
|
||||
* The default configuration settings for JSDoc.
|
||||
*
|
||||
* @module @jsdoc/config/defaults
|
||||
* @module @jsdoc/config/lib/defaults
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// TODO(hegemonic): integrate CLI options with other options
|
||||
opts: {
|
||||
access: ['package', 'protected', 'public', 'undefined'],
|
||||
destination: './out',
|
||||
encoding: 'utf8'
|
||||
},
|
||||
@ -1,7 +1,7 @@
|
||||
describe('@jsdoc/config', () => {
|
||||
const mockFs = require('mock-fs');
|
||||
const config = require('../../index');
|
||||
const defaults = require('../../defaults');
|
||||
const defaults = require('../../lib/defaults');
|
||||
|
||||
afterEach(() => mockFs.restore());
|
||||
|
||||
@ -9,10 +9,20 @@ describe('@jsdoc/config', () => {
|
||||
expect(config).toBeObject();
|
||||
});
|
||||
|
||||
it('has a defaults object', () => {
|
||||
expect(config.defaults).toBeObject();
|
||||
});
|
||||
|
||||
it('has a loadSync method', () => {
|
||||
expect(config.loadSync).toBeFunction();
|
||||
});
|
||||
|
||||
describe('defaults', () => {
|
||||
it('is ./lib/defaults', () => {
|
||||
expect(config.defaults).toBe(defaults);
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadSync', () => {
|
||||
it('returns an object with `config` and `filepath` properties', () => {
|
||||
mockFs({
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const defaults = require('../../defaults');
|
||||
const defaults = require('../../../lib/defaults');
|
||||
|
||||
describe('@jsdoc/config/defaults', () => {
|
||||
describe('@jsdoc/config/lib/defaults', () => {
|
||||
it('exists', () => {
|
||||
expect(defaults).toBeObject();
|
||||
});
|
||||
11
packages/jsdoc-util/README.md
Normal file
11
packages/jsdoc-util/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# @jsdoc/util
|
||||
|
||||
Utility modules for JSDoc.
|
||||
|
||||
## Installing the package
|
||||
|
||||
Using npm:
|
||||
|
||||
```shell
|
||||
npm install --save @jsdoc/util
|
||||
```
|
||||
7
packages/jsdoc-util/index.js
Normal file
7
packages/jsdoc-util/index.js
Normal file
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* @module @jsdoc/util
|
||||
*/
|
||||
|
||||
const cast = require('./lib/cast');
|
||||
|
||||
exports.cast = cast;
|
||||
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Module to convert values between various JavaScript types.
|
||||
* @module
|
||||
* @private
|
||||
*
|
||||
* @module @jsdoc/util/lib/cast
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -65,11 +65,10 @@ function castString(str) {
|
||||
* If an object or array is passed to this method, the object or array's values will be recursively
|
||||
* converted to the appropriate types. The original object or array is not modified.
|
||||
*
|
||||
* @private
|
||||
* @param {(string|Object|Array)} item - The item whose type will be converted.
|
||||
* @return {(string|number|boolean|Object|Array)} The converted value.
|
||||
*/
|
||||
exports.cast = function cast(item) {
|
||||
const cast = module.exports = (item => {
|
||||
let result;
|
||||
|
||||
if (Array.isArray(item)) {
|
||||
@ -92,4 +91,4 @@ exports.cast = function cast(item) {
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
});
|
||||
5
packages/jsdoc-util/package-lock.json
generated
Normal file
5
packages/jsdoc-util/package-lock.json
generated
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "@jsdoc/util",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1
|
||||
}
|
||||
22
packages/jsdoc-util/package.json
Normal file
22
packages/jsdoc-util/package.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "@jsdoc/util",
|
||||
"version": "1.0.0",
|
||||
"description": "Utility modules for JSDoc.",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jsdoc3/jsdoc"
|
||||
},
|
||||
"keywords": [
|
||||
"jsdoc"
|
||||
],
|
||||
"author": {
|
||||
"name": "Jeff Williams",
|
||||
"email": "jeffrey.l.williams@gmail.com"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/jsdoc3/jsdoc/issues"
|
||||
},
|
||||
"homepage": "https://github.com/jsdoc3/jsdoc#readme"
|
||||
}
|
||||
19
packages/jsdoc-util/test/specs/index.js
Normal file
19
packages/jsdoc-util/test/specs/index.js
Normal file
@ -0,0 +1,19 @@
|
||||
const util = require('../../index');
|
||||
|
||||
describe('@jsdoc/util', () => {
|
||||
it('is an object', () => {
|
||||
expect(util).toBeObject();
|
||||
});
|
||||
|
||||
it('has a cast method', () => {
|
||||
expect(util.cast).toBeFunction();
|
||||
});
|
||||
|
||||
describe('cast', () => {
|
||||
it('is ./lib/cast', () => {
|
||||
const cast = require('../../lib/cast');
|
||||
|
||||
expect(util.cast).toBe(cast);
|
||||
});
|
||||
});
|
||||
});
|
||||
89
packages/jsdoc-util/test/specs/lib/cast.js
Normal file
89
packages/jsdoc-util/test/specs/lib/cast.js
Normal file
@ -0,0 +1,89 @@
|
||||
const cast = require('../../../lib/cast');
|
||||
|
||||
describe('@jsdoc/util/lib/cast', () => {
|
||||
it('exists', () => {
|
||||
expect(cast).toBeFunction();
|
||||
});
|
||||
|
||||
it('does not modify values that are not strings, objects, or arrays', () => {
|
||||
const result = cast(8);
|
||||
|
||||
expect(result).toBe(8);
|
||||
});
|
||||
|
||||
it('does not modify strings that are not boolean-ish or number-ish', () => {
|
||||
const result = cast('hello world');
|
||||
|
||||
expect(result).toBe('hello world');
|
||||
});
|
||||
|
||||
it('casts boolean-ish values to booleans', () => {
|
||||
const truthish = cast('true');
|
||||
const falsish = cast('false');
|
||||
|
||||
expect(truthish).toBeTrue();
|
||||
expect(falsish).toBeFalse();
|
||||
});
|
||||
|
||||
it('casts null-ish values to null', () => {
|
||||
const nullish = cast('null');
|
||||
|
||||
expect(nullish).toBeNull();
|
||||
});
|
||||
|
||||
it('casts undefined-ish values to undefined', () => {
|
||||
const undefinedish = cast('undefined');
|
||||
|
||||
expect(undefinedish).toBeUndefined();
|
||||
});
|
||||
|
||||
it('casts positive number-ish values to numbers', () => {
|
||||
const positive = cast('17.35');
|
||||
|
||||
expect(positive).toBe(17.35);
|
||||
});
|
||||
|
||||
it('casts negative number-ish values to numbers', () => {
|
||||
const negative = cast('-17.35');
|
||||
|
||||
expect(negative).toBe(-17.35);
|
||||
});
|
||||
|
||||
it('casts NaN-ish values to NaN', () => {
|
||||
const nan = cast('NaN');
|
||||
|
||||
expect(nan).toBeNaN();
|
||||
});
|
||||
|
||||
it('converts values in an object', () => {
|
||||
const result = cast({ foo: 'true' });
|
||||
|
||||
expect(result).toEqual({ foo: true });
|
||||
});
|
||||
|
||||
it('converts values in nested objects', () => {
|
||||
const result = cast({
|
||||
foo: {
|
||||
bar: 'true'
|
||||
}
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
foo: {
|
||||
bar: true
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('converts values in an array', () => {
|
||||
const result = cast(['true', '17.35']);
|
||||
|
||||
expect(result).toEqual([true, 17.35]);
|
||||
});
|
||||
|
||||
it('converts values in a nested array', () => {
|
||||
const result = cast(['true', ['17.35']]);
|
||||
|
||||
expect(result).toEqual([true, [17.35]]);
|
||||
});
|
||||
});
|
||||
@ -1,168 +0,0 @@
|
||||
describe('jsdoc/opts/argparser', () => {
|
||||
const ArgParser = require('jsdoc/opts/argparser');
|
||||
let argParser;
|
||||
let ourOptions;
|
||||
|
||||
function trueFalse(v) {
|
||||
let r = false;
|
||||
|
||||
if (v) {
|
||||
if (v === 'true') { r = true; }
|
||||
else if (v === 'false') { r = false; }
|
||||
else { v = Boolean(r); }
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
argParser = new ArgParser()
|
||||
.addOption('s', 'strict', true, 'Throw error on invalid input.', false, trueFalse)
|
||||
.addOption('n', 'name', true, 'The name of the project.', false);
|
||||
|
||||
ourOptions = argParser.parse(['-s', 'true', '-n', 'true']);
|
||||
});
|
||||
|
||||
it('should exist', () => {
|
||||
expect(ArgParser).toBeDefined();
|
||||
});
|
||||
|
||||
it('should be a constructor', () => {
|
||||
expect(typeof ArgParser).toBe('function');
|
||||
expect(new ArgParser() instanceof ArgParser).toBe(true);
|
||||
});
|
||||
|
||||
describe('ArgParser', () => {
|
||||
it('should provide an "addIgnoredOption" method', () => {
|
||||
expect(argParser.addIgnoredOption).toBeDefined();
|
||||
expect(typeof argParser.addIgnoredOption).toBe('function');
|
||||
});
|
||||
|
||||
it('should provide an "addOption" method', () => {
|
||||
expect(argParser.addOption).toBeDefined();
|
||||
expect(typeof argParser.addOption).toBe('function');
|
||||
});
|
||||
|
||||
it('should provide a "help" method', () => {
|
||||
expect(argParser.help).toBeDefined();
|
||||
expect(typeof argParser.help).toBe('function');
|
||||
});
|
||||
|
||||
it('should provide a "parse" method', () => {
|
||||
expect(argParser.parse).toBeDefined();
|
||||
expect(typeof argParser.parse).toBe('function');
|
||||
});
|
||||
|
||||
describe('addIgnoredOption', () => {
|
||||
it('should be chainable', () => {
|
||||
expect(argParser.addIgnoredOption({})).toBe(argParser);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addOption', () => {
|
||||
it('should be chainable', () => {
|
||||
expect(argParser.addOption('a', null, false, 'Option')).toBe(argParser);
|
||||
});
|
||||
});
|
||||
|
||||
describe('help', () => {
|
||||
const columns = process.stdout.columns;
|
||||
|
||||
beforeEach(() => {
|
||||
process.stdout.columns = 80;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
process.stdout.columns = columns;
|
||||
});
|
||||
|
||||
it('should format the help text correctly', () => {
|
||||
const helpText = [
|
||||
'Options:',
|
||||
' --noshortname Just a long name.',
|
||||
' -o <value> Only a short name.',
|
||||
' -s, --supercalifragilisticexpialidocious If you say it loud enough,',
|
||||
" you'll always sound",
|
||||
' precocious.'
|
||||
].join('\n');
|
||||
|
||||
argParser = new ArgParser()
|
||||
.addIgnoredOption('m', 'meh', false, 'Ignore me.')
|
||||
.addOption(null, 'noshortname', false, 'Just a long name.')
|
||||
.addOption('o', null, true, 'Only a short name.')
|
||||
.addOption('s', 'supercalifragilisticexpialidocious', false,
|
||||
"If you say it loud enough, you'll always sound precocious.");
|
||||
|
||||
expect(argParser.help()).toBe(helpText);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parse', () => {
|
||||
it('should return an object with information about the options', () => {
|
||||
expect(typeof ourOptions).toBe('object');
|
||||
expect(ourOptions.strict).toBe(true);
|
||||
expect(ourOptions.name).toBe('true');
|
||||
});
|
||||
|
||||
it('should merge the defaults into the command-line options', () => {
|
||||
const defaults = {
|
||||
strict: false,
|
||||
name: 'Hello world!'
|
||||
};
|
||||
|
||||
ourOptions = argParser.parse(['-s', true], defaults);
|
||||
|
||||
expect(ourOptions.strict).toBe(true);
|
||||
expect(ourOptions.name).toBe(defaults.name);
|
||||
});
|
||||
|
||||
it('should recognize options that can be used more than once', () => {
|
||||
argParser.addOption(null, 'multi', true, '', true);
|
||||
|
||||
ourOptions = argParser.parse(['--multi', 'value1', '--multi', 'value2',
|
||||
'--multi', 'value3']);
|
||||
expect(Array.isArray(ourOptions.multi)).toBe(true);
|
||||
expect(ourOptions.multi.length).toBe(3);
|
||||
expect(ourOptions.multi[0]).toBe('value1');
|
||||
expect(ourOptions.multi[1]).toBe('value2');
|
||||
expect(ourOptions.multi[2]).toBe('value3');
|
||||
});
|
||||
|
||||
it('should throw an error if an unrecognized short option is used', () => {
|
||||
function badShortOption() {
|
||||
argParser.parse(['-w']);
|
||||
}
|
||||
|
||||
expect(badShortOption).toThrow();
|
||||
});
|
||||
|
||||
it('should throw an error if an unrecognized long option is used', () => {
|
||||
function badLongOption() {
|
||||
argParser.parse(['--whatever']);
|
||||
}
|
||||
|
||||
expect(badLongOption).toThrow();
|
||||
});
|
||||
|
||||
it('should throw an error if a required value is missing', () => {
|
||||
function missingValue() {
|
||||
argParser.parse(['--requires-value']);
|
||||
}
|
||||
|
||||
argParser.addOption(null, 'requires-value', true, '');
|
||||
|
||||
expect(missingValue).toThrow();
|
||||
});
|
||||
|
||||
it('should coerce a true value if a coercer is provided', () => {
|
||||
expect(ourOptions.strict).toBeDefined();
|
||||
expect(ourOptions.strict).toBe(true);
|
||||
});
|
||||
|
||||
it('should coerce a string value if no coercer is provided', () => {
|
||||
expect(ourOptions.name).toBeDefined();
|
||||
expect(ourOptions.name).toBe('true');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,344 +0,0 @@
|
||||
describe('jsdoc/opts/args', () => {
|
||||
const args = require('jsdoc/opts/args');
|
||||
const querystring = require('querystring');
|
||||
|
||||
it('should exist', () => {
|
||||
expect(args).toBeDefined();
|
||||
expect(typeof args).toBe('object');
|
||||
});
|
||||
|
||||
it('should export a "parse" function', () => {
|
||||
expect(args.parse).toBeDefined();
|
||||
expect(typeof args.parse).toBe('function');
|
||||
});
|
||||
|
||||
it('should export a "help" function', () => {
|
||||
expect(args.help).toBeDefined();
|
||||
expect(typeof args.help).toBe('function');
|
||||
});
|
||||
|
||||
it('should export a "get" function', () => {
|
||||
expect(args.get).toBeDefined();
|
||||
expect(typeof args.get).toBe('function');
|
||||
});
|
||||
|
||||
describe('parse', () => {
|
||||
it('should accept a "-t" option and return an object with a "template" property', () => {
|
||||
args.parse(['-t', 'mytemplate']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.template).toBe('mytemplate');
|
||||
});
|
||||
|
||||
it('should accept a "--template" option and return an object with a "template" property', () => {
|
||||
args.parse(['--template', 'mytemplate']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.template).toBe('mytemplate');
|
||||
});
|
||||
|
||||
it('should accept a "-c" option with a JSON file and return an object with a "configure" property', () => {
|
||||
args.parse(['-c', 'myconf.json']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.configure).toBe('myconf.json');
|
||||
});
|
||||
|
||||
it('should accept a "-c" option with a JS file and return an object with a "configure" property', () => {
|
||||
args.parse(['-c', 'myconf.js']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.configure).toBe('myconf.js');
|
||||
});
|
||||
|
||||
it('should accept a "--configure" option with a JSON file and return an object with a "configure" property', () => {
|
||||
args.parse(['--configure', 'myconf.json']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.configure).toBe('myconf.json');
|
||||
});
|
||||
|
||||
it('should accept a "--configure" option with a JS file and return an object with a "configure" property', () => {
|
||||
args.parse(['--configure', 'myconf.js']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.configure).toBe('myconf.js');
|
||||
});
|
||||
|
||||
it('should accept an "-e" option and return an object with a "encoding" property', () => {
|
||||
args.parse(['-e', 'ascii']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.encoding).toBe('ascii');
|
||||
});
|
||||
|
||||
it('should accept an "--encoding" option and return an object with an "encoding" property', () => {
|
||||
args.parse(['--encoding', 'ascii']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.encoding).toBe('ascii');
|
||||
});
|
||||
|
||||
it('should accept a "-T" option and return an object with a "test" property', () => {
|
||||
args.parse(['-T']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.test).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept a "--test" option and return an object with a "test" property', () => {
|
||||
args.parse(['--test']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.test).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept a "-d" option and return an object with a "destination" property', () => {
|
||||
args.parse(['-d', 'mydestination']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.destination).toBe('mydestination');
|
||||
});
|
||||
|
||||
it('should accept a "--destination" option and return an object with a "destination" property', () => {
|
||||
args.parse(['--destination', 'mydestination']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.destination).toBe('mydestination');
|
||||
});
|
||||
|
||||
it('should accept a "-p" option and return an object with a "private" property', () => {
|
||||
args.parse(['-p']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.private).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept a "--private" option and return an object with a "private" property', () => {
|
||||
args.parse(['--private']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.private).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept a "-a" option and return an object with an "access" property', () => {
|
||||
args.parse(['-a', 'public']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.access).toBe('public');
|
||||
});
|
||||
|
||||
it('should accept a "--access" option and return an object with an "access" property', () => {
|
||||
args.parse(['--access', 'public']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.access).toBe('public');
|
||||
});
|
||||
|
||||
it('should accept multiple "--access" options and return an object with an "access" property', () => {
|
||||
args.parse(['--access', 'public', '--access', 'protected']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.access).toContain('public');
|
||||
expect(r.access).toContain('protected');
|
||||
});
|
||||
|
||||
it('should accept a "-r" option and return an object with a "recurse" property', () => {
|
||||
args.parse(['-r']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.recurse).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept a "--recurse" option and return an object with a "recurse" property', () => {
|
||||
args.parse(['--recurse']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.recurse).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept a "-l" option and ignore it', () => {
|
||||
args.parse(['-l']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.lenient).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should accept a "--lenient" option and ignore it', () => {
|
||||
args.parse(['--lenient']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.lenient).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should accept a "-h" option and return an object with a "help" property', () => {
|
||||
args.parse(['-h']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.help).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept a "--help" option and return an object with a "help" property', () => {
|
||||
args.parse(['--help']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.help).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept an "-X" option and return an object with an "explain" property', () => {
|
||||
args.parse(['-X']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.explain).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept an "--explain" option and return an object with an "explain" property', () => {
|
||||
args.parse(['--explain']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.explain).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept a "-q" option and return an object with a "query" property', () => {
|
||||
args.parse(['-q', 'foo=bar&fab=baz']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.query).toEqual({
|
||||
foo: 'bar',
|
||||
fab: 'baz'
|
||||
});
|
||||
});
|
||||
|
||||
it('should accept a "--query" option and return an object with a "query" property', () => {
|
||||
args.parse(['--query', 'foo=bar&fab=baz']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.query).toEqual({
|
||||
foo: 'bar',
|
||||
fab: 'baz'
|
||||
});
|
||||
});
|
||||
|
||||
it('should use type coercion on the "query" property so it has real booleans and numbers', () => {
|
||||
const obj = {
|
||||
foo: 'fab',
|
||||
bar: true,
|
||||
baz: false,
|
||||
qux: [1, -97]
|
||||
};
|
||||
let r;
|
||||
|
||||
args.parse(['-q', querystring.stringify(obj)]);
|
||||
r = args.get();
|
||||
|
||||
expect(r.query).toEqual(obj);
|
||||
});
|
||||
|
||||
it('should accept a "-u" option and return an object with a "tutorials" property', () => {
|
||||
args.parse(['-u', 'mytutorials']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.tutorials).toBe('mytutorials');
|
||||
});
|
||||
|
||||
it('should accept a "--tutorials" option and return an object with a "tutorials" property', () => {
|
||||
args.parse(['--tutorials', 'mytutorials']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.tutorials).toBe('mytutorials');
|
||||
});
|
||||
|
||||
it('should accept a "--debug" option and return an object with a "debug" property', () => {
|
||||
args.parse(['--debug']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.debug).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept a "--verbose" option and return an object with a "verbose" property', () => {
|
||||
args.parse(['--verbose']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.verbose).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept a "--pedantic" option and return an object with a "pedantic" property', () => {
|
||||
args.parse(['--pedantic']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.pedantic).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept a "--match" option and return an object with a "match" property', () => {
|
||||
args.parse(['--match', '.*tag']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.match).toBe('.*tag');
|
||||
});
|
||||
|
||||
it('should accept multiple "--match" options and return an object with a "match" property', () => {
|
||||
args.parse(['--match', '.*tag', '--match', 'parser']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.match).toEqual(['.*tag', 'parser']);
|
||||
});
|
||||
|
||||
it('should accept a "--nocolor" option and return an object with a "nocolor" property', () => {
|
||||
args.parse(['--nocolor']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.nocolor).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept a "-P" option and return an object with a "package" property', () => {
|
||||
args.parse(['-P', 'path/to/package/file.json']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.package).toBe('path/to/package/file.json');
|
||||
});
|
||||
|
||||
it('should accept a "--package" option and return an object with a "package" property', () => {
|
||||
args.parse(['--package', 'path/to/package/file.json']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.package).toBe('path/to/package/file.json');
|
||||
});
|
||||
|
||||
it('should accept a "-R" option and return an object with a "readme" property', () => {
|
||||
args.parse(['-R', 'path/to/readme/file.md']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.readme).toBe('path/to/readme/file.md');
|
||||
});
|
||||
|
||||
it('should accept a "--readme" option and return an object with a "readme" property', () => {
|
||||
args.parse(['--readme', 'path/to/readme/file.md']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.readme).toBe('path/to/readme/file.md');
|
||||
});
|
||||
|
||||
it('should accept a "-v" option and return an object with a "version" property', () => {
|
||||
args.parse(['-v']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.version).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept a "--version" option and return an object with a "version" property', () => {
|
||||
args.parse(['--version']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r.version).toBe(true);
|
||||
});
|
||||
|
||||
it('should accept a naked option (with no "-") and return an object with a "_" property', () => {
|
||||
args.parse(['myfile1', 'myfile2']);
|
||||
const r = args.get();
|
||||
|
||||
expect(r._).toEqual(['myfile1', 'myfile2']);
|
||||
});
|
||||
|
||||
// TODO: tests for args that must have values
|
||||
});
|
||||
});
|
||||
@ -1,96 +0,0 @@
|
||||
describe('jsdoc/util/cast', () => {
|
||||
const cast = require('jsdoc/util/cast');
|
||||
|
||||
it('should exist', () => {
|
||||
expect(typeof cast).toBe('object');
|
||||
});
|
||||
|
||||
it('should export a "cast" method', () => {
|
||||
expect(typeof cast.cast).toBe('function');
|
||||
});
|
||||
|
||||
describe('cast', () => {
|
||||
it('should not modify values that are not strings, objects, or arrays', () => {
|
||||
const result = cast.cast(8);
|
||||
|
||||
expect(result).toBe(8);
|
||||
});
|
||||
|
||||
it('should not modify strings that are not boolean-ish or number-ish', () => {
|
||||
const result = cast.cast('hello world');
|
||||
|
||||
expect(result).toBe('hello world');
|
||||
});
|
||||
|
||||
it('should cast boolean-ish values to booleans', () => {
|
||||
const truthish = cast.cast('true');
|
||||
const falsish = cast.cast('false');
|
||||
|
||||
expect(truthish).toBe(true);
|
||||
expect(falsish).toBe(false);
|
||||
});
|
||||
|
||||
it('should cast null-ish values to null', () => {
|
||||
const nullish = cast.cast('null');
|
||||
|
||||
expect(nullish).toBe(null);
|
||||
});
|
||||
|
||||
it('should cast undefined-ish values to undefined', () => {
|
||||
const undefinedish = cast.cast('undefined');
|
||||
|
||||
expect(undefinedish).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should cast positive number-ish values to numbers', () => {
|
||||
const positive = cast.cast('17.35');
|
||||
|
||||
expect(positive).toBe(17.35);
|
||||
});
|
||||
|
||||
it('should cast negative number-ish values to numbers', () => {
|
||||
const negative = cast.cast('-17.35');
|
||||
|
||||
expect(negative).toBe(-17.35);
|
||||
});
|
||||
|
||||
it('should cast NaN-ish values to NaN', () => {
|
||||
const nan = cast.cast('NaN');
|
||||
|
||||
expect(typeof nan).toBe('number');
|
||||
expect(isNaN(nan)).toBe(true);
|
||||
});
|
||||
|
||||
it('should convert values in an object', () => {
|
||||
const result = cast.cast({ foo: 'true' });
|
||||
|
||||
expect(result).toEqual({ foo: true });
|
||||
});
|
||||
|
||||
it('should convert values in nested objects', () => {
|
||||
const result = cast.cast({
|
||||
foo: {
|
||||
bar: 'true'
|
||||
}
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
foo: {
|
||||
bar: true
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should convert values in an array', () => {
|
||||
const result = cast.cast(['true', '17.35']);
|
||||
|
||||
expect(result).toEqual([true, 17.35]);
|
||||
});
|
||||
|
||||
it('should convert values in a nested array', () => {
|
||||
const result = cast.cast(['true', ['17.35']]);
|
||||
|
||||
expect(result).toEqual([true, [17.35]]);
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user