js-build-tools 4.0.12 → 4.1.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.
Files changed (49) hide show
  1. package/README.md +0 -120
  2. package/dist/build.js +1 -3
  3. package/dist/build.min.js +1 -1
  4. package/dist/bundle.js +1 -2
  5. package/dist/bundle.min.js +1 -1
  6. package/dist/bundleLint.js +1 -2
  7. package/dist/bundleLint.min.js +1 -1
  8. package/dist/bundleMinify.js +1 -2
  9. package/dist/bundleMinify.min.js +1 -1
  10. package/dist/copyFonts.js +0 -1
  11. package/dist/copyFonts.min.js +1 -1
  12. package/dist/default.js +1 -5
  13. package/dist/default.min.js +1 -1
  14. package/dist/distLint.js +0 -1
  15. package/dist/distLint.min.js +1 -1
  16. package/dist/distMinify.js +0 -1
  17. package/dist/distMinify.min.js +1 -1
  18. package/dist/partials/addToReadme.js +0 -1
  19. package/dist/partials/beginWatcher.js +0 -1
  20. package/dist/partials/clean.js +0 -1
  21. package/dist/partials/distFor.js +6 -14
  22. package/dist/partials/distForSrc.js +1 -5
  23. package/dist/partials/distSeries.js +1 -5
  24. package/dist/partials/imagesFor.js +7 -12
  25. package/dist/partials/readmeTemplate.js +0 -1
  26. package/dist/partials/runOnChange.js +3 -7
  27. package/dist/partials/sassFor.js +4 -9
  28. package/dist/partials/tsFor.js +86 -27
  29. package/dist/test-helpers/setUp.js +20 -22
  30. package/dist/testFull.js +20 -22
  31. package/dist/testFull.min.js +1 -1
  32. package/dist/testHelpers.js +0 -1
  33. package/dist/testHelpers.min.js +1 -1
  34. package/dist/testQuick.js +22 -24
  35. package/dist/testQuick.min.js +1 -1
  36. package/dist/utilities/dotGet.js +2 -6
  37. package/dist/utilities/dotNotate.js +6 -15
  38. package/dist/utilities/dotSet.js +2 -4
  39. package/dist/watchTest.js +0 -1
  40. package/dist/watchTest.min.js +1 -1
  41. package/functions/build.test.mjs +24 -0
  42. package/functions/partials/distFor.test.mjs +41 -10
  43. package/functions/partials/tsFor.mjs +73 -9
  44. package/functions/partials/tsFor.test.mjs +31 -1
  45. package/functions/testFull.mjs +2 -2
  46. package/functions/testFull.test.mjs +2 -2
  47. package/functions/testQuick.mjs +2 -2
  48. package/functions/testQuick.test.mjs +2 -2
  49. package/package.json +10 -8
@@ -1,22 +1,86 @@
1
- import { dest, parallel, src } from 'gulp'
1
+ import { dest, src } from 'gulp'
2
+ import path from 'node:path'
2
3
  import * as gulpConfig from '../../gulp.config.mjs'
3
- import ts from 'gulp-typescript'
4
+ import ts from 'typescript'
5
+
6
+ // gulp-ts-compile ships ESM-only (no CJS build - see its own package.json) since it's meant to be consumed by
7
+ // gulpfiles running under a real ESM loader, same as this project's own gulpfile.mjs does. This project also
8
+ // compiles itself to a CommonJS build (dist/*.js, this file's own compiled counterpart) for consumers using
9
+ // require() though, and even a dynamic `import()` gets downleveled by babel's CommonJS transform into a
10
+ // require() call - which can't load a real ES module. Hiding the import() call inside a Function constructor is
11
+ // the standard escape hatch: babel can't see (and so can't rewrite) an import expression that only exists as a
12
+ // runtime-evaluated string, so it survives as a genuine dynamic import, capable of loading gulp-ts-compile from
13
+ // either build.
14
+ const importGulpTsCompile = new Function('return import(\'gulp-ts-compile\')')
15
+
16
+ /**
17
+ * Wrap a stream in a promise that resolves once it finishes writing.
18
+ * @memberOf module:partials
19
+ * @param {import('node:stream').Stream} stream
20
+ * @returns {Promise<void>}
21
+ */
22
+ const streamToPromise = (stream) => new Promise((resolve, reject) => {
23
+ stream.on('finish', resolve)
24
+ stream.on('error', reject)
25
+ })
26
+
27
+ /**
28
+ * Read a tsconfig.json file into real typescript.CompilerOptions values, using only TypeScript's stable, current,
29
+ * public config-reading API (the same one `tsc --project` itself uses internally) - never
30
+ * `ts.convertCompilerOptionsFromJson`, which is exactly the kind of internal/legacy surface that broke
31
+ * gulp-typescript when a removed API call started throwing under TypeScript 7.
32
+ * @memberOf module:partials
33
+ * @param {string} configPath - Path to a tsconfig.json file.
34
+ * @returns {import('typescript').CompilerOptions}
35
+ */
36
+ const readCompilerOptions = (configPath) => {
37
+ const configFile = ts.readConfigFile(configPath, ts.sys.readFile)
38
+ const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path.dirname(configPath))
39
+ return parsedConfig.options
40
+ }
4
41
 
