@gjsify/child_process 0.4.35 → 0.4.36

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/lib/esm/index.js CHANGED
@@ -1 +1 @@
1
- import"./_virtual/_rolldown/runtime.js";import e from"@girs/gio-2.0";import t from"@girs/glib-2.0";import{EventEmitter as n}from"node:events";import{Buffer as r}from"node:buffer";import{Readable as i,Writable as a}from"node:stream";import{deferEmit as o,ensureMainLoop as s,gbytesToUint8Array as c}from"@gjsify/utils";var GioInputStreamReadable=class extends i{_stream;_cancellable=new e.Cancellable;constructor(e){super(),this._stream=e}_read(e){this._stream.read_bytes_async(Math.max(e,4096),t.PRIORITY_DEFAULT,this._cancellable,(e,t)=>{try{let e=this._stream.read_bytes_finish(t).get_data();!e||e.length===0?this.push(null):this.push(r.from(e))}catch(e){this._cancellable.is_cancelled()||this.destroy(e)}})}_destroy(e,t){this._cancellable.cancel(),t(e)}},GioOutputStreamWritable=class extends a{_stream;_cancellable=new e.Cancellable;_closed=!1;constructor(e){super(),this._stream=e}_write(e,n,i){if(this._closed){i(Error(`write after end`));return}let a=typeof e==`string`?r.from(e):e instanceof Uint8Array?e:r.from(e);this._stream.write_bytes_async(new t.Bytes(a),t.PRIORITY_DEFAULT,this._cancellable,(e,t)=>{try{this._stream.write_bytes_finish(t),i()}catch(e){this._cancellable.is_cancelled()?i():i(e)}})}_final(e){if(this._closed){e();return}this._closed=!0;try{this._stream.close(null)}catch{}e()}_destroy(e,t){if(this._cancellable.cancel(),!this._closed){this._closed=!0;try{this._stream.close(null)}catch{}}t(e)}};const l=new Set;var ChildProcess=class extends n{pid;exitCode=null;signalCode=null;killed=!1;connected=!1;stdin=null;stdout=null;stderr=null;get stdio(){return[this.stdin,this.stdout,this.stderr]}_subprocess=null;_setSubprocess(e){this._subprocess=e;let t=e.get_identifier();t&&(this.pid=parseInt(t,10))}kill(e){if(!this._subprocess)return!1;try{return e===`SIGKILL`||e===9?this._subprocess.force_exit():this._subprocess.send_signal(typeof e==`number`?e:15),this.killed=!0,!0}catch{return!1}}ref(){return this}unref(){return this}};function _spawnSubprocess(t,n,r){let i=new e.SubprocessLauncher({flags:n});if(r?.cwd&&i.set_cwd(r.cwd),r?.env)for(let[e,t]of Object.entries(r.env))i.setenv(e,t,!0);return i.spawnv(t)}function execSync(n,i){let a=i?.encoding,o=i?.input,s=e.SubprocessFlags.STDOUT_PIPE|e.SubprocessFlags.STDERR_PIPE|(o?e.SubprocessFlags.STDIN_PIPE:e.SubprocessFlags.NONE),l=_spawnSubprocess([typeof i?.shell==`string`?i.shell:`/bin/sh`,`-c`,n],s,i),u=o?new t.Bytes(typeof o==`string`?new TextEncoder().encode(o):o):null,[,d,f]=l.communicate(u,null),p=l.get_exit_status();if(p!==0){let e=f?new TextDecoder().decode(c(f)):``,t=Error(`Command failed: ${n}\n${e}`);throw t.status=p,t.stderr=e,t.stdout=d?new TextDecoder().decode(c(d)):``,t}if(!d)return a&&a!==`buffer`?``:r.alloc(0);let m=c(d);return a&&a!==`buffer`?new TextDecoder().decode(m):r.from(m)}function _exec(t,n,r){typeof n==`function`&&(r=n,n={});let i=n||{},a=new ChildProcess,o=typeof i.shell==`string`?i.shell:`/bin/sh`,c=e.SubprocessFlags.STDOUT_PIPE|e.SubprocessFlags.STDERR_PIPE;try{let e=_spawnSubprocess([o,`-c`,t],c,i);a._setSubprocess(e),s(),e.communicate_utf8_async(null,null,(n,i)=>{try{let[,n,o]=e.communicate_utf8_finish(i),s=e.get_exit_status();if(a.exitCode=s,s!==0){let e=Error(`Command failed: ${t}`);e.code=s,e.killed=a.killed,e.stdout=n||``,e.stderr=o||``,r&&r(e,n||``,o||``)}else r&&r(null,n||``,o||``);a.emit(`close`,s,null),a.emit(`exit`,s,null)}catch(e){let t=e instanceof Error?e:Error(String(e));r&&r(t,``,``),a.emit(`error`,t)}})}catch(e){let t=e instanceof Error?e:Error(String(e));setTimeout(()=>{r&&r(t,``,``),a.emit(`error`,t)},0)}return a}function execFile(t,n,r,i){let a=[],o={},c;typeof n==`function`?c=n:Array.isArray(n)&&(a=n,typeof r==`function`?c=r:(o=r||{},c=i));let l=new ChildProcess,u=e.SubprocessFlags.STDOUT_PIPE|e.SubprocessFlags.STDERR_PIPE;try{let e=_spawnSubprocess([t,...a],u,o);l._setSubprocess(e),s(),e.communicate_utf8_async(null,null,(n,r)=>{try{let[,n,i]=e.communicate_utf8_finish(r),a=e.get_exit_status();if(l.exitCode=a,a!==0){let e=Error(`Command failed: ${t}`);e.code=a,e.stdout=n||``,e.stderr=i||``,c&&c(e,n||``,i||``)}else c&&c(null,n||``,i||``);l.emit(`close`,a,null),l.emit(`exit`,a,null)}catch(e){let t=e instanceof Error?e:Error(String(e));c&&c(t,``,``),l.emit(`error`,t)}})}catch(e){let t=e instanceof Error?e:Error(String(e));setTimeout(()=>{c&&c(t,``,``),l.emit(`error`,t)},0)}return l}function execFileSync(n,i,a){let o=i||[],s=a?.encoding,l=a?.input,u=e.SubprocessFlags.STDOUT_PIPE|e.SubprocessFlags.STDERR_PIPE|(l?e.SubprocessFlags.STDIN_PIPE:e.SubprocessFlags.NONE),d=_spawnSubprocess([n,...o],u,a),f=l?new t.Bytes(typeof l==`string`?new TextEncoder().encode(l):l):null,[,p,m]=d.communicate(f,null),h=d.get_exit_status();if(h!==0){let e=m?new TextDecoder().decode(c(m)):``,t=Error(`Command failed: ${n} ${o.join(` `)}`);throw t.status=h,t.stderr=e,t}if(!p)return s&&s!==`buffer`?``:r.alloc(0);let g=c(p);return s&&s!==`buffer`?new TextDecoder().decode(g):r.from(g)}function spawn(t,n,r){let i,a;Array.isArray(n)?(i=n,a=r):(i=void 0,a=n);let c=i||[],u=new ChildProcess,d=a?.shell,f;f=d?[typeof d==`string`?d:`/bin/sh`,`-c`,[t,...c].join(` `)]:[t,...c];let p=a?.stdio,m=Array.isArray(p)?[typeof p[0]==`string`?p[0]:`pipe`,typeof p[1]==`string`?p[1]:`pipe`,typeof p[2]==`string`?p[2]:`pipe`]:typeof p==`string`?[p,p,p]:[`pipe`,`pipe`,`pipe`],h=e.SubprocessFlags.NONE;m[0]===`pipe`?h|=e.SubprocessFlags.STDIN_PIPE:m[0]===`inherit`&&(h|=e.SubprocessFlags.STDIN_INHERIT),m[1]===`pipe`&&(h|=e.SubprocessFlags.STDOUT_PIPE),m[1]===`ignore`&&(h|=e.SubprocessFlags.STDOUT_SILENCE),m[2]===`pipe`&&(h|=e.SubprocessFlags.STDERR_PIPE),m[2]===`ignore`&&(h|=e.SubprocessFlags.STDERR_SILENCE);try{let e=_spawnSubprocess(f,h,a);if(u._setSubprocess(e),l.add(u),m[0]===`pipe`){let t=e.get_stdin_pipe();t&&(u.stdin=new GioOutputStreamWritable(t))}let t=e.get_stdout_pipe();t&&(u.stdout=new GioInputStreamReadable(t));let n=e.get_stderr_pipe();n&&(u.stderr=new GioInputStreamReadable(n));let r=a?.signal,i=null,emitAbortError=()=>{let e=a?.killSignal??`SIGTERM`;u.kill(e);let t=Error(`The operation was aborted`);t.name=`AbortError`,u.emit(`error`,t)};r&&(r.aborted?queueMicrotask(emitAbortError):(i=emitAbortError,r.addEventListener(`abort`,i,{once:!0}))),s(),e.wait_async(null,(t,n)=>{try{e.wait_finish(n);let t=e.get_if_exited()?e.get_exit_status():null,a=e.get_if_signaled()?`SIGTERM`:null;u.exitCode=t,u.signalCode=a,r&&i&&r.removeEventListener(`abort`,i),u.stdin&&!u.stdin.destroyed&&u.stdin.destroy(),u.emit(`exit`,t,a),u.emit(`close`,t,a)}catch(e){u.emit(`error`,e instanceof Error?e:Error(String(e)))}l.delete(u)}),o(u,`spawn`)}catch(e){o(u,`error`,e instanceof Error?e:Error(String(e)))}return u}function spawnSync(n,i,a){let o,s;Array.isArray(i)?(o=i,s=a):(o=void 0,s=i);let l=o||[],u=s?.shell,d=s?.input,f;f=u?[typeof u==`string`?u:`/bin/sh`,`-c`,[n,...l].join(` `)]:[n,...l];let p=e.SubprocessFlags.STDOUT_PIPE|e.SubprocessFlags.STDERR_PIPE|(d?e.SubprocessFlags.STDIN_PIPE:e.SubprocessFlags.NONE);try{let e=_spawnSubprocess(f,p,s),n=e.get_identifier(),i=d?new t.Bytes(typeof d==`string`?new TextEncoder().encode(d):d):null,[,a,o]=e.communicate(i,null),l=a?r.from(c(a)):r.alloc(0),u=o?r.from(c(o)):r.alloc(0),m=s?.encoding,h=m&&m!==`buffer`?new TextDecoder().decode(l):l,g=m&&m!==`buffer`?new TextDecoder().decode(u):u,_=e.get_if_exited()?e.get_exit_status():null,v=e.get_if_signaled()?`SIGTERM`:null;return{pid:n?parseInt(n,10):0,output:[null,h,g],stdout:h,stderr:g,status:_,signal:v}}catch(e){let t=s?.encoding&&s.encoding!==`buffer`?``:r.alloc(0);return{pid:0,output:[null,t,t],stdout:t,stderr:t,status:null,signal:null,error:e instanceof Error?e:Error(String(e))}}}var u={ChildProcess,exec:_exec,execSync,execFile,execFileSync,spawn,spawnSync};export{ChildProcess,u as default,_exec as exec,execFile,execFileSync,execSync,spawn,spawnSync};
1
+ import"./_virtual/_rolldown/runtime.js";import e from"@girs/gio-2.0";import t from"@girs/glib-2.0";import{EventEmitter as n}from"node:events";import{Buffer as r}from"node:buffer";import{Readable as i,Writable as a}from"node:stream";import{fileURLToPath as o}from"node:url";import{deferEmit as s,ensureMainLoop as c,gbytesToUint8Array as l}from"@gjsify/utils";var GioInputStreamReadable=class extends i{_stream;_cancellable=new e.Cancellable;constructor(e){super(),this._stream=e}_read(e){this._stream.read_bytes_async(Math.max(e,4096),t.PRIORITY_DEFAULT,this._cancellable,(e,t)=>{try{let e=this._stream.read_bytes_finish(t).get_data();!e||e.length===0?this.push(null):this.push(r.from(e))}catch(e){this._cancellable.is_cancelled()||this.destroy(e)}})}_destroy(e,t){this._cancellable.cancel(),t(e)}},GioOutputStreamWritable=class extends a{_stream;_cancellable=new e.Cancellable;_closed=!1;constructor(e){super(),this._stream=e}_write(e,n,i){if(this._closed){i(Error(`write after end`));return}let a=typeof e==`string`?r.from(e):e instanceof Uint8Array?e:r.from(e);this._stream.write_bytes_async(new t.Bytes(a),t.PRIORITY_DEFAULT,this._cancellable,(e,t)=>{try{this._stream.write_bytes_finish(t),i()}catch(e){this._cancellable.is_cancelled()?i():i(e)}})}_final(e){if(this._closed){e();return}this._closed=!0;try{this._stream.close(null)}catch{}e()}_destroy(e,t){if(this._cancellable.cancel(),!this._closed){this._closed=!0;try{this._stream.close(null)}catch{}}t(e)}};function _gioErrorToNodeError(e,n,r){let i=e??Error(`Unknown spawn error`),a=i,o=i.code,s=i.matches,c=!1;if(typeof s==`function`)try{c=s.call(i,t.SpawnError,t.SpawnError.NOENT)===!0}catch{}if(!c&&o===t.SpawnError.NOENT&&(c=!0),!c&&typeof i.message==`string`&&/No such file or directory|ENOENT|Failed to execute|nicht gefunden|nicht ausgeführt/i.test(i.message)&&(c=!0),c){let e=Error(`spawn ${n} ENOENT`);return e.code=`ENOENT`,e.errno=-2,e.syscall=`spawn ${n}`,e.path=n,e.spawnargs=r.slice(),e}if(i instanceof Error)return a;let l=i,u=typeof l.message==`string`?l.message:String(i),d=Error(u);return(typeof o==`number`||typeof o==`string`)&&(d.code=o),d}const u=new Set;var ChildProcess=class extends n{pid;exitCode=null;signalCode=null;killed=!1;connected=!1;stdin=null;stdout=null;stderr=null;get stdio(){return[this.stdin,this.stdout,this.stderr]}_subprocess=null;_setSubprocess(e){this._subprocess=e;let t=e.get_identifier();t&&(this.pid=parseInt(t,10))}kill(e){if(!this._subprocess)return!1;try{let t=e??`SIGTERM`;return t===`SIGKILL`||t===9?this._subprocess.force_exit():typeof t==`number`?this._subprocess.send_signal(t):this._subprocess.send_signal({SIGHUP:1,SIGINT:2,SIGQUIT:3,SIGABRT:6,SIGKILL:9,SIGUSR1:10,SIGUSR2:12,SIGTERM:15}[t]??15),this.killed=!0,!0}catch{return!1}}ref(){return this}unref(){return this}};function _normalizeCwd(e){if(e!=null){if(typeof e==`string`)return e;if(typeof e==`object`&&e&&typeof e.href==`string`&&typeof e.protocol==`string`){let t=e;if(t.protocol!==`file:`)throw TypeError(`The URL must be of scheme file:; received '${t.protocol}' for 'options.cwd'`);return o(t)}return e instanceof Uint8Array?new TextDecoder().decode(e):String(e)}}function _encodeEnvValue(e){if(e!==void 0)return`${e}`}function _spawnSubprocess(t,n,r){let i=new e.SubprocessLauncher({flags:n}),a=_normalizeCwd(r?.cwd);if(a!==void 0&&i.set_cwd(a),r?.env){let e=r.env;i.set_environ([]);let t=new Set;for(let n in e){if(t.has(n))continue;t.add(n);let r=_encodeEnvValue(e[n]);r!==void 0&&i.setenv(n,r,!0)}}let o=t;if(r?.argv0!==void 0&&r.argv0!==null){if(typeof r.argv0!=`string`)throw TypeError(`The "options.argv0" property must be of type string. Received type ${typeof r.argv0}`);o=[`/bin/sh`,`-c`,`exec -a "$0" "$@"`,r.argv0,...t]}return r?.detached===!0&&(o=[`/usr/bin/setsid`,...o]),i.spawnv(o)}function execSync(n,i){let a=i?.encoding,o=i?.input,s=e.SubprocessFlags.STDOUT_PIPE|e.SubprocessFlags.STDERR_PIPE|(o?e.SubprocessFlags.STDIN_PIPE:e.SubprocessFlags.NONE),c=typeof i?.shell==`string`?i.shell:`/bin/sh`,u;try{u=_spawnSubprocess([c,`-c`,n],s,i)}catch(e){throw _gioErrorToNodeError(e,c,[`-c`,n])}let d=o?new t.Bytes(typeof o==`string`?new TextEncoder().encode(o):o):null,[,f,p]=u.communicate(d,null),m=u.get_exit_status();if(m!==0){let e=p?new TextDecoder().decode(l(p)):``,t=f?new TextDecoder().decode(l(f)):``,i=Error(`Command failed: ${n}\n${e}`);throw i.status=m,a===`buffer`||a===null?(i.stderr=p?r.from(l(p)):r.alloc(0),i.stdout=f?r.from(l(f)):r.alloc(0)):(i.stderr=e,i.stdout=t),i}if(!f)return a===`buffer`||a==null?r.alloc(0):``;let h=l(f);if(a===`buffer`||a==null)return r.from(h);let g=r.isEncoding(a)?a:`utf8`;return r.from(h).toString(g)}function _decodeExecOutput(e,t){let n=e??new Uint8Array;if(t===`buffer`||t===null)return r.from(n);let i=t&&r.isEncoding(t)?t:`utf8`;return r.from(n).toString(i)}function _normalizeKillSignal(e){return e??`SIGTERM`}function _exec(t,n,r){typeof n==`function`&&(r=n,n={});let i=n||{},a=new ChildProcess,o=typeof i.shell==`string`?i.shell:`/bin/sh`,s=e.SubprocessFlags.STDOUT_PIPE|e.SubprocessFlags.STDERR_PIPE,c=i.maxBuffer??1024*1024,l=i.timeout&&i.timeout>0?i.timeout:0,u=_normalizeKillSignal(i.killSignal),d=i.signal;return _execImpl(a,[o,`-c`,t],s,i,{cmd:t,encoding:i.encoding,maxBuffer:c,timeoutMs:l,killSignal:u,abortSignal:d,callback:r})}function _execImpl(e,t,n,r,i){let a=null,o=!1,d=null,f=null,armTimeout=t=>{i.timeoutMs&&(a=setTimeout(()=>{o=!0;try{t.send_signal(typeof i.killSignal==`number`?i.killSignal:15)}catch{}e.killed=!0},i.timeoutMs))},disarmTimeout=()=>{a!==null&&(clearTimeout(a),a=null)},armAbort=t=>{if(!i.abortSignal)return;let fire=()=>{d=Error(`The operation was aborted`),d.name=`AbortError`;try{t.send_signal(typeof i.killSignal==`number`?i.killSignal:15)}catch{}e.killed=!0};if(i.abortSignal.aborted){queueMicrotask(fire);return}f=fire,i.abortSignal.addEventListener(`abort`,f,{once:!0})},disarmAbort=()=>{i.abortSignal&&f&&(i.abortSignal.removeEventListener(`abort`,f),f=null)};try{let a=_spawnSubprocess(t,n,r);e._setSubprocess(a),u.add(e),c(),armTimeout(a),armAbort(a),a.communicate_async(null,null,(t,n)=>{disarmTimeout(),disarmAbort(),u.delete(e);try{let[,t,r]=a.communicate_finish(n),s=t?l(t):null,c=r?l(r):null,u=null;i.maxBuffer!==1/0&&s&&s.length>i.maxBuffer&&(s=s.subarray(0,i.maxBuffer),u=RangeError(`stdout maxBuffer length exceeded`),u.code=`ERR_CHILD_PROCESS_STDIO_MAXBUFFER`),!u&&i.maxBuffer!==1/0&&c&&c.length>i.maxBuffer&&(c=c.subarray(0,i.maxBuffer),u=RangeError(`stderr maxBuffer length exceeded`),u.code=`ERR_CHILD_PROCESS_STDIO_MAXBUFFER`);let f=_decodeExecOutput(s,i.encoding),p=_decodeExecOutput(c,i.encoding),m=a.get_if_exited()?a.get_exit_status():null,h=a.get_if_signaled()?typeof i.killSignal==`string`?i.killSignal:`SIGTERM`:null;e.exitCode=m,e.signalCode=h;let g=null;if(d)g=d,g.killed=!0,g.signal=h,g.stdout=f,g.stderr=p,g.cmd=i.cmd;else if(u)g=u,g.killed=e.killed,g.signal=h,g.stdout=f,g.stderr=p,g.cmd=i.cmd;else if(o)g=Error(`Command failed: ${i.cmd}`),g.killed=!0,g.code=null,g.signal=typeof i.killSignal==`string`?i.killSignal:`SIGTERM`,g.stdout=f,g.stderr=p,g.cmd=i.cmd;else if(m!==0&&m!==null){let t=typeof p==`string`?p:p.toString();g=Error(`Command failed: ${i.cmd}\n${t}`),g.code=m,g.killed=e.killed,g.signal=h,g.stdout=f,g.stderr=p,g.cmd=i.cmd}else h&&(g=Error(`Command failed: ${i.cmd}`),g.killed=!0,g.signal=h,g.code=null,g.stdout=f,g.stderr=p,g.cmd=i.cmd);i.callback&&i.callback(g,f,p),e.emit(`exit`,m,h),e.emit(`close`,m,h)}catch(t){let n=t instanceof Error?t:Error(String(t));i.callback&&i.callback(n,``,``),e.emit(`error`,n)}}),s(e,`spawn`)}catch(n){disarmTimeout(),disarmAbort();let r=_gioErrorToNodeError(n,t[0]??``,t.slice(1));setTimeout(()=>{i.callback&&i.callback(r,``,``),e.emit(`error`,r)},0)}return e}function execFile(t,n,r,i){let a=[],o={},s;typeof n==`function`?s=n:Array.isArray(n)?(a=n,typeof r==`function`?s=r:(o=r||{},s=i)):n&&typeof n==`object`&&(o=n,s=typeof r==`function`?r:i);let c=new ChildProcess,l=e.SubprocessFlags.STDOUT_PIPE|e.SubprocessFlags.STDERR_PIPE,u=o.maxBuffer??1024*1024,d=o.timeout&&o.timeout>0?o.timeout:0,f=_normalizeKillSignal(o.killSignal);return _execImpl(c,[t,...a],l,o,{cmd:t,encoding:o.encoding,maxBuffer:u,timeoutMs:d,killSignal:f,abortSignal:o.signal,callback:s})}function execFileSync(n,i,a){let o=[],s;Array.isArray(i)?(o=i,s=a):i&&typeof i==`object`&&(s=i);let c=s?.encoding,u=s?.input,d=e.SubprocessFlags.STDOUT_PIPE|e.SubprocessFlags.STDERR_PIPE|(u?e.SubprocessFlags.STDIN_PIPE:e.SubprocessFlags.NONE),f;try{f=_spawnSubprocess([n,...o],d,s)}catch(e){throw _gioErrorToNodeError(e,n,o)}let p=u?new t.Bytes(typeof u==`string`?new TextEncoder().encode(u):u):null,[,m,h]=f.communicate(p,null),g=f.get_exit_status();if(g!==0){let e=h?new TextDecoder().decode(l(h)):``,t=m?new TextDecoder().decode(l(m)):``,i=Error(`Command failed: ${n} ${o.join(` `)}`);throw i.status=g,c===`buffer`||c===null?(i.stderr=h?r.from(l(h)):r.alloc(0),i.stdout=m?r.from(l(m)):r.alloc(0)):(i.stderr=e,i.stdout=t),i}if(!m)return c===`buffer`||c==null?r.alloc(0):``;let _=l(m);if(c===`buffer`||c==null)return r.from(_);let v=r.isEncoding(c)?c:`utf8`;return r.from(_).toString(v)}function spawn(t,n,r){let i,a;if(Array.isArray(n))i=n,a=r;else if(n!=null){if(typeof n!=`object`)throw TypeError(`The "args" argument must be of type object. Received type ${typeof n}`);i=void 0,a=n}else i=void 0,a=n;if(a!=null&&typeof a!=`object`)throw TypeError(`The "options" argument must be of type object. Received type ${typeof a}`);if(a?.argv0!==void 0&&a.argv0!==null&&typeof a.argv0!=`string`)throw TypeError(`The "options.argv0" property must be of type string. Received type ${typeof a.argv0}`);a?.cwd!==void 0&&_normalizeCwd(a.cwd);let o=i||[],l=new ChildProcess,d=a?.shell,f;f=d?[typeof d==`string`?d:`/bin/sh`,`-c`,[t,...o].join(` `)]:[t,...o];let p=a?.stdio,m=Array.isArray(p)?[typeof p[0]==`string`?p[0]:`pipe`,typeof p[1]==`string`?p[1]:`pipe`,typeof p[2]==`string`?p[2]:`pipe`]:typeof p==`string`?[p,p,p]:[`pipe`,`pipe`,`pipe`],h=e.SubprocessFlags.NONE;m[0]===`pipe`?h|=e.SubprocessFlags.STDIN_PIPE:m[0]===`inherit`&&(h|=e.SubprocessFlags.STDIN_INHERIT),m[1]===`pipe`&&(h|=e.SubprocessFlags.STDOUT_PIPE),m[1]===`ignore`&&(h|=e.SubprocessFlags.STDOUT_SILENCE),m[2]===`pipe`&&(h|=e.SubprocessFlags.STDERR_PIPE),m[2]===`ignore`&&(h|=e.SubprocessFlags.STDERR_SILENCE);try{let e=_spawnSubprocess(f,h,a);if(l._setSubprocess(e),u.add(l),m[0]===`pipe`){let t=e.get_stdin_pipe();t&&(l.stdin=new GioOutputStreamWritable(t))}let t=e.get_stdout_pipe();t&&(l.stdout=new GioInputStreamReadable(t));let n=e.get_stderr_pipe();n&&(l.stderr=new GioInputStreamReadable(n));let r=a?.signal,i=null,emitAbortError=()=>{let e=a?.killSignal??`SIGTERM`;l.kill(e);let t=Error(`The operation was aborted`);t.name=`AbortError`,l.emit(`error`,t)};r&&(r.aborted?queueMicrotask(emitAbortError):(i=emitAbortError,r.addEventListener(`abort`,i,{once:!0})));let o=null;if(a?.timeout&&a.timeout>0){let e=a.killSignal??`SIGTERM`;o=setTimeout(()=>{l.kill(e),o=null},a.timeout)}c(),e.wait_async(null,(t,n)=>{try{e.wait_finish(n);let t=e.get_if_exited()?e.get_exit_status():null,s=null;if(e.get_if_signaled()){let e=a?.killSignal;s=typeof e==`string`?e:`SIGTERM`}l.exitCode=t,l.signalCode=s,o!==null&&(clearTimeout(o),o=null),r&&i&&r.removeEventListener(`abort`,i),l.stdin&&!l.stdin.destroyed&&l.stdin.destroy(),l.emit(`exit`,t,s),l.emit(`close`,t,s)}catch(e){l.emit(`error`,e instanceof Error?e:Error(String(e)))}u.delete(l)}),s(l,`spawn`)}catch(e){s(l,`error`,_gioErrorToNodeError(e,d?t:f[0]??``,d?o:f.slice(1)))}return l}function spawnSync(n,i,a){let o,s;if(Array.isArray(i))o=i,s=a;else if(i!=null){if(typeof i!=`object`)throw TypeError(`The "args" argument must be of type object. Received type ${typeof i}`);o=void 0,s=i}else o=void 0,s=i;if(s!=null&&typeof s!=`object`)throw TypeError(`The "options" argument must be of type object. Received type ${typeof s}`);if(s?.argv0!==void 0&&s.argv0!==null&&typeof s.argv0!=`string`)throw TypeError(`The "options.argv0" property must be of type string. Received type ${typeof s.argv0}`);s?.cwd!==void 0&&_normalizeCwd(s.cwd);let c=o||[],u=s?.shell,d=s?.input,f;f=u?[typeof u==`string`?u:`/bin/sh`,`-c`,[n,...c].join(` `)]:[n,...c];let p=!1;if(s?.timeout&&s.timeout>0){let e=s.timeout/1e3,t=s.killSignal;f=[`/usr/bin/timeout`,`-s`,typeof t==`string`?t.replace(/^SIG/,``):`TERM`,String(e),...f],p=!0}let m=e.SubprocessFlags.STDOUT_PIPE|e.SubprocessFlags.STDERR_PIPE|(d?e.SubprocessFlags.STDIN_PIPE:e.SubprocessFlags.NONE),h=d;if(h!=null&&typeof h!=`string`&&!(h instanceof Uint8Array)&&!(h instanceof ArrayBuffer)&&!ArrayBuffer.isView(h))throw TypeError(`The "input" property must be of type string, Buffer, TypedArray, or DataView. Received type ${typeof h}`);let g=s?.encoding,_=g===`buffer`||g==null?r.alloc(0):``,v;try{v=_spawnSubprocess(f,m,s)}catch(e){let t=u?n:f[0]??``,r=u?c:f.slice(1);return{pid:0,output:[null,_,_],stdout:_,stderr:_,status:null,signal:null,error:_gioErrorToNodeError(e,t,r)}}let y=v.get_identifier(),b=d?new t.Bytes(typeof d==`string`?new TextEncoder().encode(d):d):null,x,S,C=null;try{let e=v.communicate(b,null);x=e[1]??null,S=e[2]??null}catch(e){C=e instanceof Error?e:Error(String(e)),x=null,S=null}let w=x?r.from(l(x)):r.alloc(0),T=S?r.from(l(S)):r.alloc(0),decode=e=>{if(g===`buffer`||g==null)return e;let t=r.isEncoding(g)?g:`utf8`;return e.toString(t)},E=decode(w),D=decode(T),O=v.get_if_exited()?v.get_exit_status():null,k=null;if(v.get_if_signaled()){let e=s?.killSignal;k=typeof e==`string`?e:`SIGTERM`}let A=!1;p&&(O===124||O===137)&&(A=!0,k=typeof s?.killSignal==`string`?s.killSignal:`SIGTERM`);let j={pid:y?parseInt(y,10):0,output:[null,E,D],stdout:E,stderr:D,status:A?null:O,signal:k};if(A){let e=Error(`Command failed: ${f.join(` `)}\n${typeof D==`string`?D:D.toString()}`);e.code=`ETIMEDOUT`,e.killed=!0,e.signal=k,j.error=e}else C&&(j.error=C);return j}var d={ChildProcess,exec:_exec,execSync,execFile,execFileSync,spawn,spawnSync};export{ChildProcess,d as default,_exec as exec,execFile,execFileSync,execSync,spawn,spawnSync};
@@ -2,10 +2,23 @@ import Gio from '@girs/gio-2.0';
2
2
  import { EventEmitter } from 'node:events';
3
3
  import { Buffer } from 'node:buffer';
4
4
  import { Readable, Writable } from 'node:stream';
5
+ interface ExecError extends Error {
6
+ status?: number;
7
+ code?: number | string;
8
+ errno?: number;
9
+ syscall?: string;
10
+ path?: string;
11
+ spawnargs?: string[];
12
+ signal?: string | null;
13
+ killed?: boolean;
14
+ stdout?: string | Buffer;
15
+ stderr?: string | Buffer;
16
+ cmd?: string;
17
+ }
5
18
  export interface ExecOptions {
6
- cwd?: string;
7
- env?: Record<string, string>;
8
- encoding?: BufferEncoding | 'buffer';
19
+ cwd?: string | URL;
20
+ env?: Record<string, unknown> | NodeJS.ProcessEnv;
21
+ encoding?: BufferEncoding | 'buffer' | null;
9
22
  shell?: string | boolean;
10
23
  timeout?: number;
11
24
  maxBuffer?: number;
@@ -13,25 +26,54 @@ export interface ExecOptions {
13
26
  uid?: number;
14
27
  gid?: number;
15
28
  windowsHide?: boolean;
29
+ /**
30
+ * Allows aborting the child process via an `AbortController`. When the
31
+ * signal fires, the child is killed with `killSignal` (default `SIGTERM`)
32
+ * and the registered callback receives an `Error` with `name: 'AbortError'`.
33
+ * Reference: https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback
34
+ */
35
+ signal?: AbortSignal;
16
36
  }
17
37
  export interface ExecSyncOptions {
18
- cwd?: string;
19
- env?: Record<string, string>;
20
- encoding?: BufferEncoding | 'buffer';
38
+ cwd?: string | URL;
39
+ env?: Record<string, unknown> | NodeJS.ProcessEnv;
40
+ encoding?: BufferEncoding | 'buffer' | null;
21
41
  shell?: string | boolean;
22
42
  timeout?: number;
23
43
  maxBuffer?: number;
24
44
  killSignal?: string | number;
45
+ uid?: number;
46
+ gid?: number;
47
+ argv0?: string;
25
48
  stdio?: string | string[];
26
49
  input?: string | Buffer | Uint8Array;
50
+ windowsHide?: boolean;
51
+ windowsVerbatimArguments?: boolean;
27
52
  }
28
53
  export interface SpawnOptions {
29
- cwd?: string;
30
- env?: Record<string, string>;
54
+ cwd?: string | URL;
55
+ env?: Record<string, unknown> | NodeJS.ProcessEnv;
31
56
  stdio?: string | string[];
32
57
  shell?: string | boolean;
33
58
  timeout?: number;
34
59
  killSignal?: string | number;
60
+ uid?: number;
61
+ gid?: number;
62
+ /**
63
+ * Override what the child process sees as `argv[0]`. Implemented by
64
+ * wrapping the spawn through `/bin/sh -c 'exec -a "$0" "$@"'` because
65
+ * `Gio.SubprocessLauncher` does not expose `set_child_setup` to GIR.
66
+ */
67
+ argv0?: string;
68
+ /**
69
+ * Spawn the child as the leader of a new process group via `setsid` so
70
+ * it survives the parent exiting.
71
+ */
72
+ detached?: boolean;
73
+ /** No-op on Linux — accepted for cross-platform compatibility. */
74
+ windowsHide?: boolean;
75
+ /** No-op on Linux — accepted for cross-platform compatibility. */
76
+ windowsVerbatimArguments?: boolean;
35
77
  /**
36
78
  * Allows aborting the child process via an `AbortController`. When the
37
79
  * signal fires, the child is killed with `killSignal` (default `SIGTERM`)
@@ -74,7 +116,16 @@ export declare class ChildProcess extends EventEmitter {
74
116
  private _subprocess;
75
117
  /** @internal Set the underlying Gio.Subprocess and extract PID. */
76
118
  _setSubprocess(proc: Gio.Subprocess): void;
77
- /** Send a signal to the child process. */
119
+ /**
120
+ * Send a signal to the child process.
121
+ *
122
+ * Accepts a numeric signal or a POSIX signal NAME (`'SIGTERM'`,
123
+ * `'SIGKILL'`, …). Unrecognised names default to SIGTERM the way
124
+ * Gio's `send_signal` does. Returns `true` on success / when the
125
+ * signal was at least dispatched, `false` if we no longer have a
126
+ * subprocess handle (matches Node's "no-op on already-reaped child"
127
+ * return shape).
128
+ */
78
129
  kill(signal?: string | number): boolean;
79
130
  ref(): this;
80
131
  unref(): this;
@@ -82,17 +133,44 @@ export declare class ChildProcess extends EventEmitter {
82
133
  export declare function execSync(command: string, options?: ExecSyncOptions): Buffer | string;
83
134
  /**
84
135
  * Execute a command in a shell (async with callback).
136
+ *
137
+ * Supports the full Node option set (per
138
+ * `refs/node/lib/child_process.js` and the
139
+ * `refs/node-test/parallel/test-child-process-exec-*` tests):
140
+ * - `encoding`: `'utf8'` (default), other `BufferEncoding`, `'buffer'`
141
+ * or `null` (→ Buffer)
142
+ * - `timeout`: kill the child with `killSignal` (default `SIGTERM`)
143
+ * after N ms; the callback receives an Error with `killed: true`
144
+ * and `signal` set to the kill signal
145
+ * - `maxBuffer`: throw `ERR_CHILD_PROCESS_STDIO_MAXBUFFER` when the
146
+ * captured stdout/stderr exceeds N bytes (default 1 MiB, matching
147
+ * Node's `MAX_BUFFER`); the child is killed and the truncated
148
+ * output is returned
149
+ * - `signal` (`AbortSignal`): kill the child on abort and surface an
150
+ * `AbortError` to the callback
151
+ * - `killSignal`: signal used by timeout / abort (default `SIGTERM`)
152
+ * - `cwd` / `env` / `shell` / `uid` / `gid` / `argv0` etc. via
153
+ * `_spawnSubprocess`
85
154
  */
86
- declare function _exec(command: string, options?: ExecOptions | ((error: Error | null, stdout: string, stderr: string) => void), callback?: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess;
155
+ declare function _exec(command: string, options?: ExecOptions | ((error: ExecError | null, stdout: string | Buffer, stderr: string | Buffer) => void), callback?: (error: ExecError | null, stdout: string | Buffer, stderr: string | Buffer) => void): ChildProcess;
87
156
  export { _exec as exec };
88
157
  /**
89
158
  * Execute a file directly without shell (async).
159
+ *
160
+ * Shares the timeout / maxBuffer / signal / encoding plumbing with `exec`
161
+ * via `_execImpl`. The only structural difference is argv construction
162
+ * (no shell wrap).
90
163
  */
91
- export declare function execFile(file: string, args?: string[] | ((error: Error | null, stdout: string, stderr: string) => void), options?: ExecOptions | ((error: Error | null, stdout: string, stderr: string) => void), callback?: (error: Error | null, stdout: string, stderr: string) => void): ChildProcess;
164
+ export declare function execFile(file: string, args?: string[] | ((error: ExecError | null, stdout: string | Buffer, stderr: string | Buffer) => void), options?: ExecOptions | ((error: ExecError | null, stdout: string | Buffer, stderr: string | Buffer) => void), callback?: (error: ExecError | null, stdout: string | Buffer, stderr: string | Buffer) => void): ChildProcess;
92
165
  /**
93
166
  * Execute a file directly without shell (sync).
167
+ *
168
+ * Node's overloads accept `execFileSync(file)`, `execFileSync(file, args)`,
169
+ * `execFileSync(file, options)` and `execFileSync(file, args, options)`.
170
+ * Match all four — passing options as the 2nd positional must not be
171
+ * spread into argv.
94
172
  */
95
- export declare function execFileSync(file: string, args?: string[], options?: ExecSyncOptions): Buffer | string;
173
+ export declare function execFileSync(file: string, args?: string[] | ExecSyncOptions, options?: ExecSyncOptions): Buffer | string;
96
174
  /**
97
175
  * Spawn a new process (async, with event-based API).
98
176
  *
@@ -0,0 +1,2 @@
1
+ declare const _default: () => Promise<void>;
2
+ export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/child_process",
3
- "version": "0.4.35",
3
+ "version": "0.4.36",
4
4
  "description": "Node.js child_process module for Gjs",
5
5
  "type": "module",
6
6
  "module": "lib/esm/index.js",
@@ -33,18 +33,18 @@
33
33
  "child_process"
34
34
  ],
35
35
  "devDependencies": {
36
- "@gjsify/cli": "^0.4.35",
37
- "@gjsify/dom-elements": "^0.4.35",
38
- "@gjsify/unit": "^0.4.35",
36
+ "@gjsify/cli": "^0.4.36",
37
+ "@gjsify/dom-elements": "^0.4.36",
38
+ "@gjsify/unit": "^0.4.36",
39
39
  "@types/node": "^25.9.1",
40
- "typescript": "^6.0.3"
40
+ "typescript": "^5.9.3"
41
41
  },
42
42
  "dependencies": {
43
- "@girs/gio-2.0": "2.88.0-4.0.1",
44
- "@girs/glib-2.0": "2.88.0-4.0.1",
45
- "@gjsify/buffer": "^0.4.35",
46
- "@gjsify/events": "^0.4.35",
47
- "@gjsify/utils": "^0.4.35"
43
+ "@girs/gio-2.0": "2.88.0-4.0.4",
44
+ "@girs/glib-2.0": "2.88.0-4.0.4",
45
+ "@gjsify/buffer": "^0.4.36",
46
+ "@gjsify/events": "^0.4.36",
47
+ "@gjsify/utils": "^0.4.36"
48
48
  },
49
49
  "gjsify": {
50
50
  "runtimes": {
@@ -52,5 +52,15 @@
52
52
  "node": "none",
53
53
  "browser": "none"
54
54
  }
55
- }
55
+ },
56
+ "license": "MIT",
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "git+https://github.com/gjsify/gjsify.git",
60
+ "directory": "packages/node/child_process"
61
+ },
62
+ "bugs": {
63
+ "url": "https://github.com/gjsify/gjsify/issues"
64
+ },
65
+ "homepage": "https://github.com/gjsify/gjsify/tree/main/packages/node/child_process#readme"
56
66
  }