Socket
Socket
Sign inDemoInstall

@jsdoc/cli

Package Overview
Dependencies
66
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.3.9 to 0.3.10

266

lib/engine.js

@@ -17,86 +17,15 @@ /*

import EventEmitter from 'node:events';
import { Api, config as jsdocConfig } from '@jsdoc/core';
import { getLogFunctions } from '@jsdoc/util';
import _ from 'lodash';
import ow from 'ow';
import yargs from 'yargs-parser';
import flags from './flags.js';
import { flags, parseFlags } from './flags.js';
import help from './help.js';
import { LEVELS, Logger } from './logger.js';
function validateChoice(flagInfo, choices, values) {
let flagNames = flagInfo.alias ? `-${flagInfo.alias}/` : '';
const FATAL_ERROR_MESSAGE =
'Exiting JSDoc because an error occurred. See the previous log messages for details.';
flagNames += `--${flagInfo.name}`;
for (let value of values) {
if (!choices.includes(value)) {
throw new TypeError(`The flag ${flagNames} accepts only these values: ${choices.join(', ')}`);
}
}
}
/**
* `KNOWN_FLAGS` is a set of all known flag names, including the long and short forms.
*
* `YARGS_FLAGS` is details about the known command-line flags, but in a form that `yargs-parser`
* understands. (That form is relatively hard to read, so we build this object from the more
* readable `flags` object.)
*
* @private
*/
const { KNOWN_FLAGS, YARGS_FLAGS } = (() => {
const names = new Set();
const opts = {
alias: {},
array: [],
boolean: [],
coerce: {},
narg: {},
normalize: [],
};
// `_` contains unparsed arguments.
names.add('_');
Object.keys(flags).forEach((flag) => {
const value = flags[flag];
names.add(flag);
if (value.alias) {
names.add(value.alias);
opts.alias[flag] = [value.alias];
}
if (value.array) {
opts.array.push(flag);
}
if (value.boolean) {
opts.boolean.push(flag);
}
if (value.coerce) {
opts.coerce[flag] = value.coerce;
}
if (value.normalize) {
opts.normalize.push(flag);
}
if (value.requiresArg) {
opts.narg[flag] = 1;
}
});
return {
KNOWN_FLAGS: names,
YARGS_FLAGS: opts,
};
})();
/**
* CLI engine for JSDoc.

@@ -133,3 +62,5 @@ *

this.emitter = opts.emitter ?? new EventEmitter();
this.api = opts.api ?? new Api({ emitter: opts.emitter });
this.emitter = this.api.emitter;
this.env = this.api.env;
this.flags = [];

@@ -141,13 +72,108 @@ this.log = opts.log ?? getLogFunctions(this.emitter);

});
// TODO: Make these private when `cli.js` no longer needs them.
this.shouldExitWithError = false;
this.shouldPrintHelp = false;
// Support the format used by `Env`.
// TODO: Make the formats consistent.
if (_.isObject(opts.version)) {
this.env.version = opts.version;
this.version = opts.version.number;
this.revision = new Date(opts.version.revision);
this.env.version.revision = opts.version.revision;
} else {
this.version = opts.version;
this.env.version = {};
this.version = this.env.version.number = opts.version;
this.revision = opts.revision;
this.env.version.revision = opts.revision?.toUTCString();
}
}
configureLogger() {
const fatalError = () => {
this.exit(1);
};
const { LOG_LEVELS } = Engine;
const { options } = this.env;
const recoverableError = () => {
this.shouldExitWithError = true;
};
if (options.test) {
this.logLevel = LOG_LEVELS.SILENT;
} else {
if (options.debug) {
this.logLevel = LOG_LEVELS.DEBUG;
} else if (options.verbose) {
this.logLevel = LOG_LEVELS.INFO;
}
if (options.pedantic) {
this.emitter.once('logger:warn', recoverableError);
this.emitter.once('logger:error', fatalError);
} else {
this.emitter.once('logger:error', recoverableError);
}
this.emitter.once('logger:fatal', fatalError);
}
}
dumpParseResults(docletStore) {
let doclets;
const { options } = this.env;
if (options.debug || options.verbose) {
doclets = docletStore.allDoclets;
} else {
doclets = docletStore.doclets;
}
console.log(JSON.stringify(Array.from(doclets), null, 2));
}
exit(exitCode, message) {
ow(exitCode, ow.number);
ow(message, ow.optional.string);
if (exitCode > 0) {
this.shouldExitWithError = true;
process.on('exit', () => {
if (message) {
console.error(message);
}
});
}
process.on('exit', () => {
if (this.shouldPrintHelp) {
this.printHelp();
}
// eslint-disable-next-line no-process-exit
process.exit(exitCode);
});
}
async generate() {
let docletStore;
const { api, env } = this;
await api.findSourceFiles();
if (env.sourceFiles.length === 0) {
console.log('There are no input files to process.');
} else {
docletStore = await api.parseSourceFiles();
if (env.options.explain) {
this.dumpParseResults(docletStore);
} else {
await api.generateDocs(docletStore);
}
}
env.run.finish = new Date();
return 0;
}
/**

@@ -174,2 +200,3 @@ * Get help text for JSDoc.

// TODO: Add a typedef for this.
/**

@@ -182,3 +209,38 @@ * Details about the command-line flags that JSDoc recognizes.

// TODO: Add details about the directory and filenames that this method looks for.
/**
* Parses command-line flags; loads the JSDoc configuration file; and adds configuration details
* to the JSDoc environment.
*
* For details about supported command-line flags, see the value of the
* {@link module:@jsdoc/cli#knownFlags} property.
*
* @returns {Promise<undefined>} A promise that is fulfilled after the configuration is loaded.
*/
loadConfig() {
const { env } = this;
try {
env.opts = _.defaults({}, this.parseFlags(env.args), env.opts);
} catch (e) {
this.shouldPrintHelp = true;
this.exit(1, `${e.message}\n`);
return Promise.reject(e);
}
// TODO: Await the promise and use try-catch.
return jsdocConfig.load(env.opts.configure).then(
(conf) => {
env.conf = conf.config;
// Look for options on the command line, then in the config.
env.opts = _.defaults(env.opts, env.conf.opts);
},
(e) => {
this.exit(1, `Cannot parse the config file: ${e}\n${FATAL_ERROR_MESSAGE}`);
}
);
}
/**
* The log level to use. Messages are logged only if they are at or above this level.

@@ -203,46 +265,22 @@ * Must be an enumerated value of {@link module:@jsdoc/cli.LOG_LEVELS}.

* @param {Array<string>} cliFlags - The command-line flags to parse.
* @returns {Object} The name and value for each flag. The `_` property contains all arguments
* other than flags and flag values.
* @returns {Object<string, *>} The long name and value for each flag. The `_` property contains
* all arguments other than flags and flag values.
*/
parseFlags(cliFlags) {
ow(cliFlags, ow.array);
this.flags = parseFlags(cliFlags);
let normalizedFlags;
let parsed;
let parsedFlags;
let parsedFlagNames;
return this.flags;
}
normalizedFlags = Object.keys(flags);
parsed = yargs.detailed(cliFlags, YARGS_FLAGS);
if (parsed.error) {
throw parsed.error;
}
parsedFlags = parsed.argv;
parsedFlagNames = new Set(Object.keys(parsedFlags));
printHelp() {
this.printVersion();
console.log(this.help({ maxLength: process.stdout.columns }));
// Check all parsed flags for unknown flag names.
for (let flag of parsedFlagNames) {
if (!KNOWN_FLAGS.has(flag)) {
throw new TypeError(
'Unknown command-line option: ' + (flag.length === 1 ? `-${flag}` : `--${flag}`)
);
}
}
return Promise.resolve(0);
}
// Validate the values of known flags.
for (let flag of normalizedFlags) {
if (parsedFlags[flag] && flags[flag].choices) {
let flagInfo = {
name: flag,
alias: flags[flag].alias,
};
printVersion() {
console.log(this.versionDetails);
validateChoice(flagInfo, flags[flag].choices, parsedFlags[flag]);
}
}
// Only keep the long name of each flag.
this.flags = _.pick(parsedFlags, normalizedFlags.concat(['_']));
return this.flags;
return Promise.resolve(0);
}

