@pinnacle0/pnpm-single-version 1.0.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.
Files changed (43) hide show
  1. package/README.md +74 -0
  2. package/dist/checker/error-message.js +47 -0
  3. package/dist/checker/index.js +33 -0
  4. package/dist/command/checkDeps.js +62 -0
  5. package/dist/command/index.js +2 -0
  6. package/dist/command/install.js +51 -0
  7. package/dist/command/pnpmfile/.pnpmfile.cjs +7 -0
  8. package/dist/command/pnpmfile/hook.js +2 -0
  9. package/dist/command/setup.js +13 -0
  10. package/dist/constant.js +2 -0
  11. package/dist/error.js +37 -0
  12. package/dist/hook-bundle.js +29 -0
  13. package/dist/hook.js +55 -0
  14. package/dist/index.js +2 -0
  15. package/dist/parser-option/find-project-root.js +54 -0
  16. package/dist/parser-option/parse-option.js +62 -0
  17. package/dist/type.js +1 -0
  18. package/dist/util/array-value-map-Helper.js +18 -0
  19. package/dist/util/glob-util.js +16 -0
  20. package/dist/util/logger.js +19 -0
  21. package/dist/util/pipe.js +3 -0
  22. package/dist/util/pnpm-logger.js +15 -0
  23. package/package.json +47 -0
  24. package/src/checker/error-message.ts +58 -0
  25. package/src/checker/index.ts +46 -0
  26. package/src/command/checkDeps.ts +27 -0
  27. package/src/command/index.ts +2 -0
  28. package/src/command/install.ts +17 -0
  29. package/src/command/pnpmfile/.pnpmfile.cjs +7 -0
  30. package/src/command/pnpmfile/hook.ts +3 -0
  31. package/src/command/setup.ts +13 -0
  32. package/src/constant.ts +2 -0
  33. package/src/error.ts +43 -0
  34. package/src/hook.ts +23 -0
  35. package/src/index.ts +3 -0
  36. package/src/parser-option/find-project-root.ts +22 -0
  37. package/src/parser-option/parse-option.ts +38 -0
  38. package/src/type.ts +17 -0
  39. package/src/util/array-value-map-Helper.ts +19 -0
  40. package/src/util/glob-util.ts +25 -0
  41. package/src/util/logger.ts +24 -0
  42. package/src/util/pipe.ts +43 -0
  43. package/src/util/pnpm-logger.ts +15 -0
