@badisi/latest-version 2.1.4 → 4.0.1
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/cjs/index.js +224 -162
- package/cjs/index.js.map +7 -0
- package/{cjs/index.d.ts → index.d.ts} +3 -1
- package/index.d.ts.map +1 -0
- package/package.json +6 -7
- package/esm/index.d.ts +0 -142
- package/esm/index.js +0 -177
- package/esm/package.json +0 -3
package/cjs/index.js
CHANGED
|
@@ -1,178 +1,240 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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 || (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;
|
|
17
23
|
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const registryUrl = (options === null || options === void 0 ? void 0 : options.registryUrl) || (0, registry_url_1.default)(pkgScope);
|
|
23
|
-
const pkgUrl = new url_1.URL(encodeURIComponent(pkgName).replace(/^%40/, '@'), registryUrl);
|
|
24
|
-
let requestOptions = {
|
|
25
|
-
headers: { accept: 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' },
|
|
26
|
-
host: pkgUrl.hostname,
|
|
27
|
-
path: pkgUrl.pathname,
|
|
28
|
-
port: pkgUrl.port
|
|
29
|
-
};
|
|
30
|
-
const authInfo = (0, registry_auth_token_1.default)(pkgUrl.toString(), { recursive: true });
|
|
31
|
-
if (authInfo && requestOptions.headers) {
|
|
32
|
-
requestOptions.headers.authorization = `${authInfo.type} ${authInfo.token}`;
|
|
33
|
-
}
|
|
34
|
-
if (options === null || options === void 0 ? void 0 : options.requestOptions) {
|
|
35
|
-
requestOptions = Object.assign(Object.assign({}, requestOptions), options.requestOptions);
|
|
36
|
-
}
|
|
37
|
-
const { get } = require((pkgUrl.protocol === 'https:') ? 'https' : 'http');
|
|
38
|
-
const request = get(requestOptions, (res) => {
|
|
39
|
-
if (res.statusCode === 200) {
|
|
40
|
-
let rawData = '';
|
|
41
|
-
res.setEncoding('utf8');
|
|
42
|
-
res.on('data', (chunk) => rawData += chunk);
|
|
43
|
-
res.once('end', () => {
|
|
44
|
-
res.setTimeout(0);
|
|
45
|
-
res.removeAllListeners();
|
|
46
|
-
try {
|
|
47
|
-
const pkgMetadata = JSON.parse(rawData);
|
|
48
|
-
return resolve({
|
|
49
|
-
name: pkgName,
|
|
50
|
-
lastUpdateDate: Date.now(),
|
|
51
|
-
versions: Object.keys(pkgMetadata.versions),
|
|
52
|
-
distTags: pkgMetadata['dist-tags']
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
catch (err) {
|
|
56
|
-
return reject(err);
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
res.removeAllListeners();
|
|
62
|
-
res.resume(); // consume response data to free up memory
|
|
63
|
-
return reject(`Request error (${res.statusCode}): ${pkgUrl}`);
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
const abort = (error) => {
|
|
67
|
-
request.removeAllListeners();
|
|
68
|
-
request.destroy();
|
|
69
|
-
return reject(error);
|
|
70
|
-
};
|
|
71
|
-
request.once('timeout', () => abort(`Request timed out: ${pkgUrl}`));
|
|
72
|
-
request.once('error', (err) => abort(err));
|
|
73
|
-
});
|
|
24
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
25
|
+
var __export = (target, all) => {
|
|
26
|
+
for (var name in all)
|
|
27
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
74
28
|
};
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
29
|
+
var __copyProps = (to, from, except, desc) => {
|
|
30
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
31
|
+
for (let key of __getOwnPropNames(from))
|
|
32
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
33
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
34
|
+
}
|
|
35
|
+
return to;
|
|
82
36
|
};
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
37
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
38
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
39
|
+
mod
|
|
40
|
+
));
|
|
41
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
42
|
+
var __async = (__this, __arguments, generator) => {
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
var fulfilled = (value) => {
|
|
45
|
+
try {
|
|
46
|
+
step(generator.next(value));
|
|
47
|
+
} catch (e) {
|
|
48
|
+
reject(e);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
var rejected = (value) => {
|
|
52
|
+
try {
|
|
53
|
+
step(generator.throw(value));
|
|
54
|
+
} catch (e) {
|
|
55
|
+
reject(e);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
59
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
60
|
+
});
|
|
89
61
|
};
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
62
|
+
|
|
63
|
+
// src/index.ts
|
|
64
|
+
var src_exports = {};
|
|
65
|
+
__export(src_exports, {
|
|
66
|
+
default: () => src_default
|
|
67
|
+
});
|
|
68
|
+
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
|
+
var import_fs = require("fs");
|
|
72
|
+
var import_semver = require("semver");
|
|
73
|
+
var import_global_dirs = require("global-dirs");
|
|
74
|
+
var import_path = require("path");
|
|
75
|
+
var import_os = require("os");
|
|
76
|
+
var import_url = require("url");
|
|
77
|
+
var ONE_DAY = 1e3 * 60 * 60 * 24;
|
|
78
|
+
var isPackageJson = (obj) => {
|
|
79
|
+
return obj.dependencies !== void 0 || obj.devDependencies !== void 0 || obj.peerDependencies !== void 0;
|
|
100
80
|
};
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
81
|
+
var downloadMetadata = (pkgName, options) => {
|
|
82
|
+
return new Promise((resolve, reject) => {
|
|
83
|
+
const i = pkgName.indexOf("/");
|
|
84
|
+
const pkgScope = i !== -1 ? pkgName.slice(0, i) : "";
|
|
85
|
+
const registryUrl = (options == null ? void 0 : options.registryUrl) || (0, import_registry_url.default)(pkgScope);
|
|
86
|
+
const pkgUrl = new import_url.URL(encodeURIComponent(pkgName).replace(/^%40/, "@"), registryUrl);
|
|
87
|
+
let requestOptions = {
|
|
88
|
+
headers: { accept: "application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*" },
|
|
89
|
+
host: pkgUrl.hostname,
|
|
90
|
+
path: pkgUrl.pathname,
|
|
91
|
+
port: pkgUrl.port
|
|
92
|
+
};
|
|
93
|
+
const authInfo = (0, import_registry_auth_token.default)(pkgUrl.toString(), { recursive: true });
|
|
94
|
+
if (authInfo && requestOptions.headers) {
|
|
95
|
+
requestOptions.headers.authorization = `${authInfo.type} ${authInfo.token}`;
|
|
109
96
|
}
|
|
110
|
-
|
|
111
|
-
|
|
97
|
+
if (options == null ? void 0 : options.requestOptions) {
|
|
98
|
+
requestOptions = __spreadValues(__spreadValues({}, requestOptions), options.requestOptions);
|
|
112
99
|
}
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
100
|
+
const { get } = pkgUrl.protocol === "https:" ? require("https") : require("http");
|
|
101
|
+
const request = get(requestOptions, (res) => {
|
|
102
|
+
if (res.statusCode === 200) {
|
|
103
|
+
let rawData = "";
|
|
104
|
+
res.setEncoding("utf8");
|
|
105
|
+
res.on("data", (chunk) => rawData += chunk);
|
|
106
|
+
res.once("end", () => {
|
|
107
|
+
res.setTimeout(0);
|
|
108
|
+
res.removeAllListeners();
|
|
109
|
+
try {
|
|
110
|
+
const pkgMetadata = JSON.parse(rawData);
|
|
111
|
+
return resolve({
|
|
112
|
+
name: pkgName,
|
|
113
|
+
lastUpdateDate: Date.now(),
|
|
114
|
+
versions: Object.keys(pkgMetadata.versions),
|
|
115
|
+
distTags: pkgMetadata["dist-tags"]
|
|
116
|
+
});
|
|
117
|
+
} catch (err) {
|
|
118
|
+
return reject(err);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
} else {
|
|
122
|
+
res.removeAllListeners();
|
|
123
|
+
res.resume();
|
|
124
|
+
return reject(`Request error (${res.statusCode}): ${pkgUrl}`);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
const abort = (error) => {
|
|
128
|
+
request.removeAllListeners();
|
|
129
|
+
request.destroy();
|
|
130
|
+
return reject(error);
|
|
116
131
|
};
|
|
117
|
-
|
|
118
|
-
|
|
132
|
+
request.once("timeout", () => abort(`Request timed out: ${pkgUrl}`));
|
|
133
|
+
request.once("error", (err) => abort(err));
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
var getCacheDir = (name = "@badisi/latest-version") => {
|
|
137
|
+
const homeDir = (0, import_os.homedir)();
|
|
138
|
+
switch (process.platform) {
|
|
139
|
+
case "darwin":
|
|
140
|
+
return (0, import_path.join)(homeDir, "Library", "Caches", name);
|
|
141
|
+
case "win32":
|
|
142
|
+
return (0, import_path.join)(process.env.LOCALAPPDATA || (0, import_path.join)(homeDir, "AppData", "Local"), name, "Cache");
|
|
143
|
+
default:
|
|
144
|
+
return (0, import_path.join)(process.env.XDG_CACHE_HOME || (0, import_path.join)(homeDir, ".cache"), name);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
var saveMetadataToCache = (pkg) => {
|
|
148
|
+
const filePath = (0, import_path.join)(getCacheDir(), `${pkg.name}.json`);
|
|
149
|
+
if (!(0, import_fs.existsSync)((0, import_path.dirname)(filePath))) {
|
|
150
|
+
(0, import_fs.mkdirSync)((0, import_path.dirname)(filePath), { recursive: true });
|
|
151
|
+
}
|
|
152
|
+
(0, import_fs.writeFileSync)(filePath, JSON.stringify(pkg));
|
|
153
|
+
};
|
|
154
|
+
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;
|
|
119
161
|
}
|
|
120
|
-
|
|
121
|
-
|
|
162
|
+
}
|
|
163
|
+
return void 0;
|
|
164
|
+
};
|
|
165
|
+
var getLatestVersions = (pkgName, tagOrRange, options) => __async(void 0, null, function* () {
|
|
166
|
+
var _a, _b, _c;
|
|
167
|
+
let pkgMetadata;
|
|
168
|
+
if (pkgName.length && (options == null ? void 0 : options.useCache)) {
|
|
169
|
+
pkgMetadata = getMetadataFromCache(pkgName, options);
|
|
170
|
+
if (!pkgMetadata) {
|
|
171
|
+
return downloadMetadata(pkgName, options).then(saveMetadataToCache);
|
|
122
172
|
}
|
|
123
|
-
|
|
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_semver.maxSatisfying)(pkgMetadata.versions, tagOrRange) || void 0;
|
|
184
|
+
}
|
|
185
|
+
return versions;
|
|
124
186
|
});
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
187
|
+
var getInstalledVersion = (pkgName) => {
|
|
188
|
+
var _a;
|
|
189
|
+
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;
|
|
192
|
+
} catch (e) {
|
|
193
|
+
return void 0;
|
|
194
|
+
}
|
|
134
195
|
};
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
196
|
+
var getInfo = (pkg, options) => __async(void 0, null, function* () {
|
|
197
|
+
const i = pkg.lastIndexOf("@");
|
|
198
|
+
let pkgInfo = {
|
|
199
|
+
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 }
|
|
202
|
+
};
|
|
203
|
+
try {
|
|
204
|
+
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
|
|
141
211
|
};
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
next: (pkgInfo.installed && pkgInfo.next) ? (0, semver_1.gt)(pkgInfo.next, pkgInfo.installed) : false,
|
|
147
|
-
wanted: (pkgInfo.installed && pkgInfo.wanted) ? (0, semver_1.gt)(pkgInfo.wanted, pkgInfo.installed) : false
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
catch (err) {
|
|
151
|
-
pkgInfo.error = (err === null || err === void 0 ? void 0 : err.message) || err;
|
|
152
|
-
}
|
|
153
|
-
return pkgInfo;
|
|
212
|
+
} catch (err) {
|
|
213
|
+
pkgInfo.error = (err == null ? void 0 : err.message) || err;
|
|
214
|
+
}
|
|
215
|
+
return pkgInfo;
|
|
154
216
|
});
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const results = jobs.map((jobResult) => jobResult.value);
|
|
175
|
-
return (typeof arg === 'string') ? results[0] : results;
|
|
217
|
+
var latestVersion = (arg, options) => __async(void 0, null, function* () {
|
|
218
|
+
const pkgs = [];
|
|
219
|
+
if (typeof arg === "string") {
|
|
220
|
+
pkgs.push(arg);
|
|
221
|
+
} else if (Array.isArray(arg)) {
|
|
222
|
+
pkgs.push(...arg);
|
|
223
|
+
} else if (isPackageJson(arg)) {
|
|
224
|
+
const addDeps = (deps) => {
|
|
225
|
+
if (deps) {
|
|
226
|
+
pkgs.push(...Object.keys(deps).map((key) => `${key}@${deps[key]}`));
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
addDeps(arg.dependencies);
|
|
230
|
+
addDeps(arg.devDependencies);
|
|
231
|
+
addDeps(arg.peerDependencies);
|
|
232
|
+
}
|
|
233
|
+
const jobs = yield Promise.allSettled(pkgs.map((pkg) => getInfo(pkg, options)));
|
|
234
|
+
const results = jobs.map((jobResult) => jobResult.value);
|
|
235
|
+
return typeof arg === "string" ? results[0] : results;
|
|
176
236
|
});
|
|
177
|
-
|
|
178
|
-
|
|
237
|
+
var src_default = latestVersion;
|
|
238
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
239
|
+
0 && (module.exports = {});
|
|
240
|
+
//# sourceMappingURL=index.js.map
|
package/cjs/index.js.map
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
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
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
2
3
|
import { Agent } from 'http';
|
|
3
4
|
interface LatestVersions {
|
|
4
5
|
/**
|
|
@@ -138,5 +139,6 @@ declare type PackageJson = Record<string, any> & ({
|
|
|
138
139
|
peerDependencies: PackageJsonDependencies;
|
|
139
140
|
});
|
|
140
141
|
declare const latestVersion: LatestVersion;
|
|
141
|
-
export { LatestVersion, Package, PackageRange, PackageJson, PackageJsonDependencies, LatestVersions, LatestVersionPackage, RequestOptions, LatestVersionOptions };
|
|
142
|
+
export type { LatestVersion, Package, PackageRange, PackageJson, PackageJsonDependencies, LatestVersions, LatestVersionPackage, RequestOptions, LatestVersionOptions };
|
|
142
143
|
export default latestVersion;
|
|
144
|
+
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
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,aAAK,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,aAAK,YAAY,GAAG,GAAG,GAAG,GAAG,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;AACrD,aAAK,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC;AACrC,aAAK,uBAAuB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACtD,aAAK,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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@badisi/latest-version",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "Get latest versions of packages",
|
|
5
5
|
"homepage": "https://github.com/badisi/latest-version",
|
|
6
6
|
"license": "MIT",
|
|
@@ -8,12 +8,11 @@
|
|
|
8
8
|
"name": "Badisi"
|
|
9
9
|
},
|
|
10
10
|
"main": "cjs/index.js",
|
|
11
|
-
"
|
|
12
|
-
"types": "esm/index.d.ts",
|
|
11
|
+
"types": "index.d.ts",
|
|
13
12
|
"exports": {
|
|
14
13
|
".": {
|
|
15
|
-
"
|
|
16
|
-
"
|
|
14
|
+
"types": "./index.d.ts",
|
|
15
|
+
"require": "./cjs/index.js"
|
|
17
16
|
}
|
|
18
17
|
},
|
|
19
18
|
"repository": {
|
|
@@ -36,10 +35,10 @@
|
|
|
36
35
|
],
|
|
37
36
|
"dependencies": {
|
|
38
37
|
"global-dirs": "^3.0.0",
|
|
39
|
-
"registry-auth-token": "^
|
|
38
|
+
"registry-auth-token": "^5.0.1",
|
|
40
39
|
"semver": "^7.3.7"
|
|
41
40
|
},
|
|
42
41
|
"engines": {
|
|
43
|
-
"node": ">=
|
|
42
|
+
"node": ">= 14"
|
|
44
43
|
}
|
|
45
44
|
}
|
package/esm/index.d.ts
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
import { Agent } from 'http';
|
|
3
|
-
interface LatestVersions {
|
|
4
|
-
/**
|
|
5
|
-
* The latest version of the package found on the provided registry (if found).
|
|
6
|
-
*/
|
|
7
|
-
latest?: string;
|
|
8
|
-
/**
|
|
9
|
-
* The next version of the package found on the provided registry (if found).
|
|
10
|
-
*/
|
|
11
|
-
next?: string;
|
|
12
|
-
/**
|
|
13
|
-
* The latest version of the package found on the provided registry and satisfied by the provided tag or version range (if provided).
|
|
14
|
-
*/
|
|
15
|
-
wanted?: string;
|
|
16
|
-
}
|
|
17
|
-
interface LatestVersionPackage extends LatestVersions {
|
|
18
|
-
/**
|
|
19
|
-
* The name of the package.
|
|
20
|
-
*/
|
|
21
|
-
name: string;
|
|
22
|
-
/**
|
|
23
|
-
* The current local or global installed version of the package (if installed).
|
|
24
|
-
*/
|
|
25
|
-
installed?: string;
|
|
26
|
-
/**
|
|
27
|
-
* The tag or version range that was provided (if provided).
|
|
28
|
-
*/
|
|
29
|
-
wantedTagOrRange?: string;
|
|
30
|
-
/**
|
|
31
|
-
* Whether the installed version (if any) could be upgraded or not.
|
|
32
|
-
*/
|
|
33
|
-
updatesAvailable: {
|
|
34
|
-
latest: boolean;
|
|
35
|
-
next: boolean;
|
|
36
|
-
wanted: boolean;
|
|
37
|
-
};
|
|
38
|
-
/**
|
|
39
|
-
* Any error that might have occurred during the process.
|
|
40
|
-
*/
|
|
41
|
-
error?: Error;
|
|
42
|
-
}
|
|
43
|
-
interface RequestOptions {
|
|
44
|
-
readonly ca?: string | Buffer | Array<string | Buffer>;
|
|
45
|
-
readonly rejectUnauthorized?: boolean;
|
|
46
|
-
readonly agent?: Agent | boolean;
|
|
47
|
-
readonly timeout?: number;
|
|
48
|
-
}
|
|
49
|
-
interface LatestVersionOptions {
|
|
50
|
-
/**
|
|
51
|
-
* Awaiting the api to return might take time, depending on the network, and might impact your package loading performance.
|
|
52
|
-
* You can use the cache mechanism to improve load performance and reduce unnecessary network requests.
|
|
53
|
-
* If `useCache` is not supplied, the api will always check for updates and wait for every requests to return before returning itself.
|
|
54
|
-
* If `useCache` is used, the api will always returned immediately, with either (for each provided packages):
|
|
55
|
-
* 1) a latest/next version available if a cache was found
|
|
56
|
-
* 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
|
|
57
|
-
* be created for each provided packages and made available for the next call to the api.
|
|
58
|
-
*
|
|
59
|
-
* @default false
|
|
60
|
-
*/
|
|
61
|
-
readonly useCache?: boolean;
|
|
62
|
-
/**
|
|
63
|
-
* How long the cache for the provided packages should be used before being refreshed (in milliseconds).
|
|
64
|
-
* If `useCache` is not supplied, this option has no effect.
|
|
65
|
-
* If `0` is used, this will force the cache to refresh immediately:
|
|
66
|
-
* 1) The api will returned immediately (without any latest nor next version available for the provided packages)
|
|
67
|
-
* 2) New updates will be fetched in the background
|
|
68
|
-
* 3) The cache for each provided packages will be refreshed and made available for the next call to the api
|
|
69
|
-
*
|
|
70
|
-
* @default ONE_DAY
|
|
71
|
-
*/
|
|
72
|
-
readonly cacheMaxAge?: number;
|
|
73
|
-
/**
|
|
74
|
-
* A JavaScript package registry url that implements the CommonJS Package Registry specification.
|
|
75
|
-
*
|
|
76
|
-
* @default "Looks at any registry urls in the .npmrc file or fallback to the default npm registry instead"
|
|
77
|
-
* @example <caption>.npmrc</caption>
|
|
78
|
-
* registry = 'https://custom-registry.com/'
|
|
79
|
-
* @pkgscope:registry = 'https://custom-registry.com/'
|
|
80
|
-
*/
|
|
81
|
-
readonly registryUrl?: string;
|
|
82
|
-
/**
|
|
83
|
-
* Set of options to be passed down to Node.js http/https request.
|
|
84
|
-
*
|
|
85
|
-
* @example <caption>Behind a proxy with self-signed certificate</caption>
|
|
86
|
-
* { ca: [ fs.readFileSync('proxy-cert.pem') ] }
|
|
87
|
-
* @example <caption>Bypassing certificate validation</caption>
|
|
88
|
-
* { rejectUnauthorized: false }
|
|
89
|
-
*/
|
|
90
|
-
readonly requestOptions?: RequestOptions;
|
|
91
|
-
}
|
|
92
|
-
declare type LatestVersion = {
|
|
93
|
-
/**
|
|
94
|
-
* Get latest versions of packages from of a package json like object.
|
|
95
|
-
*
|
|
96
|
-
* @param {PackageJson} item - A package json like object (with dependencies, devDependencies and peerDependencies attributes).
|
|
97
|
-
* @example { dependencies: { 'npm': 'latest' }, devDependencies: { 'npm': '1.3.2' }, peerDependencies: { '@scope/name': '^5.0.2' } }
|
|
98
|
-
* @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.
|
|
99
|
-
* If `useCache` is not supplied, the default of `false` is used.
|
|
100
|
-
* If `cacheMaxAge` is not supplied, the default of `one day` is used.
|
|
101
|
-
* If `registryUrl` is not supplied, the default from `.npmrc` is used or a fallback to the `npm registry url` instead.
|
|
102
|
-
* @returns {Promise<LatestVersionPackage[]>}
|
|
103
|
-
*/
|
|
104
|
-
(item: PackageJson, options?: LatestVersionOptions): Promise<LatestVersionPackage[]>;
|
|
105
|
-
/**
|
|
106
|
-
* Get latest version of a single package.
|
|
107
|
-
*
|
|
108
|
-
* @param {Package} item - A single package object (represented by a string that should match the following format: `${'@' | ''}${string}@${string}`)
|
|
109
|
-
* @example 'npm', 'npm@1.3.2', '@scope/name@^5.0.2'
|
|
110
|
-
* @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.
|
|
111
|
-
* If `useCache` is not supplied, the default of `false` is used.
|
|
112
|
-
* If `cacheMaxAge` is not supplied, the default of `one day` is used.
|
|
113
|
-
* If `registryUrl` is not supplied, the default from `.npmrc` is used or a fallback to the npm registry url instead.
|
|
114
|
-
* @returns {Promise<LatestVersionPackage>}
|
|
115
|
-
*/
|
|
116
|
-
(item: Package, options?: LatestVersionOptions): Promise<LatestVersionPackage>;
|
|
117
|
-
/**
|
|
118
|
-
* Get latest versions of a collection of packages.
|
|
119
|
-
*
|
|
120
|
-
* @param {Package[]} items - A collection of package object (represented by a string that should match the following format: `${'@' | ''}${string}@${string}`)
|
|
121
|
-
* @example ['npm', 'npm@1.3.2', '@scope/name@^5.0.2']
|
|
122
|
-
* @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.
|
|
123
|
-
* If `useCache` is not supplied, the default of `false` is used.
|
|
124
|
-
* If `cacheMaxAge` is not supplied, the default of `one day` is used.
|
|
125
|
-
* If `registryUrl` is not supplied, the default from `.npmrc` is used or a fallback to the npm registry url instead.
|
|
126
|
-
* @returns {Promise<LatestVersionPackage[]>}
|
|
127
|
-
*/
|
|
128
|
-
(items: Package[], options?: LatestVersionOptions): Promise<LatestVersionPackage[]>;
|
|
129
|
-
};
|
|
130
|
-
declare type PackageRange = `${'@' | ''}${string}@${string}`;
|
|
131
|
-
declare type Package = string | PackageRange;
|
|
132
|
-
declare type PackageJsonDependencies = Record<string, string>;
|
|
133
|
-
declare type PackageJson = Record<string, any> & ({
|
|
134
|
-
dependencies: PackageJsonDependencies;
|
|
135
|
-
} | {
|
|
136
|
-
devDependencies: PackageJsonDependencies;
|
|
137
|
-
} | {
|
|
138
|
-
peerDependencies: PackageJsonDependencies;
|
|
139
|
-
});
|
|
140
|
-
declare const latestVersion: LatestVersion;
|
|
141
|
-
export { LatestVersion, Package, PackageRange, PackageJson, PackageJsonDependencies, LatestVersions, LatestVersionPackage, RequestOptions, LatestVersionOptions };
|
|
142
|
-
export default latestVersion;
|
package/esm/index.js
DELETED
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
import getRegistryUrl from 'registry-auth-token/registry-url';
|
|
2
|
-
import registryAuthToken from 'registry-auth-token';
|
|
3
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
4
|
-
import { gt, maxSatisfying } from 'semver';
|
|
5
|
-
import { npm, yarn } from 'global-dirs';
|
|
6
|
-
import { join, dirname } from 'path';
|
|
7
|
-
import { homedir } from 'os';
|
|
8
|
-
import { URL } from 'url';
|
|
9
|
-
const ONE_DAY = 1000 * 60 * 60 * 24; // eslint-disable-line @typescript-eslint/naming-convention
|
|
10
|
-
const isPackageJson = (obj) => {
|
|
11
|
-
return (obj.dependencies !== undefined) ||
|
|
12
|
-
(obj.devDependencies !== undefined) ||
|
|
13
|
-
(obj.peerDependencies !== undefined);
|
|
14
|
-
};
|
|
15
|
-
const downloadMetadata = (pkgName, options) => {
|
|
16
|
-
return new Promise((resolve, reject) => {
|
|
17
|
-
const i = pkgName.indexOf('/');
|
|
18
|
-
const pkgScope = (i !== -1) ? pkgName.slice(0, i) : '';
|
|
19
|
-
const registryUrl = options?.registryUrl || getRegistryUrl(pkgScope);
|
|
20
|
-
const pkgUrl = new URL(encodeURIComponent(pkgName).replace(/^%40/, '@'), registryUrl);
|
|
21
|
-
let requestOptions = {
|
|
22
|
-
headers: { accept: 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' },
|
|
23
|
-
host: pkgUrl.hostname,
|
|
24
|
-
path: pkgUrl.pathname,
|
|
25
|
-
port: pkgUrl.port
|
|
26
|
-
};
|
|
27
|
-
const authInfo = registryAuthToken(pkgUrl.toString(), { recursive: true });
|
|
28
|
-
if (authInfo && requestOptions.headers) {
|
|
29
|
-
requestOptions.headers.authorization = `${authInfo.type} ${authInfo.token}`;
|
|
30
|
-
}
|
|
31
|
-
if (options?.requestOptions) {
|
|
32
|
-
requestOptions = { ...requestOptions, ...options.requestOptions };
|
|
33
|
-
}
|
|
34
|
-
const { get } = require((pkgUrl.protocol === 'https:') ? 'https' : 'http');
|
|
35
|
-
const request = get(requestOptions, (res) => {
|
|
36
|
-
if (res.statusCode === 200) {
|
|
37
|
-
let rawData = '';
|
|
38
|
-
res.setEncoding('utf8');
|
|
39
|
-
res.on('data', (chunk) => rawData += chunk);
|
|
40
|
-
res.once('end', () => {
|
|
41
|
-
res.setTimeout(0);
|
|
42
|
-
res.removeAllListeners();
|
|
43
|
-
try {
|
|
44
|
-
const pkgMetadata = JSON.parse(rawData);
|
|
45
|
-
return resolve({
|
|
46
|
-
name: pkgName,
|
|
47
|
-
lastUpdateDate: Date.now(),
|
|
48
|
-
versions: Object.keys(pkgMetadata.versions),
|
|
49
|
-
distTags: pkgMetadata['dist-tags']
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
catch (err) {
|
|
53
|
-
return reject(err);
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
res.removeAllListeners();
|
|
59
|
-
res.resume(); // consume response data to free up memory
|
|
60
|
-
return reject(`Request error (${res.statusCode}): ${pkgUrl}`);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
const abort = (error) => {
|
|
64
|
-
request.removeAllListeners();
|
|
65
|
-
request.destroy();
|
|
66
|
-
return reject(error);
|
|
67
|
-
};
|
|
68
|
-
request.once('timeout', () => abort(`Request timed out: ${pkgUrl}`));
|
|
69
|
-
request.once('error', (err) => abort(err));
|
|
70
|
-
});
|
|
71
|
-
};
|
|
72
|
-
const getCacheDir = (name = '@badisi/latest-version') => {
|
|
73
|
-
const homeDir = homedir();
|
|
74
|
-
switch (process.platform) {
|
|
75
|
-
case 'darwin': return join(homeDir, 'Library', 'Caches', name);
|
|
76
|
-
case 'win32': return join(process.env.LOCALAPPDATA || join(homeDir, 'AppData', 'Local'), name, 'Cache');
|
|
77
|
-
default: return join(process.env.XDG_CACHE_HOME || join(homeDir, '.cache'), name);
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
const saveMetadataToCache = (pkg) => {
|
|
81
|
-
const filePath = join(getCacheDir(), `${pkg.name}.json`);
|
|
82
|
-
if (!existsSync(dirname(filePath))) {
|
|
83
|
-
mkdirSync(dirname(filePath), { recursive: true });
|
|
84
|
-
}
|
|
85
|
-
writeFileSync(filePath, JSON.stringify(pkg));
|
|
86
|
-
};
|
|
87
|
-
const getMetadataFromCache = (pkgName, options) => {
|
|
88
|
-
const pkgCacheFilePath = join(getCacheDir(), `${pkgName}.json`);
|
|
89
|
-
if (existsSync(pkgCacheFilePath)) {
|
|
90
|
-
const pkg = JSON.parse(readFileSync(pkgCacheFilePath).toString());
|
|
91
|
-
const maxAge = (options?.cacheMaxAge !== undefined) ? options.cacheMaxAge : ONE_DAY;
|
|
92
|
-
if ((Date.now() - pkg.lastUpdateDate) < maxAge) {
|
|
93
|
-
return pkg;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return undefined;
|
|
97
|
-
};
|
|
98
|
-
const getLatestVersions = async (pkgName, tagOrRange, options) => {
|
|
99
|
-
let pkgMetadata;
|
|
100
|
-
if (pkgName.length && options?.useCache) {
|
|
101
|
-
pkgMetadata = getMetadataFromCache(pkgName, options);
|
|
102
|
-
if (!pkgMetadata) {
|
|
103
|
-
return downloadMetadata(pkgName, options).then(saveMetadataToCache);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
else if (pkgName.length) {
|
|
107
|
-
pkgMetadata = await downloadMetadata(pkgName, options);
|
|
108
|
-
}
|
|
109
|
-
const versions = {
|
|
110
|
-
latest: pkgMetadata?.distTags?.latest,
|
|
111
|
-
next: pkgMetadata?.distTags?.next
|
|
112
|
-
};
|
|
113
|
-
if (tagOrRange && pkgMetadata?.distTags && pkgMetadata?.distTags[tagOrRange]) {
|
|
114
|
-
versions.wanted = pkgMetadata.distTags[tagOrRange];
|
|
115
|
-
}
|
|
116
|
-
else if (tagOrRange && pkgMetadata?.versions?.length) {
|
|
117
|
-
versions.wanted = maxSatisfying(pkgMetadata.versions, tagOrRange) || undefined;
|
|
118
|
-
}
|
|
119
|
-
return versions;
|
|
120
|
-
};
|
|
121
|
-
const getInstalledVersion = (pkgName) => {
|
|
122
|
-
try {
|
|
123
|
-
const paths = ['.', npm.packages, yarn.packages];
|
|
124
|
-
return require(require.resolve(join(pkgName, 'package.json'), { paths }))?.version;
|
|
125
|
-
}
|
|
126
|
-
catch {
|
|
127
|
-
return undefined;
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
const getInfo = async (pkg, options) => {
|
|
131
|
-
const i = pkg.lastIndexOf('@');
|
|
132
|
-
let pkgInfo = {
|
|
133
|
-
name: (i > 1) ? pkg.slice(0, i) : pkg,
|
|
134
|
-
wantedTagOrRange: (i > 1) ? pkg.slice(i + 1) : undefined,
|
|
135
|
-
updatesAvailable: { latest: false, next: false, wanted: false }
|
|
136
|
-
};
|
|
137
|
-
try {
|
|
138
|
-
pkgInfo = {
|
|
139
|
-
...pkgInfo,
|
|
140
|
-
installed: getInstalledVersion(pkgInfo.name),
|
|
141
|
-
...(await getLatestVersions(pkgInfo.name, pkgInfo.wantedTagOrRange, options))
|
|
142
|
-
};
|
|
143
|
-
pkgInfo.updatesAvailable = {
|
|
144
|
-
latest: (pkgInfo.installed && pkgInfo.latest) ? gt(pkgInfo.latest, pkgInfo.installed) : false,
|
|
145
|
-
next: (pkgInfo.installed && pkgInfo.next) ? gt(pkgInfo.next, pkgInfo.installed) : false,
|
|
146
|
-
wanted: (pkgInfo.installed && pkgInfo.wanted) ? gt(pkgInfo.wanted, pkgInfo.installed) : false
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
catch (err) {
|
|
150
|
-
pkgInfo.error = err?.message || err;
|
|
151
|
-
}
|
|
152
|
-
return pkgInfo;
|
|
153
|
-
};
|
|
154
|
-
const latestVersion = async (arg, options) => {
|
|
155
|
-
const pkgs = [];
|
|
156
|
-
if (typeof arg === 'string') {
|
|
157
|
-
pkgs.push(arg);
|
|
158
|
-
}
|
|
159
|
-
else if (Array.isArray(arg)) {
|
|
160
|
-
pkgs.push(...arg);
|
|
161
|
-
}
|
|
162
|
-
else if (isPackageJson(arg)) {
|
|
163
|
-
const addDeps = (deps) => {
|
|
164
|
-
if (deps) {
|
|
165
|
-
pkgs.push(...Object.keys(deps).map((key) => `${key}@${deps[key]}`));
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
|
-
addDeps(arg.dependencies);
|
|
169
|
-
addDeps(arg.devDependencies);
|
|
170
|
-
addDeps(arg.peerDependencies);
|
|
171
|
-
}
|
|
172
|
-
const jobs = await Promise.allSettled(pkgs.map((pkg) => getInfo(pkg, options)));
|
|
173
|
-
const results = jobs.map((jobResult) => jobResult.value);
|
|
174
|
-
return (typeof arg === 'string') ? results[0] : results;
|
|
175
|
-
};
|
|
176
|
-
export default latestVersion;
|
|
177
|
-
module.exports = latestVersion;
|
package/esm/package.json
DELETED