Skip to content

Commit

Permalink
fix: remove premove and merge-options (#1449)
Browse files Browse the repository at this point in the history
These deps don't work with `Node16` module resolution and PRs to
fix this have been open for ages.

Unblocks #1434
  • Loading branch information
achingbrain authored Jan 12, 2024
1 parent 3474407 commit 889b03a
Show file tree
Hide file tree
Showing 18 changed files with 225 additions and 21 deletions.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@
"fs-extra": "^11.1.0",
"gh-pages": "^6.0.0",
"globby": "^14.0.0",
"is-plain-obj": "^4.1.0",
"kleur": "^4.1.4",
"lilconfig": "^3.0.0",
"listr": "~0.14.2",
Expand All @@ -275,7 +276,6 @@
"mdast-util-gfm-table": "^2.0.0",
"mdast-util-gfm-task-list-item": "^2.0.0",
"mdast-util-to-markdown": "^2.0.0",
"merge-options": "^3.0.4",
"micromark-extension-gfm": "^3.0.0",
"micromark-extension-gfm-footnote": "^2.0.0",
"micromark-extension-gfm-strikethrough": "^2.0.0",
Expand All @@ -292,7 +292,6 @@
"path": "^0.12.7",
"playwright-test": "^14.0.0",
"polka": "^0.5.2",
"premove": "^4.0.0",
"prompt": "^1.2.2",
"proper-lockfile": "^4.1.2",
"react-native-test-runner": "^5.0.0",
Expand Down
2 changes: 1 addition & 1 deletion src/build/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import esbuild from 'esbuild'
import { execa } from 'execa'
import fs from 'fs-extra'
import Listr from 'listr'
import merge from 'merge-options'
import pascalcase from 'pascalcase'
import merge from '../utils/merge-options.js'
import { gzipSize, pkg, hasTsconfig, isTypescript, fromRoot, paths, findBinary } from './../utils.js'

const defaults = merge.bind({
Expand Down
2 changes: 1 addition & 1 deletion src/check-project/manifests/typed-cjs.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import mergeOptions from 'merge-options'
import mergeOptions from '../../utils/merge-options.js'
import { semanticReleaseConfig } from '../semantic-release-config.js'
import {
sortFields,
Expand Down
2 changes: 1 addition & 1 deletion src/check-project/manifests/typed-esm.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import mergeOptions from 'merge-options'
import mergeOptions from '../../utils/merge-options.js'
import { semanticReleaseConfig } from '../semantic-release-config.js'
import {
sortFields,
Expand Down
2 changes: 1 addition & 1 deletion src/check-project/manifests/typescript.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable no-console */

import mergeOptions from 'merge-options'
import mergeOptions from '../../utils/merge-options.js'
import { semanticReleaseConfig } from '../semantic-release-config.js'
import {
sortFields,
Expand Down
2 changes: 1 addition & 1 deletion src/check-project/manifests/untyped-cjs.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import mergeOptions from 'merge-options'
import mergeOptions from '../../utils/merge-options.js'
import { semanticReleaseConfig } from '../semantic-release-config.js'
import {
sortFields,
Expand Down
2 changes: 1 addition & 1 deletion src/check-project/manifests/untyped-esm.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import mergeOptions from 'merge-options'
import mergeOptions from '../../utils/merge-options.js'
import { semanticReleaseConfig } from '../semantic-release-config.js'
import {
sortFields,
Expand Down
2 changes: 1 addition & 1 deletion src/cmds/check.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import path from 'path'
import esbuild from 'esbuild'
import fs from 'fs-extra'
import kleur from 'kleur'
import merge from 'merge-options'
import { readPackageUp } from 'read-pkg-up'
import { loadUserConfig } from '../config/user.js'
import merge from '../utils/merge-options.js'
import { fromRoot, paths } from '../utils.js'

const defaults = merge.bind({
Expand Down
2 changes: 1 addition & 1 deletion src/config/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { pathToFileURL } from 'url'
import { lilconfig } from 'lilconfig'
import merge from 'merge-options'
import merge from '../utils/merge-options.js'
import { isTypescript } from '../utils.js'

/**
Expand Down
7 changes: 5 additions & 2 deletions src/docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { execa } from 'execa'
import fs from 'fs-extra'
import ghPages from 'gh-pages'
import Listr from 'listr'
import { premove as del } from 'premove/sync'
import { hasTsconfig, fromAegir, fromRoot, readJson, isMonorepoParent } from './utils.js'

const publishPages = promisify(ghPages.publish)
Expand Down Expand Up @@ -153,7 +152,11 @@ const tasks = new Listr(
* @param {GlobalOptions & DocsOptions} ctx
*/
task: (ctx) => {
del(ctx.directory)
if (fs.existsSync(ctx.directory)) {
fs.rmdirSync(ctx.directory, {
recursive: true
})
}
}
},
{
Expand Down
2 changes: 1 addition & 1 deletion src/document-check.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import fs from 'fs-extra'
import { globby } from 'globby'
import kleur from 'kleur'
import Listr from 'listr'
import merge from 'merge-options'
import { compileSnippets } from 'typescript-docs-verifier'
import merge from './utils/merge-options.js'
import { formatCode, formatError, fromRoot, hasTsconfig, readJson } from './utils.js'
/**
* @typedef {import("./types").GlobalOptions} GlobalOptions
Expand Down
2 changes: 1 addition & 1 deletion src/lint.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import fs from 'fs-extra'
import { globby } from 'globby'
import kleur from 'kleur'
import Listr from 'listr'
import merge from 'merge-options'
import merge from './utils/merge-options.js'
import { fromRoot, readJson, hasTsconfig, isTypescript, findBinary, hasDocCheck } from './utils.js'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
Expand Down
2 changes: 1 addition & 1 deletion src/test/browser.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path'
import { fileURLToPath } from 'url'
import { execa } from 'execa'
import merge from 'merge-options'
import merge from '../utils/merge-options.js'
import { fromAegir, findBinary } from '../utils.js'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
Expand Down
2 changes: 1 addition & 1 deletion src/test/electron.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path'
import { fileURLToPath } from 'url'
import { execa } from 'execa'
import merge from 'merge-options'
import merge from '../utils/merge-options.js'
import { getElectron, findBinary } from '../utils.js'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
Expand Down
2 changes: 1 addition & 1 deletion src/test/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import path from 'path'
import { fileURLToPath } from 'url'
import { execa } from 'execa'
import kleur from 'kleur'
import merge from 'merge-options'
import * as tempy from 'tempy'
import merge from '../utils/merge-options.js'

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

Expand Down
2 changes: 1 addition & 1 deletion src/test/react-native.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import path from 'path'
import { fileURLToPath } from 'url'
import { execa } from 'execa'
import merge from 'merge-options'
import merge from '../utils/merge-options.js'

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

Expand Down
199 changes: 199 additions & 0 deletions src/utils/merge-options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import isOptionObject from 'is-plain-obj'

const { hasOwnProperty } = Object.prototype
const { propertyIsEnumerable } = Object
/**
* @param {*} object
* @param {string | symbol | number} name
* @param {any} value
*/
const defineProperty = (object, name, value) => Object.defineProperty(object, name, {
value,
writable: true,
enumerable: true,
configurable: true
})

const globalThis = this
const defaultMergeOptions = {
concatArrays: false,
ignoreUndefined: false
}

/**
* @param {*} value
* @returns {Array<string | symbol>}
*/
const getEnumerableOwnPropertyKeys = value => {
/** @type {Array<string | symbol>} */
const keys = []

for (const key in value) {
if (hasOwnProperty.call(value, key)) {
keys.push(key)
}
}

/* istanbul ignore else */
if (Object.getOwnPropertySymbols) {
const symbols = Object.getOwnPropertySymbols(value)

for (const symbol of symbols) {
if (propertyIsEnumerable.call(value, symbol)) {
keys.push(symbol)
}
}
}

return keys
}

/**
* @param {*} value
*/
function clone (value) {
if (Array.isArray(value)) {
return cloneArray(value)
}

if (isOptionObject(value)) {
return cloneOptionObject(value)
}

return value
}

/**
* @param {*} array
*/
function cloneArray (array) {
const result = array.slice(0, 0)

getEnumerableOwnPropertyKeys(array).forEach(key => {
defineProperty(result, key, clone(array[key]))
})

return result
}

/**
* @param {*} object
*/
function cloneOptionObject (object) {
const result = Object.getPrototypeOf(object) === null ? Object.create(null) : {}

getEnumerableOwnPropertyKeys(object).forEach(key => {
defineProperty(result, key, clone(object[key]))
})

return result
}

/**
* @param {*} merged - already cloned
* @param {*} source - something to merge
* @param {Array<string | symbol>} keys - keys to merge
* @param {object} config - Config Object
* @param {boolean} [config.ignoreUndefined] - whether to ignore undefined values
* @param {boolean} [config.concatArrays] - Config Object
* @returns {*} cloned Object
*/
const mergeKeys = (merged, source, keys, config) => {
keys.forEach(key => {
if (typeof source[key] === 'undefined' && config.ignoreUndefined) {
return
}

// Do not recurse into prototype chain of merged
if (key in merged && merged[key] !== Object.getPrototypeOf(merged)) {
defineProperty(merged, key, merge(merged[key], source[key], config))
} else {
defineProperty(merged, key, clone(source[key]))
}
})

return merged
}

/**
* @param {*} merged - already cloned
* @param {*} source - something to merge
* @param {object} config - Config Object
* @returns {*} cloned Object
*
* see [Array.prototype.concat ( ...arguments )](http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.concat)
*/
const concatArrays = (merged, source, config) => {
let result = merged.slice(0, 0)
let resultIndex = 0;

[merged, source].forEach(array => {
/** @type {Array<string | symbol>} */
const indices = []

// `result.concat(array)` with cloning
for (let k = 0; k < array.length; k++) {
if (!hasOwnProperty.call(array, k)) {
continue
}

indices.push(String(k))

if (array === merged) {
// Already cloned
defineProperty(result, resultIndex++, array[k])
} else {
defineProperty(result, resultIndex++, clone(array[k]))
}
}

// Merge non-index keys
result = mergeKeys(result, array, getEnumerableOwnPropertyKeys(array).filter(key => !indices.includes(key)), config)
})

return result
}

/**
* @param {*} merged - already cloned
* @param {*} source - something to merge
* @param {object} config - Config Object
* @param {boolean} [config.concatArrays] - Config Object
* @returns {*} cloned Object
*/
function merge (merged, source, config) {
if (config.concatArrays && Array.isArray(merged) && Array.isArray(source)) {
return concatArrays(merged, source, config)
}

if (!isOptionObject(source) || !isOptionObject(merged)) {
return clone(source)
}

return mergeKeys(merged, source, getEnumerableOwnPropertyKeys(source), config)
}

/**
* @param {...any} options
*/
function mergeOptions (...options) {
// @ts-expect-error this is shadowed by the container
const config = merge(clone(defaultMergeOptions), (this !== globalThis && this) || {}, defaultMergeOptions)
let merged = { _: {} }

for (const option of options) {
if (option === undefined) {
continue
}

if (!isOptionObject(option)) {
throw new TypeError('`' + option + '` is not an Option Object')
}

merged = merge(merged, { _: option }, config)
}

return merged._
}

export default mergeOptions
9 changes: 6 additions & 3 deletions test/lint.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
/* eslint-env mocha */

import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
import { premove as del } from 'premove/sync'
import fs from 'fs-extra'
import { loadUserConfig } from '../src/config/user.js'
import lint from '../src/lint.js'
import { expect } from '../utils/chai.js'
Expand Down Expand Up @@ -75,7 +74,11 @@ describe('lint', () => {

after(() => {
process.chdir(cwd)
del(TEMP_FOLDER)
if (fs.existsSync(TEMP_FOLDER)) {
fs.rmdirSync(TEMP_FOLDER, {
recursive: true
})
}
})

it('lint itself (aegir)', async function () {
Expand Down

0 comments on commit 889b03a

Please sign in to comment.