From 80dff3bcbedb2a0440b453557e95fcf8eb2784f8 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Mon, 11 Mar 2024 00:06:48 +0300 Subject: [PATCH 01/14] chore: inject zurk --- package-lock.json | 152 ++++------------------------------------------ package.json | 5 +- src/core.ts | 66 ++++++++++++++------ 3 files changed, 66 insertions(+), 157 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0714991abb..40c8666493 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "zx", "version": "7.2.3", "license": "Apache-2.0", + "dependencies": { + "zurk": "^0.0.3" + }, "bin": { "zx": "build/cli.js" }, @@ -29,7 +32,6 @@ "globby": "^14.0.1", "madge": "^6.1.0", "minimist": "^1.2.8", - "node-fetch": "3.3.2", "node-fetch-native": "^1.6.2", "prettier": "^2.8.8", "ps-tree": "^1.2.0", @@ -2130,15 +2132,6 @@ "node": ">= 8" } }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", - "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, "node_modules/date-format": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", @@ -3091,29 +3084,6 @@ "reusify": "^1.0.4" } }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, "node_modules/figures": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", @@ -3242,18 +3212,6 @@ "node": ">=8.0.0" } }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dev": true, - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, "node_modules/from": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", @@ -4658,43 +4616,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dev": true, - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, "node_modules/node-fetch-native": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.2.tgz", @@ -6758,15 +6679,6 @@ "integrity": "sha512-V8X6hPIzY1juvrSVREmtRhK9AHn/8c2z8XxaibESU+jyG/RinZ9x9x6aw8qEuFAi7R6Kl/EWGbU2Yq/9u6TTjw==", "dev": true }, - "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, "node_modules/webpod": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/webpod/-/webpod-0.0.2.tgz", @@ -6926,6 +6838,11 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zurk": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.3.tgz", + "integrity": "sha512-yMCJYRsJFATrRa0XCb6hbfodTd0XPWAY8Grcz/CtBAjmdEhRbQ2UqF9Le+gbM2zPztyBRfjgrtaC0s2lIHQTzA==" } }, "dependencies": { @@ -8356,12 +8273,6 @@ } } }, - "data-uri-to-buffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz", - "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==", - "dev": true - }, "date-format": { "version": "4.0.14", "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", @@ -9072,16 +8983,6 @@ "reusify": "^1.0.4" } }, - "fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "dev": true, - "requires": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - } - }, "figures": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", @@ -9174,15 +9075,6 @@ "signal-exit": "^3.0.2" } }, - "formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dev": true, - "requires": { - "fetch-blob": "^3.1.2" - } - }, "from": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", @@ -10186,23 +10078,6 @@ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true }, - "node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "dev": true - }, - "node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dev": true, - "requires": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - } - }, "node-fetch-native": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.2.tgz", @@ -11686,12 +11561,6 @@ "integrity": "sha512-V8X6hPIzY1juvrSVREmtRhK9AHn/8c2z8XxaibESU+jyG/RinZ9x9x6aw8qEuFAi7R6Kl/EWGbU2Yq/9u6TTjw==", "dev": true }, - "web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", - "dev": true - }, "webpod": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/webpod/-/webpod-0.0.2.tgz", @@ -11808,6 +11677,11 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true + }, + "zurk": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.3.tgz", + "integrity": "sha512-yMCJYRsJFATrRa0XCb6hbfodTd0XPWAY8Grcz/CtBAjmdEhRbQ2UqF9Le+gbM2zPztyBRfjgrtaC0s2lIHQTzA==" } } } diff --git a/package.json b/package.json index 094078fcbf..a04ae6a586 100644 --- a/package.json +++ b/package.json @@ -98,5 +98,8 @@ }, "repository": "google/zx", "author": "Anton Medvedev ", - "license": "Apache-2.0" + "license": "Apache-2.0", + "dependencies": { + "zurk": "^0.0.3" + } } diff --git a/src/core.ts b/src/core.ts index 28131d9b41..1b995c5b8d 100644 --- a/src/core.ts +++ b/src/core.ts @@ -17,6 +17,10 @@ import { ChildProcess, spawn, StdioNull, StdioPipe } from 'node:child_process' import { AsyncLocalStorage, createHook } from 'node:async_hooks' import { Readable, Writable } from 'node:stream' import { inspect } from 'node:util' +import { + $ as zurk$, + TShellResponse as TZurkShellResponse +} from 'zurk' import { chalk, which, @@ -159,6 +163,7 @@ export class ProcessPromise extends Promise { private _resolved = false private _halted = false private _piped = false + private _zurk: TZurkShellResponse | null = null _prerun = noop _postrun = noop @@ -180,29 +185,41 @@ export class ProcessPromise extends Promise { const $ = this._snapshot if (this.child) return this // The _run() can be called from a few places. this._prerun() // In case $1.pipe($2), the $2 returned, and on $2._run() invoke $1._run(). + $.log({ kind: 'cmd', cmd: this._command, verbose: $.verbose && !this._quiet, }) - this.child = $.spawn($.prefix + this._command, { - cwd: $.cwd ?? $[processCwd], - shell: typeof $.shell === 'string' ? $.shell : true, - stdio: this._stdio, - windowsHide: true, - env: $.env, - }) + + this._zurk = zurk$({ + get cwd() { return $.cwd ?? $[processCwd] }, + cmd: $.prefix + this._command, + get shell() { return typeof $.shell === 'string' ? $.shell : true }, + get env() { return $.env }, + stdio: this._stdio as any, + get spawn() { return $.spawn }, + run: cb => cb(), + sync: false, + nothrow: true + })() as TZurkShellResponse + + this.child = this._zurk._ctx.child as ChildProcess + + // this._zurk.then(({}) => { + // + // }) + + // this.child = $.spawn($.prefix + this._command, { + // cwd: $.cwd ?? $[processCwd], + // shell: typeof $.shell === 'string' ? $.shell : true, + // stdio: this._stdio, + // windowsHide: true, + // env: $.env, + // }) + this.child.on('close', (code, signal) => { - let message = `exit code: ${code}` - if (code != 0 || signal != null) { - message = `${stderr || '\n'} at ${this._from}` - message += `\n exit code: ${code}${ - exitCodeInfo(code) ? ' (' + exitCodeInfo(code) + ')' : '' - }` - if (signal != null) { - message += `\n signal: ${signal}` - } - } + let message = ProcessOutput.getMessage(code, signal, stderr, this._from) let output = new ProcessOutput( code, signal, @@ -425,6 +442,21 @@ export class ProcessOutput extends Error { return this._signal } + static getMessage(code: number | null, signal: NodeJS.Signals | null, stderr: string, from: string) { + let message = `exit code: ${code}` + if (code != 0 || signal != null) { + message = `${stderr || '\n'} at ${from}` + message += `\n exit code: ${code}${ + exitCodeInfo(code) ? ' (' + exitCodeInfo(code) + ')' : '' + }` + if (signal != null) { + message += `\n signal: ${signal}` + } + } + + return message + } + [inspect.custom]() { let stringify = (s: string, c: ChalkInstance) => s.length === 0 ? "''" : c(inspect(s)) From ef8104176aa3cbd2cff120145e4da72fca0cc24e Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Mon, 11 Mar 2024 22:15:29 +0300 Subject: [PATCH 02/14] chore: handle timeouts via zurk --- package-lock.json | 14 +++++------ package.json | 2 +- src/core.ts | 61 +++++++++++++++++++++++++++++++---------------- test/core.test.js | 2 +- 4 files changed, 50 insertions(+), 29 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40c8666493..5ee7025db0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "7.2.3", "license": "Apache-2.0", "dependencies": { - "zurk": "^0.0.3" + "zurk": "^0.0.4" }, "bin": { "zx": "build/cli.js" @@ -6840,9 +6840,9 @@ } }, "node_modules/zurk": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.3.tgz", - "integrity": "sha512-yMCJYRsJFATrRa0XCb6hbfodTd0XPWAY8Grcz/CtBAjmdEhRbQ2UqF9Le+gbM2zPztyBRfjgrtaC0s2lIHQTzA==" + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.4.tgz", + "integrity": "sha512-VZOH2Drh4cnS7CtF5A7Ej+31Uz+zZsYF/BKaEX5VMlvx56EWib6ZyYCVG3b5TL94b85VDIU2Uv+hN0KSXmWJRw==" } }, "dependencies": { @@ -11679,9 +11679,9 @@ "dev": true }, "zurk": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.3.tgz", - "integrity": "sha512-yMCJYRsJFATrRa0XCb6hbfodTd0XPWAY8Grcz/CtBAjmdEhRbQ2UqF9Le+gbM2zPztyBRfjgrtaC0s2lIHQTzA==" + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.4.tgz", + "integrity": "sha512-VZOH2Drh4cnS7CtF5A7Ej+31Uz+zZsYF/BKaEX5VMlvx56EWib6ZyYCVG3b5TL94b85VDIU2Uv+hN0KSXmWJRw==" } } } diff --git a/package.json b/package.json index a04ae6a586..96a38b18a8 100644 --- a/package.json +++ b/package.json @@ -100,6 +100,6 @@ "author": "Anton Medvedev ", "license": "Apache-2.0", "dependencies": { - "zurk": "^0.0.3" + "zurk": "^0.0.4" } } diff --git a/src/core.ts b/src/core.ts index 1b995c5b8d..29e72b20b2 100644 --- a/src/core.ts +++ b/src/core.ts @@ -183,6 +183,7 @@ export class ProcessPromise extends Promise { run(): ProcessPromise { const $ = this._snapshot + const self = this if (this.child) return this // The _run() can be called from a few places. this._prerun() // In case $1.pipe($2), the $2 returned, and on $2._run() invoke $1._run(). @@ -193,22 +194,38 @@ export class ProcessPromise extends Promise { }) this._zurk = zurk$({ - get cwd() { return $.cwd ?? $[processCwd] }, cmd: $.prefix + this._command, + get cwd() { return $.cwd ?? $[processCwd] }, get shell() { return typeof $.shell === 'string' ? $.shell : true }, get env() { return $.env }, - stdio: this._stdio as any, get spawn() { return $.spawn }, - run: cb => cb(), + stdio: this._stdio as any, sync: false, - nothrow: true + nothrow: true, + onStdout(data: any) { $.log({ kind: 'stdout', data, verbose: $.verbose && !self._quiet }) }, + onStderr(data: any) { $.log({ kind: 'stderr', data, verbose: $.verbose && !self._quiet }) }, + run: cb => cb(), + timeout: self._timeout, + timeoutSignal: self._timeoutSignal as NodeJS.Signals, })() as TZurkShellResponse this.child = this._zurk._ctx.child as ChildProcess - // this._zurk.then(({}) => { - // - // }) + this._zurk.finally(() => self._resolved = true) + this._zurk.then(({ + error, + stdout, + stderr, + status: code, + signal + }) => { + if (error) { + + } else { + + } + + }) // this.child = $.spawn($.prefix + this._command, { // cwd: $.cwd ?? $[processCwd], @@ -233,39 +250,35 @@ export class ProcessPromise extends Promise { } else { this._reject(output) } - this._resolved = true + // this._resolved = true }) this.child.on('error', (err: NodeJS.ErrnoException) => { - const message = - `${err.message}\n` + - ` errno: ${err.errno} (${errnoMessage(err.errno)})\n` + - ` code: ${err.code}\n` + - ` at ${this._from}` + const message = ProcessOutput.getErrorMessage(err, this._from) this._reject( new ProcessOutput(null, null, stdout, stderr, combined, message) ) - this._resolved = true + // this._resolved = true }) let stdout = '', stderr = '', combined = '' let onStdout = (data: any) => { - $.log({ kind: 'stdout', data, verbose: $.verbose && !this._quiet }) + // $.log({ kind: 'stdout', data, verbose: $.verbose && !this._quiet }) stdout += data combined += data } let onStderr = (data: any) => { - $.log({ kind: 'stderr', data, verbose: $.verbose && !this._quiet }) + // $.log({ kind: 'stderr', data, verbose: $.verbose && !this._quiet }) stderr += data combined += data } if (!this._piped) this.child.stdout?.on('data', onStdout) // If process is piped, don't collect or print output. this.child.stderr?.on('data', onStderr) // Stderr should be printed regardless of piping. this._postrun() // In case $1.pipe($2), after both subprocesses are running, we can pipe $1.stdout to $2.stdin. - if (this._timeout && this._timeoutSignal) { - const t = setTimeout(() => this.kill(this._timeoutSignal), this._timeout) - this.finally(() => clearTimeout(t)).catch(noop) - } + // if (this._timeout && this._timeoutSignal) { + // const t = setTimeout(() => this.kill(this._timeoutSignal), this._timeout) + // this.finally(() => clearTimeout(t)).catch(noop) + // } return this } @@ -457,6 +470,14 @@ export class ProcessOutput extends Error { return message } + static getErrorMessage(err: NodeJS.ErrnoException, from: string) { + return ``+ + `${err.message}\n` + + ` errno: ${err.errno} (${errnoMessage(err.errno)})\n` + + ` code: ${err.code}\n` + + ` at ${from}` + } + [inspect.custom]() { let stringify = (s: string, c: ChalkInstance) => s.length === 0 ? "''" : c(inspect(s)) diff --git a/test/core.test.js b/test/core.test.js index 5f689ee592..6cda6ffb70 100644 --- a/test/core.test.js +++ b/test/core.test.js @@ -378,7 +378,7 @@ describe('core', () => { signal = p.signal } assert.equal(exitCode, undefined) - assert.equal(signal, undefined) + assert.equal(signal, 'SIGTERM') }) test('$ thrown as error', async () => { From a1353b08198fb20aa03add9a353d455cd4ade47d Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Tue, 12 Mar 2024 14:47:18 +0300 Subject: [PATCH 03/14] chore: override zurk quote --- package-lock.json | 14 +++++++------- package.json | 2 +- src/core.ts | 6 +++++- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5ee7025db0..c8039849a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "7.2.3", "license": "Apache-2.0", "dependencies": { - "zurk": "^0.0.4" + "zurk": "^0.0.6" }, "bin": { "zx": "build/cli.js" @@ -6840,9 +6840,9 @@ } }, "node_modules/zurk": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.4.tgz", - "integrity": "sha512-VZOH2Drh4cnS7CtF5A7Ej+31Uz+zZsYF/BKaEX5VMlvx56EWib6ZyYCVG3b5TL94b85VDIU2Uv+hN0KSXmWJRw==" + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.6.tgz", + "integrity": "sha512-Vl+sHXA0W9uVKJo4xOQ2yUHVLETIuGLH18OPGHtgM7JhbWX1/TxWRhstG+LnmBAJAR9WhrjCbmtxlXX/9KJyLg==" } }, "dependencies": { @@ -11679,9 +11679,9 @@ "dev": true }, "zurk": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.4.tgz", - "integrity": "sha512-VZOH2Drh4cnS7CtF5A7Ej+31Uz+zZsYF/BKaEX5VMlvx56EWib6ZyYCVG3b5TL94b85VDIU2Uv+hN0KSXmWJRw==" + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.6.tgz", + "integrity": "sha512-Vl+sHXA0W9uVKJo4xOQ2yUHVLETIuGLH18OPGHtgM7JhbWX1/TxWRhstG+LnmBAJAR9WhrjCbmtxlXX/9KJyLg==" } } } diff --git a/package.json b/package.json index 96a38b18a8..c56a4677f1 100644 --- a/package.json +++ b/package.json @@ -100,6 +100,6 @@ "author": "Anton Medvedev ", "license": "Apache-2.0", "dependencies": { - "zurk": "^0.0.4" + "zurk": "^0.0.6" } } diff --git a/src/core.ts b/src/core.ts index 29e72b20b2..99e377efa6 100644 --- a/src/core.ts +++ b/src/core.ts @@ -196,9 +196,13 @@ export class ProcessPromise extends Promise { this._zurk = zurk$({ cmd: $.prefix + this._command, get cwd() { return $.cwd ?? $[processCwd] }, - get shell() { return typeof $.shell === 'string' ? $.shell : true }, + get shell() { + console.log('!!!shell=', $.shell) + return typeof $.shell === 'string' ? $.shell : true + }, get env() { return $.env }, get spawn() { return $.spawn }, + quote: (v: T): T => v, // let zx handle quoting stdio: this._stdio as any, sync: false, nothrow: true, From 7a7ca81233b847bdbef390e7bc8e5a207b1c3fce Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Tue, 12 Mar 2024 22:38:03 +0300 Subject: [PATCH 04/14] chore: use zurk response to build ProcessOutput --- package-lock.json | 14 ++--- package.json | 2 +- src/core.ts | 129 ++++++++++++++++++++++++++------------------- test/win32.test.js | 2 + 4 files changed, 86 insertions(+), 61 deletions(-) diff --git a/package-lock.json b/package-lock.json index c8039849a8..13c4f72176 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "7.2.3", "license": "Apache-2.0", "dependencies": { - "zurk": "^0.0.6" + "zurk": "^0.0.9" }, "bin": { "zx": "build/cli.js" @@ -6840,9 +6840,9 @@ } }, "node_modules/zurk": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.6.tgz", - "integrity": "sha512-Vl+sHXA0W9uVKJo4xOQ2yUHVLETIuGLH18OPGHtgM7JhbWX1/TxWRhstG+LnmBAJAR9WhrjCbmtxlXX/9KJyLg==" + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.9.tgz", + "integrity": "sha512-6AYDIzvTgyEk0gVgrS3VY4SrI4RkJWqvYwpFFh4kKarfZH1uWBqffQFRHcO60LR7tRhb8tpD5hfrVid2Mhx1uA==" } }, "dependencies": { @@ -11679,9 +11679,9 @@ "dev": true }, "zurk": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.6.tgz", - "integrity": "sha512-Vl+sHXA0W9uVKJo4xOQ2yUHVLETIuGLH18OPGHtgM7JhbWX1/TxWRhstG+LnmBAJAR9WhrjCbmtxlXX/9KJyLg==" + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.9.tgz", + "integrity": "sha512-6AYDIzvTgyEk0gVgrS3VY4SrI4RkJWqvYwpFFh4kKarfZH1uWBqffQFRHcO60LR7tRhb8tpD5hfrVid2Mhx1uA==" } } } diff --git a/package.json b/package.json index c56a4677f1..783d262159 100644 --- a/package.json +++ b/package.json @@ -100,6 +100,6 @@ "author": "Anton Medvedev ", "license": "Apache-2.0", "dependencies": { - "zurk": "^0.0.6" + "zurk": "^0.0.9" } } diff --git a/src/core.ts b/src/core.ts index 99e377efa6..c584ada001 100644 --- a/src/core.ts +++ b/src/core.ts @@ -81,7 +81,7 @@ export const defaults: Options = { spawn, log, } - +const isWin = process.platform == 'win32' try { defaults.shell = which.sync('bash') defaults.prefix = 'set -euo pipefail;' @@ -120,6 +120,7 @@ export const $ = new Proxy( } cmd += s + pieces[++i] } + isWin && console.log('cmd=', cmd) promise._bind(cmd, from, resolve!, reject!, getStore()) // Postpone run to allow promise configuration. setImmediate(() => promise.isHalted || promise.run()) @@ -197,7 +198,7 @@ export class ProcessPromise extends Promise { cmd: $.prefix + this._command, get cwd() { return $.cwd ?? $[processCwd] }, get shell() { - console.log('!!!shell=', $.shell) + isWin && console.log('$.shell=', $.shell) return typeof $.shell === 'string' ? $.shell : true }, get env() { return $.env }, @@ -206,6 +207,8 @@ export class ProcessPromise extends Promise { stdio: this._stdio as any, sync: false, nothrow: true, + nohandle: true, + detached: !isWin, onStdout(data: any) { $.log({ kind: 'stdout', data, verbose: $.verbose && !self._quiet }) }, onStderr(data: any) { $.log({ kind: 'stderr', data, verbose: $.verbose && !self._quiet }) }, run: cb => cb(), @@ -220,13 +223,31 @@ export class ProcessPromise extends Promise { error, stdout, stderr, - status: code, + stdall, + status, signal }) => { + isWin && console.log('ctx=', this._zurk?._ctx) if (error) { - + const message = ProcessOutput.getErrorMessage(error, self._from) + self._reject( + new ProcessOutput(null, null, stdout, stderr, stdall, message) + ) } else { - + const message = ProcessOutput.getMessage(status, signal, stderr, self._from) + const output = new ProcessOutput( + status, + signal, + stdout, + stderr, + stdall, + message, + ) + if (status === 0 || self._nothrow) { + self._resolve(output) + } else { + self._reject(output) + } } }) @@ -239,45 +260,45 @@ export class ProcessPromise extends Promise { // env: $.env, // }) - this.child.on('close', (code, signal) => { - let message = ProcessOutput.getMessage(code, signal, stderr, this._from) - let output = new ProcessOutput( - code, - signal, - stdout, - stderr, - combined, - message - ) - if (code === 0 || this._nothrow) { - this._resolve(output) - } else { - this._reject(output) - } - // this._resolved = true - }) - this.child.on('error', (err: NodeJS.ErrnoException) => { - const message = ProcessOutput.getErrorMessage(err, this._from) - this._reject( - new ProcessOutput(null, null, stdout, stderr, combined, message) - ) - // this._resolved = true - }) - let stdout = '', - stderr = '', - combined = '' - let onStdout = (data: any) => { - // $.log({ kind: 'stdout', data, verbose: $.verbose && !this._quiet }) - stdout += data - combined += data - } - let onStderr = (data: any) => { - // $.log({ kind: 'stderr', data, verbose: $.verbose && !this._quiet }) - stderr += data - combined += data - } - if (!this._piped) this.child.stdout?.on('data', onStdout) // If process is piped, don't collect or print output. - this.child.stderr?.on('data', onStderr) // Stderr should be printed regardless of piping. + // this.child.on('close', (code, signal) => { + // // let message = ProcessOutput.getMessage(code, signal, stderr, this._from) + // // let output = new ProcessOutput( + // // code, + // // signal, + // // stdout, + // // stderr, + // // combined, + // // message + // // ) + // // if (code === 0 || this._nothrow) { + // // this._resolve(output) + // // } else { + // // this._reject(output) + // // } + // // this._resolved = true + // }) + // this.child.on('error', (err: NodeJS.ErrnoException) => { + // // const message = ProcessOutput.getErrorMessage(err, this._from) + // // this._reject( + // // new ProcessOutput(null, null, stdout, stderr, combined, message) + // // ) + // // this._resolved = true + // }) + // let stdout = '', + // stderr = '', + // combined = '' + // let onStdout = (data: any) => { + // // $.log({ kind: 'stdout', data, verbose: $.verbose && !this._quiet }) + // stdout += data + // combined += data + // } + // let onStderr = (data: any) => { + // // $.log({ kind: 'stderr', data, verbose: $.verbose && !this._quiet }) + // stderr += data + // combined += data + // } + // if (!this._piped) this.child.stdout?.on('data', onStdout) // If process is piped, don't collect or print output. + // this.child.stderr?.on('data', onStderr) // Stderr should be printed regardless of piping. this._postrun() // In case $1.pipe($2), after both subprocesses are running, we can pipe $1.stdout to $2.stdin. // if (this._timeout && this._timeoutSignal) { // const t = setTimeout(() => this.kill(this._timeoutSignal), this._timeout) @@ -374,15 +395,17 @@ export class ProcessPromise extends Promise { if (!this.child) throw new Error('Trying to kill a process without creating one.') if (!this.child.pid) throw new Error('The process pid is undefined.') - let children = await psTree(this.child.pid) - for (const p of children) { - try { - process.kill(+p.PID, signal) - } catch (e) {} - } - try { - process.kill(this.child.pid, signal) - } catch (e) {} + + await this._zurk?.kill(signal as NodeJS.Signals) + // let children = await psTree(this.child.pid) + // for (const p of children) { + // try { + // process.kill(+p.PID, signal) + // } catch (e) {} + // } + // try { + // process.kill(this.child.pid, signal) + // } catch (e) {} } stdio(stdin: IO, stdout: IO = 'pipe', stderr: IO = 'pipe'): ProcessPromise { diff --git a/test/win32.test.js b/test/win32.test.js index 7c63de9a71..5546ccba3a 100644 --- a/test/win32.test.js +++ b/test/win32.test.js @@ -27,6 +27,7 @@ _describe('win32', () => { const p = await $`echo $0` // Bash is first by default. assert.match(p.stdout, /bash/) await within(async () => { + $.prefix = '' $.shell = which.sync('powershell.exe') $.quote = quotePowerShell const p = await $`get-host` @@ -36,6 +37,7 @@ _describe('win32', () => { test('quotePowerShell works', async () => { await within(async () => { + $.prefix = '' $.shell = which.sync('powershell.exe') $.quote = quotePowerShell const p = await $`echo ${`Windows 'rulez!'`}` From 98a0e6692a6d8460f60b691a9d9cf8a688b28349 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Tue, 12 Mar 2024 23:20:32 +0300 Subject: [PATCH 05/14] chore: linting --- src/core.ts | 113 +++++++++++++++------------------------------ test/win32.test.js | 2 - 2 files changed, 36 insertions(+), 79 deletions(-) diff --git a/src/core.ts b/src/core.ts index c584ada001..9d09f07b6a 100644 --- a/src/core.ts +++ b/src/core.ts @@ -17,10 +17,7 @@ import { ChildProcess, spawn, StdioNull, StdioPipe } from 'node:child_process' import { AsyncLocalStorage, createHook } from 'node:async_hooks' import { Readable, Writable } from 'node:stream' import { inspect } from 'node:util' -import { - $ as zurk$, - TShellResponse as TZurkShellResponse -} from 'zurk' +import { $ as zurk$, TShellResponse as TZurkShellResponse } from 'zurk' import { chalk, which, @@ -87,7 +84,7 @@ try { defaults.prefix = 'set -euo pipefail;' defaults.quote = quote } catch (err) { - if (process.platform == 'win32') { + if (isWin) { try { defaults.shell = which.sync('powershell.exe') defaults.quote = quotePowerShell @@ -120,7 +117,6 @@ export const $ = new Proxy( } cmd += s + pieces[++i] } - isWin && console.log('cmd=', cmd) promise._bind(cmd, from, resolve!, reject!, getStore()) // Postpone run to allow promise configuration. setImmediate(() => promise.isHalted || promise.run()) @@ -196,52 +192,58 @@ export class ProcessPromise extends Promise { this._zurk = zurk$({ cmd: $.prefix + this._command, - get cwd() { return $.cwd ?? $[processCwd] }, + get cwd() { + return $.cwd ?? $[processCwd] + }, get shell() { - isWin && console.log('$.shell=', $.shell) return typeof $.shell === 'string' ? $.shell : true }, - get env() { return $.env }, - get spawn() { return $.spawn }, + get env() { + return $.env + }, + get spawn() { + return $.spawn + }, quote: (v: T): T => v, // let zx handle quoting stdio: this._stdio as any, sync: false, nothrow: true, nohandle: true, detached: !isWin, - onStdout(data: any) { $.log({ kind: 'stdout', data, verbose: $.verbose && !self._quiet }) }, - onStderr(data: any) { $.log({ kind: 'stderr', data, verbose: $.verbose && !self._quiet }) }, - run: cb => cb(), + onStdout(data: any) { + $.log({ kind: 'stdout', data, verbose: $.verbose && !self._quiet }) + }, + onStderr(data: any) { + $.log({ kind: 'stderr', data, verbose: $.verbose && !self._quiet }) + }, + run: (cb) => cb(), timeout: self._timeout, timeoutSignal: self._timeoutSignal as NodeJS.Signals, })() as TZurkShellResponse this.child = this._zurk._ctx.child as ChildProcess - this._zurk.finally(() => self._resolved = true) - this._zurk.then(({ - error, - stdout, - stderr, - stdall, - status, - signal - }) => { - isWin && console.log('ctx=', this._zurk?._ctx) + this._zurk.finally(() => (self._resolved = true)) + this._zurk.then(({ error, stdout, stderr, stdall, status, signal }) => { if (error) { const message = ProcessOutput.getErrorMessage(error, self._from) self._reject( new ProcessOutput(null, null, stdout, stderr, stdall, message) ) } else { - const message = ProcessOutput.getMessage(status, signal, stderr, self._from) + const message = ProcessOutput.getMessage( + status, + signal, + stderr, + self._from + ) const output = new ProcessOutput( status, signal, stdout, stderr, stdall, - message, + message ) if (status === 0 || self._nothrow) { self._resolve(output) @@ -249,61 +251,12 @@ export class ProcessPromise extends Promise { self._reject(output) } } - }) - // this.child = $.spawn($.prefix + this._command, { - // cwd: $.cwd ?? $[processCwd], - // shell: typeof $.shell === 'string' ? $.shell : true, - // stdio: this._stdio, - // windowsHide: true, - // env: $.env, - // }) - - // this.child.on('close', (code, signal) => { - // // let message = ProcessOutput.getMessage(code, signal, stderr, this._from) - // // let output = new ProcessOutput( - // // code, - // // signal, - // // stdout, - // // stderr, - // // combined, - // // message - // // ) - // // if (code === 0 || this._nothrow) { - // // this._resolve(output) - // // } else { - // // this._reject(output) - // // } - // // this._resolved = true - // }) - // this.child.on('error', (err: NodeJS.ErrnoException) => { - // // const message = ProcessOutput.getErrorMessage(err, this._from) - // // this._reject( - // // new ProcessOutput(null, null, stdout, stderr, combined, message) - // // ) - // // this._resolved = true - // }) - // let stdout = '', - // stderr = '', - // combined = '' - // let onStdout = (data: any) => { - // // $.log({ kind: 'stdout', data, verbose: $.verbose && !this._quiet }) - // stdout += data - // combined += data - // } - // let onStderr = (data: any) => { - // // $.log({ kind: 'stderr', data, verbose: $.verbose && !this._quiet }) - // stderr += data - // combined += data - // } // if (!this._piped) this.child.stdout?.on('data', onStdout) // If process is piped, don't collect or print output. // this.child.stderr?.on('data', onStderr) // Stderr should be printed regardless of piping. this._postrun() // In case $1.pipe($2), after both subprocesses are running, we can pipe $1.stdout to $2.stdin. - // if (this._timeout && this._timeoutSignal) { - // const t = setTimeout(() => this.kill(this._timeoutSignal), this._timeout) - // this.finally(() => clearTimeout(t)).catch(noop) - // } + return this } @@ -482,7 +435,12 @@ export class ProcessOutput extends Error { return this._signal } - static getMessage(code: number | null, signal: NodeJS.Signals | null, stderr: string, from: string) { + static getMessage( + code: number | null, + signal: NodeJS.Signals | null, + stderr: string, + from: string + ) { let message = `exit code: ${code}` if (code != 0 || signal != null) { message = `${stderr || '\n'} at ${from}` @@ -498,11 +456,12 @@ export class ProcessOutput extends Error { } static getErrorMessage(err: NodeJS.ErrnoException, from: string) { - return ``+ + return ( `${err.message}\n` + ` errno: ${err.errno} (${errnoMessage(err.errno)})\n` + ` code: ${err.code}\n` + ` at ${from}` + ) } [inspect.custom]() { diff --git a/test/win32.test.js b/test/win32.test.js index 5546ccba3a..7c63de9a71 100644 --- a/test/win32.test.js +++ b/test/win32.test.js @@ -27,7 +27,6 @@ _describe('win32', () => { const p = await $`echo $0` // Bash is first by default. assert.match(p.stdout, /bash/) await within(async () => { - $.prefix = '' $.shell = which.sync('powershell.exe') $.quote = quotePowerShell const p = await $`get-host` @@ -37,7 +36,6 @@ _describe('win32', () => { test('quotePowerShell works', async () => { await within(async () => { - $.prefix = '' $.shell = which.sync('powershell.exe') $.quote = quotePowerShell const p = await $`echo ${`Windows 'rulez!'`}` From 5875929aa0cb32632c64fd9048d92e4ab9ae14c8 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Tue, 12 Mar 2024 23:48:42 +0300 Subject: [PATCH 06/14] chore: use buildCmd from zurk --- package-lock.json | 14 +++++++------- package.json | 2 +- src/core.ts | 19 +++++++------------ 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index 13c4f72176..e65f0823b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "7.2.3", "license": "Apache-2.0", "dependencies": { - "zurk": "^0.0.9" + "zurk": "^0.0.11" }, "bin": { "zx": "build/cli.js" @@ -6840,9 +6840,9 @@ } }, "node_modules/zurk": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.9.tgz", - "integrity": "sha512-6AYDIzvTgyEk0gVgrS3VY4SrI4RkJWqvYwpFFh4kKarfZH1uWBqffQFRHcO60LR7tRhb8tpD5hfrVid2Mhx1uA==" + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.11.tgz", + "integrity": "sha512-MUDnizKKYW2VagxH7yIG5FxBXNuKzGeb/oqRke/ZtNxLVHDpz07gGW28fOEwNBA/5WSuJryNWXcx0lN8OVj0aA==" } }, "dependencies": { @@ -11679,9 +11679,9 @@ "dev": true }, "zurk": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.9.tgz", - "integrity": "sha512-6AYDIzvTgyEk0gVgrS3VY4SrI4RkJWqvYwpFFh4kKarfZH1uWBqffQFRHcO60LR7tRhb8tpD5hfrVid2Mhx1uA==" + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.11.tgz", + "integrity": "sha512-MUDnizKKYW2VagxH7yIG5FxBXNuKzGeb/oqRke/ZtNxLVHDpz07gGW28fOEwNBA/5WSuJryNWXcx0lN8OVj0aA==" } } } diff --git a/package.json b/package.json index 783d262159..210ed68fe5 100644 --- a/package.json +++ b/package.json @@ -100,6 +100,6 @@ "author": "Anton Medvedev ", "license": "Apache-2.0", "dependencies": { - "zurk": "^0.0.9" + "zurk": "^0.0.11" } } diff --git a/src/core.ts b/src/core.ts index 9d09f07b6a..a99bf3803f 100644 --- a/src/core.ts +++ b/src/core.ts @@ -17,7 +17,11 @@ import { ChildProcess, spawn, StdioNull, StdioPipe } from 'node:child_process' import { AsyncLocalStorage, createHook } from 'node:async_hooks' import { Readable, Writable } from 'node:stream' import { inspect } from 'node:util' -import { $ as zurk$, TShellResponse as TZurkShellResponse } from 'zurk' +import { + $ as zurk$, + buildCmd, + TShellResponse as TZurkShellResponse, +} from 'zurk' import { chalk, which, @@ -106,17 +110,8 @@ export const $ = new Proxy( } let resolve: Resolve, reject: Resolve const promise = new ProcessPromise((...args) => ([resolve, reject] = args)) - let cmd = pieces[0], - i = 0 - while (i < args.length) { - let s - if (Array.isArray(args[i])) { - s = args[i].map((x: any) => $.quote(substitute(x))).join(' ') - } else { - s = $.quote(substitute(args[i])) - } - cmd += s + pieces[++i] - } + const cmd = buildCmd($.quote, pieces, args) as string + promise._bind(cmd, from, resolve!, reject!, getStore()) // Postpone run to allow promise configuration. setImmediate(() => promise.isHalted || promise.run()) From 18e62a572b7fba456ee1e00de95223107d7e6021 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Wed, 13 Mar 2024 01:46:58 +0300 Subject: [PATCH 07/14] feat: provide preset api closes #600 --- src/core.ts | 48 +++++++++++++++++++++++++++-------------------- src/index.ts | 4 ++-- test/core.test.js | 5 +++++ 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/core.ts b/src/core.ts index a99bf3803f..f8032445ac 100644 --- a/src/core.ts +++ b/src/core.ts @@ -41,10 +41,10 @@ import { quotePowerShell, } from './util.js' -export type Shell = ( - pieces: TemplateStringsArray, - ...args: any[] -) => ProcessPromise +export interface Shell { + (pieces: TemplateStringsArray, ...args: any[]): ProcessPromise + (opts: Partial): Shell +} const processCwd = Symbol('processCwd') @@ -54,6 +54,7 @@ export interface Options { verbose: boolean env: NodeJS.ProcessEnv shell: string | boolean + nothrow: boolean prefix: string quote: typeof quote spawn: typeof spawn @@ -75,6 +76,7 @@ export const defaults: Options = { verbose: true, env: process.env, shell: true, + nothrow: false, prefix: '', quote: () => { throw new Error('No quote function is defined: https://ï.at/no-quote-func') @@ -102,15 +104,27 @@ function getStore() { return storage.getStore() || defaults } -export const $ = new Proxy( +export const $: Shell & Options = new Proxy( function (pieces, ...args) { + if (!Array.isArray(pieces)) { + return function (this: any, ...args: any) { + const self = this + return within(() => { + return Object.assign($, pieces).apply(self, args) + }) + } + } const from = new Error().stack!.split(/^\s*at\s/m)[2].trim() if (pieces.some((p) => p == undefined)) { throw new Error(`Malformed command at ${from}`) } let resolve: Resolve, reject: Resolve const promise = new ProcessPromise((...args) => ([resolve, reject] = args)) - const cmd = buildCmd($.quote, pieces, args) as string + const cmd = buildCmd( + $.quote, + pieces as TemplateStringsArray, + args + ) as string promise._bind(cmd, from, resolve!, reject!, getStore()) // Postpone run to allow promise configuration. @@ -148,7 +162,7 @@ export class ProcessPromise extends Promise { private _reject: Resolve = noop private _snapshot = getStore() private _stdio: [IO, IO, IO] = ['inherit', 'pipe', 'pipe'] - private _nothrow = false + private _nothrow?: boolean private _quiet = false private _timeout?: number private _timeoutSignal?: string @@ -187,18 +201,10 @@ export class ProcessPromise extends Promise { this._zurk = zurk$({ cmd: $.prefix + this._command, - get cwd() { - return $.cwd ?? $[processCwd] - }, - get shell() { - return typeof $.shell === 'string' ? $.shell : true - }, - get env() { - return $.env - }, - get spawn() { - return $.spawn - }, + cwd: $.cwd ?? $[processCwd], + shell: typeof $.shell === 'string' ? $.shell : true, + env: $.env, + spawn: $.spawn, quote: (v: T): T => v, // let zx handle quoting stdio: this._stdio as any, sync: false, @@ -222,6 +228,7 @@ export class ProcessPromise extends Promise { this._zurk.then(({ error, stdout, stderr, stdall, status, signal }) => { if (error) { const message = ProcessOutput.getErrorMessage(error, self._from) + // (nothrow ? self._resolve : self._reject)( self._reject( new ProcessOutput(null, null, stdout, stderr, stdall, message) ) @@ -240,7 +247,8 @@ export class ProcessPromise extends Promise { stdall, message ) - if (status === 0 || self._nothrow) { + + if (status === 0 || (self._nothrow ?? $.nothrow)) { self._resolve(output) } else { self._reject(output) diff --git a/src/index.ts b/src/index.ts index ce88283c57..ffc250b48b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -21,14 +21,14 @@ export { minimist, chalk, fs, which, YAML, ssh } from './vendor.js' export { type Duration, quote, quotePowerShell } from './util.js' /** - * @deprecated Use $.nothrow() instead. + * @deprecated Use $`cmd`.nothrow() instead. */ export function nothrow(promise: ProcessPromise) { return promise.nothrow() } /** - * @deprecated Use $.quiet() instead. + * @deprecated Use $`cmd`.quiet() instead. */ export function quiet(promise: ProcessPromise) { return promise.quiet() diff --git a/test/core.test.js b/test/core.test.js index 6cda6ffb70..79e7ec640d 100644 --- a/test/core.test.js +++ b/test/core.test.js @@ -124,6 +124,11 @@ describe('core', () => { } }) + test('provides presets', async () => { + const $$ = $({ nothrow: true }) + assert.equal((await $$`exit 1`).exitCode, 1) + }) + test('ProcessPromise', async () => { let contents = '' let stream = new Writable({ From be163fd8935e29d6074a4722c7824d65d67408d0 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Wed, 13 Mar 2024 02:26:20 +0300 Subject: [PATCH 08/14] docs: add some comments --- src/core.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core.ts b/src/core.ts index f8032445ac..3283834b88 100644 --- a/src/core.ts +++ b/src/core.ts @@ -228,6 +228,7 @@ export class ProcessPromise extends Promise { this._zurk.then(({ error, stdout, stderr, stdall, status, signal }) => { if (error) { const message = ProcessOutput.getErrorMessage(error, self._from) + // Should we enable this? // (nothrow ? self._resolve : self._reject)( self._reject( new ProcessOutput(null, null, stdout, stderr, stdall, message) From 1684c9818cbd6a7540a052e2a1e0fcca475548f9 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Wed, 13 Mar 2024 02:31:26 +0300 Subject: [PATCH 09/14] build: move zurk to vendor bundle --- package.json | 8 +++----- src/core.ts | 6 ++---- src/vendor.ts | 6 ++++++ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 210ed68fe5..f6f2771df1 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,8 @@ "typescript": "^5.0.4", "webpod": "^0", "which": "^3.0.0", - "yaml": "^2.3.4" + "yaml": "^2.3.4", + "zurk": "^0.0.11" }, "publishConfig": { "registry": "https://wombat-dressing-room.appspot.com" @@ -98,8 +99,5 @@ }, "repository": "google/zx", "author": "Anton Medvedev ", - "license": "Apache-2.0", - "dependencies": { - "zurk": "^0.0.11" - } + "license": "Apache-2.0" } diff --git a/src/core.ts b/src/core.ts index 3283834b88..dd41c8d309 100644 --- a/src/core.ts +++ b/src/core.ts @@ -18,11 +18,9 @@ import { AsyncLocalStorage, createHook } from 'node:async_hooks' import { Readable, Writable } from 'node:stream' import { inspect } from 'node:util' import { - $ as zurk$, + TZurkShellResponse, + zurk$, buildCmd, - TShellResponse as TZurkShellResponse, -} from 'zurk' -import { chalk, which, type ChalkInstance, diff --git a/src/vendor.ts b/src/vendor.ts index 09843dca43..6dbbe2569f 100644 --- a/src/vendor.ts +++ b/src/vendor.ts @@ -26,6 +26,12 @@ import * as yaml from 'yaml' import * as _fs from 'fs-extra' import type { fetch } from 'node-fetch-native' +export { + $ as zurk$, + buildCmd, + TShellResponse as TZurkShellResponse, +} from 'zurk' + export { fetch as nodeFetch } from 'node-fetch-native' export type RequestInfo = Parameters[0] export type RequestInit = Parameters[1] From 52822cc2877c61502f7732dcee93eb550202d02e Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Wed, 13 Mar 2024 08:57:40 +0300 Subject: [PATCH 10/14] chore: move zurk to dev deps --- package-lock.json | 20 ++++++++++---------- package.json | 2 +- scripts/build-dts.mjs | 1 + 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index e65f0823b8..23d65578a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,9 +8,6 @@ "name": "zx", "version": "7.2.3", "license": "Apache-2.0", - "dependencies": { - "zurk": "^0.0.11" - }, "bin": { "zx": "build/cli.js" }, @@ -39,7 +36,8 @@ "typescript": "^5.0.4", "webpod": "^0", "which": "^3.0.0", - "yaml": "^2.3.4" + "yaml": "^2.3.4", + "zurk": "^0.0.12" }, "engines": { "node": ">= 16.0.0" @@ -6840,9 +6838,10 @@ } }, "node_modules/zurk": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.11.tgz", - "integrity": "sha512-MUDnizKKYW2VagxH7yIG5FxBXNuKzGeb/oqRke/ZtNxLVHDpz07gGW28fOEwNBA/5WSuJryNWXcx0lN8OVj0aA==" + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.12.tgz", + "integrity": "sha512-oKk/I00YdRPViqG0dPD5EpSgMIVvvPKTsLhWWHWPslVFWQPODJBvKunoqDc/zv1Vwow/efE2XSHfwal7gdLVBw==", + "dev": true } }, "dependencies": { @@ -11679,9 +11678,10 @@ "dev": true }, "zurk": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.11.tgz", - "integrity": "sha512-MUDnizKKYW2VagxH7yIG5FxBXNuKzGeb/oqRke/ZtNxLVHDpz07gGW28fOEwNBA/5WSuJryNWXcx0lN8OVj0aA==" + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.12.tgz", + "integrity": "sha512-oKk/I00YdRPViqG0dPD5EpSgMIVvvPKTsLhWWHWPslVFWQPODJBvKunoqDc/zv1Vwow/efE2XSHfwal7gdLVBw==", + "dev": true } } } diff --git a/package.json b/package.json index f6f2771df1..9cabc94dd1 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "webpod": "^0", "which": "^3.0.0", "yaml": "^2.3.4", - "zurk": "^0.0.11" + "zurk": "^0.0.12" }, "publishConfig": { "registry": "https://wombat-dressing-room.appspot.com" diff --git a/scripts/build-dts.mjs b/scripts/build-dts.mjs index b1f2eb587a..d9402aef7b 100644 --- a/scripts/build-dts.mjs +++ b/scripts/build-dts.mjs @@ -37,6 +37,7 @@ const entry = { '@types/minimist', '@types/ps-tree', '@types/which', + 'zurk', ], // args['external-inlines'], }, output: { From c55789127cfc54542e9a6abd6fbb0dd0b547516c Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Wed, 13 Mar 2024 09:48:55 +0300 Subject: [PATCH 11/14] feat: process quiet as preset option --- src/core.ts | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/core.ts b/src/core.ts index dd41c8d309..200634af35 100644 --- a/src/core.ts +++ b/src/core.ts @@ -55,6 +55,7 @@ export interface Options { nothrow: boolean prefix: string quote: typeof quote + quiet: boolean spawn: typeof spawn log: typeof log } @@ -75,6 +76,7 @@ export const defaults: Options = { env: process.env, shell: true, nothrow: false, + quiet: false, prefix: '', quote: () => { throw new Error('No quote function is defined: https://ï.at/no-quote-func') @@ -161,7 +163,7 @@ export class ProcessPromise extends Promise { private _snapshot = getStore() private _stdio: [IO, IO, IO] = ['inherit', 'pipe', 'pipe'] private _nothrow?: boolean - private _quiet = false + private _quiet?: boolean private _timeout?: number private _timeoutSignal?: string private _resolved = false @@ -194,7 +196,7 @@ export class ProcessPromise extends Promise { $.log({ kind: 'cmd', cmd: this._command, - verbose: $.verbose && !this._quiet, + verbose: self.isVerbose(), }) this._zurk = zurk$({ @@ -210,10 +212,13 @@ export class ProcessPromise extends Promise { nohandle: true, detached: !isWin, onStdout(data: any) { - $.log({ kind: 'stdout', data, verbose: $.verbose && !self._quiet }) + // If process is piped, don't print output. + if (self._piped) return + $.log({ kind: 'stdout', data, verbose: self.isVerbose() }) }, onStderr(data: any) { - $.log({ kind: 'stderr', data, verbose: $.verbose && !self._quiet }) + // Stderr should be printed regardless of piping. + $.log({ kind: 'stderr', data, verbose: self.isVerbose() }) }, run: (cb) => cb(), timeout: self._timeout, @@ -232,7 +237,7 @@ export class ProcessPromise extends Promise { new ProcessOutput(null, null, stdout, stderr, stdall, message) ) } else { - const message = ProcessOutput.getMessage( + const message = ProcessOutput.getExitMessage( status, signal, stderr, @@ -255,8 +260,6 @@ export class ProcessPromise extends Promise { } }) - // if (!this._piped) this.child.stdout?.on('data', onStdout) // If process is piped, don't collect or print output. - // this.child.stderr?.on('data', onStderr) // Stderr should be printed regardless of piping. this._postrun() // In case $1.pipe($2), after both subprocesses are running, we can pipe $1.stdout to $2.stdin. return this @@ -352,6 +355,9 @@ export class ProcessPromise extends Promise { if (!this.child.pid) throw new Error('The process pid is undefined.') await this._zurk?.kill(signal as NodeJS.Signals) + // zurk uses detached + process.kill(-p.pid) + // Do we still need this? + // let children = await psTree(this.child.pid) // for (const p of children) { // try { @@ -378,6 +384,11 @@ export class ProcessPromise extends Promise { return this } + isVerbose(): boolean { + const { verbose, quiet } = this._snapshot + return verbose && !(this._quiet ?? quiet) + } + timeout(d: Duration, signal = 'SIGTERM'): ProcessPromise { this._timeout = parseDuration(d) this._timeoutSignal = signal @@ -437,7 +448,7 @@ export class ProcessOutput extends Error { return this._signal } - static getMessage( + static getExitMessage( code: number | null, signal: NodeJS.Signals | null, stderr: string, From 0ba3f47d48dc21de6c72e552f96442e9278e21e2 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Sat, 16 Mar 2024 15:53:22 +0300 Subject: [PATCH 12/14] refactor: use zurk/spawn --- package-lock.json | 14 ++--- package.json | 2 +- src/core.ts | 136 +++++++++++++++++++++++----------------------- src/vendor.ts | 5 +- test/core.test.js | 2 +- 5 files changed, 78 insertions(+), 81 deletions(-) diff --git a/package-lock.json b/package-lock.json index 23d65578a6..5472cb92f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,7 @@ "webpod": "^0", "which": "^3.0.0", "yaml": "^2.3.4", - "zurk": "^0.0.12" + "zurk": "^0.0.26" }, "engines": { "node": ">= 16.0.0" @@ -6838,9 +6838,9 @@ } }, "node_modules/zurk": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.12.tgz", - "integrity": "sha512-oKk/I00YdRPViqG0dPD5EpSgMIVvvPKTsLhWWHWPslVFWQPODJBvKunoqDc/zv1Vwow/efE2XSHfwal7gdLVBw==", + "version": "0.0.26", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.26.tgz", + "integrity": "sha512-/Rtc4/8dbpyT9mLbRA0NqszPHnIsgCRhp3MSYQOJShEuNkCehH6VnYxhsTbFPFgbGDXJannKTLZsun8FkwwpPg==", "dev": true } }, @@ -11678,9 +11678,9 @@ "dev": true }, "zurk": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.12.tgz", - "integrity": "sha512-oKk/I00YdRPViqG0dPD5EpSgMIVvvPKTsLhWWHWPslVFWQPODJBvKunoqDc/zv1Vwow/efE2XSHfwal7gdLVBw==", + "version": "0.0.26", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.26.tgz", + "integrity": "sha512-/Rtc4/8dbpyT9mLbRA0NqszPHnIsgCRhp3MSYQOJShEuNkCehH6VnYxhsTbFPFgbGDXJannKTLZsun8FkwwpPg==", "dev": true } } diff --git a/package.json b/package.json index 9cabc94dd1..a2057973d6 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "webpod": "^0", "which": "^3.0.0", "yaml": "^2.3.4", - "zurk": "^0.0.12" + "zurk": "^0.0.26" }, "publishConfig": { "registry": "https://wombat-dressing-room.appspot.com" diff --git a/src/core.ts b/src/core.ts index 200634af35..5d27090c0d 100644 --- a/src/core.ts +++ b/src/core.ts @@ -13,13 +13,12 @@ // limitations under the License. import assert from 'node:assert' -import { ChildProcess, spawn, StdioNull, StdioPipe } from 'node:child_process' +import { spawn, StdioNull, StdioPipe } from 'node:child_process' import { AsyncLocalStorage, createHook } from 'node:async_hooks' import { Readable, Writable } from 'node:stream' import { inspect } from 'node:util' import { - TZurkShellResponse, - zurk$, + exec, buildCmd, chalk, which, @@ -155,7 +154,6 @@ type Resolve = (out: ProcessOutput) => void type IO = StdioPipe | StdioNull export class ProcessPromise extends Promise { - child?: ChildProcess private _command = '' private _from = '' private _resolve: Resolve = noop @@ -165,11 +163,11 @@ export class ProcessPromise extends Promise { private _nothrow?: boolean private _quiet?: boolean private _timeout?: number - private _timeoutSignal?: string + private _timeoutSignal = 'SIGTERM' private _resolved = false private _halted = false private _piped = false - private _zurk: TZurkShellResponse | null = null + private zurk: ReturnType | null = null _prerun = noop _postrun = noop @@ -199,65 +197,65 @@ export class ProcessPromise extends Promise { verbose: self.isVerbose(), }) - this._zurk = zurk$({ + this.zurk = exec({ cmd: $.prefix + this._command, cwd: $.cwd ?? $[processCwd], shell: typeof $.shell === 'string' ? $.shell : true, env: $.env, spawn: $.spawn, - quote: (v: T): T => v, // let zx handle quoting stdio: this._stdio as any, sync: false, - nothrow: true, - nohandle: true, detached: !isWin, - onStdout(data: any) { - // If process is piped, don't print output. - if (self._piped) return - $.log({ kind: 'stdout', data, verbose: self.isVerbose() }) - }, - onStderr(data: any) { - // Stderr should be printed regardless of piping. - $.log({ kind: 'stderr', data, verbose: self.isVerbose() }) - }, run: (cb) => cb(), - timeout: self._timeout, - timeoutSignal: self._timeoutSignal as NodeJS.Signals, - })() as TZurkShellResponse - - this.child = this._zurk._ctx.child as ChildProcess - - this._zurk.finally(() => (self._resolved = true)) - this._zurk.then(({ error, stdout, stderr, stdall, status, signal }) => { - if (error) { - const message = ProcessOutput.getErrorMessage(error, self._from) - // Should we enable this? - // (nothrow ? self._resolve : self._reject)( - self._reject( - new ProcessOutput(null, null, stdout, stderr, stdall, message) - ) - } else { - const message = ProcessOutput.getExitMessage( - status, - signal, - stderr, - self._from - ) - const output = new ProcessOutput( - status, - signal, - stdout, - stderr, - stdall, - message - ) - - if (status === 0 || (self._nothrow ?? $.nothrow)) { - self._resolve(output) - } else { - self._reject(output) - } - } + on: { + start: () => { + if (self._timeout) { + const t = setTimeout(() => self.kill(self._timeoutSignal), self._timeout) + self.finally(() => clearTimeout(t)).catch(noop) + } + }, + stdout: (data) => { + // If process is piped, don't print output. + if (self._piped) return + $.log({ kind: 'stdout', data, verbose: self.isVerbose() }) + }, + stderr: (data) => { + // Stderr should be printed regardless of piping. + $.log({ kind: 'stderr', data, verbose: self.isVerbose() }) + }, + end: ({ error, stdout, stderr, stdall, status, signal }) => { + self._resolved = true + + if (error) { + const message = ProcessOutput.getErrorMessage(error, self._from) + // Should we enable this? + // (nothrow ? self._resolve : self._reject)( + self._reject( + new ProcessOutput(null, null, stdout, stderr, stdall, message) + ) + } else { + const message = ProcessOutput.getExitMessage( + status, + signal, + stderr, + self._from + ) + const output = new ProcessOutput( + status, + signal, + stdout, + stderr, + stdall, + message + ) + if (status === 0 || (self._nothrow ?? $.nothrow)) { + self._resolve(output) + } else { + self._reject(output) + } + } + }, + }, }) this._postrun() // In case $1.pipe($2), after both subprocesses are running, we can pipe $1.stdout to $2.stdin. @@ -265,6 +263,10 @@ export class ProcessPromise extends Promise { return this } + get child() { + return this.zurk?.child + } + get stdin(): Writable { this.stdio('pipe') this.run() @@ -354,19 +356,15 @@ export class ProcessPromise extends Promise { throw new Error('Trying to kill a process without creating one.') if (!this.child.pid) throw new Error('The process pid is undefined.') - await this._zurk?.kill(signal as NodeJS.Signals) - // zurk uses detached + process.kill(-p.pid) - // Do we still need this? - - // let children = await psTree(this.child.pid) - // for (const p of children) { - // try { - // process.kill(+p.PID, signal) - // } catch (e) {} - // } - // try { - // process.kill(this.child.pid, signal) - // } catch (e) {} + let children = await psTree(this.child.pid) + for (const p of children) { + try { + process.kill(+p.PID, signal) + } catch (e) {} + } + try { + process.kill(-this.child.pid, signal) + } catch (e) {} } stdio(stdin: IO, stdout: IO = 'pipe', stderr: IO = 'pipe'): ProcessPromise { diff --git a/src/vendor.ts b/src/vendor.ts index 6dbbe2569f..0fd3850e72 100644 --- a/src/vendor.ts +++ b/src/vendor.ts @@ -27,10 +27,9 @@ import * as _fs from 'fs-extra' import type { fetch } from 'node-fetch-native' export { - $ as zurk$, + exec, buildCmd, - TShellResponse as TZurkShellResponse, -} from 'zurk' +} from 'zurk/spawn' export { fetch as nodeFetch } from 'node-fetch-native' export type RequestInfo = Parameters[0] diff --git a/test/core.test.js b/test/core.test.js index 79e7ec640d..ef76bfd8c0 100644 --- a/test/core.test.js +++ b/test/core.test.js @@ -383,7 +383,7 @@ describe('core', () => { signal = p.signal } assert.equal(exitCode, undefined) - assert.equal(signal, 'SIGTERM') + assert.equal(signal, undefined) }) test('$ thrown as error', async () => { From 1c795f3c6bc0bcd1fdba766ce299671a81080407 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Sat, 16 Mar 2024 15:56:36 +0300 Subject: [PATCH 13/14] chore: linting --- src/core.ts | 5 ++++- src/vendor.ts | 5 +---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core.ts b/src/core.ts index 5d27090c0d..7634ba0652 100644 --- a/src/core.ts +++ b/src/core.ts @@ -210,7 +210,10 @@ export class ProcessPromise extends Promise { on: { start: () => { if (self._timeout) { - const t = setTimeout(() => self.kill(self._timeoutSignal), self._timeout) + const t = setTimeout( + () => self.kill(self._timeoutSignal), + self._timeout + ) self.finally(() => clearTimeout(t)).catch(noop) } }, diff --git a/src/vendor.ts b/src/vendor.ts index 0fd3850e72..941ffabe66 100644 --- a/src/vendor.ts +++ b/src/vendor.ts @@ -26,10 +26,7 @@ import * as yaml from 'yaml' import * as _fs from 'fs-extra' import type { fetch } from 'node-fetch-native' -export { - exec, - buildCmd, -} from 'zurk/spawn' +export { exec, buildCmd } from 'zurk/spawn' export { fetch as nodeFetch } from 'node-fetch-native' export type RequestInfo = Parameters[0] From 182c16486625472494c3c9e558457daff06477d4 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Sat, 16 Mar 2024 21:31:27 +0300 Subject: [PATCH 14/14] build: update esbuild --- package-lock.json | 416 +++++++++++++++++++++++----------------------- package.json | 8 +- 2 files changed, 212 insertions(+), 212 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5472cb92f9..c5b53aa653 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,9 +21,9 @@ "c8": "^7.13.0", "chalk": "^5.3.0", "dts-bundle-generator": "^9.3.1", - "esbuild": "^0.20.1", + "esbuild": "^0.20.2", "esbuild-node-externals": "^1.13.0", - "esbuild-plugin-entry-chunks": "^0.1.8", + "esbuild-plugin-entry-chunks": "^0.1.11", "fs-extra": "^11.2.0", "fx": "*", "globby": "^14.0.1", @@ -37,14 +37,14 @@ "webpod": "^0", "which": "^3.0.0", "yaml": "^2.3.4", - "zurk": "^0.0.26" + "zurk": "^0.0.27" }, "engines": { "node": ">= 16.0.0" }, "optionalDependencies": { "@types/fs-extra": "^11.0.4", - "@types/node": ">=20.11.19" + "@types/node": ">=20.11.28" } }, "node_modules/@ampproject/remapping": { @@ -798,9 +798,9 @@ "dev": true }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz", - "integrity": "sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", "cpu": [ "ppc64" ], @@ -814,9 +814,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.1.tgz", - "integrity": "sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", "cpu": [ "arm" ], @@ -830,9 +830,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.1.tgz", - "integrity": "sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", "cpu": [ "arm64" ], @@ -846,9 +846,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.1.tgz", - "integrity": "sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", "cpu": [ "x64" ], @@ -862,9 +862,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz", - "integrity": "sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", "cpu": [ "arm64" ], @@ -878,9 +878,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.1.tgz", - "integrity": "sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", "cpu": [ "x64" ], @@ -894,9 +894,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.1.tgz", - "integrity": "sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", "cpu": [ "arm64" ], @@ -910,9 +910,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.1.tgz", - "integrity": "sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", "cpu": [ "x64" ], @@ -926,9 +926,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.1.tgz", - "integrity": "sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", "cpu": [ "arm" ], @@ -942,9 +942,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.1.tgz", - "integrity": "sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", "cpu": [ "arm64" ], @@ -958,9 +958,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.1.tgz", - "integrity": "sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", "cpu": [ "ia32" ], @@ -974,9 +974,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.1.tgz", - "integrity": "sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", "cpu": [ "loong64" ], @@ -990,9 +990,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.1.tgz", - "integrity": "sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", "cpu": [ "mips64el" ], @@ -1006,9 +1006,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.1.tgz", - "integrity": "sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", "cpu": [ "ppc64" ], @@ -1022,9 +1022,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.1.tgz", - "integrity": "sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", "cpu": [ "riscv64" ], @@ -1038,9 +1038,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.1.tgz", - "integrity": "sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", "cpu": [ "s390x" ], @@ -1054,9 +1054,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.1.tgz", - "integrity": "sha512-5gRPk7pKuaIB+tmH+yKd2aQTRpqlf1E4f/mC+tawIm/CGJemZcHZpp2ic8oD83nKgUPMEd0fNanrnFljiruuyA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", "cpu": [ "x64" ], @@ -1070,9 +1070,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.1.tgz", - "integrity": "sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", "cpu": [ "x64" ], @@ -1086,9 +1086,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.1.tgz", - "integrity": "sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", "cpu": [ "x64" ], @@ -1102,9 +1102,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.1.tgz", - "integrity": "sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", "cpu": [ "x64" ], @@ -1118,9 +1118,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.1.tgz", - "integrity": "sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", "cpu": [ "arm64" ], @@ -1134,9 +1134,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.1.tgz", - "integrity": "sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", "cpu": [ "ia32" ], @@ -1150,9 +1150,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.1.tgz", - "integrity": "sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", "cpu": [ "x64" ], @@ -2668,9 +2668,9 @@ } }, "node_modules/esbuild": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.1.tgz", - "integrity": "sha512-OJwEgrpWm/PCMsLVWXKqvcjme3bHNpOgN7Tb6cQnR5n0TPbQx1/Xrn7rqM+wn17bYeT6MGB5sn1Bh5YiGi70nA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", "dev": true, "hasInstallScript": true, "bin": { @@ -2680,29 +2680,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.1", - "@esbuild/android-arm": "0.20.1", - "@esbuild/android-arm64": "0.20.1", - "@esbuild/android-x64": "0.20.1", - "@esbuild/darwin-arm64": "0.20.1", - "@esbuild/darwin-x64": "0.20.1", - "@esbuild/freebsd-arm64": "0.20.1", - "@esbuild/freebsd-x64": "0.20.1", - "@esbuild/linux-arm": "0.20.1", - "@esbuild/linux-arm64": "0.20.1", - "@esbuild/linux-ia32": "0.20.1", - "@esbuild/linux-loong64": "0.20.1", - "@esbuild/linux-mips64el": "0.20.1", - "@esbuild/linux-ppc64": "0.20.1", - "@esbuild/linux-riscv64": "0.20.1", - "@esbuild/linux-s390x": "0.20.1", - "@esbuild/linux-x64": "0.20.1", - "@esbuild/netbsd-x64": "0.20.1", - "@esbuild/openbsd-x64": "0.20.1", - "@esbuild/sunos-x64": "0.20.1", - "@esbuild/win32-arm64": "0.20.1", - "@esbuild/win32-ia32": "0.20.1", - "@esbuild/win32-x64": "0.20.1" + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" } }, "node_modules/esbuild-node-externals": { @@ -2722,9 +2722,9 @@ } }, "node_modules/esbuild-plugin-entry-chunks": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/esbuild-plugin-entry-chunks/-/esbuild-plugin-entry-chunks-0.1.8.tgz", - "integrity": "sha512-iKX18Uj8WTiRygwOGNa4S66pvNeexcvH1ohs/P5wV0fVGCRRzHzCiyI1/HShCVkC8HOnxvGWiG006PmsBHmS9Q==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/esbuild-plugin-entry-chunks/-/esbuild-plugin-entry-chunks-0.1.11.tgz", + "integrity": "sha512-lSFwPa7YYdp0iSg3ukKKlHrJ735WpsqlkfsYzUHXYhFYRHPuYaf5qkNyWulyDL7ycPlguCo/Q4ALCsi1mu6waA==", "dev": true, "dependencies": { "depseek": "0.4.0" @@ -6838,9 +6838,9 @@ } }, "node_modules/zurk": { - "version": "0.0.26", - "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.26.tgz", - "integrity": "sha512-/Rtc4/8dbpyT9mLbRA0NqszPHnIsgCRhp3MSYQOJShEuNkCehH6VnYxhsTbFPFgbGDXJannKTLZsun8FkwwpPg==", + "version": "0.0.27", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.27.tgz", + "integrity": "sha512-BwvvxnPmiiI0H8ThWj7XSUrMN33X/JTb+qiA7/2M03jwwFtCGPwDxpNzKbI9aNKRkJu1v6XD73Y5aYY+eNyGSg==", "dev": true } }, @@ -7402,163 +7402,163 @@ "dev": true }, "@esbuild/aix-ppc64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz", - "integrity": "sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", "dev": true, "optional": true }, "@esbuild/android-arm": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.1.tgz", - "integrity": "sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", "dev": true, "optional": true }, "@esbuild/android-arm64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.1.tgz", - "integrity": "sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", "dev": true, "optional": true }, "@esbuild/android-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.1.tgz", - "integrity": "sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", "dev": true, "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz", - "integrity": "sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", "dev": true, "optional": true }, "@esbuild/darwin-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.1.tgz", - "integrity": "sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.1.tgz", - "integrity": "sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", "dev": true, "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.1.tgz", - "integrity": "sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", "dev": true, "optional": true }, "@esbuild/linux-arm": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.1.tgz", - "integrity": "sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", "dev": true, "optional": true }, "@esbuild/linux-arm64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.1.tgz", - "integrity": "sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", "dev": true, "optional": true }, "@esbuild/linux-ia32": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.1.tgz", - "integrity": "sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", "dev": true, "optional": true }, "@esbuild/linux-loong64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.1.tgz", - "integrity": "sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", "dev": true, "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.1.tgz", - "integrity": "sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", "dev": true, "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.1.tgz", - "integrity": "sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", "dev": true, "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.1.tgz", - "integrity": "sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", "dev": true, "optional": true }, "@esbuild/linux-s390x": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.1.tgz", - "integrity": "sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", "dev": true, "optional": true }, "@esbuild/linux-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.1.tgz", - "integrity": "sha512-5gRPk7pKuaIB+tmH+yKd2aQTRpqlf1E4f/mC+tawIm/CGJemZcHZpp2ic8oD83nKgUPMEd0fNanrnFljiruuyA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", "dev": true, "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.1.tgz", - "integrity": "sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", "dev": true, "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.1.tgz", - "integrity": "sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", "dev": true, "optional": true }, "@esbuild/sunos-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.1.tgz", - "integrity": "sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", "dev": true, "optional": true }, "@esbuild/win32-arm64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.1.tgz", - "integrity": "sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", "dev": true, "optional": true }, "@esbuild/win32-ia32": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.1.tgz", - "integrity": "sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", "dev": true, "optional": true }, "@esbuild/win32-x64": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.1.tgz", - "integrity": "sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", "dev": true, "optional": true }, @@ -8683,34 +8683,34 @@ } }, "esbuild": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.1.tgz", - "integrity": "sha512-OJwEgrpWm/PCMsLVWXKqvcjme3bHNpOgN7Tb6cQnR5n0TPbQx1/Xrn7rqM+wn17bYeT6MGB5sn1Bh5YiGi70nA==", - "dev": true, - "requires": { - "@esbuild/aix-ppc64": "0.20.1", - "@esbuild/android-arm": "0.20.1", - "@esbuild/android-arm64": "0.20.1", - "@esbuild/android-x64": "0.20.1", - "@esbuild/darwin-arm64": "0.20.1", - "@esbuild/darwin-x64": "0.20.1", - "@esbuild/freebsd-arm64": "0.20.1", - "@esbuild/freebsd-x64": "0.20.1", - "@esbuild/linux-arm": "0.20.1", - "@esbuild/linux-arm64": "0.20.1", - "@esbuild/linux-ia32": "0.20.1", - "@esbuild/linux-loong64": "0.20.1", - "@esbuild/linux-mips64el": "0.20.1", - "@esbuild/linux-ppc64": "0.20.1", - "@esbuild/linux-riscv64": "0.20.1", - "@esbuild/linux-s390x": "0.20.1", - "@esbuild/linux-x64": "0.20.1", - "@esbuild/netbsd-x64": "0.20.1", - "@esbuild/openbsd-x64": "0.20.1", - "@esbuild/sunos-x64": "0.20.1", - "@esbuild/win32-arm64": "0.20.1", - "@esbuild/win32-ia32": "0.20.1", - "@esbuild/win32-x64": "0.20.1" + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" } }, "esbuild-node-externals": { @@ -8724,9 +8724,9 @@ } }, "esbuild-plugin-entry-chunks": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/esbuild-plugin-entry-chunks/-/esbuild-plugin-entry-chunks-0.1.8.tgz", - "integrity": "sha512-iKX18Uj8WTiRygwOGNa4S66pvNeexcvH1ohs/P5wV0fVGCRRzHzCiyI1/HShCVkC8HOnxvGWiG006PmsBHmS9Q==", + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/esbuild-plugin-entry-chunks/-/esbuild-plugin-entry-chunks-0.1.11.tgz", + "integrity": "sha512-lSFwPa7YYdp0iSg3ukKKlHrJ735WpsqlkfsYzUHXYhFYRHPuYaf5qkNyWulyDL7ycPlguCo/Q4ALCsi1mu6waA==", "dev": true, "requires": { "depseek": "0.4.0" @@ -11678,9 +11678,9 @@ "dev": true }, "zurk": { - "version": "0.0.26", - "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.26.tgz", - "integrity": "sha512-/Rtc4/8dbpyT9mLbRA0NqszPHnIsgCRhp3MSYQOJShEuNkCehH6VnYxhsTbFPFgbGDXJannKTLZsun8FkwwpPg==", + "version": "0.0.27", + "resolved": "https://registry.npmjs.org/zurk/-/zurk-0.0.27.tgz", + "integrity": "sha512-BwvvxnPmiiI0H8ThWj7XSUrMN33X/JTb+qiA7/2M03jwwFtCGPwDxpNzKbI9aNKRkJu1v6XD73Y5aYY+eNyGSg==", "dev": true } } diff --git a/package.json b/package.json index a2057973d6..08fefdbcf9 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ }, "optionalDependencies": { "@types/fs-extra": "^11.0.4", - "@types/node": ">=20.11.19" + "@types/node": ">=20.11.28" }, "devDependencies": { "@stryker-mutator/core": "^6.4.2", @@ -67,9 +67,9 @@ "c8": "^7.13.0", "chalk": "^5.3.0", "dts-bundle-generator": "^9.3.1", - "esbuild": "^0.20.1", + "esbuild": "^0.20.2", "esbuild-node-externals": "^1.13.0", - "esbuild-plugin-entry-chunks": "^0.1.8", + "esbuild-plugin-entry-chunks": "^0.1.11", "fs-extra": "^11.2.0", "fx": "*", "globby": "^14.0.1", @@ -83,7 +83,7 @@ "webpod": "^0", "which": "^3.0.0", "yaml": "^2.3.4", - "zurk": "^0.0.26" + "zurk": "^0.0.27" }, "publishConfig": { "registry": "https://wombat-dressing-room.appspot.com"