js-build-tools 4.1.0 → 5.0.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 +274 -267
- package/dist/build.js +58 -56
- package/dist/build.min.js +1 -1
- package/dist/bundle.js +16 -16
- package/dist/bundleLint.js +16 -20
- package/dist/bundleLint.min.js +1 -1
- package/dist/bundleMinify.js +13 -13
- package/dist/compileReadme.js +10 -10
- package/dist/copyFonts.js +13 -13
- package/dist/default.js +15 -15
- package/dist/dist.js +10 -10
- package/dist/distLint.js +16 -20
- package/dist/distLint.min.js +1 -1
- package/dist/distMinify.js +13 -13
- package/dist/images.js +10 -10
- package/dist/partials/copyFor.js +12 -9
- package/dist/partials/imagesFor.js +56 -21
- package/dist/partials/removeDirectory.js +37 -13
- package/dist/partials/sassFor.js +8 -2
- package/dist/partials/standardLint.js +96 -0
- package/dist/partials/tsFor.js +67 -59
- package/dist/partials.js +110 -103
- package/dist/partials.min.js +1 -1
- package/dist/sass.js +10 -10
- package/dist/test-helpers/standardLintWithRealStandard.js +28 -0
- package/dist/testFull.js +20 -21
- package/dist/testFull.min.js +1 -1
- package/dist/testHelpers.js +10 -10
- package/dist/testQuick.js +22 -23
- package/dist/testQuick.min.js +1 -1
- package/dist/typeScript.js +9 -9
- package/dist/watchFull.js +10 -10
- package/dist/watchTest.js +16 -16
- package/functions/build.mjs +6 -3
- package/functions/build.test.mjs +31 -0
- package/functions/bundleLint.mjs +2 -6
- package/functions/bundleLint.test.mjs +3 -0
- package/functions/distLint.mjs +2 -6
- package/functions/distLint.test.mjs +3 -0
- package/functions/partials/copyFor.mjs +2 -1
- package/functions/partials/copyFor.test.mjs +18 -0
- package/functions/partials/imagesFor.mjs +35 -3
- package/functions/partials/imagesFor.test.mjs +83 -1
- package/functions/partials/removeDirectory.mjs +28 -14
- package/functions/partials/removeDirectory.test.mjs +44 -0
- package/functions/partials/sassFor.mjs +5 -2
- package/functions/partials/sassFor.test.mjs +22 -4
- package/functions/partials/standardLint.mjs +80 -0
- package/functions/partials/standardLint.test.mjs +99 -0
- package/functions/partials/tsFor.mjs +8 -1
- package/functions/partials.mjs +1 -0
- package/functions/partials.test.mjs +1 -1
- package/functions/test-helpers/standardLintWithRealStandard.mjs +21 -0
- package/functions/testFull.mjs +2 -2
- package/functions/testFull.test.mjs +2 -2
- package/functions/testQuick.mjs +2 -2
- package/functions/testQuick.test.mjs +2 -2
- package/package.json +19 -8
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
import fs from 'fs'
|
|
2
|
+
import { rm } from 'node:fs/promises'
|
|
2
3
|
import { removeDirectory } from './removeDirectory.mjs'
|
|
3
4
|
|
|
5
|
+
// Wrap rm so tests can simulate something recreating the directory while (or right after) it is deleted.
|
|
6
|
+
jest.mock('node:fs/promises', () => {
|
|
7
|
+
const actual = jest.requireActual('node:fs/promises')
|
|
8
|
+
return { ...actual, rm: jest.fn(actual.rm) }
|
|
9
|
+
})
|
|
10
|
+
const { rm: realRm } = jest.requireActual('node:fs/promises')
|
|
11
|
+
|
|
12
|
+
const dirPath = 'remove-directory'
|
|
13
|
+
const recreateAfterRemoving = async (target, options) => {
|
|
14
|
+
await realRm(target, options)
|
|
15
|
+
fs.mkdirSync(target)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
afterEach(() => {
|
|
19
|
+
rm.mockReset()
|
|
20
|
+
rm.mockImplementation(realRm)
|
|
21
|
+
fs.rmSync(dirPath, { recursive: true, force: true })
|
|
22
|
+
})
|
|
23
|
+
|
|
4
24
|
describe('removeDirectory', () => {
|
|
5
25
|
test('able to delete the remove-directory', async () => {
|
|
6
26
|
const dirPath = 'remove-directory'
|
|
@@ -25,4 +45,28 @@ describe('removeDirectory', () => {
|
|
|
25
45
|
expect(fs.existsSync(dirPath)).toBeFalsy()
|
|
26
46
|
expect(await removeDirectory(dirPath)).toBe(dirPath)
|
|
27
47
|
})
|
|
48
|
+
|
|
49
|
+
test('removes with force and Node\'s built-in retry-with-back-off for busy or locked directories', async () => {
|
|
50
|
+
expect.assertions(1)
|
|
51
|
+
fs.mkdirSync(dirPath)
|
|
52
|
+
await removeDirectory(dirPath)
|
|
53
|
+
expect(rm).toHaveBeenCalledWith(dirPath, expect.objectContaining({ recursive: true, force: true, maxRetries: 5 }))
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
test('removes the directory again when something recreates it right after the first removal', async () => {
|
|
57
|
+
expect.assertions(2)
|
|
58
|
+
fs.mkdirSync(dirPath)
|
|
59
|
+
rm.mockImplementationOnce(recreateAfterRemoving)
|
|
60
|
+
await removeDirectory(dirPath)
|
|
61
|
+
expect(fs.existsSync(dirPath)).toBeFalsy()
|
|
62
|
+
expect(rm).toHaveBeenCalledTimes(2)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('fails with a clear error instead of leaving stale output when the directory keeps coming back', async () => {
|
|
66
|
+
expect.assertions(2)
|
|
67
|
+
fs.mkdirSync(dirPath)
|
|
68
|
+
rm.mockImplementation(recreateAfterRemoving)
|
|
69
|
+
await expect(removeDirectory(dirPath)).rejects.toThrow(/Unable to remove "remove-directory" - it was recreated or is locked/)
|
|
70
|
+
expect(rm).toHaveBeenCalledTimes(4)
|
|
71
|
+
})
|
|
28
72
|
})
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { dest, src } from 'gulp'
|
|
2
2
|
import * as gulpConfig from '../../gulp.config.mjs'
|
|
3
|
-
import
|
|
3
|
+
import autoprefixer from 'autoprefixer'
|
|
4
|
+
import cssnano from 'cssnano'
|
|
5
|
+
import postcss from 'gulp-postcss'
|
|
4
6
|
import rename from 'gulp-rename'
|
|
5
7
|
import * as sass from 'sass'
|
|
6
8
|
import { default as gulpSass } from 'gulp-sass'
|
|
@@ -17,6 +19,7 @@ const runSass = gulpSass(sass)
|
|
|
17
19
|
export const sassFor = (srcSearch = gulpConfig.get('sass.from'), cssPath = gulpConfig.get('sass.to')) => src(srcSearch)
|
|
18
20
|
.pipe(runSass().on('error', runSass.logError)) // Passes it through a gulp-sass, log errors to console
|
|
19
21
|
.pipe(dest(cssPath))
|
|
20
|
-
.
|
|
22
|
+
// add: false - the old gulp-cssnano only ever removed obsolete vendor prefixes, never added any; keep that.
|
|
23
|
+
.pipe(postcss([autoprefixer({ add: false }), cssnano()]))
|
|
21
24
|
.pipe(rename({ extname: '.min.css' }))
|
|
22
25
|
.pipe(dest(cssPath))
|
|
@@ -27,10 +27,7 @@ const sassContents = 'html\n' +
|
|
|
27
27
|
|
|
28
28
|
const sassPath = gulpConfig.get('sass.path')
|
|
29
29
|
|
|
30
|
-
beforeEach(() => {
|
|
31
|
-
setUp.beforeEach()
|
|
32
|
-
return fs.mkdirSync(sassPath, { recursive: true })
|
|
33
|
-
})
|
|
30
|
+
beforeEach(() => setUp.beforeEach().then(() => fs.mkdirSync(sassPath, { recursive: true })))
|
|
34
31
|
|
|
35
32
|
afterEach(setUp.afterEach)
|
|
36
33
|
|
|
@@ -60,4 +57,25 @@ describe('sassFor', () => {
|
|
|
60
57
|
done()
|
|
61
58
|
})
|
|
62
59
|
})
|
|
60
|
+
|
|
61
|
+
test('also writes a minified .min.css next to the css output', done => {
|
|
62
|
+
const sassFile = `${sassPath}/sassFor.sass`
|
|
63
|
+
fs.writeFileSync(sassFile, sassContents)
|
|
64
|
+
expect.assertions(4)
|
|
65
|
+
const cssPath = gulpConfig.get('sass.to')
|
|
66
|
+
sassFor(sassFile)
|
|
67
|
+
.on('finish', () => {
|
|
68
|
+
const cssContents = fs.readFileSync(`${cssPath}/sassFor.css`).toString()
|
|
69
|
+
const minContents = fs.readFileSync(`${cssPath}/sassFor.min.css`).toString()
|
|
70
|
+
expect(minContents.length).toBeLessThan(cssContents.length)
|
|
71
|
+
expect(countMatches(minContents.trim(), '\n')).toEqual(0)
|
|
72
|
+
expect(minContents).toContain('outline:none')
|
|
73
|
+
expect(minContents).toContain('text-align:center')
|
|
74
|
+
done()
|
|
75
|
+
})
|
|
76
|
+
.on('error', error => {
|
|
77
|
+
console.error('Encountered error', error)
|
|
78
|
+
done()
|
|
79
|
+
})
|
|
80
|
+
})
|
|
63
81
|
})
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import through from 'through2'
|
|
3
|
+
|
|
4
|
+
// `standard` (17+) ships ESM-only, but this package also publishes a CommonJS build (dist/*.js) whose babel
|
|
5
|
+
// transform would turn even a dynamic import() into a require() that cannot load an ES module. Hiding the import()
|
|
6
|
+
// inside a Function constructor keeps it a genuine dynamic import that works from either build (same escape hatch
|
|
7
|
+
// as tsFor.mjs uses for gulp-ts-compile).
|
|
8
|
+
const importStandard = new Function('return import(\'standard\')')
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Print a file's lint messages, if it has any.
|
|
12
|
+
* @memberOf module:partials
|
|
13
|
+
* @param {import('vinyl')} file
|
|
14
|
+
* @param {{messages: Array<{line: number, column: number, message: string}>, errorCount: number, warningCount: number}} result
|
|
15
|
+
* @returns {undefined}
|
|
16
|
+
*/
|
|
17
|
+
const printFileReport = (file, result) => {
|
|
18
|
+
if (!result.messages.length) {
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
console.log(path.relative(file.cwd, file.path))
|
|
22
|
+
result.messages.forEach(({ line, column, message }) => console.log(`line ${line}:${column}\t${message}`))
|
|
23
|
+
console.log(`✖ ${result.errorCount} error\t⚠ ${result.warningCount} warning\n`)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Lint every file streaming through with JavaScript Standard Style and, unless `fix` is false, apply the automatic
|
|
28
|
+
* fixes to the file's contents so a following `dest()` writes the fixed version. Remaining problems are printed
|
|
29
|
+
* along with a summary once the stream ends; they never fail the build.
|
|
30
|
+
*
|
|
31
|
+
* Project-level Standard configuration (the `standard` field in package.json: ignore, env, globals, ...) is honored
|
|
32
|
+
* because the file's own path and cwd are handed to Standard.
|
|
33
|
+
* @memberOf module:partials
|
|
34
|
+
* @param {Object} [options={}]
|
|
35
|
+
* @param {boolean} [options.fix=true] - Apply Standard's automatic fixes to the file contents.
|
|
36
|
+
* @param {function(): Promise<{lintText: Function}>} [loadStandard] - Resolves the `standard` module. Real callers
|
|
37
|
+
* should never need to pass this - it exists so tests can supply a stand-in, since this project's
|
|
38
|
+
* CommonJS-transform-based Jest setup cannot execute a real dynamic import() of an ES module.
|
|
39
|
+
* @returns {import('stream').Transform}
|
|
40
|
+
*/
|
|
41
|
+
export const standardLint = (
|
|
42
|
+
{ fix = true } = {},
|
|
43
|
+
loadStandard = () => importStandard().then(({ default: standard }) => standard)
|
|
44
|
+
) => {
|
|
45
|
+
const totals = { errors: 0, warnings: 0 }
|
|
46
|
+
return through.obj(
|
|
47
|
+
function (file, enc, callback) {
|
|
48
|
+
if (file.isNull()) {
|
|
49
|
+
callback(null, file)
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
if (file.isStream()) {
|
|
53
|
+
callback(new Error('standardLint: streaming file contents are not supported.'))
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
loadStandard()
|
|
57
|
+
.then(standard => standard.lintText(file.contents.toString(), { filename: file.path, cwd: file.cwd, fix }))
|
|
58
|
+
.then(results => {
|
|
59
|
+
// No result at all means the file is ignored by the project's Standard configuration.
|
|
60
|
+
const [result] = results
|
|
61
|
+
if (result) {
|
|
62
|
+
if (typeof result.output === 'string') {
|
|
63
|
+
file.contents = Buffer.from(result.output)
|
|
64
|
+
}
|
|
65
|
+
totals.errors += result.errorCount
|
|
66
|
+
totals.warnings += result.warningCount
|
|
67
|
+
printFileReport(file, result)
|
|
68
|
+
}
|
|
69
|
+
callback(null, file)
|
|
70
|
+
}, callback)
|
|
71
|
+
},
|
|
72
|
+
function (callback) {
|
|
73
|
+
console.log('Standard linter results')
|
|
74
|
+
console.log('======================================')
|
|
75
|
+
console.log(`✖ Errors total: ${totals.errors}`)
|
|
76
|
+
console.log(`⚠ Warnings total: ${totals.warnings}\n`)
|
|
77
|
+
callback()
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import Vinyl from 'vinyl'
|
|
2
|
+
import { Readable } from 'node:stream'
|
|
3
|
+
import { standardLint } from './standardLint.mjs'
|
|
4
|
+
|
|
5
|
+
const makeFile = (contents, filePath = '/project/dist/example.js') => new Vinyl({
|
|
6
|
+
cwd: '/project',
|
|
7
|
+
base: '/project/dist',
|
|
8
|
+
path: filePath,
|
|
9
|
+
contents
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
const run = (transform, files) => new Promise((resolve, reject) => {
|
|
13
|
+
const out = []
|
|
14
|
+
transform.on('data', file => out.push(file)).on('end', () => resolve(out)).on('error', reject)
|
|
15
|
+
files.forEach(file => transform.write(file))
|
|
16
|
+
transform.end()
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const fakeStandard = (resultFor) => ({
|
|
20
|
+
lintText: jest.fn((text, options) => Promise.resolve(resultFor(text, options)))
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
let logSpy
|
|
24
|
+
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
logSpy = jest.spyOn(console, 'log').mockImplementation(() => {})
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
afterEach(() => {
|
|
30
|
+
logSpy.mockRestore()
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
describe('standardLint', () => {
|
|
34
|
+
test('replaces file contents with the fixed output and hands Standard the file path, cwd and fix option', async () => {
|
|
35
|
+
expect.assertions(3)
|
|
36
|
+
const standard = fakeStandard((text) => [{ messages: [], errorCount: 0, warningCount: 0, output: text.replace(/"/g, '\'') }])
|
|
37
|
+
const [linted] = await run(standardLint({ fix: true }, () => Promise.resolve(standard)), [makeFile(Buffer.from('const a = "b"'))])
|
|
38
|
+
expect(linted.contents.toString()).toEqual('const a = \'b\'')
|
|
39
|
+
expect(standard.lintText).toHaveBeenCalledWith('const a = "b"', { filename: '/project/dist/example.js', cwd: '/project', fix: true })
|
|
40
|
+
expect(linted.path).toEqual('/project/dist/example.js')
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('leaves the contents alone when Standard has no fixed output (nothing needed fixing)', async () => {
|
|
44
|
+
expect.assertions(1)
|
|
45
|
+
const standard = fakeStandard(() => [{ messages: [], errorCount: 0, warningCount: 0 }])
|
|
46
|
+
const [linted] = await run(standardLint({}, () => Promise.resolve(standard)), [makeFile(Buffer.from('const a = 1'))])
|
|
47
|
+
expect(linted.contents.toString()).toEqual('const a = 1')
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
test('passes fix: false through so nothing is rewritten', async () => {
|
|
51
|
+
expect.assertions(1)
|
|
52
|
+
const standard = fakeStandard(() => [{ messages: [], errorCount: 0, warningCount: 0 }])
|
|
53
|
+
await run(standardLint({ fix: false }, () => Promise.resolve(standard)), [makeFile(Buffer.from('x'))])
|
|
54
|
+
expect(standard.lintText.mock.calls[0][1].fix).toBe(false)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('passes a file through untouched when the project ignores it (Standard returns no results)', async () => {
|
|
58
|
+
expect.assertions(2)
|
|
59
|
+
const standard = fakeStandard(() => [])
|
|
60
|
+
const [linted] = await run(standardLint({}, () => Promise.resolve(standard)), [makeFile(Buffer.from('var x=1'))])
|
|
61
|
+
expect(linted.contents.toString()).toEqual('var x=1')
|
|
62
|
+
expect(logSpy).toHaveBeenCalledWith('✖ Errors total: 0')
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('skips null-content files without linting them', async () => {
|
|
66
|
+
expect.assertions(2)
|
|
67
|
+
const standard = fakeStandard(() => [])
|
|
68
|
+
const [passed] = await run(standardLint({}, () => Promise.resolve(standard)), [makeFile(null)])
|
|
69
|
+
expect(passed.isNull()).toBeTruthy()
|
|
70
|
+
expect(standard.lintText).not.toHaveBeenCalled()
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
test('errors on streaming file contents, which cannot be linted', async () => {
|
|
74
|
+
expect.assertions(1)
|
|
75
|
+
const streamFile = makeFile(Readable.from(['x']))
|
|
76
|
+
await expect(run(standardLint({}, () => Promise.resolve(fakeStandard(() => []))), [streamFile])).rejects.toThrow(/streaming/)
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
test('prints per-file problems and a summary of totals across all files, without failing', async () => {
|
|
80
|
+
expect.assertions(5)
|
|
81
|
+
const standard = fakeStandard((text, { filename }) => filename.endsWith('a.js')
|
|
82
|
+
? [{ messages: [{ line: 2, column: 7, message: 'unused b' }, { line: 3, column: 1, message: 'bad thing' }], errorCount: 2, warningCount: 0 }]
|
|
83
|
+
: [{ messages: [{ line: 1, column: 1, message: 'just a warning' }], errorCount: 0, warningCount: 1 }])
|
|
84
|
+
const out = await run(
|
|
85
|
+
standardLint({}, () => Promise.resolve(standard)),
|
|
86
|
+
[makeFile(Buffer.from('a'), '/project/dist/a.js'), makeFile(Buffer.from('b'), '/project/dist/b.js')]
|
|
87
|
+
)
|
|
88
|
+
expect(out).toHaveLength(2)
|
|
89
|
+
expect(logSpy).toHaveBeenCalledWith('dist/a.js')
|
|
90
|
+
expect(logSpy).toHaveBeenCalledWith('line 2:7\tunused b')
|
|
91
|
+
expect(logSpy).toHaveBeenCalledWith('✖ Errors total: 2')
|
|
92
|
+
expect(logSpy).toHaveBeenCalledWith('⚠ Warnings total: 1\n')
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
test('surfaces a failure to load or run Standard as a stream error', async () => {
|
|
96
|
+
expect.assertions(1)
|
|
97
|
+
await expect(run(standardLint({}, () => Promise.reject(new Error('cannot load'))), [makeFile(Buffer.from('x'))])).rejects.toThrow('cannot load')
|
|
98
|
+
})
|
|
99
|
+
})
|
|
@@ -61,7 +61,14 @@ export const tsFor = (
|
|
|
61
61
|
return () => {}
|
|
62
62
|
}
|
|
63
63
|
const configPath = gulpConfig.get('typescript.config')
|
|
64
|
-
|
|
64
|
+
// When no tsconfig.json is configured, target/module are pinned explicitly rather than left for TypeScript's
|
|
65
|
+
// own compiler defaults - those defaults have already shifted once across a TypeScript version bump in this
|
|
66
|
+
// project's own history (silently changing whether output keeps `const`/`let` or downlevels to `var`), and
|
|
67
|
+
// pinning them keeps this task's output stable across future TypeScript upgrades too. ES5/CommonJS matches
|
|
68
|
+
// what the downstream babel/browserify bundling pipeline has always assumed it receives.
|
|
69
|
+
const compilerOptions = configPath
|
|
70
|
+
? readCompilerOptions(configPath)
|
|
71
|
+
: { declaration: true, target: ts.ScriptTarget.ES5, module: ts.ModuleKind.CommonJS, esModuleInterop: false }
|
|
65
72
|
// Accepts gulp's own callback-style task convention (an optional `done`, called once finished) rather than
|
|
66
73
|
// just returning a Promise, since callers may invoke the returned function directly with a callback instead
|
|
67
74
|
// of relying on gulp's own runner to observe a returned Promise.
|
package/functions/partials.mjs
CHANGED
|
@@ -20,4 +20,5 @@ export { readmeTemplate } from './partials/readmeTemplate.mjs'
|
|
|
20
20
|
export { removeDirectory } from './partials/removeDirectory.mjs'
|
|
21
21
|
export { runOnChange } from './partials/runOnChange.mjs'
|
|
22
22
|
export { sassFor } from './partials/sassFor.mjs'
|
|
23
|
+
export { standardLint } from './partials/standardLint.mjs'
|
|
23
24
|
export { tsFor } from './partials/tsFor.mjs'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process'
|
|
2
|
+
|
|
3
|
+
// Jest's CommonJS transform cannot load `standard` (ESM-only) or run a real dynamic import(), so tests that need
|
|
4
|
+
// genuine Standard behavior run the actual `standard` package in a plain Node subprocess instead of faking it.
|
|
5
|
+
const script = 'import { readFileSync } from \'node:fs\'\n' +
|
|
6
|
+
'import standard from \'standard\'\n' +
|
|
7
|
+
'const { text, options } = JSON.parse(readFileSync(0, \'utf8\'))\n' +
|
|
8
|
+
'process.stdout.write(JSON.stringify(await standard.lintText(text, options)))\n'
|
|
9
|
+
|
|
10
|
+
export const loadStandardViaSubprocess = () => Promise.resolve({
|
|
11
|
+
lintText: (text, options) => Promise.resolve().then(() => JSON.parse(execFileSync(
|
|
12
|
+
process.execPath,
|
|
13
|
+
['--input-type=module', '--eval', script],
|
|
14
|
+
{ input: JSON.stringify({ text, options }), encoding: 'utf8', cwd: process.cwd(), maxBuffer: 256 * 1024 * 1024 }
|
|
15
|
+
)))
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const actual = jest.requireActual('../partials/standardLint.mjs')
|
|
19
|
+
|
|
20
|
+
// Drop-in replacement for the partial module (see jest.mock in the lint/build tests): same API, real Standard.
|
|
21
|
+
export const standardLint = (options) => actual.standardLint(options, loadStandardViaSubprocess)
|
package/functions/testFull.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as gulpConfig from '../gulp.config.mjs'
|
|
2
|
-
import {
|
|
2
|
+
import { runCLI } from 'jest'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Run all tests with jest.
|
|
@@ -13,5 +13,5 @@ export const testFull = () => {
|
|
|
13
13
|
// The testPath must be an array of strings
|
|
14
14
|
testPath = [testPath]
|
|
15
15
|
}
|
|
16
|
-
return
|
|
16
|
+
return runCLI(gulpConfig.get('test.options'), testPath)
|
|
17
17
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { testHelpers } from './testHelpers.mjs'
|
|
2
|
-
import {
|
|
2
|
+
import { runCLI } from 'jest'
|
|
3
3
|
import { testFull } from './testFull.mjs'
|
|
4
4
|
|
|
5
5
|
const gulpConfig = testHelpers.gulpConfig
|
|
@@ -12,6 +12,6 @@ describe('testFull', () => {
|
|
|
12
12
|
test('runs the Jest CLI with the configured options', () => {
|
|
13
13
|
expect.assertions(1)
|
|
14
14
|
testFull()
|
|
15
|
-
expect(
|
|
15
|
+
expect(runCLI).toHaveBeenCalledWith(gulpConfig.get('test.options'), [gulpConfig.get('test.path')])
|
|
16
16
|
})
|
|
17
17
|
})
|
package/functions/testQuick.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as gulpConfig from '../gulp.config.mjs'
|
|
2
|
-
import {
|
|
2
|
+
import { runCLI } from 'jest'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Run the Jest tests for files which have been modified (based on git status).
|
|
@@ -13,5 +13,5 @@ export const testQuick = () => {
|
|
|
13
13
|
// The testPath must be an array of strings
|
|
14
14
|
testPath = [testPath]
|
|
15
15
|
}
|
|
16
|
-
return
|
|
16
|
+
return runCLI({ onlyChanged: true }, testPath)
|
|
17
17
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { testHelpers } from './testHelpers.mjs'
|
|
2
|
-
import {
|
|
2
|
+
import { runCLI } from 'jest'
|
|
3
3
|
import { testQuick } from './testQuick.mjs'
|
|
4
4
|
|
|
5
5
|
const gulpConfig = testHelpers.gulpConfig
|
|
@@ -12,6 +12,6 @@ describe('testQuick', () => {
|
|
|
12
12
|
test('runs the jest CLI with onlyChanged option', () => {
|
|
13
13
|
expect.assertions(1)
|
|
14
14
|
testQuick()
|
|
15
|
-
expect(
|
|
15
|
+
expect(runCLI).toHaveBeenCalledWith({ onlyChanged: true }, [gulpConfig.get('test.path')])
|
|
16
16
|
})
|
|
17
17
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "js-build-tools",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "Standardised build process with gulp.",
|
|
5
5
|
"main": "gulpfile.base.js",
|
|
6
6
|
"exports": {
|
|
@@ -50,30 +50,40 @@
|
|
|
50
50
|
"@babel/plugin-transform-modules-commonjs": "^7.29.7",
|
|
51
51
|
"@babel/preset-env": "^7.29.7",
|
|
52
52
|
"@babel/preset-typescript": "^7.29.7",
|
|
53
|
-
"@babel/runtime-corejs3": "^
|
|
53
|
+
"@babel/runtime-corejs3": "^8.0.6",
|
|
54
|
+
"autoprefixer": "^10.6.1",
|
|
54
55
|
"babel-jest": "^30.4.1",
|
|
55
56
|
"browserify": "^17.0.1",
|
|
56
57
|
"core-js": "^3.49.0",
|
|
58
|
+
"cssnano": "^6.1.2",
|
|
57
59
|
"glob": "^13.0.6",
|
|
58
60
|
"gulp": "^5.0.1",
|
|
59
61
|
"gulp-babel": "^8.1.0",
|
|
60
62
|
"gulp-cache": "^1.1.3",
|
|
61
|
-
"gulp-
|
|
62
|
-
"gulp-imagemin": "github:jheagle/gulp-imagemin#common-js-compatibility",
|
|
63
|
+
"gulp-postcss": "^10.0.0",
|
|
63
64
|
"gulp-rename": "^2.1.0",
|
|
64
65
|
"gulp-sass": "^6.0.1",
|
|
65
|
-
"gulp-standard": "^14.0.0",
|
|
66
66
|
"gulp-ts-compile": "^1.0.0",
|
|
67
67
|
"gulp-uglify-es": "^3.0.0",
|
|
68
|
-
"jest": "^
|
|
68
|
+
"jest": "^30.5.2",
|
|
69
69
|
"jest-environment-jsdom": "^30.4.1",
|
|
70
70
|
"jsdoc-to-markdown": "^9.1.3",
|
|
71
|
+
"postcss": "^8.5.28",
|
|
71
72
|
"regenerator-runtime": "^0.14.1",
|
|
72
73
|
"sass": "^1.101.0",
|
|
73
|
-
"
|
|
74
|
+
"standard": "^17.1.2",
|
|
75
|
+
"test-filesystem": "^1.5.0",
|
|
74
76
|
"through2": "^4.0.2",
|
|
75
77
|
"vinyl-source-stream": "^2.0.0"
|
|
76
78
|
},
|
|
79
|
+
"peerDependencies": {
|
|
80
|
+
"gulp-imagemin": ">=9.0.0"
|
|
81
|
+
},
|
|
82
|
+
"peerDependenciesMeta": {
|
|
83
|
+
"gulp-imagemin": {
|
|
84
|
+
"optional": true
|
|
85
|
+
}
|
|
86
|
+
},
|
|
77
87
|
"files": [
|
|
78
88
|
"babel.config.js",
|
|
79
89
|
"dist",
|
|
@@ -86,6 +96,7 @@
|
|
|
86
96
|
],
|
|
87
97
|
"funding": "https://www.paypal.com/donate/?business=LRYR6SZRWKXVY&no_recurring=0&item_name=Let%27s+build+together+today+to+simplify+our+jobs+tomorrow.¤cy_code=CAD",
|
|
88
98
|
"devDependencies": {
|
|
89
|
-
"
|
|
99
|
+
"gulp-imagemin": "github:jheagle/gulp-imagemin#common-js-compatibility",
|
|
100
|
+
"typescript": "^6.0.3"
|
|
90
101
|
}
|
|
91
102
|
}
|