@vlandoss/clibuddy 0.0.1

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/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # Clibuddy
2
+
3
+ A helper library to create CLIs in Variable Land
4
+
5
+ ## Installation
6
+
7
+ ```sh
8
+ pnpm add @vlandoss/clibuddy
9
+ ```
package/dist/index.cjs ADDED
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ PkgService: () => PkgService,
34
+ ShellService: () => ShellService,
35
+ colors: () => colors,
36
+ createPkgService: () => createPkgService,
37
+ createShellService: () => createShellService,
38
+ cwd: () => cwd,
39
+ getVersion: () => getVersion,
40
+ isRaw: () => isRaw,
41
+ quote: () => quote
42
+ });
43
+ module.exports = __toCommonJS(index_exports);
44
+
45
+ // src/colors.ts
46
+ var import_chalk = __toESM(require("chalk"), 1);
47
+ var import_supports_color = __toESM(require("supports-color"), 1);
48
+ var colorIsSupported = () => import_supports_color.default.stdout && !Bun.env.NO_COLOR;
49
+ var identity = (x) => x;
50
+ var safe = (style) => colorIsSupported() ? style : identity;
51
+ var colors = {
52
+ blueBright: safe(import_chalk.default.blueBright),
53
+ redBright: safe(import_chalk.default.redBright),
54
+ greenBright: safe(import_chalk.default.greenBright)
55
+ };
56
+
57
+ // src/services/pkg.ts
58
+ var import_node_fs = __toESM(require("fs"), 1);
59
+ var import_node_path = __toESM(require("path"), 1);
60
+ var import_read_package_up = require("read-package-up");
61
+ var PkgService = class {
62
+ #packageJson;
63
+ #dirPath;
64
+ get dirPath() {
65
+ return this.#dirPath;
66
+ }
67
+ get packageJson() {
68
+ return this.#packageJson;
69
+ }
70
+ constructor(packageJson, pkgPath) {
71
+ this.#packageJson = packageJson;
72
+ this.#dirPath = import_node_path.default.dirname(pkgPath);
73
+ }
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
+ info() {
81
+ return {
82
+ packageJson: this.#packageJson,
83
+ dirPath: this.#dirPath
84
+ };
85
+ }
86
+ };
87
+ async function createPkgService(cwd2) {
88
+ const searchResult = await (0, import_read_package_up.readPackageUp)({ cwd: cwd2 });
89
+ if (!searchResult) {
90
+ return null;
91
+ }
92
+ const { packageJson, path: path3 } = searchResult;
93
+ return new PkgService(packageJson, path3);
94
+ }
95
+
96
+ // src/services/shell/shell.ts
97
+ var import_zx = require("zx");
98
+ var ShellService = class {
99
+ #shell;
100
+ constructor(options) {
101
+ this.#shell = Object.assign((0, import_zx.$)(options), {
102
+ quiet: (0, import_zx.$)({ ...options, verbose: false })
103
+ });
104
+ }
105
+ get $() {
106
+ return this.#shell;
107
+ }
108
+ };
109
+
110
+ // src/services/shell/create.ts
111
+ var import_node_fs2 = __toESM(require("fs"), 1);
112
+ var import_node_path2 = __toESM(require("path"), 1);
113
+ var cwd = import_node_fs2.default.realpathSync(process.cwd());
114
+ function quote(arg) {
115
+ if (/^[\w./:=@-]+$/i.test(arg) || arg === "") {
116
+ return arg;
117
+ }
118
+ 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");
119
+ }
120
+ var isRaw = (arg) => typeof arg === "object" && arg !== null && "stdout" in arg && typeof arg.stdout === "string";
121
+ var getLocalBinPath = (dirPath) => import_node_path2.default.join(dirPath, "node_modules", ".bin");
122
+ function defaultQuote(arg) {
123
+ if (typeof arg === "string") {
124
+ return quote(arg);
125
+ }
126
+ if (isRaw(arg)) {
127
+ return arg.stdout;
128
+ }
129
+ throw TypeError(`Unsupported argument type: ${typeof arg}`);
130
+ }
131
+ function createShellService(options = {}) {
132
+ const preferLocal = !options.localBaseBinPath ? void 0 : Array.isArray(options.localBaseBinPath) ? options.localBaseBinPath.map(getLocalBinPath) : [options.localBaseBinPath].map(getLocalBinPath);
133
+ return new ShellService({
134
+ verbose: true,
135
+ cwd,
136
+ preferLocal,
137
+ quote: defaultQuote,
138
+ ...options
139
+ });
140
+ }
141
+
142
+ // src/version.ts
143
+ function getVersion(pkg) {
144
+ return Bun.env.VERSION || pkg.packageJson.version;
145
+ }
146
+ // Annotate the CommonJS export names for ESM import in node:
147
+ 0 && (module.exports = {
148
+ PkgService,
149
+ ShellService,
150
+ colors,
151
+ createPkgService,
152
+ createShellService,
153
+ cwd,
154
+ getVersion,
155
+ isRaw,
156
+ quote
157
+ });
158
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +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"]}
@@ -0,0 +1,46 @@
1
+ import { ChalkInstance } from 'chalk';
2
+ import { NormalizedPackageJson } from 'read-package-up';
3
+ import { Shell as Shell$1, Options } from 'zx';
4
+
5
+ declare const colors: {
6
+ blueBright: (<T>(x: T) => T) | ChalkInstance;
7
+ redBright: (<T>(x: T) => T) | ChalkInstance;
8
+ greenBright: (<T>(x: T) => T) | ChalkInstance;
9
+ };
10
+
11
+ declare class PkgService {
12
+ #private;
13
+ get dirPath(): string;
14
+ get packageJson(): NormalizedPackageJson;
15
+ constructor(packageJson: NormalizedPackageJson, pkgPath: string);
16
+ hasFile(name: string): boolean;
17
+ info(): {
18
+ packageJson: NormalizedPackageJson;
19
+ dirPath: string;
20
+ };
21
+ }
22
+ declare function createPkgService(cwd: string): Promise<PkgService | null>;
23
+
24
+ type ShellOptions = Partial<Options>;
25
+ type Shell = Shell$1 & {
26
+ quiet: Shell$1;
27
+ };
28
+ declare class ShellService {
29
+ #private;
30
+ constructor(options: ShellOptions);
31
+ get $(): Shell;
32
+ }
33
+
34
+ type CreateOptions = {
35
+ localBaseBinPath?: string | Array<string>;
36
+ };
37
+ declare const cwd: string;
38
+ declare function quote(arg: string): string;
39
+ declare const isRaw: (arg: unknown) => arg is {
40
+ stdout: string;
41
+ };
42
+ declare function createShellService(options?: CreateOptions): ShellService;
43
+
44
+ declare function getVersion(pkg: PkgService): string;
45
+
46
+ export { PkgService, type Shell, ShellService, colors, createPkgService, createShellService, cwd, getVersion, isRaw, quote };
@@ -0,0 +1,46 @@
1
+ import { ChalkInstance } from 'chalk';
2
+ import { NormalizedPackageJson } from 'read-package-up';
3
+ import { Shell as Shell$1, Options } from 'zx';
4
+
5
+ declare const colors: {
6
+ blueBright: (<T>(x: T) => T) | ChalkInstance;
7
+ redBright: (<T>(x: T) => T) | ChalkInstance;
8
+ greenBright: (<T>(x: T) => T) | ChalkInstance;
9
+ };
10
+
11
+ declare class PkgService {
12
+ #private;
13
+ get dirPath(): string;
14
+ get packageJson(): NormalizedPackageJson;
15
+ constructor(packageJson: NormalizedPackageJson, pkgPath: string);
16
+ hasFile(name: string): boolean;
17
+ info(): {
18
+ packageJson: NormalizedPackageJson;
19
+ dirPath: string;
20
+ };
21
+ }
22
+ declare function createPkgService(cwd: string): Promise<PkgService | null>;
23
+
24
+ type ShellOptions = Partial<Options>;
25
+ type Shell = Shell$1 & {
26
+ quiet: Shell$1;
27
+ };
28
+ declare class ShellService {
29
+ #private;
30
+ constructor(options: ShellOptions);
31
+ get $(): Shell;
32
+ }
33
+
34
+ type CreateOptions = {
35
+ localBaseBinPath?: string | Array<string>;
36
+ };
37
+ declare const cwd: string;
38
+ declare function quote(arg: string): string;
39
+ declare const isRaw: (arg: unknown) => arg is {
40
+ stdout: string;
41
+ };
42
+ declare function createShellService(options?: CreateOptions): ShellService;
43
+
44
+ declare function getVersion(pkg: PkgService): string;
45
+
46
+ export { PkgService, type Shell, ShellService, colors, createPkgService, createShellService, cwd, getVersion, isRaw, quote };
package/dist/index.js ADDED
@@ -0,0 +1,113 @@
1
+ // src/colors.ts
2
+ import chalk from "chalk";
3
+ import supportsColor from "supports-color";
4
+ var colorIsSupported = () => supportsColor.stdout && !Bun.env.NO_COLOR;
5
+ var identity = (x) => x;
6
+ var safe = (style) => colorIsSupported() ? style : identity;
7
+ var colors = {
8
+ blueBright: safe(chalk.blueBright),
9
+ redBright: safe(chalk.redBright),
10
+ greenBright: safe(chalk.greenBright)
11
+ };
12
+
13
+ // src/services/pkg.ts
14
+ import fs from "node:fs";
15
+ import path from "node:path";
16
+ import { readPackageUp } from "read-package-up";
17
+ var PkgService = class {
18
+ #packageJson;
19
+ #dirPath;
20
+ get dirPath() {
21
+ return this.#dirPath;
22
+ }
23
+ get packageJson() {
24
+ return this.#packageJson;
25
+ }
26
+ constructor(packageJson, pkgPath) {
27
+ this.#packageJson = packageJson;
28
+ this.#dirPath = path.dirname(pkgPath);
29
+ }
30
+ hasFile(name) {
31
+ return fs.existsSync(this.#fromApp(name));
32
+ }
33
+ #fromApp(...args) {
34
+ return path.join(this.#dirPath, ...args);
35
+ }
36
+ info() {
37
+ return {
38
+ packageJson: this.#packageJson,
39
+ dirPath: this.#dirPath
40
+ };
41
+ }
42
+ };
43
+ async function createPkgService(cwd2) {
44
+ const searchResult = await readPackageUp({ cwd: cwd2 });
45
+ if (!searchResult) {
46
+ return null;
47
+ }
48
+ const { packageJson, path: path3 } = searchResult;
49
+ return new PkgService(packageJson, path3);
50
+ }
51
+
52
+ // src/services/shell/shell.ts
53
+ import { $ as make$ } from "zx";
54
+ var ShellService = class {
55
+ #shell;
56
+ constructor(options) {
57
+ this.#shell = Object.assign(make$(options), {
58
+ quiet: make$({ ...options, verbose: false })
59
+ });
60
+ }
61
+ get $() {
62
+ return this.#shell;
63
+ }
64
+ };
65
+
66
+ // src/services/shell/create.ts
67
+ import fs2 from "node:fs";
68
+ import path2 from "node:path";
69
+ var cwd = fs2.realpathSync(process.cwd());
70
+ function quote(arg) {
71
+ if (/^[\w./:=@-]+$/i.test(arg) || arg === "") {
72
+ return arg;
73
+ }
74
+ 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");
75
+ }
76
+ var isRaw = (arg) => typeof arg === "object" && arg !== null && "stdout" in arg && typeof arg.stdout === "string";
77
+ var getLocalBinPath = (dirPath) => path2.join(dirPath, "node_modules", ".bin");
78
+ function defaultQuote(arg) {
79
+ if (typeof arg === "string") {
80
+ return quote(arg);
81
+ }
82
+ if (isRaw(arg)) {
83
+ return arg.stdout;
84
+ }
85
+ throw TypeError(`Unsupported argument type: ${typeof arg}`);
86
+ }
87
+ function createShellService(options = {}) {
88
+ const preferLocal = !options.localBaseBinPath ? void 0 : Array.isArray(options.localBaseBinPath) ? options.localBaseBinPath.map(getLocalBinPath) : [options.localBaseBinPath].map(getLocalBinPath);
89
+ return new ShellService({
90
+ verbose: true,
91
+ cwd,
92
+ preferLocal,
93
+ quote: defaultQuote,
94
+ ...options
95
+ });
96
+ }
97
+
98
+ // src/version.ts
99
+ function getVersion(pkg) {
100
+ return Bun.env.VERSION || pkg.packageJson.version;
101
+ }
102
+ export {
103
+ PkgService,
104
+ ShellService,
105
+ colors,
106
+ createPkgService,
107
+ createShellService,
108
+ cwd,
109
+ getVersion,
110
+ isRaw,
111
+ quote
112
+ };
113
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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":"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","names":["cwd","path","fs","path","fs","path"]}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@vlandoss/clibuddy",
3
+ "version": "0.0.1",
4
+ "description": "A helper library to create CLIs in Variable Land",
5
+ "homepage": "https://github.com/variableland/dx/tree/main/packages/clibuddy#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/variableland/dx/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/variableland/dx.git"
12
+ },
13
+ "license": "MIT",
14
+ "author": "rcrd <rcrd@variable.land>",
15
+ "type": "module",
16
+ "exports": {
17
+ ".": {
18
+ "bun": "./src/index.ts",
19
+ "import": "./dist/index.js",
20
+ "require": "./dist/index.cjs",
21
+ "default": "./dist/index.js"
22
+ },
23
+ "./test-helpers": {
24
+ "bun": "./test-helpers/index.ts"
25
+ }
26
+ },
27
+ "main": "./dist/index.cjs",
28
+ "module": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "files": [
31
+ "dist",
32
+ "src"
33
+ ],
34
+ "dependencies": {
35
+ "chalk": "5.4.1",
36
+ "read-package-up": "11.0.0",
37
+ "supports-color": "10.0.0",
38
+ "zx": "8.4.0"
39
+ },
40
+ "publishConfig": {
41
+ "access": "public"
42
+ },
43
+ "engines": {
44
+ "bun": ">=1.0.0"
45
+ },
46
+ "scripts": {
47
+ "build": "tsup",
48
+ "typecheck": "rr tsc"
49
+ }
50
+ }
package/src/colors.ts ADDED
@@ -0,0 +1,14 @@
1
+ import chalk, { type ChalkInstance } from "chalk";
2
+ import supportsColor from "supports-color";
3
+
4
+ // https://no-color.org/
5
+ const colorIsSupported = () => supportsColor.stdout && !Bun.env.NO_COLOR;
6
+
7
+ const identity = <T>(x: T) => x;
8
+ const safe = (style: ChalkInstance) => (colorIsSupported() ? style : identity);
9
+
10
+ export const colors = {
11
+ blueBright: safe(chalk.blueBright),
12
+ redBright: safe(chalk.redBright),
13
+ greenBright: safe(chalk.greenBright),
14
+ };
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./colors";
2
+ export * from "./services";
3
+ export * from "./version";
@@ -0,0 +1,2 @@
1
+ export * from "./pkg";
2
+ export * from "./shell";
@@ -0,0 +1,48 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { type NormalizedPackageJson, readPackageUp } from "read-package-up";
4
+
5
+ export class PkgService {
6
+ #packageJson: NormalizedPackageJson;
7
+ #dirPath: string;
8
+
9
+ get dirPath() {
10
+ return this.#dirPath;
11
+ }
12
+
13
+ get packageJson() {
14
+ return this.#packageJson;
15
+ }
16
+
17
+ constructor(packageJson: NormalizedPackageJson, pkgPath: string) {
18
+ this.#packageJson = packageJson;
19
+ this.#dirPath = path.dirname(pkgPath);
20
+ }
21
+
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
+ info() {
31
+ return {
32
+ packageJson: this.#packageJson,
33
+ dirPath: this.#dirPath,
34
+ };
35
+ }
36
+ }
37
+
38
+ export async function createPkgService(cwd: string): Promise<PkgService | null> {
39
+ const searchResult = await readPackageUp({ cwd });
40
+
41
+ if (!searchResult) {
42
+ return null;
43
+ }
44
+
45
+ const { packageJson, path } = searchResult;
46
+
47
+ return new PkgService(packageJson, path);
48
+ }
@@ -0,0 +1,59 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { ShellService } from "./shell";
4
+
5
+ type CreateOptions = {
6
+ localBaseBinPath?: string | Array<string>;
7
+ };
8
+
9
+ export const cwd = fs.realpathSync(process.cwd());
10
+
11
+ // Inspired by https://dub.sh/6tiHVgn
12
+ export function quote(arg: string) {
13
+ if (/^[\w./:=@-]+$/i.test(arg) || arg === "") {
14
+ return arg;
15
+ }
16
+
17
+ return arg
18
+ .replace(/\\/g, "\\\\")
19
+ .replace(/'/g, "\\'")
20
+ .replace(/\f/g, "\\f")
21
+ .replace(/\n/g, "\\n")
22
+ .replace(/\r/g, "\\r")
23
+ .replace(/\t/g, "\\t")
24
+ .replace(/\v/g, "\\v")
25
+ .replace(/\0/g, "\\0");
26
+ }
27
+
28
+ export const isRaw = (arg: unknown): arg is { stdout: string } =>
29
+ typeof arg === "object" && arg !== null && "stdout" in arg && typeof arg.stdout === "string";
30
+
31
+ const getLocalBinPath = (dirPath: string) => path.join(dirPath, "node_modules", ".bin");
32
+
33
+ function defaultQuote(arg: unknown) {
34
+ if (typeof arg === "string") {
35
+ return quote(arg);
36
+ }
37
+
38
+ if (isRaw(arg)) {
39
+ return arg.stdout;
40
+ }
41
+
42
+ throw TypeError(`Unsupported argument type: ${typeof arg}`);
43
+ }
44
+
45
+ export function createShellService(options: CreateOptions = {}) {
46
+ const preferLocal = !options.localBaseBinPath
47
+ ? undefined
48
+ : Array.isArray(options.localBaseBinPath)
49
+ ? options.localBaseBinPath.map(getLocalBinPath)
50
+ : [options.localBaseBinPath].map(getLocalBinPath);
51
+
52
+ return new ShellService({
53
+ verbose: true,
54
+ cwd,
55
+ preferLocal,
56
+ quote: defaultQuote,
57
+ ...options,
58
+ });
59
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./shell";
2
+ export * from "./create";
@@ -0,0 +1,19 @@
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 };
6
+
7
+ export class ShellService {
8
+ #shell: Shell;
9
+
10
+ constructor(options: ShellOptions) {
11
+ this.#shell = Object.assign(make$(options), {
12
+ quiet: make$({ ...options, verbose: false }),
13
+ });
14
+ }
15
+
16
+ get $() {
17
+ return this.#shell;
18
+ }
19
+ }
package/src/version.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { PkgService } from "./services";
2
+
3
+ export function getVersion(pkg: PkgService) {
4
+ return Bun.env.VERSION || pkg.packageJson.version;
5
+ }