@vlandoss/clibuddy 0.0.2-git-1383198.0 → 0.0.2-git-8d13199.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.
package/dist/index.cjs CHANGED
@@ -45,7 +45,7 @@ module.exports = __toCommonJS(index_exports);
45
45
  // src/colors.ts
46
46
  var import_chalk = __toESM(require("chalk"), 1);
47
47
  var import_supports_color = __toESM(require("supports-color"), 1);
48
- var colorIsSupported = () => import_supports_color.default.stdout && !Bun.env.NO_COLOR;
48
+ var colorIsSupported = () => import_supports_color.default.stdout && !process.env.NO_COLOR;
49
49
  var identity = (x) => x;
50
50
  var safe = (style) => colorIsSupported() ? style : identity;
51
51
  var colors = {
@@ -57,6 +57,8 @@ var colors = {
57
57
  // src/services/pkg.ts
58
58
  var import_node_fs = __toESM(require("fs"), 1);
59
59
  var import_node_path = __toESM(require("path"), 1);
60
+ var import_workspace = require("@pnpm/workspace.find-packages");
61
+ var import_workspace2 = require("@pnpm/workspace.read-manifest");
60
62
  var import_read_package_up = require("read-package-up");
61
63
  var PkgService = class {
62
64
  #packageJson;
@@ -71,18 +73,47 @@ var PkgService = class {
71
73
  this.#packageJson = packageJson;
72
74
  this.#dirPath = import_node_path.default.dirname(pkgPath);
73
75
  }
74
- hasFile(name) {
75
- return import_node_fs.default.existsSync(this.#fromApp(name));
76
- }
77
- #fromApp(...args) {
78
- return import_node_path.default.join(this.#dirPath, ...args);
79
- }
80
76
  info() {
81
77
  return {
82
78
  packageJson: this.#packageJson,
83
79
  dirPath: this.#dirPath
84
80
  };
85
81
  }
82
+ hasFile(name, dir) {
83
+ const filepath = dir ? import_node_path.default.join(dir, name) : this.#fromApp(name);
84
+ return import_node_fs.default.existsSync(filepath);
85
+ }
86
+ isMonorepo() {
87
+ return this.#packageJson.workspaces !== void 0 || this.#hasPnpmWorkspace();
88
+ }
89
+ async getWorkspaceProjects() {
90
+ let patterns;
91
+ if (this.#hasPnpmWorkspace()) {
92
+ const manifest = await (0, import_workspace2.readWorkspaceManifest)(this.#dirPath);
93
+ if (!manifest) {
94
+ throw new Error("Can't read pnpm workspace manifest");
95
+ }
96
+ patterns = manifest.packages;
97
+ } else {
98
+ patterns = Array.isArray(this.#packageJson.workspaces) ? this.#packageJson.workspaces : this.#packageJson.workspaces?.packages ?? [];
99
+ }
100
+ if (!Array.isArray(patterns) || patterns.some((p) => typeof p !== "string")) {
101
+ throw new Error("Invalid workspace patterns");
102
+ }
103
+ const projects = await (0, import_workspace.findWorkspacePackages)(this.#dirPath, {
104
+ patterns
105
+ });
106
+ const excludeRoot = (projects2) => {
107
+ return projects2.filter((project) => project.rootDir !== this.#dirPath);
108
+ };
109
+ return excludeRoot(projects);
110
+ }
111
+ #hasPnpmWorkspace() {
112
+ return this.hasFile("pnpm-workspace.yaml");
113
+ }
114
+ #fromApp(...args) {
115
+ return import_node_path.default.join(this.#dirPath, ...args);
116
+ }
86
117
  };
87
118
  async function createPkgService(cwd2) {
88
119
  const searchResult = await (0, import_read_package_up.readPackageUp)({ cwd: cwd2 });
@@ -95,16 +126,34 @@ async function createPkgService(cwd2) {
95
126
 
96
127
  // src/services/shell/shell.ts
97
128
  var import_zx = require("zx");
98
- var ShellService = class {
129
+ var ShellService = class _ShellService {
99
130
  #shell;
131
+ #options;
100
132
  constructor(options) {
101
- this.#shell = Object.assign((0, import_zx.$)(options), {
102
- quiet: (0, import_zx.$)({ ...options, verbose: false })
103
- });
133
+ this.#options = options;
134
+ this.#shell = (0, import_zx.$)(options);
104
135
  }
105
136
  get $() {
106
137
  return this.#shell;
107
138
  }
139
+ quiet(options) {
140
+ return this.child({
141
+ ...options,
142
+ verbose: false
143
+ });
144
+ }
145
+ at(cwd2, options) {
146
+ return this.child({
147
+ ...options,
148
+ cwd: cwd2
149
+ });
150
+ }
151
+ child(options) {
152
+ return new _ShellService({
153
+ ...this.#options,
154
+ ...options
155
+ });
156
+ }
108
157
  };
109
158
 
110
159
  // src/services/shell/create.ts
@@ -141,7 +190,7 @@ function createShellService(options = {}) {
141
190
 
142
191
  // src/version.ts
143
192
  function getVersion(pkg) {
144
- return Bun.env.VERSION || pkg.packageJson.version;
193
+ return process.env.VERSION || pkg.packageJson.version;
145
194
  }
146
195
  // Annotate the CommonJS export names for ESM import in node:
147
196
  0 && (module.exports = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/colors.ts","../src/services/pkg.ts","../src/services/shell/shell.ts","../src/services/shell/create.ts","../src/version.ts"],"sourcesContent":["export * from \"./colors\";\nexport * from \"./services\";\nexport * from \"./version\";\n","import chalk, { type ChalkInstance } from \"chalk\";\nimport supportsColor from \"supports-color\";\n\n// https://no-color.org/\nconst colorIsSupported = () => supportsColor.stdout && !Bun.env.NO_COLOR;\n\nconst identity = <T>(x: T) => x;\nconst safe = (style: ChalkInstance) => (colorIsSupported() ? style : identity);\n\nexport const colors = {\n blueBright: safe(chalk.blueBright),\n redBright: safe(chalk.redBright),\n greenBright: safe(chalk.greenBright),\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { type NormalizedPackageJson, readPackageUp } from \"read-package-up\";\n\nexport class PkgService {\n #packageJson: NormalizedPackageJson;\n #dirPath: string;\n\n get dirPath() {\n return this.#dirPath;\n }\n\n get packageJson() {\n return this.#packageJson;\n }\n\n constructor(packageJson: NormalizedPackageJson, pkgPath: string) {\n this.#packageJson = packageJson;\n this.#dirPath = path.dirname(pkgPath);\n }\n\n hasFile(name: string) {\n return fs.existsSync(this.#fromApp(name));\n }\n\n #fromApp(...args: string[]) {\n return path.join(this.#dirPath, ...args);\n }\n\n info() {\n return {\n packageJson: this.#packageJson,\n dirPath: this.#dirPath,\n };\n }\n}\n\nexport async function createPkgService(cwd: string): Promise<PkgService | null> {\n const searchResult = await readPackageUp({ cwd });\n\n if (!searchResult) {\n return null;\n }\n\n const { packageJson, path } = searchResult;\n\n return new PkgService(packageJson, path);\n}\n","import { type Options as ZxOptions, type Shell as ZxShell, $ as make$ } from \"zx\";\n\ntype ShellOptions = Partial<ZxOptions>;\n\nexport type Shell = ZxShell & { quiet: ZxShell };\n\nexport class ShellService {\n #shell: Shell;\n\n constructor(options: ShellOptions) {\n this.#shell = Object.assign(make$(options), {\n quiet: make$({ ...options, verbose: false }),\n });\n }\n\n get $() {\n return this.#shell;\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { ShellService } from \"./shell\";\n\ntype CreateOptions = {\n localBaseBinPath?: string | Array<string>;\n};\n\nexport const cwd = fs.realpathSync(process.cwd());\n\n// Inspired by https://dub.sh/6tiHVgn\nexport function quote(arg: string) {\n if (/^[\\w./:=@-]+$/i.test(arg) || arg === \"\") {\n return arg;\n }\n\n return arg\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/'/g, \"\\\\'\")\n .replace(/\\f/g, \"\\\\f\")\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\t/g, \"\\\\t\")\n .replace(/\\v/g, \"\\\\v\")\n .replace(/\\0/g, \"\\\\0\");\n}\n\nexport const isRaw = (arg: unknown): arg is { stdout: string } =>\n typeof arg === \"object\" && arg !== null && \"stdout\" in arg && typeof arg.stdout === \"string\";\n\nconst getLocalBinPath = (dirPath: string) => path.join(dirPath, \"node_modules\", \".bin\");\n\nfunction defaultQuote(arg: unknown) {\n if (typeof arg === \"string\") {\n return quote(arg);\n }\n\n if (isRaw(arg)) {\n return arg.stdout;\n }\n\n throw TypeError(`Unsupported argument type: ${typeof arg}`);\n}\n\nexport function createShellService(options: CreateOptions = {}) {\n const preferLocal = !options.localBaseBinPath\n ? undefined\n : Array.isArray(options.localBaseBinPath)\n ? options.localBaseBinPath.map(getLocalBinPath)\n : [options.localBaseBinPath].map(getLocalBinPath);\n\n return new ShellService({\n verbose: true,\n cwd,\n preferLocal,\n quote: defaultQuote,\n ...options,\n });\n}\n","import type { PkgService } from \"./services\";\n\nexport function getVersion(pkg: PkgService) {\n return Bun.env.VERSION || pkg.packageJson.version;\n}\n"],"mappings":"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","names":["supportsColor","chalk","path","fs","cwd","make$","import_node_fs","import_node_path","fs","path"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/colors.ts","../src/services/pkg.ts","../src/services/shell/shell.ts","../src/services/shell/create.ts","../src/version.ts"],"sourcesContent":["export * from \"./colors\";\nexport * from \"./services\";\nexport * from \"./version\";\n","import chalk, { type ChalkInstance } from \"chalk\";\nimport supportsColor from \"supports-color\";\n\n// https://no-color.org/\nconst colorIsSupported = () => supportsColor.stdout && !process.env.NO_COLOR;\n\nconst identity = <T>(x: T) => x;\nconst safe = (style: ChalkInstance) => (colorIsSupported() ? style : identity);\n\nexport const colors = {\n blueBright: safe(chalk.blueBright),\n redBright: safe(chalk.redBright),\n greenBright: safe(chalk.greenBright),\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { type Project, findWorkspacePackages } from \"@pnpm/workspace.find-packages\";\nimport { readWorkspaceManifest } from \"@pnpm/workspace.read-manifest\";\nimport { type NormalizedPackageJson, readPackageUp } from \"read-package-up\";\n\nexport type { Project };\n\nexport class PkgService {\n #packageJson: NormalizedPackageJson;\n #dirPath: string;\n\n get dirPath() {\n return this.#dirPath;\n }\n\n get packageJson() {\n return this.#packageJson;\n }\n\n constructor(packageJson: NormalizedPackageJson, pkgPath: string) {\n this.#packageJson = packageJson;\n this.#dirPath = path.dirname(pkgPath);\n }\n\n info() {\n return {\n packageJson: this.#packageJson,\n dirPath: this.#dirPath,\n };\n }\n\n hasFile(name: string, dir?: string) {\n const filepath = dir ? path.join(dir, name) : this.#fromApp(name);\n return fs.existsSync(filepath);\n }\n\n isMonorepo() {\n return this.#packageJson.workspaces !== undefined || this.#hasPnpmWorkspace();\n }\n\n async getWorkspaceProjects() {\n let patterns: string[];\n\n if (this.#hasPnpmWorkspace()) {\n const manifest = await readWorkspaceManifest(this.#dirPath);\n\n if (!manifest) {\n throw new Error(\"Can't read pnpm workspace manifest\");\n }\n\n patterns = manifest.packages;\n } else {\n patterns = Array.isArray(this.#packageJson.workspaces)\n ? this.#packageJson.workspaces\n : (this.#packageJson.workspaces?.packages ?? []);\n }\n\n if (!Array.isArray(patterns) || patterns.some((p) => typeof p !== \"string\")) {\n throw new Error(\"Invalid workspace patterns\");\n }\n\n const projects = await findWorkspacePackages(this.#dirPath, {\n patterns,\n });\n\n const excludeRoot = (projects: Project[]) => {\n return projects.filter((project) => project.rootDir !== this.#dirPath);\n };\n\n return excludeRoot(projects);\n }\n\n #hasPnpmWorkspace() {\n return this.hasFile(\"pnpm-workspace.yaml\");\n }\n\n #fromApp(...args: string[]) {\n return path.join(this.#dirPath, ...args);\n }\n}\n\nexport async function createPkgService(cwd: string): Promise<PkgService | null> {\n const searchResult = await readPackageUp({ cwd });\n\n if (!searchResult) {\n return null;\n }\n\n const { packageJson, path } = searchResult;\n\n return new PkgService(packageJson, path);\n}\n","import { $ as make$ } from \"zx\";\nimport type { Shell, ShellOptions } from \"./types\";\n\nexport class ShellService {\n #shell: Shell;\n #options: ShellOptions;\n\n constructor(options: ShellOptions) {\n this.#options = options;\n this.#shell = make$(options);\n }\n\n get $() {\n return this.#shell;\n }\n\n quiet(options?: ShellOptions) {\n return this.child({\n ...options,\n verbose: false,\n });\n }\n\n at(cwd: string, options?: ShellOptions) {\n return this.child({\n ...options,\n cwd,\n });\n }\n\n child(options: ShellOptions) {\n return new ShellService({\n ...this.#options,\n ...options,\n });\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { ShellService } from \"./shell\";\nimport type { CreateOptions } from \"./types\";\n\nexport const cwd = fs.realpathSync(process.cwd());\n\n// Inspired by https://dub.sh/6tiHVgn\nexport function quote(arg: string) {\n if (/^[\\w./:=@-]+$/i.test(arg) || arg === \"\") {\n return arg;\n }\n\n return arg\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/'/g, \"\\\\'\")\n .replace(/\\f/g, \"\\\\f\")\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\t/g, \"\\\\t\")\n .replace(/\\v/g, \"\\\\v\")\n .replace(/\\0/g, \"\\\\0\");\n}\n\nexport const isRaw = (arg: unknown): arg is { stdout: string } =>\n typeof arg === \"object\" && arg !== null && \"stdout\" in arg && typeof arg.stdout === \"string\";\n\nconst getLocalBinPath = (dirPath: string) => path.join(dirPath, \"node_modules\", \".bin\");\n\nfunction defaultQuote(arg: unknown) {\n if (typeof arg === \"string\") {\n return quote(arg);\n }\n\n if (isRaw(arg)) {\n return arg.stdout;\n }\n\n throw TypeError(`Unsupported argument type: ${typeof arg}`);\n}\n\nexport function createShellService(options: CreateOptions = {}) {\n const preferLocal = !options.localBaseBinPath\n ? undefined\n : Array.isArray(options.localBaseBinPath)\n ? options.localBaseBinPath.map(getLocalBinPath)\n : [options.localBaseBinPath].map(getLocalBinPath);\n\n return new ShellService({\n verbose: true,\n cwd,\n preferLocal,\n quote: defaultQuote,\n ...options,\n });\n}\n","import type { PkgService } from \"./services\";\n\nexport function getVersion(pkg: PkgService) {\n return process.env.VERSION || pkg.packageJson.version;\n}\n"],"mappings":"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","names":["supportsColor","chalk","import_workspace","path","fs","projects","cwd","make$","cwd","import_node_fs","import_node_path","fs","path"]}
package/dist/index.d.cts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { ChalkInstance } from 'chalk';
2
+ import { Project } from '@pnpm/workspace.find-packages';
3
+ export { Project } from '@pnpm/workspace.find-packages';
2
4
  import { NormalizedPackageJson } from 'read-package-up';
3
- import { Shell as Shell$1, Options } from 'zx';
5
+ import { Options, Shell as Shell$1 } from 'zx';
4
6
 
5
7
  declare const colors: {
6
8
  blueBright: (<T>(x: T) => T) | ChalkInstance;
@@ -13,27 +15,31 @@ declare class PkgService {
13
15
  get dirPath(): string;
14
16
  get packageJson(): NormalizedPackageJson;
15
17
  constructor(packageJson: NormalizedPackageJson, pkgPath: string);
16
- hasFile(name: string): boolean;
17
18
  info(): {
18
19
  packageJson: NormalizedPackageJson;
19
20
  dirPath: string;
20
21
  };
22
+ hasFile(name: string, dir?: string): boolean;
23
+ isMonorepo(): boolean;
24
+ getWorkspaceProjects(): Promise<Project[]>;
21
25
  }
22
26
  declare function createPkgService(cwd: string): Promise<PkgService | null>;
23
27
 
28
+ type Shell = Shell$1;
24
29
  type ShellOptions = Partial<Options>;
25
- type Shell = Shell$1 & {
26
- quiet: Shell$1;
30
+ type CreateOptions = ShellOptions & {
31
+ localBaseBinPath?: string | Array<string>;
27
32
  };
33
+
28
34
  declare class ShellService {
29
35
  #private;
30
36
  constructor(options: ShellOptions);
31
37
  get $(): Shell;
38
+ quiet(options?: ShellOptions): ShellService;
39
+ at(cwd: string, options?: ShellOptions): ShellService;
40
+ child(options: ShellOptions): ShellService;
32
41
  }
33
42
 
34
- type CreateOptions = {
35
- localBaseBinPath?: string | Array<string>;
36
- };
37
43
  declare const cwd: string;
38
44
  declare function quote(arg: string): string;
39
45
  declare const isRaw: (arg: unknown) => arg is {
@@ -43,4 +49,4 @@ declare function createShellService(options?: CreateOptions): ShellService;
43
49
 
44
50
  declare function getVersion(pkg: PkgService): string;
45
51
 
46
- export { PkgService, type Shell, ShellService, colors, createPkgService, createShellService, cwd, getVersion, isRaw, quote };
52
+ export { PkgService, ShellService, colors, createPkgService, createShellService, cwd, getVersion, isRaw, quote };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { ChalkInstance } from 'chalk';
2
+ import { Project } from '@pnpm/workspace.find-packages';
3
+ export { Project } from '@pnpm/workspace.find-packages';
2
4
  import { NormalizedPackageJson } from 'read-package-up';
3
- import { Shell as Shell$1, Options } from 'zx';
5
+ import { Options, Shell as Shell$1 } from 'zx';
4
6
 
5
7
  declare const colors: {
6
8
  blueBright: (<T>(x: T) => T) | ChalkInstance;
@@ -13,27 +15,31 @@ declare class PkgService {
13
15
  get dirPath(): string;
14
16
  get packageJson(): NormalizedPackageJson;
15
17
  constructor(packageJson: NormalizedPackageJson, pkgPath: string);
16
- hasFile(name: string): boolean;
17
18
  info(): {
18
19
  packageJson: NormalizedPackageJson;
19
20
  dirPath: string;
20
21
  };
22
+ hasFile(name: string, dir?: string): boolean;
23
+ isMonorepo(): boolean;
24
+ getWorkspaceProjects(): Promise<Project[]>;
21
25
  }
22
26
  declare function createPkgService(cwd: string): Promise<PkgService | null>;
23
27
 
28
+ type Shell = Shell$1;
24
29
  type ShellOptions = Partial<Options>;
25
- type Shell = Shell$1 & {
26
- quiet: Shell$1;
30
+ type CreateOptions = ShellOptions & {
31
+ localBaseBinPath?: string | Array<string>;
27
32
  };
33
+
28
34
  declare class ShellService {
29
35
  #private;
30
36
  constructor(options: ShellOptions);
31
37
  get $(): Shell;
38
+ quiet(options?: ShellOptions): ShellService;
39
+ at(cwd: string, options?: ShellOptions): ShellService;
40
+ child(options: ShellOptions): ShellService;
32
41
  }
33
42
 
34
- type CreateOptions = {
35
- localBaseBinPath?: string | Array<string>;
36
- };
37
43
  declare const cwd: string;
38
44
  declare function quote(arg: string): string;
39
45
  declare const isRaw: (arg: unknown) => arg is {
@@ -43,4 +49,4 @@ declare function createShellService(options?: CreateOptions): ShellService;
43
49
 
44
50
  declare function getVersion(pkg: PkgService): string;
45
51
 
46
- export { PkgService, type Shell, ShellService, colors, createPkgService, createShellService, cwd, getVersion, isRaw, quote };
52
+ export { PkgService, ShellService, colors, createPkgService, createShellService, cwd, getVersion, isRaw, quote };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/colors.ts
2
2
  import chalk from "chalk";
3
3
  import supportsColor from "supports-color";
4
- var colorIsSupported = () => supportsColor.stdout && !Bun.env.NO_COLOR;
4
+ var colorIsSupported = () => supportsColor.stdout && !process.env.NO_COLOR;
5
5
  var identity = (x) => x;
6
6
  var safe = (style) => colorIsSupported() ? style : identity;
7
7
  var colors = {
@@ -13,6 +13,8 @@ var colors = {
13
13
  // src/services/pkg.ts
14
14
  import fs from "node:fs";
15
15
  import path from "node:path";
16
+ import { findWorkspacePackages } from "@pnpm/workspace.find-packages";
17
+ import { readWorkspaceManifest } from "@pnpm/workspace.read-manifest";
16
18
  import { readPackageUp } from "read-package-up";
17
19
  var PkgService = class {
18
20
  #packageJson;
@@ -27,18 +29,47 @@ var PkgService = class {
27
29
  this.#packageJson = packageJson;
28
30
  this.#dirPath = path.dirname(pkgPath);
29
31
  }
30
- hasFile(name) {
31
- return fs.existsSync(this.#fromApp(name));
32
- }
33
- #fromApp(...args) {
34
- return path.join(this.#dirPath, ...args);
35
- }
36
32
  info() {
37
33
  return {
38
34
  packageJson: this.#packageJson,
39
35
  dirPath: this.#dirPath
40
36
  };
41
37
  }
38
+ hasFile(name, dir) {
39
+ const filepath = dir ? path.join(dir, name) : this.#fromApp(name);
40
+ return fs.existsSync(filepath);
41
+ }
42
+ isMonorepo() {
43
+ return this.#packageJson.workspaces !== void 0 || this.#hasPnpmWorkspace();
44
+ }
45
+ async getWorkspaceProjects() {
46
+ let patterns;
47
+ if (this.#hasPnpmWorkspace()) {
48
+ const manifest = await readWorkspaceManifest(this.#dirPath);
49
+ if (!manifest) {
50
+ throw new Error("Can't read pnpm workspace manifest");
51
+ }
52
+ patterns = manifest.packages;
53
+ } else {
54
+ patterns = Array.isArray(this.#packageJson.workspaces) ? this.#packageJson.workspaces : this.#packageJson.workspaces?.packages ?? [];
55
+ }
56
+ if (!Array.isArray(patterns) || patterns.some((p) => typeof p !== "string")) {
57
+ throw new Error("Invalid workspace patterns");
58
+ }
59
+ const projects = await findWorkspacePackages(this.#dirPath, {
60
+ patterns
61
+ });
62
+ const excludeRoot = (projects2) => {
63
+ return projects2.filter((project) => project.rootDir !== this.#dirPath);
64
+ };
65
+ return excludeRoot(projects);
66
+ }
67
+ #hasPnpmWorkspace() {
68
+ return this.hasFile("pnpm-workspace.yaml");
69
+ }
70
+ #fromApp(...args) {
71
+ return path.join(this.#dirPath, ...args);
72
+ }
42
73
  };
43
74
  async function createPkgService(cwd2) {
44
75
  const searchResult = await readPackageUp({ cwd: cwd2 });
@@ -51,16 +82,34 @@ async function createPkgService(cwd2) {
51
82
 
52
83
  // src/services/shell/shell.ts
53
84
  import { $ as make$ } from "zx";
54
- var ShellService = class {
85
+ var ShellService = class _ShellService {
55
86
  #shell;
87
+ #options;
56
88
  constructor(options) {
57
- this.#shell = Object.assign(make$(options), {
58
- quiet: make$({ ...options, verbose: false })
59
- });
89
+ this.#options = options;
90
+ this.#shell = make$(options);
60
91
  }
61
92
  get $() {
62
93
  return this.#shell;
63
94
  }
95
+ quiet(options) {
96
+ return this.child({
97
+ ...options,
98
+ verbose: false
99
+ });
100
+ }
101
+ at(cwd2, options) {
102
+ return this.child({
103
+ ...options,
104
+ cwd: cwd2
105
+ });
106
+ }
107
+ child(options) {
108
+ return new _ShellService({
109
+ ...this.#options,
110
+ ...options
111
+ });
112
+ }
64
113
  };
65
114
 
66
115
  // src/services/shell/create.ts
@@ -97,7 +146,7 @@ function createShellService(options = {}) {
97
146
 
98
147
  // src/version.ts
99
148
  function getVersion(pkg) {
100
- return Bun.env.VERSION || pkg.packageJson.version;
149
+ return process.env.VERSION || pkg.packageJson.version;
101
150
  }
102
151
  export {
103
152
  PkgService,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/colors.ts","../src/services/pkg.ts","../src/services/shell/shell.ts","../src/services/shell/create.ts","../src/version.ts"],"sourcesContent":["import chalk, { type ChalkInstance } from \"chalk\";\nimport supportsColor from \"supports-color\";\n\n// https://no-color.org/\nconst colorIsSupported = () => supportsColor.stdout && !Bun.env.NO_COLOR;\n\nconst identity = <T>(x: T) => x;\nconst safe = (style: ChalkInstance) => (colorIsSupported() ? style : identity);\n\nexport const colors = {\n blueBright: safe(chalk.blueBright),\n redBright: safe(chalk.redBright),\n greenBright: safe(chalk.greenBright),\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { type NormalizedPackageJson, readPackageUp } from \"read-package-up\";\n\nexport class PkgService {\n #packageJson: NormalizedPackageJson;\n #dirPath: string;\n\n get dirPath() {\n return this.#dirPath;\n }\n\n get packageJson() {\n return this.#packageJson;\n }\n\n constructor(packageJson: NormalizedPackageJson, pkgPath: string) {\n this.#packageJson = packageJson;\n this.#dirPath = path.dirname(pkgPath);\n }\n\n hasFile(name: string) {\n return fs.existsSync(this.#fromApp(name));\n }\n\n #fromApp(...args: string[]) {\n return path.join(this.#dirPath, ...args);\n }\n\n info() {\n return {\n packageJson: this.#packageJson,\n dirPath: this.#dirPath,\n };\n }\n}\n\nexport async function createPkgService(cwd: string): Promise<PkgService | null> {\n const searchResult = await readPackageUp({ cwd });\n\n if (!searchResult) {\n return null;\n }\n\n const { packageJson, path } = searchResult;\n\n return new PkgService(packageJson, path);\n}\n","import { type Options as ZxOptions, type Shell as ZxShell, $ as make$ } from \"zx\";\n\ntype ShellOptions = Partial<ZxOptions>;\n\nexport type Shell = ZxShell & { quiet: ZxShell };\n\nexport class ShellService {\n #shell: Shell;\n\n constructor(options: ShellOptions) {\n this.#shell = Object.assign(make$(options), {\n quiet: make$({ ...options, verbose: false }),\n });\n }\n\n get $() {\n return this.#shell;\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { ShellService } from \"./shell\";\n\ntype CreateOptions = {\n localBaseBinPath?: string | Array<string>;\n};\n\nexport const cwd = fs.realpathSync(process.cwd());\n\n// Inspired by https://dub.sh/6tiHVgn\nexport function quote(arg: string) {\n if (/^[\\w./:=@-]+$/i.test(arg) || arg === \"\") {\n return arg;\n }\n\n return arg\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/'/g, \"\\\\'\")\n .replace(/\\f/g, \"\\\\f\")\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\t/g, \"\\\\t\")\n .replace(/\\v/g, \"\\\\v\")\n .replace(/\\0/g, \"\\\\0\");\n}\n\nexport const isRaw = (arg: unknown): arg is { stdout: string } =>\n typeof arg === \"object\" && arg !== null && \"stdout\" in arg && typeof arg.stdout === \"string\";\n\nconst getLocalBinPath = (dirPath: string) => path.join(dirPath, \"node_modules\", \".bin\");\n\nfunction defaultQuote(arg: unknown) {\n if (typeof arg === \"string\") {\n return quote(arg);\n }\n\n if (isRaw(arg)) {\n return arg.stdout;\n }\n\n throw TypeError(`Unsupported argument type: ${typeof arg}`);\n}\n\nexport function createShellService(options: CreateOptions = {}) {\n const preferLocal = !options.localBaseBinPath\n ? undefined\n : Array.isArray(options.localBaseBinPath)\n ? options.localBaseBinPath.map(getLocalBinPath)\n : [options.localBaseBinPath].map(getLocalBinPath);\n\n return new ShellService({\n verbose: true,\n cwd,\n preferLocal,\n quote: defaultQuote,\n ...options,\n });\n}\n","import type { PkgService } from \"./services\";\n\nexport function getVersion(pkg: PkgService) {\n return Bun.env.VERSION || pkg.packageJson.version;\n}\n"],"mappings":";AAAA,OAAO,WAAmC;AAC1C,OAAO,mBAAmB;AAG1B,IAAM,mBAAmB,MAAM,cAAc,UAAU,CAAC,IAAI,IAAI;AAEhE,IAAM,WAAW,CAAI,MAAS;AAC9B,IAAM,OAAO,CAAC,UAA0B,iBAAiB,IAAI,QAAQ;AAE9D,IAAM,SAAS;AAAA,EACpB,YAAY,KAAK,MAAM,UAAU;AAAA,EACjC,WAAW,KAAK,MAAM,SAAS;AAAA,EAC/B,aAAa,KAAK,MAAM,WAAW;AACrC;;;ACbA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAqC,qBAAqB;AAEnD,IAAM,aAAN,MAAiB;AAAA,EACtB;AAAA,EACA;AAAA,EAEA,IAAI,UAAU;AACZ,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,cAAc;AAChB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAY,aAAoC,SAAiB;AAC/D,SAAK,eAAe;AACpB,SAAK,WAAW,KAAK,QAAQ,OAAO;AAAA,EACtC;AAAA,EAEA,QAAQ,MAAc;AACpB,WAAO,GAAG,WAAW,KAAK,SAAS,IAAI,CAAC;AAAA,EAC1C;AAAA,EAEA,YAAY,MAAgB;AAC1B,WAAO,KAAK,KAAK,KAAK,UAAU,GAAG,IAAI;AAAA,EACzC;AAAA,EAEA,OAAO;AACL,WAAO;AAAA,MACL,aAAa,KAAK;AAAA,MAClB,SAAS,KAAK;AAAA,IAChB;AAAA,EACF;AACF;AAEA,eAAsB,iBAAiBA,MAAyC;AAC9E,QAAM,eAAe,MAAM,cAAc,EAAE,KAAAA,KAAI,CAAC;AAEhD,MAAI,CAAC,cAAc;AACjB,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,aAAa,MAAAC,MAAK,IAAI;AAE9B,SAAO,IAAI,WAAW,aAAaA,KAAI;AACzC;;;AC/CA,SAA2D,KAAK,aAAa;AAMtE,IAAM,eAAN,MAAmB;AAAA,EACxB;AAAA,EAEA,YAAY,SAAuB;AACjC,SAAK,SAAS,OAAO,OAAO,MAAM,OAAO,GAAG;AAAA,MAC1C,OAAO,MAAM,EAAE,GAAG,SAAS,SAAS,MAAM,CAAC;AAAA,IAC7C,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,IAAI;AACN,WAAO,KAAK;AAAA,EACd;AACF;;;AClBA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAOV,IAAM,MAAMC,IAAG,aAAa,QAAQ,IAAI,CAAC;AAGzC,SAAS,MAAM,KAAa;AACjC,MAAI,iBAAiB,KAAK,GAAG,KAAK,QAAQ,IAAI;AAC5C,WAAO;AAAA,EACT;AAEA,SAAO,IACJ,QAAQ,OAAO,MAAM,EACrB,QAAQ,MAAM,KAAK,EACnB,QAAQ,OAAO,KAAK,EACpB,QAAQ,OAAO,KAAK,EACpB,QAAQ,OAAO,KAAK,EACpB,QAAQ,OAAO,KAAK,EACpB,QAAQ,OAAO,KAAK,EACpB,QAAQ,OAAO,KAAK;AACzB;AAEO,IAAM,QAAQ,CAAC,QACpB,OAAO,QAAQ,YAAY,QAAQ,QAAQ,YAAY,OAAO,OAAO,IAAI,WAAW;AAEtF,IAAM,kBAAkB,CAAC,YAAoBC,MAAK,KAAK,SAAS,gBAAgB,MAAM;AAEtF,SAAS,aAAa,KAAc;AAClC,MAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO,MAAM,GAAG;AAAA,EAClB;AAEA,MAAI,MAAM,GAAG,GAAG;AACd,WAAO,IAAI;AAAA,EACb;AAEA,QAAM,UAAU,8BAA8B,OAAO,GAAG,EAAE;AAC5D;AAEO,SAAS,mBAAmB,UAAyB,CAAC,GAAG;AAC9D,QAAM,cAAc,CAAC,QAAQ,mBACzB,SACA,MAAM,QAAQ,QAAQ,gBAAgB,IACpC,QAAQ,iBAAiB,IAAI,eAAe,IAC5C,CAAC,QAAQ,gBAAgB,EAAE,IAAI,eAAe;AAEpD,SAAO,IAAI,aAAa;AAAA,IACtB,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,GAAG;AAAA,EACL,CAAC;AACH;;;ACxDO,SAAS,WAAW,KAAiB;AAC1C,SAAO,IAAI,IAAI,WAAW,IAAI,YAAY;AAC5C;","names":["cwd","path","fs","path","fs","path"]}
1
+ {"version":3,"sources":["../src/colors.ts","../src/services/pkg.ts","../src/services/shell/shell.ts","../src/services/shell/create.ts","../src/version.ts"],"sourcesContent":["import chalk, { type ChalkInstance } from \"chalk\";\nimport supportsColor from \"supports-color\";\n\n// https://no-color.org/\nconst colorIsSupported = () => supportsColor.stdout && !process.env.NO_COLOR;\n\nconst identity = <T>(x: T) => x;\nconst safe = (style: ChalkInstance) => (colorIsSupported() ? style : identity);\n\nexport const colors = {\n blueBright: safe(chalk.blueBright),\n redBright: safe(chalk.redBright),\n greenBright: safe(chalk.greenBright),\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { type Project, findWorkspacePackages } from \"@pnpm/workspace.find-packages\";\nimport { readWorkspaceManifest } from \"@pnpm/workspace.read-manifest\";\nimport { type NormalizedPackageJson, readPackageUp } from \"read-package-up\";\n\nexport type { Project };\n\nexport class PkgService {\n #packageJson: NormalizedPackageJson;\n #dirPath: string;\n\n get dirPath() {\n return this.#dirPath;\n }\n\n get packageJson() {\n return this.#packageJson;\n }\n\n constructor(packageJson: NormalizedPackageJson, pkgPath: string) {\n this.#packageJson = packageJson;\n this.#dirPath = path.dirname(pkgPath);\n }\n\n info() {\n return {\n packageJson: this.#packageJson,\n dirPath: this.#dirPath,\n };\n }\n\n hasFile(name: string, dir?: string) {\n const filepath = dir ? path.join(dir, name) : this.#fromApp(name);\n return fs.existsSync(filepath);\n }\n\n isMonorepo() {\n return this.#packageJson.workspaces !== undefined || this.#hasPnpmWorkspace();\n }\n\n async getWorkspaceProjects() {\n let patterns: string[];\n\n if (this.#hasPnpmWorkspace()) {\n const manifest = await readWorkspaceManifest(this.#dirPath);\n\n if (!manifest) {\n throw new Error(\"Can't read pnpm workspace manifest\");\n }\n\n patterns = manifest.packages;\n } else {\n patterns = Array.isArray(this.#packageJson.workspaces)\n ? this.#packageJson.workspaces\n : (this.#packageJson.workspaces?.packages ?? []);\n }\n\n if (!Array.isArray(patterns) || patterns.some((p) => typeof p !== \"string\")) {\n throw new Error(\"Invalid workspace patterns\");\n }\n\n const projects = await findWorkspacePackages(this.#dirPath, {\n patterns,\n });\n\n const excludeRoot = (projects: Project[]) => {\n return projects.filter((project) => project.rootDir !== this.#dirPath);\n };\n\n return excludeRoot(projects);\n }\n\n #hasPnpmWorkspace() {\n return this.hasFile(\"pnpm-workspace.yaml\");\n }\n\n #fromApp(...args: string[]) {\n return path.join(this.#dirPath, ...args);\n }\n}\n\nexport async function createPkgService(cwd: string): Promise<PkgService | null> {\n const searchResult = await readPackageUp({ cwd });\n\n if (!searchResult) {\n return null;\n }\n\n const { packageJson, path } = searchResult;\n\n return new PkgService(packageJson, path);\n}\n","import { $ as make$ } from \"zx\";\nimport type { Shell, ShellOptions } from \"./types\";\n\nexport class ShellService {\n #shell: Shell;\n #options: ShellOptions;\n\n constructor(options: ShellOptions) {\n this.#options = options;\n this.#shell = make$(options);\n }\n\n get $() {\n return this.#shell;\n }\n\n quiet(options?: ShellOptions) {\n return this.child({\n ...options,\n verbose: false,\n });\n }\n\n at(cwd: string, options?: ShellOptions) {\n return this.child({\n ...options,\n cwd,\n });\n }\n\n child(options: ShellOptions) {\n return new ShellService({\n ...this.#options,\n ...options,\n });\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { ShellService } from \"./shell\";\nimport type { CreateOptions } from \"./types\";\n\nexport const cwd = fs.realpathSync(process.cwd());\n\n// Inspired by https://dub.sh/6tiHVgn\nexport function quote(arg: string) {\n if (/^[\\w./:=@-]+$/i.test(arg) || arg === \"\") {\n return arg;\n }\n\n return arg\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/'/g, \"\\\\'\")\n .replace(/\\f/g, \"\\\\f\")\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\t/g, \"\\\\t\")\n .replace(/\\v/g, \"\\\\v\")\n .replace(/\\0/g, \"\\\\0\");\n}\n\nexport const isRaw = (arg: unknown): arg is { stdout: string } =>\n typeof arg === \"object\" && arg !== null && \"stdout\" in arg && typeof arg.stdout === \"string\";\n\nconst getLocalBinPath = (dirPath: string) => path.join(dirPath, \"node_modules\", \".bin\");\n\nfunction defaultQuote(arg: unknown) {\n if (typeof arg === \"string\") {\n return quote(arg);\n }\n\n if (isRaw(arg)) {\n return arg.stdout;\n }\n\n throw TypeError(`Unsupported argument type: ${typeof arg}`);\n}\n\nexport function createShellService(options: CreateOptions = {}) {\n const preferLocal = !options.localBaseBinPath\n ? undefined\n : Array.isArray(options.localBaseBinPath)\n ? options.localBaseBinPath.map(getLocalBinPath)\n : [options.localBaseBinPath].map(getLocalBinPath);\n\n return new ShellService({\n verbose: true,\n cwd,\n preferLocal,\n quote: defaultQuote,\n ...options,\n });\n}\n","import type { PkgService } from \"./services\";\n\nexport function getVersion(pkg: PkgService) {\n return process.env.VERSION || pkg.packageJson.version;\n}\n"],"mappings":"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","names":["projects","cwd","path","cwd","fs","path","fs","path"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vlandoss/clibuddy",
3
- "version": "0.0.2-git-1383198.0",
3
+ "version": "0.0.2-git-8d13199.0",
4
4
  "description": "A helper library to create CLIs in Variable Land",
5
5
  "homepage": "https://github.com/variableland/dx/tree/main/packages/clibuddy#readme",
6
6
  "bugs": {
@@ -32,6 +32,8 @@
32
32
  "src"
33
33
  ],
34
34
  "dependencies": {
35
+ "@pnpm/workspace.find-packages": "^1000.0.23",
36
+ "@pnpm/workspace.read-manifest": "^1000.1.4",
35
37
  "chalk": "5.4.1",
36
38
  "read-package-up": "11.0.0",
37
39
  "supports-color": "10.0.0",
package/src/colors.ts CHANGED
@@ -2,7 +2,7 @@ import chalk, { type ChalkInstance } from "chalk";
2
2
  import supportsColor from "supports-color";
3
3
 
4
4
  // https://no-color.org/
5
- const colorIsSupported = () => supportsColor.stdout && !Bun.env.NO_COLOR;
5
+ const colorIsSupported = () => supportsColor.stdout && !process.env.NO_COLOR;
6
6
 
7
7
  const identity = <T>(x: T) => x;
8
8
  const safe = (style: ChalkInstance) => (colorIsSupported() ? style : identity);
@@ -1,7 +1,11 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import { type Project, findWorkspacePackages } from "@pnpm/workspace.find-packages";
4
+ import { readWorkspaceManifest } from "@pnpm/workspace.read-manifest";
3
5
  import { type NormalizedPackageJson, readPackageUp } from "read-package-up";
4
6
 
7
+ export type { Project };
8
+
5
9
  export class PkgService {
6
10
  #packageJson: NormalizedPackageJson;
7
11
  #dirPath: string;
@@ -19,20 +23,61 @@ export class PkgService {
19
23
  this.#dirPath = path.dirname(pkgPath);
20
24
  }
21
25
 
22
- hasFile(name: string) {
23
- return fs.existsSync(this.#fromApp(name));
24
- }
25
-
26
- #fromApp(...args: string[]) {
27
- return path.join(this.#dirPath, ...args);
28
- }
29
-
30
26
  info() {
31
27
  return {
32
28
  packageJson: this.#packageJson,
33
29
  dirPath: this.#dirPath,
34
30
  };
35
31
  }
32
+
33
+ hasFile(name: string, dir?: string) {
34
+ const filepath = dir ? path.join(dir, name) : this.#fromApp(name);
35
+ return fs.existsSync(filepath);
36
+ }
37
+
38
+ isMonorepo() {
39
+ return this.#packageJson.workspaces !== undefined || this.#hasPnpmWorkspace();
40
+ }
41
+
42
+ async getWorkspaceProjects() {
43
+ let patterns: string[];
44
+
45
+ if (this.#hasPnpmWorkspace()) {
46
+ const manifest = await readWorkspaceManifest(this.#dirPath);
47
+
48
+ if (!manifest) {
49
+ throw new Error("Can't read pnpm workspace manifest");
50
+ }
51
+
52
+ patterns = manifest.packages;
53
+ } else {
54
+ patterns = Array.isArray(this.#packageJson.workspaces)
55
+ ? this.#packageJson.workspaces
56
+ : (this.#packageJson.workspaces?.packages ?? []);
57
+ }
58
+
59
+ if (!Array.isArray(patterns) || patterns.some((p) => typeof p !== "string")) {
60
+ throw new Error("Invalid workspace patterns");
61
+ }
62
+
63
+ const projects = await findWorkspacePackages(this.#dirPath, {
64
+ patterns,
65
+ });
66
+
67
+ const excludeRoot = (projects: Project[]) => {
68
+ return projects.filter((project) => project.rootDir !== this.#dirPath);
69
+ };
70
+
71
+ return excludeRoot(projects);
72
+ }
73
+
74
+ #hasPnpmWorkspace() {
75
+ return this.hasFile("pnpm-workspace.yaml");
76
+ }
77
+
78
+ #fromApp(...args: string[]) {
79
+ return path.join(this.#dirPath, ...args);
80
+ }
36
81
  }
37
82
 
38
83
  export async function createPkgService(cwd: string): Promise<PkgService | null> {
@@ -1,10 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { ShellService } from "./shell";
4
-
5
- type CreateOptions = {
6
- localBaseBinPath?: string | Array<string>;
7
- };
4
+ import type { CreateOptions } from "./types";
8
5
 
9
6
  export const cwd = fs.realpathSync(process.cwd());
10
7
 
@@ -1,19 +1,37 @@
1
- import { type Options as ZxOptions, type Shell as ZxShell, $ as make$ } from "zx";
2
-
3
- type ShellOptions = Partial<ZxOptions>;
4
-
5
- export type Shell = ZxShell & { quiet: ZxShell };
1
+ import { $ as make$ } from "zx";
2
+ import type { Shell, ShellOptions } from "./types";
6
3
 
7
4
  export class ShellService {
8
5
  #shell: Shell;
6
+ #options: ShellOptions;
9
7
 
10
8
  constructor(options: ShellOptions) {
11
- this.#shell = Object.assign(make$(options), {
12
- quiet: make$({ ...options, verbose: false }),
13
- });
9
+ this.#options = options;
10
+ this.#shell = make$(options);
14
11
  }
15
12
 
16
13
  get $() {
17
14
  return this.#shell;
18
15
  }
16
+
17
+ quiet(options?: ShellOptions) {
18
+ return this.child({
19
+ ...options,
20
+ verbose: false,
21
+ });
22
+ }
23
+
24
+ at(cwd: string, options?: ShellOptions) {
25
+ return this.child({
26
+ ...options,
27
+ cwd,
28
+ });
29
+ }
30
+
31
+ child(options: ShellOptions) {
32
+ return new ShellService({
33
+ ...this.#options,
34
+ ...options,
35
+ });
36
+ }
19
37
  }
@@ -0,0 +1,9 @@
1
+ import type { Options as ZxOptions, Shell as ZxShell } from "zx";
2
+
3
+ export type Shell = ZxShell;
4
+
5
+ export type ShellOptions = Partial<ZxOptions>;
6
+
7
+ export type CreateOptions = ShellOptions & {
8
+ localBaseBinPath?: string | Array<string>;
9
+ };
package/src/version.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { PkgService } from "./services";
2
2
 
3
3
  export function getVersion(pkg: PkgService) {
4
- return Bun.env.VERSION || pkg.packageJson.version;
4
+ return process.env.VERSION || pkg.packageJson.version;
5
5
  }