syncpack 12.0.0-alpha.1 → 12.0.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/README.md CHANGED
@@ -8,13 +8,6 @@
8
8
  npm install --save-dev syncpack
9
9
  ```
10
10
 
11
- <!-- prettier-ignore-start -->
12
-
13
- > [!NOTE]
14
- > syncpack 🚀 [12.0.0-alpha.0](https://github.com/JamieMason/syncpack/releases/tag/12.0.0-alpha.0) is available to trial and give feedback. This release adds support for a much wider range of npm version specifiers than before, console output improvements, and more.
15
-
16
- <!-- prettier-ignore-end -->
17
-
18
11
  ## Documentation
19
12
 
20
13
  Full information can be found in the documentation at https://jamiemason.github.io/syncpack/.
@@ -88,7 +88,7 @@ function logSemverRangeMismatch(report) {
88
88
  const expected = report.fixable.raw;
89
89
  const propPath = instance.strategy.path;
90
90
  const filePath = instance.packageJsonFile.jsonFile.shortPath;
91
- return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {green ${expected}} {gray ${filePath} > ${propPath}} {gray.dim [${_tag}]}`);
91
+ return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {green ${expected}} {gray ${filePath} > ${propPath}} {blue [${_tag}]}`);
92
92
  }
93
93
  function logUnsupportedMismatch(report) {
94
94
  const _tag = report._tag;
@@ -97,5 +97,5 @@ function logUnsupportedMismatch(report) {
97
97
  const actual = instance.rawSpecifier;
98
98
  const propPath = instance.strategy.path;
99
99
  const filePath = instance.packageJsonFile.jsonFile.shortPath;
100
- return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross} name {white ${name}} or version {white ${actual}} are not supported} {gray ${filePath} > ${propPath}} {gray.dim [${_tag}]}`);
100
+ return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross} name {white ${name}} or version {white ${actual}} are not supported} {gray ${filePath} > ${propPath}} {blue [${_tag}]}`);
101
101
  }
@@ -55,7 +55,7 @@ function list({ io, cli, errorHandlers = default_error_handlers_1.defaultErrorHa
55
55
  if (_tag === 'Valid') {
56
56
  const actual = report.specifier.raw;
57
57
  matches.add(report.specifier._tag === 'UnsupportedSpecifier'
58
- ? (0, chalk_1.default) `{gray ${actual}} {gray.dim [UnsupportedSpecifier]}`
58
+ ? (0, chalk_1.default) `{gray ${actual}} {blue [UnsupportedMismatch]}`
59
59
  : (0, chalk_1.default) `{gray ${actual}}`);
60
60
  }
61
61
  else if (_tag === 'HighestSemverMismatch' ||
@@ -106,12 +106,12 @@ function getLogForFixable(report) {
106
106
  const _tag = report._tag;
107
107
  const actual = report.fixable.instance.rawSpecifier;
108
108
  const expected = report.fixable.raw;
109
- return (0, chalk_1.default) `{red ${actual}} {gray ${constants_1.ICON.rightArrow}} {green ${expected}} {gray.dim [${_tag}]}`;
109
+ return (0, chalk_1.default) `{red ${actual}} {gray ${constants_1.ICON.rightArrow}} {green ${expected}} {blue [${_tag}]}`;
110
110
  }
111
111
  function getLogForUnfixable(report) {
112
112
  const _tag = report._tag;
113
113
  const actual = report.unfixable.rawSpecifier;
114
- return (0, chalk_1.default) `{red ${actual}} {gray ${constants_1.ICON.rightArrow}} {gray.dim [${_tag}]}`;
114
+ return (0, chalk_1.default) `{red ${actual}} {gray ${constants_1.ICON.rightArrow}} {blue [${_tag}]}`;
115
115
  }
116
116
  function logOtherCommands() {
117
117
  return effect_1.Effect.logInfo([
@@ -136,7 +136,7 @@ function logBanned(report) {
136
136
  const jsonFile = instance.packageJsonFile.jsonFile;
137
137
  const path = instance.strategy.path;
138
138
  const shortPath = jsonFile.shortPath;
139
- return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red banned} {gray ${shortPath} > ${path}} {gray.dim [${_tag}]}`);
139
+ return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red banned} {gray ${shortPath} > ${path}} {blue [${_tag}]}`);
140
140
  }
141
141
  function logHighestSemverMismatch(report) {
142
142
  const _tag = report._tag;
@@ -148,7 +148,7 @@ function logHighestSemverMismatch(report) {
148
148
  const name = instance.name;
149
149
  const path = instance.strategy.path;
150
150
  const shortPath = jsonFile.shortPath;
151
- return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {green ${expected}} {gray ${shortPath} > ${path}} {gray.dim [${_tag}]}`);
151
+ return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {green ${expected}} {gray ${shortPath} > ${path}} {blue [${_tag}]}`);
152
152
  }
153
153
  function logLocalPackageMismatch(report) {
154
154
  const _tag = report._tag;
@@ -159,7 +159,7 @@ function logLocalPackageMismatch(report) {
159
159
  const name = instance.name;
160
160
  const path = instance.strategy.path;
161
161
  const shortPath = instance.packageJsonFile.jsonFile.shortPath;
162
- return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {green ${expected}} {gray ${shortPath} > ${path}} {gray.dim [${_tag}]}`);
162
+ return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {green ${expected}} {gray ${shortPath} > ${path}} {blue [${_tag}]}`);
163
163
  }
164
164
  function logLowestSemverMismatch(report) {
165
165
  const _tag = report._tag;
@@ -170,7 +170,7 @@ function logLowestSemverMismatch(report) {
170
170
  const name = instance.name;
171
171
  const path = instance.strategy.path;
172
172
  const shortPath = instance.packageJsonFile.jsonFile.shortPath;
173
- return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {green ${expected}} {gray ${shortPath} > ${path}} {gray.dim [${_tag}]}`);
173
+ return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {green ${expected}} {gray ${shortPath} > ${path}} {blue [${_tag}]}`);
174
174
  }
175
175
  function logPinnedMismatch(report) {
176
176
  const _tag = report._tag;
@@ -181,7 +181,7 @@ function logPinnedMismatch(report) {
181
181
  const name = instance.name;
182
182
  const path = instance.strategy.path;
183
183
  const shortPath = instance.packageJsonFile.jsonFile.shortPath;
184
- return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {green ${expected}} {gray ${shortPath} > ${path}} {gray.dim [${_tag}]}`);
184
+ return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {green ${expected}} {gray ${shortPath} > ${path}} {blue [${_tag}]}`);
185
185
  }
186
186
  function logSemverRangeMismatch(report) {
187
187
  const _tag = report._tag;
@@ -192,7 +192,7 @@ function logSemverRangeMismatch(report) {
192
192
  const name = instance.name;
193
193
  const path = instance.strategy.path;
194
194
  const shortPath = instance.packageJsonFile.jsonFile.shortPath;
195
- return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {green ${expected}} {gray ${shortPath} > ${path}} {gray.dim [${_tag}]}`);
195
+ return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {green ${expected}} {gray ${shortPath} > ${path}} {blue [${_tag}]}`);
196
196
  }
197
197
  function logSnappedToMismatch(report) {
198
198
  const _tag = report._tag;
@@ -203,7 +203,7 @@ function logSnappedToMismatch(report) {
203
203
  const name = instance.name;
204
204
  const path = instance.strategy.path;
205
205
  const shortPath = instance.packageJsonFile.jsonFile.shortPath;
206
- return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {green ${expected}} {gray ${shortPath} > ${path}} {gray.dim [${_tag}]}`);
206
+ return effect_1.Effect.logInfo((0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {green ${expected}} {gray ${shortPath} > ${path}} {blue [${_tag}]}`);
207
207
  }
208
208
  function logMissingLocalVersion(report) {
209
209
  const instance = report.unfixable;
@@ -214,7 +214,7 @@ function logMissingLocalVersion(report) {
214
214
  const path = instance.strategy.path;
215
215
  const shortPath = jsonFile.shortPath;
216
216
  return effect_1.Effect.logInfo([
217
- (0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {red ???} {gray ${shortPath} > ${path}} {gray.dim [missing local version]}`,
217
+ (0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {red ???} {gray ${shortPath} > ${path}} {blue [MissingLocalVersion]}`,
218
218
  (0, chalk_1.default) ` {red ${localPath} does not have a .version property which is exact semver}`,
219
219
  ].join(os_1.EOL));
220
220
  }
@@ -227,7 +227,7 @@ function logMissingSnappedToMismatch(report) {
227
227
  const path = instance.strategy.path;
228
228
  const shortPath = jsonFile.shortPath;
229
229
  return effect_1.Effect.logInfo([
230
- (0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {red ???} {gray ${shortPath} > ${path}} {gray.dim [missing snapTo version]}`,
230
+ (0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {red ???} {gray ${shortPath} > ${path}} {blue [MissingSnappedToMismatch]}`,
231
231
  (0, chalk_1.default) ` {red no package in this groups .snapTo array depend on ${name}}`,
232
232
  ].join(os_1.EOL));
233
233
  }
@@ -240,7 +240,7 @@ function logUnsupportedMismatch(report) {
240
240
  const path = instance.strategy.path;
241
241
  const shortPath = jsonFile.shortPath;
242
242
  return effect_1.Effect.logInfo([
243
- (0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {red ???} {gray ${shortPath} > ${path}} {gray.dim [unsupported mismatch]}`,
243
+ (0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red ${actual}} {dim ${constants_1.ICON.rightArrow}} {red ???} {gray ${shortPath} > ${path}} {blue [UnsupportedMismatch]}`,
244
244
  (0, chalk_1.default) ` {red use {blue syncpack prompt} to fix this manually}`,
245
245
  ].join(os_1.EOL));
246
246
  }
@@ -254,7 +254,7 @@ function logSameRangeMismatch(report) {
254
254
  const shortPath = jsonFile.shortPath;
255
255
  const mismatches = report.mismatches;
256
256
  return effect_1.Effect.logInfo([
257
- (0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red range ${actual} does not include ${mismatches.join(', ')}} {gray ${shortPath} > ${path}} {gray.dim [same range mismatch]}`,
257
+ (0, chalk_1.default) `{red ${constants_1.ICON.cross}} ${name} {red range ${actual} does not include ${mismatches.join(', ')}} {gray ${shortPath} > ${path}} {blue [SameRangeMismatch]}`,
258
258
  (0, chalk_1.default) ` {gray use {blue syncpack prompt} to fix this manually}`,
259
259
  ].join(os_1.EOL));
260
260
  }
@@ -10,6 +10,7 @@ declare class Releases extends Releases_base<{
10
10
  all: string[];
11
11
  latest: string;
12
12
  };
13
+ repoUrl: string | undefined;
13
14
  }> {
14
15
  }
