mirror of
https://github.com/jsdoc/jsdoc.git
synced 2025-12-08 19:46:11 +00:00
add @jsdoc/core package
This commit is contained in:
parent
d4321a75b4
commit
a291608954
2
packages/jsdoc-core/.gitignore
vendored
Normal file
2
packages/jsdoc-core/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Dotfile detritus
|
||||
.DS_Store
|
||||
14
packages/jsdoc-core/.npmignore
Normal file
14
packages/jsdoc-core/.npmignore
Normal file
@ -0,0 +1,14 @@
|
||||
.editorconfig
|
||||
.eslintignore
|
||||
.eslintrc.js
|
||||
.gitignore
|
||||
.github/
|
||||
.renovaterc.json
|
||||
.travis.yml
|
||||
CHANGES.md
|
||||
CODE_OF_CONDUCT.md
|
||||
CONTRIBUTING.md
|
||||
gulpfile.js
|
||||
lerna.json
|
||||
packages/
|
||||
test/
|
||||
3
packages/jsdoc-core/README.md
Normal file
3
packages/jsdoc-core/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# `@jsdoc/core`
|
||||
|
||||
Core functionality for JSDoc.
|
||||
11
packages/jsdoc-core/index.js
Normal file
11
packages/jsdoc-core/index.js
Normal file
@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Provides core functionality for JSDoc.
|
||||
*
|
||||
* @module @jsdoc/config
|
||||
*/
|
||||
|
||||
const config = require('./lib/config');
|
||||
|
||||
module.exports = {
|
||||
config
|
||||
};
|
||||
134
packages/jsdoc-core/lib/config.js
Normal file
134
packages/jsdoc-core/lib/config.js
Normal file
@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Manages configuration settings for JSDoc.
|
||||
*
|
||||
* @alias module:@jsdoc/core.config
|
||||
*/
|
||||
|
||||
const _ = require('lodash');
|
||||
const cosmiconfig = 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
|
||||
}
|
||||
};
|
||||
|
||||
class Config {
|
||||
constructor(filepath, config) {
|
||||
this.config = config;
|
||||
this.filepath = filepath;
|
||||
}
|
||||
}
|
||||
|
||||
function loadJson(filepath, content) {
|
||||
return cosmiconfig.loadJson(filepath, stripBom(stripJsonComments(content)));
|
||||
}
|
||||
|
||||
function loadYaml(filepath, content) {
|
||||
return cosmiconfig.loadYaml(filepath, stripBom(content));
|
||||
}
|
||||
|
||||
const explorer = cosmiconfig(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 = explorer.loadSync(filepath);
|
||||
} else {
|
||||
loaded = explorer.searchSync() || {};
|
||||
}
|
||||
|
||||
return new Config(
|
||||
loaded.filepath,
|
||||
_.defaultsDeep({}, loaded.config, defaults)
|
||||
);
|
||||
};
|
||||
134
packages/jsdoc-core/package-lock.json
generated
Normal file
134
packages/jsdoc-core/package-lock.json
generated
Normal file
@ -0,0 +1,134 @@
|
||||
{
|
||||
"name": "@jsdoc/core",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"requires": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"caller-callsite": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
|
||||
"integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
|
||||
"requires": {
|
||||
"callsites": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"caller-path": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
|
||||
"integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
|
||||
"requires": {
|
||||
"caller-callsite": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"callsites": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
|
||||
"integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA="
|
||||
},
|
||||
"cosmiconfig": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
|
||||
"integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
|
||||
"requires": {
|
||||
"import-fresh": "^2.0.0",
|
||||
"is-directory": "^0.3.1",
|
||||
"js-yaml": "^3.13.1",
|
||||
"parse-json": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"error-ex": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
|
||||
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
|
||||
"requires": {
|
||||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
|
||||
},
|
||||
"import-fresh": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
|
||||
"integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
|
||||
"requires": {
|
||||
"caller-path": "^2.0.0",
|
||||
"resolve-from": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"is-arrayish": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
|
||||
"integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
|
||||
},
|
||||
"is-directory": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
|
||||
"integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE="
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.13.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
|
||||
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"json-parse-better-errors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
|
||||
"integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
|
||||
},
|
||||
"mock-fs": {
|
||||
"version": "4.10.1",
|
||||
"resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.10.1.tgz",
|
||||
"integrity": "sha512-w22rOL5ZYu6HbUehB5deurghGM0hS/xBVyHMGKOuQctkk93J9z9VEOhDsiWrXOprVNQpP9uzGKdl8v9mFspKuw==",
|
||||
"dev": true
|
||||
},
|
||||
"parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
|
||||
"integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
|
||||
"requires": {
|
||||
"error-ex": "^1.3.1",
|
||||
"json-parse-better-errors": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"resolve-from": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
|
||||
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
|
||||
},
|
||||
"sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||
},
|
||||
"strip-bom": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
|
||||
"integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w=="
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
|
||||
"integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw=="
|
||||
}
|
||||
}
|
||||
}
|
||||
30
packages/jsdoc-core/package.json
Normal file
30
packages/jsdoc-core/package.json
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "@jsdoc/core",
|
||||
"version": "0.1.0",
|
||||
"description": "Core functionality for JSDoc.",
|
||||
"keywords": [
|
||||
"jsdoc"
|
||||
],
|
||||
"author": "Jeff Williams <jeffrey.l.williams@gmail.com>",
|
||||
"homepage": "https://jsdoc.app/",
|
||||
"license": "Apache-2.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jsdoc/jsdoc.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: run tests from root\" && exit 1"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jsdoc/jsdoc/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"cosmiconfig": "^5.2.1",
|
||||
"lodash": "^4.17.15",
|
||||
"strip-bom": "^4.0.0",
|
||||
"strip-json-comments": "^3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mock-fs": "^4.10.1"
|
||||
}
|
||||
}
|
||||
14
packages/jsdoc-core/test/specs/index.js
Normal file
14
packages/jsdoc-core/test/specs/index.js
Normal file
@ -0,0 +1,14 @@
|
||||
const config = require('../../lib/config');
|
||||
const core = require('../../index');
|
||||
|
||||
describe('@jsdoc/core', () => {
|
||||
it('exists', () => {
|
||||
expect(core).toBeObject();
|
||||
});
|
||||
|
||||
describe('config', () => {
|
||||
it('is lib/config', () => {
|
||||
expect(core.config).toBe(config);
|
||||
});
|
||||
});
|
||||
});
|
||||
186
packages/jsdoc-core/test/specs/lib/config.js
Normal file
186
packages/jsdoc-core/test/specs/lib/config.js
Normal file
@ -0,0 +1,186 @@
|
||||
const { config } = require('@jsdoc/core');
|
||||
const mockFs = require('mock-fs');
|
||||
|
||||
describe('@jsdoc/config', () => {
|
||||
afterEach(() => mockFs.restore());
|
||||
|
||||
it('exists', () => {
|
||||
expect(config).toBeObject();
|
||||
});
|
||||
|
||||
describe('loadSync', () => {
|
||||
it('exists', () => {
|
||||
expect(config.loadSync).toBeFunction();
|
||||
});
|
||||
|
||||
it('returns an object with `config` and `filepath` properties', () => {
|
||||
mockFs({
|
||||
'conf.json': '{}'
|
||||
});
|
||||
|
||||
const conf = config.loadSync('conf.json');
|
||||
|
||||
expect(conf.config).toBeObject();
|
||||
expect(conf.filepath).toEndWith('conf.json');
|
||||
});
|
||||
|
||||
it('loads settings from the specified filepath if there is one', () => {
|
||||
mockFs({
|
||||
'conf.json': '{"foo":"bar"}'
|
||||
});
|
||||
|
||||
const conf = config.loadSync('conf.json');
|
||||
|
||||
expect(conf.config.foo).toBe('bar');
|
||||
});
|
||||
|
||||
it('finds the config file when no filepath is specified', () => {
|
||||
mockFs({
|
||||
'package.json': '{"jsdoc":{"foo":"bar"}}'
|
||||
});
|
||||
|
||||
const conf = config.loadSync();
|
||||
|
||||
expect(conf.config.foo).toBe('bar');
|
||||
});
|
||||
|
||||
it('parses JSON config files that have an extension and contain comments', () => {
|
||||
mockFs({
|
||||
'.jsdocrc.json': '// comment\n{"foo":"bar"}'
|
||||
});
|
||||
|
||||
const conf = config.loadSync();
|
||||
|
||||
expect(conf.config.foo).toBe('bar');
|
||||
});
|
||||
|
||||
it('parses JSON files that start with a BOM', () => {
|
||||
mockFs({
|
||||
'.jsdocrc.json': '\uFEFF{"foo":"bar"}'
|
||||
});
|
||||
|
||||
const conf = config.loadSync();
|
||||
|
||||
expect(conf.config.foo).toBe('bar');
|
||||
});
|
||||
|
||||
it('parses YAML files that start with a BOM', () => {
|
||||
mockFs({
|
||||
'.jsdocrc.yaml': '\uFEFF{"foo":"bar"}'
|
||||
});
|
||||
|
||||
const conf = config.loadSync();
|
||||
|
||||
expect(conf.config.foo).toBe('bar');
|
||||
});
|
||||
|
||||
it('provides the default config if the user config is an empty object', () => {
|
||||
mockFs({
|
||||
'.jsdocrc.json': '{}'
|
||||
});
|
||||
|
||||
const conf = config.loadSync();
|
||||
|
||||
expect(conf.config).toEqual(config.defaults);
|
||||
});
|
||||
|
||||
it('provides the default config if there is no user config', () => {
|
||||
const conf = config.loadSync();
|
||||
|
||||
expect(conf.config).toEqual(config.defaults);
|
||||
});
|
||||
|
||||
it('merges nested defaults with nested user settings as expected', () => {
|
||||
mockFs({
|
||||
'.jsdocrc.json': '{"tags":{"foo":"bar"}}'
|
||||
});
|
||||
|
||||
const conf = config.loadSync();
|
||||
|
||||
expect(conf.config.tags.allowUnknownTags).toBe(config.defaults.tags.allowUnknownTags);
|
||||
expect(conf.config.tags.foo).toBe('bar');
|
||||
});
|
||||
});
|
||||
|
||||
describe('defaults', () => {
|
||||
const { defaults } = config;
|
||||
|
||||
it('exists', () => {
|
||||
expect(defaults).toBeObject();
|
||||
});
|
||||
|
||||
describe('plugins', () => {
|
||||
it('is an array', () => {
|
||||
expect(defaults.plugins).toBeArray();
|
||||
});
|
||||
});
|
||||
|
||||
describe('source', () => {
|
||||
it('is an object', () => {
|
||||
expect(defaults.source).toBeObject();
|
||||
});
|
||||
|
||||
describe('excludePattern', () => {
|
||||
it('is a string', () => {
|
||||
expect(defaults.source.excludePattern).toBeString();
|
||||
});
|
||||
|
||||
it('represents a valid regexp', () => {
|
||||
expect(() => new RegExp(defaults.source.excludePattern)).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('includePattern', () => {
|
||||
it('is a string', () => {
|
||||
expect(defaults.source.includePattern).toBeString();
|
||||
});
|
||||
|
||||
it('represents a valid regexp', () => {
|
||||
expect(() => new RegExp(defaults.source.includePattern)).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('type', () => {
|
||||
it('is a string', () => {
|
||||
expect(defaults.source.type).toBeString();
|
||||
});
|
||||
});
|
||||
|
||||
describe('tags', () => {
|
||||
it('is an object', () => {
|
||||
expect(defaults.tags).toBeObject();
|
||||
});
|
||||
|
||||
describe('allowUnknownTags', () => {
|
||||
it('is a boolean', () => {
|
||||
expect(defaults.tags.allowUnknownTags).toBeBoolean();
|
||||
});
|
||||
});
|
||||
|
||||
describe('dictionaries', () => {
|
||||
it('is an array of strings', () => {
|
||||
expect(defaults.tags.dictionaries).toBeArrayOfStrings();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('templates', () => {
|
||||
it('is an object', () => {
|
||||
expect(defaults.templates).toBeObject();
|
||||
});
|
||||
|
||||
describe('cleverLinks', () => {
|
||||
it('is a boolean', () => {
|
||||
expect(defaults.templates.cleverLinks).toBeBoolean();
|
||||
});
|
||||
});
|
||||
|
||||
describe('monospaceLinks', () => {
|
||||
it('is a boolean', () => {
|
||||
expect(defaults.templates.monospaceLinks).toBeBoolean();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user