/** * Manages configuration settings for JSDoc. * * @alias module:@jsdoc/core.config */ const _ = require('lodash'); const { cosmiconfigSync, defaultLoaders } = require('cosmiconfig'); const stripBom = require('strip-bom'); const stripJsonComments = require('strip-json-comments'); const MODULE_NAME = 'jsdoc'; const defaults = exports.defaults = { // TODO(hegemonic): Integrate CLI options with other options. opts: { destination: './out', encoding: 'utf8' }, /** * The JSDoc plugins to load. */ plugins: [], // TODO(hegemonic): Move to `source` or remove. recurseDepth: 10, /** * Settings for loading and parsing source files. */ source: { /** * A regular expression that matches source files to exclude from processing. * * To exclude files if any portion of their path begins with an underscore, use the value * `(^|\\/|\\\\)_`. */ excludePattern: '', /** * A regular expression that matches source files that JSDoc should process. * * By default, all source files with the extensions `.js`, `.jsdoc`, and `.jsx` are * processed. */ includePattern: '.+\\.js(doc|x)?$', /** * The type of source file. In general, you should use the value `module`. If none of your * source files use ECMAScript >=2015 syntax, you can use the value `script`. */ type: 'module' }, /** * Settings for interpreting JSDoc tags. */ tags: { /** * Set to `true` to allow tags that JSDoc does not recognize. */ allowUnknownTags: true, // TODO(hegemonic): Use module paths, not magic strings. /** * The JSDoc tag dictionaries to load. * * If you specify two or more tag dictionaries, and a tag is defined in multiple * dictionaries, JSDoc uses the definition from the first dictionary that includes that tag. */ dictionaries: [ 'jsdoc', 'closure' ] }, /** * Settings for generating output with JSDoc templates. Some JSDoc templates might ignore these * settings. */ templates: { /** * Set to `true` to use a monospaced font for links to other code symbols, but not links to * websites. */ cleverLinks: false, /** * Set to `true` to use a monospaced font for all links. */ monospaceLinks: false } }; // TODO: Consider exporting this class. class Config { constructor(filepath, config) { this.config = config; this.filepath = filepath; } } function loadJson(filepath, content) { return defaultLoaders['.json'](filepath, stripBom(stripJsonComments(content))); } function loadYaml(filepath, content) { return defaultLoaders['.yaml'](filepath, stripBom(content)); } const explorerSync = cosmiconfigSync(MODULE_NAME, { cache: false, loaders: { '.json': loadJson, '.yaml': loadYaml, '.yml': loadYaml, noExt: loadYaml }, searchPlaces: [ 'package.json', `.${MODULE_NAME}rc`, `.${MODULE_NAME}rc.json`, `.${MODULE_NAME}rc.yaml`, `.${MODULE_NAME}rc.yml`, `.${MODULE_NAME}rc.js`, `${MODULE_NAME}.config.js` ] }); exports.loadSync = (filepath) => { let loaded; if (filepath) { loaded = explorerSync.load(filepath); } else { loaded = explorerSync.search() || {}; } return new Config( loaded.filepath, _.defaultsDeep({}, loaded.config, defaults) ); };