mirror of
https://github.com/appium/appium.git
synced 2026-10-26 02:29:38 +08:00
96 lines
3.1 KiB
TypeScript
96 lines
3.1 KiB
TypeScript
import nodeFs from 'node:fs';
|
|
import path from 'node:path';
|
|
|
|
import {fs} from '@appium/support';
|
|
import normalizePackageData from 'normalize-package-data';
|
|
import type {PackageJson as TypeFestPackageJson} from 'type-fest';
|
|
|
|
export type PackageJson = TypeFestPackageJson;
|
|
|
|
export type NormalizedPackageJson = PackageJson & {
|
|
name: string;
|
|
version: string;
|
|
readme: string;
|
|
_id: string;
|
|
bugs?: {url: string};
|
|
repository?: {type: string; url: string; directory?: string};
|
|
};
|
|
|
|
export type ReadPackageOptions = {
|
|
/** Directory containing `package.json`. Defaults to `process.cwd()`. */
|
|
cwd?: string;
|
|
/** Normalize package data. Defaults to `true`. */
|
|
normalize?: boolean;
|
|
};
|
|
|
|
export type NormalizeOptions = ReadPackageOptions & {normalize?: true};
|
|
|
|
/** Finds the directory containing the nearest `package.json` by walking upward from `dir`. */
|
|
export async function findPackageRoot(dir: string): Promise<string> {
|
|
assertNonEmptyDir(dir, 'findPackageRoot');
|
|
let current = path.resolve(dir);
|
|
const fsRoot = path.parse(current).root;
|
|
|
|
while (true) {
|
|
if (await fs.exists(path.join(current, 'package.json'))) {
|
|
return current;
|
|
}
|
|
if (current === fsRoot) {
|
|
throwPackageRootNotFound(dir);
|
|
}
|
|
current = path.dirname(current);
|
|
}
|
|
}
|
|
|
|
/** Finds the project root directory from `dir`. */
|
|
export function findPackageRootSync(dir: string): string {
|
|
assertNonEmptyDir(dir, 'findPackageRootSync');
|
|
let current = path.resolve(dir);
|
|
const fsRoot = path.parse(current).root;
|
|
|
|
while (true) {
|
|
if (nodeFs.existsSync(path.join(current, 'package.json'))) {
|
|
return current;
|
|
}
|
|
if (current === fsRoot) {
|
|
throwPackageRootNotFound(dir);
|
|
}
|
|
current = path.dirname(current);
|
|
}
|
|
}
|
|
|
|
/** Reads and parses `package.json` from `cwd`. */
|
|
export async function readPackage(options?: NormalizeOptions): Promise<NormalizedPackageJson>;
|
|
export async function readPackage(options: ReadPackageOptions): Promise<PackageJson>;
|
|
export async function readPackage(options: ReadPackageOptions = {}): Promise<PackageJson | NormalizedPackageJson> {
|
|
const {cwd, normalize = true} = options;
|
|
const contents = await fs.readFile(getPackagePath(cwd), 'utf8');
|
|
return parsePackageJson(contents, normalize);
|
|
}
|
|
|
|
function assertNonEmptyDir(dir: string, fnName: string): void {
|
|
if (!dir) {
|
|
throw new TypeError(`\`${fnName}()\` must be provided a non-empty path`);
|
|
}
|
|
}
|
|
|
|
function throwPackageRootNotFound(dir: string): never {
|
|
throw new Error(`Could not find \`package.json\` from ${dir}`);
|
|
}
|
|
|
|
function getPackagePath(cwd?: string): string {
|
|
return path.resolve(cwd ?? process.cwd(), 'package.json');
|
|
}
|
|
|
|
function parsePackageJson(contents: string, normalize: true): NormalizedPackageJson;
|
|
function parsePackageJson(contents: string, normalize: false): PackageJson;
|
|
function parsePackageJson(contents: string, normalize?: boolean): PackageJson | NormalizedPackageJson;
|
|
function parsePackageJson(contents: string, normalize = true): PackageJson | NormalizedPackageJson {
|
|
const json = JSON.parse(contents) as PackageJson;
|
|
if (normalize === false) {
|
|
return json;
|
|
}
|
|
normalizePackageData(json);
|
|
return json as NormalizedPackageJson;
|
|
}
|