Skip to content

Commit

Permalink
feat: renamed some functions and added deprecated message for the old…
Browse files Browse the repository at this point in the history
… ones, added a resolvePackage function

Signed-off-by: prisis <d.bannert@anolilab.de>
  • Loading branch information
prisis committed Jun 15, 2023
1 parent fffca2b commit 75c9790
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 33 deletions.
24 changes: 20 additions & 4 deletions packages/package-json-utils/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,12 @@ test("isPackageAvailable: returns false when the package is not available", () =
assert.isFalse(isPackageAvailable("vitest2"));
});

test.each(["warn", "log", "error", "info"])("showMissingPackages: logs a %type message with the missing packages", (type: "error" | "info" | "log" | "warn") => {
test.each([
"warn",
"log",
"error",
"info",
])("showMissingPackages: logs a %type message with the missing packages", (type: "error" | "info" | "log" | "warn") => {
const consoleMock = vi.spyOn(console, type);

showMissingPackages("example", ["package1", "package2"], {
Expand Down Expand Up @@ -161,9 +166,20 @@ test("showMissingPackages: logs a warning message with the missing packages, pre
});

test("unique: returns an array with unique values", () => {
const array = [1, 2, 2, 3, 3, 3];

assert.deepEqual(unique(array), [1, 2, 3]);
const array = [
1,
2,
2,
3,
3,
3,
];

assert.deepEqual(unique(array), [
1,
2,
3,
]);
});

test("pkg: returns packageJson as NormalizedReadResult or undefined", () => {
Expand Down
14 changes: 7 additions & 7 deletions packages/package-json-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,6 @@
"read-pkg-up": "^7.0.1"
},
"devDependencies": {
"cross-env": "^7.0.3",
"rimraf": "^5.0.1",
"tsup": "^6.7.0",
"typescript": "^5.1.3",
"vitest": "^0.32.0",
"semantic-release": "^21.0.4",
"@commitlint/cli": "^17.6.5",
"@commitlint/config-conventional": "^17.6.5",
"@commitlint/core": "^17.6.5",
Expand All @@ -76,8 +70,14 @@
"@semantic-release/release-notes-generator": "^11.0.3",
"commitizen": "^4.3.0",
"conventional-changelog-conventionalcommits": "^6.0.0",
"cross-env": "^7.0.3",
"cz-conventional-changelog": "^3.3.0",
"semantic-release-conventional-commits": "^3.0.0"
"rimraf": "^5.0.1",
"semantic-release": "^21.0.4",
"semantic-release-conventional-commits": "^3.0.0",
"tsup": "^6.7.0",
"typescript": "^5.1.3",
"vitest": "^0.32.0"
},
"engines": {
"node": ">=16"
Expand Down
82 changes: 60 additions & 22 deletions packages/package-json-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { getByPath } from "dot-path-value";
import { existsSync, realpathSync } from "node:fs";
import module from "node:module";
import { dirname, join } from "node:path";
import type { NormalizedPackageJson } from "read-pkg";
import readPkgUp from "read-pkg-up";

const { packageJson, path: packagePath } = readPkgUp.sync({
Expand All @@ -17,9 +18,23 @@ const atLatest = (name: string): string => {
};

// eslint-disable-next-line max-len
export const hasPackageProperties = (properties: string[]): boolean => properties.some((property: string) => Boolean(packageJson !== undefined && getByPath(packageJson, property)));
export const hasPackageProperty = (property: string): boolean => Boolean(packageJson !== undefined && getByPath(packageJson, property));

export const hasPackageSubProperties = (packageProperty: string) => (properties: string[]): boolean => hasPackageProperties(properties.map((p) => `${packageProperty}.${p}`));
export const hasPackageSubProperty = (packageProperty: string) => (property: string): boolean => hasPackageProperty(`${packageProperty}.${property}`);

// eslint-disable-next-line max-len
export const hasPackageProperties = (properties: string[], strict?: boolean): boolean => {
if (strict) {
return properties.every((property: string) => hasPackageProperty(property));
}

return properties.some((property: string) => hasPackageProperty(property));
};

export const hasPackageSubProperties = (packageProperty: string) => (properties: string[], strict?: boolean): boolean => hasPackageProperties(
properties.map((p) => `${packageProperty}.${p}`),
strict,
);

export const environmentIsSet = (name: string): boolean => Boolean(process.env[name] && process.env[name] !== "undefined");

Expand All @@ -38,53 +53,76 @@ export const parseEnvironment = (name: string, defaultValue: unknown): any => {
export const projectPath: string = packagePath ? dirname(packagePath) : "";
// @deprecated Use `projectPath` instead.
export const appDirectory: string = projectPath;
export const fromRoot = (...p: string[]): string => join(appDirectory, ...p);
export const fromRoot = (...p: string[]): string => join(projectPath, ...p);
export const hasFile = (...p: string[]): boolean => existsSync(fromRoot(...p));

export const hasScripts = hasPackageSubProperties("scripts");
export const hasPeerDep = hasPackageSubProperties("peerDependencies");
export const hasDep = hasPackageSubProperties("dependencies");
export const hasDevelopmentDep = hasPackageSubProperties("devDependencies");
export const hasPeerDependency = hasPackageSubProperty("peerDependencies");
export const hasPeerDependencies = hasPackageSubProperties("peerDependencies");
// @deprecated Use `hasPeerDependencies` instead.
export const hasPeerDep = hasPeerDependencies;
export const hasDependency = hasPackageSubProperty("dependencies");
export const hasDependencies = hasPackageSubProperties("dependencies");
// @deprecated Use `hasDependencies` instead.
export const hasDep = hasDependencies;
// eslint-disable-next-line unicorn/prevent-abbreviations
export const hasDevDependency = hasPackageSubProperty("devDependencies");
// eslint-disable-next-line unicorn/prevent-abbreviations
export const hasDevDependencies = hasPackageSubProperties("devDependencies");
// @deprecated Use `hasDevDependencies` instead.
export const hasDevelopmentDep = hasDevDependencies;
// eslint-disable-next-line max-len
export const hasAnyDep = (arguments_: string[]): boolean => [hasDep, hasDevelopmentDep, hasPeerDep].some((function_: (arguments_: string[]) => boolean) => function_(arguments_));
export const hasAnyDep = (arguments_: string[], options?: { peerDeps?: boolean; strict?: boolean }): boolean => [
hasDependencies,
hasDevDependencies,
options?.peerDeps === false ? () => false : hasPeerDependencies,
].some(
(function_: (arguments_: string[], strict?: boolean) => boolean) => function_(arguments_, options?.strict),
);

export const hasTypescript: boolean = hasAnyDep(["typescript"]) && hasFile("tsconfig.json");
export const hasTypescript: boolean = (hasDependency("typescript") || hasDevDependency("typescript")) && hasFile("tsconfig.json");

export const packageIsTypeModule = hasPackageProperties(["type"]) && packageJson?.["type"] === "module";

export const isPackageAvailable = (moduleName: string): boolean => {
const targetModule = import.meta.url;
export const resolvePackage = (packageName: string): string | undefined => {
// See https://yarnpkg.com/advanced/pnpapi
if (process.versions["pnp"]) {
const targetModule = import.meta.url;
// @ts-expect-error TS2339: Property 'findPnpApi' does not exist on type 'typeof Module'.
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-assignment
const targetPnp = module.findPnpApi(targetModule);

// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
if (targetPnp.resolveRequest(moduleName, targetModule)) {
return true;
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
const resolved = targetPnp.resolveRequest(packageName, targetModule);

if (resolved) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return resolved;
}
} else if (packageIsTypeModule) {
const targetModule = import.meta.url;
// See https://nodejs.org/api/esm.html#esm_resolver_algorithm
try {
module.createRequire(targetModule).resolve(moduleName);

return true;
return module.createRequire(targetModule).resolve(packageName);
} catch {
return false;
return undefined;
}
}

try {
// eslint-disable-next-line unicorn/prefer-module
require.resolve(moduleName);

return true;
return require.resolve(packageName);
} catch {
return false;
return undefined;
}
};

export const isPackageAvailable = (packageName: string): boolean => {
const resolved = resolvePackage(packageName);

return resolved !== undefined;
};

export const showMissingPackages = (
packageName: string,
packages: string[],
Expand Down Expand Up @@ -125,4 +163,4 @@ ${options.postMessage ?? ""}\n
export const unique = (array: unknown[]): unknown[] => [...new Set(array)];

// eslint-disable-next-line unicorn/prevent-abbreviations
export const pkg = packageJson as readPkgUp.NormalizedReadResult | undefined;
export const pkg = packageJson as NormalizedPackageJson | undefined;

0 comments on commit 75c9790

Please sign in to comment.