ph-cmd 0.41.5 → 0.43.0-dev.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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=update.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.test.d.ts","sourceRoot":"","sources":["../../../../src/commands/__tests__/update.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,150 @@
1
+ import { Command } from "commander";
2
+ import * as childProcess from "node:child_process";
3
+ import * as fs from "node:fs";
4
+ import path from "node:path";
5
+ import { beforeEach, describe, expect, it, vi } from "vitest";
6
+ import { findContainerDirectory, getPackageManagerFromLockfile, getProjectInfo, } from "../../utils.js";
7
+ import { updateCommand } from "../update.js";
8
+ // Mock dependencies
9
+ vi.mock("node:fs");
10
+ vi.mock("node:child_process");
11
+ // Import installDependency after mocking
12
+ import { installDependency } from "../../utils.js";
13
+ vi.mock("../../utils.js", () => ({
14
+ packageManagers: {
15
+ pnpm: {
16
+ buildAffected: "pnpm run build:affected",
17
+ updateCommand: "pnpm update {{dependency}}",
18
+ installCommand: "pnpm install {{dependency}}",
19
+ workspaceOption: "--workspace-root",
20
+ lockfile: "pnpm-lock.yaml",
21
+ },
22
+ },
23
+ getPackageManagerFromLockfile: vi.fn(),
24
+ getProjectInfo: vi.fn(),
25
+ findContainerDirectory: vi.fn(),
26
+ installDependency: vi.fn(),
27
+ }));
28
+ describe("updateCommand", () => {
29
+ let program;
30
+ beforeEach(() => {
31
+ vi.clearAllMocks();
32
+ vi.restoreAllMocks();
33
+ program = new Command();
34
+ updateCommand(program);
35
+ // Mock utils functions
36
+ vi.mocked(getPackageManagerFromLockfile).mockReturnValue("pnpm");
37
+ vi.mocked(getProjectInfo).mockReturnValue({
38
+ path: "/test/project",
39
+ });
40
+ vi.mocked(findContainerDirectory).mockReturnValue("/user/powerhouse/monorepo");
41
+ // Mock fs.readFileSync for package.json
42
+ vi.mocked(fs.readFileSync).mockImplementation((filePath) => {
43
+ if (filePath === path.join("/test/project", "package.json")) {
44
+ return JSON.stringify({
45
+ dependencies: {
46
+ "@powerhousedao/builder-tools": "link:/user/powerhouse/monorepo/packages/builder-tools",
47
+ },
48
+ });
49
+ }
50
+ throw new Error(`Unexpected file read: ${String(filePath)}`);
51
+ });
52
+ // Mock fs.existsSync to return true for test paths
53
+ vi.spyOn(fs, "existsSync").mockImplementation((p) => {
54
+ const validPaths = [
55
+ "/test/project",
56
+ "/user/powerhouse/monorepo",
57
+ "/test/project/package.json",
58
+ path.join("/test/project", "package.json"),
59
+ path.join("/test/project", "pnpm-lock.yaml"),
60
+ ];
61
+ return validPaths.includes(p);
62
+ });
63
+ // Mock execSync
64
+ vi.mocked(childProcess.execSync).mockReturnValue(Buffer.from(""));
65
+ // Mock installDependency
66
+ vi.mocked(installDependency).mockImplementation(() => { });
67
+ });
68
+ it("should register the update command with correct options", () => {
69
+ const cmd = program.commands.find((c) => c.name() === "update");
70
+ expect(cmd).toBeDefined();
71
+ expect(cmd?.description()).toContain("update your dependencies");
72
+ // Get options from the command definition, not from parsed args
73
+ const options = cmd?.options.map((opt) => opt.attributeName());
74
+ expect(options).toContain("force");
75
+ expect(options).toContain("packageManager");
76
+ expect(options).toContain("debug");
77
+ });
78
+ it("should execute update command with local dependencies", async () => {
79
+ const cmd = program.commands.find((c) => c.name() === "update");
80
+ await cmd?.parseAsync(["node", "test"]);
81
+ expect(childProcess.execSync).toHaveBeenCalledWith("pnpm run build:affected", expect.objectContaining({
82
+ stdio: "inherit",
83
+ cwd: "/user/powerhouse/monorepo",
84
+ }));
85
+ });
86
+ it("should execute update command with force flag", async () => {
87
+ // Mock fs.readFileSync for the specific package.json read in this test
88
+ vi.mocked(fs.readFileSync).mockImplementation((filePath) => {
89
+ if (filePath === path.join("/test/project", "package.json")) {
90
+ return JSON.stringify({
91
+ dependencies: {},
92
+ devDependencies: {},
93
+ });
94
+ }
95
+ throw new Error(`Unexpected file read: ${String(filePath)}`);
96
+ });
97
+ // Mock fs.existsSync to return true for test paths
98
+ vi.spyOn(fs, "existsSync").mockImplementation((p) => {
99
+ const validPaths = [
100
+ "/test/project",
101
+ "/user/powerhouse/monorepo",
102
+ "/test/project/package.json",
103
+ path.join("/test/project", "package.json"),
104
+ path.join("/test/project", "pnpm-lock.yaml"),
105
+ ];
106
+ return validPaths.includes(p);
107
+ });
108
+ const cmd = program.commands.find((c) => c.name() === "update");
109
+ await cmd?.parseAsync(["node", "test", "--force", "prod"]);
110
+ // When using --force, it should call installDependency with the latest versions
111
+ expect(installDependency).toHaveBeenCalledWith("pnpm", [
112
+ "@powerhousedao/common@latest",
113
+ "@powerhousedao/design-system@latest",
114
+ "@powerhousedao/reactor-browser@latest",
115
+ "@powerhousedao/builder-tools@latest",
116
+ "@powerhousedao/codegen@latest",
117
+ "@powerhousedao/reactor-api@latest",
118
+ "@powerhousedao/reactor-local@latest",
119
+ "@powerhousedao/scalars@latest",
120
+ "@powerhousedao/ph-cli@latest",
121
+ ], "/test/project");
122
+ });
123
+ it("should handle debug flag", async () => {
124
+ const consoleSpy = vi.spyOn(console, "log");
125
+ const cmd = program.commands.find((c) => c.name() === "update");
126
+ await cmd?.parseAsync(["node", "test", "--debug"]);
127
+ expect(consoleSpy).toHaveBeenCalledWith(">>> options", expect.any(Object));
128
+ });
129
+ it("should execute update command without local dependencies", async () => {
130
+ // Mock fs.readFileSync to return package.json without local dependencies
131
+ vi.mocked(fs.readFileSync).mockImplementation((filePath) => {
132
+ if (filePath === path.join("/test/project", "package.json")) {
133
+ return JSON.stringify({
134
+ dependencies: {
135
+ "@powerhousedao/builder-tools": "^0.40.0",
136
+ "@powerhousedao/common": "^0.40.0",
137
+ },
138
+ });
139
+ }
140
+ throw new Error(`Unexpected file read: ${String(filePath)}`);
141
+ });
142
+ const cmd = program.commands.find((c) => c.name() === "update");
143
+ await cmd?.parseAsync(["node", "test"]);
144
+ // Should call execSync with pnpm update for all dependencies
145
+ expect(childProcess.execSync).toHaveBeenCalledWith("pnpm update @powerhousedao/common @powerhousedao/design-system @powerhousedao/reactor-browser @powerhousedao/builder-tools @powerhousedao/codegen @powerhousedao/reactor-api @powerhousedao/reactor-local @powerhousedao/scalars @powerhousedao/ph-cli", expect.objectContaining({
146
+ stdio: "inherit",
147
+ cwd: "/test/project",
148
+ }));
149
+ });
150
+ });
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=use.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use.test.d.ts","sourceRoot":"","sources":["../../../../src/commands/__tests__/use.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,128 @@
1
+ import { Command } from "commander";
2
+ import * as fs from "node:fs";
3
+ import path from "node:path";
4
+ import { beforeEach, describe, expect, it, vi } from "vitest";
5
+ import { getPackageManagerFromLockfile, getProjectInfo, } from "../../utils.js";
6
+ import { useCommand } from "../use.js";
7
+ // Mock dependencies
8
+ vi.mock("node:fs");
9
+ // Import installDependency after mocking
10
+ import { installDependency } from "../../utils.js";
11
+ vi.mock("../../utils.js", () => ({
12
+ packageManagers: {
13
+ pnpm: {
14
+ buildAffected: "pnpm run build:affected",
15
+ updateCommand: "pnpm update {{dependency}}",
16
+ installCommand: "pnpm install {{dependency}}",
17
+ workspaceOption: "--workspace-root",
18
+ lockfile: "pnpm-lock.yaml",
19
+ },
20
+ },
21
+ getPackageManagerFromLockfile: vi.fn(),
22
+ getProjectInfo: vi.fn(),
23
+ installDependency: vi.fn(),
24
+ }));
25
+ describe("useCommand", () => {
26
+ let program;
27
+ beforeEach(() => {
28
+ vi.clearAllMocks();
29
+ vi.restoreAllMocks();
30
+ program = new Command();
31
+ useCommand(program);
32
+ // Mock utils functions
33
+ vi.mocked(getPackageManagerFromLockfile).mockReturnValue("pnpm");
34
+ vi.mocked(getProjectInfo).mockReturnValue({
35
+ path: "/test/project",
36
+ });
37
+ // Mock fs.existsSync to return true for test paths
38
+ vi.spyOn(fs, "existsSync").mockImplementation((p) => {
39
+ const validPaths = [
40
+ "/test/project",
41
+ "/test/project/package.json",
42
+ path.join("/test/project", "package.json"),
43
+ path.join("/test/project", "pnpm-lock.yaml"),
44
+ ];
45
+ return validPaths.includes(p);
46
+ });
47
+ // Mock installDependency
48
+ vi.mocked(installDependency).mockImplementation(() => { });
49
+ });
50
+ it("should register the use command with correct options", () => {
51
+ const cmd = program.commands.find((c) => c.name() === "use");
52
+ expect(cmd).toBeDefined();
53
+ expect(cmd?.description()).toContain("change your environment");
54
+ const options = cmd?.options.map((opt) => opt.attributeName());
55
+ expect(options).toContain("dev");
56
+ expect(options).toContain("prod");
57
+ expect(options).toContain("latest");
58
+ expect(options).toContain("local");
59
+ expect(options).toContain("packageManager");
60
+ expect(options).toContain("debug");
61
+ });
62
+ it("should execute use command with dev environment", async () => {
63
+ const cmd = program.commands.find((c) => c.name() === "use");
64
+ await cmd?.parseAsync(["node", "test", "--dev"]);
65
+ expect(installDependency).toHaveBeenCalledWith("pnpm", [
66
+ "@powerhousedao/common@dev",
67
+ "@powerhousedao/design-system@dev",
68
+ "@powerhousedao/reactor-browser@dev",
69
+ "@powerhousedao/builder-tools@dev",
70
+ "@powerhousedao/codegen@dev",
71
+ "@powerhousedao/reactor-api@dev",
72
+ "@powerhousedao/reactor-local@dev",
73
+ "@powerhousedao/scalars@dev",
74
+ "@powerhousedao/ph-cli@dev",
75
+ ], "/test/project");
76
+ });
77
+ it("should execute use command with prod environment", async () => {
78
+ const cmd = program.commands.find((c) => c.name() === "use");
79
+ await cmd?.parseAsync(["node", "test", "--prod"]);
80
+ expect(installDependency).toHaveBeenCalledWith("pnpm", [
81
+ "@powerhousedao/common@latest",
82
+ "@powerhousedao/design-system@latest",
83
+ "@powerhousedao/reactor-browser@latest",
84
+ "@powerhousedao/builder-tools@latest",
85
+ "@powerhousedao/codegen@latest",
86
+ "@powerhousedao/reactor-api@latest",
87
+ "@powerhousedao/reactor-local@latest",
88
+ "@powerhousedao/scalars@latest",
89
+ "@powerhousedao/ph-cli@latest",
90
+ ], "/test/project");
91
+ });
92
+ it("should execute use command with local environment", async () => {
93
+ const cmd = program.commands.find((c) => c.name() === "use");
94
+ await cmd?.parseAsync(["node", "test", "--local", "/path/to/local"]);
95
+ expect(installDependency).toHaveBeenCalledWith("pnpm", [
96
+ "/path/to/local/packages/common",
97
+ "/path/to/local/packages/design-system",
98
+ "/path/to/local/packages/reactor-browser",
99
+ "/path/to/local/packages/builder-tools",
100
+ "/path/to/local/packages/codegen",
101
+ "/path/to/local/packages/reactor-api",
102
+ "/path/to/local/packages/reactor-local",
103
+ "/path/to/local/packages/scalars",
104
+ "/path/to/local/clis/ph-cli",
105
+ ], "/test/project");
106
+ });
107
+ it("should handle debug flag", async () => {
108
+ const consoleSpy = vi.spyOn(console, "log");
109
+ const cmd = program.commands.find((c) => c.name() === "use");
110
+ await cmd?.parseAsync(["node", "test", "--dev", "--debug"]);
111
+ expect(consoleSpy).toHaveBeenCalledWith(">>> options", expect.any(Object));
112
+ });
113
+ it("should throw error when no environment is specified", async () => {
114
+ const cmd = program.commands.find((c) => c.name() === "use");
115
+ await expect(cmd?.parseAsync(["node", "test"])).rejects.toThrow("❌ Please specify an environment");
116
+ });
117
+ it("should use specified package manager", async () => {
118
+ const cmd = program.commands.find((c) => c.name() === "use");
119
+ await cmd?.parseAsync([
120
+ "node",
121
+ "test",
122
+ "--dev",
123
+ "--package-manager",
124
+ "npm",
125
+ ]);
126
+ expect(installDependency).toHaveBeenCalledWith("npm", expect.any(Array), "/test/project");
127
+ });
128
+ });
@@ -2,6 +2,8 @@ import { type Command } from "commander";
2
2
  import { setupGlobalsCommand } from "./setup-globals.js";
