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.
Files changed (169) hide show
  1. package/LICENSE +674 -674
  2. package/README.md +762 -701
  3. package/babel.config.js +28 -28
  4. package/dist/build.js +75 -75
  5. package/dist/bundle.js +19 -19
  6. package/dist/bundleMinify.js +7 -7
  7. package/dist/compileReadme.js +4 -4
  8. package/dist/copyFiles.js +17 -17
  9. package/dist/copyFonts.js +4 -4
  10. package/dist/default.js +5 -5
  11. package/dist/dist.js +4 -4
  12. package/dist/distMinify.js +4 -4
  13. package/dist/docs.js +7 -7
  14. package/dist/images.js +4 -4
  15. package/dist/jsdocDocs.js +6 -6
  16. package/dist/lint.js +16 -16
  17. package/dist/partials/addToReadme.js +9 -9
  18. package/dist/partials/beginWatcher.js +4 -4
  19. package/dist/partials/clean.js +5 -5
  20. package/dist/partials/copyFor.js +9 -9
  21. package/dist/partials/distFor.js +6 -6
  22. package/dist/partials/distForSrc.js +5 -5
  23. package/dist/partials/distSeries.js +7 -7
  24. package/dist/partials/imagesFor.js +93 -93
  25. package/dist/partials/jsdocDocsFor.js +46 -46
  26. package/dist/partials/lintSource.js +51 -51
  27. package/dist/partials/loadPeer.js +99 -99
  28. package/dist/partials/loadPlaywright.js +14 -14
  29. package/dist/partials/minifyFor.js +20 -20
  30. package/dist/partials/neostandardLint.js +175 -175
  31. package/dist/partials/readmeTemplate.js +4 -4
  32. package/dist/partials/removeDirectory.js +11 -11
  33. package/dist/partials/resolveDocsMethod.js +6 -6
  34. package/dist/partials/runOnChange.js +31 -31
  35. package/dist/partials/sassFor.js +6 -6
  36. package/dist/partials/serveStatic.js +9 -9
  37. package/dist/partials/tsFor.js +32 -32
  38. package/dist/partials/typeDocsFor.js +264 -264
  39. package/dist/partials.js +176 -176
  40. package/dist/sourceLint.js +18 -18
  41. package/dist/test-helpers/isolateGulpCache.js +24 -24
  42. package/dist/test-helpers/setUp.js +4 -4
  43. package/dist/testFull.js +5 -5
  44. package/dist/testQuick.js +5 -5
  45. package/dist/typeDocs.js +5 -5
  46. package/dist/typeScript.js +4 -4
  47. package/dist/utilities/convertMjsFilesForDocs.js +12 -12
  48. package/dist/utilities/dotGet.js +54 -54
  49. package/dist/utilities/dotNotate.js +79 -79
  50. package/dist/utilities/dotSet.js +45 -45
  51. package/dist/utilities/esmNamedExportsToCjs.js +15 -15
  52. package/dist/utilities/getBundleConfigs.js +9 -9
  53. package/dist/utilities/isObject.js +6 -6
  54. package/dist/utilities/strAfter.js +7 -7
  55. package/dist/utilities/strBefore.js +7 -7
  56. package/dist/watchFull.js +4 -4
  57. package/dist/watchTest.js +4 -4
  58. package/functions/build.mjs +72 -72
  59. package/functions/build.test.mjs +763 -759
  60. package/functions/bundle.mjs +44 -44
  61. package/functions/bundle.test.mjs +219 -219
  62. package/functions/bundleMinify.mjs +16 -16
  63. package/functions/bundleMinify.test.mjs +37 -37
  64. package/functions/compileReadme.mjs +9 -9
  65. package/functions/compileReadme.test.mjs +18 -18
  66. package/functions/copyFiles.mjs +32 -32
  67. package/functions/copyFiles.test.mjs +78 -78
  68. package/functions/copyFonts.mjs +9 -9
  69. package/functions/copyFonts.test.mjs +32 -32
  70. package/functions/default.mjs +12 -12
  71. package/functions/default.test.mjs +33 -33
  72. package/functions/dist.mjs +8 -8
  73. package/functions/dist.test.mjs +44 -44
  74. package/functions/distMinify.mjs +9 -9
  75. package/functions/distMinify.test.mjs +15 -15
  76. package/functions/docs.mjs +13 -13
  77. package/functions/docs.test.mjs +45 -45
  78. package/functions/gulpConfigEntries.test.mjs +23 -23
  79. package/functions/images.mjs +8 -8
  80. package/functions/images.test.mjs +142 -142
  81. package/functions/jsdocDocs.mjs +10 -10
  82. package/functions/jsdocEsmExports.test.mjs +24 -24
  83. package/functions/lint.mjs +9 -9
  84. package/functions/partials/addToReadme.mjs +25 -25
  85. package/functions/partials/addToReadme.test.mjs +34 -34
  86. package/functions/partials/beginWatcher.mjs +9 -9
  87. package/functions/partials/beginWatcher.test.mjs +19 -19
  88. package/functions/partials/clean.mjs +13 -13
  89. package/functions/partials/clean.test.mjs +22 -22
  90. package/functions/partials/copyFor.mjs +15 -15
  91. package/functions/partials/copyFor.test.mjs +53 -53
  92. package/functions/partials/distFor.mjs +22 -22
  93. package/functions/partials/distFor.test.mjs +195 -195
  94. package/functions/partials/distForSrc.mjs +11 -11
  95. package/functions/partials/distForSrc.test.mjs +18 -18
  96. package/functions/partials/distSeries.mjs +21 -21
  97. package/functions/partials/distSeries.test.mjs +34 -34
  98. package/functions/partials/imagesFor.mjs +83 -83
  99. package/functions/partials/imagesFor.test.mjs +287 -287
  100. package/functions/partials/jsdocDocsFor.mjs +163 -152
  101. package/functions/partials/jsdocDocsFor.test.mjs +182 -152
  102. package/functions/partials/lintSource.mjs +41 -41
  103. package/functions/partials/loadPeer.mjs +76 -76
  104. package/functions/partials/loadPeer.test.mjs +58 -58
  105. package/functions/partials/loadPlaywright.mjs +23 -23
  106. package/functions/partials/loadPlaywright.test.mjs +70 -70
  107. package/functions/partials/minifyFor.mjs +15 -15
  108. package/functions/partials/minifyFor.test.mjs +49 -49
  109. package/functions/partials/neostandardLint.mjs +142 -142
  110. package/functions/partials/neostandardLint.test.mjs +131 -131
  111. package/functions/partials/readmeTemplate.mjs +12 -12
  112. package/functions/partials/readmeTemplate.test.mjs +34 -34
  113. package/functions/partials/removeDirectory.mjs +34 -34
  114. package/functions/partials/removeDirectory.test.mjs +72 -72
  115. package/functions/partials/resolveDocsMethod.mjs +10 -10
  116. package/functions/partials/resolveDocsMethod.test.mjs +33 -33
  117. package/functions/partials/runOnChange.mjs +54 -54
  118. package/functions/partials/runOnChange.test.mjs +95 -95
  119. package/functions/partials/sassFor.mjs +25 -25
  120. package/functions/partials/sassFor.test.mjs +81 -81
  121. package/functions/partials/serveStatic.mjs +47 -47
  122. package/functions/partials/serveStatic.test.mjs +71 -71
  123. package/functions/partials/tsFor.mjs +92 -92
  124. package/functions/partials/tsFor.test.mjs +88 -88
  125. package/functions/partials/typeDocsFor.mjs +231 -231
  126. package/functions/partials/typeDocsFor.test.mjs +263 -263
  127. package/functions/partials.mjs +31 -31
  128. package/functions/partials.test.mjs +7 -7
  129. package/functions/sass.mjs +4 -4
  130. package/functions/sass.test.mjs +31 -31
  131. package/functions/sourceLint.mjs +13 -13
  132. package/functions/sourceLint.test.mjs +166 -166
  133. package/functions/test-helpers/isolateGulpCache.mjs +16 -16
  134. package/functions/test-helpers/neostandardLintWithRealNeostandard.mjs +40 -40
  135. package/functions/test-helpers/setUp.mjs +100 -100
  136. package/functions/test-helpers/setUp.test.mjs +19 -19
  137. package/functions/testFull.mjs +17 -17
  138. package/functions/testFull.test.mjs +17 -17
  139. package/functions/testHelpers.mjs +10 -10
  140. package/functions/testHelpers.test.mjs +7 -7
  141. package/functions/testQuick.mjs +17 -17
  142. package/functions/testQuick.test.mjs +17 -17
  143. package/functions/typeDocs.mjs +9 -9
  144. package/functions/typeDocs.test.mjs +11 -11
  145. package/functions/typeScript.mjs +8 -8
  146. package/functions/typeScript.test.mjs +11 -11
  147. package/functions/utilities/convertMjsFilesForDocs.mjs +34 -34
  148. package/functions/utilities/convertMjsFilesForDocs.test.mjs +58 -58
  149. package/functions/utilities/dotGet.mjs +49 -49
  150. package/functions/utilities/dotNotate.mjs +73 -73
  151. package/functions/utilities/dotNotate.test.mjs +41 -41
  152. package/functions/utilities/dotSet.mjs +40 -40
  153. package/functions/utilities/esmNamedExportsToCjs.mjs +30 -30
  154. package/functions/utilities/esmNamedExportsToCjs.test.mjs +47 -47
  155. package/functions/utilities/getBundleConfigs.mjs +30 -30
  156. package/functions/utilities/isObject.mjs +8 -8
  157. package/functions/utilities/strAfter.mjs +12 -12
  158. package/functions/utilities/strBefore.mjs +12 -12
  159. package/functions/watchFull.mjs +9 -9
  160. package/functions/watchFull.test.mjs +41 -41
  161. package/functions/watchTest.mjs +10 -10
  162. package/functions/watchTest.test.mjs +49 -49
  163. package/gulp.config.js +4 -4
  164. package/gulp.config.mjs +344 -340
  165. package/gulpfile.base.js +51 -51
  166. package/gulpfile.base.mjs +29 -29
  167. package/jsdoc.base.js +16 -16
  168. package/jsdoc.esmExports.js +17 -17
  169. 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
+ }