From d4e762d3b2d9934ca8e61abad9554c5292d2c525 Mon Sep 17 00:00:00 2001 From: Jeff Williams Date: Sun, 15 Jan 2023 16:05:25 -0800 Subject: [PATCH] refactor: move Package class to `@jsdoc/doclet` --- packages/jsdoc-doclet/index.js | 2 + .../lib/jsdoc => jsdoc-doclet/lib}/package.js | 21 ++- packages/jsdoc-doclet/package-lock.json | 128 ++++++++++++++++++ packages/jsdoc-doclet/package.json | 5 +- packages/jsdoc-doclet/test/specs/index.js | 8 ++ .../test/specs}/package.js | 92 +++++++------ packages/jsdoc/cli.js | 2 +- 7 files changed, 200 insertions(+), 58 deletions(-) rename packages/{jsdoc/lib/jsdoc => jsdoc-doclet/lib}/package.js (90%) create mode 100644 packages/jsdoc-doclet/package-lock.json rename packages/{jsdoc/test/specs/jsdoc => jsdoc-doclet/test/specs}/package.js (69%) diff --git a/packages/jsdoc-doclet/index.js b/packages/jsdoc-doclet/index.js index 3f598c6d..d076e2f3 100644 --- a/packages/jsdoc-doclet/index.js +++ b/packages/jsdoc-doclet/index.js @@ -13,8 +13,10 @@ See the License for the specific language governing permissions and limitations under the License. */ +const { Package } = require('./lib/package'); const schema = require('./lib/schema'); module.exports = { + Package, schema, }; diff --git a/packages/jsdoc/lib/jsdoc/package.js b/packages/jsdoc-doclet/lib/package.js similarity index 90% rename from packages/jsdoc/lib/jsdoc/package.js rename to packages/jsdoc-doclet/lib/package.js index 4342220a..b7575a55 100644 --- a/packages/jsdoc/lib/jsdoc/package.js +++ b/packages/jsdoc-doclet/lib/package.js @@ -19,7 +19,6 @@ const stripBom = require('strip-bom'); /** * Provides access to information about a JavaScript package. * - * @module jsdoc/package * @see https://www.npmjs.org/doc/files/package.json.html */ @@ -37,7 +36,7 @@ function getLicenses(packageInfo) { /** * Information about where to report bugs in the package. * - * @typedef {Object} module:jsdoc/package.Package~BugInfo + * @typedef {Object} module:@jsdoc/doclet/package.Package~BugInfo * @property {string} email - The email address for reporting bugs. * @property {string} url - The URL for reporting bugs. */ @@ -45,7 +44,7 @@ function getLicenses(packageInfo) { /** * Information about a package's software license. * - * @typedef {Object} module:jsdoc/package.Package~LicenseInfo + * @typedef {Object} module:@jsdoc/doclet/package.Package~LicenseInfo * @property {string} type - An identifier for the type of license. * @property {string} url - The URL for the complete text of the license. */ @@ -53,7 +52,7 @@ function getLicenses(packageInfo) { /** * Information about a package author or contributor. * - * @typedef {Object} module:jsdoc/package.Package~PersonInfo + * @typedef {Object} module:@jsdoc/doclet/package.Package~PersonInfo * @property {string} name - The person's full name. * @property {string} email - The person's email address. * @property {string} url - The URL of the person's website. @@ -62,7 +61,7 @@ function getLicenses(packageInfo) { /** * Information about a package's version-control repository. * - * @typedef {Object} module:jsdoc/package.Package~RepositoryInfo + * @typedef {Object} module:@jsdoc/doclet/package.Package~RepositoryInfo * @property {string} type - The type of version-control system that the repository uses (for * example, `git` or `svn`). * @property {string} url - The URL for the repository. @@ -119,10 +118,10 @@ class Package { if (packageInfo.author) { /** * The author of this package. Contains either a - * {@link module:jsdoc/package.Package~PersonInfo PersonInfo} object or a string with + * {@link module:@jsdoc/doclet/package.Package~PersonInfo PersonInfo} object or a string with * information about the author. * - * @type {(module:jsdoc/package.Package~PersonInfo|string)} + * @type {(module:@jsdoc/doclet/package.Package~PersonInfo|string)} * @since 3.3.0 */ this.author = packageInfo.author; @@ -133,7 +132,7 @@ class Package { * Information about where to report bugs in the project. May contain a URL, a string, or an * object with more detailed information. * - * @type {(string|module:jsdoc/package.Package~BugInfo)} + * @type {(string|module:@jsdoc/doclet/package.Package~BugInfo)} * @since 3.3.0 */ this.bugs = packageInfo.bugs; @@ -143,7 +142,7 @@ class Package { /** * The contributors to this package. * - * @type {Array.<(module:jsdoc/package.Package~PersonInfo|string)>} + * @type {Array.<(module:@jsdoc/doclet/package.Package~PersonInfo|string)>} * @since 3.3.0 */ this.contributors = packageInfo.contributors; @@ -229,7 +228,7 @@ class Package { * The licenses used by this package. Combines information from the `package.json` file's * `license` property and the deprecated `licenses` property. * - * @type {Array.} + * @type {Array.} */ this.licenses = getLicenses(packageInfo); } @@ -250,7 +249,7 @@ class Package { /** * The version-control repository for the package. * - * @type {module:jsdoc/package.Package~RepositoryInfo} + * @type {module:@jsdoc/doclet/package.Package~RepositoryInfo} * @since 3.3.0 */ this.repository = packageInfo.repository; diff --git a/packages/jsdoc-doclet/package-lock.json b/packages/jsdoc-doclet/package-lock.json new file mode 100644 index 00000000..b5f70c70 --- /dev/null +++ b/packages/jsdoc-doclet/package-lock.json @@ -0,0 +1,128 @@ +{ + "name": "@jsdoc/doclet", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@jsdoc/doclet", + "version": "0.0.1", + "license": "Apache-2.0", + "dependencies": { + "@jsdoc/util": "^0.2.7", + "strip-bom": "^4.0.0" + } + }, + "node_modules/@jsdoc/util": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@jsdoc/util/-/util-0.2.7.tgz", + "integrity": "sha512-PHbdRflULw07QHals3iRqex/TSSQ+Uk5u3R5P3g3FJnpmXdp3NbPqYY+IaLDX2L5btvL87TfY8u0Hq7X/RpCtA==", + "dependencies": { + "klaw-sync": "^6.0.0", + "lodash": "^4.17.21", + "ow": "^0.28.2" + }, + "engines": { + "node": ">=v18.12.0" + } + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, + "node_modules/ow": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/ow/-/ow-0.28.2.tgz", + "integrity": "sha512-dD4UpyBh/9m4X2NVjA+73/ZPBRF+uF4zIMFvvQsabMiEK8x41L3rQ8EENOi35kyyoaJwNxEeJcP6Fj1H4U409Q==", + "dependencies": { + "@sindresorhus/is": "^4.2.0", + "callsites": "^3.1.0", + "dot-prop": "^6.0.1", + "lodash.isequal": "^4.5.0", + "vali-date": "^1.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/vali-date": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", + "integrity": "sha512-sgECfZthyaCKW10N0fm27cg8HYTFK5qMWgypqkXMQ4Wbl/zZKx7xZICgcoxIIE+WFAP/MBL2EFwC/YvLxw3Zeg==", + "engines": { + "node": ">=0.10.0" + } + } + } +} diff --git a/packages/jsdoc-doclet/package.json b/packages/jsdoc-doclet/package.json index de674b74..98f74577 100644 --- a/packages/jsdoc-doclet/package.json +++ b/packages/jsdoc-doclet/package.json @@ -21,5 +21,8 @@ "bugs": { "url": "https://github.com/jsdoc/jsdoc/issues" }, - "dependencies": {} + "dependencies": { + "@jsdoc/util": "^0.2.7", + "strip-bom": "^4.0.0" + } } diff --git a/packages/jsdoc-doclet/test/specs/index.js b/packages/jsdoc-doclet/test/specs/index.js index bd508ef2..7d0fa503 100644 --- a/packages/jsdoc-doclet/test/specs/index.js +++ b/packages/jsdoc-doclet/test/specs/index.js @@ -20,6 +20,14 @@ describe('@jsdoc/doclet', () => { expect(doclet).toBeObject(); }); + describe('Package', () => { + it('is lib/package.Package', () => { + const { Package } = require('../../lib/package'); + + expect(doclet.Package).toBe(Package); + }); + }); + describe('schema', () => { it('is lib/schema', () => { const schema = require('../../lib/schema'); diff --git a/packages/jsdoc/test/specs/jsdoc/package.js b/packages/jsdoc-doclet/test/specs/package.js similarity index 69% rename from packages/jsdoc/test/specs/jsdoc/package.js rename to packages/jsdoc-doclet/test/specs/package.js index cfb61385..7e4100dd 100644 --- a/packages/jsdoc/test/specs/jsdoc/package.js +++ b/packages/jsdoc-doclet/test/specs/package.js @@ -13,10 +13,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -describe('jsdoc/package', () => { +/* global jsdoc */ +const jsdocPackage = require('../../lib/package'); +const { Package } = jsdocPackage; + +describe('@jsdoc/doclet/lib/package', () => { let emptyPackage; - const jsdocPackage = require('jsdoc/package'); - const Package = jsdocPackage.Package; function checkPackageProperty(name, value) { let myPackage; @@ -24,18 +26,18 @@ describe('jsdoc/package', () => { obj[name] = value; myPackage = new Package(JSON.stringify(obj)); - // add the package object to the cached parse results, so we can validate it against the - // doclet schema + // Add the package object to the cached parse results, so we can validate it against the + // doclet schema. jsdoc.addParseResults(`package-property-${name}.js`, [myPackage]); expect(myPackage[name]).toEqual(value); } - it('should exist', () => { + it('is an object', () => { expect(jsdocPackage).toBeObject(); }); - it('should export a "Package" constructor', () => { + it('exports a `Package` constructor', () => { expect(Package).toBeFunction(); }); @@ -44,7 +46,7 @@ describe('jsdoc/package', () => { emptyPackage = new Package(); }); - it('should accept a JSON-format string', () => { + it('accepts a JSON-format string', () => { function newPackage() { return new Package('{"foo": "bar"}'); } @@ -52,7 +54,7 @@ describe('jsdoc/package', () => { expect(newPackage).not.toThrow(); }); - it('should accept a JSON-format string with a leading BOM', () => { + it('accepts a JSON-format string with a leading BOM', () => { function newPackage() { return new Package('\uFEFF{}'); } @@ -60,7 +62,7 @@ describe('jsdoc/package', () => { expect(newPackage).not.toThrow(); }); - it('should work when called with no arguments', () => { + it('works with no arguments', () => { function newPackage() { return new Package(); } @@ -68,7 +70,7 @@ describe('jsdoc/package', () => { expect(newPackage).not.toThrow(); }); - it('should log an error when called with bad input', () => { + it('logs an error when called with bad input', () => { function newPackage() { return new Package('abcdefg'); } @@ -78,11 +80,11 @@ describe('jsdoc/package', () => { }); describe('author', () => { - it('should not exist by default', () => { + it('does not exist by default', () => { expect(Object.hasOwn(emptyPackage, 'author')).toBeFalse(); }); - it('should contain the value from the package file', () => { + it('contains the value from the package file', () => { checkPackageProperty('author', { name: 'Jane Smith', email: 'jsmith@example.com', @@ -91,21 +93,21 @@ describe('jsdoc/package', () => { }); describe('bugs', () => { - it('should not exist by default', () => { + it('does not exist by default', () => { expect(Object.hasOwn(emptyPackage, 'bugs')).toBeFalse(); }); - it('should contain the value from the package file', () => { + it('contains the value from the package file', () => { checkPackageProperty('bugs', { url: 'http://example.com/bugs' }); }); }); describe('contributors', () => { - it('should not exist by default', () => { + it('does not exist by default', () => { expect(Object.hasOwn(emptyPackage, 'contributors')).toBeFalse(); }); - it('should contain the value from the package file', () => { + it('contains the value from the package file', () => { checkPackageProperty('contributors', [ { name: 'Jane Smith', @@ -116,51 +118,51 @@ describe('jsdoc/package', () => { }); describe('dependencies', () => { - it('should not exist by default', () => { + it('does not exist by default', () => { expect(Object.hasOwn(emptyPackage, 'dependencies')).toBeFalse(); }); - it('should contain the value from the package file', () => { + it('contains the value from the package file', () => { checkPackageProperty('dependencies', { bar: '~1.1.0' }); }); }); describe('description', () => { - it('should not exist by default', () => { + it('does not exist by default', () => { expect(Object.hasOwn(emptyPackage, 'description')).toBeFalse(); }); - it('should contain the value from the package file', () => { + it('contains the value from the package file', () => { checkPackageProperty('description', 'My package.'); }); }); describe('devDependencies', () => { - it('should not exist by default', () => { + it('does not exist by default', () => { expect(Object.hasOwn(emptyPackage, 'devDependencies')).toBeFalse(); }); - it('should contain the value from the package file', () => { + it('contains the value from the package file', () => { checkPackageProperty('devDependencies', { baz: '~3.4.5' }); }); }); describe('engines', () => { - it('should not exist by default', () => { + it('does not exist by default', () => { expect(Object.hasOwn(emptyPackage, 'engines')).toBeFalse(); }); - it('should contain the value from the package file', () => { + it('contains the value from the package file', () => { checkPackageProperty('engines', { node: '>=0.10.3' }); }); }); describe('files', () => { - it('should contain an empty array by default', () => { + it('contains an empty array by default', () => { expect(emptyPackage.files).toBeEmptyArray(); }); - it('should ignore the value from the package file', () => { + it('ignores the value from the package file', () => { const myPackage = new Package('{"files": ["foo", "bar"]}'); expect(myPackage.files).toBeEmptyArray(); @@ -168,31 +170,31 @@ describe('jsdoc/package', () => { }); describe('homepage', () => { - it('should not exist by default', () => { + it('does not exist by default', () => { expect(Object.hasOwn(emptyPackage, 'homepage')).toBeFalse(); }); - it('should contain the value from the package file', () => { + it('contains the value from the package file', () => { checkPackageProperty('homepage', 'http://example.com/'); }); }); describe('keywords', () => { - it('should not exist by default', () => { + it('does not exist by default', () => { expect(Object.hasOwn(emptyPackage, 'keywords')).toBeFalse(); }); - it('should contain the value from the package file', () => { + it('contains the value from the package file', () => { checkPackageProperty('keywords', ['foo', 'bar']); }); }); describe('licenses', () => { - it('should not exist by default', () => { + it('does not exist by default', () => { expect(Object.hasOwn(emptyPackage, 'licenses')).toBeFalse(); }); - it('should contain the value from the package file', () => { + it('contains the value from the package file', () => { checkPackageProperty('licenses', [ { type: 'My Open-Source License', @@ -201,7 +203,7 @@ describe('jsdoc/package', () => { ]); }); - it('should contain the value of "license" from the package file', () => { + it('contains the value of `license` from the package file', () => { const myPackage = new Package('{"license": "My-OSS-License"}'); expect(myPackage.license).toBeUndefined(); @@ -209,7 +211,7 @@ describe('jsdoc/package', () => { expect(myPackage.licenses[0].type).toBe('My-OSS-License'); }); - it('should combine the "license" and "licenses" properties', () => { + it('combines the `license` and `licenses` properties', () => { const packageInfo = { license: 'My-OSS-License', licenses: [ @@ -226,11 +228,11 @@ describe('jsdoc/package', () => { }); describe('longname', () => { - it('should default to "package:undefined"', () => { + it('defaults to `package:undefined`', () => { expect(emptyPackage.longname).toBe('package:undefined'); }); - it('should reflect the value of the "name" property', () => { + it('reflects the value of the `name` property', () => { const myPackage = new Package('{"name": "foo"}'); expect(myPackage.longname).toBe('package:foo'); @@ -238,31 +240,31 @@ describe('jsdoc/package', () => { }); describe('main', () => { - it('should not exist by default', () => { + it('does not exist by default', () => { expect(Object.hasOwn(emptyPackage, 'main')).toBeFalse(); }); - it('should contain the value from the package file', () => { + it('contains the value from the package file', () => { checkPackageProperty('main', 'foo'); }); }); describe('name', () => { - it('should not exist by default', () => { + it('does not exist by default', () => { expect(Object.hasOwn(emptyPackage, 'name')).toBeFalse(); }); - it('should contain the value from the package file', () => { + it('contains the value from the package file', () => { checkPackageProperty('name', 'foo'); }); }); describe('repository', () => { - it('should not exist by default', () => { + it('does not exist by default', () => { expect(Object.hasOwn(emptyPackage, 'repository')).toBeFalse(); }); - it('should contain the value from the package file', () => { + it('contains the value from the package file', () => { checkPackageProperty('repository', { type: 'git', url: 'git@example.org:foo/bar/baz.git', @@ -271,11 +273,11 @@ describe('jsdoc/package', () => { }); describe('version', () => { - it('should not exist by default', () => { + it('does not exist by default', () => { expect(Object.hasOwn(emptyPackage, 'version')).toBeFalse(); }); - it('should contain the value from the package file', () => { + it('contains the value from the package file', () => { checkPackageProperty('version', '0.1.2'); }); }); diff --git a/packages/jsdoc/cli.js b/packages/jsdoc/cli.js index 99a00e5f..aac0febf 100644 --- a/packages/jsdoc/cli.js +++ b/packages/jsdoc/cli.js @@ -21,7 +21,7 @@ const Engine = require('@jsdoc/cli'); const { EventBus, log } = require('@jsdoc/util'); const { Filter } = require('jsdoc/src/filter'); const fs = require('fs'); -const { Package } = require('jsdoc/package'); +const { Package } = require('@jsdoc/doclet'); const path = require('path'); const { Scanner } = require('jsdoc/src/scanner'); const stripBom = require('strip-bom');