-
Notifications
You must be signed in to change notification settings - Fork 168
Expand file tree
/
Copy pathpackage.ts
More file actions
84 lines (77 loc) · 2.64 KB
/
package.ts
File metadata and controls
84 lines (77 loc) · 2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import fs from 'node:fs';
import { createRequire } from 'node:module';
import path from 'node:path';
import { VITE_PLUS_NAME } from './constants.ts';
import { readJsonFile } from './json.ts';
export function getScopeFromPackageName(packageName: string): string {
if (packageName.startsWith('@')) {
return packageName.split('/')[0];
}
return '';
}
interface PackageMetadata {
name: string;
version: string;
path: string;
}
export function detectPackageMetadata(
projectPath: string,
packageName: string,
): PackageMetadata | void {
try {
// Create require from the project path so resolution only searches
// the project's node_modules, not the global installation's
const require = createRequire(path.join(projectPath, 'noop.js'));
const pkgFilePath = require.resolve(`${packageName}/package.json`);
const pkg = JSON.parse(fs.readFileSync(pkgFilePath, 'utf8'));
return {
name: pkg.name,
version: pkg.version,
path: path.dirname(pkgFilePath),
};
} catch {
// ignore MODULE_NOT_FOUND error
return;
}
}
/**
* Read the nearest package.json file from the current directory up to the root directory.
* @param currentDir - The current directory to start searching from.
* @returns The package.json content as a JSON object, or null if no package.json is found.
*/
export function readNearestPackageJson(currentDir: string): Record<string, unknown> | null {
do {
const packageJsonPath = path.join(currentDir, 'package.json');
if (fs.existsSync(packageJsonPath)) {
return readJsonFile(packageJsonPath);
}
currentDir = path.dirname(currentDir);
} while (currentDir !== path.dirname(currentDir));
return null;
}
export function hasVitePlusDependency(
pkg?: {
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
} | null,
) {
return Boolean(pkg?.dependencies?.[VITE_PLUS_NAME] || pkg?.devDependencies?.[VITE_PLUS_NAME]);
}
/**
* Check if an npm package exists in the public registry.
* Returns true if the package exists or if the check could not be performed (network error, timeout).
* Returns false only if the registry definitively responds with 404.
*/
export async function checkNpmPackageExists(packageName: string): Promise<boolean> {
const atIndex = packageName.indexOf('@', 2);
const name = atIndex === -1 ? packageName : packageName.slice(0, atIndex);
try {
const response = await fetch(`https://registry.npmjs.org/${name}`, {
method: 'HEAD',
signal: AbortSignal.timeout(3000),
});
return response.status !== 404;
} catch {
return true; // Network error or timeout - let the package manager handle it
}
}