diff --git a/package-lock.json b/package-lock.json index 2691752..1e9a857 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "find-up": "^5.0.0", "fs-extra": "^9.1.0", "glob": "^7.1.6", + "merge-strategies": "^0.2.0", "pipettes": "^0.1.3", "prefix-stream": "^1.0.1", "type-core": "^0.8.0" @@ -1788,6 +1789,19 @@ "node": ">=8" } }, + "node_modules/@riseup/common/node_modules/merge-strategies": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/merge-strategies/-/merge-strategies-0.1.6.tgz", + "integrity": "sha512-JaiqrKkE8Bw0WT7AKLyxGCIfN9LilaZ/K/sagxWqnN13LPi1IVMhsvieIQrTuBRjs2l6xQ77kyJo0Uo6J5iLYA==", + "dev": true, + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lodash.mergewith": "^4.6.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@riseup/common/node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -1944,6 +1958,19 @@ "node": ">=8" } }, + "node_modules/@riseup/tooling/node_modules/merge-strategies": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/merge-strategies/-/merge-strategies-0.1.6.tgz", + "integrity": "sha512-JaiqrKkE8Bw0WT7AKLyxGCIfN9LilaZ/K/sagxWqnN13LPi1IVMhsvieIQrTuBRjs2l6xQ77kyJo0Uo6J5iLYA==", + "dev": true, + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lodash.mergewith": "^4.6.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@riseup/tooling/node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -12406,8 +12433,7 @@ "node_modules/lodash.mergewith": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" }, "node_modules/lodash.sortby": { "version": "4.7.0", @@ -12876,12 +12902,10 @@ "dev": true }, "node_modules/merge-strategies": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/merge-strategies/-/merge-strategies-0.1.6.tgz", - "integrity": "sha512-JaiqrKkE8Bw0WT7AKLyxGCIfN9LilaZ/K/sagxWqnN13LPi1IVMhsvieIQrTuBRjs2l6xQ77kyJo0Uo6J5iLYA==", - "dev": true, + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/merge-strategies/-/merge-strategies-0.2.0.tgz", + "integrity": "sha512-ftbWMGDBu4ICs9xrHUTZANKtlp9FwF9UIPgScICkEByve100/viJF2uc3d8V/Rr+c/BuDGs4lfO0kXHncNfx8g==", "dependencies": { - "lodash.clonedeep": "^4.5.0", "lodash.mergewith": "^4.6.1" }, "engines": { @@ -15644,6 +15668,19 @@ "node": ">=8" } }, + "node_modules/slimconf/node_modules/merge-strategies": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/merge-strategies/-/merge-strategies-0.1.6.tgz", + "integrity": "sha512-JaiqrKkE8Bw0WT7AKLyxGCIfN9LilaZ/K/sagxWqnN13LPi1IVMhsvieIQrTuBRjs2l6xQ77kyJo0Uo6J5iLYA==", + "dev": true, + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lodash.mergewith": "^4.6.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -19295,6 +19332,16 @@ "p-locate": "^4.1.0" } }, + "merge-strategies": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/merge-strategies/-/merge-strategies-0.1.6.tgz", + "integrity": "sha512-JaiqrKkE8Bw0WT7AKLyxGCIfN9LilaZ/K/sagxWqnN13LPi1IVMhsvieIQrTuBRjs2l6xQ77kyJo0Uo6J5iLYA==", + "dev": true, + "requires": { + "lodash.clonedeep": "^4.5.0", + "lodash.mergewith": "^4.6.1" + } + }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -19423,6 +19470,16 @@ "p-locate": "^4.1.0" } }, + "merge-strategies": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/merge-strategies/-/merge-strategies-0.1.6.tgz", + "integrity": "sha512-JaiqrKkE8Bw0WT7AKLyxGCIfN9LilaZ/K/sagxWqnN13LPi1IVMhsvieIQrTuBRjs2l6xQ77kyJo0Uo6J5iLYA==", + "dev": true, + "requires": { + "lodash.clonedeep": "^4.5.0", + "lodash.mergewith": "^4.6.1" + } + }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -27790,8 +27847,7 @@ "lodash.mergewith": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", - "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==", - "dev": true + "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" }, "lodash.sortby": { "version": "4.7.0", @@ -28170,12 +28226,10 @@ "dev": true }, "merge-strategies": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/merge-strategies/-/merge-strategies-0.1.6.tgz", - "integrity": "sha512-JaiqrKkE8Bw0WT7AKLyxGCIfN9LilaZ/K/sagxWqnN13LPi1IVMhsvieIQrTuBRjs2l6xQ77kyJo0Uo6J5iLYA==", - "dev": true, + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/merge-strategies/-/merge-strategies-0.2.0.tgz", + "integrity": "sha512-ftbWMGDBu4ICs9xrHUTZANKtlp9FwF9UIPgScICkEByve100/viJF2uc3d8V/Rr+c/BuDGs4lfO0kXHncNfx8g==", "requires": { - "lodash.clonedeep": "^4.5.0", "lodash.mergewith": "^4.6.1" } }, @@ -30349,6 +30403,18 @@ "lodash.isequal": "^4.5.0", "merge-strategies": "^0.1.4", "object-hash": "^1.3.1" + }, + "dependencies": { + "merge-strategies": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/merge-strategies/-/merge-strategies-0.1.6.tgz", + "integrity": "sha512-JaiqrKkE8Bw0WT7AKLyxGCIfN9LilaZ/K/sagxWqnN13LPi1IVMhsvieIQrTuBRjs2l6xQ77kyJo0Uo6J5iLYA==", + "dev": true, + "requires": { + "lodash.clonedeep": "^4.5.0", + "lodash.mergewith": "^4.6.1" + } + } } }, "snapdragon": { diff --git a/package.json b/package.json index d796ef2..edc9361 100644 --- a/package.json +++ b/package.json @@ -95,6 +95,7 @@ "find-up": "^5.0.0", "fs-extra": "^9.1.0", "glob": "^7.1.6", + "merge-strategies": "^0.2.0", "pipettes": "^0.1.3", "prefix-stream": "^1.0.1", "type-core": "^0.8.0" diff --git a/src/bin/index.ts b/src/bin/index.ts index 52fffb4..16132bf 100644 --- a/src/bin/index.ts +++ b/src/bin/index.ts @@ -4,6 +4,7 @@ import { log } from '../tasks/stdio/log'; import { constants } from '../constants'; import main from './main'; import { NullaryFn } from 'type-core'; +import { shallow } from 'merge-strategies'; import { attach, options as _options, resolver, add } from 'exits'; export interface BinOptions { @@ -22,14 +23,14 @@ export interface BinOptions { */ export async function bin(options?: BinOptions): Promise { try { - const opts = Object.assign( + const opts = shallow( { bin: constants.bin, file: constants.file, description: constants.description, version: constants.version }, - options + options || undefined ); const task = await main({ argv: process.argv.slice(2) }, opts); diff --git a/src/tasks/filesystem/copy.ts b/src/tasks/filesystem/copy.ts index 87e0130..52d40c2 100644 --- a/src/tasks/filesystem/copy.ts +++ b/src/tasks/filesystem/copy.ts @@ -2,6 +2,7 @@ import { Task, Context } from '../../definitions'; import { getPathPairs, usePair } from '../../helpers/paths'; import { isCancelled } from '../../utils/is-cancelled'; import { log } from '../stdio/log'; +import { shallow } from 'merge-strategies'; import { into } from 'pipettes'; import fs from 'fs-extra'; @@ -29,9 +30,9 @@ export function copy( return async (ctx: Context): Promise => { into(ctx, log('debug', 'Copy', paths, 'to', destination)); - const opts = Object.assign( + const opts = shallow( { glob: false, single: false, strict: false, exists: 'error' }, - options + options || undefined ); const pairs = await getPathPairs(paths, destination, ctx, { glob: opts.glob, diff --git a/src/tasks/filesystem/edit.ts b/src/tasks/filesystem/edit.ts index ee943a7..196805b 100644 --- a/src/tasks/filesystem/edit.ts +++ b/src/tasks/filesystem/edit.ts @@ -3,6 +3,7 @@ import { getPaths, useSource } from '../../helpers/paths'; import { isCancelled } from '../../utils/is-cancelled'; import { log } from '../stdio/log'; import { Serial } from 'type-core'; +import { shallow } from 'merge-strategies'; import { into } from 'pipettes'; import fs from 'fs-extra'; @@ -33,7 +34,7 @@ export function edit( return async (ctx: Context): Promise => { into(ctx, log('debug', 'Edit:', paths)); - const opts = Object.assign({ glob: false, strict: false }, options); + const opts = shallow({ glob: false, strict: false }, options || undefined); const sources = await getPaths(paths, ctx, { glob: opts.glob, strict: opts.strict diff --git a/src/tasks/filesystem/mkdir.ts b/src/tasks/filesystem/mkdir.ts index 22e5f17..27a9e51 100644 --- a/src/tasks/filesystem/mkdir.ts +++ b/src/tasks/filesystem/mkdir.ts @@ -2,6 +2,7 @@ import { Task, Context } from '../../definitions'; import { getPaths } from '../../helpers/paths'; import { isCancelled } from '../../utils/is-cancelled'; import { log } from '../stdio/log'; +import { shallow } from 'merge-strategies'; import { into } from 'pipettes'; import fs from 'fs-extra'; @@ -21,7 +22,7 @@ export function mkdir( return async (ctx: Context): Promise => { into(ctx, log('debug', 'Create directories:', paths)); - const opts = Object.assign({ ensure: false }, options); + const opts = shallow({ ensure: false }, options || undefined); const dirs = await getPaths(paths, ctx, { glob: false, strict: false }); diff --git a/src/tasks/filesystem/move.ts b/src/tasks/filesystem/move.ts index 8ce237e..108cdf3 100644 --- a/src/tasks/filesystem/move.ts +++ b/src/tasks/filesystem/move.ts @@ -2,6 +2,7 @@ import { Task, Context } from '../../definitions'; import { getPathPairs, usePair } from '../../helpers/paths'; import { isCancelled } from '../../utils/is-cancelled'; import { log } from '../stdio/log'; +import { shallow } from 'merge-strategies'; import { into } from 'pipettes'; import fs from 'fs-extra'; @@ -29,9 +30,9 @@ export function move( return async (ctx: Context): Promise => { into(ctx, log('debug', 'Move', paths, 'to', destination)); - const opts = Object.assign( + const opts = shallow( { glob: false, single: false, strict: false, exists: 'error' }, - options + options || undefined ); const pairs = await getPathPairs(paths, destination, ctx, { glob: opts.glob, diff --git a/src/tasks/filesystem/remove.ts b/src/tasks/filesystem/remove.ts index fa6198d..5776339 100644 --- a/src/tasks/filesystem/remove.ts +++ b/src/tasks/filesystem/remove.ts @@ -2,6 +2,7 @@ import { Task, Context } from '../../definitions'; import { getPaths, useSource } from '../../helpers/paths'; import { isCancelled } from '../../utils/is-cancelled'; import { log } from '../stdio/log'; +import { shallow } from 'merge-strategies'; import { into } from 'pipettes'; import fs from 'fs-extra'; @@ -25,9 +26,9 @@ export function remove( return async (ctx: Context): Promise => { into(ctx, log('debug', 'Remove:', paths)); - const opts = Object.assign( + const opts = shallow( { glob: false, strict: false, exists: 'error' }, - options + options || undefined ); const sources = await getPaths(paths, ctx, { glob: opts.glob, diff --git a/src/tasks/filesystem/watch.ts b/src/tasks/filesystem/watch.ts index 40557b5..033b722 100644 --- a/src/tasks/filesystem/watch.ts +++ b/src/tasks/filesystem/watch.ts @@ -5,6 +5,7 @@ import { clear } from '../stdio/clear'; import { series } from '../aggregate/series'; import { NullaryFn, UnaryFn, Empty } from 'type-core'; import { into, combine } from 'pipettes'; +import { shallow } from 'merge-strategies'; import chokidar from 'chokidar'; import debounce from 'debounce'; @@ -51,7 +52,7 @@ export function watch(options: WatchOptions | Empty, task: Task): Task.Async { poll: -1, symlinks: false }, - (defaults): Required => Object.assign(defaults, options), + (defaults) => shallow(defaults, options || undefined), ({ include, exclude, ...options }) => ({ ...options, include: Array.isArray(include) ? include : [include], diff --git a/src/tasks/filesystem/write.ts b/src/tasks/filesystem/write.ts index a8fb32a..19465d2 100644 --- a/src/tasks/filesystem/write.ts +++ b/src/tasks/filesystem/write.ts @@ -2,6 +2,7 @@ import { Task, Context } from '../../definitions'; import { useDestination } from '../../helpers/paths'; import { log } from '../stdio/log'; import { Serial } from 'type-core'; +import { shallow } from 'merge-strategies'; import { into } from 'pipettes'; import fs from 'fs-extra'; @@ -31,7 +32,7 @@ export function write( await useDestination( path, ctx, - Object.assign({ exists: 'error' }, options), + shallow({ exists: 'error' }, options || undefined), (dest) => fs.writeFile(dest, data) ); }; diff --git a/src/tasks/process/exec.ts b/src/tasks/process/exec.ts index 43513a5..c56a3f1 100644 --- a/src/tasks/process/exec.ts +++ b/src/tasks/process/exec.ts @@ -2,9 +2,10 @@ import { Task, Context } from '../../definitions'; import { getPrefix } from '../../helpers/prefix'; import { log } from '../stdio/log'; import { Empty } from 'type-core'; +import { shallow } from 'merge-strategies'; +import transform from 'prefix-stream'; import { WriteStream } from 'tty'; import { into } from 'pipettes'; -import transform from 'prefix-stream'; import execa from 'execa'; export interface ExecOptions extends execa.Options { @@ -24,7 +25,7 @@ export function exec( options?: ExecOptions | Empty, cb?: (ps: execa.ExecaChildProcess) => void ): Task.Async { - const opts = Object.assign({ extendEnv: true }, options || undefined); + const opts = shallow({ extendEnv: true }, options || undefined); return async (ctx: Context): Promise => { const fullArgs = (args || []).concat(ctx.args || []); diff --git a/src/tasks/reflection/lift.ts b/src/tasks/reflection/lift.ts index a110ac3..0a20563 100644 --- a/src/tasks/reflection/lift.ts +++ b/src/tasks/reflection/lift.ts @@ -7,6 +7,7 @@ import { constants } from '../../constants'; import { select } from '../transform/select'; import { write } from '../filesystem/write'; import { print } from '../stdio/print'; +import { shallow } from 'merge-strategies'; import { Members } from 'type-core'; import { into } from 'pipettes'; import chalk from 'chalk'; @@ -38,9 +39,9 @@ export interface LiftOptions { */ export function lift(tasks: Task.Record, options?: LiftOptions): Task.Async { return async (ctx: Context): Promise => { - const opts = Object.assign( + const opts = shallow( { purge: false, mode: 'default', bin: constants.bin }, - options + options || undefined ); const pkgPath = getAbsolutePath('package.json', ctx); diff --git a/src/tasks/reflection/list.ts b/src/tasks/reflection/list.ts index 8ac9083..63aca51 100644 --- a/src/tasks/reflection/list.ts +++ b/src/tasks/reflection/list.ts @@ -3,6 +3,7 @@ import { parseToArray } from '../../helpers/parse'; import { constants } from '../../constants'; import { print } from '../stdio/print'; import { Empty } from 'type-core'; +import { shallow } from 'merge-strategies'; import { into } from 'pipettes'; import table from 'as-table'; import chalk from 'chalk'; @@ -25,7 +26,7 @@ export function list( map?: (name: string, route: string[]) => string[] ): Task.Sync { return (ctx: Context): void => { - const opts = Object.assign({ bin: constants.bin }, options); + const opts = shallow({ bin: constants.bin }, options || undefined); const items = parseToArray(tasks); const maxRouteLength = items.reduce( (acc, item) => (acc > item.route.length ? acc : item.route.length), diff --git a/src/tasks/transform/catches.ts b/src/tasks/transform/catches.ts index 4fcf856..ccbbc7c 100644 --- a/src/tasks/transform/catches.ts +++ b/src/tasks/transform/catches.ts @@ -1,6 +1,7 @@ import { Task, Context, LogLevel } from '../../definitions'; import { formatMessage } from '../../helpers/format-message'; import { log } from '../stdio/log'; +import { shallow } from 'merge-strategies'; import { into } from 'pipettes'; export interface CatchesOptions { @@ -24,7 +25,7 @@ export function catches( options?: CatchesOptions ): Task.Async { return async (ctx: Context): Promise => { - const opts = Object.assign({ level: 'warn' }, options); + const opts = shallow({ level: 'warn' }, options || undefined); try { await task(ctx); } catch (err) { diff --git a/src/tasks/transform/select.ts b/src/tasks/transform/select.ts index 5dcd92b..41a9fcf 100644 --- a/src/tasks/transform/select.ts +++ b/src/tasks/transform/select.ts @@ -4,6 +4,7 @@ import { run } from '../../utils/run'; import { print } from '../stdio/print'; import { log } from '../stdio/log'; import { Members, Empty } from 'type-core'; +import { shallow } from 'merge-strategies'; import { createInterface } from 'readline'; import { into } from 'pipettes'; @@ -38,13 +39,13 @@ export function select( options: SelectOptions | Empty, tasks: Members ): Task.Async { - const opts = Object.assign( + const opts = shallow( { message: 'Continue?', timeout: -1, default: null as string | null }, - options + options || undefined ); const lowercaseDefault =