js-build-tools 6.3.1 → 6.4.1
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 +10 -3
- package/dist/lint.js +17 -0
- package/dist/lint.min.js +1 -0
- package/dist/partials/imagesFor.js +42 -43
- package/dist/partials/jsdocDocsFor.js +128 -128
- package/dist/partials/lintSource.js +52 -0
- package/dist/partials/loadPeer.js +71 -70
- package/dist/partials/minifyFor.js +16 -16
- package/dist/partials/neostandardLint.js +134 -123
- package/dist/partials.js +176 -169
- package/dist/partials.min.js +1 -1
- package/dist/sourceLint.js +11 -27
- package/dist/sourceLint.min.js +1 -1
- package/dist/test-helpers/isolateGulpCache.js +25 -0
- package/dist/utilities/dotGet.js +46 -46
- package/dist/utilities/dotNotate.js +48 -48
- package/dist/utilities/dotSet.js +37 -37
- package/functions/build.test.mjs +17 -7
- package/functions/bundle.test.mjs +0 -1
- package/functions/images.test.mjs +4 -1
- package/functions/lint.mjs +9 -0
- package/functions/partials/addToReadme.test.mjs +2 -1
- package/functions/partials/imagesFor.mjs +0 -1
- package/functions/partials/imagesFor.test.mjs +5 -2
- package/functions/partials/lintSource.mjs +41 -0
- package/functions/partials/loadPeer.mjs +1 -0
- package/functions/partials/loadPlaywright.test.mjs +1 -2
- package/functions/partials/minifyFor.mjs +1 -1
- package/functions/partials/neostandardLint.mjs +14 -4
- package/functions/partials/neostandardLint.test.mjs +14 -0
- package/functions/partials/runOnChange.test.mjs +5 -4
- package/functions/partials/tsFor.test.mjs +1 -0
- package/functions/partials.mjs +1 -0
- package/functions/partials.test.mjs +1 -1
- package/functions/sourceLint.mjs +4 -15
- package/functions/sourceLint.test.mjs +69 -0
- package/functions/test-helpers/isolateGulpCache.mjs +16 -0
- package/functions/test-helpers/setUp.mjs +7 -7
- package/functions/testFull.test.mjs +1 -1
- package/functions/testQuick.test.mjs +1 -1
- package/functions/utilities/convertMjsFilesForDocs.test.mjs +1 -0
- package/functions/utilities/dotGet.mjs +2 -2
- package/functions/utilities/dotNotate.mjs +2 -2
- package/functions/utilities/dotNotate.test.mjs +7 -0
- package/functions/utilities/dotSet.mjs +1 -1
- package/gulpfile.base.mjs +1 -0
- package/package.json +12 -2
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.dotNotate = void 0;
|
|
7
|
-
require("core-js/modules/esnext.iterator.constructor.js");
|
|
8
|
-
require("core-js/modules/esnext.iterator.map.js");
|
|
9
|
-
var _isObject = require("./isObject.js");
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.dotNotate = void 0;
|
|
7
|
+
require("core-js/modules/esnext.iterator.constructor.js");
|
|
8
|
+
require("core-js/modules/esnext.iterator.map.js");
|
|
9
|
+
var _isObject = require("./isObject.js");
|
|
10
10
|
/**
|
|
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
14
|
* @private
|
|
15
|
-
*/
|
|
16
|
-
const handleRetainObjects = (retainObjects = []) => {
|
|
17
|
-
if (!retainObjects.length) {
|
|
15
|
+
*/
|
|
16
|
+
const handleRetainObjects = (retainObjects = []) => {
|
|
17
|
+
if (!retainObjects.length) {
|
|
18
18
|
/**
|
|
19
19
|
* Bypass the test function if there are no retainObjects.
|
|
20
20
|
* @returns {false}
|
|
21
21
|
* @private
|
|
22
|
-
*/
|
|
23
|
-
return (currentKey, value, results) => false;
|
|
24
|
-
}
|
|
25
|
-
retainObjects = retainObjects.map(key => key.
|
|
26
|
-
const retainRegex = new RegExp(`(${retainObjects.join('|')})$`);
|
|
22
|
+
*/
|
|
23
|
+
return (currentKey, value, results) => false;
|
|
24
|
+
}
|
|
25
|
+
retainObjects = retainObjects.map(key => key.replaceAll('.', '\\.'));
|
|
26
|
+
const retainRegex = new RegExp(`(${retainObjects.join('|')})$`);
|
|
27
27
|
/**
|
|
28
28
|
* Test if a key should be retained as an object.
|
|
29
29
|
* @param {string} currentKey - The key to test
|
|
@@ -31,16 +31,16 @@ const handleRetainObjects = (retainObjects = []) => {
|
|
|
31
31
|
* @param {Object} results - The result object to add to
|
|
32
32
|
* @returns {boolean}
|
|
33
33
|
* @private
|
|
34
|
-
*/
|
|
35
|
-
return (currentKey, value, results) => {
|
|
36
|
-
if (!currentKey.match(retainRegex)) {
|
|
37
|
-
return false;
|
|
38
|
-
}
|
|
39
|
-
results[currentKey] = value;
|
|
40
|
-
return true;
|
|
41
|
-
};
|
|
42
|
-
};
|
|
43
|
-
|
|
34
|
+
*/
|
|
35
|
+
return (currentKey, value, results) => {
|
|
36
|
+
if (!currentKey.match(retainRegex)) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
results[currentKey] = value;
|
|
40
|
+
return true;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
|
|
44
44
|
/**
|
|
45
45
|
* The underlying logic function for converting arrays to dot-notation.
|
|
46
46
|
* @param {Object} arrayObject - The array or object to dot-notate
|
|
@@ -49,25 +49,25 @@ const handleRetainObjects = (retainObjects = []) => {
|
|
|
49
49
|
* @param {Object<string, *>} [results={}] - The final notated object to return
|
|
50
50
|
* @returns {Object<string, *>} The dot-notated object
|
|
51
51
|
* @private
|
|
52
|
-
*/
|
|
53
|
-
const performDotNotate = (arrayObject, didRetain, prepend = '', results = {}) => {
|
|
54
|
-
for (
|
|
55
|
-
const value = arrayObject[key];
|
|
56
|
-
const currentKey = `${prepend}${key}`;
|
|
57
|
-
if (didRetain(currentKey, value, results)) {
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
// An empty object/array has no keys to flatten into - recursing into one would silently drop currentKey
|
|
61
|
-
// from the result entirely, rather than keeping it as the empty value it actually is. Treat it as a leaf.
|
|
62
|
-
if ((0, _isObject.isObject)(value) && Object.keys(value).length) {
|
|
63
|
-
performDotNotate(value, didRetain, `${currentKey}.`, results);
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
results[currentKey] = value;
|
|
67
|
-
}
|
|
68
|
-
return results;
|
|
69
|
-
};
|
|
70
|
-
|
|
52
|
+
*/
|
|
53
|
+
const performDotNotate = (arrayObject, didRetain, prepend = '', results = {}) => {
|
|
54
|
+
for (const key in arrayObject) {
|
|
55
|
+
const value = arrayObject[key];
|
|
56
|
+
const currentKey = `${prepend}${key}`;
|
|
57
|
+
if (didRetain(currentKey, value, results)) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
// An empty object/array has no keys to flatten into - recursing into one would silently drop currentKey
|
|
61
|
+
// from the result entirely, rather than keeping it as the empty value it actually is. Treat it as a leaf.
|
|
62
|
+
if ((0, _isObject.isObject)(value) && Object.keys(value).length) {
|
|
63
|
+
performDotNotate(value, didRetain, `${currentKey}.`, results);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
results[currentKey] = value;
|
|
67
|
+
}
|
|
68
|
+
return results;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
71
|
/**
|
|
72
72
|
* Convert an array or object to a single dimensional associative array with dot notation.
|
|
73
73
|
* Original source concepts from {@link https://github.com/jheagle/si-funciona/blob/main/src/helpers/objects/dotNotate.ts Sí, funciona}
|
|
@@ -75,6 +75,6 @@ const performDotNotate = (arrayObject, didRetain, prepend = '', results = {}) =>
|
|
|
75
75
|
* @param {Array.<string>} [retainObjects=[]] - An array of keys to retain as objects
|
|
76
76
|
* @returns {Object<string, *>} The dot-notated object
|
|
77
77
|
* @private
|
|
78
|
-
*/
|
|
79
|
-
const dotNotate = (arrayObject, retainObjects = []) => performDotNotate(arrayObject, handleRetainObjects(retainObjects));
|
|
78
|
+
*/
|
|
79
|
+
const dotNotate = (arrayObject, retainObjects = []) => performDotNotate(arrayObject, handleRetainObjects(retainObjects));
|
|
80
80
|
exports.dotNotate = dotNotate;
|
package/dist/utilities/dotSet.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.dotSet = void 0;
|
|
7
|
-
var _isObject = require("./isObject.js");
|
|
8
|
-
var _strAfter = require("./strAfter.js");
|
|
9
|
-
var _strBefore = require("./strBefore.js");
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.dotSet = void 0;
|
|
7
|
+
var _isObject = require("./isObject.js");
|
|
8
|
+
var _strAfter = require("./strAfter.js");
|
|
9
|
+
var _strBefore = require("./strBefore.js");
|
|
10
10
|
/**
|
|
11
11
|
* Set a nested property value an object.
|
|
12
12
|
* Original source concepts from {@link https://github.com/jheagle/si-funciona/blob/main/src/helpers/objects/dotSet.ts Sí, funciona}
|
|
@@ -15,32 +15,32 @@ var _strBefore = require("./strBefore.js");
|
|
|
15
15
|
* @param {*} value - The default value to return if the property is not found
|
|
16
16
|
* @returns {Object} The modified object
|
|
17
17
|
* @private
|
|
18
|
-
*/
|
|
19
|
-
const dotSet = (arrayObject, dotNotation, value = null) => {
|
|
20
|
-
let key = (0, _strBefore.strBefore)(dotNotation, '.');
|
|
21
|
-
const lastKey = !key;
|
|
22
|
-
if (lastKey) {
|
|
23
|
-
key = dotNotation;
|
|
24
|
-
}
|
|
25
|
-
if (key === '*') {
|
|
26
|
-
for (
|
|
27
|
-
if (lastKey) {
|
|
28
|
-
arrayObject[wildKey] = value;
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
if (!(0, _isObject.isObject)(arrayObject[wildKey])) {
|
|
32
|
-
continue;
|
|
33
|
-
}
|
|
34
|
-
dotSet(arrayObject[wildKey], (0, _strAfter.strAfter)(dotNotation, '.'), value);
|
|
35
|
-
}
|
|
36
|
-
return arrayObject;
|
|
37
|
-
}
|
|
38
|
-
if (lastKey) {
|
|
39
|
-
arrayObject[dotNotation] = value;
|
|
40
|
-
return arrayObject;
|
|
41
|
-
}
|
|
42
|
-
const next = arrayObject[key] ?? [];
|
|
43
|
-
arrayObject[key] = dotSet(next, (0, _strAfter.strAfter)(dotNotation, '.'), value);
|
|
44
|
-
return arrayObject;
|
|
45
|
-
};
|
|
18
|
+
*/
|
|
19
|
+
const dotSet = (arrayObject, dotNotation, value = null) => {
|
|
20
|
+
let key = (0, _strBefore.strBefore)(dotNotation, '.');
|
|
21
|
+
const lastKey = !key;
|
|
22
|
+
if (lastKey) {
|
|
23
|
+
key = dotNotation;
|
|
24
|
+
}
|
|
25
|
+
if (key === '*') {
|
|
26
|
+
for (const wildKey in arrayObject) {
|
|
27
|
+
if (lastKey) {
|
|
28
|
+
arrayObject[wildKey] = value;
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (!(0, _isObject.isObject)(arrayObject[wildKey])) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
dotSet(arrayObject[wildKey], (0, _strAfter.strAfter)(dotNotation, '.'), value);
|
|
35
|
+
}
|
|
36
|
+
return arrayObject;
|
|
37
|
+
}
|
|
38
|
+
if (lastKey) {
|
|
39
|
+
arrayObject[dotNotation] = value;
|
|
40
|
+
return arrayObject;
|
|
41
|
+
}
|
|
42
|
+
const next = arrayObject[key] ?? [];
|
|
43
|
+
arrayObject[key] = dotSet(next, (0, _strAfter.strAfter)(dotNotation, '.'), value);
|
|
44
|
+
return arrayObject;
|
|
45
|
+
};
|
|
46
46
|
exports.dotSet = dotSet;
|
package/functions/build.test.mjs
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
|
+
/* eslint-disable no-template-curly-in-string -- fixture source code, the ${...} is meant to stay literal */
|
|
1
2
|
import fs from 'fs'
|
|
2
3
|
import * as setUp from './test-helpers/setUp.mjs'
|
|
3
4
|
import { build } from './build.mjs'
|
|
4
5
|
import { clean } from './partials/clean.mjs'
|
|
6
|
+
import { sourceLint } from './sourceLint.mjs'
|
|
5
7
|
import { testFull } from './testFull.mjs'
|
|
6
8
|
import { typeDocs } from './typeDocs.mjs'
|
|
7
9
|
import { jsdocDocs } from './jsdocDocs.mjs'
|
|
8
10
|
import { countMatches } from 'test-filesystem'
|
|
9
|
-
|
|
10
|
-
// Run the real neostandard (in a subprocess) - Jest's CommonJS transform can't load the ESM-only package itself.
|
|
11
|
-
jest.mock('./partials/neostandardLint.mjs', () => require('./test-helpers/neostandardLintWithRealNeostandard.mjs'))
|
|
11
|
+
import { isolateGulpCache } from './test-helpers/isolateGulpCache.mjs'
|
|
12
12
|
|
|
13
13
|
setUp.setDefaults('test-build')
|
|
14
|
+
const clearImageCache = isolateGulpCache('build')
|
|
14
15
|
const gulpConfig = setUp.gulpConfig
|
|
15
16
|
|
|
16
17
|
const genericFunction = () => Promise.resolve(true)
|
|
17
18
|
|
|
18
19
|
jest.mock('./partials/clean.mjs', () => ({ clean: jest.fn(genericFunction) }))
|
|
19
20
|
jest.mock('./testFull.mjs', () => ({ testFull: jest.fn(genericFunction) }))
|
|
21
|
+
// Real linting is covered by sourceLint.test.mjs. Here it would run a fresh neostandard subprocess for every source
|
|
22
|
+
// file in every test, which pushed these tests past their timeout whenever the whole suite ran in parallel.
|
|
23
|
+
jest.mock('./sourceLint.mjs', () => ({ sourceLint: jest.fn(genericFunction) }))
|
|
20
24
|
// The documentation is generated by TypeDoc or jsdoc, whose own tests cover that (see typeDocsFor.test.mjs /
|
|
21
25
|
// jsdocDocsFor.test.mjs) - jsdocDocs in particular shells out to a real CLI, far too slow for a build.mjs unit
|
|
22
26
|
// test to actually run.
|
|
@@ -226,7 +230,7 @@ const imageContent = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'
|
|
|
226
230
|
' inkscape:connector-curvature="0" />\n' +
|
|
227
231
|
'</svg>\n'
|
|
228
232
|
|
|
229
|
-
const imageCompressed = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600"><image width="600" height="600" preserveAspectRatio="none" xlink:href="data:image/png;base64,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 TkSuQmCC"/><path d="M19.04 494.382C2.001 482.76-2.83 468.022 5.006 451.587c3.27-6.858 10.156-15.228 15.3-18.599 8.904-5.834 9.948-5.675 21.728 3.31 28.014 21.367 44.09 18.882 51.548-7.971 5.951-21.426 5.252-305.141-.77-313.044-2.617-3.433-11.316-6.65-19.688-7.28-14.39-1.082-15.047-1.7-16.164-15.19L55.797 78.75h326.107l2.574 11.718c2.93 13.34-1.711 18.133-17.648 18.225-19.29.11-21.83 7.13-21.83 60.325V217.5h135v-48.169c0-41.902-.892-48.976-6.858-54.375-3.772-3.413-10.384-6.206-14.693-6.206-15.006 0-19.699-4.116-19.699-17.276V78.75h161.703l-1.164 14.063c-1.132 13.677-1.605 14.094-17.28 15.224-13.45.97-16.737 2.798-19.876 11.053-5.802 15.26-2.837 249.42 3.25 256.747 2.617 3.15 11.477 6.801 19.688 8.114C599.596 386.274 600 386.745 600 401.37v15.03l-79.687-1.012-79.688-1.012-1.137-13.607c-1.135-13.594-1.12-13.61 16.875-16.305 9.907-1.484 19.252-4.642 20.767-7.018 1.515-2.376 2.781-30.054 2.813-61.508L480 258.75H344.814l1.03 60.938 1.031 60.937 19.688 3.34c20.492 3.476 22.165 5.78 17.323 23.848-2.253 8.408-2.53 8.437-80.573 8.437H225v-14.956c0-14.536.418-15.022 14.93-17.343 8.21-1.313 17.07-4.966 19.687-8.119 3.637-4.381 4.758-35.56 4.758-132.343 0-69.636-1.23-127.842-2.735-129.348-9.738-9.743-68.924-8.348-79.154 1.866-3.087 3.081-4.993 46.77-6.525 149.486-1.455 97.609-3.646 149.68-6.69 159.02-13.551 41.573-61.403 74.912-111 77.337-22.755 1.112-28.167.082-39.232-7.468z"/></svg>'
|
|
233
|
+
const imageCompressed = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600"><image width="600" height="600" preserveAspectRatio="none" xlink:href="data:image/png;base64,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 TkSuQmCC"/><path style="fill:#000" d="M19.04 494.382C2.001 482.76-2.83 468.022 5.006 451.587c3.27-6.858 10.156-15.228 15.3-18.599 8.904-5.834 9.948-5.675 21.728 3.31 28.014 21.367 44.09 18.882 51.548-7.971 5.951-21.426 5.252-305.141-.77-313.044-2.617-3.433-11.316-6.65-19.688-7.28-14.39-1.082-15.047-1.7-16.164-15.19L55.797 78.75h326.107l2.574 11.718c2.93 13.34-1.711 18.133-17.648 18.225-19.29.11-21.83 7.13-21.83 60.325V217.5h135v-48.169c0-41.902-.892-48.976-6.858-54.375-3.772-3.413-10.384-6.206-14.693-6.206-15.006 0-19.699-4.116-19.699-17.276V78.75h161.703l-1.164 14.063c-1.132 13.677-1.605 14.094-17.28 15.224-13.45.97-16.737 2.798-19.876 11.053-5.802 15.26-2.837 249.42 3.25 256.747 2.617 3.15 11.477 6.801 19.688 8.114C599.596 386.274 600 386.745 600 401.37v15.03l-79.687-1.012-79.688-1.012-1.137-13.607c-1.135-13.594-1.12-13.61 16.875-16.305 9.907-1.484 19.252-4.642 20.767-7.018 1.515-2.376 2.781-30.054 2.813-61.508L480 258.75H344.814l1.03 60.938 1.031 60.937 19.688 3.34c20.492 3.476 22.165 5.78 17.323 23.848-2.253 8.408-2.53 8.437-80.573 8.437H225v-14.956c0-14.536.418-15.022 14.93-17.343 8.21-1.313 17.07-4.966 19.687-8.119 3.637-4.381 4.758-35.56 4.758-132.343 0-69.636-1.23-127.842-2.735-129.348-9.738-9.743-68.924-8.348-79.154 1.866-3.087 3.081-4.993 46.77-6.525 149.486-1.455 97.609-3.646 149.68-6.69 159.02-13.551 41.573-61.403 74.912-111 77.337-22.755 1.112-28.167.082-39.232-7.468z"/></svg>'
|
|
230
234
|
|
|
231
235
|
const imagePath = gulpConfig.get('srcPath') + '/img'
|
|
232
236
|
|
|
@@ -251,8 +255,10 @@ const sassContents = 'html\n' +
|
|
|
251
255
|
|
|
252
256
|
const sassPath = gulpConfig.get('sass.path')
|
|
253
257
|
|
|
258
|
+
// The cache outlives a run, so clear it or a stale result from an older imagemin can pass
|
|
254
259
|
beforeEach(
|
|
255
|
-
() =>
|
|
260
|
+
() => clearImageCache()
|
|
261
|
+
.then(setUp.beforeEach)
|
|
256
262
|
.then(
|
|
257
263
|
async () => {
|
|
258
264
|
const srcPath = gulpConfig.get('srcPath')
|
|
@@ -695,7 +701,7 @@ describe('build', () => {
|
|
|
695
701
|
})
|
|
696
702
|
}, 30000)
|
|
697
703
|
|
|
698
|
-
test('finishes clean before starting the tasks that write into the output folders', done => {
|
|
704
|
+
test('finishes clean and sourceLint before starting the tasks that write into the output folders', done => {
|
|
699
705
|
const srcPath = gulpConfig.get('srcPath')
|
|
700
706
|
const sourcesPath = `${srcPath}/sources`
|
|
701
707
|
fs.writeFileSync(`${sourcesPath}/file1.js`, file1Contents)
|
|
@@ -707,6 +713,10 @@ describe('build', () => {
|
|
|
707
713
|
events.push('clean finished')
|
|
708
714
|
resolve(true)
|
|
709
715
|
}, 100)))
|
|
716
|
+
sourceLint.mockImplementationOnce(() => new Promise(resolve => setTimeout(() => {
|
|
717
|
+
events.push('sourceLint finished')
|
|
718
|
+
resolve(true)
|
|
719
|
+
}, 50)))
|
|
710
720
|
testFull.mockImplementationOnce(() => {
|
|
711
721
|
events.push('testFull started')
|
|
712
722
|
return Promise.resolve(true)
|
|
@@ -719,7 +729,7 @@ describe('build', () => {
|
|
|
719
729
|
gulpConfig.set('typescript.enabled', false)
|
|
720
730
|
gulpConfig.set('docs.enabled', false)
|
|
721
731
|
build(() => {
|
|
722
|
-
expect(events).toEqual(['clean finished', 'testFull started'])
|
|
732
|
+
expect(events).toEqual(['sourceLint finished', 'clean finished', 'testFull started'])
|
|
723
733
|
done()
|
|
724
734
|
})
|
|
725
735
|
}, 30000)
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import fs from 'fs'
|
|
2
2
|
import * as setUp from './test-helpers/setUp.mjs'
|
|
3
3
|
import { images } from './images.mjs'
|
|
4
|
+
import { isolateGulpCache } from './test-helpers/isolateGulpCache.mjs'
|
|
4
5
|
|
|
5
6
|
setUp.setDefaults('test-images')
|
|
7
|
+
const clearImageCache = isolateGulpCache('images')
|
|
6
8
|
const gulpConfig = setUp.gulpConfig
|
|
7
9
|
|
|
8
10
|
const imageContents = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' +
|
|
@@ -114,7 +116,8 @@ const imageContents = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'
|
|
|
114
116
|
' inkscape:connector-curvature="0" />\n' +
|
|
115
117
|
'</svg>\n'
|
|
116
118
|
|
|
117
|
-
|
|
119
|
+
// The cache outlives a run, so clear it or a stale result from an older imagemin can pass
|
|
120
|
+
beforeEach(() => clearImageCache().then(setUp.beforeEach))
|
|
118
121
|
|
|
119
122
|
afterEach(setUp.afterEach)
|
|
120
123
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { lintSource } from './partials/lintSource.mjs'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The standalone lint command (`gulp lint`, or `npm run lint`): the same linting and fixing as sourceLint, but it
|
|
5
|
+
* fails (exits non-zero) when any errors remain that neostandard could not fix automatically.
|
|
6
|
+
* @memberOf module:js-build-tools
|
|
7
|
+
* @returns {*}
|
|
8
|
+
*/
|
|
9
|
+
export const lint = () => lintSource({ failOnError: true })
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-template-curly-in-string -- fixture source code, the ${...} is meant to stay literal */
|
|
1
2
|
import fs from 'fs'
|
|
2
3
|
import * as setUp from '../test-helpers/setUp.mjs'
|
|
3
4
|
import { addToReadme } from './addToReadme.mjs'
|
|
@@ -30,4 +31,4 @@ describe('addToReadme', () => {
|
|
|
30
31
|
// At least the documentation will have the addToReadme documentation
|
|
31
32
|
await expect(readme.includes('sayHello')).toBeTruthy()
|
|
32
33
|
})
|
|
33
|
-
})
|
|
34
|
+
})
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import cache from 'gulp-cache'
|
|
2
2
|
import { requirePeer } from './loadPeer.mjs'
|
|
3
3
|
import { dest, src } from 'gulp'
|
|
4
|
-
import path from 'node:path'
|
|
5
4
|
import * as gulpConfig from '../../gulp.config.mjs'
|
|
6
5
|
|
|
7
6
|
const installHint = 'Add it to your project with: npm install --save-dev github:jheagle/gulp-imagemin#common-js-compatibility ' +
|
|
@@ -3,8 +3,10 @@ import * as setUp from '../test-helpers/setUp.mjs'
|
|
|
3
3
|
import os from 'os'
|
|
4
4
|
import zlib from 'zlib'
|
|
5
5
|
import { imagesFor, loadImagemin } from './imagesFor.mjs'
|
|
6
|
+
import { isolateGulpCache } from '../test-helpers/isolateGulpCache.mjs'
|
|
6
7
|
|
|
7
8
|
setUp.setDefaults('test-images-for')
|
|
9
|
+
const clearImageCache = isolateGulpCache('images-for')
|
|
8
10
|
const gulpConfig = setUp.gulpConfig
|
|
9
11
|
|
|
10
12
|
const imageContents = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' +
|
|
@@ -116,7 +118,7 @@ const imageContents = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'
|
|
|
116
118
|
' inkscape:connector-curvature="0" />\n' +
|
|
117
119
|
'</svg>\n'
|
|
118
120
|
|
|
119
|
-
const imageCompressed = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600"><image width="600" height="600" preserveAspectRatio="none" xlink:href="data:image/png;base64,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 TkSuQmCC"/><path d="M19.04 494.382C2.001 482.76-2.83 468.022 5.006 451.587c3.27-6.858 10.156-15.228 15.3-18.599 8.904-5.834 9.948-5.675 21.728 3.31 28.014 21.367 44.09 18.882 51.548-7.971 5.951-21.426 5.252-305.141-.77-313.044-2.617-3.433-11.316-6.65-19.688-7.28-14.39-1.082-15.047-1.7-16.164-15.19L55.797 78.75h326.107l2.574 11.718c2.93 13.34-1.711 18.133-17.648 18.225-19.29.11-21.83 7.13-21.83 60.325V217.5h135v-48.169c0-41.902-.892-48.976-6.858-54.375-3.772-3.413-10.384-6.206-14.693-6.206-15.006 0-19.699-4.116-19.699-17.276V78.75h161.703l-1.164 14.063c-1.132 13.677-1.605 14.094-17.28 15.224-13.45.97-16.737 2.798-19.876 11.053-5.802 15.26-2.837 249.42 3.25 256.747 2.617 3.15 11.477 6.801 19.688 8.114C599.596 386.274 600 386.745 600 401.37v15.03l-79.687-1.012-79.688-1.012-1.137-13.607c-1.135-13.594-1.12-13.61 16.875-16.305 9.907-1.484 19.252-4.642 20.767-7.018 1.515-2.376 2.781-30.054 2.813-61.508L480 258.75H344.814l1.03 60.938 1.031 60.937 19.688 3.34c20.492 3.476 22.165 5.78 17.323 23.848-2.253 8.408-2.53 8.437-80.573 8.437H225v-14.956c0-14.536.418-15.022 14.93-17.343 8.21-1.313 17.07-4.966 19.687-8.119 3.637-4.381 4.758-35.56 4.758-132.343 0-69.636-1.23-127.842-2.735-129.348-9.738-9.743-68.924-8.348-79.154 1.866-3.087 3.081-4.993 46.77-6.525 149.486-1.455 97.609-3.646 149.68-6.69 159.02-13.551 41.573-61.403 74.912-111 77.337-22.755 1.112-28.167.082-39.232-7.468z"/></svg>'
|
|
121
|
+
const imageCompressed = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600"><image width="600" height="600" preserveAspectRatio="none" xlink:href="data:image/png;base64,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 TkSuQmCC"/><path style="fill:#000" d="M19.04 494.382C2.001 482.76-2.83 468.022 5.006 451.587c3.27-6.858 10.156-15.228 15.3-18.599 8.904-5.834 9.948-5.675 21.728 3.31 28.014 21.367 44.09 18.882 51.548-7.971 5.951-21.426 5.252-305.141-.77-313.044-2.617-3.433-11.316-6.65-19.688-7.28-14.39-1.082-15.047-1.7-16.164-15.19L55.797 78.75h326.107l2.574 11.718c2.93 13.34-1.711 18.133-17.648 18.225-19.29.11-21.83 7.13-21.83 60.325V217.5h135v-48.169c0-41.902-.892-48.976-6.858-54.375-3.772-3.413-10.384-6.206-14.693-6.206-15.006 0-19.699-4.116-19.699-17.276V78.75h161.703l-1.164 14.063c-1.132 13.677-1.605 14.094-17.28 15.224-13.45.97-16.737 2.798-19.876 11.053-5.802 15.26-2.837 249.42 3.25 256.747 2.617 3.15 11.477 6.801 19.688 8.114C599.596 386.274 600 386.745 600 401.37v15.03l-79.687-1.012-79.688-1.012-1.137-13.607c-1.135-13.594-1.12-13.61 16.875-16.305 9.907-1.484 19.252-4.642 20.767-7.018 1.515-2.376 2.781-30.054 2.813-61.508L480 258.75H344.814l1.03 60.938 1.031 60.937 19.688 3.34c20.492 3.476 22.165 5.78 17.323 23.848-2.253 8.408-2.53 8.437-80.573 8.437H225v-14.956c0-14.536.418-15.022 14.93-17.343 8.21-1.313 17.07-4.966 19.687-8.119 3.637-4.381 4.758-35.56 4.758-132.343 0-69.636-1.23-127.842-2.735-129.348-9.738-9.743-68.924-8.348-79.154 1.866-3.087 3.081-4.993 46.77-6.525 149.486-1.455 97.609-3.646 149.68-6.69 159.02-13.551 41.573-61.403 74.912-111 77.337-22.755 1.112-28.167.082-39.232-7.468z"/></svg>'
|
|
120
122
|
|
|
121
123
|
// Build a small but real PNG so the test exercises binary data (a text-only SVG hid Gulp 5's utf8 corruption of images).
|
|
122
124
|
const crc32 = buffer => {
|
|
@@ -156,7 +158,8 @@ const makePng = (size = 32) => {
|
|
|
156
158
|
])
|
|
157
159
|
}
|
|
158
160
|
|
|
159
|
-
|
|
161
|
+
// The cache outlives a run, so clear it or a stale result from an older imagemin can pass
|
|
162
|
+
beforeEach(() => clearImageCache().then(setUp.beforeEach))
|
|
160
163
|
|
|
161
164
|
afterEach(setUp.afterEach)
|
|
162
165
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as gulpConfig from '../../gulp.config.mjs'
|
|
2
|
+
import { dest, src } from 'gulp'
|
|
3
|
+
import { neostandardLint } from './neostandardLint.mjs'
|
|
4
|
+
import { Transform } from 'node:stream'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Lint the project's source (srcPath: .js, .mjs and .cjs, plus .ts when typescript.enabled) with neostandard and
|
|
8
|
+
* write the automatic fixes back in place. Shared by the sourceLint (build) and lint (standalone) tasks.
|
|
9
|
+
* @memberOf module:partials
|
|
10
|
+
* @param {Object} [options={}]
|
|
11
|
+
* @param {boolean} [options.failOnError=false] - Fail once linting finishes if any errors could not be fixed.
|
|
12
|
+
* @returns {stream.Stream}
|
|
13
|
+
*/
|
|
14
|
+
export const lintSource = ({ failOnError = false } = {}) => {
|
|
15
|
+
const srcPath = gulpConfig.get('srcPath')
|
|
16
|
+
const ts = gulpConfig.get('typescript.enabled')
|
|
17
|
+
const patterns = [`${srcPath}/**/*.{js,mjs,cjs}`]
|
|
18
|
+
if (ts) {
|
|
19
|
+
patterns.push(`${srcPath}/**/*.ts`)
|
|
20
|
+
}
|
|
21
|
+
const linter = neostandardLint({ fix: true, ts, rules: gulpConfig.get('lint.rules') })
|
|
22
|
+
// Fail only once dest() has written every fixed file: gulp exits as soon as a task fails, so failing from the
|
|
23
|
+
// linter itself (before dest() finished) could leave a file that dest() had opened, but not yet written, empty.
|
|
24
|
+
// dest() passes each file on only after writing it, so this last step's flush runs after the final write. Files
|
|
25
|
+
// are consumed here rather than passed on, so nothing downstream has to read them.
|
|
26
|
+
const written = new Transform({
|
|
27
|
+
objectMode: true,
|
|
28
|
+
transform: (file, enc, callback) => callback(),
|
|
29
|
+
flush: callback => failOnError && linter.totals.errors
|
|
30
|
+
? callback(new Error(`neostandard found ${linter.totals.errors} lint error(s) that could not be fixed automatically.`))
|
|
31
|
+
: callback()
|
|
32
|
+
})
|
|
33
|
+
const saved = src(patterns)
|
|
34
|
+
.pipe(linter)
|
|
35
|
+
.pipe(dest(srcPath))
|
|
36
|
+
saved.pipe(written)
|
|
37
|
+
// pipe() does not forward errors, and gulp only watches the returned stream, so pass any failure along.
|
|
38
|
+
linter.on('error', error => written.destroy(error))
|
|
39
|
+
saved.on('error', error => written.destroy(error))
|
|
40
|
+
return written
|
|
41
|
+
}
|
|
@@ -6,6 +6,7 @@ import { pathToFileURL } from 'node:url'
|
|
|
6
6
|
// build (dist/*.js) whose babel transform would turn even a dynamic import() into a require() that cannot load an ES
|
|
7
7
|
// module. Hiding the import() inside a Function constructor keeps it a genuine dynamic import that works from either
|
|
8
8
|
// build, because babel cannot see (and so cannot rewrite) an import expression which only exists as a runtime string.
|
|
9
|
+
// eslint-disable-next-line no-new-func -- deliberate, see above
|
|
9
10
|
const dynamicImport = new Function('specifier', 'return import(specifier)')
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import fs from 'fs'
|
|
2
|
-
import path from 'node:path'
|
|
3
2
|
import * as setUp from '../test-helpers/setUp.mjs'
|
|
4
3
|
import { loadPlaywright, launchBrowser } from './loadPlaywright.mjs'
|
|
5
4
|
import { serveStatic } from './serveStatic.mjs'
|
|
@@ -61,7 +60,7 @@ describe('a real page, served and loaded end to end', () => {
|
|
|
61
60
|
const page = await browser.newPage()
|
|
62
61
|
await page.goto(`${url}/index.html`)
|
|
63
62
|
expect(await page.title()).toBe('loaded via a real module script')
|
|
64
|
-
const backgroundColor = await page.evaluate(() => getComputedStyle(document.body).backgroundColor)
|
|
63
|
+
const backgroundColor = await page.evaluate(() => globalThis.getComputedStyle(document.body).backgroundColor)
|
|
65
64
|
expect(backgroundColor).toBe('rgb(1, 2, 3)')
|
|
66
65
|
} finally {
|
|
67
66
|
await browser.close()
|
|
@@ -2,7 +2,7 @@ import { dest, src } from 'gulp'
|
|
|
2
2
|
import { default as gulpUglify } from 'gulp-uglify-es'
|
|
3
3
|
import rename from 'gulp-rename'
|
|
4
4
|
|
|
5
|
-
const uglify =
|
|
5
|
+
const uglify = Object.hasOwn(gulpUglify, 'default') ? gulpUglify.default : gulpUglify
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Minify files and rename the output with '.min' extension.
|
|
@@ -71,7 +71,8 @@ const printFileReport = (file, result) => {
|
|
|
71
71
|
/**
|
|
72
72
|
* Lint every file streaming through with neostandard and, unless `fix` is false, apply the automatic fixes to the
|
|
73
73
|
* file's contents so a following `dest()` writes the fixed version. Remaining problems are printed along with a
|
|
74
|
-
* summary once the stream ends; they
|
|
74
|
+
* summary once the stream ends; they only fail the stream when `failOnError` is set (the standalone `lint` task),
|
|
75
|
+
* never during `build`.
|
|
75
76
|
*
|
|
76
77
|
* One ESLint instance is built from the first file's own cwd and reused for the rest of the stream, since every
|
|
77
78
|
* file in a given lint pass shares the same project (and so the same config).
|
|
@@ -81,18 +82,20 @@ const printFileReport = (file, result) => {
|
|
|
81
82
|
* @param {boolean} [options.ts=false] - Lint `.ts` files too, with type-aware rules (see neostandard's `ts` option).
|
|
82
83
|
* @param {Object<string, *>} [options.rules={}] - ESLint rule overrides layered on top of neostandard's own rules
|
|
83
84
|
* (see gulp.config.mjs's `lint.rules`).
|
|
85
|
+
* @param {boolean} [options.failOnError=false] - Emit an error once the stream ends if any lint errors remain after
|
|
86
|
+
* fixing, so a command-line run exits non-zero.
|
|
84
87
|
* @param {function(Object): Promise<{lintText: Function}>} [loadEslint] - Resolves an ESLint-shaped linter. Real
|
|
85
88
|
* callers should never need to pass this - it exists so tests can supply a stand-in, since this project's
|
|
86
89
|
* CommonJS-transform-based Jest setup cannot execute a real dynamic import() of neostandard (ESM-only).
|
|
87
|
-
* @returns {stream.Transform}
|
|
90
|
+
* @returns {stream.Transform} With a `totals` property ({errors, warnings}), complete once the stream ends.
|
|
88
91
|
*/
|
|
89
92
|
export const neostandardLint = (
|
|
90
|
-
{ fix = true, ts = false, rules = {} } = {},
|
|
93
|
+
{ fix = true, ts = false, rules = {}, failOnError = false } = {},
|
|
91
94
|
loadEslint = buildEslint
|
|
92
95
|
) => {
|
|
93
96
|
const totals = { errors: 0, warnings: 0 }
|
|
94
97
|
let eslintPromise = null
|
|
95
|
-
|
|
98
|
+
const linter = through.obj(
|
|
96
99
|
function (file, enc, callback) {
|
|
97
100
|
if (file.isNull()) {
|
|
98
101
|
callback(null, file)
|
|
@@ -126,7 +129,14 @@ export const neostandardLint = (
|
|
|
126
129
|
console.log('======================================')
|
|
127
130
|
console.log(`✖ Errors total: ${totals.errors}`)
|
|
128
131
|
console.log(`⚠ Warnings total: ${totals.warnings}\n`)
|
|
132
|
+
if (failOnError && totals.errors) {
|
|
133
|
+
callback(new Error(`neostandard found ${totals.errors} lint error(s) that could not be fixed automatically.`))
|
|
134
|
+
return
|
|
135
|
+
}
|
|
129
136
|
callback()
|
|
130
137
|
}
|
|
131
138
|
)
|
|
139
|
+
// Read by lintSource, which can only fail once the fixed files have been written, after this stream has ended.
|
|
140
|
+
linter.totals = totals
|
|
141
|
+
return linter
|
|
132
142
|
}
|
|
@@ -110,6 +110,20 @@ describe('neostandardLint', () => {
|
|
|
110
110
|
expect(logSpy).toHaveBeenCalledWith('⚠ Warnings total: 1\n')
|
|
111
111
|
})
|
|
112
112
|
|
|
113
|
+
test('with failOnError, fails the stream once it ends if any errors remain', async () => {
|
|
114
|
+
expect.assertions(2)
|
|
115
|
+
const eslint = fakeEslint(() => [{ messages: [{ line: 1, column: 1, message: 'bad thing' }], errorCount: 1, warningCount: 0 }])
|
|
116
|
+
await expect(run(neostandardLint({ failOnError: true }, () => Promise.resolve(eslint)), [makeFile(Buffer.from('a'))]))
|
|
117
|
+
.rejects.toThrow('neostandard found 1 lint error(s)')
|
|
118
|
+
expect(logSpy).toHaveBeenCalledWith('✖ Errors total: 1')
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
test('with failOnError, still passes when there are only warnings', async () => {
|
|
122
|
+
expect.assertions(1)
|
|
123
|
+
const eslint = fakeEslint(() => [{ messages: [{ line: 1, column: 1, message: 'just a warning' }], errorCount: 0, warningCount: 1 }])
|
|
124
|
+
await expect(run(neostandardLint({ failOnError: true }, () => Promise.resolve(eslint)), [makeFile(Buffer.from('a'))])).resolves.toHaveLength(1)
|
|
125
|
+
})
|
|
126
|
+
|
|
113
127
|
test('surfaces a failure to load or run the linter as a stream error', async () => {
|
|
114
128
|
expect.assertions(1)
|
|
115
129
|
await expect(run(neostandardLint({}, () => Promise.reject(new Error('cannot load'))), [makeFile(Buffer.from('x'))])).rejects.toThrow('cannot load')
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-template-curly-in-string -- fixture source code, the ${...} is meant to stay literal */
|
|
1
2
|
import fs from 'fs'
|
|
2
3
|
import * as setUp from '../test-helpers/setUp.mjs'
|
|
3
4
|
import { bundle } from '../bundle.mjs'
|
|
@@ -26,10 +27,10 @@ const srcFile = `${srcPath}/runOnChange.js`
|
|
|
26
27
|
const srcTsFile = `${srcPath}/runOnChange.ts`
|
|
27
28
|
|
|
28
29
|
beforeEach(() => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
return setUp.beforeEach()
|
|
31
|
+
.then(() => fs.writeFileSync(srcTsFile, rawContents))
|
|
32
|
+
.then(() => fs.writeFileSync(srcFile, rawContents))
|
|
33
|
+
}
|
|
33
34
|
)
|
|
34
35
|
|
|
35
36
|
afterEach(() => {
|
package/functions/partials.mjs
CHANGED
|
@@ -18,6 +18,7 @@ export { imagesFor } from './partials/imagesFor.mjs'
|
|
|
18
18
|
export { importModule, importPeer, requirePeer } from './partials/loadPeer.mjs'
|
|
19
19
|
export { jsdocDocsFor } from './partials/jsdocDocsFor.mjs'
|
|
20
20
|
export { loadPlaywright, launchBrowser } from './partials/loadPlaywright.mjs'
|
|
21
|
+
export { lintSource } from './partials/lintSource.mjs'
|
|
21
22
|
export { minifyFor } from './partials/minifyFor.mjs'
|
|
22
23
|
export { neostandardLint } from './partials/neostandardLint.mjs'
|
|
23
24
|
export { readmeTemplate } from './partials/readmeTemplate.mjs'
|
package/functions/sourceLint.mjs
CHANGED
|
@@ -1,24 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { dest, src } from 'gulp'
|
|
3
|
-
import { neostandardLint } from './partials/neostandardLint.mjs'
|
|
1
|
+
import { lintSource } from './partials/lintSource.mjs'
|
|
4
2
|
|
|
5
3
|
/**
|
|
6
4
|
* Applies neostandard linting (js-build-tools' chosen style) to the real, hand-written source - not the compiled
|
|
7
5
|
* dist/browser output, which is generated and so was never going to pass a hand-authored-code style check (every
|
|
8
6
|
* compiler/bundler emits its own boilerplate - import aliasing, interop headers - that only looks like a style
|
|
9
7
|
* violation). Includes test files: there is no reason to hold tests to a lower style bar than the rest of the
|
|
10
|
-
* source. When typescript.enabled, the real TypeScript source is linted too, with type-aware rules.
|
|
8
|
+
* source. When typescript.enabled, the real TypeScript source is linted too, with type-aware rules. Runs as part of
|
|
9
|
+
* `build`, where remaining errors are reported but never fail it.
|
|
11
10
|
* @memberOf module:js-build-tools
|
|
12
11
|
* @returns {*}
|
|
13
12
|
*/
|
|
14
|
-
export const sourceLint = () =>
|
|
15
|
-
const srcPath = gulpConfig.get('srcPath')
|
|
16
|
-
const ts = gulpConfig.get('typescript.enabled')
|
|
17
|
-
const patterns = [`${srcPath}/**/*.js`]
|
|
18
|
-
if (ts) {
|
|
19
|
-
patterns.push(`${srcPath}/**/*.ts`)
|
|
20
|
-
}
|
|
21
|
-
return src(patterns)
|
|
22
|
-
.pipe(neostandardLint({ fix: true, ts, rules: gulpConfig.get('lint.rules') }))
|
|
23
|
-
.pipe(dest(srcPath))
|
|
24
|
-
}
|
|
13
|
+
export const sourceLint = () => lintSource()
|