js-build-tools 6.6.0 → 6.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -674
- package/README.md +762 -701
- package/babel.config.js +28 -28
- package/dist/build.js +75 -75
- package/dist/bundle.js +19 -19
- package/dist/bundleMinify.js +7 -7
- package/dist/compileReadme.js +4 -4
- package/dist/copyFiles.js +17 -17
- package/dist/copyFonts.js +4 -4
- package/dist/default.js +5 -5
- package/dist/dist.js +4 -4
- package/dist/distMinify.js +4 -4
- package/dist/docs.js +7 -7
- package/dist/images.js +4 -4
- package/dist/jsdocDocs.js +6 -6
- package/dist/lint.js +16 -16
- package/dist/partials/addToReadme.js +9 -9
- package/dist/partials/beginWatcher.js +4 -4
- package/dist/partials/clean.js +5 -5
- package/dist/partials/copyFor.js +9 -9
- package/dist/partials/distFor.js +6 -6
- package/dist/partials/distForSrc.js +5 -5
- package/dist/partials/distSeries.js +7 -7
- package/dist/partials/imagesFor.js +93 -93
- package/dist/partials/jsdocDocsFor.js +46 -46
- package/dist/partials/lintSource.js +51 -51
- package/dist/partials/loadPeer.js +99 -99
- package/dist/partials/loadPlaywright.js +14 -14
- package/dist/partials/minifyFor.js +20 -20
- package/dist/partials/neostandardLint.js +175 -175
- package/dist/partials/readmeTemplate.js +4 -4
- package/dist/partials/removeDirectory.js +11 -11
- package/dist/partials/resolveDocsMethod.js +6 -6
- package/dist/partials/runOnChange.js +31 -31
- package/dist/partials/sassFor.js +6 -6
- package/dist/partials/serveStatic.js +9 -9
- package/dist/partials/tsFor.js +32 -32
- package/dist/partials/typeDocsFor.js +264 -264
- package/dist/partials.js +176 -176
- package/dist/sourceLint.js +18 -18
- package/dist/test-helpers/isolateGulpCache.js +24 -24
- package/dist/test-helpers/setUp.js +4 -4
- package/dist/testFull.js +5 -5
- package/dist/testQuick.js +5 -5
- package/dist/typeDocs.js +5 -5
- package/dist/typeScript.js +4 -4
- package/dist/utilities/convertMjsFilesForDocs.js +12 -12
- package/dist/utilities/dotGet.js +54 -54
- package/dist/utilities/dotNotate.js +79 -79
- package/dist/utilities/dotSet.js +45 -45
- package/dist/utilities/esmNamedExportsToCjs.js +15 -15
- package/dist/utilities/getBundleConfigs.js +9 -9
- package/dist/utilities/isObject.js +6 -6
- package/dist/utilities/strAfter.js +7 -7
- package/dist/utilities/strBefore.js +7 -7
- package/dist/watchFull.js +4 -4
- package/dist/watchTest.js +4 -4
- package/functions/build.mjs +72 -72
- package/functions/build.test.mjs +763 -759
- package/functions/bundle.mjs +44 -44
- package/functions/bundle.test.mjs +219 -219
- package/functions/bundleMinify.mjs +16 -16
- package/functions/bundleMinify.test.mjs +37 -37
- package/functions/compileReadme.mjs +9 -9
- package/functions/compileReadme.test.mjs +18 -18
- package/functions/copyFiles.mjs +32 -32
- package/functions/copyFiles.test.mjs +78 -78
- package/functions/copyFonts.mjs +9 -9
- package/functions/copyFonts.test.mjs +32 -32
- package/functions/default.mjs +12 -12
- package/functions/default.test.mjs +33 -33
- package/functions/dist.mjs +8 -8
- package/functions/dist.test.mjs +44 -44
- package/functions/distMinify.mjs +9 -9
- package/functions/distMinify.test.mjs +15 -15
- package/functions/docs.mjs +13 -13
- package/functions/docs.test.mjs +45 -45
- package/functions/gulpConfigEntries.test.mjs +23 -23
- package/functions/images.mjs +8 -8
- package/functions/images.test.mjs +142 -142
- package/functions/jsdocDocs.mjs +10 -10
- package/functions/jsdocEsmExports.test.mjs +24 -24
- package/functions/lint.mjs +9 -9
- package/functions/partials/addToReadme.mjs +25 -25
- package/functions/partials/addToReadme.test.mjs +34 -34
- package/functions/partials/beginWatcher.mjs +9 -9
- package/functions/partials/beginWatcher.test.mjs +19 -19
- package/functions/partials/clean.mjs +13 -13
- package/functions/partials/clean.test.mjs +22 -22
- package/functions/partials/copyFor.mjs +15 -15
- package/functions/partials/copyFor.test.mjs +53 -53
- package/functions/partials/distFor.mjs +22 -22
- package/functions/partials/distFor.test.mjs +195 -195
- package/functions/partials/distForSrc.mjs +11 -11
- package/functions/partials/distForSrc.test.mjs +18 -18
- package/functions/partials/distSeries.mjs +21 -21
- package/functions/partials/distSeries.test.mjs +34 -34
- package/functions/partials/imagesFor.mjs +83 -83
- package/functions/partials/imagesFor.test.mjs +287 -287
- package/functions/partials/jsdocDocsFor.mjs +163 -152
- package/functions/partials/jsdocDocsFor.test.mjs +182 -152
- package/functions/partials/lintSource.mjs +41 -41
- package/functions/partials/loadPeer.mjs +76 -76
- package/functions/partials/loadPeer.test.mjs +58 -58
- package/functions/partials/loadPlaywright.mjs +23 -23
- package/functions/partials/loadPlaywright.test.mjs +70 -70
- package/functions/partials/minifyFor.mjs +15 -15
- package/functions/partials/minifyFor.test.mjs +49 -49
- package/functions/partials/neostandardLint.mjs +142 -142
- package/functions/partials/neostandardLint.test.mjs +131 -131
- package/functions/partials/readmeTemplate.mjs +12 -12
- package/functions/partials/readmeTemplate.test.mjs +34 -34
- package/functions/partials/removeDirectory.mjs +34 -34
- package/functions/partials/removeDirectory.test.mjs +72 -72
- package/functions/partials/resolveDocsMethod.mjs +10 -10
- package/functions/partials/resolveDocsMethod.test.mjs +33 -33
- package/functions/partials/runOnChange.mjs +54 -54
- package/functions/partials/runOnChange.test.mjs +95 -95
- package/functions/partials/sassFor.mjs +25 -25
- package/functions/partials/sassFor.test.mjs +81 -81
- package/functions/partials/serveStatic.mjs +47 -47
- package/functions/partials/serveStatic.test.mjs +71 -71
- package/functions/partials/tsFor.mjs +92 -92
- package/functions/partials/tsFor.test.mjs +88 -88
- package/functions/partials/typeDocsFor.mjs +231 -231
- package/functions/partials/typeDocsFor.test.mjs +263 -263
- package/functions/partials.mjs +31 -31
- package/functions/partials.test.mjs +7 -7
- package/functions/sass.mjs +4 -4
- package/functions/sass.test.mjs +31 -31
- package/functions/sourceLint.mjs +13 -13
- package/functions/sourceLint.test.mjs +166 -166
- package/functions/test-helpers/isolateGulpCache.mjs +16 -16
- package/functions/test-helpers/neostandardLintWithRealNeostandard.mjs +40 -40
- package/functions/test-helpers/setUp.mjs +100 -100
- package/functions/test-helpers/setUp.test.mjs +19 -19
- package/functions/testFull.mjs +17 -17
- package/functions/testFull.test.mjs +17 -17
- package/functions/testHelpers.mjs +10 -10
- package/functions/testHelpers.test.mjs +7 -7
- package/functions/testQuick.mjs +17 -17
- package/functions/testQuick.test.mjs +17 -17
- package/functions/typeDocs.mjs +9 -9
- package/functions/typeDocs.test.mjs +11 -11
- package/functions/typeScript.mjs +8 -8
- package/functions/typeScript.test.mjs +11 -11
- package/functions/utilities/convertMjsFilesForDocs.mjs +34 -34
- package/functions/utilities/convertMjsFilesForDocs.test.mjs +58 -58
- package/functions/utilities/dotGet.mjs +49 -49
- package/functions/utilities/dotNotate.mjs +73 -73
- package/functions/utilities/dotNotate.test.mjs +41 -41
- package/functions/utilities/dotSet.mjs +40 -40
- package/functions/utilities/esmNamedExportsToCjs.mjs +30 -30
- package/functions/utilities/esmNamedExportsToCjs.test.mjs +47 -47
- package/functions/utilities/getBundleConfigs.mjs +30 -30
- package/functions/utilities/isObject.mjs +8 -8
- package/functions/utilities/strAfter.mjs +12 -12
- package/functions/utilities/strBefore.mjs +12 -12
- package/functions/watchFull.mjs +9 -9
- package/functions/watchFull.test.mjs +41 -41
- package/functions/watchTest.mjs +10 -10
- package/functions/watchTest.test.mjs +49 -49
- package/gulp.config.js +4 -4
- package/gulp.config.mjs +344 -340
- package/gulpfile.base.js +51 -51
- package/gulpfile.base.mjs +29 -29
- package/jsdoc.base.js +16 -16
- package/jsdoc.esmExports.js +17 -17
- package/package.json +146 -145
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
/* eslint-disable no-template-curly-in-string -- fixture source code, the ${...} is meant to stay literal */
|
|
2
|
-
import fs from 'fs'
|
|
3
|
-
import * as setUp from '../test-helpers/setUp.mjs'
|
|
4
|
-
import { convertMjsFilesForDocs } from './convertMjsFilesForDocs.mjs'
|
|
5
|
-
|
|
6
|
-
setUp.setDefaults('test-temp-convert-mjs-for-docs')
|
|
7
|
-
const gulpConfig = setUp.gulpConfig
|
|
8
|
-
|
|
9
|
-
const rawContents = '/**\n' +
|
|
10
|
-
' * Say hello with a given name.\n' +
|
|
11
|
-
' * @memberOf module:greet\n' +
|
|
12
|
-
' * @param {string} name\n' +
|
|
13
|
-
' * @returns {string}\n' +
|
|
14
|
-
' */\n' +
|
|
15
|
-
'export const sayHello = name => `Hello from ${name}`\n'
|
|
16
|
-
|
|
17
|
-
beforeEach(() => setUp.beforeEach()
|
|
18
|
-
.then(() => fs.writeFileSync(gulpConfig.get('srcPath') + '/greet.mjs', rawContents)))
|
|
19
|
-
|
|
20
|
-
afterEach(setUp.afterEach)
|
|
21
|
-
|
|
22
|
-
describe('convertMjsFilesForDocs', () => {
|
|
23
|
-
test('returns an empty result, with a safe no-op cleanUp, for an empty list', () => {
|
|
24
|
-
const { filePaths, cleanUp } = convertMjsFilesForDocs([])
|
|
25
|
-
expect(filePaths).toEqual([])
|
|
26
|
-
expect(() => cleanUp()).not.toThrow()
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
test('writes a rewritten, doc-parseable .js copy outside the project tree', () => {
|
|
30
|
-
const mjsFilePath = gulpConfig.get('srcPath') + '/greet.mjs'
|
|
31
|
-
const { filePaths, cleanUp } = convertMjsFilesForDocs([mjsFilePath])
|
|
32
|
-
|
|
33
|
-
expect(filePaths).toHaveLength(1)
|
|
34
|
-
expect(filePaths[0]).toMatch(/greet\.js$/)
|
|
35
|
-
expect(filePaths[0]).not.toContain(process.cwd())
|
|
36
|
-
|
|
37
|
-
const converted = fs.readFileSync(filePaths[0], 'utf8')
|
|
38
|
-
expect(converted).toContain('const sayHello = name => `Hello from ${name}`')
|
|
39
|
-
expect(converted).toContain('module.exports = { sayHello }')
|
|
40
|
-
|
|
41
|
-
cleanUp()
|
|
42
|
-
expect(fs.existsSync(filePaths[0])).toBe(false)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
test('converts several files into the same temp directory', () => {
|
|
46
|
-
fs.writeFileSync(gulpConfig.get('srcPath') + '/greetAgain.mjs', rawContents.replace('sayHello', 'sayHelloAgain'))
|
|
47
|
-
const { filePaths, cleanUp } = convertMjsFilesForDocs([
|
|
48
|
-
gulpConfig.get('srcPath') + '/greet.mjs',
|
|
49
|
-
gulpConfig.get('srcPath') + '/greetAgain.mjs'
|
|
50
|
-
])
|
|
51
|
-
|
|
52
|
-
expect(filePaths).toHaveLength(2)
|
|
53
|
-
filePaths.forEach(filePath => expect(fs.existsSync(filePath)).toBe(true))
|
|
54
|
-
|
|
55
|
-
cleanUp()
|
|
56
|
-
filePaths.forEach(filePath => expect(fs.existsSync(filePath)).toBe(false))
|
|
57
|
-
})
|
|
58
|
-
})
|
|
1
|
+
/* eslint-disable no-template-curly-in-string -- fixture source code, the ${...} is meant to stay literal */
|
|
2
|
+
import fs from 'fs'
|
|
3
|
+
import * as setUp from '../test-helpers/setUp.mjs'
|
|
4
|
+
import { convertMjsFilesForDocs } from './convertMjsFilesForDocs.mjs'
|
|
5
|
+
|
|
6
|
+
setUp.setDefaults('test-temp-convert-mjs-for-docs')
|
|
7
|
+
const gulpConfig = setUp.gulpConfig
|
|
8
|
+
|
|
9
|
+
const rawContents = '/**\n' +
|
|
10
|
+
' * Say hello with a given name.\n' +
|
|
11
|
+
' * @memberOf module:greet\n' +
|
|
12
|
+
' * @param {string} name\n' +
|
|
13
|
+
' * @returns {string}\n' +
|
|
14
|
+
' */\n' +
|
|
15
|
+
'export const sayHello = name => `Hello from ${name}`\n'
|
|
16
|
+
|
|
17
|
+
beforeEach(() => setUp.beforeEach()
|
|
18
|
+
.then(() => fs.writeFileSync(gulpConfig.get('srcPath') + '/greet.mjs', rawContents)))
|
|
19
|
+
|
|
20
|
+
afterEach(setUp.afterEach)
|
|
21
|
+
|
|
22
|
+
describe('convertMjsFilesForDocs', () => {
|
|
23
|
+
test('returns an empty result, with a safe no-op cleanUp, for an empty list', () => {
|
|
24
|
+
const { filePaths, cleanUp } = convertMjsFilesForDocs([])
|
|
25
|
+
expect(filePaths).toEqual([])
|
|
26
|
+
expect(() => cleanUp()).not.toThrow()
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test('writes a rewritten, doc-parseable .js copy outside the project tree', () => {
|
|
30
|
+
const mjsFilePath = gulpConfig.get('srcPath') + '/greet.mjs'
|
|
31
|
+
const { filePaths, cleanUp } = convertMjsFilesForDocs([mjsFilePath])
|
|
32
|
+
|
|
33
|
+
expect(filePaths).toHaveLength(1)
|
|
34
|
+
expect(filePaths[0]).toMatch(/greet\.js$/)
|
|
35
|
+
expect(filePaths[0]).not.toContain(process.cwd())
|
|
36
|
+
|
|
37
|
+
const converted = fs.readFileSync(filePaths[0], 'utf8')
|
|
38
|
+
expect(converted).toContain('const sayHello = name => `Hello from ${name}`')
|
|
39
|
+
expect(converted).toContain('module.exports = { sayHello }')
|
|
40
|
+
|
|
41
|
+
cleanUp()
|
|
42
|
+
expect(fs.existsSync(filePaths[0])).toBe(false)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
test('converts several files into the same temp directory', () => {
|
|
46
|
+
fs.writeFileSync(gulpConfig.get('srcPath') + '/greetAgain.mjs', rawContents.replace('sayHello', 'sayHelloAgain'))
|
|
47
|
+
const { filePaths, cleanUp } = convertMjsFilesForDocs([
|
|
48
|
+
gulpConfig.get('srcPath') + '/greet.mjs',
|
|
49
|
+
gulpConfig.get('srcPath') + '/greetAgain.mjs'
|
|
50
|
+
])
|
|
51
|
+
|
|
52
|
+
expect(filePaths).toHaveLength(2)
|
|
53
|
+
filePaths.forEach(filePath => expect(fs.existsSync(filePath)).toBe(true))
|
|
54
|
+
|
|
55
|
+
cleanUp()
|
|
56
|
+
filePaths.forEach(filePath => expect(fs.existsSync(filePath)).toBe(false))
|
|
57
|
+
})
|
|
58
|
+
})
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
import { isObject } from './isObject.mjs'
|
|
2
|
-
import { strAfter } from './strAfter.mjs'
|
|
3
|
-
import { strBefore } from './strBefore.mjs'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Get a nested property value from an object.
|
|
7
|
-
* Original source concepts from {@link https://github.com/jheagle/si-funciona/blob/main/src/helpers/objects/dotGet.ts Sí, funciona}
|
|
8
|
-
* @param {Object} [arrayObject={}] - The array or object to get the property from
|
|
9
|
-
* @param {string} [dotNotation=''] - The path to the property
|
|
10
|
-
* @param {string|null} [defaultValue=null] - The default value to return if the property is not found
|
|
11
|
-
* @returns {*} The value of the property
|
|
12
|
-
* @private
|
|
13
|
-
*/
|
|
14
|
-
export const dotGet = (arrayObject = {}, dotNotation = '', defaultValue = null) => {
|
|
15
|
-
if (!dotNotation) {
|
|
16
|
-
return arrayObject
|
|
17
|
-
}
|
|
18
|
-
let key = strBefore(dotNotation, '.')
|
|
19
|
-
const lastKey = !key
|
|
20
|
-
if (lastKey) {
|
|
21
|
-
key = dotNotation
|
|
22
|
-
}
|
|
23
|
-
if (key === '*') {
|
|
24
|
-
const result = []
|
|
25
|
-
for (const wildKey in arrayObject) {
|
|
26
|
-
const wildValue = arrayObject[wildKey]
|
|
27
|
-
if (lastKey) {
|
|
28
|
-
result[wildKey] = wildValue
|
|
29
|
-
continue
|
|
30
|
-
}
|
|
31
|
-
if (!isObject(wildValue)) {
|
|
32
|
-
continue
|
|
33
|
-
}
|
|
34
|
-
result[wildKey] = dotGet(wildValue, strAfter(dotNotation, '.'), defaultValue)
|
|
35
|
-
}
|
|
36
|
-
return result
|
|
37
|
-
}
|
|
38
|
-
if (lastKey) {
|
|
39
|
-
return arrayObject[dotNotation] ?? defaultValue
|
|
40
|
-
}
|
|
41
|
-
if (typeof arrayObject[key] === 'undefined') {
|
|
42
|
-
return defaultValue
|
|
43
|
-
}
|
|
44
|
-
const next = arrayObject[key]
|
|
45
|
-
if (!isObject(next)) {
|
|
46
|
-
return defaultValue
|
|
47
|
-
}
|
|
48
|
-
return dotGet(next, strAfter(dotNotation, '.'), defaultValue)
|
|
49
|
-
}
|
|
1
|
+
import { isObject } from './isObject.mjs'
|
|
2
|
+
import { strAfter } from './strAfter.mjs'
|
|
3
|
+
import { strBefore } from './strBefore.mjs'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Get a nested property value from an object.
|
|
7
|
+
* Original source concepts from {@link https://github.com/jheagle/si-funciona/blob/main/src/helpers/objects/dotGet.ts Sí, funciona}
|
|
8
|
+
* @param {Object} [arrayObject={}] - The array or object to get the property from
|
|
9
|
+
* @param {string} [dotNotation=''] - The path to the property
|
|
10
|
+
* @param {string|null} [defaultValue=null] - The default value to return if the property is not found
|
|
11
|
+
* @returns {*} The value of the property
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
14
|
+
export const dotGet = (arrayObject = {}, dotNotation = '', defaultValue = null) => {
|
|
15
|
+
if (!dotNotation) {
|
|
16
|
+
return arrayObject
|
|
17
|
+
}
|
|
18
|
+
let key = strBefore(dotNotation, '.')
|
|
19
|
+
const lastKey = !key
|
|
20
|
+
if (lastKey) {
|
|
21
|
+
key = dotNotation
|
|
22
|
+
}
|
|
23
|
+
if (key === '*') {
|
|
24
|
+
const result = []
|
|
25
|
+
for (const wildKey in arrayObject) {
|
|
26
|
+
const wildValue = arrayObject[wildKey]
|
|
27
|
+
if (lastKey) {
|
|
28
|
+
result[wildKey] = wildValue
|
|
29
|
+
continue
|
|
30
|
+
}
|
|
31
|
+
if (!isObject(wildValue)) {
|
|
32
|
+
continue
|
|
33
|
+
}
|
|
34
|
+
result[wildKey] = dotGet(wildValue, strAfter(dotNotation, '.'), defaultValue)
|
|
35
|
+
}
|
|
36
|
+
return result
|
|
37
|
+
}
|
|
38
|
+
if (lastKey) {
|
|
39
|
+
return arrayObject[dotNotation] ?? defaultValue
|
|
40
|
+
}
|
|
41
|
+
if (typeof arrayObject[key] === 'undefined') {
|
|
42
|
+
return defaultValue
|
|
43
|
+
}
|
|
44
|
+
const next = arrayObject[key]
|
|
45
|
+
if (!isObject(next)) {
|
|
46
|
+
return defaultValue
|
|
47
|
+
}
|
|
48
|
+
return dotGet(next, strAfter(dotNotation, '.'), defaultValue)
|
|
49
|
+
}
|
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
import { isObject } from './isObject.mjs'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Convert an array of keys into a regex, return a function to test if incoming keys match.
|
|
5
|
-
* @param {Array.<string>} [retainObjects=[]] - An array of keys to retain as objects
|
|
6
|
-
* @returns {Function} The dot-notated array
|
|
7
|
-
* @private
|
|
8
|
-
*/
|
|
9
|
-
const handleRetainObjects = (retainObjects = []) => {
|
|
10
|
-
if (!retainObjects.length) {
|
|
11
|
-
/**
|
|
12
|
-
* Bypass the test function if there are no retainObjects.
|
|
13
|
-
* @returns {false}
|
|
14
|
-
* @private
|
|
15
|
-
*/
|
|
16
|
-
return (currentKey, value, results) => false
|
|
17
|
-
}
|
|
18
|
-
retainObjects = retainObjects.map(key => key.replaceAll('.', '\\.'))
|
|
19
|
-
const retainRegex = new RegExp(`(${retainObjects.join('|')})$`)
|
|
20
|
-
/**
|
|
21
|
-
* Test if a key should be retained as an object.
|
|
22
|
-
* @param {string} currentKey - The key to test
|
|
23
|
-
* @param {*} value - The value of the key
|
|
24
|
-
* @param {Object} results - The result object to add to
|
|
25
|
-
* @returns {boolean}
|
|
26
|
-
* @private
|
|
27
|
-
*/
|
|
28
|
-
return (currentKey, value, results) => {
|
|
29
|
-
if (!currentKey.match(retainRegex)) {
|
|
30
|
-
return false
|
|
31
|
-
}
|
|
32
|
-
results[currentKey] = value
|
|
33
|
-
return true
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* The underlying logic function for converting arrays to dot-notation.
|
|
39
|
-
* @param {Object} arrayObject - The array or object to dot-notate
|
|
40
|
-
* @param {Function} didRetain - The test function to see if a key should be retained
|
|
41
|
-
* @param {string} [prepend=''] - The path for the property being processed
|
|
42
|
-
* @param {Object<string, *>} [results={}] - The final notated object to return
|
|
43
|
-
* @returns {Object<string, *>} The dot-notated object
|
|
44
|
-
* @private
|
|
45
|
-
*/
|
|
46
|
-
const performDotNotate = (arrayObject, didRetain, prepend = '', results = {}) => {
|
|
47
|
-
for (const key in arrayObject) {
|
|
48
|
-
const value = arrayObject[key]
|
|
49
|
-
const currentKey = `${prepend}${key}`
|
|
50
|
-
if (didRetain(currentKey, value, results)) {
|
|
51
|
-
continue
|
|
52
|
-
}
|
|
53
|
-
// An empty object/array has no keys to flatten into - recursing into one would silently drop currentKey
|
|
54
|
-
// from the result entirely, rather than keeping it as the empty value it actually is. Treat it as a leaf.
|
|
55
|
-
if (isObject(value) && Object.keys(value).length) {
|
|
56
|
-
performDotNotate(value, didRetain, `${currentKey}.`, results)
|
|
57
|
-
continue
|
|
58
|
-
}
|
|
59
|
-
results[currentKey] = value
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
return results
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Convert an array or object to a single dimensional associative array with dot notation.
|
|
67
|
-
* Original source concepts from {@link https://github.com/jheagle/si-funciona/blob/main/src/helpers/objects/dotNotate.ts Sí, funciona}
|
|
68
|
-
* @param {Object} arrayObject - The array or object to dot-notate
|
|
69
|
-
* @param {Array.<string>} [retainObjects=[]] - An array of keys to retain as objects
|
|
70
|
-
* @returns {Object<string, *>} The dot-notated object
|
|
71
|
-
* @private
|
|
72
|
-
*/
|
|
73
|
-
export const dotNotate = (arrayObject, retainObjects = []) => performDotNotate(arrayObject, handleRetainObjects(retainObjects))
|
|
1
|
+
import { isObject } from './isObject.mjs'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Convert an array of keys into a regex, return a function to test if incoming keys match.
|
|
5
|
+
* @param {Array.<string>} [retainObjects=[]] - An array of keys to retain as objects
|
|
6
|
+
* @returns {Function} The dot-notated array
|
|
7
|
+
* @private
|
|
8
|
+
*/
|
|
9
|
+
const handleRetainObjects = (retainObjects = []) => {
|
|
10
|
+
if (!retainObjects.length) {
|
|
11
|
+
/**
|
|
12
|
+
* Bypass the test function if there are no retainObjects.
|
|
13
|
+
* @returns {false}
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
return (currentKey, value, results) => false
|
|
17
|
+
}
|
|
18
|
+
retainObjects = retainObjects.map(key => key.replaceAll('.', '\\.'))
|
|
19
|
+
const retainRegex = new RegExp(`(${retainObjects.join('|')})$`)
|
|
20
|
+
/**
|
|
21
|
+
* Test if a key should be retained as an object.
|
|
22
|
+
* @param {string} currentKey - The key to test
|
|
23
|
+
* @param {*} value - The value of the key
|
|
24
|
+
* @param {Object} results - The result object to add to
|
|
25
|
+
* @returns {boolean}
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
return (currentKey, value, results) => {
|
|
29
|
+
if (!currentKey.match(retainRegex)) {
|
|
30
|
+
return false
|
|
31
|
+
}
|
|
32
|
+
results[currentKey] = value
|
|
33
|
+
return true
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The underlying logic function for converting arrays to dot-notation.
|
|
39
|
+
* @param {Object} arrayObject - The array or object to dot-notate
|
|
40
|
+
* @param {Function} didRetain - The test function to see if a key should be retained
|
|
41
|
+
* @param {string} [prepend=''] - The path for the property being processed
|
|
42
|
+
* @param {Object<string, *>} [results={}] - The final notated object to return
|
|
43
|
+
* @returns {Object<string, *>} The dot-notated object
|
|
44
|
+
* @private
|
|
45
|
+
*/
|
|
46
|
+
const performDotNotate = (arrayObject, didRetain, prepend = '', results = {}) => {
|
|
47
|
+
for (const key in arrayObject) {
|
|
48
|
+
const value = arrayObject[key]
|
|
49
|
+
const currentKey = `${prepend}${key}`
|
|
50
|
+
if (didRetain(currentKey, value, results)) {
|
|
51
|
+
continue
|
|
52
|
+
}
|
|
53
|
+
// An empty object/array has no keys to flatten into - recursing into one would silently drop currentKey
|
|
54
|
+
// from the result entirely, rather than keeping it as the empty value it actually is. Treat it as a leaf.
|
|
55
|
+
if (isObject(value) && Object.keys(value).length) {
|
|
56
|
+
performDotNotate(value, didRetain, `${currentKey}.`, results)
|
|
57
|
+
continue
|
|
58
|
+
}
|
|
59
|
+
results[currentKey] = value
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return results
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Convert an array or object to a single dimensional associative array with dot notation.
|
|
67
|
+
* Original source concepts from {@link https://github.com/jheagle/si-funciona/blob/main/src/helpers/objects/dotNotate.ts Sí, funciona}
|
|
68
|
+
* @param {Object} arrayObject - The array or object to dot-notate
|
|
69
|
+
* @param {Array.<string>} [retainObjects=[]] - An array of keys to retain as objects
|
|
70
|
+
* @returns {Object<string, *>} The dot-notated object
|
|
71
|
+
* @private
|
|
72
|
+
*/
|
|
73
|
+
export const dotNotate = (arrayObject, retainObjects = []) => performDotNotate(arrayObject, handleRetainObjects(retainObjects))
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import { dotNotate } from './dotNotate.mjs'
|
|
2
|
-
|
|
3
|
-
describe('dotNotate', () => {
|
|
4
|
-
test('flattens a nested object into dot-notation leaves', () => {
|
|
5
|
-
expect(dotNotate({ a: { b: 'c', d: { e: 'f' } } })).toEqual({ 'a.b': 'c', 'a.d.e': 'f' })
|
|
6
|
-
})
|
|
7
|
-
|
|
8
|
-
test('flattens a non-empty array into index-numbered leaves, same as a plain object', () => {
|
|
9
|
-
expect(dotNotate({ a: ['x', 'y'] })).toEqual({ 'a.0': 'x', 'a.1': 'y' })
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
test('keeps a primitive value (including null) as its own leaf, unflattened', () => {
|
|
13
|
-
expect(dotNotate({ a: 1, b: 'two', c: null })).toEqual({ a: 1, b: 'two', c: null })
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
test('keeps an empty object as a leaf value, rather than silently dropping its key', () => {
|
|
17
|
-
expect(dotNotate({ a: {}, b: 'c' })).toEqual({ a: {}, b: 'c' })
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
test('keeps an empty array as a leaf value, rather than silently dropping its key', () => {
|
|
21
|
-
expect(dotNotate({ a: [], b: 'c' })).toEqual({ a: [], b: 'c' })
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
test('keeps an empty object/array as a leaf even nested inside other objects', () => {
|
|
25
|
-
expect(dotNotate({ a: { b: [], c: {} } })).toEqual({ 'a.b': [], 'a.c': {} })
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
test('retains a matching key as a whole object instead of flattening into it', () => {
|
|
29
|
-
expect(dotNotate({ a: { b: 'c' }, options: { fix: true } }, ['options'])).toEqual({
|
|
30
|
-
'a.b': 'c',
|
|
31
|
-
options: { fix: true }
|
|
32
|
-
})
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
test('treats every dot in a retained key literally, not as a regex wildcard', () => {
|
|
36
|
-
expect(dotNotate({ a: { bXc: { d: 1 }, b: { c: { d: 2 } } } }, ['a.b.c'])).toEqual({
|
|
37
|
-
'a.bXc.d': 1,
|
|
38
|
-
'a.b.c': { d: 2 }
|
|
39
|
-
})
|
|
40
|
-
})
|
|
41
|
-
})
|
|
1
|
+
import { dotNotate } from './dotNotate.mjs'
|
|
2
|
+
|
|
3
|
+
describe('dotNotate', () => {
|
|
4
|
+
test('flattens a nested object into dot-notation leaves', () => {
|
|
5
|
+
expect(dotNotate({ a: { b: 'c', d: { e: 'f' } } })).toEqual({ 'a.b': 'c', 'a.d.e': 'f' })
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
test('flattens a non-empty array into index-numbered leaves, same as a plain object', () => {
|
|
9
|
+
expect(dotNotate({ a: ['x', 'y'] })).toEqual({ 'a.0': 'x', 'a.1': 'y' })
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
test('keeps a primitive value (including null) as its own leaf, unflattened', () => {
|
|
13
|
+
expect(dotNotate({ a: 1, b: 'two', c: null })).toEqual({ a: 1, b: 'two', c: null })
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('keeps an empty object as a leaf value, rather than silently dropping its key', () => {
|
|
17
|
+
expect(dotNotate({ a: {}, b: 'c' })).toEqual({ a: {}, b: 'c' })
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test('keeps an empty array as a leaf value, rather than silently dropping its key', () => {
|
|
21
|
+
expect(dotNotate({ a: [], b: 'c' })).toEqual({ a: [], b: 'c' })
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('keeps an empty object/array as a leaf even nested inside other objects', () => {
|
|
25
|
+
expect(dotNotate({ a: { b: [], c: {} } })).toEqual({ 'a.b': [], 'a.c': {} })
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test('retains a matching key as a whole object instead of flattening into it', () => {
|
|
29
|
+
expect(dotNotate({ a: { b: 'c' }, options: { fix: true } }, ['options'])).toEqual({
|
|
30
|
+
'a.b': 'c',
|
|
31
|
+
options: { fix: true }
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
test('treats every dot in a retained key literally, not as a regex wildcard', () => {
|
|
36
|
+
expect(dotNotate({ a: { bXc: { d: 1 }, b: { c: { d: 2 } } } }, ['a.b.c'])).toEqual({
|
|
37
|
+
'a.bXc.d': 1,
|
|
38
|
+
'a.b.c': { d: 2 }
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
})
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import { isObject } from './isObject.mjs'
|
|
2
|
-
import { strAfter } from './strAfter.mjs'
|
|
3
|
-
import { strBefore } from './strBefore.mjs'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Set a nested property value an object.
|
|
7
|
-
* Original source concepts from {@link https://github.com/jheagle/si-funciona/blob/main/src/helpers/objects/dotSet.ts Sí, funciona}
|
|
8
|
-
* @param {Object} arrayObject - The array or object to set the property on
|
|
9
|
-
* @param {string} dotNotation - The path for the property
|
|
10
|
-
* @param {*} value - The default value to return if the property is not found
|
|
11
|
-
* @returns {Object} The modified object
|
|
12
|
-
* @private
|
|
13
|
-
*/
|
|
14
|
-
export const dotSet = (arrayObject, dotNotation, value = null) => {
|
|
15
|
-
let key = strBefore(dotNotation, '.')
|
|
16
|
-
const lastKey = !key
|
|
17
|
-
if (lastKey) {
|
|
18
|
-
key = dotNotation
|
|
19
|
-
}
|
|
20
|
-
if (key === '*') {
|
|
21
|
-
for (const wildKey in arrayObject) {
|
|
22
|
-
if (lastKey) {
|
|
23
|
-
arrayObject[wildKey] = value
|
|
24
|
-
continue
|
|
25
|
-
}
|
|
26
|
-
if (!isObject(arrayObject[wildKey])) {
|
|
27
|
-
continue
|
|
28
|
-
}
|
|
29
|
-
dotSet(arrayObject[wildKey], strAfter(dotNotation, '.'), value)
|
|
30
|
-
}
|
|
31
|
-
return arrayObject
|
|
32
|
-
}
|
|
33
|
-
if (lastKey) {
|
|
34
|
-
arrayObject[dotNotation] = value
|
|
35
|
-
return arrayObject
|
|
36
|
-
}
|
|
37
|
-
const next = arrayObject[key] ?? []
|
|
38
|
-
arrayObject[key] = dotSet(next, strAfter(dotNotation, '.'), value)
|
|
39
|
-
return arrayObject
|
|
40
|
-
}
|
|
1
|
+
import { isObject } from './isObject.mjs'
|
|
2
|
+
import { strAfter } from './strAfter.mjs'
|
|
3
|
+
import { strBefore } from './strBefore.mjs'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Set a nested property value an object.
|
|
7
|
+
* Original source concepts from {@link https://github.com/jheagle/si-funciona/blob/main/src/helpers/objects/dotSet.ts Sí, funciona}
|
|
8
|
+
* @param {Object} arrayObject - The array or object to set the property on
|
|
9
|
+
* @param {string} dotNotation - The path for the property
|
|
10
|
+
* @param {*} value - The default value to return if the property is not found
|
|
11
|
+
* @returns {Object} The modified object
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
14
|
+
export const dotSet = (arrayObject, dotNotation, value = null) => {
|
|
15
|
+
let key = strBefore(dotNotation, '.')
|
|
16
|
+
const lastKey = !key
|
|
17
|
+
if (lastKey) {
|
|
18
|
+
key = dotNotation
|
|
19
|
+
}
|
|
20
|
+
if (key === '*') {
|
|
21
|
+
for (const wildKey in arrayObject) {
|
|
22
|
+
if (lastKey) {
|
|
23
|
+
arrayObject[wildKey] = value
|
|
24
|
+
continue
|
|
25
|
+
}
|
|
26
|
+
if (!isObject(arrayObject[wildKey])) {
|
|
27
|
+
continue
|
|
28
|
+
}
|
|
29
|
+
dotSet(arrayObject[wildKey], strAfter(dotNotation, '.'), value)
|
|
30
|
+
}
|
|
31
|
+
return arrayObject
|
|
32
|
+
}
|
|
33
|
+
if (lastKey) {
|
|
34
|
+
arrayObject[dotNotation] = value
|
|
35
|
+
return arrayObject
|
|
36
|
+
}
|
|
37
|
+
const next = arrayObject[key] ?? []
|
|
38
|
+
arrayObject[key] = dotSet(next, strAfter(dotNotation, '.'), value)
|
|
39
|
+
return arrayObject
|
|
40
|
+
}
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Rewrites named `export const`/`export function`/`export class` declarations to plain declarations plus a
|
|
3
|
-
* trailing `module.exports = { ... }` - the same shape jsdoc-to-markdown already documents cleanly (a plain
|
|
4
|
-
* declaration with its own `@memberOf` tag, exported all at once at the bottom), rather than the "exports.name"
|
|
5
|
-
* longname jsdoc-to-markdown's own ESM-compat layer produces for an inline `export const name = ...`.
|
|
6
|
-
*
|
|
7
|
-
* This is a narrow, text-level rewrite for documentation purposes only - it does not execute the module, so it
|
|
8
|
-
* only has to look enough like the real thing for jsdoc-to-markdown's parser. It handles the common named-export
|
|
9
|
-
* forms (`export const`, `export function`, `export class`) and leaves everything else (including `export
|
|
10
|
-
* default`, re-exports, and `export { a, b }` lists) untouched in place - a file using one of those keeps its
|
|
11
|
-
* own export line as-is, which jsdoc-to-markdown will document however it already does for ESM.
|
|
12
|
-
* @memberOf module:utilities
|
|
13
|
-
* @param {string} source - The raw ESM source text (never executed, just rewritten as text).
|
|
14
|
-
* @returns {string} The rewritten text, safe to write out with a `.js` extension for jsdoc-to-markdown to read.
|
|
15
|
-
* @private
|
|
16
|
-
*/
|
|
17
|
-
export const esmNamedExportsToCjs = (source) => {
|
|
18
|
-
const exportedNames = []
|
|
19
|
-
const rewritten = source.replace(
|
|
20
|
-
/^export (const|function|class) (\w+)/gm,
|
|
21
|
-
(match, keyword, name) => {
|
|
22
|
-
exportedNames.push(name)
|
|
23
|
-
return `${keyword} ${name}`
|
|
24
|
-
}
|
|
25
|
-
)
|
|
26
|
-
if (exportedNames.length === 0) {
|
|
27
|
-
return rewritten
|
|
28
|
-
}
|
|
29
|
-
return `${rewritten}\n\nmodule.exports = { ${exportedNames.join(', ')} }\n`
|
|
30
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Rewrites named `export const`/`export function`/`export class` declarations to plain declarations plus a
|
|
3
|
+
* trailing `module.exports = { ... }` - the same shape jsdoc-to-markdown already documents cleanly (a plain
|
|
4
|
+
* declaration with its own `@memberOf` tag, exported all at once at the bottom), rather than the "exports.name"
|
|
5
|
+
* longname jsdoc-to-markdown's own ESM-compat layer produces for an inline `export const name = ...`.
|
|
6
|
+
*
|
|
7
|
+
* This is a narrow, text-level rewrite for documentation purposes only - it does not execute the module, so it
|
|
8
|
+
* only has to look enough like the real thing for jsdoc-to-markdown's parser. It handles the common named-export
|
|
9
|
+
* forms (`export const`, `export function`, `export class`) and leaves everything else (including `export
|
|
10
|
+
* default`, re-exports, and `export { a, b }` lists) untouched in place - a file using one of those keeps its
|
|
11
|
+
* own export line as-is, which jsdoc-to-markdown will document however it already does for ESM.
|
|
12
|
+
* @memberOf module:utilities
|
|
13
|
+
* @param {string} source - The raw ESM source text (never executed, just rewritten as text).
|
|
14
|
+
* @returns {string} The rewritten text, safe to write out with a `.js` extension for jsdoc-to-markdown to read.
|
|
15
|
+
* @private
|
|
16
|
+
*/
|
|
17
|
+
export const esmNamedExportsToCjs = (source) => {
|
|
18
|
+
const exportedNames = []
|
|
19
|
+
const rewritten = source.replace(
|
|
20
|
+
/^export (const|function|class) (\w+)/gm,
|
|
21
|
+
(match, keyword, name) => {
|
|
22
|
+
exportedNames.push(name)
|
|
23
|
+
return `${keyword} ${name}`
|
|
24
|
+
}
|
|
25
|
+
)
|
|
26
|
+
if (exportedNames.length === 0) {
|
|
27
|
+
return rewritten
|
|
28
|
+
}
|
|
29
|
+
return `${rewritten}\n\nmodule.exports = { ${exportedNames.join(', ')} }\n`
|
|
30
|
+
}
|