15
16
  declare const PromptCancelled_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").Equals<Omit<A, keyof import("effect/Equal").Equal>, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" | keyof import("effect/Equal").Equal ? never : P]: A[P]; }) => Data.Data<Readonly<A> & {
@@ -39,6 +39,7 @@ const gtr_1 = __importDefault(require("semver/ranges/gtr"));
39
39
  const is_array_1 = require("tightrope/guard/is-array");
40
40
  const is_empty_object_1 = require("tightrope/guard/is-empty-object");
41
41
  const constants_1 = require("../constants");
42
+ const format_repository_url_1 = require("../lib/format-repository-url");
42
43
  const ring_buffer_1 = require("../lib/ring-buffer");
43
44
  const set_semver_range_1 = require("../lib/set-semver-range");
44
45
  const specifier_1 = require("../specifier");
@@ -133,15 +134,21 @@ exports.updateEffects = {
133
134
  effect_1.Effect.flatMap(Schema.parse(Schema.struct({
134
135
  'dist-tags': Schema.struct({ latest: Schema.string }),
135
136
  'time': Schema.record(Schema.string, Schema.string),
137
+ 'homepage': Schema.optional(Schema.string),
138
+ 'repository': Schema.optional(Schema.union(Schema.string, Schema.struct({ url: Schema.optional(Schema.string) }))),
136
139
  }))),
137
140
  // transform it into something more appropriate
138
- effect_1.Effect.map((struct) => new Releases({
139
- instance,
140
- versions: {
141
- all: Object.keys(struct.time).filter((key) => key !== 'modified' && key !== 'created'),
142
- latest: struct['dist-tags'].latest,
143
- },
144
- })),
141
+ effect_1.Effect.map((struct) => {
142
+ const rawRepoUrl = typeof struct.repository === 'object' ? struct.repository.url : struct.repository;
143
+ return new Releases({
144
+ instance,
145
+ versions: {
146
+ all: Object.keys(struct.time).filter((key) => key !== 'modified' && key !== 'created'),
147
+ latest: struct['dist-tags'].latest,
148
+ },
149
+ repoUrl: (0, format_repository_url_1.formatRepositoryUrl)(rawRepoUrl),
150
+ });
151
+ }),
145
152
  // hide ParseErrors and just treat them as another kind of NpmRegistryError
146
153
  effect_1.Effect.catchTags({
147
154
  ParseError: () => effect_1.Effect.fail(new NpmRegistryError({ error: `Invalid response for ${instance.name}` })),
@@ -198,11 +205,21 @@ function promptForReleaseType(releaseType, doState) {
198
205
  // @ts-expect-error optionsPerPage *does* exist https://github.com/terkelg/prompts#options-7
199
206
  optionsPerPage,
200
207
  message: `${releases.length} ${releaseType} updates`,
201
- choices: releases.map((updateable) => ({
202
- title: (0, chalk_1.default) `${updateable.instance.name} {gray ${updateable.instance.rawSpecifier} ${constants_1.ICON.rightArrow}} {green ${updateable.versions.latest}}`,
203
- selected: true,
204
- value: updateable,
205
- })),
208
+ choices: releases.map((updateable) => {
209
+ const spacingValue = 50 -
210
+ updateable.instance.name.length -
211
+ updateable.instance.rawSpecifier.length -
212
+ updateable.versions.latest.length;
213
+ const spacing = Array.from({ length: spacingValue }).fill(' ').join('');
214
+ const repoUrl = updateable.repoUrl
215
+ ? (0, chalk_1.default) `${spacing} {white - ${updateable.repoUrl}}`
216
+ : '';
217
+ return {
218
+ title: (0, chalk_1.default) `${updateable.instance.name} {gray ${updateable.instance.rawSpecifier} ${constants_1.ICON.rightArrow}} {green ${updateable.versions.latest}} ${repoUrl}`,
219
+ selected: true,
220
+ value: updateable,
221
+ };
222
+ }),
206
223
  }),
207
224
  catch: effect_1.identity,
208
225
  }),
@@ -0,0 +1 @@
1
+ export declare function formatRepositoryUrl(input: string | undefined): string | undefined;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatRepositoryUrl = void 0;
4
+ function formatRepositoryUrl(input) {
5
+ if (!input)
6
+ return undefined;
7
+ const extractedUrl = input.match(/https?:\/\/[^\s]+/)?.[0];
8
+ if (extractedUrl) {
9
+ const withoutSuffix = removeSuffix(extractedUrl);
10
+ return withoutSuffix;
11
+ }
12
+ const isSSHProtocol = input.startsWith('git@');
13
+ if (isSSHProtocol) {
14
+ const withoutAffix = removeSuffix(removePrefix(input, 'git@'));
15
+ const [origin, path] = withoutAffix.split(':');
16
+ if (!origin || !path)
17
+ return undefined;
18
+ return `https://${origin}/${path}`;
19
+ }
20
+ const isShortcut = input.split('/').length === 2;
21
+ if (isShortcut)
22
+ return `https://github.com/${input}`;
23
+ const isGitProtocol = input.startsWith('git://');
24
+ if (isGitProtocol) {
25
+ const withoutAffix = removeSuffix(removePrefix(input));
26
+ return `https://${withoutAffix}`;
27
+ }
28
+ }
29
+ exports.formatRepositoryUrl = formatRepositoryUrl;
30
+ function removeSuffix(url, suffix = '.git') {
31
+ if (url.endsWith(suffix)) {
32
+ return url.slice(0, url.length - suffix.length);
33
+ }
34
+ return url;
35
+ }
36
+ function removePrefix(url, prefix = 'git://') {
37
+ if (url.startsWith(prefix)) {
38
+ return url.slice(prefix.length, url.length);
39
+ }
40
+ return url;
41
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "syncpack",
3
3
  "description": "Consistent dependency versions in large JavaScript Monorepos",
4
- "version": "12.0.0-alpha.1",
4
+ "version": "12.0.0",
5
5
  "author": "Jamie Mason <jamie@foldleft.io> (https://github.com/JamieMason)",
6
6
  "bin": {
7
7
  "syncpack": "dist/bin.js",
@@ -27,6 +27,7 @@
27
27
  "Luis Vieira (https://github.com/luisvieiragmr)",
28
28
  "Marais Rossouw (https://github.com/maraisr)",
29
29
  "Matt Sprague (https://github.com/uforic)",
30
+ "Michał Warać (https://github.com/auto200)",
30
31
  "Siraj (https://github.com/Syhner)",
31
32
  "Tom Fletcher (https://github.com/tom-fletcher)"
32
33
  ],
@@ -108,18 +109,18 @@
108
109
  },
109
110
  "repository": "JamieMason/syncpack",
110
111
  "scripts": {
111
- "build": "yarn clean && yarn build:source && yarn build:json-schema",
112
+ "build": "npm run clean && npm run build:source && npm run build:json-schema",
112
113
  "build:json-schema": "typescript-json-schema --noExtraProps src/index.ts RcFile --out dist/schema.json",
113
114
  "build:source": "tsc --project tsconfig.build.json",
114
115
  "clean": "rm -rf ./dist",
115
- "format": "yarn format:lint && yarn format:source",
116
- "format:lint": "yarn lint --fix",
116
+ "format": "npm run format:lint && npm run format:source",
117
+ "format:lint": "eslint --ext .ts . --fix",
117
118
  "format:source": "prettier --write .",
118
- "lint": "yarn lint:ts && yarn lint:eslint",
119
+ "lint": "npm run lint:ts && npm run lint:eslint",
119
120
  "lint:eslint": "eslint --ext .ts .",
120
121
  "lint:ts": "tsc --noEmit --project tsconfig.json",
121
- "prepack": "yarn build",
122
- "release": "release-it --increment=prerelease",
122
+ "prepack": "npm run build",
123
+ "release": "release-it",
123
124
  "test": "vitest run --config vitest.config.ts"
124
125
  }
125
126
  }