@badisi/latest-version 5.0.0 → 6.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
@@ -31,12 +31,13 @@
31
31
 
32
32
  ## Features
33
33
 
34
+ ✅ Get `installed` versions of packages *(if installed locally or globally with npm or yarn)*<br/>
34
35
  ✅ Get `latest` and `next` versions of packages *(from package registries)*<br/>
35
36
  ✅ Get `wanted` version of packages *(if a version range or a tag is provided)*<br/>
36
- Get `installed` version of packages *(if installed locally or globally)*<br/>
37
- ✅ Check if `updates` are available<br/>
37
+ Check if any `updates` are available<br/>
38
38
  ✅ Cache support to increase data retrieval performance<br/>
39
39
  ✅ Support public/private repositories and proxies<br/>
40
+ ✅ [Command line tool](#command-line-tool) that helps visualize packages updates<br/>
40
41
 
41
42
  ## Installation
42
43
 
@@ -69,7 +70,7 @@ import latestVersion from '@badisi/latest-version';
69
70
  const pkgs = await latestVersion(['npm', 'npm@1.3.2', 'npm@beta', '@scope/name@^5.0.2']);
70
71
 
71
72
  // Package.json
72
- const pkgs = await latestVersion(JSON.parse(readFileSync('package.json')));
73
+ const pkgs = await latestVersion(JSON.parse(readFileSync('package.json').toString()));
73
74
 
74
75
  // Using cache
75
76
  const pkg = await latestVersion('npm@^5.0.2', { useCache: true });
@@ -87,33 +88,43 @@ interface LatestVersionPackage {
87
88
  */
88
89
  name: string;
89
90
  /**
90
- * The current local or global installed version of the package (if installed).
91
+ * The current local installed version of the package (if installed).
91
92
  */
92
- installed?: string;
93
+ local?: string;
93
94
  /**
94
- * The latest version of the package found on the provided registry (if found).
95
+ * The current npm global installed version of the package (if installed).
95
96
  */
96
- latest?: string;
97
+ globalNpm?: string;
97
98
  /**
98
- * The next version of the package found on the provided registry (if found).
99
+ * The current yarn global installed version of the package (if installed).
99
100
  */
100
- next?: string;
101
+ globalYarn?: string;
101
102
  /**
102
- * The latest version of the package found on the provided registry and satisfied by the provided tag or version range (if provided).
103
+ * The latest version of the package found on the registry (if found).
103
104
  */
104
- wanted?: string;
105
+ latest?: string;
106
+ /**
107
+ * The next version of the package found on the registry (if found).
108
+ */
109
+ next?: string;
105
110
  /**
106
111
  * The tag or version range that was provided (if provided).
112
+ *
113
+ * @default "latest"
107
114
  */
108
115
  wantedTagOrRange?: string;
109
116
  /**
110
- * Whether the installed version (if any) could be upgraded or not.
117
+ * The latest version of the package found on the registry and satisfied by the wanted tag or version range.
118
+ */
119
+ wanted?: string;
120
+ /**
121
+ * Whether the local or global installed versions (if any) could be upgraded or not, based on the wanted version.
111
122
  */
112
123
  updatesAvailable: {
113
- latest: boolean;
114
- next: boolean;
115
- wanted: boolean;
116
- };
124
+ local: string | false;
125
+ globalNpm: string | false;
126
+ globalYarn: string | false;
127
+ } | false;
117
128
  /**
118
129
  * Any error that might have occurred during the process.
119
130
  */
@@ -129,22 +140,20 @@ interface LatestVersionOptions {
129
140
  * Awaiting the api to return might take time, depending on the network, and might impact your package loading performance.
130
141
  * You can use the cache mechanism to improve load performance and reduce unnecessary network requests.
131
142
  * If `useCache` is not supplied, the api will always check for updates and wait for every requests to return before returning itself.
132
- * If `useCache` is used, the api will always returned immediately, with either (for each provided packages):
133
- * 1) a latest/next version available if a cache was found
134
- * 2) no latest/next version available if no cache was found - in such case updates will be fetched in the background and a cache will
135
- * be created for each provided packages and made available for the next call to the api.
143
+ * If `useCache` is used, the api will either (for each provided packages):
144
+ * 1) return immediately if a cache was found.
145
+ * 2) fetch and wait for updates of that particular package then creates a cache for it so that it is available for the next call to the api.
136
146
  *
137
147
  * @default false
138
148
  */
139
149
  useCache?: boolean;
140
150
 
141
151
  /**
142
- * How long the cache for the provided packages should be used before being refreshed (in milliseconds).
152
+ * How long the cache for each provided packages should be used before being refreshed (in milliseconds).
143
153
  * If `useCache` is not supplied, this option has no effect.
144
154
  * If `0` is used, this will force the cache to refresh immediately:
145
- * 1) The api will returned immediately (without any latest nor next version available for the provided packages)
146
- * 2) New updates will be fetched in the background
147
- * 3) The cache for each provided packages will be refreshed and made available for the next call to the api
155
+ * 1) New updates will be fetched and waited
156
+ * 2) The cache for each provided packages will be refreshed and made available for the next call to the api
148
157
  *
149
158
  * @default ONE_DAY
150
159
  */
