@vlandoss/clibuddy 0.0.5-git-a15eb4f.0 → 0.0.6-git-5566e2b.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
@@ -36,6 +36,7 @@ __export(index_exports, {
36
36
  createPkgService: () => createPkgService,
37
37
  createShellService: () => createShellService,
38
38
  cwd: () => cwd,
39
+ getPreferLocal: () => getPreferLocal,
39
40
  getVersion: () => getVersion,
40
41
  isProcessOutput: () => isProcessOutput,
41
42
  isRaw: () => isRaw,
@@ -128,16 +129,28 @@ async function createPkgService(cwd2) {
128
129
 
129
130
  // src/services/shell/create.ts
130
131
  var import_node_fs2 = __toESM(require("fs"), 1);
131
- var import_node_path2 = __toESM(require("path"), 1);
132
132
 
133
133
  // src/services/shell/shell.ts
134
+ var import_zx2 = require("zx");
135
+
136
+ // src/services/shell/utils.ts
137
+ var import_node_path2 = __toESM(require("path"), 1);
134
138
  var import_zx = require("zx");
139
+ function isProcessOutput(value) {
140
+ return value instanceof import_zx.ProcessOutput;
141
+ }
142
+ var getLocalBinPath = (dirPath) => import_node_path2.default.join(dirPath, "node_modules", ".bin");
143
+ function getPreferLocal(localBaseBinPath) {
144
+ return !localBaseBinPath ? void 0 : Array.isArray(localBaseBinPath) ? localBaseBinPath.map(getLocalBinPath) : [localBaseBinPath].map(getLocalBinPath);
145
+ }
146
+
147
+ // src/services/shell/shell.ts
135
148
  var ShellService = class _ShellService {
136
149
  #shell;
137
150
  #options;
138
151
  constructor(options) {
139
152
  this.#options = Object.freeze(options);
140
- this.#shell = (0, import_zx.$)(options);
153
+ this.#shell = (0, import_zx2.$)(options);
141
154
  }
142
155
  get options() {
143
156
  return this.#options;
@@ -145,6 +158,12 @@ var ShellService = class _ShellService {
145
158
  get $() {
146
159
  return this.#shell;
147
160
  }
161
+ child(options) {
162
+ return new _ShellService({
163
+ ...this.#options,
164
+ ...options
165
+ });
166
+ }
148
167
  quiet(options) {
149
168
  return this.child({
150
169
  ...options,
@@ -152,15 +171,20 @@ var ShellService = class _ShellService {
152
171
  });
153
172
  }
154
173
  at(cwd2, options) {
174
+ const getLocals = (locals) => (
175
+ // NOTE: the boolean handling is done outside when determining preferLocal
176
+ typeof locals === "boolean" ? [] : typeof locals === "undefined" ? [] : Array.isArray(locals) ? locals : [locals]
177
+ );
178
+ const cwdPreferLocal = getPreferLocal(cwd2);
179
+ const preferLocal = options?.preferLocal === false ? false : [
180
+ ...getLocals(this.#options.preferLocal),
181
+ ...getLocals(options?.preferLocal),
182
+ ...cwdPreferLocal ? cwdPreferLocal : []
183
+ ];
155
184
  return this.child({
156
185
  ...options,
157
- cwd: cwd2
158
- });
159
- }
160
- child(options) {
161
- return new _ShellService({
162
- ...this.#options,
163
- ...options
186
+ cwd: cwd2,
187
+ preferLocal
164
188
  });
165
189
  }
166
190
  };
@@ -174,7 +198,6 @@ function quote(arg) {
174
198
  return arg.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\f/g, "\\f").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t").replace(/\v/g, "\\v").replace(/\0/g, "\\0");
175
199
  }
176
200
  var isRaw = (arg) => typeof arg === "object" && arg !== null && "stdout" in arg && typeof arg.stdout === "string";
177
- var getLocalBinPath = (dirPath) => import_node_path2.default.join(dirPath, "node_modules", ".bin");
178
201
  function defaultQuote(arg) {
179
202
  if (typeof arg === "string") {
180
203
  return quote(arg);
@@ -185,7 +208,7 @@ function defaultQuote(arg) {
185
208
  throw TypeError(`Unsupported argument type: ${typeof arg}`);
186
209
  }
187
210
  function createShellService(options = {}) {
188
- const preferLocal = !options.localBaseBinPath ? void 0 : Array.isArray(options.localBaseBinPath) ? options.localBaseBinPath.map(getLocalBinPath) : [options.localBaseBinPath].map(getLocalBinPath);
211
+ const preferLocal = getPreferLocal(options.localBaseBinPath);
189
212
  return new ShellService({
190
213
  verbose: true,
191
214
  cwd,
@@ -195,12 +218,6 @@ function createShellService(options = {}) {
195
218
  });
196
219
  }
197
220
 
198
- // src/services/shell/utils.ts
199
- var import_zx2 = require("zx");
200
- function isProcessOutput(value) {
201
- return value instanceof import_zx2.ProcessOutput;
202
- }
203
-
204
221
  // src/version.ts
205
222
  function getVersion(pkg) {
206
223
  return process.env.VERSION || pkg.packageJson.version;
@@ -213,6 +230,7 @@ function getVersion(pkg) {
213
230
  createPkgService,
214
231
  createShellService,
215
232
  cwd,
233
+ getPreferLocal,
216
234
  getVersion,
217
235
  isProcessOutput,
218
236
  isRaw,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/colors.ts","../src/services/pkg.ts","../src/services/shell/create.ts","../src/services/shell/shell.ts","../src/services/shell/utils.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 bold: safe(chalk.bold),\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { findWorkspacePackages, type Project } 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 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 { $ 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 = Object.freeze(options);\n this.#shell = make$(options);\n }\n\n get options() {\n return this.#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 { ProcessOutput } from \"zx\";\n\nexport function isProcessOutput(value: unknown): value is ProcessOutput {\n return value instanceof ProcessOutput;\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","import_node_fs","import_node_path","make$","cwd","fs","path","import_zx"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/colors.ts","../src/services/pkg.ts","../src/services/shell/create.ts","../src/services/shell/shell.ts","../src/services/shell/utils.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 bold: safe(chalk.bold),\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { findWorkspacePackages, type Project } 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 fs from \"node:fs\";\nimport { ShellService } from \"./shell\";\nimport type { CreateOptions } from \"./types\";\nimport { getPreferLocal } from \"./utils\";\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\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 = getPreferLocal(options.localBaseBinPath);\n\n return new ShellService({\n verbose: true,\n cwd,\n preferLocal,\n quote: defaultQuote,\n ...options,\n });\n}\n","import { $ as make$ } from \"zx\";\nimport type { Shell, ShellOptions } from \"./types\";\nimport { getPreferLocal } from \"./utils\";\n\nexport class ShellService {\n #shell: Shell;\n #options: ShellOptions;\n\n constructor(options: ShellOptions) {\n this.#options = Object.freeze(options);\n this.#shell = make$(options);\n }\n\n get options() {\n return this.#options;\n }\n\n get $() {\n return this.#shell;\n }\n\n child(options: ShellOptions) {\n return new ShellService({\n ...this.#options,\n ...options,\n });\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 const getLocals = (locals: boolean | string | string[] | undefined) =>\n // NOTE: the boolean handling is done outside when determining preferLocal\n typeof locals === \"boolean\" ? [] : typeof locals === \"undefined\" ? [] : Array.isArray(locals) ? locals : [locals];\n\n const cwdPreferLocal = getPreferLocal(cwd);\n\n const preferLocal =\n options?.preferLocal === false\n ? false\n : [\n ...getLocals(this.#options.preferLocal),\n ...getLocals(options?.preferLocal),\n ...(cwdPreferLocal ? cwdPreferLocal : []),\n ];\n\n return this.child({\n ...options,\n cwd,\n preferLocal,\n });\n }\n}\n","import path from \"node:path\";\nimport { ProcessOutput } from \"zx\";\n\nexport function isProcessOutput(value: unknown): value is ProcessOutput {\n return value instanceof ProcessOutput;\n}\n\nconst getLocalBinPath = (dirPath: string) => path.join(dirPath, \"node_modules\", \".bin\");\n\nexport function getPreferLocal(localBaseBinPath: string | Array<string> | undefined) {\n return !localBaseBinPath\n ? undefined\n : Array.isArray(localBaseBinPath)\n ? localBaseBinPath.map(getLocalBinPath)\n : [localBaseBinPath].map(getLocalBinPath);\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","import_node_fs","import_zx","import_node_path","path","make$","cwd","fs"]}
package/dist/index.d.cts CHANGED
@@ -38,9 +38,9 @@ declare class ShellService {
38
38
  constructor(options: ShellOptions);
39
39
  get options(): Partial<zx.Options>;
40
40
  get $(): Shell;
41
+ child(options: ShellOptions): ShellService;
41
42
  quiet(options?: ShellOptions): ShellService;
42
43
  at(cwd: string, options?: ShellOptions): ShellService;
43
- child(options: ShellOptions): ShellService;
44
44
  }
45
45
 
46
46
  declare const cwd: string;
@@ -51,7 +51,8 @@ declare const isRaw: (arg: unknown) => arg is {
51
51
  declare function createShellService(options?: CreateOptions): ShellService;
52
52
 
53
53
  declare function isProcessOutput(value: unknown): value is ProcessOutput;
54
+ declare function getPreferLocal(localBaseBinPath: string | Array<string> | undefined): string[] | undefined;
54
55
 
55
56
  declare function getVersion(pkg: PkgService): string;
56
57
 
57
- export { type CreateOptions, PkgService, type Shell, type ShellOptions, ShellService, colors, createPkgService, createShellService, cwd, getVersion, isProcessOutput, isRaw, quote };
58
+ export { type CreateOptions, PkgService, type Shell, type ShellOptions, ShellService, colors, createPkgService, createShellService, cwd, getPreferLocal, getVersion, isProcessOutput, isRaw, quote };
package/dist/index.d.ts CHANGED
@@ -38,9 +38,9 @@ declare class ShellService {
38
38
  constructor(options: ShellOptions);
39
39
  get options(): Partial<zx.Options>;
40
40
  get $(): Shell;
41
+ child(options: ShellOptions): ShellService;
41
42
  quiet(options?: ShellOptions): ShellService;
42
43
  at(cwd: string, options?: ShellOptions): ShellService;
43
- child(options: ShellOptions): ShellService;
44
44
  }
45
45
 
46
46
  declare const cwd: string;
@@ -51,7 +51,8 @@ declare const isRaw: (arg: unknown) => arg is {
51
51
  declare function createShellService(options?: CreateOptions): ShellService;
52
52
 
53
53
  declare function isProcessOutput(value: unknown): value is ProcessOutput;
54
+ declare function getPreferLocal(localBaseBinPath: string | Array<string> | undefined): string[] | undefined;
54
55
 
55
56
  declare function getVersion(pkg: PkgService): string;
56
57
 
57
- export { type CreateOptions, PkgService, type Shell, type ShellOptions, ShellService, colors, createPkgService, createShellService, cwd, getVersion, isProcessOutput, isRaw, quote };
58
+ export { type CreateOptions, PkgService, type Shell, type ShellOptions, ShellService, colors, createPkgService, createShellService, cwd, getPreferLocal, getVersion, isProcessOutput, isRaw, quote };
package/dist/index.js CHANGED
@@ -83,10 +83,22 @@ async function createPkgService(cwd2) {
83
83
 
84
84
  // src/services/shell/create.ts
85
85
  import fs2 from "fs";
86
- import path2 from "path";
87
86
 
88
87
  // src/services/shell/shell.ts
89
88
  import { $ as make$ } from "zx";
89
+
90
+ // src/services/shell/utils.ts
91
+ import path2 from "path";
92
+ import { ProcessOutput } from "zx";
93
+ function isProcessOutput(value) {
94
+ return value instanceof ProcessOutput;
95
+ }
96
+ var getLocalBinPath = (dirPath) => path2.join(dirPath, "node_modules", ".bin");
97
+ function getPreferLocal(localBaseBinPath) {
98
+ return !localBaseBinPath ? void 0 : Array.isArray(localBaseBinPath) ? localBaseBinPath.map(getLocalBinPath) : [localBaseBinPath].map(getLocalBinPath);
99
+ }
100
+
101
+ // src/services/shell/shell.ts
90
102
  var ShellService = class _ShellService {
91
103
  #shell;
92
104
  #options;
@@ -100,6 +112,12 @@ var ShellService = class _ShellService {
100
112
  get $() {
101
113
  return this.#shell;
102
114
  }
115
+ child(options) {
116
+ return new _ShellService({
117
+ ...this.#options,
118
+ ...options
119
+ });
120
+ }
103
121
  quiet(options) {
104
122
  return this.child({
105
123
  ...options,
@@ -107,15 +125,20 @@ var ShellService = class _ShellService {
107
125
  });
108
126
  }
109
127
  at(cwd2, options) {
128
+ const getLocals = (locals) => (
129
+ // NOTE: the boolean handling is done outside when determining preferLocal
130
+ typeof locals === "boolean" ? [] : typeof locals === "undefined" ? [] : Array.isArray(locals) ? locals : [locals]
131
+ );
132
+ const cwdPreferLocal = getPreferLocal(cwd2);
133
+ const preferLocal = options?.preferLocal === false ? false : [
134
+ ...getLocals(this.#options.preferLocal),
135
+ ...getLocals(options?.preferLocal),
136
+ ...cwdPreferLocal ? cwdPreferLocal : []
137
+ ];
110
138
  return this.child({
111
139
  ...options,
112
- cwd: cwd2
113
- });
114
- }
115
- child(options) {
116
- return new _ShellService({
117
- ...this.#options,
118
- ...options
140
+ cwd: cwd2,
141
+ preferLocal
119
142
  });
120
143
  }
121
144
  };
@@ -129,7 +152,6 @@ function quote(arg) {
129
152
  return arg.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/\f/g, "\\f").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t").replace(/\v/g, "\\v").replace(/\0/g, "\\0");
130
153
  }
131
154
  var isRaw = (arg) => typeof arg === "object" && arg !== null && "stdout" in arg && typeof arg.stdout === "string";
132
- var getLocalBinPath = (dirPath) => path2.join(dirPath, "node_modules", ".bin");
133
155
  function defaultQuote(arg) {
134
156
  if (typeof arg === "string") {
135
157
  return quote(arg);
@@ -140,7 +162,7 @@ function defaultQuote(arg) {
140
162
  throw TypeError(`Unsupported argument type: ${typeof arg}`);
141
163
  }
142
164
  function createShellService(options = {}) {
143
- const preferLocal = !options.localBaseBinPath ? void 0 : Array.isArray(options.localBaseBinPath) ? options.localBaseBinPath.map(getLocalBinPath) : [options.localBaseBinPath].map(getLocalBinPath);
165
+ const preferLocal = getPreferLocal(options.localBaseBinPath);
144
166
  return new ShellService({
145
167
  verbose: true,
146
168
  cwd,
@@ -150,12 +172,6 @@ function createShellService(options = {}) {
150
172
  });
151
173
  }
152
174
 
153
- // src/services/shell/utils.ts
154
- import { ProcessOutput } from "zx";
155
- function isProcessOutput(value) {
156
- return value instanceof ProcessOutput;
157
- }
158
-
159
175
  // src/version.ts
160
176
  function getVersion(pkg) {
161
177
  return process.env.VERSION || pkg.packageJson.version;
@@ -167,6 +183,7 @@ export {
167
183
  createPkgService,
168
184
  createShellService,
169
185
  cwd,
186
+ getPreferLocal,
170
187
  getVersion,
171
188
  isProcessOutput,
172
189
  isRaw,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/colors.ts","../src/services/pkg.ts","../src/services/shell/create.ts","../src/services/shell/shell.ts","../src/services/shell/utils.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 bold: safe(chalk.bold),\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { findWorkspacePackages, type Project } 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 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 { $ 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 = Object.freeze(options);\n this.#shell = make$(options);\n }\n\n get options() {\n return this.#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 { ProcessOutput } from \"zx\";\n\nexport function isProcessOutput(value: unknown): value is ProcessOutput {\n return value instanceof ProcessOutput;\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","fs","path","cwd","fs","path"]}
1
+ {"version":3,"sources":["../src/colors.ts","../src/services/pkg.ts","../src/services/shell/create.ts","../src/services/shell/shell.ts","../src/services/shell/utils.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 bold: safe(chalk.bold),\n};\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { findWorkspacePackages, type Project } 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 fs from \"node:fs\";\nimport { ShellService } from \"./shell\";\nimport type { CreateOptions } from \"./types\";\nimport { getPreferLocal } from \"./utils\";\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\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 = getPreferLocal(options.localBaseBinPath);\n\n return new ShellService({\n verbose: true,\n cwd,\n preferLocal,\n quote: defaultQuote,\n ...options,\n });\n}\n","import { $ as make$ } from \"zx\";\nimport type { Shell, ShellOptions } from \"./types\";\nimport { getPreferLocal } from \"./utils\";\n\nexport class ShellService {\n #shell: Shell;\n #options: ShellOptions;\n\n constructor(options: ShellOptions) {\n this.#options = Object.freeze(options);\n this.#shell = make$(options);\n }\n\n get options() {\n return this.#options;\n }\n\n get $() {\n return this.#shell;\n }\n\n child(options: ShellOptions) {\n return new ShellService({\n ...this.#options,\n ...options,\n });\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 const getLocals = (locals: boolean | string | string[] | undefined) =>\n // NOTE: the boolean handling is done outside when determining preferLocal\n typeof locals === \"boolean\" ? [] : typeof locals === \"undefined\" ? [] : Array.isArray(locals) ? locals : [locals];\n\n const cwdPreferLocal = getPreferLocal(cwd);\n\n const preferLocal =\n options?.preferLocal === false\n ? false\n : [\n ...getLocals(this.#options.preferLocal),\n ...getLocals(options?.preferLocal),\n ...(cwdPreferLocal ? cwdPreferLocal : []),\n ];\n\n return this.child({\n ...options,\n cwd,\n preferLocal,\n });\n }\n}\n","import path from \"node:path\";\nimport { ProcessOutput } from \"zx\";\n\nexport function isProcessOutput(value: unknown): value is ProcessOutput {\n return value instanceof ProcessOutput;\n}\n\nconst getLocalBinPath = (dirPath: string) => path.join(dirPath, \"node_modules\", \".bin\");\n\nexport function getPreferLocal(localBaseBinPath: string | Array<string> | undefined) {\n return !localBaseBinPath\n ? undefined\n : Array.isArray(localBaseBinPath)\n ? localBaseBinPath.map(getLocalBinPath)\n : [localBaseBinPath].map(getLocalBinPath);\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","fs","path","cwd","fs"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vlandoss/clibuddy",
3
- "version": "0.0.5-git-a15eb4f.0",
3
+ "version": "0.0.6-git-5566e2b.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": {
@@ -1,7 +1,7 @@
1
1
  import fs from "node:fs";
2
- import path from "node:path";
3
2
  import { ShellService } from "./shell";
4
3
  import type { CreateOptions } from "./types";
4
+ import { getPreferLocal } from "./utils";
5
5
 
6
6
  export const cwd = fs.realpathSync(process.cwd());
7
7
 
@@ -25,8 +25,6 @@ export function quote(arg: string) {
25
25
  export const isRaw = (arg: unknown): arg is { stdout: string } =>
26
26
  typeof arg === "object" && arg !== null && "stdout" in arg && typeof arg.stdout === "string";
27
27
 
28
- const getLocalBinPath = (dirPath: string) => path.join(dirPath, "node_modules", ".bin");
29
-
30
28
  function defaultQuote(arg: unknown) {
31
29
  if (typeof arg === "string") {
32
30
  return quote(arg);
@@ -40,11 +38,7 @@ function defaultQuote(arg: unknown) {
40
38
  }
41
39
 
42
40
  export function createShellService(options: CreateOptions = {}) {
43
- const preferLocal = !options.localBaseBinPath
44
- ? undefined
45
- : Array.isArray(options.localBaseBinPath)
46
- ? options.localBaseBinPath.map(getLocalBinPath)
47
- : [options.localBaseBinPath].map(getLocalBinPath);
41
+ const preferLocal = getPreferLocal(options.localBaseBinPath);
48
42
 
49
43
  return new ShellService({
50
44
  verbose: true,
@@ -1,5 +1,6 @@
1
1
  import { $ as make$ } from "zx";
2
2
  import type { Shell, ShellOptions } from "./types";
3
+ import { getPreferLocal } from "./utils";
3
4
 
4
5
  export class ShellService {
5
6
  #shell: Shell;
@@ -18,6 +19,13 @@ export class ShellService {
18
19
  return this.#shell;
19
20
  }
20
21
 
22
+ child(options: ShellOptions) {
23
+ return new ShellService({
24
+ ...this.#options,
25
+ ...options,
26
+ });
27
+ }
28
+
21
29
  quiet(options?: ShellOptions) {
22
30
  return this.child({
23
31
  ...options,
@@ -26,16 +34,25 @@ export class ShellService {
26
34
  }
27
35
 
28
36
  at(cwd: string, options?: ShellOptions) {
37
+ const getLocals = (locals: boolean | string | string[] | undefined) =>
38
+ // NOTE: the boolean handling is done outside when determining preferLocal
39
+ typeof locals === "boolean" ? [] : typeof locals === "undefined" ? [] : Array.isArray(locals) ? locals : [locals];
40
+
41
+ const cwdPreferLocal = getPreferLocal(cwd);
42
+
43
+ const preferLocal =
44
+ options?.preferLocal === false
45
+ ? false
46
+ : [
47
+ ...getLocals(this.#options.preferLocal),
48
+ ...getLocals(options?.preferLocal),
49
+ ...(cwdPreferLocal ? cwdPreferLocal : []),
50
+ ];
51
+
29
52
  return this.child({
30
53
  ...options,
31
54
  cwd,
32
- });
33
- }
34
-
35
- child(options: ShellOptions) {
36
- return new ShellService({
37
- ...this.#options,
38
- ...options,
55
+ preferLocal,
39
56
  });
40
57
  }
41
58
  }
@@ -1,5 +1,16 @@
1
+ import path from "node:path";
1
2
  import { ProcessOutput } from "zx";
2
3
 
3
4
  export function isProcessOutput(value: unknown): value is ProcessOutput {
4
5
  return value instanceof ProcessOutput;
5
6
  }
7
+
8
+ const getLocalBinPath = (dirPath: string) => path.join(dirPath, "node_modules", ".bin");
9
+
10
+ export function getPreferLocal(localBaseBinPath: string | Array<string> | undefined) {
11
+ return !localBaseBinPath
12
+ ? undefined
13
+ : Array.isArray(localBaseBinPath)
14
+ ? localBaseBinPath.map(getLocalBinPath)
15
+ : [localBaseBinPath].map(getLocalBinPath);
16
+ }