js-build-tools 6.2.0 → 6.3.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/README.md +180 -9
- package/dist/build.js +2 -4
- package/dist/build.min.js +1 -1
- package/dist/bundle.js +1 -1
- package/dist/docs.js +19 -0
- package/dist/docs.min.js +1 -0
- package/dist/partials/jsdocDocsFor.js +31 -13
- package/dist/partials/loadPlaywright.js +34 -0
- package/dist/partials/neostandardLint.js +5 -3
- package/dist/partials/resolveDocsMethod.js +19 -0
- package/dist/partials/serveStatic.js +57 -0
- package/dist/partials/tsFor.js +2 -2
- package/dist/partials/typeDocsFor.js +28 -22
- package/dist/partials.js +34 -0
- package/dist/partials.min.js +1 -1
- package/dist/test-helpers/setUp.js +6 -0
- package/dist/utilities/convertMjsFilesForDocs.js +1 -0
- package/dist/utilities/dotGet.js +1 -0
- package/dist/utilities/dotNotate.js +5 -0
- package/dist/utilities/dotSet.js +1 -0
- package/dist/utilities/esmNamedExportsToCjs.js +1 -0
- package/dist/utilities/getBundleConfigs.js +1 -0
- package/dist/utilities/isObject.js +1 -0
- package/dist/utilities/strAfter.js +1 -0
- package/dist/utilities/strBefore.js +1 -0
- package/functions/build.mjs +2 -4
- package/functions/bundle.mjs +1 -1
- package/functions/docs.mjs +13 -0
- package/functions/docs.test.mjs +45 -0
- package/functions/jsdocEsmExports.test.mjs +24 -0
- package/functions/partials/jsdocDocsFor.mjs +25 -13
- package/functions/partials/jsdocDocsFor.test.mjs +48 -0
- package/functions/partials/loadPlaywright.mjs +23 -0
- package/functions/partials/loadPlaywright.test.mjs +71 -0
- package/functions/partials/neostandardLint.mjs +5 -3
- package/functions/partials/resolveDocsMethod.mjs +10 -0
- package/functions/partials/resolveDocsMethod.test.mjs +33 -0
- package/functions/partials/serveStatic.mjs +47 -0
- package/functions/partials/serveStatic.test.mjs +71 -0
- package/functions/partials/tsFor.mjs +2 -2
- package/functions/partials/typeDocsFor.mjs +24 -20
- package/functions/partials/typeDocsFor.test.mjs +23 -0
- package/functions/partials.mjs +4 -0
- package/functions/partials.test.mjs +1 -1
- package/functions/test-helpers/setUp.mjs +6 -0
- package/functions/utilities/convertMjsFilesForDocs.mjs +1 -0
- package/functions/utilities/dotGet.mjs +1 -0
- package/functions/utilities/dotNotate.mjs +5 -0
- package/functions/utilities/dotSet.mjs +1 -0
- package/functions/utilities/esmNamedExportsToCjs.mjs +1 -0
- package/functions/utilities/getBundleConfigs.mjs +1 -0
- package/functions/utilities/isObject.mjs +1 -0
- package/functions/utilities/strAfter.mjs +1 -0
- package/functions/utilities/strBefore.mjs +1 -0
- package/gulp.config.mjs +2 -2
- package/gulpfile.base.mjs +3 -4
- package/jsdoc.base.js +9 -3
- package/jsdoc.esmExports.js +17 -0
- package/package.json +19 -10
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.writeDocEntries = exports.typeDocsFor = exports.loadTypeDoc = exports.describeFolder = exports.describeFile = exports.describeExports = void 0;
|
|
8
|
+
require("core-js/modules/es.array.includes.js");
|
|
8
9
|
require("core-js/modules/es.json.stringify.js");
|
|
9
10
|
require("core-js/modules/esnext.iterator.constructor.js");
|
|
10
11
|
require("core-js/modules/esnext.iterator.filter.js");
|
|
@@ -42,12 +43,19 @@ exports.loadTypeDoc = loadTypeDoc;
|
|
|
42
43
|
const isSource = fileName => /\.(ts|tsx|mts|cts)$/.test(fileName) && !/\.d\.[cm]?ts$/.test(fileName) && !/\.(test|spec)\./.test(fileName);
|
|
43
44
|
const listSources = dirPath => _nodeFs.default.readdirSync(dirPath, {
|
|
44
45
|
withFileTypes: true
|
|
45
|
-
}).
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
}).filter(entry => entry.isFile() && isSource(entry.name)).map(entry => _nodePath.default.join(dirPath, entry.name));
|
|
47
|
+
|
|
48
|
+
// Every folder below dirPath (at any depth), named by its path from dirPath, with the source files directly in it
|
|
49
|
+
const listFolders = (dirPath, prefix = '') => _nodeFs.default.readdirSync(dirPath, {
|
|
50
|
+
withFileTypes: true
|
|
51
|
+
}).filter(entry => entry.isDirectory() && entry.name !== 'node_modules').flatMap(entry => {
|
|
52
|
+
const folderPath = _nodePath.default.join(dirPath, entry.name);
|
|
53
|
+
const name = `${prefix}${entry.name}`;
|
|
54
|
+
return [{
|
|
55
|
+
name,
|
|
56
|
+
path: folderPath,
|
|
57
|
+
files: listSources(folderPath)
|
|
58
|
+
}, ...listFolders(folderPath, `${name}/`)];
|
|
51
59
|
});
|
|
52
60
|
const toIdentifier = fileName => fileName.replace(/[^\w$]+(\w)?/g, (match, letter) => (letter || '').toUpperCase()).replace(/^(\d)/, '_$1');
|
|
53
61
|
const toModulePath = filePath => filePath.replace(/\.[cm]?tsx?$/, '').split(_nodePath.default.sep).join('/');
|
|
@@ -127,11 +135,12 @@ const describeFile = filePath => {
|
|
|
127
135
|
|
|
128
136
|
/**
|
|
129
137
|
* Write one entry file per folder of the source directory into the entry directory. TypeDoc makes a module of every
|
|
130
|
-
* entry file, so the modules of the documentation mirror the folders.
|
|
138
|
+
* entry file, so the modules of the documentation mirror the folders. Nested folders are modules of their own, named
|
|
139
|
+
* by their path (utilities/parsers), and a folder's module holds only the files directly in it. The default export of each source file is
|
|
131
140
|
* re-exported under the name of the file (the source files hold one function each), and anything else a file exports
|
|
132
141
|
* is re-exported as it is (that is where the types.ts files go). Index files (the barrels), tests and declaration
|
|
133
142
|
* files are left out, but the first doc comment of a folder's index file becomes the description of its module.
|
|
134
|
-
* A file which sits beside the folders (not an index or
|
|
143
|
+
* A file which sits beside the folders (not an index, main or browser file) is a module of its own, described by its header
|
|
135
144
|
* comment. A source directory with no folders gets a single entry called index.
|
|
136
145
|
* @memberOf module:partials
|
|
137
146
|
* @param {Object} ts - The TypeScript compiler API.
|
|
@@ -145,18 +154,10 @@ const writeDocEntries = (ts, srcDir, entryDir) => {
|
|
|
145
154
|
_nodeFs.default.mkdirSync(entryDir, {
|
|
146
155
|
recursive: true
|
|
147
156
|
});
|
|
148
|
-
const folders =
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
path: _nodePath.default.join(absoluteSrc, entry.name),
|
|
153
|
-
files: listSources(_nodePath.default.join(absoluteSrc, entry.name))
|
|
154
|
-
})).filter(folder => folder.files.length);
|
|
155
|
-
const rootFiles = _nodeFs.default.readdirSync(absoluteSrc, {
|
|
156
|
-
withFileTypes: true
|
|
157
|
-
}).filter(entry => entry.isFile() && isSource(entry.name) && !/^(index|main)\./.test(entry.name)).map(entry => _nodePath.default.join(absoluteSrc, entry.name));
|
|
158
|
-
// Folders make modules, and so do the files which sit beside them (except the barrel: index and main). A source
|
|
159
|
-
// directory with no folders gets a single module called index which holds its files.
|
|
157
|
+
const folders = listFolders(absoluteSrc).filter(folder => folder.files.some(file => !/^index\./.test(_nodePath.default.basename(file))));
|
|
158
|
+
const rootFiles = listSources(absoluteSrc).filter(file => !/^(index|main|browser)\./.test(_nodePath.default.basename(file)));
|
|
159
|
+
// Folders make modules, and so do the files which sit beside them (except the barrels: index, main and browser, the
|
|
160
|
+
// browser bundle's entry). A source directory with no folders gets a single module called index which holds its files.
|
|
160
161
|
const groups = folders.length ? [...folders, ...rootFiles.map(file => ({
|
|
161
162
|
name: toIdentifier(_nodePath.default.basename(file).replace(/\.[cm]?tsx?$/, '')),
|
|
162
163
|
files: [file],
|
|
@@ -178,8 +179,13 @@ const writeDocEntries = (ts, srcDir, entryDir) => {
|
|
|
178
179
|
});
|
|
179
180
|
const description = group.description ?? (group.path ? describeFolder(group.path) : '');
|
|
180
181
|
// TypeDoc takes the first comment of an entry file which has the @module tag as the description of the module
|
|
181
|
-
|
|
182
|
+
// A nested folder's module is named by its path (utilities/parsers), so it is not mistaken for its parent's
|
|
183
|
+
const moduleName = group.name.includes('/') ? ` ${group.name}` : '';
|
|
184
|
+
const moduleComment = description || moduleName ? `/**\n${description ? description.split('\n').map(line => ` * ${line}`.trimEnd()).join('\n') + '\n' : ''} * @module${moduleName}\n */\n\n` : '';
|
|
182
185
|
const entryPath = _nodePath.default.join(entryDir, `${group.name}.ts`);
|
|
186
|
+
_nodeFs.default.mkdirSync(_nodePath.default.dirname(entryPath), {
|
|
187
|
+
recursive: true
|
|
188
|
+
});
|
|
183
189
|
_nodeFs.default.writeFileSync(entryPath, moduleComment + lines.join('\n') + '\n');
|
|
184
190
|
return entryPath;
|
|
185
191
|
});
|
|
@@ -225,7 +231,7 @@ const typeDocsFor = (srcPath = gulpConfig.get('docs.from'), outPath = gulpConfig
|
|
|
225
231
|
...(projectConfig ? {
|
|
226
232
|
extends: _nodePath.default.resolve(projectConfig)
|
|
227
233
|
} : {}),
|
|
228
|
-
include: [_nodePath.default.join(workDir, 'entries', '*.ts').split(_nodePath.default.sep).join('/'), _nodePath.default.resolve(srcPath).split(_nodePath.default.sep).join('/') + '/**/*.ts'],
|
|
234
|
+
include: [_nodePath.default.join(workDir, 'entries', '**', '*.ts').split(_nodePath.default.sep).join('/'), _nodePath.default.resolve(srcPath).split(_nodePath.default.sep).join('/') + '/**/*.ts'],
|
|
229
235
|
exclude: [_nodePath.default.resolve(srcPath).split(_nodePath.default.sep).join('/') + '/**/*.test.*']
|
|
230
236
|
}));
|
|
231
237
|
const indexFile = gulpConfig.get('docs.index');
|
package/dist/partials.js
CHANGED
|
@@ -63,6 +63,24 @@ Object.defineProperty(exports, "importPeer", {
|
|
|
63
63
|
return _loadPeer.importPeer;
|
|
64
64
|
}
|
|
65
65
|
});
|
|
66
|
+
Object.defineProperty(exports, "jsdocDocsFor", {
|
|
67
|
+
enumerable: true,
|
|
68
|
+
get: function () {
|
|
69
|
+
return _jsdocDocsFor.jsdocDocsFor;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
Object.defineProperty(exports, "launchBrowser", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: function () {
|
|
75
|
+
return _loadPlaywright.launchBrowser;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
Object.defineProperty(exports, "loadPlaywright", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
get: function () {
|
|
81
|
+
return _loadPlaywright.loadPlaywright;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
66
84
|
Object.defineProperty(exports, "minifyFor", {
|
|
67
85
|
enumerable: true,
|
|
68
86
|
get: function () {
|
|
@@ -93,6 +111,12 @@ Object.defineProperty(exports, "requirePeer", {
|
|
|
93
111
|
return _loadPeer.requirePeer;
|
|
94
112
|
}
|
|
95
113
|
});
|
|
114
|
+
Object.defineProperty(exports, "resolveDocsMethod", {
|
|
115
|
+
enumerable: true,
|
|
116
|
+
get: function () {
|
|
117
|
+
return _resolveDocsMethod.resolveDocsMethod;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
96
120
|
Object.defineProperty(exports, "runOnChange", {
|
|
97
121
|
enumerable: true,
|
|
98
122
|
get: function () {
|
|
@@ -105,6 +129,12 @@ Object.defineProperty(exports, "sassFor", {
|
|
|
105
129
|
return _sassFor.sassFor;
|
|
106
130
|
}
|
|
107
131
|
});
|
|
132
|
+
Object.defineProperty(exports, "serveStatic", {
|
|
133
|
+
enumerable: true,
|
|
134
|
+
get: function () {
|
|
135
|
+
return _serveStatic.serveStatic;
|
|
136
|
+
}
|
|
137
|
+
});
|
|
108
138
|
Object.defineProperty(exports, "tsFor", {
|
|
109
139
|
enumerable: true,
|
|
110
140
|
get: function () {
|
|
@@ -126,11 +156,15 @@ var _distForSrc = require("./partials/distForSrc.js");
|
|
|
126
156
|
var _distSeries = require("./partials/distSeries.js");
|
|
127
157
|
var _imagesFor = require("./partials/imagesFor.js");
|
|
128
158
|
var _loadPeer = require("./partials/loadPeer.js");
|
|
159
|
+
var _jsdocDocsFor = require("./partials/jsdocDocsFor.js");
|
|
160
|
+
var _loadPlaywright = require("./partials/loadPlaywright.js");
|
|
129
161
|
var _minifyFor = require("./partials/minifyFor.js");
|
|
130
162
|
var _neostandardLint = require("./partials/neostandardLint.js");
|
|
131
163
|
var _readmeTemplate = require("./partials/readmeTemplate.js");
|
|
132
164
|
var _removeDirectory = require("./partials/removeDirectory.js");
|
|
165
|
+
var _resolveDocsMethod = require("./partials/resolveDocsMethod.js");
|
|
133
166
|
var _runOnChange = require("./partials/runOnChange.js");
|
|
134
167
|
var _sassFor = require("./partials/sassFor.js");
|
|
168
|
+
var _serveStatic = require("./partials/serveStatic.js");
|
|
135
169
|
var _tsFor = require("./partials/tsFor.js");
|
|
136
170
|
var _typeDocsFor = require("./partials/typeDocsFor.js");
|
package/dist/partials.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"addToReadme",{enumerable:!0,get:function(){return _addToReadme.addToReadme}}),Object.defineProperty(exports,"beginWatcher",{enumerable:!0,get:function(){return _beginWatcher.beginWatcher}}),Object.defineProperty(exports,"clean",{enumerable:!0,get:function(){return _clean.clean}}),Object.defineProperty(exports,"copyFor",{enumerable:!0,get:function(){return _copyFor.copyFor}}),Object.defineProperty(exports,"distFor",{enumerable:!0,get:function(){return _distFor.distFor}}),Object.defineProperty(exports,"distForSrc",{enumerable:!0,get:function(){return _distForSrc.distForSrc}}),Object.defineProperty(exports,"distSeries",{enumerable:!0,get:function(){return _distSeries.distSeries}}),Object.defineProperty(exports,"imagesFor",{enumerable:!0,get:function(){return _imagesFor.imagesFor}}),Object.defineProperty(exports,"importModule",{enumerable:!0,get:function(){return _loadPeer.importModule}}),Object.defineProperty(exports,"importPeer",{enumerable:!0,get:function(){return _loadPeer.importPeer}}),Object.defineProperty(exports,"minifyFor",{enumerable:!0,get:function(){return _minifyFor.minifyFor}}),Object.defineProperty(exports,"neostandardLint",{enumerable:!0,get:function(){return _neostandardLint.neostandardLint}}),Object.defineProperty(exports,"readmeTemplate",{enumerable:!0,get:function(){return _readmeTemplate.readmeTemplate}}),Object.defineProperty(exports,"removeDirectory",{enumerable:!0,get:function(){return _removeDirectory.removeDirectory}}),Object.defineProperty(exports,"requirePeer",{enumerable:!0,get:function(){return _loadPeer.requirePeer}}),Object.defineProperty(exports,"runOnChange",{enumerable:!0,get:function(){return _runOnChange.runOnChange}}),Object.defineProperty(exports,"sassFor",{enumerable:!0,get:function(){return _sassFor.sassFor}}),Object.defineProperty(exports,"tsFor",{enumerable:!0,get:function(){return _tsFor.tsFor}}),Object.defineProperty(exports,"typeDocsFor",{enumerable:!0,get:function(){return _typeDocsFor.typeDocsFor}});var _addToReadme=require("./partials/addToReadme.js"),_beginWatcher=require("./partials/beginWatcher.js"),_clean=require("./partials/clean.js"),_copyFor=require("./partials/copyFor.js"),_distFor=require("./partials/distFor.js"),_distForSrc=require("./partials/distForSrc.js"),_distSeries=require("./partials/distSeries.js"),_imagesFor=require("./partials/imagesFor.js"),_loadPeer=require("./partials/loadPeer.js"),_minifyFor=require("./partials/minifyFor.js"),_neostandardLint=require("./partials/neostandardLint.js"),_readmeTemplate=require("./partials/readmeTemplate.js"),_removeDirectory=require("./partials/removeDirectory.js"),_runOnChange=require("./partials/runOnChange.js"),_sassFor=require("./partials/sassFor.js"),_tsFor=require("./partials/tsFor.js"),_typeDocsFor=require("./partials/typeDocsFor.js");
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),Object.defineProperty(exports,"addToReadme",{enumerable:!0,get:function(){return _addToReadme.addToReadme}}),Object.defineProperty(exports,"beginWatcher",{enumerable:!0,get:function(){return _beginWatcher.beginWatcher}}),Object.defineProperty(exports,"clean",{enumerable:!0,get:function(){return _clean.clean}}),Object.defineProperty(exports,"copyFor",{enumerable:!0,get:function(){return _copyFor.copyFor}}),Object.defineProperty(exports,"distFor",{enumerable:!0,get:function(){return _distFor.distFor}}),Object.defineProperty(exports,"distForSrc",{enumerable:!0,get:function(){return _distForSrc.distForSrc}}),Object.defineProperty(exports,"distSeries",{enumerable:!0,get:function(){return _distSeries.distSeries}}),Object.defineProperty(exports,"imagesFor",{enumerable:!0,get:function(){return _imagesFor.imagesFor}}),Object.defineProperty(exports,"importModule",{enumerable:!0,get:function(){return _loadPeer.importModule}}),Object.defineProperty(exports,"importPeer",{enumerable:!0,get:function(){return _loadPeer.importPeer}}),Object.defineProperty(exports,"jsdocDocsFor",{enumerable:!0,get:function(){return _jsdocDocsFor.jsdocDocsFor}}),Object.defineProperty(exports,"launchBrowser",{enumerable:!0,get:function(){return _loadPlaywright.launchBrowser}}),Object.defineProperty(exports,"loadPlaywright",{enumerable:!0,get:function(){return _loadPlaywright.loadPlaywright}}),Object.defineProperty(exports,"minifyFor",{enumerable:!0,get:function(){return _minifyFor.minifyFor}}),Object.defineProperty(exports,"neostandardLint",{enumerable:!0,get:function(){return _neostandardLint.neostandardLint}}),Object.defineProperty(exports,"readmeTemplate",{enumerable:!0,get:function(){return _readmeTemplate.readmeTemplate}}),Object.defineProperty(exports,"removeDirectory",{enumerable:!0,get:function(){return _removeDirectory.removeDirectory}}),Object.defineProperty(exports,"requirePeer",{enumerable:!0,get:function(){return _loadPeer.requirePeer}}),Object.defineProperty(exports,"resolveDocsMethod",{enumerable:!0,get:function(){return _resolveDocsMethod.resolveDocsMethod}}),Object.defineProperty(exports,"runOnChange",{enumerable:!0,get:function(){return _runOnChange.runOnChange}}),Object.defineProperty(exports,"sassFor",{enumerable:!0,get:function(){return _sassFor.sassFor}}),Object.defineProperty(exports,"serveStatic",{enumerable:!0,get:function(){return _serveStatic.serveStatic}}),Object.defineProperty(exports,"tsFor",{enumerable:!0,get:function(){return _tsFor.tsFor}}),Object.defineProperty(exports,"typeDocsFor",{enumerable:!0,get:function(){return _typeDocsFor.typeDocsFor}});var _addToReadme=require("./partials/addToReadme.js"),_beginWatcher=require("./partials/beginWatcher.js"),_clean=require("./partials/clean.js"),_copyFor=require("./partials/copyFor.js"),_distFor=require("./partials/distFor.js"),_distForSrc=require("./partials/distForSrc.js"),_distSeries=require("./partials/distSeries.js"),_imagesFor=require("./partials/imagesFor.js"),_loadPeer=require("./partials/loadPeer.js"),_jsdocDocsFor=require("./partials/jsdocDocsFor.js"),_loadPlaywright=require("./partials/loadPlaywright.js"),_minifyFor=require("./partials/minifyFor.js"),_neostandardLint=require("./partials/neostandardLint.js"),_readmeTemplate=require("./partials/readmeTemplate.js"),_removeDirectory=require("./partials/removeDirectory.js"),_resolveDocsMethod=require("./partials/resolveDocsMethod.js"),_runOnChange=require("./partials/runOnChange.js"),_sassFor=require("./partials/sassFor.js"),_serveStatic=require("./partials/serveStatic.js"),_tsFor=require("./partials/tsFor.js"),_typeDocsFor=require("./partials/typeDocsFor.js");
|
|
@@ -76,6 +76,12 @@ const setDefaults = (testDir = 'test-temp') => {
|
|
|
76
76
|
gulpConfig.set('dist.from', `${srcPath}/**/!(*.test).js`);
|
|
77
77
|
gulpConfig.set('dist.main', `${distPath}/main`);
|
|
78
78
|
gulpConfig.set('dist.to', distPath);
|
|
79
|
+
// Reset explicitly, for the same reason as readme.fromEsm below: this project's own build-tools.config.json turns
|
|
80
|
+
// docs on and points them at the website checkout, which would leak into every test that never sets these itself.
|
|
81
|
+
gulpConfig.set('docs.enabled', false);
|
|
82
|
+
gulpConfig.set('docs.from', srcPath);
|
|
83
|
+
gulpConfig.set('docs.to', `${tempDir}docs`);
|
|
84
|
+
gulpConfig.set('docs.title', '');
|
|
79
85
|
gulpConfig.set('fonts.from', `${srcPath}/fonts/**/*`);
|
|
80
86
|
gulpConfig.set('fonts.to', `${browserPath}/fonts`);
|
|
81
87
|
gulpConfig.set('images.from', `${srcPath}/img/**/*.+(png|jpg|jpeg|gif|svg)`);
|
|
@@ -22,6 +22,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
22
22
|
* @param {Array<string>} mjsFilePaths - Real `.mjs` files to convert. An empty array is a safe, cheap no-op.
|
|
23
23
|
* @returns {{filePaths: Array<string>, cleanUp: function(): void}} The temp `.js` file paths to pass to
|
|
24
24
|
* jsdoc-to-markdown instead of the real `.mjs` ones, and a function to remove the temp directory afterward.
|
|
25
|
+
* @private
|
|
25
26
|
*/
|
|
26
27
|
const convertMjsFilesForDocs = (mjsFilePaths = []) => {
|
|
27
28
|
if (mjsFilePaths.length === 0) {
|
package/dist/utilities/dotGet.js
CHANGED
|
@@ -14,6 +14,7 @@ var _strBefore = require("./strBefore.js");
|
|
|
14
14
|
* @param {string} [dotNotation=''] - The path to the property
|
|
15
15
|
* @param {string|null} [defaultValue=null] - The default value to return if the property is not found
|
|
16
16
|
* @returns {*} The value of the property
|
|
17
|
+
* @private
|
|
17
18
|
*/
|
|
18
19
|
const dotGet = (arrayObject = {}, dotNotation = '', defaultValue = null) => {
|
|
19
20
|
if (!dotNotation) {
|
|
@@ -11,12 +11,14 @@ var _isObject = require("./isObject.js");
|
|
|
11
11
|
* Convert an array of keys into a regex, return a function to test if incoming keys match.
|
|
12
12
|
* @param {Array.<string>} [retainObjects=[]] - An array of keys to retain as objects
|
|
13
13
|
* @returns {Function} The dot-notated array
|
|
14
|
+
* @private
|
|
14
15
|
*/
|
|
15
16
|
const handleRetainObjects = (retainObjects = []) => {
|
|
16
17
|
if (!retainObjects.length) {
|
|
17
18
|
/**
|
|
18
19
|
* Bypass the test function if there are no retainObjects.
|
|
19
20
|
* @returns {false}
|
|
21
|
+
* @private
|
|
20
22
|
*/
|
|
21
23
|
return (currentKey, value, results) => false;
|
|
22
24
|
}
|
|
@@ -28,6 +30,7 @@ const handleRetainObjects = (retainObjects = []) => {
|
|
|
28
30
|
* @param {*} value - The value of the key
|
|
29
31
|
* @param {Object} results - The result object to add to
|
|
30
32
|
* @returns {boolean}
|
|
33
|
+
* @private
|
|
31
34
|
*/
|
|
32
35
|
return (currentKey, value, results) => {
|
|
33
36
|
if (!currentKey.match(retainRegex)) {
|
|
@@ -45,6 +48,7 @@ const handleRetainObjects = (retainObjects = []) => {
|
|
|
45
48
|
* @param {string} [prepend=''] - The path for the property being processed
|
|
46
49
|
* @param {Object<string, *>} [results={}] - The final notated object to return
|
|
47
50
|
* @returns {Object<string, *>} The dot-notated object
|
|
51
|
+
* @private
|
|
48
52
|
*/
|
|
49
53
|
const performDotNotate = (arrayObject, didRetain, prepend = '', results = {}) => {
|
|
50
54
|
for (let key in arrayObject) {
|
|
@@ -70,6 +74,7 @@ const performDotNotate = (arrayObject, didRetain, prepend = '', results = {}) =>
|
|
|
70
74
|
* @param {Object} arrayObject - The array or object to dot-notate
|
|
71
75
|
* @param {Array.<string>} [retainObjects=[]] - An array of keys to retain as objects
|
|
72
76
|
* @returns {Object<string, *>} The dot-notated object
|
|
77
|
+
* @private
|
|
73
78
|
*/
|
|
74
79
|
const dotNotate = (arrayObject, retainObjects = []) => performDotNotate(arrayObject, handleRetainObjects(retainObjects));
|
|
75
80
|
exports.dotNotate = dotNotate;
|
package/dist/utilities/dotSet.js
CHANGED
|
@@ -14,6 +14,7 @@ var _strBefore = require("./strBefore.js");
|
|
|
14
14
|
* @param {string} dotNotation - The path for the property
|
|
15
15
|
* @param {*} value - The default value to return if the property is not found
|
|
16
16
|
* @returns {Object} The modified object
|
|
17
|
+
* @private
|
|
17
18
|
*/
|
|
18
19
|
const dotSet = (arrayObject, dotNotation, value = null) => {
|
|
19
20
|
let key = (0, _strBefore.strBefore)(dotNotation, '.');
|
|
@@ -18,6 +18,7 @@ exports.esmNamedExportsToCjs = void 0;
|
|
|
18
18
|
* @memberOf module:utilities
|
|
19
19
|
* @param {string} source - The raw ESM source text (never executed, just rewritten as text).
|
|
20
20
|
* @returns {string} The rewritten text, safe to write out with a `.js` extension for jsdoc-to-markdown to read.
|
|
21
|
+
* @private
|
|
21
22
|
*/
|
|
22
23
|
const esmNamedExportsToCjs = source => {
|
|
23
24
|
const exportedNames = [];
|
|
@@ -18,6 +18,7 @@ function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e;
|
|
|
18
18
|
* specify what's actually different about it.
|
|
19
19
|
* @memberOf module:utilities
|
|
20
20
|
* @returns {Array<{name: string, main: string, ignore: Array, exclude: Array}>}
|
|
21
|
+
* @private
|
|
21
22
|
*/
|
|
22
23
|
const getBundleConfigs = () => {
|
|
23
24
|
const primary = {
|
|
@@ -9,6 +9,7 @@ exports.isObject = void 0;
|
|
|
9
9
|
* Original source concepts from {@link https://github.com/jheagle/si-funciona/blob/main/src/helpers/objects/isObject.ts Sí, funciona}
|
|
10
10
|
* @param {*} object
|
|
11
11
|
* @returns {boolean}
|
|
12
|
+
* @private
|
|
12
13
|
*/
|
|
13
14
|
const isObject = object => typeof object === 'object' && object !== null;
|
|
14
15
|
exports.isObject = isObject;
|
package/functions/build.mjs
CHANGED
|
@@ -10,6 +10,7 @@ import { parallel, series } from 'gulp'
|
|
|
10
10
|
import * as gulpConfig from '../gulp.config.mjs'
|
|
11
11
|
import { copyFonts } from './copyFonts.mjs'
|
|
12
12
|
import { images } from './images.mjs'
|
|
13
|
+
import { resolveDocsMethod } from './partials/resolveDocsMethod.mjs'
|
|
13
14
|
import { sass } from './sass.mjs'
|
|
14
15
|
import { testFull } from './testFull.mjs'
|
|
15
16
|
|
|
@@ -23,10 +24,7 @@ import { testFull } from './testFull.mjs'
|
|
|
23
24
|
export const build = (done = null) => {
|
|
24
25
|
const buildActions = [distSeries(), distMinify]
|
|
25
26
|
const generateDocs = gulpConfig.get('docs.enabled')
|
|
26
|
-
|
|
27
|
-
// typescript.enabled - every existing TypeScript project's config, which never sets method, keeps producing
|
|
28
|
-
// TypeDoc output exactly as it always has.
|
|
29
|
-
const docsMethod = gulpConfig.get('docs.method') || (gulpConfig.get('typescript.enabled') ? 'typedoc' : 'jsdoc')
|
|
27
|
+
const docsMethod = resolveDocsMethod()
|
|
30
28
|
if (generateDocs) {
|
|
31
29
|
// The documentation is generated from the source itself, the readme is written by hand
|
|
32
30
|
buildActions.push(docsMethod === 'jsdoc' ? jsdocDocs : typeDocs)
|
package/functions/bundle.mjs
CHANGED
|
@@ -14,7 +14,7 @@ import { getBundleConfigs } from './utilities/getBundleConfigs.mjs'
|
|
|
14
14
|
*
|
|
15
15
|
* A bundle's name does double duty: it names the output file (name.js) and, via browserify's
|
|
16
16
|
* `standalone` option, is also the name its exports are exposed under - as a global when loaded
|
|
17
|
-
* with a bare
|
|
17
|
+
* with a bare `<script>` tag, or as the module when required via CommonJS/AMD. Without this, a
|
|
18
18
|
* bundle built from a real entry point (one that actually exports something) builds successfully
|
|
19
19
|
* but exposes nothing a consumer can reach.
|
|
20
20
|
*
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsdocDocs } from './jsdocDocs.mjs'
|
|
2
|
+
import { resolveDocsMethod } from './partials/resolveDocsMethod.mjs'
|
|
3
|
+
import { typeDocs } from './typeDocs.mjs'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Generate the HTML documentation with whichever engine docs.method (or its typescript.enabled-based default)
|
|
7
|
+
* resolves to - see {@link module:partials.resolveDocsMethod}. The standalone counterpart to build's own
|
|
8
|
+
* internal branching, for running `gulp docs` directly instead of as part of a full build.
|
|
9
|
+
* @memberOf module:js-build-tools
|
|
10
|
+
* @param {Function} [done]
|
|
11
|
+
* @returns {*}
|
|
12
|
+
*/
|
|
13
|
+
export const docs = (done = null) => (resolveDocsMethod() === 'jsdoc' ? jsdocDocs : typeDocs)(done)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as setUp from './test-helpers/setUp.mjs'
|
|
2
|
+
import { docs } from './docs.mjs'
|
|
3
|
+
import { typeDocs } from './typeDocs.mjs'
|
|
4
|
+
import { jsdocDocs } from './jsdocDocs.mjs'
|
|
5
|
+
|
|
6
|
+
const genericFunction = () => Promise.resolve(true)
|
|
7
|
+
|
|
8
|
+
jest.mock('./typeDocs.mjs', () => ({ typeDocs: jest.fn(genericFunction) }))
|
|
9
|
+
jest.mock('./jsdocDocs.mjs', () => ({ jsdocDocs: jest.fn(genericFunction) }))
|
|
10
|
+
|
|
11
|
+
setUp.setDefaults('test-docs')
|
|
12
|
+
const gulpConfig = setUp.gulpConfig
|
|
13
|
+
|
|
14
|
+
beforeEach(() => setUp.beforeEach().then(() => {
|
|
15
|
+
typeDocs.mockClear()
|
|
16
|
+
jsdocDocs.mockClear()
|
|
17
|
+
}))
|
|
18
|
+
|
|
19
|
+
afterEach(setUp.afterEach)
|
|
20
|
+
|
|
21
|
+
describe('docs', () => {
|
|
22
|
+
test('runs jsdocDocs when resolveDocsMethod infers jsdoc', async () => {
|
|
23
|
+
gulpConfig.set('typescript.enabled', false)
|
|
24
|
+
gulpConfig.set('docs.method', false)
|
|
25
|
+
await docs()
|
|
26
|
+
expect(jsdocDocs).toHaveBeenCalledTimes(1)
|
|
27
|
+
expect(typeDocs).not.toHaveBeenCalled()
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
test('runs typeDocs when resolveDocsMethod infers typedoc', async () => {
|
|
31
|
+
gulpConfig.set('typescript.enabled', true)
|
|
32
|
+
gulpConfig.set('docs.method', false)
|
|
33
|
+
await docs()
|
|
34
|
+
expect(typeDocs).toHaveBeenCalledTimes(1)
|
|
35
|
+
expect(jsdocDocs).not.toHaveBeenCalled()
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test('docs.method overrides the typescript.enabled inference either way', async () => {
|
|
39
|
+
gulpConfig.set('typescript.enabled', true)
|
|
40
|
+
gulpConfig.set('docs.method', 'jsdoc')
|
|
41
|
+
await docs()
|
|
42
|
+
expect(jsdocDocs).toHaveBeenCalledTimes(1)
|
|
43
|
+
expect(typeDocs).not.toHaveBeenCalled()
|
|
44
|
+
})
|
|
45
|
+
})
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import jsdocBase from '../jsdoc.base.js'
|
|
3
|
+
import { handlers } from '../jsdoc.esmExports.js'
|
|
4
|
+
|
|
5
|
+
describe('jsdoc.esmExports', () => {
|
|
6
|
+
test('is one of the plugins in jsdoc.base', () => {
|
|
7
|
+
expect(jsdocBase.plugins).toContain(path.resolve('jsdoc.esmExports.js'))
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
test('drops the exports. jsdoc gives a documented export of a file without its own @module tag', () => {
|
|
11
|
+
const doclet = { name: 'exports.build', longname: 'module:js-build-tools.exports.build' }
|
|
12
|
+
handlers.newDoclet({ doclet })
|
|
13
|
+
expect(doclet).toEqual({ name: 'build', longname: 'module:js-build-tools.build' })
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('leaves every other name as it is', () => {
|
|
17
|
+
const doclet = { name: 'build', longname: 'module:js-build-tools.build' }
|
|
18
|
+
handlers.newDoclet({ doclet })
|
|
19
|
+
expect(doclet).toEqual({ name: 'build', longname: 'module:js-build-tools.build' })
|
|
20
|
+
const exportsless = { name: 'exportsThing', longname: 'exportsThing' }
|
|
21
|
+
handlers.newDoclet({ doclet: exportsless })
|
|
22
|
+
expect(exportsless).toEqual({ name: 'exportsThing', longname: 'exportsThing' })
|
|
23
|
+
})
|
|
24
|
+
})
|
|
@@ -6,14 +6,16 @@ import { execFile } from 'node:child_process'
|
|
|
6
6
|
import { promisify } from 'node:util'
|
|
7
7
|
import * as gulpConfig from '../../gulp.config.mjs'
|
|
8
8
|
import { removeDirectory } from './removeDirectory.mjs'
|
|
9
|
-
// jsdoc.base.js is CommonJS (it's also required directly by consuming projects' own .jsdoc.conf.js
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
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
13
|
import jsdocBase from '../../jsdoc.base.js'
|
|
14
14
|
|
|
15
15
|
const execFileAsync = promisify(execFile)
|
|
16
16
|
|
|
17
|
+
const escapeHtml = text => String(text).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"')
|
|
18
|
+
|
|
17
19
|
const jsdocInstallHint = 'Install it in your project with: npm install --save-dev jsdoc'
|
|
18
20
|
const themeInstallHint = name => `Install it in your project with: npm install --save-dev ${name}`
|
|
19
21
|
|
|
@@ -60,11 +62,9 @@ export const resolveJsdocBin = (projectPath = process.cwd()) =>
|
|
|
60
62
|
path.join(resolvePeerDir('jsdoc', { task: 'docs', installHint: jsdocInstallHint, projectPath }), 'jsdoc.js')
|
|
61
63
|
|
|
62
64
|
/**
|
|
63
|
-
* Resolve a jsdoc theme package's own template directory, for jsdoc's own opts.template config key
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* classic jsdoc template layout (a bare package root with its own tmpl/static folders) - clean-jsdoc-theme does
|
|
67
|
-
* not (it is a modern, self-contained, server-rendered theme with no such folders at its package root at all).
|
|
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
68
|
* @memberOf module:partials
|
|
69
69
|
* @param {string} name
|
|
70
70
|
* @param {string} [projectPath=process.cwd()]
|
|
@@ -72,7 +72,8 @@ export const resolveJsdocBin = (projectPath = process.cwd()) =>
|
|
|
72
72
|
*/
|
|
73
73
|
export const resolveJsdocTheme = (name, projectPath = process.cwd()) => {
|
|
74
74
|
const packageDir = resolvePeerDir(name, { task: 'docs', installHint: themeInstallHint(name), projectPath })
|
|
75
|
-
|
|
75
|
+
const distDir = path.join(packageDir, 'dist')
|
|
76
|
+
return fs.existsSync(path.join(distDir, 'publish.js')) ? distDir : packageDir
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
/**
|
|
@@ -82,7 +83,8 @@ export const resolveJsdocTheme = (name, projectPath = process.cwd()) => {
|
|
|
82
83
|
* options generated here instead of hand-maintained per project. Configure this with 'docs.from', 'docs.to',
|
|
83
84
|
* 'docs.index', 'docs.theme' and 'docs.title'.
|
|
84
85
|
* @memberOf module:partials
|
|
85
|
-
* @param {string} [srcPath=gulpConfig.get('docs.from')] - The directory (or
|
|
86
|
+
* @param {string|Array<string>} [srcPath=gulpConfig.get('docs.from')] - The directory (or directories and files) holding
|
|
87
|
+
* the JS source.
|
|
86
88
|
* @param {string} [outPath=gulpConfig.get('docs.to')] - The directory the documentation is generated into (cleared first).
|
|
87
89
|
* @param {function(string, Array<string>): Promise<Object>} [runJsdoc] - Runs the jsdoc CLI, tests can inject a stand-in.
|
|
88
90
|
* @returns {Function} A gulp task, it accepts an optional callback and returns a promise.
|
|
@@ -100,12 +102,13 @@ export const jsdocDocsFor = (
|
|
|
100
102
|
const theme = gulpConfig.get('docs.theme') || 'clean-jsdoc-theme'
|
|
101
103
|
const themeDir = resolveJsdocTheme(theme)
|
|
102
104
|
const indexFile = gulpConfig.get('docs.index')
|
|
105
|
+
const title = gulpConfig.get('docs.title')
|
|
103
106
|
await removeDirectory(outPath)
|
|
104
107
|
const config = {
|
|
105
108
|
...jsdocBase,
|
|
106
109
|
source: {
|
|
107
110
|
...jsdocBase.source,
|
|
108
|
-
include: [path.resolve(
|
|
111
|
+
include: [].concat(srcPath).map(includePath => path.resolve(includePath))
|
|
109
112
|
},
|
|
110
113
|
opts: {
|
|
111
114
|
destination: path.resolve(outPath),
|
|
@@ -114,6 +117,9 @@ export const jsdocDocsFor = (
|
|
|
114
117
|
// quick-start example, which sets this explicitly, not assumed from jsdoc's own classic defaults.
|
|
115
118
|
recurse: true,
|
|
116
119
|
template: themeDir,
|
|
120
|
+
// clean-jsdoc-theme's own option for the name in its header. Given as a link: a plain-text title links to the
|
|
121
|
+
// site root ("/"), while every page is in one folder, so index.html is the home page wherever they are served
|
|
122
|
+
...(title ? { theme_opts: { title: `<a href="index.html" class="sidebar-title sidebar-title-anchor">${escapeHtml(title)}</a>` } } : {}),
|
|
117
123
|
...(indexFile && fs.existsSync(indexFile) ? { readme: path.resolve(indexFile) } : {})
|
|
118
124
|
}
|
|
119
125
|
}
|
|
@@ -122,7 +128,13 @@ export const jsdocDocsFor = (
|
|
|
122
128
|
const configPath = path.join(workDir, 'jsdoc.conf.json')
|
|
123
129
|
fs.writeFileSync(configPath, JSON.stringify(config))
|
|
124
130
|
const bin = resolveJsdocBin()
|
|
125
|
-
|
|
131
|
+
// Pass on what jsdoc and the theme report (warnings such as a page which failed to render), which would
|
|
132
|
+
// otherwise be lost with the captured output
|
|
133
|
+
const { stdout = '', stderr = '' } = (await runJsdoc(bin, ['-c', configPath])) || {}
|
|
134
|
+
const report = `${stdout}${stderr}`.trim()
|
|
135
|
+
if (report) {
|
|
136
|
+
console.warn(report)
|
|
137
|
+
}
|
|
126
138
|
} finally {
|
|
127
139
|
await removeDirectory(workDir)
|
|
128
140
|
}
|
|
@@ -2,6 +2,7 @@ import fs from 'fs'
|
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
import * as setUp from '../test-helpers/setUp.mjs'
|
|
4
4
|
import { jsdocDocsFor, resolveJsdocBin, resolveJsdocTheme } from './jsdocDocsFor.mjs'
|
|
5
|
+
import jsdocBase from '../../jsdoc.base.js'
|
|
5
6
|
|
|
6
7
|
setUp.setDefaults('test-jsdoc-docs-for')
|
|
7
8
|
const gulpConfig = setUp.gulpConfig
|
|
@@ -57,6 +58,53 @@ describe('jsdocDocsFor', () => {
|
|
|
57
58
|
expect(fs.existsSync(`${outPath}/index.html`)).toBe(true)
|
|
58
59
|
expect(calls.config.opts.destination).toBe(path.resolve(outPath))
|
|
59
60
|
expect(calls.config.source.include).toEqual([path.resolve(gulpConfig.get('srcPath'))])
|
|
61
|
+
// Headings of the front page get ids, so the theme's table of contents can follow them
|
|
62
|
+
expect(calls.config.markdown).toEqual({ idInHeadings: true })
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('passes on what jsdoc reports', async () => {
|
|
66
|
+
gulpConfig.set('docs.enabled', true)
|
|
67
|
+
const srcPath = gulpConfig.get('srcPath')
|
|
68
|
+
const warn = jest.spyOn(console, 'warn').mockImplementation(() => {})
|
|
69
|
+
const calls = {}
|
|
70
|
+
const reporting = (bin, args) => fakeRunJsdoc(calls)(bin, args).then(() => ({ stdout: '', stderr: 'WARNING: a page failed\n' }))
|
|
71
|
+
await jsdocDocsFor(srcPath, `${srcPath}/../docs`, reporting)()
|
|
72
|
+
expect(warn).toHaveBeenCalledWith('WARNING: a page failed')
|
|
73
|
+
warn.mockClear()
|
|
74
|
+
await jsdocDocsFor(srcPath, `${srcPath}/../docs`, fakeRunJsdoc(calls))()
|
|
75
|
+
expect(warn).not.toHaveBeenCalled()
|
|
76
|
+
warn.mockRestore()
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
test('takes a list of directories and files to document', async () => {
|
|
80
|
+
gulpConfig.set('docs.enabled', true)
|
|
81
|
+
const srcPath = gulpConfig.get('srcPath')
|
|
82
|
+
const calls = {}
|
|
83
|
+
await jsdocDocsFor([srcPath, `${srcPath}/../gulp.config.mjs`], `${srcPath}/../docs`, fakeRunJsdoc(calls))()
|
|
84
|
+
expect(calls.config.source.include).toEqual([path.resolve(srcPath), path.resolve(`${srcPath}/../gulp.config.mjs`)])
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
test('documents .js, .mjs and .cjs files, but not tests or minified copies', () => {
|
|
88
|
+
const include = new RegExp(jsdocBase.source.includePattern)
|
|
89
|
+
const exclude = new RegExp(jsdocBase.source.excludePattern)
|
|
90
|
+
const documented = file => include.test(file) && !exclude.test(file)
|
|
91
|
+
expect(['a.js', 'a.mjs', 'a.cjs', 'dir/a.mjs'].filter(documented)).toEqual(['a.js', 'a.mjs', 'a.cjs', 'dir/a.mjs'])
|
|
92
|
+
expect(['a.test.mjs', 'a.min.js', 'a.min.mjs', 'dir/_private.mjs', 'a.ts'].filter(documented)).toEqual([])
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
test('passes docs.title to the theme as a link to the home page of the docs, and leaves it out when unset', async () => {
|
|
96
|
+
gulpConfig.set('docs.enabled', true)
|
|
97
|
+
const srcPath = gulpConfig.get('srcPath')
|
|
98
|
+
const calls = {}
|
|
99
|
+
gulpConfig.set('docs.title', 'Tom & Jerry <Tools>')
|
|
100
|
+
await jsdocDocsFor(srcPath, `${srcPath}/../docs`, fakeRunJsdoc(calls))()
|
|
101
|
+
expect(calls.config.opts.theme_opts).toEqual({
|
|
102
|
+
title: '<a href="index.html" class="sidebar-title sidebar-title-anchor">Tom & Jerry <Tools></a>'
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
gulpConfig.set('docs.title', '')
|
|
106
|
+
await jsdocDocsFor(srcPath, `${srcPath}/../docs`, fakeRunJsdoc(calls))()
|
|
107
|
+
expect(calls.config.opts.theme_opts).toBeUndefined()
|
|
60
108
|
})
|
|
61
109
|
|
|
62
110
|
test('uses the configured theme as the template directory', async () => {
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { requirePeer } from './loadPeer.mjs'
|
|
2
|
+
|
|
3
|
+
const installHint = 'Install it in your project with: npm install --save-dev playwright'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Find Playwright (headless-browser automation) of the project being built, an optional peer dependency only
|
|
7
|
+
* needed by whatever actually drives a real browser - projects which never do never need it installed.
|
|
8
|
+
* @memberOf module:partials
|
|
9
|
+
* @param {string} [projectPath=process.cwd()] The folder of the project (which has the package.json) being built.
|
|
10
|
+
* @returns {Object} The Playwright module.
|
|
11
|
+
* @throws {Error} With install instructions when playwright is not installed.
|
|
12
|
+
*/
|
|
13
|
+
export const loadPlaywright = (projectPath = process.cwd()) => requirePeer('playwright', { task: 'browser automation', installHint, projectPath })
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Launch a real headless Chromium browser via Playwright. See {@link loadPlaywright}.
|
|
17
|
+
* @memberOf module:partials
|
|
18
|
+
* @param {Function} [load=loadPlaywright] Which Playwright to launch - swappable in tests.
|
|
19
|
+
* @param {string} [projectPath=process.cwd()] The folder of the project (which has the package.json) being built.
|
|
20
|
+
* @returns {Promise<Browser>} The running Playwright browser - close it yourself (browser.close()) once done with it.
|
|
21
|
+
* @throws {Error} With install instructions when playwright is not installed.
|
|
22
|
+
*/
|
|
23
|
+
export const launchBrowser = (load = loadPlaywright, projectPath = process.cwd()) => load(projectPath).chromium.launch()
|