From dd6f721bd9b51d6c9f1a2c03422183560f3cd51f Mon Sep 17 00:00:00 2001 From: Niklas Mollenhauer Date: Sun, 28 Sep 2025 19:47:35 +0200 Subject: [PATCH 1/7] Replace `isArray` with `Array.isArray` It is available since Node.js 0.10: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray#browser_compatibility The library just re-exports Array.isArray if it's available: https://github.com/isaacs/core-util-is/blob/b90f777c19e0ca1304c2e1c48949b61779d70f1b/lib/util.js#L25-L31 --- src/array.js | 3 +-- src/common.js | 3 +-- src/stringify.js | 8 ++++---- test/array.test.js | 4 ++-- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/array.js b/src/array.js index 17ee0d4..b6403e3 100644 --- a/src/array.js +++ b/src/array.js @@ -1,4 +1,3 @@ -const {isArray} = require('core-util-is') const {sort} = require('array-timsort') const { @@ -217,7 +216,7 @@ class CommentArray extends Array { items.forEach(item => { const prev = length - length += isArray(item) + length += Array.isArray(item) ? item.length : 1 diff --git a/src/common.js b/src/common.js index 8f886e2..505149c 100644 --- a/src/common.js +++ b/src/common.js @@ -1,6 +1,5 @@ const { isObject, - isArray, isString, isNumber } = require('core-util-is') @@ -168,7 +167,7 @@ module.exports = { // We assign non-property comments // if argument `keys` is not specified assign_non_prop_comments(target, source) - } else if (!isArray(keys)) { + } else if (!Array.isArray(keys)) { throw new TypeError('keys must be array or undefined') } else if (keys.length === 0) { // Or argument `keys` is an empty array diff --git a/src/stringify.js b/src/stringify.js index 80a35d7..b604ae9 100644 --- a/src/stringify.js +++ b/src/stringify.js @@ -1,5 +1,5 @@ const { - isArray, isObject, isFunction, isNumber, isString + isObject, isFunction, isNumber, isString } = require('core-util-is') const { @@ -198,7 +198,7 @@ const object_stringify = (value, gap) => { let after_comma = EMPTY let first = true - const keys = isArray(replacer) + const keys = Array.isArray(replacer) ? replacer : Object.keys(value) @@ -292,7 +292,7 @@ function stringify (key, holder, gap) { // If the type is 'object', we might be dealing with an object or an array or // null. case 'object': - return isArray(value) + return Array.isArray(value) ? array_stringify(value, gap) : object_stringify(value, gap) @@ -344,7 +344,7 @@ module.exports = (value, replacer_, space) => { } // vanilla `JSON.parse` allow invalid replacer - if (!isFunction(replacer_) && !isArray(replacer_)) { + if (!isFunction(replacer_) && !Array.isArray(replacer_)) { replacer_ = null } diff --git a/test/array.test.js b/test/array.test.js index 4754122..83a9a59 100644 --- a/test/array.test.js +++ b/test/array.test.js @@ -1,7 +1,7 @@ // eslint-disable-next-line import/no-unresolved const test = require('ava') const { - isFunction, isObject, isString, isArray + isFunction, isObject, isString } = require('core-util-is') const { parse, stringify, assign, CommentArray @@ -315,7 +315,7 @@ CASES.forEach(([d, a, run, e, s]) => { expect( t, // Cleaned return value - isArray(ret) + Array.isArray(ret) // clean ret ? [...ret] : ret, From 6dff3bb86184b75da46d3fd9fd8fa520ee6cc22f Mon Sep 17 00:00:00 2001 From: Niklas Mollenhauer Date: Sun, 28 Sep 2025 19:51:43 +0200 Subject: [PATCH 2/7] Replace isFunction with `typeof` calls isFunction is just an alias for that: https://github.com/isaacs/core-util-is/blob/b90f777c19e0ca1304c2e1c48949b61779d70f1b/lib/util.js#L88-L91 --- src/stringify.js | 8 ++++---- test/array.test.js | 4 ++-- test/stringify.test.js | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/stringify.js b/src/stringify.js index b604ae9..5f4b0dc 100644 --- a/src/stringify.js +++ b/src/stringify.js @@ -1,5 +1,5 @@ const { - isObject, isFunction, isNumber, isString + isObject, isNumber, isString } = require('core-util-is') const { @@ -263,13 +263,13 @@ function stringify (key, holder, gap) { let value = holder[key] // If the value has a toJSON method, call it to obtain a replacement value. - if (isObject(value) && isFunction(value.toJSON)) { + if (isObject(value) && typeof value.toJSON === 'function') { value = value.toJSON(key) } // If we were called with a replacer function, then call the replacer to // obtain a replacement value. - if (isFunction(replacer)) { + if (typeof replacer === 'function') { value = replacer.call(holder, key, value) } @@ -344,7 +344,7 @@ module.exports = (value, replacer_, space) => { } // vanilla `JSON.parse` allow invalid replacer - if (!isFunction(replacer_) && !Array.isArray(replacer_)) { + if (typeof replacer_ !== 'function' && !Array.isArray(replacer_)) { replacer_ = null } diff --git a/test/array.test.js b/test/array.test.js index 83a9a59..a6f8e23 100644 --- a/test/array.test.js +++ b/test/array.test.js @@ -1,7 +1,7 @@ // eslint-disable-next-line import/no-unresolved const test = require('ava') const { - isFunction, isObject, isString + isObject, isString } = require('core-util-is') const { parse, stringify, assign, CommentArray @@ -305,7 +305,7 @@ CASES.forEach(([d, a, run, e, s]) => { const parsed = parse(a) const ret = run(parsed) - const expect = isFunction(e) + const expect = typeof e === 'function' ? e : (tt, r, str) => { tt.deepEqual(r, e) diff --git a/test/stringify.test.js b/test/stringify.test.js index c7b0016..4f7a142 100644 --- a/test/stringify.test.js +++ b/test/stringify.test.js @@ -2,7 +2,7 @@ const test = require('ava') const {resolve} = require('test-fixture')() const fs = require('fs') -const {isFunction, isString} = require('core-util-is') +const {isString} = require('core-util-is') const {parse, stringify} = require('..') @@ -69,7 +69,7 @@ const each = (subjects, replacers, spaces, iterator) => { spaces.forEach((space, iii) => { const desc = [subject, replacer, space] .map(s => - isFunction(s) + typeof s === 'function' ? 'replacer' : JSON.stringify(s) ) From f62a3e0a371fd7e936bb00ac4790a3f14006c8b6 Mon Sep 17 00:00:00 2001 From: Niklas Mollenhauer Date: Sun, 28 Sep 2025 19:54:10 +0200 Subject: [PATCH 3/7] Replace isNumber with `typeof` isNumber is just an alias: https://github.com/isaacs/core-util-is/blob/b90f777c19e0ca1304c2e1c48949b61779d70f1b/lib/util.js#L48-L51 --- src/common.js | 5 ++--- src/stringify.js | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/common.js b/src/common.js index 505149c..475d79f 100644 --- a/src/common.js +++ b/src/common.js @@ -1,7 +1,6 @@ const { isObject, - isString, - isNumber + isString } = require('core-util-is') const PREFIX_BEFORE = 'before' @@ -108,7 +107,7 @@ const assign_non_prop_comments = (target, source) => { // Assign keys and comments const assign = (target, source, keys) => { keys.forEach(key => { - if (!isString(key) && !isNumber(key)) { + if (!isString(key) && typeof key !== 'number') { return } diff --git a/src/stringify.js b/src/stringify.js index 5f4b0dc..2aaf76b 100644 --- a/src/stringify.js +++ b/src/stringify.js @@ -1,5 +1,5 @@ const { - isObject, isNumber, isString + isObject, isString } = require('core-util-is') const { @@ -306,7 +306,7 @@ function stringify (key, holder, gap) { const get_indent = space => isString(space) // If the space parameter is a string, it will be used as the indent string. ? space - : isNumber(space) + : typeof space === 'number' ? SPACE.repeat(space) : EMPTY From e3cb0791442076e9d1d6e9c79d866ae649e89c3a Mon Sep 17 00:00:00 2001 From: Niklas Mollenhauer Date: Sun, 28 Sep 2025 19:57:02 +0200 Subject: [PATCH 4/7] Replace isString with `typeof` It's just an alias: https://github.com/isaacs/core-util-is/blob/b90f777c19e0ca1304c2e1c48949b61779d70f1b/lib/util.js#L53-L56 --- src/common.js | 7 ++----- src/stringify.js | 6 ++---- test/array.test.js | 6 ++---- test/stringify.test.js | 3 +-- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/common.js b/src/common.js index 475d79f..119be7b 100644 --- a/src/common.js +++ b/src/common.js @@ -1,7 +1,4 @@ -const { - isObject, - isString -} = require('core-util-is') +const {isObject} = require('core-util-is') const PREFIX_BEFORE = 'before' const PREFIX_AFTER_PROP = 'after-prop' @@ -107,7 +104,7 @@ const assign_non_prop_comments = (target, source) => { // Assign keys and comments const assign = (target, source, keys) => { keys.forEach(key => { - if (!isString(key) && typeof key !== 'number') { + if (typeof key !== 'string' && typeof key !== 'number') { return } diff --git a/src/stringify.js b/src/stringify.js index 2aaf76b..49e1469 100644 --- a/src/stringify.js +++ b/src/stringify.js @@ -1,6 +1,4 @@ -const { - isObject, isString -} = require('core-util-is') +const {isObject} = require('core-util-is') const { PREFIX_BEFORE_ALL, @@ -303,7 +301,7 @@ function stringify (key, holder, gap) { } } -const get_indent = space => isString(space) +const get_indent = space => typeof space === 'string' // If the space parameter is a string, it will be used as the indent string. ? space : typeof space === 'number' diff --git a/test/array.test.js b/test/array.test.js index a6f8e23..dc1b487 100644 --- a/test/array.test.js +++ b/test/array.test.js @@ -1,8 +1,6 @@ // eslint-disable-next-line import/no-unresolved const test = require('ava') -const { - isObject, isString -} = require('core-util-is') +const {isObject} = require('core-util-is') const { parse, stringify, assign, CommentArray } = require('..') @@ -47,7 +45,7 @@ const texpect = ( t.is(r, ret) } - if (isString(rr)) { + if (typeof rr === 'string') { t.is(rr, str) } else { t.is(st(rr), str) diff --git a/test/stringify.test.js b/test/stringify.test.js index 4f7a142..39b1673 100644 --- a/test/stringify.test.js +++ b/test/stringify.test.js @@ -2,7 +2,6 @@ const test = require('ava') const {resolve} = require('test-fixture')() const fs = require('fs') -const {isString} = require('core-util-is') const {parse, stringify} = require('..') @@ -111,7 +110,7 @@ OLD_CASES.forEach(name => { 3, null ].forEach(space => { - const s = isString(space) + const s = typeof space === 'string' ? space.length : space From 9a80a8376a548834e33f4b2c3518df95abd1c367 Mon Sep 17 00:00:00 2001 From: Niklas Mollenhauer Date: Mon, 29 Sep 2025 16:35:09 +0200 Subject: [PATCH 5/7] Vendor isObject function from core-utils isObject also doesn't only check whether it's an object, but whether it is also !== null. Ref: https://github.com/isaacs/core-util-is/blob/b90f777c19e0ca1304c2e1c48949b61779d70f1b/lib/util.js#L73-L76 --- src/common.js | 14 ++++++++++---- src/stringify.js | 10 +++++----- test/array.test.js | 3 +-- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/common.js b/src/common.js index 119be7b..26a9b0a 100644 --- a/src/common.js +++ b/src/common.js @@ -1,5 +1,3 @@ -const {isObject} = require('core-util-is') - const PREFIX_BEFORE = 'before' const PREFIX_AFTER_PROP = 'after-prop' const PREFIX_AFTER_COLON = 'after-colon' @@ -42,6 +40,12 @@ const define = (target, key, value) => Object.defineProperty(target, key, { configurable: true }) +/** + * @param {unknown} v + * @returns {v is NonNullable} + */ +const is_object = v => typeof v === 'object' && v !== null; + const copy_comments_by_kind = ( target, source, target_key, source_key, prefix, remove_source ) => { @@ -149,12 +153,14 @@ module.exports = { swap_comments, assign_non_prop_comments, + is_object, + assign (target, source, keys) { - if (!isObject(target)) { + if (!is_object(target)) { throw new TypeError('Cannot convert undefined or null to object') } - if (!isObject(source)) { + if (!is_object(source)) { return target } diff --git a/src/stringify.js b/src/stringify.js index 49e1469..3939f6a 100644 --- a/src/stringify.js +++ b/src/stringify.js @@ -1,5 +1,3 @@ -const {isObject} = require('core-util-is') - const { PREFIX_BEFORE_ALL, PREFIX_BEFORE, @@ -17,7 +15,9 @@ const { COMMA, EMPTY, - UNDEFINED + UNDEFINED, + + is_object } = require('./common') // eslint-disable-next-line no-control-regex, no-misleading-character-class @@ -261,7 +261,7 @@ function stringify (key, holder, gap) { let value = holder[key] // If the value has a toJSON method, call it to obtain a replacement value. - if (isObject(value) && typeof value.toJSON === 'function') { + if (is_object(value) && typeof value.toJSON === 'function') { value = value.toJSON(key) } @@ -355,7 +355,7 @@ module.exports = (value, replacer_, space) => { clean() - return isObject(value) + return is_object(value) ? process_comments(value, PREFIX_BEFORE_ALL, EMPTY, true).trimLeft() + str + process_comments(value, PREFIX_AFTER_ALL, EMPTY).trimRight() diff --git a/test/array.test.js b/test/array.test.js index dc1b487..36b80a6 100644 --- a/test/array.test.js +++ b/test/array.test.js @@ -1,6 +1,5 @@ // eslint-disable-next-line import/no-unresolved const test = require('ava') -const {isObject} = require('core-util-is') const { parse, stringify, assign, CommentArray } = require('..') @@ -39,7 +38,7 @@ const texpect = ( // real return value rr ) => { - if (isObject(ret)) { + if (typeof ret === 'object' && ret !== null) { t.deepEqual(r, ret) } else { t.is(r, ret) From 41da3b29b51cb70979d0fcc89ad5d947bb324de5 Mon Sep 17 00:00:00 2001 From: Niklas Mollenhauer Date: Mon, 29 Sep 2025 16:37:37 +0200 Subject: [PATCH 6/7] Remove unused core-util-is --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index d086875..c4766fc 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,6 @@ }, "dependencies": { "array-timsort": "^1.0.3", - "core-util-is": "^1.0.3", "esprima": "^4.0.1" } } From cf80fabbda56e471807b7136e10acac86dc2421c Mon Sep 17 00:00:00 2001 From: Niklas Mollenhauer Date: Mon, 29 Sep 2025 16:46:38 +0200 Subject: [PATCH 7/7] Fix linter --- src/common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common.js b/src/common.js index 26a9b0a..354724a 100644 --- a/src/common.js +++ b/src/common.js @@ -44,7 +44,7 @@ const define = (target, key, value) => Object.defineProperty(target, key, { * @param {unknown} v * @returns {v is NonNullable} */ -const is_object = v => typeof v === 'object' && v !== null; +const is_object = v => typeof v === 'object' && v !== null const copy_comments_by_kind = ( target, source, target_key, source_key, prefix, remove_source