3
3
  export declare const commands: (typeof setupGlobalsCommand)[];
4
4
  export default function registerCommands(program: Command): void;
5
- export * from "./setup-globals.js";
6
5
  export * from "./init.js";
6
+ export * from "./setup-globals.js";
7
+ export * from "./update.js";
8
+ export * from "./use.js";
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGzD,eAAO,MAAM,QAAQ,gCAAqC,CAAC;AAE3D,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,OAAO,EAAE,OAAO,QAExD;AAED,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAIzD,eAAO,MAAM,QAAQ,gCAKpB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,OAAO,EAAE,OAAO,QAExD;AAED,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC"}
@@ -1,8 +1,17 @@
1
- import { setupGlobalsCommand } from "./setup-globals.js";
2
1
  import { initCommand } from "./init.js";
3
- export const commands = [setupGlobalsCommand, initCommand];
2
+ import { setupGlobalsCommand } from "./setup-globals.js";
3
+ import { updateCommand } from "./update.js";
4
+ import { useCommand } from "./use.js";
5
+ export const commands = [
6
+ setupGlobalsCommand,
7
+ initCommand,
8
+ useCommand,
9
+ updateCommand,
10
+ ];
4
11
  export default function registerCommands(program) {
5
12
  commands.forEach((command) => command(program));
6
13
  }
