bunosh 0.3.2 → 0.4.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.
@@ -4,13 +4,45 @@ import Printer from "../printer.js";
4
4
  const isBun = typeof Bun !== 'undefined' && typeof Bun.spawn === 'function';
5
5
 
6
6
  export default function shell(strings, ...values) {
7
+ let envs = null;
8
+ let cwd = null;
9
+
10
+ // Check if called as regular function instead of template literal
11
+ if (!Array.isArray(strings)) {
12
+ // If first argument is a string, treat it as the command
13
+ if (typeof strings === 'string') {
14
+ // For Bun shell, we need to create a template literal-like call
15
+ // But since we can't, fall back to exec
16
+ console.log('Note: shell() with string argument falls back to exec()');
17
+ const cmdPromise = (async () => {
18
+ const { default: exec } = await import("./exec.js");
19
+ let execPromise = exec(strings);
20
+ if (envs) execPromise = execPromise.env(envs);
21
+ if (cwd) execPromise = execPromise.cwd(cwd);
22
+ return execPromise;
23
+ })();
24
+
25
+ // Add .env and .cwd methods
26
+ cmdPromise.env = (newEnvs) => {
27
+ envs = newEnvs;
28
+ return cmdPromise;
29
+ };
30
+
31
+ cmdPromise.cwd = (newCwd) => {
32
+ cwd = newCwd;
33
+ return cmdPromise;
34
+ };
35
+
36
+ return cmdPromise;
37
+ } else {
38
+ throw new Error('shell() must be called as a template literal: shell`command`');
39
+ }
40
+ }
41
+
7
42
  const cmd = strings.reduce((accumulator, str, i) => {
8
43
  return accumulator + str + (values[i] || "");
9
44
  }, "");
10
45
 
11
- let envs = null;
12
- let cwd = null;
13
-
14
46
  const cmdPromise = new Promise(async (resolve, reject) => {
15
47
  const extraInfo = {};
16
48
  if (cwd) extraInfo.cwd = cwd;
@@ -18,7 +50,7 @@ export default function shell(strings, ...values) {
18
50
 
19
51
  if (!isBun) {
20
52
  const { default: exec } = await import("./exec.js");
21
- let execPromise = exec(strings, ...values);
53
+ let execPromise = exec([cmd]);
22
54
  if (envs) execPromise = execPromise.env(envs);
23
55
  if (cwd) execPromise = execPromise.cwd(cwd);
24
56
  const result = await execPromise;
@@ -64,7 +96,7 @@ export default function shell(strings, ...values) {
64
96
  finishTaskInfo(taskInfo, true, null, "fallback to exec");
65
97
 
66
98
  const { default: exec } = await import("./exec.js");
67
- let execPromise = exec`${cmd}`;
99
+ let execPromise = exec([cmd]);
68
100
  if (envs) execPromise = execPromise.env(envs);
69
101
  if (cwd) execPromise = execPromise.cwd(cwd);
70
102
  const result = await execPromise;
@@ -1,95 +0,0 @@
1
- import { spawn } from 'child_process';
2
- import path from 'path';
3
-
4
- export default function openEditor(files, options = {}) {
5
- if (!Array.isArray(files) || files.length === 0) {
6
- throw new Error('Files array is required and cannot be empty');
7
- }
8
-
9
- const editor = options.editor || getDefaultEditor();
10
- const fileArgs = buildEditorArgs(editor, files);
11
-
12
- return new Promise((resolve, reject) => {
13
- const child = spawn(editor, fileArgs, {
14
- stdio: 'inherit',
15
- detached: true
16
- });
17
-
18
- child.on('error', (err) => {
19
- reject(new Error(`Failed to open editor '${editor}': ${err.message}`));
20
- });
21
-
22
- child.on('spawn', () => {
23
- resolve();
24
- });
25
-
26
- if (child.pid) {
27
- child.unref();
28
- }
29
- });
30
- }
31
-
32
- function getDefaultEditor() {
33
- if (process.env.EDITOR) {
34
- return process.env.EDITOR;
35
- }
36
-
37
- const editors = ['code', 'subl', 'atom', 'vim', 'nvim', 'nano', 'gedit'];
38
-
39
- for (const editor of editors) {
40
- if (isCommandAvailable(editor)) {
41
- return editor;
42
- }
43
- }
44
-
45
- return process.platform === 'win32' ? 'notepad' : 'vi';
46
- }
47
-
48
- function isCommandAvailable(command) {
49
- try {
50
- const { execSync } = require('child_process');
51
- execSync(`which ${command}`, { stdio: 'ignore' });
52
- return true;
53
- } catch {
54
- return false;
55
- }
56
- }
57
-
58
- function buildEditorArgs(editor, files) {
59
- const editorName = path.basename(editor);
60
- const args = [];
61
-
62
- for (const fileInfo of files) {
63
- const filePath = typeof fileInfo === 'string' ? fileInfo : fileInfo.file;
64
-
65
- if (!filePath) {
66
- continue;
67
- }
68
-
69
- if (fileInfo.line && typeof fileInfo === 'object') {
70
- switch (editorName) {
71
- case 'code':
72
- case 'code-insiders':
73
- args.push('--goto', `${filePath}:${fileInfo.line}:${fileInfo.column || 1}`);
74
- break;
75
- case 'subl':
76
- case 'sublime_text':
77
- args.push(`${filePath}:${fileInfo.line}:${fileInfo.column || 1}`);
78
- break;
79
- case 'vim':
80
- case 'nvim':
81
- args.push(`+${fileInfo.line}`, filePath);
82
- break;
83
- case 'nano':
84
- args.push(`+${fileInfo.line}`, filePath);
85
- break;
86
- default:
87
- args.push(filePath);
88
- }
89
- } else {
90
- args.push(filePath);
91
- }
92
- }
93
-
94
- return args;
95
- }