@@ -173,6 +182,23 @@ interface LatestVersionOptions {
173
182
  ```
174
183
 
175
184
 
185
+ ## Command line tool
186
+
187
+ The CLI utility will help you visualize any available updates for a given *package.json* file, a local *package.json* file or any provided package names.
188
+
189
+ ```sh
190
+ $ latest-version <packageJson|packageName...>
191
+
192
+ Examples:
193
+ $ lv
194
+ $ latest-version path/to/package.json
195
+ $ latest-version package1 package2 package3
196
+ ```
197
+
198
+ ![CLI utility preview][clipreview]
199
+
200
+
201
+
176
202
  ## Development
177
203
 
178
204
  See the [developer docs][developer].
@@ -193,6 +219,7 @@ Please read and follow the [Code of Conduct][codeofconduct] and help me keep thi
193
219
 
194
220
 
195
221
 
222
+ [clipreview]: https://github.com/badisi/latest-version/blob/main/cli_preview.png
196
223
  [developer]: https://github.com/badisi/latest-version/blob/main/DEVELOPER.md
197
224
  [contributing]: https://github.com/badisi/latest-version/blob/main/CONTRIBUTING.md
198
225
  [codeofconduct]: https://github.com/badisi/latest-version/blob/main/CODE_OF_CONDUCT.md
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ 'use strict';
4
+
5
+ require('../cli.js');
package/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/cli.js ADDED
@@ -0,0 +1,465 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __defProps = Object.defineProperties;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
+ var __getProtoOf = Object.getPrototypeOf;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
+ var __spreadValues = (a, b) => {
14
+ for (var prop in b ||= {})
15
+ if (__hasOwnProp.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ if (__getOwnPropSymbols)
18
+ for (var prop of __getOwnPropSymbols(b)) {
19
+ if (__propIsEnum.call(b, prop))
20
+ __defNormalProp(a, prop, b[prop]);
21
+ }
22
+ return a;
23
+ };
24
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
+ var __copyProps = (to, from, except, desc) => {
26
+ if (from && typeof from === "object" || typeof from === "function") {
27
+ for (let key of __getOwnPropNames(from))
28
+ if (!__hasOwnProp.call(to, key) && key !== except)
29
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
30
+ }
31
+ return to;
32
+ };
33
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
34
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
35
+ mod
36
+ ));
37
+ var __async = (__this, __arguments, generator) => {
38
+ return new Promise((resolve, reject) => {
39
+ var fulfilled = (value) => {
40
+ try {
41
+ step(generator.next(value));
42
+ } catch (e) {
43
+ reject(e);
44
+ }
45
+ };
46
+ var rejected = (value) => {
47
+ try {
48
+ step(generator.throw(value));
49
+ } catch (e) {
50
+ reject(e);
51
+ }
52
+ };
53
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
54
+ step((generator = generator.apply(__this, __arguments)).next());
55
+ });
56
+ };
57
+
58
+ // src/cli.ts
59
+ var import_safe = require("@colors/colors/safe");
60
+ var import_fs2 = require("fs");
61
+ var import_path2 = require("path");
62
+
63
+ // src/index.ts
64
+ var import_fs = require("fs");
65
+ var import_path = require("path");
66
+ var import_global_dirs = require("global-dirs");
67
+ var import_os = require("os");
68
+ var import_url = require("url");
69
+ var import_registry_url = __toESM(require("registry-auth-token/registry-url"));
70
+ var import_registry_auth_token = __toESM(require("registry-auth-token"));
71
+ var import_max_satisfying = __toESM(require("semver/ranges/max-satisfying"));
72
+ var import_gt = __toESM(require("semver/functions/gt"));
73
+ var ONE_DAY = 1e3 * 60 * 60 * 24;
74
+ var isPackageJson = (obj) => {
75
+ return obj.dependencies !== void 0 || obj.devDependencies !== void 0 || obj.peerDependencies !== void 0;
76
+ };
77
+ var downloadMetadata = (pkgName, options) => {
78
+ return new Promise((resolve, reject) => {
79
+ const i = pkgName.indexOf("/");
80
+ const pkgScope = i !== -1 ? pkgName.slice(0, i) : "";
81
+ const registryUrl = (options == null ? void 0 : options.registryUrl) || (0, import_registry_url.default)(pkgScope);
82
+ const pkgUrl = new import_url.URL(encodeURIComponent(pkgName).replace(/^%40/, "@"), registryUrl);
83
+ let requestOptions = {
84
+ headers: { accept: "application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*" },
85
+ host: pkgUrl.hostname,
86
+ path: pkgUrl.pathname,
87
+ port: pkgUrl.port
88
+ };
89
+ const authInfo = (0, import_registry_auth_token.default)(pkgUrl.toString(), { recursive: true });
90
+ if (authInfo && requestOptions.headers) {
91
+ requestOptions.headers.authorization = `${authInfo.type} ${authInfo.token}`;
92
+ }
93
+ if (options == null ? void 0 : options.requestOptions) {
94
+ requestOptions = __spreadValues(__spreadValues({}, requestOptions), options.requestOptions);
95
+ }
96
+ const { get } = pkgUrl.protocol === "https:" ? require("https") : require("http");
97
+ const request = get(requestOptions, (res) => {
98
+ if (res.statusCode === 200) {
99
+ let rawData = "";
100
+ res.setEncoding("utf8");
101
+ res.on("data", (chunk) => rawData += chunk);
102
+ res.once("end", () => {
103
+ res.setTimeout(0);
104
+ res.removeAllListeners();
105
+ try {
106
+ const pkgMetadata = JSON.parse(rawData);
107
+ return resolve({
108
+ name: pkgName,
109
+ lastUpdateDate: Date.now(),
110
+ versions: Object.keys(pkgMetadata.versions),
111
+ distTags: pkgMetadata["dist-tags"]
112
+ });
113
+ } catch (err) {
114
+ return reject(err);
115
+ }
116
+ });
117
+ } else {
118
+ res.removeAllListeners();
119
+ res.resume();
120
+ return reject(`Request error (${res.statusCode}): ${pkgUrl}`);
121
+ }
122
+ });
123
+ const abort = (error) => {
124
+ request.removeAllListeners();
125
+ request.destroy();
126
+ return reject(error);
127
+ };
128
+ request.once("timeout", () => abort(`Request timed out: ${pkgUrl}`));
129
+ request.once("error", (err) => abort(err));
130
+ });
131
+ };
132
+ var getCacheDir = (name = "@badisi/latest-version") => {
133
+ const homeDir = (0, import_os.homedir)();
134
+ switch (process.platform) {
135
+ case "darwin":
136
+ return (0, import_path.join)(homeDir, "Library", "Caches", name);
137
+ case "win32":
138
+ return (0, import_path.join)(process.env.LOCALAPPDATA || (0, import_path.join)(homeDir, "AppData", "Local"), name, "Cache");
139
+ default:
140
+ return (0, import_path.join)(process.env.XDG_CACHE_HOME || (0, import_path.join)(homeDir, ".cache"), name);
141
+ }
142
+ };
143
+ var saveMetadataToCache = (pkg) => {
144
+ const filePath = (0, import_path.join)(getCacheDir(), `${pkg.name}.json`);
145
+ if (!(0, import_fs.existsSync)((0, import_path.dirname)(filePath))) {
146
+ (0, import_fs.mkdirSync)((0, import_path.dirname)(filePath), { recursive: true });
147
+ }
148
+ (0, import_fs.writeFileSync)(filePath, JSON.stringify(pkg));
149
+ };
150
+ var getMetadataFromCache = (pkgName, options) => {
151
+ var _a;
152
+ const maxAge = (_a = options == null ? void 0 : options.cacheMaxAge) != null ? _a : ONE_DAY;
153
+ if (maxAge !== 0) {
154
+ const pkgCacheFilePath = (0, import_path.join)(getCacheDir(), `${pkgName}.json`);
155
+ if ((0, import_fs.existsSync)(pkgCacheFilePath)) {
156
+ const pkg = JSON.parse((0, import_fs.readFileSync)(pkgCacheFilePath).toString());
157
+ if (Date.now() - pkg.lastUpdateDate < maxAge) {
158
+ return pkg;
159
+ }
160
+ }
161
+ }
162
+ return void 0;
163
+ };
164
+ var getRegistryVersions = (pkgName, tagOrRange, options) => __async(void 0, null, function* () {
165
+ var _a, _b, _c;
166
+ let pkgMetadata;
167
+ if (pkgName.length && (options == null ? void 0 : options.useCache)) {
168
+ pkgMetadata = getMetadataFromCache(pkgName, options);
169
+ if (!pkgMetadata) {
170
+ pkgMetadata = yield downloadMetadata(pkgName, options);
171
+ saveMetadataToCache(pkgMetadata);
172
+ }
173
+ } else if (pkgName.length) {
174
+ pkgMetadata = yield downloadMetadata(pkgName, options);
175
+ }
176
+ const versions = {
177
+ latest: (_a = pkgMetadata == null ? void 0 : pkgMetadata.distTags) == null ? void 0 : _a.latest,
178
+ next: (_b = pkgMetadata == null ? void 0 : pkgMetadata.distTags) == null ? void 0 : _b.next
179
+ };
180
+ if (tagOrRange && (pkgMetadata == null ? void 0 : pkgMetadata.distTags) && (pkgMetadata == null ? void 0 : pkgMetadata.distTags[tagOrRange])) {
181
+ versions.wanted = pkgMetadata.distTags[tagOrRange];
182
+ } else if (tagOrRange && ((_c = pkgMetadata == null ? void 0 : pkgMetadata.versions) == null ? void 0 : _c.length)) {
183
+ versions.wanted = (0, import_max_satisfying.default)(pkgMetadata.versions, tagOrRange) || void 0;
184
+ }
185
+ return versions;
186
+ });
187
+ var getInstalledVersion = (pkgName, location = "local") => {
188
+ var _a, _b, _c, _d;
189
+ try {
190
+ if (location === "globalNpm") {
191
+ return (_a = require((0, import_path.join)(import_global_dirs.npm.packages, pkgName, "package.json"))) == null ? void 0 : _a.version;
192
+ } else if (location === "globalYarn") {
193
+ const yarnGlobalPkg = require((0, import_path.resolve)(import_global_dirs.yarn.packages, "..", "package.json"));
194
+ if (!((_b = yarnGlobalPkg == null ? void 0 : yarnGlobalPkg.dependencies) == null ? void 0 : _b[pkgName])) {
195
+ return void 0;
196
+ }
197
+ return (_c = require((0, import_path.join)(import_global_dirs.yarn.packages, pkgName, "package.json"))) == null ? void 0 : _c.version;
198
+ } else if (location === "local") {
199
+ const { root } = (0, import_path.parse)(process.cwd());
200
+ let path = process.cwd();
201
+ const localPaths = [(0, import_path.join)(path, "node_modules")];
202
+ while (path !== root) {
203
+ path = (0, import_path.dirname)(path);
204
+ localPaths.push((0, import_path.join)(path, "node_modules"));
205
+ }
206
+ for (const localPath of localPaths) {
207
+ const pkgPath = (0, import_path.join)(localPath, pkgName, "package.json");
208
+ if ((0, import_fs.existsSync)(pkgPath)) {
209
+ return (_d = require(pkgPath)) == null ? void 0 : _d.version;
210
+ }
211
+ }
212
+ }
213
+ return void 0;
214
+ } catch (e) {
215
+ return void 0;
216
+ }
217
+ };
218
+ var getInfo = (pkg, options) => __async(void 0, null, function* () {
219
+ const i = pkg.lastIndexOf("@");
220
+ let pkgInfo = {
221
+ name: i > 1 ? pkg.slice(0, i) : pkg,
222
+ wantedTagOrRange: i > 1 ? pkg.slice(i + 1) : "latest",
223
+ updatesAvailable: false
224
+ };
225
+ try {
226
+ pkgInfo = __spreadValues(__spreadProps(__spreadValues({}, pkgInfo), {
227
+ local: getInstalledVersion(pkgInfo.name, "local"),
228
+ globalNpm: getInstalledVersion(pkgInfo.name, "globalNpm"),
229
+ globalYarn: getInstalledVersion(pkgInfo.name, "globalYarn")
230
+ }), yield getRegistryVersions(pkgInfo.name, pkgInfo.wantedTagOrRange, options));
231
+ const local = pkgInfo.local && pkgInfo.wanted ? (0, import_gt.default)(pkgInfo.wanted, pkgInfo.local) ? pkgInfo.wanted : false : false;
232
+ const globalNpm = pkgInfo.globalNpm && pkgInfo.wanted ? (0, import_gt.default)(pkgInfo.wanted, pkgInfo.globalNpm) ? pkgInfo.wanted : false : false;
233
+ const globalYarn = pkgInfo.globalYarn && pkgInfo.wanted ? (0, import_gt.default)(pkgInfo.wanted, pkgInfo.globalYarn) ? pkgInfo.wanted : false : false;
234
+ pkgInfo.updatesAvailable = local || globalNpm || globalYarn ? { local, globalNpm, globalYarn } : false;
235
+ } catch (err) {
236
+ pkgInfo.error = (err == null ? void 0 : err.message) || err;
237
+ }
238
+ return pkgInfo;
239
+ });
240
+ var latestVersion = (arg, options) => __async(void 0, null, function* () {
241
+ const pkgs = [];
242
+ if (typeof arg === "string") {
243
+ pkgs.push(arg);
244
+ } else if (Array.isArray(arg)) {
245
+ pkgs.push(...arg);
246
+ } else if (isPackageJson(arg)) {
247
+ const addDeps = (deps) => {
248
+ if (deps) {
249
+ pkgs.push(...Object.keys(deps).map((key) => `${key}@${deps[key]}`));
250
+ }
251
+ };
252
+ addDeps(arg.dependencies);
253
+ addDeps(arg.devDependencies);
254
+ addDeps(arg.peerDependencies);
255
+ }
256
+ const jobs = yield Promise.allSettled(pkgs.map((pkg) => getInfo(pkg, options)));
257
+ const results = jobs.map((jobResult) => jobResult.value);
258
+ return typeof arg === "string" ? results[0] : results;
259
+ });
260
+ var src_default = latestVersion;
261
+
262
+ // src/cli.ts
263
+ var import_major = __toESM(require("semver/functions/major"));
264
+ var import_diff = __toESM(require("semver/functions/diff"));
265
+ var import_ora = __toESM(require("ora"));
266
+ var colorizeDiff = (from, to) => {
267
+ const toParts = to.split(".");
268
+ const diffIndex = from.split(".").findIndex((part, i) => part !== toParts[i]);
269
+ if (diffIndex !== -1) {
270
+ let color = import_safe.magenta;
271
+ if (toParts[0] !== "0") {
272
+ color = diffIndex === 0 ? import_safe.red : diffIndex === 1 ? import_safe.cyan : import_safe.green;
273
+ }
274
+ const start = toParts.slice(0, diffIndex).join(".");
275
+ const mid = diffIndex === 0 ? "" : ".";
276
+ const end = color(toParts.slice(diffIndex).join("."));
277
+ return `${start}${mid}${end}`;
278
+ }
279
+ return to;
280
+ };
281
+ var columnCellRenderer = (column, row) => {
282
+ var _a;
283
+ let text = (_a = row[column.attrName]) != null ? _a : "";
284
+ const gap = text.length < column.maxLength ? " ".repeat(column.maxLength - text.length) : "";
285
+ switch (column.attrName) {
286
+ case "name":
287
+ text = (0, import_safe.yellow)(text);
288
+ break;
289
+ case "installed":
290
+ case "separator":
291
+ text = (0, import_safe.blue)(text);
292
+ break;
293
+ case "wanted":
294
+ text = colorizeDiff(row.installed, text);
295
+ break;
296
+ case "latest":
297
+ if (text !== row.wanted) {
298
+ text = colorizeDiff(row.installed, text);
299
+ }
300
+ break;
301
+ default:
302
+ break;
303
+ }
304
+ return column.align === "right" ? `${gap}${text}` : `${text}${gap}`;
305
+ };
306
+ var columnHeaderRenderer = (column) => {
307
+ const text = column.label;
308
+ const gap = text.length < column.maxLength ? " ".repeat(column.maxLength - text.length) : "";
309
+ return column.align === "right" ? `${gap}${(0, import_safe.underline)(text)}` : `${(0, import_safe.underline)(text)}${gap}`;
310
+ };
311
+ var drawBox = (lines, color = import_safe.yellow, horizontalPadding = 3) => {
312
+ const maxLineWidth = lines.reduce((max, row) => Math.max(max, (0, import_safe.strip)(row).length), 0);
313
+ console.log(color(`\u250C${"\u2500".repeat(maxLineWidth + horizontalPadding * 2)}\u2510`));
314
+ lines.forEach((row) => {
315
+ const padding = " ".repeat(horizontalPadding);
316
+ const fullRow = `${row}${" ".repeat(maxLineWidth - (0, import_safe.strip)(row).length)}`;
317
+ console.log(`${color("\u2502")}${padding}${(0, import_safe.reset)(fullRow)}${padding}${color("\u2502")}`);
318
+ });
319
+ console.log(color(`\u2514${"\u2500".repeat(maxLineWidth + horizontalPadding * 2)}\u2518`));
320
+ };
321
+ var getTableColumns = (rows) => {
322
+ const columns = [
323
+ { label: "Package", attrName: "name", align: "left", maxLength: 0, items: [] },
324
+ { label: "Location", attrName: "location", align: "left", maxLength: 0, items: [] },
325
+ { label: "Installed", attrName: "installed", align: "right", maxLength: 0, items: [] },
326
+ { label: "", attrName: "tagOrRange", align: "right", maxLength: 0, items: [] },
327
+ { label: "", attrName: "separator", align: "center", maxLength: 0, items: [] },
328
+ { label: "Wanted", attrName: "wanted", align: "right", maxLength: 0, items: [] },
329
+ { label: "Latest", attrName: "latest", align: "right", maxLength: 0, items: [] }
330
+ ];
331
+ rows.forEach(
332
+ (row) => columns.forEach((column) => {
333
+ var _a;
334
+ column.maxLength = Math.max(column.label.length, column.maxLength, ((_a = row[column.attrName]) == null ? void 0 : _a.length) || 0);
335
+ })
336
+ );
337
+ return columns;
338
+ };
339
+ var getTableRows = (updates) => {
340
+ return updates.reduce((all, pkg) => {
341
+ const { name, latest, local, globalNpm, globalYarn, wantedTagOrRange, updatesAvailable } = pkg;
342
+ const getGroup = (a, b) => {
343
+ var _a;
344
+ if (b && (0, import_major.default)(b) === 0) {
345
+ return "majorVersionZero";
346
+ } else if (a && b) {
347
+ const releaseType = (_a = (0, import_diff.default)(a, b)) != null ? _a : "";
348
+ if (["major", "premajor", "prerelease"].includes(releaseType)) {
349
+ return "major";
350
+ } else if (["minor", "preminor"].includes(releaseType)) {
351
+ return "minor";
352
+ } else if (["patch", "prepatch"].includes(releaseType)) {
353
+ return "patch";
354
+ }
355
+ }
356
+ return "unknown";
357
+ };
358
+ const add = (group, location, installed, wanted) => all.push({
359
+ name: " " + (name != null ? name : "unknown"),
360
+ location: location != null ? location : "unknown",
361
+ installed: installed != null ? installed : "unknown",
362
+ latest: latest != null ? latest : "unknown",
363
+ tagOrRange: wantedTagOrRange != null ? wantedTagOrRange : "unknown",
364
+ separator: "\u2192",
365
+ wanted: wanted != null ? wanted : "unknown",
366
+ group
367
+ });
368
+ if (updatesAvailable) {
369
+ if (updatesAvailable.local) {
370
+ add(getGroup(local, updatesAvailable.local), "local", local, updatesAvailable.local);
371
+ }
372
+ if (updatesAvailable.globalNpm) {
373
+ add(getGroup(globalNpm, updatesAvailable.globalNpm), "NPM global", globalNpm, updatesAvailable.globalNpm);
374
+ }
375
+ if (updatesAvailable.globalYarn) {
376
+ add(getGroup(globalYarn, updatesAvailable.globalYarn), "YARN global", globalYarn, updatesAvailable.globalYarn);
377
+ }
378
+ } else {
379
+ if (local && local !== latest) {
380
+ add(getGroup(local, latest), "local", local, pkg.wanted);
381
+ }
382
+ if (globalNpm && globalNpm !== latest) {
383
+ add(getGroup(globalNpm, latest), "NPM global", globalNpm, pkg.wanted);
384
+ }
385
+ if (globalYarn && globalYarn !== latest) {
386
+ add(getGroup(globalYarn, latest), "YARN global", globalYarn, pkg.wanted);
387
+ }
388
+ if (!local && !globalNpm && !globalYarn) {
389
+ add("unknown", "unknown", "unknown", pkg.wanted);
390
+ }
391
+ }
392
+ return all;
393
+ }, []);
394
+ };
395
+ var displayTable = (updates) => {
396
+ const rows = getTableRows(updates);
397
+ if (rows.length) {
398
+ const hasUpdates = rows.some((row) => row.installed !== "unknown");
399
+ const columns = getTableColumns(rows);
400
+ const columnGap = 2;
401
+ const getGroupLines = (groupType, color, title, description) => {
402
+ const items = rows.filter((row) => row.group === groupType).sort((a, b) => a.name > b.name ? 1 : -1);
403
+ return !items.length ? [] : [
404
+ "",
405
+ color(`${(0, import_safe.bold)(title)} ${(0, import_safe.italic)(`(${description})`)}`),
406
+ ...items.map((row) => columns.map((column) => columnCellRenderer(column, row)).join(" ".repeat(columnGap)))
407
+ ];
408
+ };
409
+ drawBox([
410
+ "",
411
+ hasUpdates ? (0, import_safe.yellow)("Important updates are available.") : void 0,
412
+ hasUpdates ? "" : void 0,
413
+ columns.map(columnHeaderRenderer).join(" ".repeat(columnGap)),
414
+ ...getGroupLines("patch", import_safe.green, "Patch", "backwards-compatible bug fixes"),
415
+ ...getGroupLines("minor", import_safe.cyan, "Minor", "backwards-compatible features"),
416
+ ...getGroupLines("major", import_safe.red, "Major", "potentially breaking API changes"),
417
+ ...getGroupLines("majorVersionZero", import_safe.magenta, "Major version zero", "not stable, anything may change"),
418
+ ...getGroupLines("unknown", import_safe.blue, "Missing", "not installed"),
419
+ ""
420
+ ].filter((line) => line !== void 0));
421
+ } else {
422
+ console.log((0, import_safe.green)("\u{1F389} Packages are up-to-date"));
423
+ }
424
+ };
425
+ var checkVersions = (_0, ..._1) => __async(exports, [_0, ..._1], function* (packages, options = { useCache: true }) {
426
+ const spinner = (0, import_ora.default)({ text: (0, import_safe.cyan)("Checking versions...") });
427
+ spinner.start();
428
+ const latestVersionPackages = yield src_default(packages, options);
429
+ spinner.stop();
430
+ displayTable(latestVersionPackages);
431
+ });
432
+ void (() => __async(exports, null, function* () {
433
+ let args = process.argv.slice(2);
434
+ if (args.length === 1 && args[0].endsWith("package.json")) {
435
+ if ((0, import_fs2.existsSync)(args[0])) {
436
+ process.chdir((0, import_path2.dirname)(args[0]));
437
+ yield checkVersions(JSON.parse((0, import_fs2.readFileSync)(args[0]).toString()));
438
+ } else {
439
+ console.log((0, import_safe.cyan)("No package.json file were found"));
440
+ }
441
+ } else {
442
+ let localPkgJson;
443
+ if ((0, import_fs2.existsSync)("package.json")) {
444
+ localPkgJson = JSON.parse((0, import_fs2.readFileSync)("package.json").toString());
445
+ }
446
+ if (args.length) {
447
+ args = args.map((arg) => {
448
+ var _a, _b, _c, _d, _e, _f;
449
+ if ((_a = localPkgJson == null ? void 0 : localPkgJson.dependencies) == null ? void 0 : _a[arg]) {
450
+ return `${arg}@${(_b = localPkgJson == null ? void 0 : localPkgJson.dependencies) == null ? void 0 : _b[arg]}`;
451
+ } else if ((_c = localPkgJson == null ? void 0 : localPkgJson.devDependencies) == null ? void 0 : _c[arg]) {
452
+ return `${arg}@${(_d = localPkgJson == null ? void 0 : localPkgJson.devDependencies) == null ? void 0 : _d[arg]}`;
453
+ } else if ((_e = localPkgJson == null ? void 0 : localPkgJson.peerDependencies) == null ? void 0 : _e[arg]) {
454
+ return `${arg}@${(_f = localPkgJson == null ? void 0 : localPkgJson.peerDependencies) == null ? void 0 : _f[arg]}`;
455
+ }
456
+ return arg;
457
+ });
458
+ yield checkVersions(args);
459
+ } else if (localPkgJson) {
460
+ yield checkVersions(localPkgJson);
461
+ } else {
462
+ console.log((0, import_safe.cyan)("No packages were found"));
463
+ }
464
+ }
465
+ }))();
package/index.d.ts CHANGED
@@ -1,41 +1,53 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { Agent } from 'http';
4
- interface LatestVersions {
3
+ import type { Agent } from 'http';
4
+ interface RegistryVersions {
5
5
  /**
6
- * The latest version of the package found on the provided registry (if found).
6
+ * The latest version of the package found on the registry (if found).
7
7
  */
8
8
  latest?: string;
9
9
  /**
10
- * The next version of the package found on the provided registry (if found).
10
+ * The next version of the package found on the registry (if found).
11
11
  */
12
12
  next?: string;
13
13
  /**
14
- * The latest version of the package found on the provided registry and satisfied by the provided tag or version range (if provided).
14
+ * The latest version of the package found on the registry and satisfied by the wanted tag or version range.
15
15
  */
16
16
  wanted?: string;
17
17
  }
18
- interface LatestVersionPackage extends LatestVersions {
18
+ interface InstalledVersions {
19
19
  /**
20
- * The name of the package.
20
+ * The current local installed version of the package (if installed).
21
21
  */
22
- name: string;
22
+ local?: string;
23
+ /**
24
+ * The current npm global installed version of the package (if installed).
25
+ */
26
+ globalNpm?: string;
27
+ /**
28
+ * The current yarn global installed version of the package (if installed).
29
+ */
30
+ globalYarn?: string;
31
+ }
32
+ interface LatestVersionPackage extends InstalledVersions, RegistryVersions {
23
33
  /**
24
- * The current local or global installed version of the package (if installed).
34
+ * The name of the package.
25
35
  */
26
- installed?: string;
36
+ name: string;
27
37
  /**
28
38
  * The tag or version range that was provided (if provided).
39
+ *
40
+ * @default "latest"
29
41
  */
30
42
  wantedTagOrRange?: string;
31
43
  /**
32
- * Whether the installed version (if any) could be upgraded or not.
44
+ * Whether the local or global installed versions (if any) could be upgraded or not, based on the wanted version.
33
45
  */
34
46
  updatesAvailable: {
35
- latest: boolean;
36
- next: boolean;
37
- wanted: boolean;
38
- };
47
+ local: string | false;
48
+ globalNpm: string | false;
49
+ globalYarn: string | false;
50
+ } | false;
39
51
  /**
40
52
  * Any error that might have occurred during the process.
41
53
  */
@@ -138,7 +150,7 @@ type PackageJson = Record<string, any> & ({
138
150
  } | {
139
151
  peerDependencies: PackageJsonDependencies;
140
152
  });
153
+ export declare const ONE_DAY: number;
141
154
  declare const latestVersion: LatestVersion;
142
- export type { LatestVersion, Package, PackageRange, PackageJson, PackageJsonDependencies, LatestVersions, LatestVersionPackage, RequestOptions, LatestVersionOptions };
155
+ export type { LatestVersion, Package, PackageRange, PackageJson, PackageJsonDependencies, RegistryVersions, LatestVersionPackage, RequestOptions, LatestVersionOptions };
143
156
  export default latestVersion;
144
- //# sourceMappingURL=index.d.ts.map
@@ -63,17 +63,19 @@ var __async = (__this, __arguments, generator) => {
63
63
  // src/index.ts
64
64
  var src_exports = {};
65
65
  __export(src_exports, {
66
+ ONE_DAY: () => ONE_DAY,
66
67
  default: () => src_default
67
68
  });
68
69
  module.exports = __toCommonJS(src_exports);
69
- var import_registry_url = __toESM(require("registry-auth-token/registry-url"));
70
- var import_registry_auth_token = __toESM(require("registry-auth-token"));
71
70
  var import_fs = require("fs");
72
- var import_semver = require("semver");
73
- var import_global_dirs = require("global-dirs");
74
71
  var import_path = require("path");
72
+ var import_global_dirs = require("global-dirs");
75
73
  var import_os = require("os");
76
74
  var import_url = require("url");
75
+ var import_registry_url = __toESM(require("registry-auth-token/registry-url"));
76
+ var import_registry_auth_token = __toESM(require("registry-auth-token"));
77
+ var import_max_satisfying = __toESM(require("semver/ranges/max-satisfying"));
78
+ var import_gt = __toESM(require("semver/functions/gt"));
77
79
  var ONE_DAY = 1e3 * 60 * 60 * 24;
78
80
  var isPackageJson = (obj) => {
79
81
  return obj.dependencies !== void 0 || obj.devDependencies !== void 0 || obj.peerDependencies !== void 0;
@@ -152,23 +154,27 @@ var saveMetadataToCache = (pkg) => {
152
154
  (0, import_fs.writeFileSync)(filePath, JSON.stringify(pkg));
153
155
  };
154
156
  var getMetadataFromCache = (pkgName, options) => {
155
- const pkgCacheFilePath = (0, import_path.join)(getCacheDir(), `${pkgName}.json`);
156
- if ((0, import_fs.existsSync)(pkgCacheFilePath)) {
157
- const pkg = JSON.parse((0, import_fs.readFileSync)(pkgCacheFilePath).toString());
158
- const maxAge = (options == null ? void 0 : options.cacheMaxAge) !== void 0 ? options.cacheMaxAge : ONE_DAY;
159
- if (Date.now() - pkg.lastUpdateDate < maxAge) {
160
- return pkg;
157
+ var _a;
158
+ const maxAge = (_a = options == null ? void 0 : options.cacheMaxAge) != null ? _a : ONE_DAY;
159
+ if (maxAge !== 0) {
160
+ const pkgCacheFilePath = (0, import_path.join)(getCacheDir(), `${pkgName}.json`);
161
+ if ((0, import_fs.existsSync)(pkgCacheFilePath)) {
162
+ const pkg = JSON.parse((0, import_fs.readFileSync)(pkgCacheFilePath).toString());
163
+ if (Date.now() - pkg.lastUpdateDate < maxAge) {
164
+ return pkg;
165
+ }
161
166
  }
162
167
  }
163
168
  return void 0;
164
169
  };
165
- var getLatestVersions = (pkgName, tagOrRange, options) => __async(void 0, null, function* () {
170
+ var getRegistryVersions = (pkgName, tagOrRange, options) => __async(void 0, null, function* () {
166
171
  var _a, _b, _c;
167
172
  let pkgMetadata;
168
173
  if (pkgName.length && (options == null ? void 0 : options.useCache)) {
169
174
  pkgMetadata = getMetadataFromCache(pkgName, options);
170
175
  if (!pkgMetadata) {
171
- return downloadMetadata(pkgName, options).then(saveMetadataToCache);
176
+ pkgMetadata = yield downloadMetadata(pkgName, options);
177
+ saveMetadataToCache(pkgMetadata);
172
178
  }
173
179
  } else if (pkgName.length) {
174
180
  pkgMetadata = yield downloadMetadata(pkgName, options);
@@ -180,15 +186,37 @@ var getLatestVersions = (pkgName, tagOrRange, options) => __async(void 0, null,
180
186
  if (tagOrRange && (pkgMetadata == null ? void 0 : pkgMetadata.distTags) && (pkgMetadata == null ? void 0 : pkgMetadata.distTags[tagOrRange])) {
181
187
  versions.wanted = pkgMetadata.distTags[tagOrRange];
182
188
  } else if (tagOrRange && ((_c = pkgMetadata == null ? void 0 : pkgMetadata.versions) == null ? void 0 : _c.length)) {
183
- versions.wanted = (0, import_semver.maxSatisfying)(pkgMetadata.versions, tagOrRange) || void 0;
189
+ versions.wanted = (0, import_max_satisfying.default)(pkgMetadata.versions, tagOrRange) || void 0;
184
190
  }
185
191
  return versions;
186
192
  });
187
- var getInstalledVersion = (pkgName) => {
188
- var _a;
193
+ var getInstalledVersion = (pkgName, location = "local") => {
194
+ var _a, _b, _c, _d;
189
195
  try {
190
- const paths = [".", import_global_dirs.npm.packages, import_global_dirs.yarn.packages];
191
- return (_a = require(require.resolve((0, import_path.join)(pkgName, "package.json"), { paths }))) == null ? void 0 : _a.version;
196
+ if (location === "globalNpm") {
197
+ return (_a = require((0, import_path.join)(import_global_dirs.npm.packages, pkgName, "package.json"))) == null ? void 0 : _a.version;
198
+ } else if (location === "globalYarn") {
199
+ const yarnGlobalPkg = require((0, import_path.resolve)(import_global_dirs.yarn.packages, "..", "package.json"));
200
+ if (!((_b = yarnGlobalPkg == null ? void 0 : yarnGlobalPkg.dependencies) == null ? void 0 : _b[pkgName])) {
201
+ return void 0;
202
+ }
203
+ return (_c = require((0, import_path.join)(import_global_dirs.yarn.packages, pkgName, "package.json"))) == null ? void 0 : _c.version;
204
+ } else if (location === "local") {
205
+ const { root } = (0, import_path.parse)(process.cwd());
206
+ let path = process.cwd();
207
+ const localPaths = [(0, import_path.join)(path, "node_modules")];
208
+ while (path !== root) {
209
+ path = (0, import_path.dirname)(path);
210
+ localPaths.push((0, import_path.join)(path, "node_modules"));
211
+ }
212
+ for (const localPath of localPaths) {
213
+ const pkgPath = (0, import_path.join)(localPath, pkgName, "package.json");
214
+ if ((0, import_fs.existsSync)(pkgPath)) {
215
+ return (_d = require(pkgPath)) == null ? void 0 : _d.version;
216
+ }
217
+ }
218
+ }
219
+ return void 0;
192
220
  } catch (e) {
193
221
  return void 0;
194
222
  }
@@ -197,18 +225,19 @@ var getInfo = (pkg, options) => __async(void 0, null, function* () {
197
225
  const i = pkg.lastIndexOf("@");
198
226
  let pkgInfo = {
199
227
  name: i > 1 ? pkg.slice(0, i) : pkg,
200
- wantedTagOrRange: i > 1 ? pkg.slice(i + 1) : void 0,
201
- updatesAvailable: { latest: false, next: false, wanted: false }
228
+ wantedTagOrRange: i > 1 ? pkg.slice(i + 1) : "latest",
229
+ updatesAvailable: false
202
230
  };
203
231
  try {
204
232
  pkgInfo = __spreadValues(__spreadProps(__spreadValues({}, pkgInfo), {
205
- installed: getInstalledVersion(pkgInfo.name)
206
- }), yield getLatestVersions(pkgInfo.name, pkgInfo.wantedTagOrRange, options));
207
- pkgInfo.updatesAvailable = {
208
- latest: pkgInfo.installed && pkgInfo.latest ? (0, import_semver.gt)(pkgInfo.latest, pkgInfo.installed) : false,
209
- next: pkgInfo.installed && pkgInfo.next ? (0, import_semver.gt)(pkgInfo.next, pkgInfo.installed) : false,
210
- wanted: pkgInfo.installed && pkgInfo.wanted ? (0, import_semver.gt)(pkgInfo.wanted, pkgInfo.installed) : false
211
- };
233
+ local: getInstalledVersion(pkgInfo.name, "local"),
234
+ globalNpm: getInstalledVersion(pkgInfo.name, "globalNpm"),
235
+ globalYarn: getInstalledVersion(pkgInfo.name, "globalYarn")
236
+ }), yield getRegistryVersions(pkgInfo.name, pkgInfo.wantedTagOrRange, options));
237
+ const local = pkgInfo.local && pkgInfo.wanted ? (0, import_gt.default)(pkgInfo.wanted, pkgInfo.local) ? pkgInfo.wanted : false : false;
238
+ const globalNpm = pkgInfo.globalNpm && pkgInfo.wanted ? (0, import_gt.default)(pkgInfo.wanted, pkgInfo.globalNpm) ? pkgInfo.wanted : false : false;
239
+ const globalYarn = pkgInfo.globalYarn && pkgInfo.wanted ? (0, import_gt.default)(pkgInfo.wanted, pkgInfo.globalYarn) ? pkgInfo.wanted : false : false;
240
+ pkgInfo.updatesAvailable = local || globalNpm || globalYarn ? { local, globalNpm, globalYarn } : false;
212
241
  } catch (err) {
213
242
  pkgInfo.error = (err == null ? void 0 : err.message) || err;
214
243
  }
@@ -236,5 +265,6 @@ var latestVersion = (arg, options) => __async(void 0, null, function* () {
236
265
  });
237
266
  var src_default = latestVersion;
238
267
  // Annotate the CommonJS export names for ESM import in node:
239
- 0 && (module.exports = {});
240
- //# sourceMappingURL=index.js.map
268
+ 0 && (module.exports = {
269
+ ONE_DAY
270
+ });
package/package.json CHANGED
@@ -1,19 +1,25 @@
1
1
  {
2
2
  "name": "@badisi/latest-version",
3
- "version": "5.0.0",
3
+ "version": "6.0.0",
4
4
  "description": "Get latest versions of packages",
5
5
  "homepage": "https://github.com/badisi/latest-version",
6
6
  "license": "MIT",
7
7
  "author": {
8
8
  "name": "Badisi"
9
9
  },
10
- "main": "cjs/index.js",
10
+ "type": "commonjs",
11
+ "main": "index.js",
11
12
  "types": "index.d.ts",
12
13
  "exports": {
13
14
  ".": {
14
15
  "types": "./index.d.ts",
15
- "require": "./cjs/index.js"
16
- }
16
+ "require": "./index.js"
17
+ },
18
+ "./package.json": "./package.json"
19
+ },
20
+ "bin": {
21
+ "latest-version": "./bin/latest-version",
22
+ "lv": "./bin/latest-version"
17
23
  },
18
24
  "repository": {
19
25
  "type": "git",
@@ -38,7 +44,9 @@
38
44
  },
39
45
  "dependencies": {
40
46
  "global-dirs": "^3.0.1",
47
+ "@colors/colors": "^1.5.0",
41
48
  "registry-auth-token": "^5.0.1",
42
- "semver": "^7.3.8"
49
+ "semver": "^7.3.8",
50
+ "ora": "5.4.1"
43
51
  }
44
52
  }
package/cjs/index.js.map DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/index.ts"],
4
- "sourcesContent": ["import getRegistryUrl from 'registry-auth-token/registry-url';\nimport registryAuthToken from 'registry-auth-token';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { RequestOptions as HttpRequestOptions, Agent, IncomingMessage } from 'http';\nimport { RequestOptions as HttpsRequestOptions } from 'https';\nimport { gt, maxSatisfying } from 'semver';\nimport { npm, yarn } from 'global-dirs';\nimport { join, dirname } from 'path';\nimport { homedir } from 'os';\nimport { URL } from 'url';\n\ninterface LatestVersions {\n /**\n * The latest version of the package found on the provided registry (if found).\n */\n latest?: string;\n /**\n * The next version of the package found on the provided registry (if found).\n */\n next?: string;\n /**\n * The latest version of the package found on the provided registry and satisfied by the provided tag or version range (if provided).\n */\n wanted?: string;\n}\n\ninterface LatestVersionPackage extends LatestVersions {\n /**\n * The name of the package.\n */\n name: string;\n /**\n * The current local or global installed version of the package (if installed).\n */\n installed?: string;\n /**\n * The tag or version range that was provided (if provided).\n */\n wantedTagOrRange?: string;\n /**\n * Whether the installed version (if any) could be upgraded or not.\n */\n updatesAvailable: {\n latest: boolean;\n next: boolean;\n wanted: boolean;\n };\n /**\n * Any error that might have occurred during the process.\n */\n error?: Error;\n}\n\ninterface RequestOptions {\n readonly ca?: string | Buffer | Array<string | Buffer>;\n readonly rejectUnauthorized?: boolean;\n readonly agent?: Agent | boolean;\n readonly timeout?: number;\n}\n\ninterface LatestVersionOptions {\n /**\n * Awaiting the api to return might take time, depending on the network, and might impact your package loading performance.\n * You can use the cache mechanism to improve load performance and reduce unnecessary network requests.\n * If `useCache` is not supplied, the api will always check for updates and wait for every requests to return before returning itself.\n * If `useCache` is used, the api will always returned immediately, with either (for each provided packages):\n * 1) a latest/next version available if a cache was found\n * 2) no latest/next version available if no cache was found - in such case updates will be fetched in the background and a cache will\n * be created for each provided packages and made available for the next call to the api.\n *\n * @default false\n */\n readonly useCache?: boolean;\n\n /**\n * How long the cache for the provided packages should be used before being refreshed (in milliseconds).\n * If `useCache` is not supplied, this option has no effect.\n * If `0` is used, this will force the cache to refresh immediately:\n * 1) The api will returned immediately (without any latest nor next version available for the provided packages)\n * 2) New updates will be fetched in the background\n * 3) The cache for each provided packages will be refreshed and made available for the next call to the api\n *\n * @default ONE_DAY\n */\n readonly cacheMaxAge?: number;\n\n /**\n * A JavaScript package registry url that implements the CommonJS Package Registry specification.\n *\n * @default \"Looks at any registry urls in the .npmrc file or fallback to the default npm registry instead\"\n * @example <caption>.npmrc</caption>\n * registry = 'https://custom-registry.com/'\n * @pkgscope:registry = 'https://custom-registry.com/'\n */\n readonly registryUrl?: string;\n\n /**\n * Set of options to be passed down to Node.js http/https request.\n *\n * @example <caption>Behind a proxy with self-signed certificate</caption>\n * { ca: [ fs.readFileSync('proxy-cert.pem') ] }\n * @example <caption>Bypassing certificate validation</caption>\n * { rejectUnauthorized: false }\n */\n readonly requestOptions?: RequestOptions;\n}\n\ntype LatestVersion = {\n /**\n * Get latest versions of packages from of a package json like object.\n *\n * @param {PackageJson} item - A package json like object (with dependencies, devDependencies and peerDependencies attributes).\n * @example { dependencies: { 'npm': 'latest' }, devDependencies: { 'npm': '1.3.2' }, peerDependencies: { '@scope/name': '^5.0.2' } }\n * @param {LatestVersionOptions} [options] - An object optionally specifying the use of the cache, the max age of the cache, the registry url and the http or https options.\n * If `useCache` is not supplied, the default of `false` is used.\n * If `cacheMaxAge` is not supplied, the default of `one day` is used.\n * If `registryUrl` is not supplied, the default from `.npmrc` is used or a fallback to the `npm registry url` instead.\n * @returns {Promise<LatestVersionPackage[]>}\n */\n (item: PackageJson, options?: LatestVersionOptions): Promise<LatestVersionPackage[]>;\n\n /**\n * Get latest version of a single package.\n *\n * @param {Package} item - A single package object (represented by a string that should match the following format: `${'@' | ''}${string}@${string}`)\n * @example 'npm', 'npm@1.3.2', '@scope/name@^5.0.2'\n * @param {LatestVersionOptions} [options] - An object optionally specifying the use of the cache, the max age of the cache, the registry url and the http or https options.\n * If `useCache` is not supplied, the default of `false` is used.\n * If `cacheMaxAge` is not supplied, the default of `one day` is used.\n * If `registryUrl` is not supplied, the default from `.npmrc` is used or a fallback to the npm registry url instead.\n * @returns {Promise<LatestVersionPackage>}\n */\n (item: Package, options?: LatestVersionOptions): Promise<LatestVersionPackage>;\n\n /**\n * Get latest versions of a collection of packages.\n *\n * @param {Package[]} items - A collection of package object (represented by a string that should match the following format: `${'@' | ''}${string}@${string}`)\n * @example ['npm', 'npm@1.3.2', '@scope/name@^5.0.2']\n * @param {LatestVersionOptions} [options] - An object optionally specifying the use of the cache, the max age of the cache, the registry url and the http or https options.\n * If `useCache` is not supplied, the default of `false` is used.\n * If `cacheMaxAge` is not supplied, the default of `one day` is used.\n * If `registryUrl` is not supplied, the default from `.npmrc` is used or a fallback to the npm registry url instead.\n * @returns {Promise<LatestVersionPackage[]>}\n */\n (items: Package[], options?: LatestVersionOptions): Promise<LatestVersionPackage[]>; // eslint-disable-line @typescript-eslint/unified-signatures\n};\ntype PackageRange = `${'@' | ''}${string}@${string}`;\ntype Package = string | PackageRange;\ntype PackageJsonDependencies = Record<string, string>;\ntype PackageJson = Record<string, any> & ({\n dependencies: PackageJsonDependencies;\n} | {\n devDependencies: PackageJsonDependencies;\n} | {\n peerDependencies: PackageJsonDependencies;\n});\n\n/**\n * @internal\n */\ninterface PackageMetadata {\n name: string;\n lastUpdateDate: number;\n versions: string[];\n distTags: Record<string, string>;\n}\n\nconst ONE_DAY = 1000 * 60 * 60 * 24; // eslint-disable-line @typescript-eslint/naming-convention\n\nconst isPackageJson = (obj: any): obj is PackageJson => {\n return ((obj as PackageJson).dependencies !== undefined) ||\n ((obj as PackageJson).devDependencies !== undefined) ||\n ((obj as PackageJson).peerDependencies !== undefined);\n};\n\nconst downloadMetadata = (pkgName: string, options?: LatestVersionOptions): Promise<PackageMetadata> => {\n return new Promise((resolve, reject) => {\n const i = pkgName.indexOf('/');\n const pkgScope = (i !== -1) ? pkgName.slice(0, i) : '';\n const registryUrl = options?.registryUrl || getRegistryUrl(pkgScope);\n const pkgUrl = new URL(encodeURIComponent(pkgName).replace(/^%40/, '@'), registryUrl);\n\n let requestOptions: HttpRequestOptions | HttpsRequestOptions = {\n headers: { accept: 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' },\n host: pkgUrl.hostname,\n path: pkgUrl.pathname,\n port: pkgUrl.port\n };\n const authInfo = registryAuthToken(pkgUrl.toString(), { recursive: true });\n if (authInfo && requestOptions.headers) {\n requestOptions.headers.authorization = `${authInfo.type} ${authInfo.token}`;\n }\n if (options?.requestOptions) {\n requestOptions = { ...requestOptions, ...options.requestOptions };\n }\n\n const { get } = require((pkgUrl.protocol === 'https:') ? 'https' : 'http');\n const request = get(requestOptions, (res: IncomingMessage) => {\n if (res.statusCode === 200) {\n let rawData = '';\n res.setEncoding('utf8');\n res.on('data', (chunk: any) => rawData += chunk);\n res.once('end', () => {\n res.setTimeout(0);\n res.removeAllListeners();\n try {\n const pkgMetadata = JSON.parse(rawData);\n return resolve({\n name: pkgName,\n lastUpdateDate: Date.now(),\n versions: Object.keys(pkgMetadata.versions as string[]),\n distTags: pkgMetadata['dist-tags']\n });\n } catch (err) {\n return reject(err);\n }\n });\n } else {\n res.removeAllListeners();\n res.resume(); // consume response data to free up memory\n return reject(`Request error (${res.statusCode}): ${pkgUrl}`);\n }\n });\n const abort = (error: Error | string): void => {\n request.removeAllListeners();\n request.destroy();\n return reject(error);\n };\n request.once('timeout', () => abort(`Request timed out: ${pkgUrl}`));\n request.once('error', (err: Error) => abort(err));\n });\n};\n\nconst getCacheDir = (name = '@badisi/latest-version'): string => {\n const homeDir = homedir();\n switch (process.platform) {\n case 'darwin': return join(homeDir, 'Library', 'Caches', name);\n case 'win32': return join(process.env.LOCALAPPDATA || join(homeDir, 'AppData', 'Local'), name, 'Cache');\n default: return join(process.env.XDG_CACHE_HOME || join(homeDir, '.cache'), name);\n }\n};\n\nconst saveMetadataToCache = (pkg: PackageMetadata): void => {\n const filePath = join(getCacheDir(), `${pkg.name}.json`);\n if (!existsSync(dirname(filePath))) { mkdirSync(dirname(filePath), { recursive: true }); }\n writeFileSync(filePath, JSON.stringify(pkg));\n};\n\nconst getMetadataFromCache = (pkgName: string, options?: LatestVersionOptions): PackageMetadata | undefined => {\n const pkgCacheFilePath = join(getCacheDir(), `${pkgName}.json`);\n if (existsSync(pkgCacheFilePath)) {\n const pkg = JSON.parse(readFileSync(pkgCacheFilePath).toString()) as PackageMetadata;\n const maxAge = (options?.cacheMaxAge !== undefined) ? options.cacheMaxAge : ONE_DAY;\n if ((Date.now() - pkg.lastUpdateDate) < maxAge) {\n return pkg;\n }\n }\n return undefined;\n};\n\nconst getLatestVersions = async (pkgName: string, tagOrRange?: string, options?: LatestVersionOptions): Promise<LatestVersions | void> => {\n let pkgMetadata: PackageMetadata | undefined;\n if (pkgName.length && options?.useCache) {\n pkgMetadata = getMetadataFromCache(pkgName, options);\n if (!pkgMetadata) {\n return downloadMetadata(pkgName, options).then(saveMetadataToCache);\n }\n } else if (pkgName.length) {\n pkgMetadata = await downloadMetadata(pkgName, options);\n }\n\n const versions: LatestVersions = {\n latest: pkgMetadata?.distTags?.latest,\n next: pkgMetadata?.distTags?.next\n };\n if (tagOrRange && pkgMetadata?.distTags && pkgMetadata?.distTags[tagOrRange]) {\n versions.wanted = pkgMetadata.distTags[tagOrRange];\n } else if (tagOrRange && pkgMetadata?.versions?.length) {\n versions.wanted = maxSatisfying(pkgMetadata.versions, tagOrRange) || undefined;\n }\n return versions;\n};\n\nconst getInstalledVersion = (pkgName: string): string | undefined => {\n try {\n const paths = ['.', npm.packages, yarn.packages];\n return require(require.resolve(join(pkgName, 'package.json'), { paths }))?.version as string | undefined;\n } catch {\n return undefined;\n }\n};\n\nconst getInfo = async (pkg: Package, options?: LatestVersionOptions): Promise<LatestVersionPackage> => {\n const i = pkg.lastIndexOf('@');\n let pkgInfo: LatestVersionPackage = {\n name: (i > 1) ? pkg.slice(0, i) : pkg,\n wantedTagOrRange: (i > 1) ? pkg.slice(i + 1) : undefined,\n updatesAvailable: { latest: false, next: false, wanted: false }\n };\n\n try {\n pkgInfo = {\n ...pkgInfo,\n installed: getInstalledVersion(pkgInfo.name),\n ...(await getLatestVersions(pkgInfo.name, pkgInfo.wantedTagOrRange, options))\n };\n pkgInfo.updatesAvailable = {\n latest: (pkgInfo.installed && pkgInfo.latest) ? gt(pkgInfo.latest, pkgInfo.installed) : false,\n next: (pkgInfo.installed && pkgInfo.next) ? gt(pkgInfo.next, pkgInfo.installed) : false,\n wanted: (pkgInfo.installed && pkgInfo.wanted) ? gt(pkgInfo.wanted, pkgInfo.installed) : false\n };\n } catch (err: any) {\n pkgInfo.error = err?.message || err;\n }\n\n return pkgInfo;\n};\n\nconst latestVersion: LatestVersion = async (arg: Package | Package[] | PackageJson, options?: LatestVersionOptions): Promise<any> => {\n const pkgs: string[] = [];\n if (typeof arg === 'string') {\n pkgs.push(arg);\n } else if (Array.isArray(arg)) {\n pkgs.push(...arg);\n } else if (isPackageJson(arg)) {\n const addDeps = (deps: PackageJsonDependencies): void => {\n if (deps) {\n pkgs.push(...Object.keys(deps).map((key: string) => `${key}@${deps[key]}`));\n }\n };\n addDeps(arg.dependencies as PackageJsonDependencies);\n addDeps(arg.devDependencies as PackageJsonDependencies);\n addDeps(arg.peerDependencies as PackageJsonDependencies);\n }\n\n const jobs = await Promise.allSettled(pkgs.map((pkg: string) => getInfo(pkg, options)));\n const results = jobs.map((jobResult: PromiseSettledResult<LatestVersionPackage>) =>\n (jobResult as PromiseFulfilledResult<LatestVersionPackage>).value);\n return (typeof arg === 'string') ? results[0] : results;\n};\n\nexport type {\n LatestVersion,\n Package,\n PackageRange,\n PackageJson,\n PackageJsonDependencies,\n LatestVersions,\n LatestVersionPackage,\n RequestOptions,\n LatestVersionOptions\n};\nexport default latestVersion;\n"],
5
- "mappings": "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",
6
- "names": ["getRegistryUrl", "registryAuthToken"]
7
- }
package/cjs/package.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "type": "commonjs"
3
- }
package/index.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAGA,OAAO,EAAwC,KAAK,EAAmB,MAAM,MAAM,CAAC;AAQpF,UAAU,cAAc;IACpB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,oBAAqB,SAAQ,cAAc;IACjD;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;OAEG;IACH,gBAAgB,EAAE;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;KACnB,CAAC;IACF;;OAEG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;CACjB;AAED,UAAU,cAAc;IACpB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACvD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,UAAU,oBAAoB;IAC1B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;;;;;;OASG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAE9B;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAE9B;;;;;;;OAOG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;CAC5C;AAED,KAAK,aAAa,GAAG;IACjB;;;;;;;;;;OAUG;IACH,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;IAErF;;;;;;;;;;OAUG;IACH,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAE/E;;;;;;;;;;OAUG;IACH,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;CACvF,CAAC;AACF,KAAK,YAAY,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;AACrD,KAAK,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC;AACrC,KAAK,uBAAuB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACtD,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC;IACtC,YAAY,EAAE,uBAAuB,CAAC;CACzC,GAAG;IACA,eAAe,EAAE,uBAAuB,CAAC;CAC5C,GAAG;IACA,gBAAgB,EAAE,uBAAuB,CAAC;CAC7C,CAAC,CAAC;AAmKH,QAAA,MAAM,aAAa,EAAE,aAqBpB,CAAC;AAEF,YAAY,EACR,aAAa,EACb,OAAO,EACP,YAAY,EACZ,WAAW,EACX,uBAAuB,EACvB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACvB,CAAC;AACF,eAAe,aAAa,CAAC"}