@@ -0,0 +1,16 @@
1
+ import { minimatch } from "minimatch";
2
+ function isMatch(target, patterns) {
3
+ let matched = false;
4
+ for (const pattern of patterns){
5
+ matched = minimatch(target, pattern);
6
+ if (matched) return matched;
7
+ }
8
+ return matched;
9
+ }
10
+ function toRegex(patterns) {
11
+ return new RegExp(patterns.map((_)=>minimatch.makeRe(_)).filter((_)=>_ !== false).map((_)=>_.source).join("|"));
12
+ }
13
+ export const globUtil = Object.freeze({
14
+ isMatch,
15
+ toRegex
16
+ });
@@ -0,0 +1,19 @@
1
+ import chalk from "chalk";
2
+ import { APP_NAME } from "../constant.js";
3
+ export function createCheckerMessage(message) {
4
+ return chalk.magenta(APP_NAME + ": ") + message;
5
+ }
6
+ function debug(object) {
7
+ console.info(object);
8
+ }
9
+ function message(value) {
10
+ console.info(createCheckerMessage(value));
11
+ }
12
+ function error(error) {
13
+ console.info(createCheckerMessage(`${chalk.bgRed(" ERROR ")} ${error.message}`));
14
+ }
15
+ export const Logger = Object.freeze({
16
+ debug,
17
+ message,
18
+ error
19
+ });
@@ -0,0 +1,3 @@
1
+ export function pipe(...fns) {
2
+ return (initial)=>fns.reduce((p, f)=>f(p), initial);
3
+ }
@@ -0,0 +1,15 @@
1
+ import { createCheckerMessage } from "./logger.js";
2
+ import { hookLogger } from "@pnpm/core-loggers";
3
+ function message(value) {
4
+ hookLogger.info({
5
+ message: createCheckerMessage(value),
6
+ prefix: ""
7
+ });
8
+ }
9
+ function error(error) {
10
+ hookLogger.error(error);
11
+ }
12
+ export const pnpmLogger = Object.freeze({
13
+ message,
14
+ error
15
+ });
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@pinnacle0/pnpm-single-version",
3
+ "version": "1.0.0",
4
+ "author": "Pinnacle",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/pinnacle0/frontend-libraries.git",
10
+ "directory": "packages/pnpm-single-version"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "src"
15
+ ],
16
+ "bin": {
17
+ "pnpm-single-version": "./dist/command/index.js",
18
+ "psv": "./dist/command/index.js"
19
+ },
20
+ "main": "dist/index.js",
21
+ "types": "dist/index.d.ts",
22
+ "dependencies": {
23
+ "@pnpm/find-workspace-dir": "1000.1.0",
24
+ "@pnpm/lockfile-file": "9.1.3",
25
+ "@pnpm/lockfile-utils": "11.0.4",
26
+ "@pnpm/logger": "1000.0.0",
27
+ "@pnpm/core-loggers": "1000.1.5",
28
+ "chalk": "5.4.1",
29
+ "commander": "10.0.1",
30
+ "find-up": "5.0.0",
31
+ "is-ci": "3.0.1",
32
+ "minimatch": "10.0.1"
33
+ },
34
+ "devDependencies": {
35
+ "@swc/cli": "0.1.62",
36
+ "@swc/core": "1.4.4",
37
+ "@types/is-ci": "^3.0.0",
38
+ "@types/minimatch": "5.1.2",
39
+ "@types/node": "22.10.1",
40
+ "esbuild": "0.18.15",
41
+ "@pinnacle0/devtool-util": "1.3.2"
42
+ },
43
+ "scripts": {
44
+ "build": "pnpm run test && pnpm tsx script/build.ts",
45
+ "test": "vitest --config config/vitest.config.ts --run"
46
+ }
47
+ }
@@ -0,0 +1,58 @@
1
+ import chalk from "chalk";
2
+ import type {LoggerType, PackageInfo} from "../type.js";
3
+
4
+ const Emoji = {
5
+ sad: "😔",
6
+ cross: "❌",
7
+ happy: "🤗",
8
+ };
9
+
10
+ const headerMessage = (num: number) => `${Emoji.cross} Found ${chalk.redBright(num)} Non-single version dependencies\n`;
11
+
12
+ const listVersionMessage = (name: string, infos: PackageInfo[]): string =>
13
+ `
14
+ - ${chalk.blueBright(name)} has ${chalk.redBright(infos.length)} distinct versions
15
+ ${infos.map(_ => _.version + (_.peersSuffix ?? "")).join(", ")}
16
+ `;
17
+
18
+ const hintMessage = `
19
+ Well, here is what you can try to do:
20
+ Run ${chalk.blueBright(`$ pnpm why <dependency> -r `)} on project root to figure out the dependencies that contain conflicted version.
21
+ If the output is too long, try to redirect output, like ${chalk.blueBright(`$ pnpm why <dependency> -r > example.txt`)}
22
+ more about ${chalk.blueBright(`$ pnpm why`)} command, check out ${chalk.greenBright("https://pnpm.io/cli/why")}
23
+ `;
24
+
25
+ export function createErrorMessage(nonSingleVersionDeps: Map<string, PackageInfo[]>): string | null {
26
+ if (nonSingleVersionDeps.size === 0) {
27
+ return null;
28
+ }
29
+ let message = headerMessage(nonSingleVersionDeps.size);
30
+ for (const [name, infos] of nonSingleVersionDeps.entries()) {
31
+ message += listVersionMessage(name, infos);
32
+ }
33
+
34
+ message += hintMessage;
35
+
36
+ return message;
37
+ }
38
+
39
+ export const logInstallationInterruptedMessage = (logger: LoggerType) => {
40
+ logger.message(`${Emoji.sad} ${chalk.red("Installation Process interrupted.")}`);
41
+ };
42
+
43
+ /**
44
+ *
45
+ * @param {string | null} message
46
+ * @returns {boolean} Any Error message logged
47
+ */
48
+ export const logErrorMessage =
49
+ (logger: LoggerType) =>
50
+ (message: string | null): boolean => {
51
+ if (!message) {
52
+ logger.message(`${Emoji.happy} All Passed!!!`);
53
+ return false;
54
+ } else {
55
+ logger.message(message);
56
+ return true;
57
+ }
58
+ };
@@ -0,0 +1,46 @@
1
+ import {nameVerFromPkgSnapshot} from "@pnpm/lockfile-utils";
2
+ import {pipe} from "../util/pipe.js";
3
+ import {ArrayValueMapHelper} from "../util/array-value-map-Helper.js";
4
+ import {LockfilePackagesMissingError} from "../error.js";
5
+ import {globUtil} from "../util/glob-util.js";
6
+ import {createErrorMessage, logErrorMessage} from "./error-message.js";
7
+ import type {CheckerOptions, LoggerType, PackageInfo} from "../type.js";
8
+ import type {Lockfile, PackageSnapshots} from "@pnpm/lockfile-utils";
9
+
10
+ export const filterNonSingleVersionDependencies = (packageInfoMap: Map<string, PackageInfo[]>): Map<string, PackageInfo[]> => {
11
+ const nonSingleVersionPackageInfo = new Map<string, PackageInfo[]>();
12
+
13
+ for (const [path, snapshots] of packageInfoMap.entries()) {
14
+ if (snapshots.length > 1) {
15
+ nonSingleVersionPackageInfo.set(path, snapshots);
16
+ }
17
+ }
18
+
19
+ return nonSingleVersionPackageInfo;
20
+ };
21
+
22
+ const filterSnapshotNeededForChecking =
23
+ (snapshots: PackageSnapshots) =>
24
+ (depsPattern: string[]): Map<string, PackageInfo[]> => {
25
+ const matcher = globUtil.toRegex(depsPattern);
26
+ const packageInfos = ArrayValueMapHelper.create<PackageInfo>();
27
+
28
+ for (const [path, snapshot] of Object.entries(snapshots)) {
29
+ const nameVersionInfo: PackageInfo = nameVerFromPkgSnapshot(path, snapshot);
30
+ if (matcher.test(nameVersionInfo.name)) {
31
+ ArrayValueMapHelper.add(packageInfos, nameVersionInfo.name, nameVersionInfo);
32
+ }
33
+ }
34
+
35
+ return packageInfos;
36
+ };
37
+
38
+ export const checker = (lockfile: Lockfile, options: CheckerOptions, logger: LoggerType) => {
39
+ if (!lockfile.packages) {
40
+ throw new LockfilePackagesMissingError();
41
+ }
42
+
43
+ logger.message("Verify single version dependencies...");
44
+
45
+ return pipe(filterSnapshotNeededForChecking(lockfile.packages), filterNonSingleVersionDependencies, createErrorMessage, logErrorMessage(logger))(options.includes);
46
+ };
@@ -0,0 +1,27 @@
1
+ import {readWantedLockfile} from "@pnpm/lockfile-file";
2
+ import {Logger} from "../util/logger.js";
3
+ import isCI from "is-ci";
4
+ import {checker} from "../checker/index.js";
5
+ import {parseOptions} from "../parser-option/parse-option.js";
6
+ import {findProjectRoot} from "../parser-option/find-project-root.js";
7
+ import chalk from "chalk";
8
+ import {logInstallationInterruptedMessage} from "../checker/error-message.js";
9
+
10
+ export const checkDeps = async () => {
11
+ try {
12
+ const projectRoot = await findProjectRoot();
13
+ const options = await parseOptions(projectRoot);
14
+ const lockfile = await readWantedLockfile(projectRoot, {ignoreIncompatible: false});
15
+ if (!lockfile) {
16
+ Logger.message(`Cannot find ${chalk.blueBright("pnpm-lock.yaml")}, try to run ${chalk.blueBright("$ pnpm install")} first`);
17
+ process.exit(1);
18
+ }
19
+ if (checker(lockfile, options, Logger) && options.failOnCI && isCI) {
20
+ logInstallationInterruptedMessage(Logger);
21
+ process.exit(1);
22
+ }
23
+ } catch (error) {
24
+ error instanceof Error ? Logger.error(error) : console.error("Unexpected error", error);
25
+ process.exit(1);
26
+ }
27
+ };
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import "./setup.js";
@@ -0,0 +1,17 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import {findProjectRoot} from "../parser-option/find-project-root.js";
4
+ import {Logger} from "../util/logger.js";
5
+
6
+ export const install = async () => {
7
+ const root = await findProjectRoot();
8
+ const psvDotFolderPath = path.join(root, ".psv");
9
+ if (fs.existsSync(psvDotFolderPath)) {
10
+ fs.rmSync(psvDotFolderPath, {force: true, recursive: true});
11
+ }
12
+
13
+ fs.mkdirSync(psvDotFolderPath);
14
+ fs.copyFileSync(path.join(import.meta.dirname, "../hook-bundle.js"), path.join(psvDotFolderPath, "hook.js"));
15
+
16
+ Logger.message("installed .psv");
17
+ };
@@ -0,0 +1,7 @@
1
+ const hook = require('./.psv/hook')
2
+
3
+ module.exports = {
4
+ hooks: {
5
+ afterAllResolved: hook
6
+ }
7
+ }
@@ -0,0 +1,3 @@
1
+ import {hook} from "../../hook.js";
2
+
3
+ export default hook;
@@ -0,0 +1,13 @@
1
+ import {Command} from "commander";
2
+ import {checkDeps} from "./checkDeps.js";
3
+ import {install} from "./install.js";
4
+ import packageJSON from "../../package.json" with {type: "json"};
5
+
6
+ const program = new Command();
7
+
8
+ program.name("pnpm-single-version").alias("psv").version(packageJSON.version);
9
+
10
+ program.command("check", {isDefault: true}).description("Verify single version dependencies").action(checkDeps);
11
+ program.command("install").description("Install the checker file into .psv").action(install);
12
+
13
+ program.parse();
@@ -0,0 +1,2 @@
1
+ export const PACKAGE_JSON_OPTIONS_KEY = 'pnpmSingleVersion'
2
+ export const APP_NAME = 'Single Version Checker'
package/src/error.ts ADDED
@@ -0,0 +1,43 @@
1
+ import chalk from "chalk";
2
+ import {PACKAGE_JSON_OPTIONS_KEY} from "./constant.js";
3
+
4
+ export class ProjectRootError extends Error {
5
+ constructor() {
6
+ super("Can not find project root");
7
+ this.name = "ProjectRootError";
8
+ }
9
+ }
10
+
11
+ export class PackageJsonNotFoundError extends Error {
12
+ constructor() {
13
+ super(`Unable to read package.json of root project `);
14
+ this.name = "PackageJsonNotFoundError";
15
+ }
16
+ }
17
+
18
+ export class OptionNotFoundError extends Error {
19
+ constructor() {
20
+ super(`Unable to find option ${chalk.blueBright(`'${PACKAGE_JSON_OPTIONS_KEY}'`)} in package.json of root project `);
21
+ this.name = "OptionsNotFound";
22
+ }
23
+ }
24
+
25
+ export class OptionSyntaxError extends Error {
26
+ constructor(message: string) {
27
+ super(`Invalid option: ${message}`);
28
+ this.name = "OptionSyntaxError";
29
+ }
30
+ }
31
+
32
+ export class LockFileError extends Error {
33
+ constructor() {
34
+ super("Unable to read lock file");
35
+ }
36
+ }
37
+
38
+ export class LockfilePackagesMissingError extends Error {
39
+ constructor() {
40
+ super(`'packages' in lockfile is missing`);
41
+ this.name = "LockfilePackagesMissingError";
42
+ }
43
+ }
package/src/hook.ts ADDED
@@ -0,0 +1,23 @@
1
+ import type {Lockfile} from "@pnpm/lockfile-file";
2
+ import {checker} from "./checker/index.js";
3
+ import {parseOptions} from "./parser-option/parse-option.js";
4
+ import {findProjectRoot} from "./parser-option/find-project-root.js";
5
+ import {pnpmLogger} from "./util/pnpm-logger.js";
6
+ import {logInstallationInterruptedMessage} from "./checker/error-message.js";
7
+ import {logger} from "@pnpm/logger";
8
+
9
+ export const hook = async (lockfile: Lockfile) => {
10
+ try {
11
+ const logger = pnpmLogger;
12
+ const projectRoot = await findProjectRoot();
13
+ const options = await parseOptions(projectRoot);
14
+ if (checker(lockfile, options, logger)) {
15
+ logInstallationInterruptedMessage(logger);
16
+ process.exit(1);
17
+ }
18
+ return lockfile;
19
+ } catch (error) {
20
+ error instanceof Error ? logger.error(error) : console.error("Unexpected error", error);
21
+ process.exit(1);
22
+ }
23
+ };
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ import {hook} from "./hook.js";
2
+
3
+ export const checkSingleVersion = hook;
@@ -0,0 +1,22 @@
1
+ import {findWorkspaceDir} from "@pnpm/find-workspace-dir";
2
+ import {realpath} from "fs/promises";
3
+ import findUp from "find-up";
4
+ import {ProjectRootError} from "../error.js";
5
+ import path from "path";
6
+
7
+ /**
8
+ * Can find the root path of the package and monorepo
9
+ */
10
+ export const findProjectRoot = async (): Promise<string> => {
11
+ let projectRoot = await findWorkspaceDir(process.cwd());
12
+ if (!projectRoot) {
13
+ const packageJSONPath = await findUp("package.json", {cwd: await realpath(process.cwd())});
14
+ projectRoot = packageJSONPath ? path.parse(packageJSONPath).dir : undefined;
15
+ }
16
+
17
+ if (!projectRoot) {
18
+ throw new ProjectRootError();
19
+ }
20
+
21
+ return projectRoot;
22
+ };
@@ -0,0 +1,38 @@
1
+ import fs from "fs/promises";
2
+ import path from "path";
3
+ import {TextDecoder} from "util";
4
+ import {PACKAGE_JSON_OPTIONS_KEY} from "../constant.js";
5
+ import {OptionNotFoundError, OptionSyntaxError} from "../error.js";
6
+ import type {CheckerOptions} from "../type.js";
7
+
8
+ const validateOptions = (options: any): CheckerOptions => {
9
+ if (!options || typeof options !== "object") {
10
+ throw new OptionNotFoundError();
11
+ }
12
+
13
+ const o = options as Partial<CheckerOptions>;
14
+
15
+ if (!Array.isArray(o?.includes)) {
16
+ throw new OptionSyntaxError("Please make sure you have included single version dependencies in option.");
17
+ }
18
+
19
+ if (o?.failOnCI !== undefined && typeof o.failOnCI !== "boolean") {
20
+ throw new OptionSyntaxError("Please use boolean for failedOnCI option");
21
+ }
22
+
23
+ return options as CheckerOptions;
24
+ };
25
+
26
+ export const parseOptions = async (projectRoot: string): Promise<CheckerOptions> => {
27
+ const packageJsonfile = await fs.readFile(path.join(projectRoot, "package.json"));
28
+ // @see https://github.dev/sindresorhus/load-json-file
29
+ const packageJSON = JSON.parse(new TextDecoder().decode(packageJsonfile));
30
+
31
+ const options = validateOptions((packageJSON as any)?.[PACKAGE_JSON_OPTIONS_KEY]);
32
+
33
+ if (options.failOnCI === undefined) {
34
+ options.failOnCI = true;
35
+ }
36
+
37
+ return options;
38
+ };
package/src/type.ts ADDED
@@ -0,0 +1,17 @@
1
+ import type {nameVerFromPkgSnapshot} from "@pnpm/lockfile-utils";
2
+
3
+ export interface CheckerOptions {
4
+ includes: string[];
5
+ /**
6
+ * default: true
7
+ * In CI env, exit with status code 1 when checker found multiple version on specified dependencies.
8
+ */
9
+ failOnCI?: boolean;
10
+ }
11
+
12
+ export interface LoggerType {
13
+ error(error: Error): void;
14
+ message(value: string): void;
15
+ }
16
+
17
+ export type PackageInfo = ReturnType<typeof nameVerFromPkgSnapshot>;
@@ -0,0 +1,19 @@
1
+ type ArrayValueMap<Value, Key = string> = Map<Key, Value[]>
2
+
3
+ function get<Value, Key = string>(map: ArrayValueMap<Value, Key>, key: Key): Value[] {
4
+ return map.get(key) ?? []
5
+ }
6
+
7
+ function add<Value, Key = string>(map: ArrayValueMap<Value, Key>, key: Key, value: Value): void {
8
+ map.set(key, [...get(map, key), value])
9
+ }
10
+
11
+ function create<Value, Key = string>(): Map<Key, Value[]> {
12
+ return new Map()
13
+ }
14
+
15
+ export const ArrayValueMapHelper = Object.freeze({
16
+ add,
17
+ get,
18
+ create
19
+ })
@@ -0,0 +1,25 @@
1
+ import {minimatch} from "minimatch";
2
+
3
+ function isMatch(target: string, patterns: string[]): boolean {
4
+ let matched = false;
5
+ for (const pattern of patterns) {
6
+ matched = minimatch(target, pattern);
7
+ if (matched) return matched;
8
+ }
9
+ return matched;
10
+ }
11
+
12
+ function toRegex(patterns: string[]): RegExp {
13
+ return new RegExp(
14
+ patterns
15
+ .map(_ => minimatch.makeRe(_))
16
+ .filter((_): _ is RegExp => _ !== false)
17
+ .map(_ => _.source)
18
+ .join("|")
19
+ );
20
+ }
21
+
22
+ export const globUtil = Object.freeze({
23
+ isMatch,
24
+ toRegex,
25
+ });
@@ -0,0 +1,24 @@
1
+ import chalk from "chalk";
2
+ import {APP_NAME} from "../constant.js";
3
+
4
+ export function createCheckerMessage(message: string): string {
5
+ return chalk.magenta(APP_NAME + ": ") + message;
6
+ }
7
+
8
+ function debug(object: object) {
9
+ console.info(object);
10
+ }
11
+
12
+ function message(value: string) {
13
+ console.info(createCheckerMessage(value));
14
+ }
15
+
16
+ function error(error: Error) {
17
+ console.info(createCheckerMessage(`${chalk.bgRed(" ERROR ")} ${error.message}`));
18
+ }
19
+
20
+ export const Logger = Object.freeze({
21
+ debug,
22
+ message,
23
+ error,
24
+ });
@@ -0,0 +1,43 @@
1
+ type OperationFunction<P, R> = (value: P) => R
2
+
3
+ export function pipe<P, A>(op1: OperationFunction<P, A>): (initial: P) => A
4
+ export function pipe<P, A, B>(op1: OperationFunction<P, A>, op2: OperationFunction<A, B>): (initial?: P) => B
5
+ export function pipe<P, A, B, C>(
6
+ op1: OperationFunction<P, A>,
7
+ op2: OperationFunction<A, B>,
8
+ op3: OperationFunction<B, C>
9
+ ): (initial?: P) => C
10
+ export function pipe<P, A, B, C, D>(
11
+ op1: OperationFunction<P, A>,
12
+ op2: OperationFunction<A, B>,
13
+ op3: OperationFunction<B, C>,
14
+ op4: OperationFunction<C, D>
15
+ ): (initial?: P) => D
16
+ export function pipe<P, A, B, C, D, E>(
17
+ op1: OperationFunction<P, A>,
18
+ op2: OperationFunction<A, B>,
19
+ op3: OperationFunction<B, C>,
20
+ op4: OperationFunction<C, D>,
21
+ op5: OperationFunction<D, E>
22
+ ): (initial?: P) => E
23
+ export function pipe<P, A, B, C, D, E, F>(
24
+ op1: OperationFunction<P, A>,
25
+ op2: OperationFunction<A, B>,
26
+ op3: OperationFunction<B, C>,
27
+ op4: OperationFunction<C, D>,
28
+ op5: OperationFunction<D, E>,
29
+ op6: OperationFunction<E, F>
30
+ ): (initial?: P) => F
31
+ export function pipe<P, A, B, C, D, E, F, G>(
32
+ op1: OperationFunction<P, A>,
33
+ op2: OperationFunction<A, B>,
34
+ op3: OperationFunction<B, C>,
35
+ op4: OperationFunction<C, D>,
36
+ op5: OperationFunction<D, E>,
37
+ op6: OperationFunction<E, F>,
38
+ op7: OperationFunction<F, G>
39
+ ): (initial?: P) => G
40
+ export function pipe(...ops: Array<OperationFunction<any, any>>): (initial?: any) => any
41
+ export function pipe(...fns: any[]) {
42
+ return (initial: any) => fns.reduce((p, f) => f(p), initial)
43
+ }
@@ -0,0 +1,15 @@
1
+ import {createCheckerMessage} from "./logger.js";
2
+ import {hookLogger} from "@pnpm/core-loggers";
3
+
4
+ function message(value: string) {
5
+ hookLogger.info({message: createCheckerMessage(value), prefix: ""});
6
+ }
7
+
8
+ function error(error: Error) {
9
+ hookLogger.error(error);
10
+ }
11
+
12
+ export const pnpmLogger = Object.freeze({
13
+ message,
14
+ error,
15
+ });