js-build-tools 6.6.0 → 6.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -674
- package/README.md +768 -701
- package/babel.config.js +28 -28
- package/dist/build.js +75 -75
- package/dist/bundle.js +19 -19
- package/dist/bundleMinify.js +7 -7
- package/dist/compileReadme.js +4 -4
- package/dist/copyFiles.js +17 -17
- package/dist/copyFonts.js +4 -4
- package/dist/default.js +5 -5
- package/dist/dist.js +4 -4
- package/dist/distMinify.js +4 -4
- package/dist/docs.js +7 -7
- package/dist/images.js +4 -4
- package/dist/jsdocDocs.js +6 -6
- package/dist/lint.js +16 -16
- package/dist/partials/addToReadme.js +9 -9
- package/dist/partials/beginWatcher.js +4 -4
- package/dist/partials/cacheFiles.js +121 -0
- package/dist/partials/clean.js +5 -5
- package/dist/partials/copyFor.js +9 -9
- package/dist/partials/distFor.js +6 -6
- package/dist/partials/distForSrc.js +5 -5
- package/dist/partials/distSeries.js +7 -7
- package/dist/partials/imagesFor.js +155 -93
- package/dist/partials/jsdocDocsFor.js +64 -51
- package/dist/partials/lintSource.js +51 -51
- package/dist/partials/loadPeer.js +99 -99
- package/dist/partials/loadPlaywright.js +14 -14
- package/dist/partials/minifyFor.js +20 -20
- package/dist/partials/neostandardLint.js +175 -175
- package/dist/partials/readmeTemplate.js +4 -4
- package/dist/partials/removeDirectory.js +11 -11
- package/dist/partials/resolveDocsMethod.js +6 -6
- package/dist/partials/runOnChange.js +31 -31
- package/dist/partials/sassFor.js +6 -6
- package/dist/partials/serveStatic.js +9 -9
- package/dist/partials/tsFor.js +32 -32
- package/dist/partials/typeDocsFor.js +264 -264
- package/dist/partials.js +183 -176
- package/dist/partials.min.js +1 -1
- package/dist/sourceLint.js +18 -18
- package/dist/test-helpers/setUp.js +6 -4
- package/dist/testFull.js +5 -5
- package/dist/testQuick.js +5 -5
- package/dist/typeDocs.js +5 -5
- package/dist/typeScript.js +4 -4
- package/dist/utilities/convertMjsFilesForDocs.js +12 -12
- package/dist/utilities/dotGet.js +54 -54
- package/dist/utilities/dotNotate.js +79 -79
- package/dist/utilities/dotSet.js +45 -45
- package/dist/utilities/esmNamedExportsToCjs.js +15 -15
- package/dist/utilities/getBundleConfigs.js +9 -9
- package/dist/utilities/isObject.js +6 -6
- package/dist/utilities/strAfter.js +7 -7
- package/dist/utilities/strBefore.js +7 -7
- package/dist/watchFull.js +4 -4
- package/dist/watchTest.js +4 -4
- package/functions/build.mjs +72 -72
- package/functions/build.test.mjs +760 -759
- package/functions/bundle.mjs +44 -44
- package/functions/bundle.test.mjs +219 -219
- package/functions/bundleMinify.mjs +16 -16
- package/functions/bundleMinify.test.mjs +37 -37
- package/functions/compileReadme.mjs +9 -9
- package/functions/compileReadme.test.mjs +18 -18
- package/functions/copyFiles.mjs +32 -32
- package/functions/copyFiles.test.mjs +78 -78
- package/functions/copyFonts.mjs +9 -9
- package/functions/copyFonts.test.mjs +32 -32
- package/functions/default.mjs +12 -12
- package/functions/default.test.mjs +33 -33
- package/functions/dist.mjs +8 -8
- package/functions/dist.test.mjs +44 -44
- package/functions/distMinify.mjs +9 -9
- package/functions/distMinify.test.mjs +15 -15
- package/functions/docs.mjs +13 -13
- package/functions/docs.test.mjs +45 -45
- package/functions/gulpConfigEntries.test.mjs +23 -23
- package/functions/images.mjs +8 -8
- package/functions/images.test.mjs +140 -142
- package/functions/jsdocDocs.mjs +10 -10
- package/functions/jsdocEsmExports.test.mjs +24 -24
- package/functions/lint.mjs +9 -9
- package/functions/partials/addToReadme.mjs +25 -25
- package/functions/partials/addToReadme.test.mjs +34 -34
- package/functions/partials/beginWatcher.mjs +9 -9
- package/functions/partials/beginWatcher.test.mjs +19 -19
- package/functions/partials/cacheFiles.mjs +114 -0
- package/functions/partials/cacheFiles.test.mjs +151 -0
- package/functions/partials/clean.mjs +13 -13
- package/functions/partials/clean.test.mjs +22 -22
- package/functions/partials/copyFor.mjs +15 -15
- package/functions/partials/copyFor.test.mjs +53 -53
- package/functions/partials/distFor.mjs +22 -22
- package/functions/partials/distFor.test.mjs +195 -195
- package/functions/partials/distForSrc.mjs +11 -11
- package/functions/partials/distForSrc.test.mjs +18 -18
- package/functions/partials/distSeries.mjs +21 -21
- package/functions/partials/distSeries.test.mjs +34 -34
- package/functions/partials/imagesFor.mjs +147 -83
- package/functions/partials/imagesFor.test.mjs +311 -287
- package/functions/partials/jsdocDocsFor.mjs +163 -152
- package/functions/partials/jsdocDocsFor.test.mjs +182 -152
- package/functions/partials/lintSource.mjs +41 -41
- package/functions/partials/loadPeer.mjs +76 -76
- package/functions/partials/loadPeer.test.mjs +58 -58
- package/functions/partials/loadPlaywright.mjs +23 -23
- package/functions/partials/loadPlaywright.test.mjs +70 -70
- package/functions/partials/minifyFor.mjs +15 -15
- package/functions/partials/minifyFor.test.mjs +49 -49
- package/functions/partials/neostandardLint.mjs +142 -142
- package/functions/partials/neostandardLint.test.mjs +131 -131
- package/functions/partials/readmeTemplate.mjs +12 -12
- package/functions/partials/readmeTemplate.test.mjs +34 -34
- package/functions/partials/removeDirectory.mjs +34 -34
- package/functions/partials/removeDirectory.test.mjs +72 -72
- package/functions/partials/resolveDocsMethod.mjs +10 -10
- package/functions/partials/resolveDocsMethod.test.mjs +33 -33
- package/functions/partials/runOnChange.mjs +54 -54
- package/functions/partials/runOnChange.test.mjs +95 -95
- package/functions/partials/sassFor.mjs +25 -25
- package/functions/partials/sassFor.test.mjs +81 -81
- package/functions/partials/serveStatic.mjs +47 -47
- package/functions/partials/serveStatic.test.mjs +71 -71
- package/functions/partials/tsFor.mjs +92 -92
- package/functions/partials/tsFor.test.mjs +88 -88
- package/functions/partials/typeDocsFor.mjs +231 -231
- package/functions/partials/typeDocsFor.test.mjs +263 -263
- package/functions/partials.mjs +32 -31
- package/functions/partials.test.mjs +7 -7
- package/functions/sass.mjs +4 -4
- package/functions/sass.test.mjs +31 -31
- package/functions/sourceLint.mjs +13 -13
- package/functions/sourceLint.test.mjs +166 -166
- package/functions/test-helpers/neostandardLintWithRealNeostandard.mjs +40 -40
- package/functions/test-helpers/setUp.mjs +102 -100
- package/functions/test-helpers/setUp.test.mjs +19 -19
- package/functions/testFull.mjs +17 -17
- package/functions/testFull.test.mjs +17 -17
- package/functions/testHelpers.mjs +10 -10
- package/functions/testHelpers.test.mjs +7 -7
- package/functions/testQuick.mjs +17 -17
- package/functions/testQuick.test.mjs +17 -17
- package/functions/typeDocs.mjs +9 -9
- package/functions/typeDocs.test.mjs +11 -11
- package/functions/typeScript.mjs +8 -8
- package/functions/typeScript.test.mjs +11 -11
- package/functions/utilities/convertMjsFilesForDocs.mjs +34 -34
- package/functions/utilities/convertMjsFilesForDocs.test.mjs +58 -58
- package/functions/utilities/dotGet.mjs +49 -49
- package/functions/utilities/dotNotate.mjs +73 -73
- package/functions/utilities/dotNotate.test.mjs +41 -41
- package/functions/utilities/dotSet.mjs +40 -40
- package/functions/utilities/esmNamedExportsToCjs.mjs +30 -30
- package/functions/utilities/esmNamedExportsToCjs.test.mjs +47 -47
- package/functions/utilities/getBundleConfigs.mjs +30 -30
- package/functions/utilities/isObject.mjs +8 -8
- package/functions/utilities/strAfter.mjs +12 -12
- package/functions/utilities/strBefore.mjs +12 -12
- package/functions/watchFull.mjs +9 -9
- package/functions/watchFull.test.mjs +41 -41
- package/functions/watchTest.mjs +10 -10
- package/functions/watchTest.test.mjs +49 -49
- package/gulp.config.js +4 -4
- package/gulp.config.mjs +349 -340
- package/gulpfile.base.js +51 -51
- package/gulpfile.base.mjs +29 -29
- package/jsdoc.base.js +16 -16
- package/jsdoc.esmExports.js +17 -17
- package/package.json +146 -145
- package/dist/test-helpers/isolateGulpCache.js +0 -25
- package/functions/test-helpers/isolateGulpCache.mjs +0 -16
|
@@ -1,152 +1,163 @@
|
|
|
1
|
-
import fs from 'node:fs'
|
|
2
|
-
import os from 'node:os'
|
|
3
|
-
import path from 'node:path'
|
|
4
|
-
import { createRequire } from 'node:module'
|
|
5
|
-
import { execFile } from 'node:child_process'
|
|
6
|
-
import { promisify } from 'node:util'
|
|
7
|
-
import * as gulpConfig from '../../gulp.config.mjs'
|
|
8
|
-
import { removeDirectory } from './removeDirectory.mjs'
|
|
9
|
-
// jsdoc.base.js is CommonJS (it's also required directly by consuming projects' own .jsdoc.conf.js) - Node's ESM
|
|
10
|
-
// loader imports a CJS module's module.exports as the default export directly, no createRequire/import.meta needed
|
|
11
|
-
// (import.meta.url tripped up this project's own Babel CJS transform, which Jest relies on to run .mjs test files -
|
|
12
|
-
// confirmed by removing it and nothing else changing).
|
|
13
|
-
import jsdocBase from '../../jsdoc.base.js'
|
|
14
|
-
|
|
15
|
-
const execFileAsync = promisify(execFile)
|
|
16
|
-
|
|
17
|
-
const escapeHtml = text => String(text).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"')
|
|
18
|
-
|
|
19
|
-
const jsdocInstallHint = 'Install it in your project with: npm install --save-dev jsdoc'
|
|
20
|
-
const themeInstallHint = name => `Install it in your project with: npm install --save-dev ${name}`
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Resolve the installed directory of an optional peer dependency, from the project being built rather than from
|
|
24
|
-
* this package. Deliberately not requirePeer/importPeer's own `require(name + '/package.json')` approach - that
|
|
25
|
-
* breaks for any package whose own package.json restricts its exports map and does not expose that subpath
|
|
26
|
-
* (clean-jsdoc-theme does; confirmed live, not assumed - resolving its own package.json throws
|
|
27
|
-
* ERR_PACKAGE_PATH_NOT_EXPORTED in plain Node, and a differently-shaped MODULE_NOT_FOUND under Jest's own
|
|
28
|
-
* resolver, which still is not "not installed" either way). Walking Node's own real module-lookup directories
|
|
29
|
-
* (require.resolve.paths) and checking each on disk sidesteps the exports map entirely - this only ever reads
|
|
30
|
-
* whether `<dir>/<name>/package.json` exists, never asks the module system to resolve a restricted subpath.
|
|
31
|
-
* @memberOf module:partials
|
|
32
|
-
* @param {string} name - The package name.
|
|
33
|
-
* @param {Object} options
|
|
34
|
-
* @param {string} options.task
|
|
35
|
-
* @param {string} options.installHint
|
|
36
|
-
* @param {string} [options.projectPath=process.cwd()]
|
|
37
|
-
* @returns {string}
|
|
38
|
-
* @throws {Error} With install instructions when the package is not installed.
|
|
39
|
-
*/
|
|
40
|
-
const resolvePeerDir = (name, { task, installHint, projectPath = process.cwd() }) => {
|
|
41
|
-
const req = createRequire(path.join(projectPath, 'package.json'))
|
|
42
|
-
const found = (req.resolve.paths(name) || [])
|
|
43
|
-
.map(dir => path.join(dir, name))
|
|
44
|
-
.find(dir => fs.existsSync(path.join(dir, 'package.json')))
|
|
45
|
-
if (!found) {
|
|
46
|
-
throw new Error(`The ${task} task needs the optional peer dependency ${name}, which is not installed. ${installHint}`)
|
|
47
|
-
}
|
|
48
|
-
return found
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Resolve jsdoc's own CLI entry point. jsdoc has no stable programmatic Node API for generating HTML docs (unlike
|
|
53
|
-
* TypeDoc's Application.bootstrap()/convert()/generateDocs()) - gulp-jsdoc3, the established gulp wrapper, is
|
|
54
|
-
* stale, and its own README admits jsdoc does not support piped input in the first place, a real anti-pattern for
|
|
55
|
-
* this project's own gulp-stream conventions. Running its real CLI via child_process is the portable way in -
|
|
56
|
-
* confirmed via `npm view jsdoc bin`, which reports "jsdoc.js" at the package root.
|
|
57
|
-
* @memberOf module:partials
|
|
58
|
-
* @param {string} [projectPath=process.cwd()]
|
|
59
|
-
* @returns {string}
|
|
60
|
-
*/
|
|
61
|
-
export const resolveJsdocBin = (projectPath = process.cwd()) =>
|
|
62
|
-
path.join(resolvePeerDir('jsdoc', { task: 'docs', installHint: jsdocInstallHint, projectPath }), 'jsdoc.js')
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Resolve a jsdoc theme package's own template directory, for jsdoc's own opts.template config key: the folder
|
|
66
|
-
* holding its publish.js. That is the package root for a classic jsdoc template (clean-jsdoc-theme 4.x included),
|
|
67
|
-
* but `dist` for a bundled one (clean-jsdoc-theme 5.x).
|
|
68
|
-
* @memberOf module:partials
|
|
69
|
-
* @param {string} name
|
|
70
|
-
* @param {string} [projectPath=process.cwd()]
|
|
71
|
-
* @returns {string}
|
|
72
|
-
*/
|
|
73
|
-
export const resolveJsdocTheme = (name, projectPath = process.cwd()) => {
|
|
74
|
-
const packageDir = resolvePeerDir(name, { task: 'docs', installHint: themeInstallHint(name), projectPath })
|
|
75
|
-
const distDir = path.join(packageDir, 'dist')
|
|
76
|
-
return fs.existsSync(path.join(distDir, 'publish.js')) ? distDir : packageDir
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Generate the HTML documentation of a plain-JavaScript project with jsdoc, using jsdoc.base.js's own shared
|
|
81
|
-
* config (plugins, includePattern/excludePattern) as the starting point rather than a parallel one - the same
|
|
82
|
-
* base a project's own .jsdoc.conf.js has always been able to extend, just with source.include and the output
|
|
83
|
-
* options generated here instead of hand-maintained per project. Configure this with 'docs.from', 'docs.to',
|
|
84
|
-
* 'docs.index', 'docs.theme' and 'docs.title'.
|
|
85
|
-
* @memberOf module:partials
|
|
86
|
-
* @param {string|Array<string>} [srcPath=gulpConfig.get('docs.from')] - The directory (or directories and files) holding
|
|
87
|
-
* the JS source.
|
|
88
|
-
* @param {string} [outPath=gulpConfig.get('docs.to')] - The directory the documentation is generated into (cleared first).
|
|
89
|
-
* @param {function(string, Array<string>): Promise<Object>} [runJsdoc] - Runs the jsdoc CLI, tests can inject a stand-in.
|
|
90
|
-
* @returns {Function} A gulp task, it accepts an optional callback and returns a promise.
|
|
91
|
-
*/
|
|
92
|
-
export const jsdocDocsFor = (
|
|
93
|
-
srcPath = gulpConfig.get('docs.from'),
|
|
94
|
-
outPath = gulpConfig.get('docs.to'),
|
|
95
|
-
runJsdoc = (bin, args) => execFileAsync(process.execPath, [bin, ...args])
|
|
96
|
-
) => {
|
|
97
|
-
if (gulpConfig.get('docs.enabled') === false) {
|
|
98
|
-
return () => {}
|
|
99
|
-
}
|
|
100
|
-
return (done) => {
|
|
101
|
-
const generate = async () => {
|
|
102
|
-
const theme = gulpConfig.get('docs.theme') || 'clean-jsdoc-theme'
|
|
103
|
-
const themeDir = resolveJsdocTheme(theme)
|
|
104
|
-
const indexFile = gulpConfig.get('docs.index')
|
|
105
|
-
const title = gulpConfig.get('docs.title')
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import os from 'node:os'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import { createRequire } from 'node:module'
|
|
5
|
+
import { execFile } from 'node:child_process'
|
|
6
|
+
import { promisify } from 'node:util'
|
|
7
|
+
import * as gulpConfig from '../../gulp.config.mjs'
|
|
8
|
+
import { removeDirectory } from './removeDirectory.mjs'
|
|
9
|
+
// jsdoc.base.js is CommonJS (it's also required directly by consuming projects' own .jsdoc.conf.js) - Node's ESM
|
|
10
|
+
// loader imports a CJS module's module.exports as the default export directly, no createRequire/import.meta needed
|
|
11
|
+
// (import.meta.url tripped up this project's own Babel CJS transform, which Jest relies on to run .mjs test files -
|
|
12
|
+
// confirmed by removing it and nothing else changing).
|
|
13
|
+
import jsdocBase from '../../jsdoc.base.js'
|
|
14
|
+
|
|
15
|
+
const execFileAsync = promisify(execFile)
|
|
16
|
+
|
|
17
|
+
const escapeHtml = text => String(text).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"')
|
|
18
|
+
|
|
19
|
+
const jsdocInstallHint = 'Install it in your project with: npm install --save-dev jsdoc'
|
|
20
|
+
const themeInstallHint = name => `Install it in your project with: npm install --save-dev ${name}`
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the installed directory of an optional peer dependency, from the project being built rather than from
|
|
24
|
+
* this package. Deliberately not requirePeer/importPeer's own `require(name + '/package.json')` approach - that
|
|
25
|
+
* breaks for any package whose own package.json restricts its exports map and does not expose that subpath
|
|
26
|
+
* (clean-jsdoc-theme does; confirmed live, not assumed - resolving its own package.json throws
|
|
27
|
+
* ERR_PACKAGE_PATH_NOT_EXPORTED in plain Node, and a differently-shaped MODULE_NOT_FOUND under Jest's own
|
|
28
|
+
* resolver, which still is not "not installed" either way). Walking Node's own real module-lookup directories
|
|
29
|
+
* (require.resolve.paths) and checking each on disk sidesteps the exports map entirely - this only ever reads
|
|
30
|
+
* whether `<dir>/<name>/package.json` exists, never asks the module system to resolve a restricted subpath.
|
|
31
|
+
* @memberOf module:partials
|
|
32
|
+
* @param {string} name - The package name.
|
|
33
|
+
* @param {Object} options
|
|
34
|
+
* @param {string} options.task
|
|
35
|
+
* @param {string} options.installHint
|
|
36
|
+
* @param {string} [options.projectPath=process.cwd()]
|
|
37
|
+
* @returns {string}
|
|
38
|
+
* @throws {Error} With install instructions when the package is not installed.
|
|
39
|
+
*/
|
|
40
|
+
const resolvePeerDir = (name, { task, installHint, projectPath = process.cwd() }) => {
|
|
41
|
+
const req = createRequire(path.join(projectPath, 'package.json'))
|
|
42
|
+
const found = (req.resolve.paths(name) || [])
|
|
43
|
+
.map(dir => path.join(dir, name))
|
|
44
|
+
.find(dir => fs.existsSync(path.join(dir, 'package.json')))
|
|
45
|
+
if (!found) {
|
|
46
|
+
throw new Error(`The ${task} task needs the optional peer dependency ${name}, which is not installed. ${installHint}`)
|
|
47
|
+
}
|
|
48
|
+
return found
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Resolve jsdoc's own CLI entry point. jsdoc has no stable programmatic Node API for generating HTML docs (unlike
|
|
53
|
+
* TypeDoc's Application.bootstrap()/convert()/generateDocs()) - gulp-jsdoc3, the established gulp wrapper, is
|
|
54
|
+
* stale, and its own README admits jsdoc does not support piped input in the first place, a real anti-pattern for
|
|
55
|
+
* this project's own gulp-stream conventions. Running its real CLI via child_process is the portable way in -
|
|
56
|
+
* confirmed via `npm view jsdoc bin`, which reports "jsdoc.js" at the package root.
|
|
57
|
+
* @memberOf module:partials
|
|
58
|
+
* @param {string} [projectPath=process.cwd()]
|
|
59
|
+
* @returns {string}
|
|
60
|
+
*/
|
|
61
|
+
export const resolveJsdocBin = (projectPath = process.cwd()) =>
|
|
62
|
+
path.join(resolvePeerDir('jsdoc', { task: 'docs', installHint: jsdocInstallHint, projectPath }), 'jsdoc.js')
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Resolve a jsdoc theme package's own template directory, for jsdoc's own opts.template config key: the folder
|
|
66
|
+
* holding its publish.js. That is the package root for a classic jsdoc template (clean-jsdoc-theme 4.x included),
|
|
67
|
+
* but `dist` for a bundled one (clean-jsdoc-theme 5.x).
|
|
68
|
+
* @memberOf module:partials
|
|
69
|
+
* @param {string} name
|
|
70
|
+
* @param {string} [projectPath=process.cwd()]
|
|
71
|
+
* @returns {string}
|
|
72
|
+
*/
|
|
73
|
+
export const resolveJsdocTheme = (name, projectPath = process.cwd()) => {
|
|
74
|
+
const packageDir = resolvePeerDir(name, { task: 'docs', installHint: themeInstallHint(name), projectPath })
|
|
75
|
+
const distDir = path.join(packageDir, 'dist')
|
|
76
|
+
return fs.existsSync(path.join(distDir, 'publish.js')) ? distDir : packageDir
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Generate the HTML documentation of a plain-JavaScript project with jsdoc, using jsdoc.base.js's own shared
|
|
81
|
+
* config (plugins, includePattern/excludePattern) as the starting point rather than a parallel one - the same
|
|
82
|
+
* base a project's own .jsdoc.conf.js has always been able to extend, just with source.include and the output
|
|
83
|
+
* options generated here instead of hand-maintained per project. Configure this with 'docs.from', 'docs.to',
|
|
84
|
+
* 'docs.index', 'docs.theme' and 'docs.title'.
|
|
85
|
+
* @memberOf module:partials
|
|
86
|
+
* @param {string|Array<string>} [srcPath=gulpConfig.get('docs.from')] - The directory (or directories and files) holding
|
|
87
|
+
* the JS source.
|
|
88
|
+
* @param {string} [outPath=gulpConfig.get('docs.to')] - The directory the documentation is generated into (cleared first).
|
|
89
|
+
* @param {function(string, Array<string>): Promise<Object>} [runJsdoc] - Runs the jsdoc CLI, tests can inject a stand-in.
|
|
90
|
+
* @returns {Function} A gulp task, it accepts an optional callback and returns a promise.
|
|
91
|
+
*/
|
|
92
|
+
export const jsdocDocsFor = (
|
|
93
|
+
srcPath = gulpConfig.get('docs.from'),
|
|
94
|
+
outPath = gulpConfig.get('docs.to'),
|
|
95
|
+
runJsdoc = (bin, args) => execFileAsync(process.execPath, [bin, ...args])
|
|
96
|
+
) => {
|
|
97
|
+
if (gulpConfig.get('docs.enabled') === false) {
|
|
98
|
+
return () => {}
|
|
99
|
+
}
|
|
100
|
+
return (done) => {
|
|
101
|
+
const generate = async () => {
|
|
102
|
+
const theme = gulpConfig.get('docs.theme') || 'clean-jsdoc-theme'
|
|
103
|
+
const themeDir = resolveJsdocTheme(theme)
|
|
104
|
+
const indexFile = gulpConfig.get('docs.index')
|
|
105
|
+
const title = gulpConfig.get('docs.title')
|
|
106
|
+
const basePath = gulpConfig.get('docs.basePath')
|
|
107
|
+
await removeDirectory(outPath)
|
|
108
|
+
const workDir = fs.mkdtempSync(path.join(os.tmpdir(), 'jsdocdocs-'))
|
|
109
|
+
// clean-jsdoc-theme 5.x writes no index.html at all without a front page, so fall back to one with the title
|
|
110
|
+
let readme = indexFile && fs.existsSync(indexFile) ? path.resolve(indexFile) : ''
|
|
111
|
+
if (!readme) {
|
|
112
|
+
readme = path.join(workDir, 'index.md')
|
|
113
|
+
fs.writeFileSync(readme, `# ${title || 'Documentation'}\n`)
|
|
114
|
+
}
|
|
115
|
+
const config = {
|
|
116
|
+
...jsdocBase,
|
|
117
|
+
source: {
|
|
118
|
+
...jsdocBase.source,
|
|
119
|
+
include: [].concat(srcPath).map(includePath => path.resolve(includePath))
|
|
120
|
+
},
|
|
121
|
+
opts: {
|
|
122
|
+
destination: path.resolve(outPath),
|
|
123
|
+
// jsdoc does not recurse into source.include's own subdirectories by default - without this, only
|
|
124
|
+
// the top level of docs.from would ever be scanned. Confirmed from clean-jsdoc-theme's own README
|
|
125
|
+
// quick-start example, which sets this explicitly, not assumed from jsdoc's own classic defaults.
|
|
126
|
+
recurse: true,
|
|
127
|
+
template: themeDir,
|
|
128
|
+
// clean-jsdoc-theme 4.x's own options for the name in its header and the home page's <title> (otherwise "Home").
|
|
129
|
+
// The header is given as a link: a plain-text title links to the site root ("/"), while every page is in one
|
|
130
|
+
// folder, so index.html is the home page wherever they are served. Both are printed unescaped by the theme.
|
|
131
|
+
// clean-jsdoc-theme 5.x reads its options from opts itself: the name in its header and <title>, and the path
|
|
132
|
+
// its root-absolute links start from (4.x reads only theme_opts).
|
|
133
|
+
...(title ? { siteName: title } : {}),
|
|
134
|
+
...(basePath ? { basePath } : {}),
|
|
135
|
+
...(title
|
|
136
|
+
? {
|
|
137
|
+
theme_opts: {
|
|
138
|
+
title: `<a href="index.html" class="sidebar-title sidebar-title-anchor">${escapeHtml(title)}</a>`,
|
|
139
|
+
homepageTitle: escapeHtml(title)
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
: {}),
|
|
143
|
+
readme
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
try {
|
|
147
|
+
const configPath = path.join(workDir, 'jsdoc.conf.json')
|
|
148
|
+
fs.writeFileSync(configPath, JSON.stringify(config))
|
|
149
|
+
const bin = resolveJsdocBin()
|
|
150
|
+
// Pass on what jsdoc and the theme report (warnings such as a page which failed to render), which would
|
|
151
|
+
// otherwise be lost with the captured output
|
|
152
|
+
const { stdout = '', stderr = '' } = (await runJsdoc(bin, ['-c', configPath])) || {}
|
|
153
|
+
const report = `${stdout}${stderr}`.trim()
|
|
154
|
+
if (report) {
|
|
155
|
+
console.warn(report)
|
|
156
|
+
}
|
|
157
|
+
} finally {
|
|
158
|
+
await removeDirectory(workDir)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return typeof done === 'function' ? generate().then(() => done(), done) : generate()
|
|
162
|
+
}
|
|
163
|
+
}
|