5
42
  /**
6
43
  * Starting at the source directory, find all the ts files and convert them into the distribution directory.
7
44
  * @memberOf module:partials
8
45
  * @param {string|array} [srcPath='']
9
46
  * @param {string} [distPath='']
47
+ * @param {function(): Promise<Function>} [loadTsCompile] - Resolves the `gulp-ts-compile` default export. Real
48
+ * callers should never need to pass this - it exists so tests can inject a stand-in compiler, sidestepping the
49
+ * genuine dynamic `import()` above that this project's current CommonJS-transform-based Jest setup cannot
50
+ * execute without a broader (and riskier) migration to Jest's native ESM support. gulp-ts-compile's own test
51
+ * suite already covers real TypeScript-compile correctness - this function's own tests only need to verify its
52
+ * config resolution and stream wiring.
10
53
  * @returns {Function}
11
- * @see `https://www.typescriptlang.org/docs/handbook/gulp.html` for more info
12
54
  */
13
- export const tsFor = (srcPath = gulpConfig.get('typescript.from'), distPath = gulpConfig.get('typescript.to')) => {
55
+ export const tsFor = (
56
+ srcPath = gulpConfig.get('typescript.from'),
57
+ distPath = gulpConfig.get('typescript.to'),
58
+ loadTsCompile = () => importGulpTsCompile().then(({ default: tsCompile }) => tsCompile)
59
+ ) => {
14
60
  if (gulpConfig.get('typescript.enabled') === false) {
15
61
  return () => {}
16
62
  }
17
- const declarationProject = ts.createProject(gulpConfig.get('typescript.config'))
18
- const tsProject = ts.createProject(gulpConfig.get('typescript.config'))
19
- const makeDeclarations = () => src(srcPath).pipe(declarationProject()).dts.pipe(dest(distPath))
20
- const compileJS = () => src(srcPath).pipe(tsProject()).js.pipe(dest(distPath))
21
- return parallel(makeDeclarations, compileJS)
63
+ const configPath = gulpConfig.get('typescript.config')
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 }
72
+ // Accepts gulp's own callback-style task convention (an optional `done`, called once finished) rather than
73
+ // just returning a Promise, since callers may invoke the returned function directly with a callback instead
74
+ // of relying on gulp's own runner to observe a returned Promise.
75
+ return (done) => {
76
+ const compile = async () => {
77
+ const tsCompile = await loadTsCompile()
78
+ const tsResult = src(srcPath).pipe(tsCompile(compilerOptions))
79
+ await Promise.all([
80
+ streamToPromise(tsResult.dts.pipe(dest(distPath))),
81
+ streamToPromise(tsResult.js.pipe(dest(distPath)))
82
+ ])
83
+ }
84
+ return typeof done === 'function' ? compile().then(() => done(), done) : compile()
85
+ }
22
86
  }
@@ -1,4 +1,7 @@
1
1
  import fs from 'fs'
2
+ import { Transform, PassThrough } from 'node:stream'
3
+ import ts from 'typescript'
4
+ import File from 'vinyl'
2
5
  import * as setUp from '../test-helpers/setUp.mjs'
3
6
  import { tsFor } from './tsFor.mjs'
4
7
  import { countMatches } from 'test-filesystem'
@@ -10,6 +13,33 @@ const rawContents = 'export function sayHello(name: string) {\n' +
10
13
  ' return `Hello from ${name}`;\n' +
11
14
  '}'
12
15
 
