syncpack 13.0.1 → 14.0.0-alpha.2
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/README.md +0 -3
- package/index.js +48 -0
- package/package.json +16 -73
- package/schema.json +917 -0
- package/syncpack.d.ts +122 -0
- package/LICENSE +0 -20
- package/dist/bin-fix-mismatches/fix-mismatches.d.ts +0 -16
- package/dist/bin-fix-mismatches/fix-mismatches.js +0 -115
- package/dist/bin-fix-mismatches/index.d.ts +0 -2
- package/dist/bin-fix-mismatches/index.js +0 -33
- package/dist/bin-format/format.d.ts +0 -13
- package/dist/bin-format/format.js +0 -92
- package/dist/bin-format/index.d.ts +0 -2
- package/dist/bin-format/index.js +0 -28
- package/dist/bin-lint/index.d.ts +0 -2
- package/dist/bin-lint/index.js +0 -17
- package/dist/bin-lint/lint.d.ts +0 -11
- package/dist/bin-lint/lint.js +0 -52
- package/dist/bin-lint-semver-ranges/index.d.ts +0 -2
- package/dist/bin-lint-semver-ranges/index.js +0 -30
- package/dist/bin-lint-semver-ranges/lint-semver-ranges.d.ts +0 -16
- package/dist/bin-lint-semver-ranges/lint-semver-ranges.js +0 -92
- package/dist/bin-list/index.d.ts +0 -2
- package/dist/bin-list/index.js +0 -27
- package/dist/bin-list/list.d.ts +0 -14
- package/dist/bin-list/list.js +0 -151
- package/dist/bin-list-mismatches/index.d.ts +0 -2
- package/dist/bin-list-mismatches/index.js +0 -29
- package/dist/bin-list-mismatches/list-mismatches.d.ts +0 -18
- package/dist/bin-list-mismatches/list-mismatches.js +0 -224
- package/dist/bin-prompt/index.d.ts +0 -2
- package/dist/bin-prompt/index.js +0 -29
- package/dist/bin-prompt/prompt.d.ts +0 -11
- package/dist/bin-prompt/prompt.js +0 -95
- package/dist/bin-set-semver-ranges/index.d.ts +0 -2
- package/dist/bin-set-semver-ranges/index.js +0 -32
- package/dist/bin-set-semver-ranges/set-semver-ranges.d.ts +0 -11
- package/dist/bin-set-semver-ranges/set-semver-ranges.js +0 -61
- package/dist/bin-update/effects.d.ts +0 -52
- package/dist/bin-update/effects.js +0 -282
- package/dist/bin-update/index.d.ts +0 -2
- package/dist/bin-update/index.js +0 -24
- package/dist/bin-update/update.d.ts +0 -6
- package/dist/bin-update/update.js +0 -59
- package/dist/bin.d.ts +0 -2
- package/dist/bin.js +0 -37
- package/dist/config/get-custom-types.d.ts +0 -19
- package/dist/config/get-custom-types.js +0 -57
- package/dist/config/get-enabled-types.d.ts +0 -17
- package/dist/config/get-enabled-types.js +0 -109
- package/dist/config/get-filter.d.ts +0 -2
- package/dist/config/get-filter.js +0 -10
- package/dist/config/get-indent.d.ts +0 -2
- package/dist/config/get-indent.js +0 -9
- package/dist/config/get-sort-az.d.ts +0 -2
- package/dist/config/get-sort-az.js +0 -8
- package/dist/config/get-sort-exports.d.ts +0 -2
- package/dist/config/get-sort-exports.js +0 -9
- package/dist/config/get-sort-first.d.ts +0 -2
- package/dist/config/get-sort-first.js +0 -8
- package/dist/config/get-source.d.ts +0 -2
- package/dist/config/get-source.js +0 -8
- package/dist/config/tag.d.ts +0 -3
- package/dist/config/tag.js +0 -2
- package/dist/config/types.d.ts +0 -134
- package/dist/config/types.js +0 -1
- package/dist/constants.d.ts +0 -106
- package/dist/constants.js +0 -103
- package/dist/error-handlers/default-error-handlers.d.ts +0 -25
- package/dist/error-handlers/default-error-handlers.js +0 -80
- package/dist/get-context/index.d.ts +0 -23
- package/dist/get-context/index.js +0 -18
- package/dist/get-context/lib/key-by.d.ts +0 -6
- package/dist/get-context/lib/key-by.js +0 -12
- package/dist/get-instances/index.d.ts +0 -14
- package/dist/get-instances/index.js +0 -42
- package/dist/get-instances/instance.d.ts +0 -26
- package/dist/get-instances/instance.js +0 -35
- package/dist/get-package-json-files/get-file-paths.d.ts +0 -21
- package/dist/get-package-json-files/get-file-paths.js +0 -22
- package/dist/get-package-json-files/get-patterns/get-lerna-patterns.d.ts +0 -3
- package/dist/get-package-json-files/get-patterns/get-lerna-patterns.js +0 -12
- package/dist/get-package-json-files/get-patterns/get-pnpm-patterns.d.ts +0 -3
- package/dist/get-package-json-files/get-patterns/get-pnpm-patterns.js +0 -14
- package/dist/get-package-json-files/get-patterns/get-yarn-patterns.d.ts +0 -3
- package/dist/get-package-json-files/get-patterns/get-yarn-patterns.js +0 -16
- package/dist/get-package-json-files/get-patterns/index.d.ts +0 -8
- package/dist/get-package-json-files/get-patterns/index.js +0 -23
- package/dist/get-package-json-files/index.d.ts +0 -10
- package/dist/get-package-json-files/index.js +0 -8
- package/dist/get-package-json-files/package-json-file.d.ts +0 -54
- package/dist/get-package-json-files/package-json-file.js +0 -44
- package/dist/guards/can-add-to-group.d.ts +0 -5
- package/dist/guards/can-add-to-group.js +0 -58
- package/dist/guards/is-semver.d.ts +0 -2
- package/dist/guards/is-semver.js +0 -15
- package/dist/guards/is-valid-semver-range.d.ts +0 -3
- package/dist/guards/is-valid-semver-range.js +0 -14
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -1
- package/dist/io/ask-for-choice.d.ts +0 -14
- package/dist/io/ask-for-choice.js +0 -17
- package/dist/io/ask-for-input.d.ts +0 -13
- package/dist/io/ask-for-input.js +0 -14
- package/dist/io/exit-if-invalid.d.ts +0 -4
- package/dist/io/exit-if-invalid.js +0 -9
- package/dist/io/glob-sync.d.ts +0 -11
- package/dist/io/glob-sync.js +0 -14
- package/dist/io/index.d.ts +0 -27
- package/dist/io/index.js +0 -26
- package/dist/io/read-config-file.d.ts +0 -7
- package/dist/io/read-config-file.js +0 -24
- package/dist/io/read-file-sync.d.ts +0 -12
- package/dist/io/read-file-sync.js +0 -9
- package/dist/io/read-json-file-sync.d.ts +0 -31
- package/dist/io/read-json-file-sync.js +0 -23
- package/dist/io/read-yaml-file-sync.d.ts +0 -12
- package/dist/io/read-yaml-file-sync.js +0 -9
- package/dist/io/to-formatted-json.d.ts +0 -9
- package/dist/io/to-formatted-json.js +0 -32
- package/dist/io/write-file-sync.d.ts +0 -12
- package/dist/io/write-file-sync.js +0 -10
- package/dist/io/write-if-changed.d.ts +0 -5
- package/dist/io/write-if-changed.js +0 -9
- package/dist/lib/format-repository-url.d.ts +0 -1
- package/dist/lib/format-repository-url.js +0 -40
- package/dist/lib/get-group-header.d.ts +0 -10
- package/dist/lib/get-group-header.js +0 -25
- package/dist/lib/get.d.ts +0 -11
- package/dist/lib/get.js +0 -44
- package/dist/lib/pad-start.d.ts +0 -1
- package/dist/lib/pad-start.js +0 -3
- package/dist/lib/ring-buffer.d.ts +0 -10
- package/dist/lib/ring-buffer.js +0 -20
- package/dist/lib/set-semver-range.d.ts +0 -3
- package/dist/lib/set-semver-range.js +0 -24
- package/dist/lib/show-help-on-error.d.ts +0 -2
- package/dist/lib/show-help-on-error.js +0 -32
- package/dist/lib/sort-by-name.d.ts +0 -5
- package/dist/lib/sort-by-name.js +0 -9
- package/dist/lib/with-logger.d.ts +0 -2
- package/dist/lib/with-logger.js +0 -28
- package/dist/option.d.ts +0 -10
- package/dist/option.js +0 -30
- package/dist/report.d.ts +0 -131
- package/dist/report.js +0 -129
- package/dist/schema.json +0 -614
- package/dist/semver-group/create-semver-groups.d.ts +0 -4
- package/dist/semver-group/create-semver-groups.js +0 -83
- package/dist/semver-group/disabled.d.ts +0 -26
- package/dist/semver-group/disabled.js +0 -28
- package/dist/semver-group/filtered-out.d.ts +0 -27
- package/dist/semver-group/filtered-out.js +0 -34
- package/dist/semver-group/ignored.d.ts +0 -22
- package/dist/semver-group/ignored.js +0 -24
- package/dist/semver-group/index.d.ts +0 -20
- package/dist/semver-group/index.js +0 -7
- package/dist/semver-group/with-range.d.ts +0 -22
- package/dist/semver-group/with-range.js +0 -45
- package/dist/specifier/alias.d.ts +0 -17
- package/dist/specifier/alias.js +0 -21
- package/dist/specifier/base.d.ts +0 -41
- package/dist/specifier/base.js +0 -54
- package/dist/specifier/delete.d.ts +0 -17
- package/dist/specifier/delete.js +0 -16
- package/dist/specifier/exact.d.ts +0 -20
- package/dist/specifier/exact.js +0 -21
- package/dist/specifier/file.d.ts +0 -8
- package/dist/specifier/file.js +0 -7
- package/dist/specifier/hosted-git.d.ts +0 -15
- package/dist/specifier/hosted-git.js +0 -24
- package/dist/specifier/index.d.ts +0 -28
- package/dist/specifier/index.js +0 -75
- package/dist/specifier/latest.d.ts +0 -19
- package/dist/specifier/latest.js +0 -20
- package/dist/specifier/lib/non-semver-error.d.ts +0 -11
- package/dist/specifier/lib/non-semver-error.js +0 -6
- package/dist/specifier/lib/parse-specifier.d.ts +0 -14
- package/dist/specifier/lib/parse-specifier.js +0 -18
- package/dist/specifier/lib/specific-registry-result.d.ts +0 -9
- package/dist/specifier/lib/specific-registry-result.js +0 -1
- package/dist/specifier/range.d.ts +0 -19
- package/dist/specifier/range.js +0 -20
- package/dist/specifier/tag.d.ts +0 -11
- package/dist/specifier/tag.js +0 -10
- package/dist/specifier/unsupported.d.ts +0 -7
- package/dist/specifier/unsupported.js +0 -7
- package/dist/specifier/url.d.ts +0 -8
- package/dist/specifier/url.js +0 -7
- package/dist/specifier/workspace-protocol.d.ts +0 -19
- package/dist/specifier/workspace-protocol.js +0 -35
- package/dist/strategy/lib/get-non-empty-string-prop.d.ts +0 -3
- package/dist/strategy/lib/get-non-empty-string-prop.js +0 -7
- package/dist/strategy/name-and-version-props.d.ts +0 -12
- package/dist/strategy/name-and-version-props.js +0 -60
- package/dist/strategy/named-version-string.d.ts +0 -11
- package/dist/strategy/named-version-string.js +0 -52
- package/dist/strategy/unnamed-version-string.d.ts +0 -11
- package/dist/strategy/unnamed-version-string.js +0 -45
- package/dist/strategy/versions-by-name.d.ts +0 -11
- package/dist/strategy/versions-by-name.js +0 -27
- package/dist/version-group/banned.d.ts +0 -17
- package/dist/version-group/banned.js +0 -26
- package/dist/version-group/create-version-groups.d.ts +0 -4
- package/dist/version-group/create-version-groups.js +0 -118
- package/dist/version-group/filtered-out.d.ts +0 -19
- package/dist/version-group/filtered-out.js +0 -30
- package/dist/version-group/ignored.d.ts +0 -17
- package/dist/version-group/ignored.js +0 -23
- package/dist/version-group/index.d.ts +0 -26
- package/dist/version-group/index.js +0 -7
- package/dist/version-group/lib/clean.d.ts +0 -2
- package/dist/version-group/lib/clean.js +0 -6
- package/dist/version-group/lib/delete.d.ts +0 -2
- package/dist/version-group/lib/delete.js +0 -1
- package/dist/version-group/lib/get-highest-version.d.ts +0 -6
- package/dist/version-group/lib/get-highest-version.js +0 -8
- package/dist/version-group/lib/get-lowest-version.d.ts +0 -6
- package/dist/version-group/lib/get-lowest-version.js +0 -8
- package/dist/version-group/lib/get-preferred-version.d.ts +0 -5
- package/dist/version-group/lib/get-preferred-version.js +0 -53
- package/dist/version-group/lib/get-range-score.d.ts +0 -2
- package/dist/version-group/lib/get-range-score.js +0 -20
- package/dist/version-group/lib/group-by.d.ts +0 -5
- package/dist/version-group/lib/group-by.js +0 -11
- package/dist/version-group/pinned.d.ts +0 -17
- package/dist/version-group/pinned.js +0 -26
- package/dist/version-group/same-range.d.ts +0 -19
- package/dist/version-group/same-range.js +0 -96
- package/dist/version-group/snapped-to.d.ts +0 -17
- package/dist/version-group/snapped-to.js +0 -71
- package/dist/version-group/standard.d.ts +0 -18
- package/dist/version-group/standard.js +0 -119
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk-template';
|
|
2
|
-
import { Context, Effect, flow, pipe } from 'effect';
|
|
3
|
-
import { uniq } from 'tightrope/array/uniq.js';
|
|
4
|
-
import { isString } from 'tightrope/guard/is-string.js';
|
|
5
|
-
import { logOtherCommands } from '../bin-list/list.js';
|
|
6
|
-
import { CliConfigTag } from '../config/tag.js';
|
|
7
|
-
import { ICON } from '../constants.js';
|
|
8
|
-
import { defaultErrorHandlers } from '../error-handlers/default-error-handlers.js';
|
|
9
|
-
import { getContext } from '../get-context/index.js';
|
|
10
|
-
import { getInstances } from '../get-instances/index.js';
|
|
11
|
-
import { askForChoice } from '../io/ask-for-choice.js';
|
|
12
|
-
import { askForInput } from '../io/ask-for-input.js';
|
|
13
|
-
import { exitIfInvalid } from '../io/exit-if-invalid.js';
|
|
14
|
-
import { IoTag } from '../io/index.js';
|
|
15
|
-
import { writeIfChanged } from '../io/write-if-changed.js';
|
|
16
|
-
import { getVersionGroupHeader } from '../lib/get-group-header.js';
|
|
17
|
-
import { withLogger } from '../lib/with-logger.js';
|
|
18
|
-
export function prompt({ io, cli, errorHandlers = defaultErrorHandlers, }) {
|
|
19
|
-
return pipe(getContext({ io, cli, errorHandlers }), Effect.flatMap(ctx => pipe(Effect.gen(function* ($) {
|
|
20
|
-
const { versionGroups } = yield* $(getInstances(ctx, io, errorHandlers));
|
|
21
|
-
let unfixableCount = 0;
|
|
22
|
-
let index = 0;
|
|
23
|
-
for (const group of versionGroups) {
|
|
24
|
-
const unfixable = [];
|
|
25
|
-
for (const groupReport of yield* $(group.inspectAll())) {
|
|
26
|
-
for (const report of groupReport.reports) {
|
|
27
|
-
if (isUnfixable(report)) {
|
|
28
|
-
unfixable.push(report);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
if (unfixable.length > 0) {
|
|
32
|
-
unfixableCount += unfixable.length;
|
|
33
|
-
Effect.logInfo(getVersionGroupHeader({ group, index }));
|
|
34
|
-
yield* $(askForNextVersion(groupReport, unfixable));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
index++;
|
|
38
|
-
}
|
|
39
|
-
if (unfixableCount) {
|
|
40
|
-
yield* $(writeIfChanged(ctx));
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
const msg = chalk `{green ${ICON.tick}} no issues which syncpack cannot fix automatically`;
|
|
44
|
-
yield* $(Effect.logInfo(msg));
|
|
45
|
-
yield* $(logOtherCommands());
|
|
46
|
-
}
|
|
47
|
-
return ctx;
|
|
48
|
-
}), Effect.catchTags({
|
|
49
|
-
WriteFileError: flow(errorHandlers.WriteFileError, Effect.map(() => {
|
|
50
|
-
ctx.isInvalid = true;
|
|
51
|
-
return ctx;
|
|
52
|
-
})),
|
|
53
|
-
}), Effect.flatMap(exitIfInvalid))), Effect.provide(pipe(Context.empty(), Context.add(CliConfigTag, cli), Context.add(IoTag, io))), withLogger);
|
|
54
|
-
}
|
|
55
|
-
function isUnfixable(report) {
|
|
56
|
-
return (report._tag === 'MissingLocalVersion' ||
|
|
57
|
-
report._tag === 'MissingSnappedToMismatch' ||
|
|
58
|
-
report._tag === 'SameRangeMismatch' ||
|
|
59
|
-
report._tag === 'UnsupportedMismatch');
|
|
60
|
-
}
|
|
61
|
-
function askForNextVersion(groupReport, unfixable) {
|
|
62
|
-
return pipe(Effect.gen(function* ($) {
|
|
63
|
-
const choices = uniq(groupReport.reports.map(report => report._tagGroup === 'Fixable'
|
|
64
|
-
? report.fixable.raw
|
|
65
|
-
: report._tagGroup === 'Unfixable'
|
|
66
|
-
? report.unfixable.rawSpecifier
|
|
67
|
-
: report._tagGroup === 'Valid'
|
|
68
|
-
? report.specifier.raw
|
|
69
|
-
: null)).filter(isString);
|
|
70
|
-
const other = chalk `{dim Other}`;
|
|
71
|
-
const skip = chalk `{dim Skip}`;
|
|
72
|
-
const quit = chalk `{dim Quit}`;
|
|
73
|
-
// Ask user to choose a version to align on
|
|
74
|
-
const choice = yield* $(askForChoice({
|
|
75
|
-
message: groupReport.name,
|
|
76
|
-
choices: [...choices, other, skip, quit],
|
|
77
|
-
}));
|
|
78
|
-
if (choice === skip) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
// @TODO: Learn https://www.effect.website/docs/data-types/exit
|
|
82
|
-
if (choice === quit) {
|
|
83
|
-
return process.exit(0);
|
|
84
|
-
}
|
|
85
|
-
const nextVersion = choice === other
|
|
86
|
-
? yield* $(askForInput({
|
|
87
|
-
message: chalk `${groupReport.name} {dim Enter a replacement version}`,
|
|
88
|
-
}))
|
|
89
|
-
: choice;
|
|
90
|
-
yield* $(pipe(unfixable, Effect.forEach(report => report.unfixable.write(nextVersion))));
|
|
91
|
-
}), Effect.catchTags({
|
|
92
|
-
AskForChoiceError: Effect.logDebug,
|
|
93
|
-
AskForInputError: Effect.logDebug,
|
|
94
|
-
}));
|
|
95
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import chalk from 'chalk-template';
|
|
3
|
-
import { program } from 'commander';
|
|
4
|
-
import { Effect } from 'effect';
|
|
5
|
-
import { io } from '../io/index.js';
|
|
6
|
-
import { showHelpOnError } from '../lib/show-help-on-error.js';
|
|
7
|
-
import { option } from '../option.js';
|
|
8
|
-
import { setSemverRanges } from './set-semver-ranges.js';
|
|
9
|
-
program.description(chalk `
|
|
10
|
-
Ensure dependency versions within {yellow dependencies}, {yellow devDependencies},
|
|
11
|
-
{yellow peerDependencies}, {yellow overrides}, and {yellow resolutions} follow a consistent format.`.replace(/^\n/, ''));
|
|
12
|
-
program.on('--help', () => { });
|
|
13
|
-
showHelpOnError(program);
|
|
14
|
-
program
|
|
15
|
-
.option(...option.source)
|
|
16
|
-
.option(...option.filter)
|
|
17
|
-
.option(...option.config)
|
|
18
|
-
.option(...option.specs)
|
|
19
|
-
.option(...option.types)
|
|
20
|
-
.option(...option.indent)
|
|
21
|
-
.parse(process.argv);
|
|
22
|
-
Effect.runPromise(setSemverRanges({
|
|
23
|
-
io,
|
|
24
|
-
cli: {
|
|
25
|
-
configPath: program.opts().config,
|
|
26
|
-
filter: program.opts().filter,
|
|
27
|
-
indent: program.opts().indent,
|
|
28
|
-
source: program.opts().source,
|
|
29
|
-
specs: program.opts().specs,
|
|
30
|
-
types: program.opts().types,
|
|
31
|
-
},
|
|
32
|
-
}));
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Effect } from 'effect';
|
|
2
|
-
import type { CliConfig } from '../config/types.js';
|
|
3
|
-
import type { ErrorHandlers } from '../error-handlers/default-error-handlers.js';
|
|
4
|
-
import type { Io } from '../io/index.js';
|
|
5
|
-
interface Input {
|
|
6
|
-
io: Io;
|
|
7
|
-
cli: Partial<CliConfig>;
|
|
8
|
-
errorHandlers?: ErrorHandlers;
|
|
9
|
-
}
|
|
10
|
-
export declare function setSemverRanges({ io, cli, errorHandlers, }: Input): Effect.Effect<unknown, never, never>;
|
|
11
|
-
export {};
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { Context, Effect, flow, pipe } from 'effect';
|
|
2
|
-
import { isNonEmptyArray } from 'tightrope/guard/is-non-empty-array.js';
|
|
3
|
-
import { fixMismatch, logAlreadyValidSize, logFixedSize, logUnfixableSize, } from '../bin-fix-mismatches/fix-mismatches.js';
|
|
4
|
-
import { logSemverGroupsDisabledWarning } from '../bin-lint-semver-ranges/lint-semver-ranges.js';
|
|
5
|
-
import { logUnsupportedMismatch } from '../bin-list-mismatches/list-mismatches.js';
|
|
6
|
-
import { CliConfigTag } from '../config/tag.js';
|
|
7
|
-
import { defaultErrorHandlers } from '../error-handlers/default-error-handlers.js';
|
|
8
|
-
import { getContext } from '../get-context/index.js';
|
|
9
|
-
import { getInstances } from '../get-instances/index.js';
|
|
10
|
-
import { exitIfInvalid } from '../io/exit-if-invalid.js';
|
|
11
|
-
import { IoTag } from '../io/index.js';
|
|
12
|
-
import { writeIfChanged } from '../io/write-if-changed.js';
|
|
13
|
-
import { withLogger } from '../lib/with-logger.js';
|
|
14
|
-
export function setSemverRanges({ io, cli, errorHandlers = defaultErrorHandlers, }) {
|
|
15
|
-
return pipe(getContext({ io, cli, errorHandlers }), Effect.flatMap(ctx => pipe(Effect.gen(function* ($) {
|
|
16
|
-
// no semver groups have been configured, they are disabled by default
|
|
17
|
-
if (!isNonEmptyArray(ctx.config.rcFile.semverGroups)) {
|
|
18
|
-
ctx.isInvalid = true;
|
|
19
|
-
yield* $(logSemverGroupsDisabledWarning());
|
|
20
|
-
return ctx;
|
|
21
|
-
}
|
|
22
|
-
const { semverGroups } = yield* $(getInstances(ctx, io, errorHandlers));
|
|
23
|
-
let fixedCount = 0;
|
|
24
|
-
let unfixableCount = 0;
|
|
25
|
-
let validCount = 0;
|
|
26
|
-
for (const group of semverGroups) {
|
|
27
|
-
if (group._tag === 'WithRange') {
|
|
28
|
-
for (const instance of group.instances) {
|
|
29
|
-
const report = yield* $(group.inspect(instance));
|
|
30
|
-
const _tag = report._tag;
|
|
31
|
-
if (_tag === 'SemverRangeMismatch') {
|
|
32
|
-
yield* $(fixMismatch(report));
|
|
33
|
-
fixedCount++;
|
|
34
|
-
}
|
|
35
|
-
else if (_tag === 'UnsupportedMismatch') {
|
|
36
|
-
yield* $(logUnsupportedMismatch(report));
|
|
37
|
-
unfixableCount++;
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
validCount++;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (validCount) {
|
|
46
|
-
yield* $(logAlreadyValidSize(validCount));
|
|
47
|
-
}
|
|
48
|
-
if (fixedCount) {
|
|
49
|
-
yield* $(logFixedSize(fixedCount));
|
|
50
|
-
}
|
|
51
|
-
if (unfixableCount) {
|
|
52
|
-
yield* $(logUnfixableSize(unfixableCount));
|
|
53
|
-
}
|
|
54
|
-
return ctx;
|
|
55
|
-
}), Effect.flatMap(writeIfChanged), Effect.catchTags({
|
|
56
|
-
WriteFileError: flow(errorHandlers.WriteFileError, Effect.map(() => {
|
|
57
|
-
ctx.isInvalid = true;
|
|
58
|
-
return ctx;
|
|
59
|
-
})),
|
|
60
|
-
}), Effect.flatMap(exitIfInvalid))), Effect.provide(pipe(Context.empty(), Context.add(CliConfigTag, cli), Context.add(IoTag, io))), withLogger);
|
|
61
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { Effect } from 'effect';
|
|
2
|
-
import type { Instance } from '../get-instances/instance.js';
|
|
3
|
-
declare const Releases_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Readonly<A> & {
|
|
4
|
-
readonly _tag: "Releases";
|
|
5
|
-
};
|
|
6
|
-
/** full release history from the npm registry for a given package */
|
|
7
|
-
declare class Releases extends Releases_base<{
|
|
8
|
-
instance: Instance;
|
|
9
|
-
versions: {
|
|
10
|
-
all: string[];
|
|
11
|
-
latest: string;
|
|
12
|
-
};
|
|
13
|
-
repoUrl: string | undefined;
|
|
14
|
-
}> {
|
|
15
|
-
}
|
|
16
|
-
declare const PromptCancelled_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Readonly<A> & {
|
|
17
|
-
readonly _tag: "PromptCancelled";
|
|
18
|
-
};
|
|
19
|
-
declare class PromptCancelled extends PromptCancelled_base<{
|
|
20
|
-
name: string;
|
|
21
|
-
}> {
|
|
22
|
-
}
|
|
23
|
-
declare const HttpError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Readonly<A> & {
|
|
24
|
-
readonly _tag: "HttpError";
|
|
25
|
-
};
|
|
26
|
-
declare class HttpError extends HttpError_base<{
|
|
27
|
-
error: string;
|
|
28
|
-
}> {
|
|
29
|
-
}
|
|
30
|
-
declare const NpmRegistryError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }) => Readonly<A> & {
|
|
31
|
-
readonly _tag: "NpmRegistryError";
|
|
32
|
-
};
|
|
33
|
-
declare class NpmRegistryError extends NpmRegistryError_base<{
|
|
34
|
-
error: string;
|
|
35
|
-
}> {
|
|
36
|
-
}
|
|
37
|
-
export declare const updateEffects: {
|
|
38
|
-
onFetchAllStart(): Effect.Effect<void, never, never>;
|
|
39
|
-
onFetchStart(instance: Instance, totalCount: number): Effect.Effect<void, never, never>;
|
|
40
|
-
onFetchEnd(instance: Instance, versions?: Releases["versions"]): Effect.Effect<void, never, never>;
|
|
41
|
-
/** After checking the registry, store this instance known to be up to date */
|
|
42
|
-
onUpToDate(instance: Instance): Effect.Effect<void, never, never>;
|
|
43
|
-
/** After checking the registry, store this instance known to have newer versions available */
|
|
44
|
-
onOutdated(instance: Instance, latest: string): Effect.Effect<void, never, never>;
|
|
45
|
-
/** As the last request completes, remove the progress information */
|
|
46
|
-
onFetchAllEnd(): Effect.Effect<void, never, never>;
|
|
47
|
-
/** Fetch available versions for a given package from the npm registry */
|
|
48
|
-
fetchLatestVersions(instance: Instance): Effect.Effect<Releases, HttpError | NpmRegistryError>;
|
|
49
|
-
/** Given responses from npm, ask the user which they want */
|
|
50
|
-
promptForUpdates(outdated: Releases[]): Effect.Effect<void, PromptCancelled>;
|
|
51
|
-
};
|
|
52
|
-
export {};
|
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
import https from 'node:https';
|
|
2
|
-
import { EOL } from 'node:os';
|
|
3
|
-
import * as Schema from '@effect/schema/Schema';
|
|
4
|
-
import chalk from 'chalk-template';
|
|
5
|
-
import { Data, Effect, identity, pipe } from 'effect';
|
|
6
|
-
import ora from 'ora';
|
|
7
|
-
import prompts from 'prompts';
|
|
8
|
-
import { diff } from 'semver';
|
|
9
|
-
import gtr from 'semver/ranges/gtr.js';
|
|
10
|
-
import { isArray } from 'tightrope/guard/is-array.js';
|
|
11
|
-
import { isEmptyObject } from 'tightrope/guard/is-empty-object.js';
|
|
12
|
-
import { ICON } from '../constants.js';
|
|
13
|
-
import { formatRepositoryUrl } from '../lib/format-repository-url.js';
|
|
14
|
-
import { RingBuffer } from '../lib/ring-buffer.js';
|
|
15
|
-
import { setSemverRange } from '../lib/set-semver-range.js';
|
|
16
|
-
import { Specifier } from '../specifier/index.js';
|
|
17
|
-
/** full release history from the npm registry for a given package */
|
|
18
|
-
class Releases extends Data.TaggedClass('Releases') {
|
|
19
|
-
}
|
|
20
|
-
// https://github.com/terkelg/prompts?tab=readme-ov-file#prompts
|
|
21
|
-
class PromptCancelled extends Data.TaggedClass('PromptCancelled') {
|
|
22
|
-
}
|
|
23
|
-
class HttpError extends Data.TaggedClass('HttpError') {
|
|
24
|
-
}
|
|
25
|
-
class NpmRegistryError extends Data.TaggedClass('NpmRegistryError') {
|
|
26
|
-
}
|
|
27
|
-
/** the API client for the terminal spinner */
|
|
28
|
-
let spinner = null;
|
|
29
|
-
/** how many HTTP requests have been sent */
|
|
30
|
-
let fetchedCount = 0;
|
|
31
|
-
/** how many instances have updates available */
|
|
32
|
-
let outdatedCount = 0;
|
|
33
|
-
/** names of instances currently being fetched from npm */
|
|
34
|
-
const inFlight = new Set();
|
|
35
|
-
/** names of instances most recently finished being fetched from npm */
|
|
36
|
-
const mostRecent = new RingBuffer(5);
|
|
37
|
-
/** page size when prompting */
|
|
38
|
-
const optionsPerPage = 50;
|
|
39
|
-
/** instance names in `inFlight` are formatted for display */
|
|
40
|
-
function format(instance) {
|
|
41
|
-
return chalk `{gray ${instance.name}}`;
|
|
42
|
-
}
|
|
43
|
-
/** we need to remove colours when sorting loading status output */
|
|
44
|
-
function stripAnsi(str) {
|
|
45
|
-
// eslint-disable-next-line no-control-regex
|
|
46
|
-
const ansiChars = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
|
|
47
|
-
return str.replace(ansiChars, '');
|
|
48
|
-
}
|
|
49
|
-
export const updateEffects = {
|
|
50
|
-
onFetchAllStart() {
|
|
51
|
-
if (!spinner) {
|
|
52
|
-
spinner = ora().start();
|
|
53
|
-
}
|
|
54
|
-
fetchedCount = 0;
|
|
55
|
-
return Effect.void;
|
|
56
|
-
},
|
|
57
|
-
onFetchStart(instance, totalCount) {
|
|
58
|
-
inFlight.add(format(instance));
|
|
59
|
-
fetchedCount++;
|
|
60
|
-
if (spinner) {
|
|
61
|
-
const indent = `${EOL} `;
|
|
62
|
-
const progress = new Set([
|
|
63
|
-
...mostRecent.filter(Boolean),
|
|
64
|
-
...inFlight.values(),
|
|
65
|
-
]);
|
|
66
|
-
const sortedProgress = Array.from(progress).sort((a, b) => stripAnsi(a).localeCompare(stripAnsi(b)));
|
|
67
|
-
const suffixText = sortedProgress.join(indent);
|
|
68
|
-
spinner.text = chalk `${outdatedCount} updates found in ${fetchedCount}/${totalCount} dependencies${indent}${suffixText}`;
|
|
69
|
-
}
|
|
70
|
-
return Effect.void;
|
|
71
|
-
},
|
|
72
|
-
onFetchEnd(instance, versions) {
|
|
73
|
-
inFlight.delete(format(instance));
|
|
74
|
-
const latest = versions?.latest;
|
|
75
|
-
if (latest) {
|
|
76
|
-
if (gtr(latest, String(instance.rawSpecifier.raw), true)) {
|
|
77
|
-
outdatedCount++;
|
|
78
|
-
mostRecent.push(chalk `${instance.name} {gray {red ${String(instance.rawSpecifier.raw)}} ${ICON.rightArrow}} {green ${latest}}`);
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
mostRecent.push(chalk `{green ${instance.name}}`);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return Effect.void;
|
|
85
|
-
},
|
|
86
|
-
/** After checking the registry, store this instance known to be up to date */
|
|
87
|
-
onUpToDate(instance) {
|
|
88
|
-
mostRecent.push(chalk `{green ${instance.name}}`);
|
|
89
|
-
return Effect.void;
|
|
90
|
-
},
|
|
91
|
-
/** After checking the registry, store this instance known to have newer versions available */
|
|
92
|
-
onOutdated(instance, latest) {
|
|
93
|
-
outdatedCount++;
|
|
94
|
-
mostRecent.push(chalk `${instance.name} {gray {red ${String(instance.rawSpecifier.raw)}} ${ICON.rightArrow}} {green ${latest}}`);
|
|
95
|
-
return Effect.void;
|
|
96
|
-
},
|
|
97
|
-
/** As the last request completes, remove the progress information */
|
|
98
|
-
onFetchAllEnd() {
|
|
99
|
-
if (spinner) {
|
|
100
|
-
spinner.stop();
|
|
101
|
-
}
|
|
102
|
-
spinner = null;
|
|
103
|
-
fetchedCount = 0;
|
|
104
|
-
return Effect.void;
|
|
105
|
-
},
|
|
106
|
-
/** Fetch available versions for a given package from the npm registry */
|
|
107
|
-
fetchLatestVersions(instance) {
|
|
108
|
-
return pipe(fetchJson(`https://registry.npmjs.org/${instance.name}`),
|
|
109
|
-
// parse and validate the specific data we expect
|
|
110
|
-
Effect.flatMap(Schema.decodeUnknownEither(Schema.Struct({
|
|
111
|
-
'dist-tags': Schema.Struct({ latest: Schema.String }),
|
|
112
|
-
time: Schema.Record({ key: Schema.String, value: Schema.String }),
|
|
113
|
-
homepage: Schema.optional(Schema.String),
|
|
114
|
-
repository: Schema.optional(Schema.Union(Schema.String, Schema.Struct({ url: Schema.optional(Schema.String) }))),
|
|
115
|
-
}))),
|
|
116
|
-
// transform it into something more appropriate
|
|
117
|
-
Effect.map(struct => {
|
|
118
|
-
const rawRepoUrl = typeof struct.repository === 'object'
|
|
119
|
-
? struct.repository.url
|
|
120
|
-
: struct.repository;
|
|
121
|
-
return new Releases({
|
|
122
|
-
instance,
|
|
123
|
-
versions: {
|
|
124
|
-
all: Object.keys(struct.time).filter(key => key !== 'modified' && key !== 'created'),
|
|
125
|
-
latest: struct['dist-tags'].latest,
|
|
126
|
-
},
|
|
127
|
-
repoUrl: formatRepositoryUrl(rawRepoUrl),
|
|
128
|
-
});
|
|
129
|
-
}),
|
|
130
|
-
// hide ParseErrors and just treat them as another kind of NpmRegistryError
|
|
131
|
-
Effect.catchTags({
|
|
132
|
-
ParseError: () => Effect.fail(new NpmRegistryError({
|
|
133
|
-
error: `Invalid response for ${instance.name}`,
|
|
134
|
-
})),
|
|
135
|
-
}));
|
|
136
|
-
},
|
|
137
|
-
/** Given responses from npm, ask the user which they want */
|
|
138
|
-
promptForUpdates(outdated) {
|
|
139
|
-
return pipe(Effect.Do, Effect.bind('releasesByType', () => groupByReleaseType(outdated)),
|
|
140
|
-
// Create choices to ask if they want major, minor, patch etc
|
|
141
|
-
Effect.bind('releaseTypeQuestions', ({ releasesByType }) => Effect.succeed(Object.keys(releasesByType)
|
|
142
|
-
.filter(type => releasesByType[type].length > 0)
|
|
143
|
-
.map(type => ({
|
|
144
|
-
title: chalk `${releasesByType[type].length} ${type}`,
|
|
145
|
-
selected: true,
|
|
146
|
-
value: type,
|
|
147
|
-
})))),
|
|
148
|
-
// Ask which release types (major, minor, patch etc) they want
|
|
149
|
-
Effect.bind('releaseTypeAnswers', ({ releaseTypeQuestions }) => releaseTypeQuestions.length > 0
|
|
150
|
-
? pipe(Effect.tryPromise({
|
|
151
|
-
try: () => prompts({
|
|
152
|
-
name: 'releaseTypeAnswers',
|
|
153
|
-
type: 'multiselect',
|
|
154
|
-
instructions: true,
|
|
155
|
-
message: `${outdated.length} updates are available`,
|
|
156
|
-
choices: releaseTypeQuestions,
|
|
157
|
-
}).then(res => res?.releaseTypeAnswers || []),
|
|
158
|
-
catch: identity,
|
|
159
|
-
}), Effect.catchAll(() => pipe(Effect.logError('Error when prompting for releaseTypeAnswers'), Effect.map(() => []))))
|
|
160
|
-
: Effect.succeed([])),
|
|
161
|
-
// For each chosen release type, list the available updates to choose from
|
|
162
|
-
Effect.bind('prepatchAnswers', doState => promptForReleaseType('prepatch', doState)), Effect.bind('patchAnswers', doState => promptForReleaseType('patch', doState)), Effect.bind('preminorAnswers', doState => promptForReleaseType('preminor', doState)), Effect.bind('minorAnswers', doState => promptForReleaseType('minor', doState)), Effect.bind('premajorAnswers', doState => promptForReleaseType('premajor', doState)), Effect.bind('majorAnswers', doState => promptForReleaseType('major', doState)), Effect.bind('prereleaseAnswers', doState => promptForReleaseType('prerelease', doState)),
|
|
163
|
-
/** Apply every update to the package.json files */
|
|
164
|
-
Effect.flatMap(doState => pipe([
|
|
165
|
-
...doState.prepatchAnswers,
|
|
166
|
-
...doState.patchAnswers,
|
|
167
|
-
...doState.preminorAnswers,
|
|
168
|
-
...doState.minorAnswers,
|
|
169
|
-
...doState.premajorAnswers,
|
|
170
|
-
...doState.majorAnswers,
|
|
171
|
-
...doState.prereleaseAnswers,
|
|
172
|
-
], Effect.forEach(({ instance, versions }) => pipe(instance.semverGroup.getFixed(Specifier.create(instance, versions.latest)), Effect.flatMap(latestWithRange => instance.write(latestWithRange.raw)), Effect.catchTag('NonSemverError', Effect.logError))), Effect.flatMap(() => Effect.void))));
|
|
173
|
-
},
|
|
174
|
-
};
|
|
175
|
-
function promptForReleaseType(releaseType, doState) {
|
|
176
|
-
const { releasesByType, releaseTypeAnswers } = doState;
|
|
177
|
-
const prop = `${releaseType}Answers`;
|
|
178
|
-
const releases = releasesByType[releaseType];
|
|
179
|
-
return releaseTypeAnswers.includes(releaseType)
|
|
180
|
-
? pipe(Effect.tryPromise({
|
|
181
|
-
try: () => prompts({
|
|
182
|
-
name: prop,
|
|
183
|
-
type: 'multiselect',
|
|
184
|
-
instructions: false,
|
|
185
|
-
// @ts-expect-error optionsPerPage *does* exist https://github.com/terkelg/prompts#options-7
|
|
186
|
-
optionsPerPage,
|
|
187
|
-
message: `${releases.length} ${releaseType} updates`,
|
|
188
|
-
choices: releases.map(updateable => {
|
|
189
|
-
const spacingValue = 50 -
|
|
190
|
-
updateable.instance.name.length -
|
|
191
|
-
String(updateable.instance.rawSpecifier).length -
|
|
192
|
-
updateable.versions.latest.length;
|
|
193
|
-
const spacing = Array.from({ length: spacingValue })
|
|
194
|
-
.fill(' ')
|
|
195
|
-
.join('');
|
|
196
|
-
const repoUrl = updateable.repoUrl
|
|
197
|
-
? chalk `${spacing} {white - ${updateable.repoUrl}}`
|
|
198
|
-
: '';
|
|
199
|
-
return {
|
|
200
|
-
title: chalk `${updateable.instance.name} {gray ${String(updateable.instance.rawSpecifier.raw)} ${ICON.rightArrow}} {green ${updateable.versions.latest}} ${repoUrl}`,
|
|
201
|
-
selected: true,
|
|
202
|
-
value: updateable,
|
|
203
|
-
};
|
|
204
|
-
}),
|
|
205
|
-
}),
|
|
206
|
-
catch: identity,
|
|
207
|
-
}),
|
|
208
|
-
// Paper over errors in terkelg/prompts for now
|
|
209
|
-
Effect.catchAll(() => pipe(Effect.logError(`terkelg/prompts errored while prompting for ${prop}`), Effect.map(() => ({ [prop]: [] })))),
|
|
210
|
-
// In terkelg/prompts, an empty object means that the user cancelled via
|
|
211
|
-
// ctrl+c or the escape key etc. Handle this case so we can skip any
|
|
212
|
-
// remaining steps.
|
|
213
|
-
Effect.flatMap(res => isEmptyObject(res)
|
|
214
|
-
? Effect.fail(new PromptCancelled({ name: releaseType }))
|
|
215
|
-
: Effect.succeed(isArray(res?.[prop]) ? res?.[prop] : [])))
|
|
216
|
-
: Effect.succeed([]);
|
|
217
|
-
}
|
|
218
|
-
function groupByReleaseType(releases) {
|
|
219
|
-
return Effect.succeed(releases.reduce((releasesByType, release) => {
|
|
220
|
-
const previous = setSemverRange('', String(release.instance.rawSpecifier.raw));
|
|
221
|
-
const latest = release.versions.latest;
|
|
222
|
-
try {
|
|
223
|
-
const type = diff(previous, latest);
|
|
224
|
-
if (type && releasesByType[type]) {
|
|
225
|
-
releasesByType[type].push(release);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
catch {
|
|
229
|
-
//
|
|
230
|
-
}
|
|
231
|
-
return releasesByType;
|
|
232
|
-
}, {
|
|
233
|
-
prepatch: [],
|
|
234
|
-
patch: [],
|
|
235
|
-
preminor: [],
|
|
236
|
-
minor: [],
|
|
237
|
-
premajor: [],
|
|
238
|
-
major: [],
|
|
239
|
-
prerelease: [],
|
|
240
|
-
}));
|
|
241
|
-
}
|
|
242
|
-
// @TODO: add a cache with a short TTL on disk in $TMPDIR
|
|
243
|
-
function fetchJson(url) {
|
|
244
|
-
return pipe(Effect.async(resume => {
|
|
245
|
-
// setTimeout(
|
|
246
|
-
// () => {
|
|
247
|
-
// resume(
|
|
248
|
-
// Effect.succeed(
|
|
249
|
-
// JSON.stringify({
|
|
250
|
-
// 'dist-tags': { latest: '3.1.1' },
|
|
251
|
-
// 'time': {
|
|
252
|
-
// '0.3.1': new Date().toJSON(),
|
|
253
|
-
// },
|
|
254
|
-
// }),
|
|
255
|
-
// ),
|
|
256
|
-
// );
|
|
257
|
-
// },
|
|
258
|
-
// Math.floor(Math.random() * 500) + 1,
|
|
259
|
-
// );
|
|
260
|
-
https
|
|
261
|
-
.get(url, res => {
|
|
262
|
-
let body = '';
|
|
263
|
-
res.setEncoding('utf8');
|
|
264
|
-
res.on('data', chunk => {
|
|
265
|
-
body = `${body}${chunk}`;
|
|
266
|
-
});
|
|
267
|
-
res.on('end', () => {
|
|
268
|
-
resume(Effect.succeed(body));
|
|
269
|
-
});
|
|
270
|
-
})
|
|
271
|
-
.on('error', err => {
|
|
272
|
-
resume(Effect.fail(new HttpError({
|
|
273
|
-
error: `Node https threw on ${url}: ${String(err)}`,
|
|
274
|
-
})));
|
|
275
|
-
});
|
|
276
|
-
}), Effect.flatMap(body => Effect.try({
|
|
277
|
-
try: () => JSON.parse(body),
|
|
278
|
-
catch: () => new NpmRegistryError({
|
|
279
|
-
error: `JSON.parse threw on response from ${url}`,
|
|
280
|
-
}),
|
|
281
|
-
})));
|
|
282
|
-
}
|
package/dist/bin-update/index.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { program } from 'commander';
|
|
3
|
-
import { Effect } from 'effect';
|
|
4
|
-
import { io } from '../io/index.js';
|
|
5
|
-
import { showHelpOnError } from '../lib/show-help-on-error.js';
|
|
6
|
-
import { option } from '../option.js';
|
|
7
|
-
import { update } from './update.js';
|
|
8
|
-
program.description(' Update to the latest versions on the npm registry.');
|
|
9
|
-
program.on('--help', () => { });
|
|
10
|
-
showHelpOnError(program);
|
|
11
|
-
program
|
|
12
|
-
.option(...option.source)
|
|
13
|
-
.option(...option.filter)
|
|
14
|
-
.option(...option.config)
|
|
15
|
-
.option(...option.specs)
|
|
16
|
-
.option(...option.types)
|
|
17
|
-
.parse(process.argv);
|
|
18
|
-
Effect.runPromise(update(io, {
|
|
19
|
-
configPath: program.opts().config,
|
|
20
|
-
filter: program.opts().filter,
|
|
21
|
-
source: program.opts().source,
|
|
22
|
-
specs: program.opts().specs,
|
|
23
|
-
types: program.opts().types,
|
|
24
|
-
}));
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { Effect } from 'effect';
|
|
2
|
-
import type { CliConfig } from '../config/types.js';
|
|
3
|
-
import type { ErrorHandlers } from '../error-handlers/default-error-handlers.js';
|
|
4
|
-
import type { Io } from '../io/index.js';
|
|
5
|
-
import { updateEffects } from './effects.js';
|
|
6
|
-
export declare function update(io: Io, cli: Partial<CliConfig>, effects?: typeof updateEffects, errorHandlers?: ErrorHandlers): Effect.Effect<unknown, never, never>;
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk-template';
|
|
2
|
-
import { Context, Effect, flow, pipe } from 'effect';
|
|
3
|
-
import { gtr } from 'semver';
|
|
4
|
-
import { CliConfigTag } from '../config/tag.js';
|
|
5
|
-
import { ICON } from '../constants.js';
|
|
6
|
-
import { defaultErrorHandlers } from '../error-handlers/default-error-handlers.js';
|
|
7
|
-
import { getContext } from '../get-context/index.js';
|
|
8
|
-
import { getInstances } from '../get-instances/index.js';
|
|
9
|
-
import { exitIfInvalid } from '../io/exit-if-invalid.js';
|
|
10
|
-
import { IoTag } from '../io/index.js';
|
|
11
|
-
import { writeIfChanged } from '../io/write-if-changed.js';
|
|
12
|
-
import { withLogger } from '../lib/with-logger.js';
|
|
13
|
-
import { Specifier } from '../specifier/index.js';
|
|
14
|
-
import { updateEffects } from './effects.js';
|
|
15
|
-
export function update(io, cli, effects = updateEffects, errorHandlers = defaultErrorHandlers) {
|
|
16
|
-
return pipe(Effect.Do, Effect.bind('ctx', () => getContext({ io, cli, errorHandlers })), Effect.bind('instances', ({ ctx }) => getInstances(ctx, io, errorHandlers)), Effect.bind('update', ({ instances }) => pipe(Effect.succeed(instances.all), Effect.map(instances => {
|
|
17
|
-
const isVisitedByName = {};
|
|
18
|
-
const updateable = [];
|
|
19
|
-
instances.forEach(instance => {
|
|
20
|
-
if (!isVisitedByName[instance.name] &&
|
|
21
|
-
(instance.versionGroup._tag === 'SameRange' ||
|
|
22
|
-
instance.versionGroup._tag === 'Standard')) {
|
|
23
|
-
const specifier = Specifier.create(instance, instance.rawSpecifier.raw);
|
|
24
|
-
if (specifier._tag === 'Range' || specifier._tag === 'Exact') {
|
|
25
|
-
isVisitedByName[instance.name] = true;
|
|
26
|
-
updateable.push(instance);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
return updateable;
|
|
31
|
-
}), Effect.tap(updateEffects.onFetchAllStart), Effect.flatMap(instances => pipe(instances, Effect.partition(instance => pipe(Effect.succeed(instance), Effect.tap(() => updateEffects.onFetchStart(instance, instances.length)), Effect.flatMap(effects.fetchLatestVersions), Effect.tapBoth({
|
|
32
|
-
onFailure: () => updateEffects.onFetchEnd(instance),
|
|
33
|
-
onSuccess: ({ versions }) => updateEffects.onFetchEnd(instance, versions),
|
|
34
|
-
}),
|
|
35
|
-
// move up to date dependencies to error channel
|
|
36
|
-
Effect.flatMap(updateable => gtr(updateable.versions.latest, String(instance.rawSpecifier.raw))
|
|
37
|
-
? pipe(updateEffects.onOutdated(instance, updateable.versions.latest), Effect.map(() => updateable))
|
|
38
|
-
: pipe(updateEffects.onUpToDate(instance), Effect.flatMap(() => Effect.fail(updateable)))),
|
|
39
|
-
// log error but don't catch it
|
|
40
|
-
Effect.tapErrorTag('HttpError', ({ error }) => Effect.logError(chalk `{red ${ICON.cross} ${error}}`)),
|
|
41
|
-
// log error but don't catch it
|
|
42
|
-
Effect.tapErrorTag('NpmRegistryError', ({ error }) => Effect.logError(chalk `{red ${ICON.cross} ${error}}`))), { concurrency: 10 }),
|
|
43
|
-
// discard errors and up to date dependencies
|
|
44
|
-
Effect.flatMap(([_, outOfDate]) => Effect.succeed(outOfDate)))),
|
|
45
|
-
// always remove the spinner when we're done
|
|
46
|
-
Effect.tapBoth({
|
|
47
|
-
onFailure: updateEffects.onFetchAllEnd,
|
|
48
|
-
onSuccess: updateEffects.onFetchAllEnd,
|
|
49
|
-
}),
|
|
50
|
-
// ask the user which updates they want
|
|
51
|
-
Effect.flatMap(updateEffects.promptForUpdates),
|
|
52
|
-
// if we think the user cancelled, say so
|
|
53
|
-
Effect.catchTag('PromptCancelled', () => Effect.logInfo(chalk `{red ${ICON.panic}} aborting after {blue syncpack update} was cancelled`)))), Effect.flatMap(({ ctx }) => pipe(writeIfChanged(ctx), Effect.catchTags({
|
|
54
|
-
WriteFileError: flow(errorHandlers.WriteFileError, Effect.map(() => {
|
|
55
|
-
ctx.isInvalid = true;
|
|
56
|
-
return ctx;
|
|
57
|
-
})),
|
|
58
|
-
}))), Effect.flatMap(exitIfInvalid), Effect.withConcurrency(10), Effect.provide(pipe(Context.empty(), Context.add(CliConfigTag, cli), Context.add(IoTag, io))), withLogger);
|
|
59
|
-
}
|
package/dist/bin.d.ts
DELETED