dt-clean 1.0.0 → 1.1.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.
- package/CHANGELOG.md +17 -0
- package/README.md +54 -2
- package/applyChanges.mjs +1 -5
- package/bin.mjs +91 -32
- package/detectIndent.d.ts +3 -0
- package/detectIndent.mjs +5 -0
- package/exitCode.mjs +31 -0
- package/package.json +5 -4
- package/setup.d.ts +12 -0
- package/setup.mjs +57 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [v1.1.0](https://github.com/ljharb/dt-clean/compare/v1.0.1...v1.1.0) - 2026-06-21
|
|
9
|
+
|
|
10
|
+
### Commits
|
|
11
|
+
|
|
12
|
+
- [New] add `--auto`, meant for the `dependencies` lifecycle script [`bc60a91`](https://github.com/ljharb/dt-clean/commit/bc60a91bf4f3e4d0964f8dcb71d1b0d1182612f9)
|
|
13
|
+
- [Tests] treat taken-down registry packages as skipped, not failures [`d020cc6`](https://github.com/ljharb/dt-clean/commit/d020cc62dd06de08189eebfe45e79a372ec8e5a1)
|
|
14
|
+
- [meta] run `dt-clean --setup` [`459cc0c`](https://github.com/ljharb/dt-clean/commit/459cc0cc3a5a2b64e498946c8930ae49899eb8b3)
|
|
15
|
+
|
|
16
|
+
## [v1.0.1](https://github.com/ljharb/dt-clean/compare/v1.0.0...v1.0.1) - 2026-06-19
|
|
17
|
+
|
|
18
|
+
### Commits
|
|
19
|
+
|
|
20
|
+
- [Fix] exit nonzero when changes are needed [`7c19b07`](https://github.com/ljharb/dt-clean/commit/7c19b07735c33d4a757f822355fd7a02760f7aed)
|
|
21
|
+
- [readme] use proper indefinite article [`a63be72`](https://github.com/ljharb/dt-clean/commit/a63be726dd3655a1e9bbecc7d8726b8637700888)
|
|
22
|
+
- [Deps] update `semver` [`a93456c`](https://github.com/ljharb/dt-clean/commit/a93456cda93fbde6d1c23b5b76418a60c11b14ea)
|
|
23
|
+
- [Dev Deps] downgrade `@types/node` [`7aa7c07`](https://github.com/ljharb/dt-clean/commit/7aa7c072d0003816e40591b7aa56cdcbe217fa92)
|
|
24
|
+
|
|
8
25
|
## v1.0.0 - 2026-06-19
|
|
9
26
|
|
|
10
27
|
### Commits
|
package/README.md
CHANGED
|
@@ -12,8 +12,8 @@ Ensures the only DefinitelyTyped (`@types/*`) packages you have installed are th
|
|
|
12
12
|
`dt-clean` inspects your `package.json` and, for each dependency, decides what should happen to its DefinitelyTyped types package:
|
|
13
13
|
|
|
14
14
|
- **add**: the runtime package ships no types of its own, but a matching `@types/*` package exists on the registry.
|
|
15
|
-
- **move**:
|
|
16
|
-
- **remove**:
|
|
15
|
+
- **move**: a `@types/*` package is in `dependencies`, but belongs in `devDependencies`.
|
|
16
|
+
- **remove**: a `@types/*` package is installed but no longer needed: the runtime package now bundles its own types, or it no longer corresponds to any dependency.
|
|
17
17
|
- **keep**: the `@types/*` package is present and still needed. `@types/node` is always kept.
|
|
18
18
|
|
|
19
19
|
## Usage
|
|
@@ -47,8 +47,60 @@ With `--update` (`-u`), `dt-clean` edits `package.json` in place - adding, movin
|
|
|
47
47
|
### Options
|
|
48
48
|
|
|
49
49
|
- `-u`, `--update`: apply the changes to `package.json` (default: report only).
|
|
50
|
+
- `--setup`: idempotently wire `dt-clean --auto` into a `dependencies` lifecycle script, without overwriting any existing script (see [Automatic cleanup](#automatic-cleanup)).
|
|
51
|
+
- `--auto`: for use in a `dependencies` lifecycle script - apply the changes like `--update` during `npm install`, but during `npm ci` only print what would change and exit `0` (see [Automatic cleanup](#automatic-cleanup)).
|
|
50
52
|
- `--help`: show usage.
|
|
51
53
|
|
|
54
|
+
### Automatic cleanup
|
|
55
|
+
|
|
56
|
+
To keep your `@types/*` set tidy on every install, run `dt-clean --auto` from a [`dependencies` lifecycle script](https://docs.npmjs.com/cli/using-npm/scripts#npm-install) - the one npm's installer (arborist) runs after any operation that changes `node_modules`.
|
|
57
|
+
|
|
58
|
+
The one-step way to set this up, in any project, is:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
npx dt-clean --setup
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`--setup` edits `package.json` for you and is safe to run anywhere:
|
|
65
|
+
|
|
66
|
+
- if you have no `dependencies` script, it adds `"dependencies": "dt-clean --auto"`;
|
|
67
|
+
- if you already have one, it adds `dt-clean --auto` to a free `postdependencies` (or `predependencies`) hook instead, so your existing script is never touched - and if every hook is taken, it appends `&& dt-clean --auto` to your `dependencies` script rather than clobbering it;
|
|
68
|
+
- if `dt-clean --auto` is already wired in, it does nothing.
|
|
69
|
+
|
|
70
|
+
It only ever adds this one invocation and leaves the rest of your `package.json` (and its formatting) alone, so it's safe to re-run. The result is simply the equivalent of:
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"scripts": {
|
|
75
|
+
"dependencies": "dt-clean --auto"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Once it's wired in, `dt-clean --auto` inspects `npm_command` to decide what to do:
|
|
81
|
+
|
|
82
|
+
- under `npm install`, it applies the changes for you, so a fresh install keeps your `@types/*` set tidy automatically;
|
|
83
|
+
- under `npm ci` (typically used in CI pipelines, where `package.json` must not be mutated), it only prints what would change and exits `0`, so it never edits a checked-in file and never fails the install.
|
|
84
|
+
|
|
85
|
+
When `npm_command` is anything else (or absent), `--auto` applies the changes, exactly as under `npm install`.
|
|
86
|
+
|
|
87
|
+
To avoid surprising edits, `--auto` runs *only* inside the `dependencies` lifecycle (or its `predependencies`/`postdependencies` hooks): it checks `npm_lifecycle_event`, and if it is invoked any other way (for example directly from the shell) it refuses to do anything and exits nonzero. Use `--update` to apply changes manually.
|
|
88
|
+
|
|
89
|
+
### Exit codes
|
|
90
|
+
|
|
91
|
+
In the default report-only mode, the exit code is a bitmask of the kinds of pending changes, so a clean project exits `0` and you can fail CI (or a `git` pre-commit hook) on drift:
|
|
92
|
+
|
|
93
|
+
| Value | Meaning |
|
|
94
|
+
| ----- | ---------------------------------------- |
|
|
95
|
+
| `1` | there are `@types/*` packages to remove |
|
|
96
|
+
| `2` | there are `@types/*` packages to add |
|
|
97
|
+
| `4` | there are `@types/*` packages to move |
|
|
98
|
+
|
|
99
|
+
The bits combine, so a project that needs both an add and a remove exits `3`, and one that needs all three exits `7`.
|
|
100
|
+
|
|
101
|
+
With `--update`, `dt-clean` applies the changes, leaving the project clean, so a successful run always exits `0`;
|
|
102
|
+
a nonzero exit then means the update itself failed.
|
|
103
|
+
|
|
52
104
|
[package-url]: https://npmjs.org/package/dt-clean
|
|
53
105
|
[npm-version-svg]: https://versionbadg.es/ljharb/dt-clean.svg
|
|
54
106
|
[npm-badge-png]: https://nodei.co/npm/dt-clean.png?downloads=true&stars=true
|
package/applyChanges.mjs
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { join } from 'path';
|
|
2
2
|
import { readFile, writeFile } from 'fs/promises';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
function detectIndent(raw) {
|
|
6
|
-
const match = (/^[ \t]+/m).exec(raw);
|
|
7
|
-
return match?.[0] ?? '\t';
|
|
8
|
-
}
|
|
4
|
+
import detectIndent from '#/detectIndent';
|
|
9
5
|
|
|
10
6
|
/** @type {<K extends string, V>(obj: Record<K, V>) => Record<K, V>} */
|
|
11
7
|
function sortKeys(obj) {
|
package/bin.mjs
CHANGED
|
@@ -7,20 +7,37 @@ import pargs from 'pargs';
|
|
|
7
7
|
import getDelTa from '#/getDelTa';
|
|
8
8
|
import applyChanges from '#/applyChanges';
|
|
9
9
|
import formatReport from '#/report';
|
|
10
|
+
import exitCode from '#/exitCode';
|
|
11
|
+
import setupScripts from '#/setup';
|
|
10
12
|
|
|
11
13
|
const {
|
|
12
|
-
values: {
|
|
14
|
+
values: {
|
|
15
|
+
auto,
|
|
16
|
+
json,
|
|
17
|
+
setup,
|
|
18
|
+
update,
|
|
19
|
+
},
|
|
13
20
|
positionals,
|
|
14
21
|
help,
|
|
15
22
|
} = await pargs(import.meta.filename, {
|
|
16
23
|
allowPositionals: 1,
|
|
17
24
|
description: 'Reports which DefinitelyTyped (`@types/*`) packages a project should add, move, or remove. By default it only reports; with `--update` it edits `package.json`.',
|
|
18
25
|
options: {
|
|
26
|
+
auto: {
|
|
27
|
+
default: false,
|
|
28
|
+
description: 'for a `dependencies` lifecycle script (or its `pre`/`post` hooks): apply the changes like `--update` during `npm install`, but during `npm ci` only print what would change and exit zero',
|
|
29
|
+
type: 'boolean',
|
|
30
|
+
},
|
|
19
31
|
json: {
|
|
20
32
|
default: false,
|
|
21
33
|
description: 'print the result as JSON on stdout (the human-readable report moves to stderr)',
|
|
22
34
|
type: 'boolean',
|
|
23
35
|
},
|
|
36
|
+
setup: {
|
|
37
|
+
default: false,
|
|
38
|
+
description: 'idempotently add `dt-clean --auto` to a `dependencies` lifecycle script in `package.json`, without overwriting any existing script',
|
|
39
|
+
type: 'boolean',
|
|
40
|
+
},
|
|
24
41
|
update: {
|
|
25
42
|
default: false,
|
|
26
43
|
description: 'apply the changes to `package.json`, then run `npm install` (or your package manager\'s equivalent)',
|
|
@@ -35,43 +52,85 @@ await help();
|
|
|
35
52
|
|
|
36
53
|
const cwd = positionals.length > 0 ? resolve(positionals[0]) : process.cwd();
|
|
37
54
|
|
|
38
|
-
const {
|
|
39
|
-
present,
|
|
40
|
-
toAdd,
|
|
41
|
-
toMove,
|
|
42
|
-
toRemain,
|
|
43
|
-
toRemove,
|
|
44
|
-
} = await getDelTa(cwd);
|
|
55
|
+
const { npm_command: npmCommand, npm_lifecycle_event: lifecycleEvent } = process.env;
|
|
45
56
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
// the `dependencies` lifecycle and its `pre`/`post` hooks are the only safe slots for `--auto`,
|
|
58
|
+
// since npm runs them after a reify; `postdependencies`/`predependencies` let you add it without
|
|
59
|
+
// clobbering an existing `dependencies` script.
|
|
60
|
+
const DEPENDENCY_HOOKS = [
|
|
61
|
+
'predependencies',
|
|
62
|
+
'dependencies',
|
|
63
|
+
'postdependencies',
|
|
64
|
+
];
|
|
52
65
|
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
console.error(
|
|
66
|
+
if (setup) {
|
|
67
|
+
const { action, script } = await setupScripts(cwd);
|
|
68
|
+
console.log({
|
|
69
|
+
chained: `Appended \`dt-clean --auto\` to the existing \`${script}\` script in \`package.json\`.`,
|
|
70
|
+
present: `\`${script}\` already runs \`dt-clean --auto\`; nothing to do.`,
|
|
71
|
+
set: `Added \`dt-clean --auto\` to the \`${script}\` script in \`package.json\`.`,
|
|
72
|
+
}[action]);
|
|
73
|
+
} else if (auto && (!lifecycleEvent || !DEPENDENCY_HOOKS.includes(lifecycleEvent))) {
|
|
74
|
+
console.error('`--auto` only runs inside a `dependencies` (or `pre`/`postdependencies`) lifecycle script (see the README); use `--update` to apply changes manually.');
|
|
75
|
+
process.exitCode = 1;
|
|
62
76
|
} else {
|
|
63
|
-
|
|
64
|
-
|
|
77
|
+
const {
|
|
78
|
+
present,
|
|
79
|
+
toAdd,
|
|
80
|
+
toMove,
|
|
81
|
+
toRemain,
|
|
82
|
+
toRemove,
|
|
83
|
+
} = await getDelTa(cwd);
|
|
65
84
|
|
|
66
|
-
|
|
67
|
-
|
|
85
|
+
const report = formatReport({
|
|
86
|
+
present,
|
|
68
87
|
toAdd,
|
|
69
88
|
toMove,
|
|
70
89
|
toRemove,
|
|
71
90
|
});
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
91
|
+
|
|
92
|
+
if (json) {
|
|
93
|
+
console.log(JSON.stringify({
|
|
94
|
+
present: Object.fromEntries(present),
|
|
95
|
+
toAdd: Object.fromEntries(toAdd),
|
|
96
|
+
toMove: Object.fromEntries(toMove),
|
|
97
|
+
toRemain: Array.from(toRemain),
|
|
98
|
+
toRemove,
|
|
99
|
+
}, null, '\t'));
|
|
100
|
+
console.error(report);
|
|
101
|
+
} else {
|
|
102
|
+
console.log(report);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (update || (auto && npmCommand !== 'ci')) {
|
|
106
|
+
// `--update` applies the changes, leaving the project clean, so a successful run exits zero;
|
|
107
|
+
// only an error (e.g. a failed write, which throws) yields a nonzero exit.
|
|
108
|
+
const changed = await applyChanges(cwd, {
|
|
109
|
+
toAdd,
|
|
110
|
+
toMove,
|
|
111
|
+
toRemove,
|
|
112
|
+
});
|
|
113
|
+
console.error(changed
|
|
114
|
+
? '\nUpdated `package.json`; run `npm install` (or your package manager’s equivalent) to sync.'
|
|
115
|
+
: '\nNo changes needed.');
|
|
116
|
+
} else {
|
|
117
|
+
const code = exitCode({
|
|
118
|
+
toAdd,
|
|
119
|
+
toMove,
|
|
120
|
+
toRemove,
|
|
121
|
+
});
|
|
122
|
+
if (auto) {
|
|
123
|
+
// `--auto` under `npm ci`: leave the exit code at zero so a CI install never fails; the
|
|
124
|
+
// report above already lists what `npm install` would change.
|
|
125
|
+
if (code > 0) {
|
|
126
|
+
console.error('\n`npm ci` detected; `package.json` left unchanged. Run `npm install` or `dt-clean --update` to apply these changes.');
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
// report-only: the exit code is a bitmask of the pending change kinds, so a clean project exits zero.
|
|
130
|
+
process.exitCode = code;
|
|
131
|
+
if (code > 0) {
|
|
132
|
+
console.error('\nRe-run with `--update` (`-u`) to apply these changes to `package.json`.');
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
77
136
|
}
|
package/detectIndent.mjs
ADDED
package/exitCode.mjs
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** @import { DTDelta } from './getDelTa.d.ts' */
|
|
2
|
+
|
|
3
|
+
export const TO_REMOVE = 1;
|
|
4
|
+
export const TO_ADD = 2;
|
|
5
|
+
export const TO_MOVE = 4;
|
|
6
|
+
|
|
7
|
+
/** @typedef {1 | 2 | 4 | 3 | 6 | 7} PossibleExitCode */
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* In report-only mode the exit code is a bitmask of the pending change kinds, so a clean
|
|
11
|
+
* delta is `0` and any combination of kinds combines (e.g. add + remove is `3`).
|
|
12
|
+
*
|
|
13
|
+
* @type {(delta: Pick<DTDelta, 'toAdd' | 'toMove' | 'toRemove'>) => PossibleExitCode}
|
|
14
|
+
*/
|
|
15
|
+
export default function exitCode({
|
|
16
|
+
toAdd,
|
|
17
|
+
toMove,
|
|
18
|
+
toRemove,
|
|
19
|
+
}) {
|
|
20
|
+
let code = 0;
|
|
21
|
+
if (toRemove.length > 0) {
|
|
22
|
+
code |= TO_REMOVE;
|
|
23
|
+
}
|
|
24
|
+
if (toAdd.size > 0) {
|
|
25
|
+
code |= TO_ADD;
|
|
26
|
+
}
|
|
27
|
+
if (toMove.size > 0) {
|
|
28
|
+
code |= TO_MOVE;
|
|
29
|
+
}
|
|
30
|
+
return /** @type {PossibleExitCode} */ (code);
|
|
31
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dt-clean",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Ensures the only DefinitelyTyped (`@types`) packages you have installed are the ones you need",
|
|
5
5
|
"bin": "./bin.mjs",
|
|
6
6
|
"exports": {
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"lint": "eslint .",
|
|
24
24
|
"posttest": "npx npm@'>= 10.2' audit --production",
|
|
25
25
|
"version": "auto-changelog && git add CHANGELOG.md",
|
|
26
|
-
"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
|
|
26
|
+
"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"",
|
|
27
|
+
"dependencies": "dt-clean --auto"
|
|
27
28
|
},
|
|
28
29
|
"repository": {
|
|
29
30
|
"type": "git",
|
|
@@ -40,13 +41,13 @@
|
|
|
40
41
|
"es-errors": "^1.3.0",
|
|
41
42
|
"hastypes": "^4.0.4",
|
|
42
43
|
"pargs": "^1.4.2",
|
|
43
|
-
"semver": "^7.8.
|
|
44
|
+
"semver": "^7.8.5"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
47
|
"@arethetypeswrong/cli": "^0.18.3",
|
|
47
48
|
"@ljharb/eslint-config": "^22.2.3",
|
|
48
49
|
"@ljharb/tsconfig": "^0.3.2",
|
|
49
|
-
"@types/node": "^
|
|
50
|
+
"@types/node": "^24.13.2",
|
|
50
51
|
"@types/semver": "^7.7.1",
|
|
51
52
|
"auto-changelog": "^2.6.0",
|
|
52
53
|
"c8": "^11.0.0",
|
package/setup.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare function setup(cwd: string): Promise<setup.SetupResult>;
|
|
2
|
+
|
|
3
|
+
declare namespace setup {
|
|
4
|
+
type DependencyHook = 'predependencies' | 'dependencies' | 'postdependencies';
|
|
5
|
+
|
|
6
|
+
type SetupResult = {
|
|
7
|
+
action: 'present' | 'set' | 'chained';
|
|
8
|
+
script: DependencyHook;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export = setup;
|
package/setup.mjs
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
2
|
+
import { readFile, writeFile } from 'fs/promises';
|
|
3
|
+
|
|
4
|
+
import detectIndent from '#/detectIndent';
|
|
5
|
+
|
|
6
|
+
/** @import { PackageJSON } from './types/types.d.ts' */
|
|
7
|
+
/** @import { SetupResult } from './setup.d.ts' */
|
|
8
|
+
|
|
9
|
+
const AUTO = 'dt-clean --auto';
|
|
10
|
+
|
|
11
|
+
// listed most-preferred first: the `dependencies` event itself, then its `post`/`pre` hooks.
|
|
12
|
+
const HOOKS = /** @type {const} */ ([
|
|
13
|
+
'dependencies',
|
|
14
|
+
'postdependencies',
|
|
15
|
+
'predependencies',
|
|
16
|
+
]);
|
|
17
|
+
|
|
18
|
+
/** @param {string | undefined} script */
|
|
19
|
+
function hasAuto(script) {
|
|
20
|
+
// matches a `dt-clean … --auto` invocation confined to one `&&`/`;`/`|`-delimited segment
|
|
21
|
+
return typeof script === 'string' && (/\bdt-clean\b[^&|;]*--auto\b/).test(script);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** @type {import('./setup.d.ts')} */
|
|
25
|
+
export default async function setup(cwd) {
|
|
26
|
+
const packageJSONpath = join(cwd, 'package.json');
|
|
27
|
+
const raw = `${await readFile(packageJSONpath)}`;
|
|
28
|
+
|
|
29
|
+
/** @type {PackageJSON} */
|
|
30
|
+
const pkg = JSON.parse(raw);
|
|
31
|
+
|
|
32
|
+
/** @type {NonNullable<PackageJSON['scripts']>} */
|
|
33
|
+
const scripts = { ...pkg.scripts };
|
|
34
|
+
|
|
35
|
+
const present = HOOKS.find((hook) => hasAuto(scripts[hook]));
|
|
36
|
+
if (present) {
|
|
37
|
+
return { action: 'present', script: present };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const free = HOOKS.find((hook) => !scripts[hook]);
|
|
41
|
+
|
|
42
|
+
/** @type {SetupResult} */
|
|
43
|
+
let result;
|
|
44
|
+
if (free) {
|
|
45
|
+
scripts[free] = AUTO;
|
|
46
|
+
result = { action: 'set', script: free };
|
|
47
|
+
} else {
|
|
48
|
+
// every hook is occupied, so chain onto `dependencies` rather than clobber anything.
|
|
49
|
+
scripts.dependencies = `${scripts.dependencies} && ${AUTO}`;
|
|
50
|
+
result = { action: 'chained', script: 'dependencies' };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const next = { ...pkg, scripts };
|
|
54
|
+
await writeFile(packageJSONpath, `${JSON.stringify(next, null, detectIndent(raw))}\n`);
|
|
55
|
+
|
|
56
|
+
return result;
|
|
57
|
+
}
|