@@ -249,0 +287,0 @@

@@ -19,2 +19,5 @@ /*

import { cast } from '@jsdoc/util';
import _ from 'lodash';
import ow from 'ow';
import yargs from 'yargs-parser';

@@ -27,3 +30,3 @@ // TODO: Document the format of this object, then update the docs for `Engine`.

*/
export default {
export const flags = {
access: {

@@ -121,1 +124,123 @@ alias: 'a',

};
/**
* `KNOWN_FLAGS` is a set of all known flag names, including the long and short forms.
*
* `YARGS_FLAGS` is details about the known command-line flags, but in a form that `yargs-parser`
* understands. (That form is relatively hard to read, so we build this object from the more
* readable `flags` object.)
*
* @private
*/
const { KNOWN_FLAGS, YARGS_FLAGS } = (() => {
const names = new Set();
const opts = {
alias: {},
array: [],
boolean: [],
coerce: {},
narg: {},
normalize: [],
};
// `_` contains unparsed arguments.
names.add('_');
Object.keys(flags).forEach((flag) => {
const value = flags[flag];
names.add(flag);
if (value.alias) {
names.add(value.alias);
opts.alias[flag] = [value.alias];
}
if (value.array) {
opts.array.push(flag);
}
if (value.boolean) {
opts.boolean.push(flag);
}
if (value.coerce) {
opts.coerce[flag] = value.coerce;
}
if (value.normalize) {
opts.normalize.push(flag);
}
if (value.requiresArg) {
opts.narg[flag] = 1;
}
});
return {
KNOWN_FLAGS: names,
YARGS_FLAGS: opts,
};
})();
function validateChoice(flagInfo, choices, values) {
let flagNames = flagInfo.alias ? `-${flagInfo.alias}/` : '';
flagNames += `--${flagInfo.name}`;
for (let value of values) {
if (!choices.includes(value)) {
throw new TypeError(`The flag ${flagNames} accepts only these values: ${choices.join(', ')}`);
}
}
}
/**
* Parse an array of command-line flags (also known as "options").
*
* Use the instance's `flags` property to retrieve the parsed flags later.
*
* @param {Array<string>} cliFlags - The command-line flags to parse.
* @returns {Object<string, *>} The long name and value for each flag. The `_` property contains
* all arguments other than flags and flag values.
*/
export function parseFlags(cliFlags) {
ow(cliFlags, ow.array);
let normalizedFlags;
let parsed;
let parsedFlags;
let parsedFlagNames;
normalizedFlags = Object.keys(flags);
parsed = yargs.detailed(cliFlags, YARGS_FLAGS);
if (parsed.error) {
throw parsed.error;
}
parsedFlags = parsed.argv;
parsedFlagNames = new Set(Object.keys(parsedFlags));
// Check all parsed flags for unknown flag names.
for (let flag of parsedFlagNames) {
if (!KNOWN_FLAGS.has(flag)) {
throw new TypeError(
'Unknown command-line option: ' + (flag.length === 1 ? `-${flag}` : `--${flag}`)
);
}
}
// Validate the values of known flags.
for (let flag of normalizedFlags) {
if (parsedFlags[flag] && flags[flag].choices) {
let flagInfo = {
name: flag,
alias: flags[flag].alias,
};
validateChoice(flagInfo, flags[flag].choices, parsedFlags[flag]);
}
}
// Only keep the long name of each flag.
return _.pick(parsedFlags, normalizedFlags.concat(['_']));
}

@@ -16,3 +16,3 @@ /*

*/
import flags from './flags.js';
import { flags } from './flags.js';

@@ -19,0 +19,0 @@ function padLeft(str, length) {

{
"name": "@jsdoc/cli",
"version": "0.3.9",
"version": "0.3.10",
"description": "Command-line tool for JSDoc.",

@@ -34,4 +34,4 @@ "keywords": [

"dependencies": {
"@jsdoc/core": "^0.5.7",
"@jsdoc/util": "^0.3.2",
"@jsdoc/core": "^0.5.8",
"@jsdoc/util": "^0.3.3",
"lodash": "^4.17.21",

@@ -45,3 +45,3 @@ "ow": "^1.1.1",

},
"gitHead": "db20d510665ac4ca9a363c08ea95e4ae88c09c4a"
"gitHead": "7942901ff766e74d5d800ae5c708ab72cf89cefe"
}
SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc