hereya-cli 0.100.2 → 0.100.3

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.
@@ -1,5 +1,5 @@
1
- import { spawn } from 'node:child_process';
2
- import { runShell } from './shell.js';
1
+ import spawn from 'cross-spawn';
2
+ import { buildGitCredentialHelperValue, runShell } from './shell.js';
3
3
  export const gitUtils = {
4
4
  /**
5
5
  * Clones a git repository using the hereya credential helper.
@@ -104,7 +104,7 @@ export async function cloneWithCredentialHelper(input) {
104
104
  const { gitUrl, hereyaBinPath, password, targetDir, username } = input;
105
105
  // Build the credential helper config
106
106
  // The ! prefix tells git to treat it as a shell command
107
- const credHelper = `!${hereyaBinPath} credential-helper`;
107
+ const credHelper = buildGitCredentialHelperValue(hereyaBinPath);
108
108
  return new Promise((resolve) => {
109
109
  const env = { ...process.env };
110
110
  if (username)
@@ -140,7 +140,7 @@ export async function cloneWithCredentialHelper(input) {
140
140
  }
141
141
  export async function setupCredentialHelper(input) {
142
142
  const { hereyaBinPath, projectDir } = input;
143
- const credHelper = `!${hereyaBinPath} credential-helper`;
143
+ const credHelper = buildGitCredentialHelperValue(hereyaBinPath);
144
144
  const runGitConfig = (args) => new Promise((resolve, reject) => {
145
145
  const child = spawn('git', args, { cwd: projectDir, stdio: 'pipe' });
146
146
  child.on('close', (code) => {
@@ -39,3 +39,23 @@ export declare const shellUtils: {
39
39
  runShell: typeof runShell;
40
40
  };
41
41
  export declare function delay(ms: number): Promise<unknown> | undefined;
42
+ /**
43
+ * Builds a shell-safe command string that invokes the hereya CLI. Suitable
44
+ * for embedding in git credential-helper config strings, SSH ProxyCommand
45
+ * lines, and anywhere else an external tool re-parses our command through
46
+ * a POSIX shell or cmd.exe.
47
+ *
48
+ * - If `binPath` ends in `.js`, prepend the absolute path of the current
49
+ * Node executable (`process.execPath`) so the helper works without
50
+ * depending on `.js` being executable.
51
+ * - Path-like tokens are normalized to forward slashes and wrapped in
52
+ * double quotes to survive spaces and Windows backslashes.
53
+ * - Args are emitted bare unless they contain whitespace, quotes, or
54
+ * backslashes.
55
+ */
56
+ export declare function buildHereyaShellCommand(binPath: string, args: string[]): string;
57
+ /**
58
+ * Builds the value for git's `credential.helper` config when the helper
59
+ * is a shell command. Git requires a leading `!` for shell-command helpers.
60
+ */
61
+ export declare function buildGitCredentialHelperValue(binPath: string, subcommand?: string): string;
package/dist/lib/shell.js CHANGED
@@ -106,3 +106,58 @@ export function delay(ms) {
106
106
  setTimeout(resolve, ms);
107
107
  });
108
108
  }
109
+ /**
110
+ * Quote a path-like token so it survives re-parsing by a POSIX shell or
111
+ * cmd.exe. Backslashes are normalized to forward slashes (Windows OpenSSH
112
+ * and Git for Windows' msys bash both accept forward-slash absolute paths
113
+ * like `C:/Users/…`). Embedded double quotes are escaped as `\"`.
114
+ */
115
+ function quotePath(p) {
116
+ const normalized = p.replaceAll('\\', '/');
117
+ const escaped = normalized.replaceAll('"', String.raw `\"`);
118
+ return `"${escaped}"`;
119
+ }
120
+ /**
121
+ * Quote a plain CLI argument. Bare args stay bare unless they contain a
122
+ * space, a double quote, or a backslash — keeping the macOS/Linux output
123
+ * close to today's (e.g. `devenv ssh-proxy -w my-ws` stays bare).
124
+ */
125
+ function quoteArg(arg) {
126
+ if (arg === '' || /[\s"\\]/.test(arg)) {
127
+ const escaped = arg.replaceAll('\\', String.raw `\\`).replaceAll('"', String.raw `\"`);
128
+ return `"${escaped}"`;
129
+ }
130
+ return arg;
131
+ }
132
+ /**
133
+ * Builds a shell-safe command string that invokes the hereya CLI. Suitable
134
+ * for embedding in git credential-helper config strings, SSH ProxyCommand
135
+ * lines, and anywhere else an external tool re-parses our command through
136
+ * a POSIX shell or cmd.exe.
137
+ *
138
+ * - If `binPath` ends in `.js`, prepend the absolute path of the current
139
+ * Node executable (`process.execPath`) so the helper works without
140
+ * depending on `.js` being executable.
141
+ * - Path-like tokens are normalized to forward slashes and wrapped in
142
+ * double quotes to survive spaces and Windows backslashes.
143
+ * - Args are emitted bare unless they contain whitespace, quotes, or
144
+ * backslashes.
145
+ */
146
+ export function buildHereyaShellCommand(binPath, args) {
147
+ const tokens = [];
148
+ if (binPath.toLowerCase().endsWith('.js')) {
149
+ tokens.push(quotePath(process.execPath));
150
+ }
151
+ tokens.push(quotePath(binPath));
152
+ for (const arg of args) {
153
+ tokens.push(quoteArg(arg));
154
+ }
155
+ return tokens.join(' ');
156
+ }
157
+ /**
158
+ * Builds the value for git's `credential.helper` config when the helper
159
+ * is a shell command. Git requires a leading `!` for shell-command helpers.
160
+ */
161
+ export function buildGitCredentialHelperValue(binPath, subcommand = 'credential-helper') {
162
+ return '!' + buildHereyaShellCommand(binPath, [subcommand]);
163
+ }