Skip to content

Commit 889b03a

Browse files
authored
fix: remove premove and merge-options (#1449)
These deps don't work with `Node16` module resolution and PRs to fix this have been open for ages. Unblocks #1434
1 parent 3474407 commit 889b03a

18 files changed

+225
-21
lines changed

package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@
265265
"fs-extra": "^11.1.0",
266266
"gh-pages": "^6.0.0",
267267
"globby": "^14.0.0",
268+
"is-plain-obj": "^4.1.0",
268269
"kleur": "^4.1.4",
269270
"lilconfig": "^3.0.0",
270271
"listr": "~0.14.2",
@@ -275,7 +276,6 @@
275276
"mdast-util-gfm-table": "^2.0.0",
276277
"mdast-util-gfm-task-list-item": "^2.0.0",
277278
"mdast-util-to-markdown": "^2.0.0",
278-
"merge-options": "^3.0.4",
279279
"micromark-extension-gfm": "^3.0.0",
280280
"micromark-extension-gfm-footnote": "^2.0.0",
281281
"micromark-extension-gfm-strikethrough": "^2.0.0",
@@ -292,7 +292,6 @@
292292
"path": "^0.12.7",
293293
"playwright-test": "^14.0.0",
294294
"polka": "^0.5.2",
295-
"premove": "^4.0.0",
296295
"prompt": "^1.2.2",
297296
"proper-lockfile": "^4.1.2",
298297
"react-native-test-runner": "^5.0.0",

src/build/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import esbuild from 'esbuild'
66
import { execa } from 'execa'
77
import fs from 'fs-extra'
88
import Listr from 'listr'
9-
import merge from 'merge-options'
109
import pascalcase from 'pascalcase'
10+
import merge from '../utils/merge-options.js'
1111
import { gzipSize, pkg, hasTsconfig, isTypescript, fromRoot, paths, findBinary } from './../utils.js'
1212

1313
const defaults = merge.bind({

src/check-project/manifests/typed-cjs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import mergeOptions from 'merge-options'
1+
import mergeOptions from '../../utils/merge-options.js'
22
import { semanticReleaseConfig } from '../semantic-release-config.js'
33
import {
44
sortFields,

src/check-project/manifests/typed-esm.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import mergeOptions from 'merge-options'
1+
import mergeOptions from '../../utils/merge-options.js'
22
import { semanticReleaseConfig } from '../semantic-release-config.js'
33
import {
44
sortFields,

src/check-project/manifests/typescript.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable no-console */
22

3-
import mergeOptions from 'merge-options'
3+
import mergeOptions from '../../utils/merge-options.js'
44
import { semanticReleaseConfig } from '../semantic-release-config.js'
55
import {
66
sortFields,

src/check-project/manifests/untyped-cjs.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import mergeOptions from 'merge-options'
1+
import mergeOptions from '../../utils/merge-options.js'
22
import { semanticReleaseConfig } from '../semantic-release-config.js'
33
import {
44
sortFields,

src/check-project/manifests/untyped-esm.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import mergeOptions from 'merge-options'
1+
import mergeOptions from '../../utils/merge-options.js'
22
import { semanticReleaseConfig } from '../semantic-release-config.js'
33
import {
44
sortFields,

src/cmds/check.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import path from 'path'
66
import esbuild from 'esbuild'
77
import fs from 'fs-extra'
88
import kleur from 'kleur'
9-
import merge from 'merge-options'
109
import { readPackageUp } from 'read-pkg-up'
1110
import { loadUserConfig } from '../config/user.js'
11+
import merge from '../utils/merge-options.js'
1212
import { fromRoot, paths } from '../utils.js'
1313

1414
const defaults = merge.bind({

src/config/user.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { pathToFileURL } from 'url'
44
import { lilconfig } from 'lilconfig'
5-
import merge from 'merge-options'
5+
import merge from '../utils/merge-options.js'
66
import { isTypescript } from '../utils.js'
77

88
/**

src/docs.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { execa } from 'execa'
55
import fs from 'fs-extra'
66
import ghPages from 'gh-pages'
77
import Listr from 'listr'
8-
import { premove as del } from 'premove/sync'
98
import { hasTsconfig, fromAegir, fromRoot, readJson, isMonorepoParent } from './utils.js'
109

1110
const publishPages = promisify(ghPages.publish)
@@ -153,7 +152,11 @@ const tasks = new Listr(
153152
* @param {GlobalOptions & DocsOptions} ctx
154153
*/
155154
task: (ctx) => {
156-
del(ctx.directory)
155+
if (fs.existsSync(ctx.directory)) {
156+
fs.rmdirSync(ctx.directory, {
157+
recursive: true
158+
})
159+
}
157160
}
158161
},
159162
{

src/document-check.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import fs from 'fs-extra'
44
import { globby } from 'globby'
55
import kleur from 'kleur'
66
import Listr from 'listr'
7-
import merge from 'merge-options'
87
import { compileSnippets } from 'typescript-docs-verifier'
8+
import merge from './utils/merge-options.js'
99
import { formatCode, formatError, fromRoot, hasTsconfig, readJson } from './utils.js'
1010
/**
1111
* @typedef {import("./types").GlobalOptions} GlobalOptions

src/lint.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import fs from 'fs-extra'
88
import { globby } from 'globby'
99
import kleur from 'kleur'
1010
import Listr from 'listr'
11-
import merge from 'merge-options'
11+
import merge from './utils/merge-options.js'
1212
import { fromRoot, readJson, hasTsconfig, isTypescript, findBinary, hasDocCheck } from './utils.js'
1313

1414
const __dirname = path.dirname(fileURLToPath(import.meta.url))

src/test/browser.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from 'path'
22
import { fileURLToPath } from 'url'
33
import { execa } from 'execa'
4-
import merge from 'merge-options'
4+
import merge from '../utils/merge-options.js'
55
import { fromAegir, findBinary } from '../utils.js'
66

77
const __dirname = path.dirname(fileURLToPath(import.meta.url))

src/test/electron.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from 'path'
22
import { fileURLToPath } from 'url'
33
import { execa } from 'execa'
4-
import merge from 'merge-options'
4+
import merge from '../utils/merge-options.js'
55
import { getElectron, findBinary } from '../utils.js'
66

77
const __dirname = path.dirname(fileURLToPath(import.meta.url))

src/test/node.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import path from 'path'
33
import { fileURLToPath } from 'url'
44
import { execa } from 'execa'
55
import kleur from 'kleur'
6-
import merge from 'merge-options'
76
import * as tempy from 'tempy'
7+
import merge from '../utils/merge-options.js'
88

99
const __dirname = path.dirname(fileURLToPath(import.meta.url))
1010

src/test/react-native.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path from 'path'
22
import { fileURLToPath } from 'url'
33
import { execa } from 'execa'
4-
import merge from 'merge-options'
4+
import merge from '../utils/merge-options.js'
55

66
const __dirname = path.dirname(fileURLToPath(import.meta.url))
77

src/utils/merge-options.js

+199
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
import isOptionObject from 'is-plain-obj'
2+
3+
const { hasOwnProperty } = Object.prototype
4+
const { propertyIsEnumerable } = Object
5+
/**
6+
* @param {*} object
7+
* @param {string | symbol | number} name
8+
* @param {any} value
9+
*/
10+
const defineProperty = (object, name, value) => Object.defineProperty(object, name, {
11+
value,
12+
writable: true,
13+
enumerable: true,
14+
configurable: true
15+
})
16+
17+
const globalThis = this
18+
const defaultMergeOptions = {
19+
concatArrays: false,
20+
ignoreUndefined: false
21+
}
22+
23+
/**
24+
* @param {*} value
25+
* @returns {Array<string | symbol>}
26+
*/
27+
const getEnumerableOwnPropertyKeys = value => {
28+
/** @type {Array<string | symbol>} */
29+
const keys = []
30+
31+
for (const key in value) {
32+
if (hasOwnProperty.call(value, key)) {
33+
keys.push(key)
34+
}
35+
}
36+
37+
/* istanbul ignore else */
38+
if (Object.getOwnPropertySymbols) {
39+
const symbols = Object.getOwnPropertySymbols(value)
40+
41+
for (const symbol of symbols) {
42+
if (propertyIsEnumerable.call(value, symbol)) {
43+
keys.push(symbol)
44+
}
45+
}
46+
}
47+
48+
return keys
49+
}
50+
51+
/**
52+
* @param {*} value
53+
*/
54+
function clone (value) {
55+
if (Array.isArray(value)) {
56+
return cloneArray(value)
57+
}
58+
59+
if (isOptionObject(value)) {
60+
return cloneOptionObject(value)
61+
}
62+
63+
return value
64+
}
65+
66+
/**
67+
* @param {*} array
68+
*/
69+
function cloneArray (array) {
70+
const result = array.slice(0, 0)
71+
72+
getEnumerableOwnPropertyKeys(array).forEach(key => {
73+
defineProperty(result, key, clone(array[key]))
74+
})
75+
76+
return result
77+
}
78+
79+
/**
80+
* @param {*} object
81+
*/
82+
function cloneOptionObject (object) {
83+
const result = Object.getPrototypeOf(object) === null ? Object.create(null) : {}
84+
85+
getEnumerableOwnPropertyKeys(object).forEach(key => {
86+
defineProperty(result, key, clone(object[key]))
87+
})
88+
89+
return result
90+
}
91+
92+
/**
93+
* @param {*} merged - already cloned
94+
* @param {*} source - something to merge
95+
* @param {Array<string | symbol>} keys - keys to merge
96+
* @param {object} config - Config Object
97+
* @param {boolean} [config.ignoreUndefined] - whether to ignore undefined values
98+
* @param {boolean} [config.concatArrays] - Config Object
99+
* @returns {*} cloned Object
100+
*/
101+
const mergeKeys = (merged, source, keys, config) => {
102+
keys.forEach(key => {
103+
if (typeof source[key] === 'undefined' && config.ignoreUndefined) {
104+
return
105+
}
106+
107+
// Do not recurse into prototype chain of merged
108+
if (key in merged && merged[key] !== Object.getPrototypeOf(merged)) {
109+
defineProperty(merged, key, merge(merged[key], source[key], config))
110+
} else {
111+
defineProperty(merged, key, clone(source[key]))
112+
}
113+
})
114+
115+
return merged
116+
}
117+
118+
/**
119+
* @param {*} merged - already cloned
120+
* @param {*} source - something to merge
121+
* @param {object} config - Config Object
122+
* @returns {*} cloned Object
123+
*
124+
* see [Array.prototype.concat ( ...arguments )](http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.concat)
125+
*/
126+
const concatArrays = (merged, source, config) => {
127+
let result = merged.slice(0, 0)
128+
let resultIndex = 0;
129+
130+
[merged, source].forEach(array => {
131+
/** @type {Array<string | symbol>} */
132+
const indices = []
133+
134+
// `result.concat(array)` with cloning
135+
for (let k = 0; k < array.length; k++) {
136+
if (!hasOwnProperty.call(array, k)) {
137+
continue
138+
}
139+
140+
indices.push(String(k))
141+
142+
if (array === merged) {
143+
// Already cloned
144+
defineProperty(result, resultIndex++, array[k])
145+
} else {
146+
defineProperty(result, resultIndex++, clone(array[k]))
147+
}
148+
}
149+
150+
// Merge non-index keys
151+
result = mergeKeys(result, array, getEnumerableOwnPropertyKeys(array).filter(key => !indices.includes(key)), config)
152+
})
153+
154+
return result
155+
}
156+
157+
/**
158+
* @param {*} merged - already cloned
159+
* @param {*} source - something to merge
160+
* @param {object} config - Config Object
161+
* @param {boolean} [config.concatArrays] - Config Object
162+
* @returns {*} cloned Object
163+
*/
164+
function merge (merged, source, config) {
165+
if (config.concatArrays && Array.isArray(merged) && Array.isArray(source)) {
166+
return concatArrays(merged, source, config)
167+
}
168+
169+
if (!isOptionObject(source) || !isOptionObject(merged)) {
170+
return clone(source)
171+
}
172+
173+
return mergeKeys(merged, source, getEnumerableOwnPropertyKeys(source), config)
174+
}
175+
176+
/**
177+
* @param {...any} options
178+
*/
179+
function mergeOptions (...options) {
180+
// @ts-expect-error this is shadowed by the container
181+
const config = merge(clone(defaultMergeOptions), (this !== globalThis && this) || {}, defaultMergeOptions)
182+
let merged = { _: {} }
183+
184+
for (const option of options) {
185+
if (option === undefined) {
186+
continue
187+
}
188+
189+
if (!isOptionObject(option)) {
190+
throw new TypeError('`' + option + '` is not an Option Object')
191+
}
192+
193+
merged = merge(merged, { _: option }, config)
194+
}
195+
196+
return merged._
197+
}
198+
199+
export default mergeOptions

test/lint.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
/* eslint-env mocha */
22

3-
import fs from 'fs'
43
import path from 'path'
54
import { fileURLToPath } from 'url'
6-
import { premove as del } from 'premove/sync'
5+
import fs from 'fs-extra'
76
import { loadUserConfig } from '../src/config/user.js'
87
import lint from '../src/lint.js'
98
import { expect } from '../utils/chai.js'
@@ -75,7 +74,11 @@ describe('lint', () => {
7574

7675
after(() => {
7776
process.chdir(cwd)
78-
del(TEMP_FOLDER)
77+
if (fs.existsSync(TEMP_FOLDER)) {
78+
fs.rmdirSync(TEMP_FOLDER, {
79+
recursive: true
80+
})
81+
}
7982
})
8083

8184
it('lint itself (aegir)', async function () {

0 commit comments

Comments
 (0)