16
+ // tsFor's real implementation loads gulp-ts-compile (a genuine ESM-only package) via a dynamic import() hidden
17
+ // from babel's static analysis - necessary for production correctness (see tsFor.mjs's own comments), but not
18
+ // something this project's current CommonJS-transform-based Jest setup can execute without a much bigger
19
+ // migration to Jest's native ESM support. This fake stands in for it here, doing real (not mocked-away)
20
+ // TypeScript transpilation via `ts.transpileModule` so this test still exercises genuine compile behavior -
21
+ // gulp-ts-compile's own test suite separately covers its whole-program/cross-file-import compile behavior.
22
+ const fakeLoadTsCompile = () => Promise.resolve((options) => {
23
+ const transform = new Transform({
24
+ objectMode: true,
25
+ transform (file, enc, callback) {
26
+ const { outputText } = ts.transpileModule(file.contents.toString(), { compilerOptions: options })
27
+ jsStream.push(new File({ cwd: file.cwd, base: file.base, path: file.path.replace(/\.ts$/, '.js'), contents: Buffer.from(outputText) }))
28
+ callback()
29
+ },
30
+ flush (callback) {
31
+ jsStream.end()
32
+ dtsStream.end()
33
+ callback()
34
+ }
35
+ })
36
+ const jsStream = new PassThrough({ objectMode: true })
37
+ const dtsStream = new PassThrough({ objectMode: true })
38
+ transform.js = jsStream
39
+ transform.dts = dtsStream
40
+ return transform
41
+ })
42
+
13
43
  beforeEach(
14
44
  () => setUp.beforeEach()
15
45
  .then(
@@ -31,7 +61,7 @@ describe('tsFor', () => {
31
61
  expect.assertions(3)
32
62
  const oldContents = fs.readFileSync(srcFile).toString()
33
63
  expect(countMatches(oldContents, 'sayHello(name: string)')).toEqual(1)
34
- tsFor(srcFile, distPath)(() => {
64
+ tsFor(srcFile, distPath, fakeLoadTsCompile)(() => {
35
65
  expect(fs.existsSync(distPath)).toBeTruthy()
36
66
  const compiledContents = fs.readFileSync(`${distPath}/typeScript.js`).toString()
37
67
  expect(countMatches(compiledContents, 'sayHello(name)')).toEqual(1)
@@ -1,5 +1,5 @@
1
1
  import * as gulpConfig from '../gulp.config.mjs'
2
- import { default as jest } from 'jest'
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 jest.runCLI(gulpConfig.get('test.options'), testPath)
16
+ return runCLI(gulpConfig.get('test.options'), testPath)
17
17
  }
@@ -1,5 +1,5 @@
1
1
  import { testHelpers } from './testHelpers.mjs'
2
- import { default as jestImport } from 'jest'
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(jestImport.runCLI).toHaveBeenCalledWith(gulpConfig.get('test.options'), [gulpConfig.get('test.path')])
15
+ expect(runCLI).toHaveBeenCalledWith(gulpConfig.get('test.options'), [gulpConfig.get('test.path')])
16
16
  })
17
17
  })
@@ -1,5 +1,5 @@
1
1
  import * as gulpConfig from '../gulp.config.mjs'
2
- import { default as jest } from 'jest'
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 jest.runCLI({ onlyChanged: true }, testPath)
16
+ return runCLI({ onlyChanged: true }, testPath)
17
17
  }
@@ -1,5 +1,5 @@
1
1
  import { testHelpers } from './testHelpers.mjs'
2
- import { default as jestImport } from 'jest'
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(jestImport.runCLI).toHaveBeenCalledWith({ onlyChanged: true }, [gulpConfig.get('test.path')])
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": "4.0.12",
3
+ "version": "4.1.1",
4
4
  "description": "Standardised build process with gulp.",
5
5
  "main": "gulpfile.base.js",
6
6
  "exports": {
@@ -50,28 +50,27 @@
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": "^7.29.7",
53
+ "@babel/runtime-corejs3": "^8.0.6",
54
54
  "babel-jest": "^30.4.1",
55
55
  "browserify": "^17.0.1",
56
56
  "core-js": "^3.49.0",
57
- "fs": "^0.0.2",
58
57
  "glob": "^13.0.6",
59
58
  "gulp": "^5.0.1",
60
59
  "gulp-babel": "^8.1.0",
61
60
  "gulp-cache": "^1.1.3",
62
61
  "gulp-cssnano": "^2.1.3",
63
- "gulp-imagemin": "^9.2.0",
62
+ "gulp-imagemin": "github:jheagle/gulp-imagemin#common-js-compatibility",
64
63
  "gulp-rename": "^2.1.0",
65
64
  "gulp-sass": "^6.0.1",
66
65
  "gulp-standard": "^14.0.0",
67
- "gulp-typescript": "^6.0.0-alpha.1",
66
+ "gulp-ts-compile": "^1.0.0",
68
67
  "gulp-uglify-es": "^3.0.0",
69
- "jest": "^29.7.0",
68
+ "jest": "^30.5.2",
70
69
  "jest-environment-jsdom": "^30.4.1",
71
70
  "jsdoc-to-markdown": "^9.1.3",
72
71
  "regenerator-runtime": "^0.14.1",
73
72
  "sass": "^1.101.0",
74
- "test-filesystem": "^1.3.14",
73
+ "test-filesystem": "^1.5.0",
75
74
  "through2": "^4.0.2",
76
75
  "vinyl-source-stream": "^2.0.0"
77
76
  },
@@ -85,5 +84,8 @@
85
84
  "gulp.config.mjs",
86
85
  "jsdoc.base.js"
87
86
  ],
88
- "funding": "https://www.paypal.com/donate/?business=LRYR6SZRWKXVY&no_recurring=0&item_name=Let%27s+build+together+today+to+simplify+our+jobs+tomorrow.&currency_code=CAD"
87
+ "funding": "https://www.paypal.com/donate/?business=LRYR6SZRWKXVY&no_recurring=0&item_name=Let%27s+build+together+today+to+simplify+our+jobs+tomorrow.&currency_code=CAD",
88
+ "devDependencies": {
89
+ "typescript": "^6.0.3"
90
+ }
89
91
  }