inup 1.4.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.
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.changelogFetcher = exports.ChangelogFetcher = void 0;
4
+ /**
5
+ * Fetches package metadata from npm registry
6
+ * Includes description, repository info, and basic metadata
7
+ */
8
+ class ChangelogFetcher {
9
+ constructor() {
10
+ this.cache = new Map();
11
+ this.failureCache = new Set(); // Track packages that failed to fetch
12
+ }
13
+ /**
14
+ * Fetch package metadata from npm registry
15
+ * Uses a cached approach to avoid repeated requests
16
+ */
17
+ async fetchPackageMetadata(packageName) {
18
+ // Check if we already have this in cache
19
+ if (this.cache.has(packageName)) {
20
+ return this.cache.get(packageName);
21
+ }
22
+ // Check if we already failed to fetch this
23
+ if (this.failureCache.has(packageName)) {
24
+ return null;
25
+ }
26
+ try {
27
+ // Fetch from npm registry
28
+ const response = await this.fetchFromRegistry(packageName);
29
+ if (!response) {
30
+ this.failureCache.add(packageName);
31
+ return null;
32
+ }
33
+ const repositoryUrl = this.extractRepositoryUrl(response.repository?.url || '');
34
+ const npmUrl = `https://www.npmjs.com/package/${encodeURIComponent(packageName)}`;
35
+ const issuesUrl = repositoryUrl ? `${repositoryUrl}/issues` : undefined;
36
+ const metadata = {
37
+ description: response.description || 'No description available',
38
+ homepage: response.homepage,
39
+ repository: response.repository,
40
+ bugs: response.bugs,
41
+ keywords: response.keywords || [],
42
+ author: response.author?.name || response.author,
43
+ license: response.license,
44
+ repositoryUrl,
45
+ npmUrl,
46
+ issuesUrl,
47
+ };
48
+ // Try to extract release notes/changelog info
49
+ if (repositoryUrl) {
50
+ metadata.releaseNotes = `${repositoryUrl}/releases`;
51
+ }
52
+ // Try to get weekly download count
53
+ try {
54
+ const downloadsData = await this.fetchDownloadStats(packageName);
55
+ if (downloadsData) {
56
+ metadata.weeklyDownloads = downloadsData.downloads;
57
+ }
58
+ }
59
+ catch {
60
+ // Ignore download stats errors - optional data
61
+ }
62
+ this.cache.set(packageName, metadata);
63
+ return metadata;
64
+ }
65
+ catch (error) {
66
+ // Cache the failure to avoid retrying
67
+ this.failureCache.add(packageName);
68
+ return null;
69
+ }
70
+ }
71
+ /**
72
+ * Fetch data from npm registry
73
+ * Returns the package data from the registry
74
+ */
75
+ async fetchFromRegistry(packageName) {
76
+ try {
77
+ const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}`, {
78
+ method: 'GET',
79
+ headers: {
80
+ accept: 'application/json',
81
+ },
82
+ });
83
+ if (!response.ok) {
84
+ return null;
85
+ }
86
+ const data = (await response.json());
87
+ // Get the latest version data
88
+ const distTags = data['dist-tags'];
89
+ const latestVersion = distTags?.latest;
90
+ const versions = data.versions;
91
+ const latestPackageData = latestVersion ? versions?.[latestVersion] : undefined;
92
+ return {
93
+ description: data.description,
94
+ homepage: (data.homepage || latestPackageData?.homepage),
95
+ repository: (data.repository || latestPackageData?.repository),
96
+ bugs: (data.bugs || latestPackageData?.bugs),
97
+ keywords: (data.keywords || []),
98
+ author: (data.author || latestPackageData?.author),
99
+ license: (data.license || latestPackageData?.license),
100
+ };
101
+ }
102
+ catch {
103
+ return null;
104
+ }
105
+ }
106
+ /**
107
+ * Extract GitHub URL from repository URL for easier access to releases
108
+ */
109
+ extractRepositoryUrl(repoUrl) {
110
+ if (!repoUrl)
111
+ return '';
112
+ // Handle various repository URL formats
113
+ // git+https://github.com/user/repo.git -> https://github.com/user/repo/releases
114
+ // https://github.com/user/repo.git -> https://github.com/user/repo/releases
115
+ // github:user/repo -> https://github.com/user/repo/releases
116
+ let cleanUrl = repoUrl
117
+ .replace(/^git\+/, '') // Remove git+ prefix
118
+ .replace(/\.git$/, '') // Remove .git suffix
119
+ .replace(/^github:/, 'https://github.com/'); // Convert github: format
120
+ // Ensure it's a proper URL
121
+ if (!cleanUrl.startsWith('http')) {
122
+ cleanUrl = 'https://github.com/' + cleanUrl;
123
+ }
124
+ return cleanUrl;
125
+ }
126
+ /**
127
+ * Fetch weekly download statistics from npm
128
+ */
129
+ async fetchDownloadStats(packageName) {
130
+ try {
131
+ const response = await fetch(`https://api.npmjs.org/downloads/point/last-week/${encodeURIComponent(packageName)}`, {
132
+ method: 'GET',
133
+ headers: {
134
+ accept: 'application/json',
135
+ },
136
+ });
137
+ if (!response.ok) {
138
+ return null;
139
+ }
140
+ const data = (await response.json());
141
+ return {
142
+ downloads: data.downloads || 0,
143
+ };
144
+ }
145
+ catch {
146
+ return null;
147
+ }
148
+ }
149
+ /**
150
+ * Get repository release URL for a package
151
+ */
152
+ getRepositoryReleaseUrl(packageName, version) {
153
+ const metadata = this.cache.get(packageName);
154
+ if (!metadata || !metadata.releaseNotes) {
155
+ return null;
156
+ }
157
+ return `${metadata.releaseNotes}/releases/tag/v${version}`;
158
+ }
159
+ /**
160
+ * Cache package metadata directly (used by utils to avoid duplicate fetches)
161
+ */
162
+ cacheMetadata(packageName, rawData) {
163
+ const repositoryUrl = this.extractRepositoryUrl(rawData.repository?.url || '');
164
+ const npmUrl = `https://www.npmjs.com/package/${encodeURIComponent(packageName)}`;
165
+ const issuesUrl = repositoryUrl ? `${repositoryUrl}/issues` : undefined;
166
+ const metadata = {
167
+ description: rawData.description || 'No description available',
168
+ homepage: rawData.homepage,
169
+ repository: rawData.repository,
170
+ bugs: rawData.bugs,
171
+ keywords: rawData.keywords || [],
172
+ author: rawData.author?.name || rawData.author,
173
+ license: rawData.license,
174
+ repositoryUrl,
175
+ npmUrl,
176
+ issuesUrl,
177
+ };
178
+ if (repositoryUrl) {
179
+ metadata.releaseNotes = `${repositoryUrl}/releases`;
180
+ }
181
+ this.cache.set(packageName, metadata);
182
+ }
183
+ /**
184
+ * Clear the cache (useful for testing)
185
+ */
186
+ clearCache() {
187
+ this.cache.clear();
188
+ this.failureCache.clear();
189
+ }
190
+ }
191
+ exports.ChangelogFetcher = ChangelogFetcher;
192
+ exports.changelogFetcher = new ChangelogFetcher();
193
+ //# sourceMappingURL=changelog-fetcher.js.map
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ /**
3
+ * External service integrations
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ __exportStar(require("./npm-registry"), exports);
21
+ __exportStar(require("./jsdelivr-registry"), exports);
22
+ __exportStar(require("./changelog-fetcher"), exports);
23
+ __exportStar(require("./version-checker"), exports);
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,232 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getAllPackageDataFromJsdelivr = getAllPackageDataFromJsdelivr;
37
+ exports.clearJsdelivrPackageCache = clearJsdelivrPackageCache;
38
+ exports.closeJsdelivrPool = closeJsdelivrPool;
39
+ const undici_1 = require("undici");
40
+ const semver = __importStar(require("semver"));
41
+ const constants_1 = require("../constants");
42
+ const npm_registry_1 = require("./npm-registry");
43
+ // Create a persistent connection pool for jsDelivr CDN with optimal settings
44
+ // This enables connection reuse and HTTP/1.1 keep-alive for blazing fast requests
45
+ const jsdelivrPool = new undici_1.Pool('https://cdn.jsdelivr.net', {
46
+ connections: constants_1.MAX_CONCURRENT_REQUESTS, // Maximum concurrent connections
47
+ pipelining: 10, // Enable request pipelining for even better performance
48
+ keepAliveTimeout: 60000, // Keep connections alive for 60 seconds
49
+ keepAliveMaxTimeout: 600000, // Maximum keep-alive timeout
50
+ });
51
+ const packageCache = new Map();
52
+ /**
53
+ * Fetches package.json from jsdelivr CDN for a specific version tag using undici pool.
54
+ * Uses connection pooling and keep-alive for maximum performance.
55
+ * @param packageName - The npm package name
56
+ * @param versionTag - The version tag (e.g., '14', 'latest')
57
+ * @returns The package.json content or null if not found
58
+ */
59
+ async function fetchPackageJsonFromJsdelivr(packageName, versionTag) {
60
+ try {
61
+ const url = `${constants_1.JSDELIVR_CDN_URL}/${encodeURIComponent(packageName)}@${versionTag}/package.json`;
62
+ const { statusCode, body } = await (0, undici_1.request)(url, {
63
+ dispatcher: jsdelivrPool,
64
+ method: 'GET',
65
+ headers: {
66
+ accept: 'application/json',
67
+ },
68
+ headersTimeout: constants_1.REQUEST_TIMEOUT,
69
+ bodyTimeout: constants_1.REQUEST_TIMEOUT,
70
+ });
71
+ if (statusCode !== 200) {
72
+ // Consume body to prevent memory leaks
73
+ await body.text();
74
+ return null;
75
+ }
76
+ const text = await body.text();
77
+ const data = JSON.parse(text);
78
+ return data.version ? { version: data.version } : null;
79
+ }
80
+ catch (error) {
81
+ console.error(`Error fetching from jsdelivr for package: ${packageName}@${versionTag}`, error);
82
+ return null;
83
+ }
84
+ }
85
+ /**
86
+ * Fetches package data from jsdelivr CDN with fallback to npm registry.
87
+ * Makes simultaneous requests for @latest and @major version.
88
+ * @param packageName - The npm package name
89
+ * @param currentVersion - The current version to extract major from (optional)
90
+ * @returns Package data with latest version and all versions
91
+ */
92
+ async function fetchPackageFromJsdelivr(packageName, currentVersion) {
93
+ // Check cache first
94
+ const cached = packageCache.get(packageName);
95
+ if (cached && Date.now() - cached.timestamp < constants_1.CACHE_TTL) {
96
+ return cached.data;
97
+ }
98
+ try {
99
+ // Determine major version from current version if provided
100
+ // Need to coerce the version first in case it's a range like ^1.1.5
101
+ const majorVersion = currentVersion
102
+ ? semver.major(semver.coerce(currentVersion) || '0.0.0').toString()
103
+ : null;
104
+ // Prepare requests: always fetch @latest, and @major if we have a current version
105
+ const requests = [
106
+ fetchPackageJsonFromJsdelivr(packageName, 'latest'),
107
+ ];
108
+ if (majorVersion) {
109
+ requests.push(fetchPackageJsonFromJsdelivr(packageName, majorVersion));
110
+ }
111
+ // Execute all requests simultaneously
112
+ const results = await Promise.all(requests);
113
+ const latestResult = results[0];
114
+ const majorResult = results[1];
115
+ if (!latestResult) {
116
+ // jsdelivr doesn't have this package, fallback to npm registry
117
+ const npmData = await (0, npm_registry_1.getAllPackageData)([packageName]);
118
+ const data = npmData.get(packageName) || { latestVersion: 'unknown', allVersions: [] };
119
+ // Cache the result
120
+ packageCache.set(packageName, {
121
+ data,
122
+ timestamp: Date.now(),
123
+ });
124
+ return data;
125
+ }
126
+ const latestVersion = latestResult.version;
127
+ // If we have a major version result, we can build a minimal version list
128
+ // This is much faster than fetching all versions from npm
129
+ if (majorResult) {
130
+ const allVersions = [latestVersion];
131
+ // Add the major version result if different from latest
132
+ if (majorResult.version !== latestVersion) {
133
+ allVersions.push(majorResult.version);
134
+ }
135
+ // Add the current version if it's valid and not already in the list
136
+ if (currentVersion && semver.valid(currentVersion)) {
137
+ const coerced = semver.coerce(currentVersion);
138
+ if (coerced && !allVersions.includes(coerced.version)) {
139
+ allVersions.push(coerced.version);
140
+ }
141
+ }
142
+ const result = {
143
+ latestVersion,
144
+ allVersions: allVersions.sort(semver.rcompare),
145
+ };
146
+ // Cache the result
147
+ packageCache.set(packageName, {
148
+ data: result,
149
+ timestamp: Date.now(),
150
+ });
151
+ return result;
152
+ }
153
+ // No major version provided, just return latest with minimal version list
154
+ const allVersions = [latestVersion];
155
+ // Add the current version if it's valid and not already in the list
156
+ if (currentVersion && semver.valid(currentVersion)) {
157
+ const coerced = semver.coerce(currentVersion);
158
+ if (coerced && !allVersions.includes(coerced.version)) {
159
+ allVersions.push(coerced.version);
160
+ }
161
+ }
162
+ const result = {
163
+ latestVersion,
164
+ allVersions: allVersions.sort(semver.rcompare),
165
+ };
166
+ // Cache the result
167
+ packageCache.set(packageName, {
168
+ data: result,
169
+ timestamp: Date.now(),
170
+ });
171
+ return result;
172
+ }
173
+ catch (error) {
174
+ // Fallback to npm registry on any error
175
+ const npmData = await (0, npm_registry_1.getAllPackageData)([packageName]);
176
+ const data = npmData.get(packageName) || { latestVersion: 'unknown', allVersions: [] };
177
+ // Cache the result
178
+ packageCache.set(packageName, {
179
+ data,
180
+ timestamp: Date.now(),
181
+ });
182
+ return data;
183
+ }
184
+ }
185
+ /**
186
+ * Fetches package version data from jsdelivr CDN for multiple packages.
187
+ * Uses undici connection pool for blazing fast performance with connection reuse.
188
+ * Falls back to npm registry if jsdelivr doesn't have the package.
189
+ * @param packageNames - Array of package names to fetch
190
+ * @param currentVersions - Optional map of package names to their current versions
191
+ * @param onProgress - Optional progress callback
192
+ * @returns Map of package names to their version data
193
+ */
194
+ async function getAllPackageDataFromJsdelivr(packageNames, currentVersions, onProgress) {
195
+ const packageData = new Map();
196
+ if (packageNames.length === 0) {
197
+ return packageData;
198
+ }
199
+ const total = packageNames.length;
200
+ let completedCount = 0;
201
+ // Fire all requests simultaneously - undici pool handles concurrency internally
202
+ // No need for p-limit - the pool's connection limit controls concurrency
203
+ const allPromises = packageNames.map(async (packageName) => {
204
+ const currentVersion = currentVersions?.get(packageName);
205
+ const data = await fetchPackageFromJsdelivr(packageName, currentVersion);
206
+ packageData.set(packageName, data);
207
+ completedCount++;
208
+ if (onProgress) {
209
+ onProgress(packageName, completedCount, total);
210
+ }
211
+ });
212
+ // Wait for all requests to complete
213
+ await Promise.all(allPromises);
214
+ // Clear the progress line and show completion time if no custom progress handler
215
+ if (!onProgress) {
216
+ process.stdout.write('\r' + ' '.repeat(80) + '\r');
217
+ }
218
+ return packageData;
219
+ }
220
+ /**
221
+ * Clear the package cache (useful for testing)
222
+ */
223
+ function clearJsdelivrPackageCache() {
224
+ packageCache.clear();
225
+ }
226
+ /**
227
+ * Close the jsDelivr connection pool (useful for graceful shutdown)
228
+ */
229
+ async function closeJsdelivrPool() {
230
+ await jsdelivrPool.close();
231
+ }
232
+ //# sourceMappingURL=jsdelivr-registry.js.map
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getAllPackageData = getAllPackageData;
37
+ exports.clearPackageCache = clearPackageCache;
38
+ exports.closeNpmPool = closeNpmPool;
39
+ const undici_1 = require("undici");
40
+ const semver = __importStar(require("semver"));
41
+ const constants_1 = require("../constants");
42
+ // Create a persistent connection pool for npm registry with optimal settings
43
+ // This enables connection reuse and HTTP/1.1 keep-alive for blazing fast requests
44
+ const npmPool = new undici_1.Pool('https://registry.npmjs.org', {
45
+ connections: constants_1.MAX_CONCURRENT_REQUESTS, // Maximum concurrent connections
46
+ pipelining: 10, // Enable request pipelining for even better performance
47
+ keepAliveTimeout: 60000, // Keep connections alive for 60 seconds
48
+ keepAliveMaxTimeout: 600000, // Maximum keep-alive timeout
49
+ });
50
+ const packageCache = new Map();
51
+ /**
52
+ * Fetches package data from npm registry with caching using undici pool.
53
+ * Uses connection pooling and keep-alive for maximum performance.
54
+ */
55
+ async function fetchPackageFromRegistry(packageName) {
56
+ // Check cache first
57
+ const cached = packageCache.get(packageName);
58
+ if (cached && Date.now() - cached.timestamp < constants_1.CACHE_TTL) {
59
+ return cached.data;
60
+ }
61
+ try {
62
+ const url = `${constants_1.NPM_REGISTRY_URL}/${encodeURIComponent(packageName)}`;
63
+ const { statusCode, body } = await (0, undici_1.request)(url, {
64
+ dispatcher: npmPool,
65
+ method: 'GET',
66
+ headers: {
67
+ accept: 'application/vnd.npm.install-v1+json',
68
+ },
69
+ headersTimeout: constants_1.REQUEST_TIMEOUT,
70
+ bodyTimeout: constants_1.REQUEST_TIMEOUT,
71
+ });
72
+ if (statusCode !== 200) {
73
+ // Consume body to prevent memory leaks
74
+ await body.text();
75
+ throw new Error(`HTTP ${statusCode}`);
76
+ }
77
+ const text = await body.text();
78
+ const data = JSON.parse(text);
79
+ // Extract versions and filter to valid semver (X.Y.Z format, no pre-releases)
80
+ const allVersions = Object.keys(data.versions || {}).filter((version) => {
81
+ // Match only X.Y.Z format (no pre-release, no build metadata)
82
+ return /^[0-9]+\.[0-9]+\.[0-9]+$/.test(version);
83
+ });
84
+ // Sort versions to find the latest
85
+ const sortedVersions = allVersions.sort(semver.rcompare);
86
+ const latestVersion = sortedVersions.length > 0 ? sortedVersions[0] : 'unknown';
87
+ const result = {
88
+ latestVersion,
89
+ allVersions,
90
+ };
91
+ // Cache the result
92
+ packageCache.set(packageName, {
93
+ data: result,
94
+ timestamp: Date.now(),
95
+ });
96
+ return result;
97
+ }
98
+ catch (error) {
99
+ // Return fallback data for failed packages
100
+ return { latestVersion: 'unknown', allVersions: [] };
101
+ }
102
+ }
103
+ /**
104
+ * Fetches package version data from npm registry for multiple packages.
105
+ * Uses undici connection pool for blazing fast performance with connection reuse.
106
+ * Only returns valid semantic versions (X.Y.Z format, excluding pre-releases).
107
+ */
108
+ async function getAllPackageData(packageNames, onProgress) {
109
+ const packageData = new Map();
110
+ if (packageNames.length === 0) {
111
+ return packageData;
112
+ }
113
+ const total = packageNames.length;
114
+ let completedCount = 0;
115
+ // Fire all requests simultaneously - undici pool handles concurrency internally
116
+ // No need for p-limit - the pool's connection limit controls concurrency
117
+ const allPromises = packageNames.map(async (packageName) => {
118
+ const data = await fetchPackageFromRegistry(packageName);
119
+ packageData.set(packageName, data);
120
+ completedCount++;
121
+ if (onProgress) {
122
+ onProgress(packageName, completedCount, total);
123
+ }
124
+ });
125
+ // Wait for all requests to complete
126
+ await Promise.all(allPromises);
127
+ // Clear the progress line and show completion time if no custom progress handler
128
+ if (!onProgress) {
129
+ process.stdout.write('\r' + ' '.repeat(80) + '\r');
130
+ }
131
+ return packageData;
132
+ }
133
+ /**
134
+ * Clear the package cache (useful for testing)
135
+ */
136
+ function clearPackageCache() {
137
+ packageCache.clear();
138
+ }
139
+ /**
140
+ * Close the npm registry connection pool (useful for graceful shutdown)
141
+ */
142
+ async function closeNpmPool() {
143
+ await npmPool.close();
144
+ }
145
+ //# sourceMappingURL=npm-registry.js.map