7
- export * from "./setup-globals.js";
8
14
  export * from "./init.js";
15
+ export * from "./setup-globals.js";
16
+ export * from "./update.js";
17
+ export * from "./use.js";
@@ -0,0 +1,11 @@
1
+ import { type Command } from "commander";
2
+ import { type CommandActionType } from "../types.js";
3
+ export declare const update: CommandActionType<[
4
+ {
5
+ force?: string;
6
+ debug?: boolean;
7
+ packageManager?: string;
8
+ }
9
+ ]>;
10
+ export declare function updateCommand(program: Command): void;
11
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAqErD,eAAO,MAAM,MAAM,EAAE,iBAAiB,CACpC;IACE;QACE,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB;CACF,CAmDF,CAAC;AAEF,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,QA4B7C"}
@@ -0,0 +1,88 @@
1
+ import { execSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { findContainerDirectory, getPackageManagerFromLockfile, getProjectInfo, packageManagers, } from "../utils.js";
5
+ import { ENV_MAP, PH_PROJECT_DEPENDENCIES, updatePackageJson, } from "./use.js";
6
+ const FILE_PROTOCOL = "file:";
7
+ const LINK_PROTOCOL = "link:";
8
+ const MONOREPO_FILE = "pnpm-workspace.yaml";
9
+ const buildLocalDependencies = (localDependencyPath, pkgManagerName) => {
10
+ const monorepoPath = findContainerDirectory(localDependencyPath, MONOREPO_FILE);
11
+ if (!monorepoPath) {
12
+ throw new Error("Monorepo root directory not found");
13
+ }
14
+ const pkgManager = packageManagers[pkgManagerName];
15
+ console.log("⚙️ Building local dependencies...");
16
+ execSync(pkgManager.buildAffected, {
17
+ stdio: "inherit",
18
+ cwd: monorepoPath,
19
+ });
20
+ };
21
+ const getLocalDependencyPath = (projectPath) => {
22
+ // read package json from projectInfo.path
23
+ const packageJson = JSON.parse(fs.readFileSync(path.join(projectPath, "package.json"), "utf-8"));
24
+ // filter dependencies
25
+ const filteredDependencies = Object.entries({
26
+ ...packageJson.dependencies,
27
+ ...packageJson.devDependencies,
28
+ }).filter(([name]) => PH_PROJECT_DEPENDENCIES.includes(name));
29
+ const [_, localDependencyPath] = filteredDependencies.find(([_, version]) => version.startsWith(FILE_PROTOCOL) || version.startsWith(LINK_PROTOCOL)) || [null, null];
30
+ if (!localDependencyPath)
31
+ return null;
32
+ return localDependencyPath
33
+ .replace(FILE_PROTOCOL, "")
34
+ .replace(LINK_PROTOCOL, "");
35
+ };
36
+ export const update = (options) => {
37
+ const { force, packageManager, debug } = options;
38
+ if (debug) {
39
+ console.log(">>> options", options);
40
+ }
41
+ const projectInfo = getProjectInfo();
42
+ const pkgManagerName = (packageManager ||
43
+ getPackageManagerFromLockfile(projectInfo.path));
44
+ const localDependencyPath = getLocalDependencyPath(projectInfo.path);
45
+ if (debug) {
46
+ console.log(">>> projectInfo", projectInfo);
47
+ console.log(">>> pkgManagerName", pkgManagerName);
48
+ console.log(">>> localDependencyPath", localDependencyPath);
49
+ }
50
+ if (localDependencyPath) {
51
+ buildLocalDependencies(localDependencyPath, pkgManagerName);
52
+ }
53
+ if (force) {
54
+ const supportedEnvs = Object.keys(ENV_MAP);
55
+ if (!supportedEnvs.includes(force)) {
56
+ throw new Error(`Invalid environment: ${force}, supported envs: ${supportedEnvs.join(", ")}`);
57
+ }
58
+ const env = force;
59
+ updatePackageJson(env, undefined, pkgManagerName, debug);
60
+ return;
61
+ }
62
+ const pkgManager = packageManagers[pkgManagerName];
63
+ const deps = PH_PROJECT_DEPENDENCIES.join(" ");
64
+ const updateCommand = pkgManager.updateCommand.replace("{{dependency}}", deps);
65
+ const commandOptions = { cwd: projectInfo.path };
66
+ execSync(updateCommand, {
67
+ stdio: "inherit",
68
+ ...commandOptions,
69
+ });
70
+ };
71
+ export function updateCommand(program) {
72
+ program
73
+ .command("update")
74
+ .description("Allows you to update your dependencies to the latest version based on the specified range in package.json. If you want to update to the latest available version, use the --force flag.")
75
+ .option("--force <env>", "Force update to latest available version for the environment specified (dev, prod, latest)")
76
+ .option("--package-manager <packageManager>", "force package manager to use")
77
+ .option("--debug", "Show additional logs")
78
+ .addHelpText("after", `
79
+ Examples:
80
+ $ ph update # Update dependencies based on package.json ranges
81
+ $ ph update --force dev # Force update to latest dev version available
82
+ $ ph update --force prod # Force update to latest stable version available (same as latest)
83
+ $ ph update --force latest # Force update to latest stable version available (same as prod)
84
+ $ ph update --package-manager pnpm # Specify package manager to use
85
+ $ ph update --debug # Show debug information during update
86
+ `)
87
+ .action(update);
88
+ }
@@ -0,0 +1,27 @@
1
+ import { type Command } from "commander";
2
+ import { type CommandActionType } from "../types.js";
3
+ import { type PackageManager } from "../utils.js";
4
+ export declare const ORG = "@powerhousedao";
5
+ export declare const CLIS: string[];
6
+ export declare const PACKAGES: string[];
7
+ export declare const PH_PROJECT_DEPENDENCIES: string[];
8
+ export declare const PH_PROJECT_LOCAL_DEPENDENCIES: string[];
9
+ export declare const ENV_MAP: {
10
+ dev: string;
11
+ prod: string;
12
+ latest: string;
13
+ };
14
+ export type Environment = keyof typeof ENV_MAP;
15
+ export declare const updatePackageJson: (env: Environment, localPath?: string, packageManager?: PackageManager, debug?: boolean) => void;
16
+ export declare const use: CommandActionType<[
17
+ {
18
+ dev?: boolean;
19
+ prod?: boolean;
20
+ local?: string;
21
+ debug?: boolean;
22
+ latest?: boolean;
23
+ packageManager?: string;
24
+ }
25
+ ]>;
26
+ export declare function useCommand(program: Command): void;
27
+ //# sourceMappingURL=use.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use.d.ts","sourceRoot":"","sources":["../../../src/commands/use.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,GAAG,mBAAmB,CAAC;AACpC,eAAO,MAAM,IAAI,UAAa,CAAC;AAC/B,eAAO,MAAM,QAAQ,UASpB,CAAC;AAEF,eAAO,MAAM,uBAAuB,UAGnC,CAAC;AAEF,eAAO,MAAM,6BAA6B,UAGzC,CAAC;AAEF,eAAO,MAAM,OAAO;;;;CAInB,CAAC;AAGF,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,OAAO,CAAC;AAE/C,eAAO,MAAM,iBAAiB,GAC5B,KAAK,WAAW,EAChB,YAAY,MAAM,EAClB,iBAAiB,cAAc,EAC/B,QAAQ,OAAO,SAuChB,CAAC;AAEF,eAAO,MAAM,GAAG,EAAE,iBAAiB,CACjC;IACE;QACE,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB;CACF,CAwBF,CAAC;AAEF,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,QAmB1C"}
@@ -0,0 +1,81 @@
1
+ import path from "node:path";
2
+ import { getPackageManagerFromLockfile, getProjectInfo, installDependency, } from "../utils.js";
3
+ export const ORG = "@powerhousedao";
4
+ export const CLIS = ["ph-cli"];
5
+ export const PACKAGES = [
6
+ "common",
7
+ "design-system",
8
+ "reactor-browser",
9
+ "builder-tools",
10
+ "codegen",
11
+ "reactor-api",
12
+ "reactor-local",
13
+ "scalars",
14
+ ];
15
+ export const PH_PROJECT_DEPENDENCIES = [
16
+ ...PACKAGES.map((dependency) => `${ORG}/${dependency}`),
17
+ ...CLIS.map((dependency) => `${ORG}/${dependency}`),
18
+ ];
19
+ export const PH_PROJECT_LOCAL_DEPENDENCIES = [
20
+ ...PACKAGES.map((dependency) => path.join("packages", dependency)),
21
+ ...CLIS.map((dependency) => path.join("clis", dependency)),
22
+ ];
23
+ export const ENV_MAP = {
24
+ dev: "dev",
25
+ prod: "latest",
26
+ latest: "latest",
27
+ };
28
+ export const updatePackageJson = (env, localPath, packageManager, debug) => {
29
+ const dependencies = [];
30
+ const projectInfo = getProjectInfo();
31
+ const pkgManager = packageManager || getPackageManagerFromLockfile(projectInfo.path);
32
+ if (debug) {
33
+ console.log(">>> projectInfo", projectInfo);
34
+ console.log(">>> pkgManager", pkgManager);
35
+ }
36
+ if (localPath) {
37
+ const localPathDependencies = PH_PROJECT_LOCAL_DEPENDENCIES.map((dependency) => path.join(localPath, dependency));
38
+ dependencies.push(...localPathDependencies);
39
+ }
40
+ else {
41
+ dependencies.push(...PH_PROJECT_DEPENDENCIES.map((dependency) => `${dependency}@${ENV_MAP[env]}`));
42
+ }
43
+ if (debug) {
44
+ console.log(">>> dependencies", dependencies);
45
+ }
46
+ try {
47
+ console.log("⚙️ Updating dependencies...");
48
+ installDependency(pkgManager, dependencies, projectInfo.path);
49
+ console.log("✅ Dependencies updated successfully");
50
+ }
51
+ catch (error) {
52
+ console.error("❌ Failed to update dependencies");
53
+ throw error;
54
+ }
55
+ };
56
+ export const use = (options) => {
57
+ const { dev, prod, latest, local, packageManager, debug } = options;
58
+ const develop = dev ? "dev" : null;
59
+ const production = prod ? "prod" : null;
60
+ const latestEnv = latest ? "latest" : null;
61
+ const env = develop || production || latestEnv;
62
+ if (debug) {
63
+ console.log(">>> options", options);
64
+ }
65
+ if (!env && !local) {
66
+ throw new Error("❌ Please specify an environment");
67
+ }
68
+ updatePackageJson(env || "dev", local, packageManager, debug);
69
+ };
70
+ export function useCommand(program) {
71
+ program
72
+ .command("use")
73
+ .description("Allows you to change your environment (latest, development, production, local)")
74
+ .option("-d, --dev", "Use development environment")
75
+ .option("-p, --prod", "Use production environment")
76
+ .option("--latest", "Use latest environment")
77
+ .option("-l, --local <localPath>", "Use local environment (you have to specify the path to the local environment)")
78
+ .option("--package-manager <packageManager>", "force package manager to use")
79
+ .option("--debug", "Show additional logs")
80
+ .action(use);
81
+ }
@@ -7,27 +7,43 @@ export declare const PH_GLOBAL_PROJECT_NAME = ".ph";
7
7
  export declare const POWERHOUSE_GLOBAL_DIR: string;
8
8
  export declare const packageManagers: {
9
9
  readonly bun: {
10
+ readonly installCommand: "bun add {{dependency}}";
10
11
  readonly execCommand: "bun ph-cli {{arguments}}";
11
12
  readonly execScript: "bun {{arguments}}";
12
13
  readonly lockfile: "bun.lock";
13
14
  readonly globalPathRegexp: RegExp;
15
+ readonly updateCommand: "bun update {{dependency}}";
16
+ readonly buildAffected: "bun run build:affected";
17
+ readonly workspaceOption: "";
14
18
  };
15
19
  readonly pnpm: {
20
+ readonly installCommand: "pnpm add {{dependency}}";
16
21
  readonly execCommand: "pnpm exec ph-cli {{arguments}}";
17
22
  readonly execScript: "pnpm {{arguments}}";
18
23
  readonly lockfile: "pnpm-lock.yaml";
19
24
  readonly globalPathRegexp: RegExp;
25
+ readonly updateCommand: "pnpm update {{dependency}}";
26
+ readonly buildAffected: "pnpm run build:affected";
27
+ readonly workspaceOption: "--workspace-root";
20
28
  };
21
29
  readonly yarn: {
30
+ readonly installCommand: "yarn add {{dependency}}";
22
31
  readonly execCommand: "yarn ph-cli {{arguments}}";
23
32
  readonly execScript: "yarn {{arguments}}";
24
33
  readonly lockfile: "yarn.lock";
25
34
  readonly globalPathRegexp: RegExp;
35
+ readonly updateCommand: "yarn upgrade {{dependency}}";
36
+ readonly buildAffected: "yarn run build:affected";
37
+ readonly workspaceOption: "-W";
26
38
  };
27
39
  readonly npm: {
40
+ readonly installCommand: "npm install {{dependency}}";
28
41
  readonly execCommand: "npx ph-cli {{arguments}}";
29
42
  readonly execScript: "npm run {{arguments}}";
30
43
  readonly lockfile: "package-lock.json";
44
+ readonly updateCommand: "npm update {{dependency}} --save";
45
+ readonly buildAffected: "npm run build:affected";
46
+ readonly workspaceOption: "";
31
47
  };
32
48
  };
33
49
  export type ProjectInfo = {
@@ -43,5 +59,23 @@ export declare function getPackageManagerFromPath(dir: string): PackageManager;
43
59
  export declare function getPackageManagerFromLockfile(dir: string): PackageManager;
44
60
  export declare function getProjectInfo(debug?: boolean): ProjectInfo;
45
61
  export declare function forwardPHCommand(packageManager: PackageManager, projectPath: string, args: string, debug?: boolean): void;
62
+ /**
63
+ * Recursively searches for a specific file by traversing up the directory tree.
64
+ * Starting from the given path, it checks each parent directory until it finds
65
+ * the target file or reaches the root directory.
66
+ *
67
+ * @param startPath - The absolute path of the directory to start searching from
68
+ * @param targetFile - The name of the file to search for (e.g., 'package.json', 'pnpm-workspace.yaml')
69
+ * @returns The absolute path of the directory containing the target file, or null if not found
70
+ *
71
+ * @example
72
+ * // Find the workspace root directory
73
+ * const workspaceRoot = findContainerDirectory('/path/to/project/src', 'pnpm-workspace.yaml');
74
+ *
75
+ * // Find the nearest package.json
76
+ * const packageDir = findContainerDirectory('/path/to/project/src/components', 'package.json');
77
+ */
78
+ export declare const findContainerDirectory: (startPath: string, targetFile: string) => string | null;
79
+ export declare function installDependency(packageManager: PackageManager, dependencies: string[], projectPath: string, workspace?: boolean): void;
46
80
  export {};
47
81
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,WAAW,QAAkB,CAAC;AAC3C,eAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,eAAO,MAAM,eAAe,UAiB3B,CAAC;AACF,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,QAAQ,QAAY,CAAC;AAClC,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAC5C,eAAO,MAAM,qBAAqB,QAGjC,CAAC;AAEF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;CAwBlB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAE7D,KAAK,cAAc,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;AAE/C,wBAAgB,qBAAqB,YAEpC;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,WAI9C;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,cAAc,GAAE,cAAsC,iBAevD;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAYrE;AAED,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAUzE;AAED,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,WAAW,CAoB3D;AAED,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,cAAc,EAC9B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,OAAO,QAmBhB"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,WAAW,QAAkB,CAAC;AAC3C,eAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,eAAO,MAAM,eAAe,UAiB3B,CAAC;AACF,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAC/D,eAAO,MAAM,QAAQ,QAAY,CAAC;AAClC,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAC5C,eAAO,MAAM,qBAAqB,QAGjC,CAAC;AAEF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwClB,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAE7D,KAAK,cAAc,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;AAE/C,wBAAgB,qBAAqB,YAEpC;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,WAI9C;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,cAAc,GAAE,cAAsC,iBAevD;AAED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAYrE;AAED,wBAAgB,6BAA6B,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAUzE;AAED,wBAAgB,cAAc,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,WAAW,CAoB3D;AAED,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,cAAc,EAC9B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,OAAO,QAmBhB;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sBAAsB,GACjC,WAAW,MAAM,EACjB,YAAY,MAAM,KACjB,MAAM,GAAG,IAeX,CAAC;AAEF,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,cAAc,EAC9B,YAAY,EAAE,MAAM,EAAE,EACtB,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,OAAO,QAuBpB"}