@ai-ecoverse/slicc-jsh 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -4
- package/dist/host/jsh.mjs +9 -884
- package/dist/host/main.mjs +893 -0
- package/dist/jsh.mjs +729 -202
- package/dist/meta-main.json +1 -1
- package/dist/node.mjs +1491 -117
- package/package.json +17 -5
package/dist/node.mjs
CHANGED
|
@@ -1536,6 +1536,952 @@ ${e3}`;
|
|
|
1536
1536
|
}
|
|
1537
1537
|
});
|
|
1538
1538
|
|
|
1539
|
+
// src/runtime/exit.mjs
|
|
1540
|
+
var NodeExitError = class extends Error {
|
|
1541
|
+
constructor(code) {
|
|
1542
|
+
super(`Process exited with code ${code}`);
|
|
1543
|
+
this.name = "NodeExitError";
|
|
1544
|
+
this.code = code;
|
|
1545
|
+
}
|
|
1546
|
+
};
|
|
1547
|
+
function numericExitCode(value) {
|
|
1548
|
+
const n = Number(value);
|
|
1549
|
+
return Number.isFinite(n) ? n & 255 : 0;
|
|
1550
|
+
}
|
|
1551
|
+
function describeReceived(value) {
|
|
1552
|
+
if (typeof value === "string") return `type string ('${value}')`;
|
|
1553
|
+
if (typeof value === "boolean") return `type boolean (${value})`;
|
|
1554
|
+
if (typeof value === "bigint") return `type bigint (${value}n)`;
|
|
1555
|
+
if (Array.isArray(value)) return "an instance of Array";
|
|
1556
|
+
if (typeof value === "object" && value !== null) return "an instance of Object";
|
|
1557
|
+
return `type ${typeof value}`;
|
|
1558
|
+
}
|
|
1559
|
+
function assignProcessExitCode(value) {
|
|
1560
|
+
if (value === null || value === void 0) return void 0;
|
|
1561
|
+
if (typeof value === "string") {
|
|
1562
|
+
const n = Number(value);
|
|
1563
|
+
if (value !== "" && Number.isInteger(n)) return n === 0 ? 0 : n;
|
|
1564
|
+
const err2 = new TypeError(
|
|
1565
|
+
`The "code" argument must be of type number. Received ${describeReceived(value)}`
|
|
1566
|
+
);
|
|
1567
|
+
err2.code = "ERR_INVALID_ARG_TYPE";
|
|
1568
|
+
throw err2;
|
|
1569
|
+
}
|
|
1570
|
+
if (typeof value === "number") {
|
|
1571
|
+
if (Number.isInteger(value)) return value === 0 ? 0 : value;
|
|
1572
|
+
const err2 = new RangeError(
|
|
1573
|
+
`The value of "code" is out of range. It must be an integer. Received ${String(value)}`
|
|
1574
|
+
);
|
|
1575
|
+
err2.code = "ERR_OUT_OF_RANGE";
|
|
1576
|
+
throw err2;
|
|
1577
|
+
}
|
|
1578
|
+
const err = new TypeError(
|
|
1579
|
+
`The "code" argument must be of type number. Received ${describeReceived(value)}`
|
|
1580
|
+
);
|
|
1581
|
+
err.code = "ERR_INVALID_ARG_TYPE";
|
|
1582
|
+
throw err;
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
// package.json
|
|
1586
|
+
var package_default = {
|
|
1587
|
+
name: "@ai-ecoverse/slicc-jsh",
|
|
1588
|
+
version: "0.3.0",
|
|
1589
|
+
description: "Node.js-compatible runtime for slicc-kernel: the node and jsh commands (abi: js)",
|
|
1590
|
+
type: "module",
|
|
1591
|
+
license: "Apache-2.0",
|
|
1592
|
+
repository: {
|
|
1593
|
+
type: "git",
|
|
1594
|
+
url: "git+https://github.com/ai-ecoverse/slicc-jsh.git"
|
|
1595
|
+
},
|
|
1596
|
+
homepage: "https://github.com/ai-ecoverse/slicc-jsh",
|
|
1597
|
+
bugs: {
|
|
1598
|
+
url: "https://github.com/ai-ecoverse/slicc-jsh/issues"
|
|
1599
|
+
},
|
|
1600
|
+
bin: {
|
|
1601
|
+
jsh: "dist/host/jsh.mjs"
|
|
1602
|
+
},
|
|
1603
|
+
engines: {
|
|
1604
|
+
node: ">=22",
|
|
1605
|
+
"slicc-kernel": ">=1.53.2"
|
|
1606
|
+
},
|
|
1607
|
+
publishConfig: {
|
|
1608
|
+
access: "public",
|
|
1609
|
+
provenance: true
|
|
1610
|
+
},
|
|
1611
|
+
fledgling: {
|
|
1612
|
+
provider: "github",
|
|
1613
|
+
workflow: "release.yml",
|
|
1614
|
+
repo: "ai-ecoverse/slicc-jsh",
|
|
1615
|
+
publish: true
|
|
1616
|
+
},
|
|
1617
|
+
files: [
|
|
1618
|
+
"LICENSE",
|
|
1619
|
+
"NOTICE",
|
|
1620
|
+
"README.md",
|
|
1621
|
+
"dist"
|
|
1622
|
+
],
|
|
1623
|
+
slicc: {
|
|
1624
|
+
commands: {
|
|
1625
|
+
node: {
|
|
1626
|
+
abi: "js",
|
|
1627
|
+
module: "dist/node.mjs",
|
|
1628
|
+
argv0: "node"
|
|
1629
|
+
},
|
|
1630
|
+
jsh: {
|
|
1631
|
+
abi: "js",
|
|
1632
|
+
module: "dist/jsh.mjs",
|
|
1633
|
+
argv0: "jsh"
|
|
1634
|
+
}
|
|
1635
|
+
},
|
|
1636
|
+
binfmt: {
|
|
1637
|
+
".jsh": "jsh"
|
|
1638
|
+
}
|
|
1639
|
+
},
|
|
1640
|
+
scripts: {
|
|
1641
|
+
build: "node scripts/build.mjs && node scripts/build-host.mjs",
|
|
1642
|
+
prepack: "npm run build",
|
|
1643
|
+
prepare: "npm run build",
|
|
1644
|
+
lint: "node scripts/lint.mjs",
|
|
1645
|
+
test: "npm run test:golden && npm run test:jsh && npm run test:integration",
|
|
1646
|
+
"test:golden": "node --max-old-space-size=512 scripts/golden.mjs check",
|
|
1647
|
+
"test:integration": "node --max-old-space-size=512 --test --test-timeout=120000 test/integration/*.test.mjs",
|
|
1648
|
+
"test:cert": "node --max-old-space-size=512 test/integration/cert/run.mjs",
|
|
1649
|
+
"test:node-parallel": "node --max-old-space-size=512 test/node-parallel/run.mjs",
|
|
1650
|
+
"golden:record": "node --max-old-space-size=512 scripts/golden.mjs record",
|
|
1651
|
+
"test:jsh": "node --max-old-space-size=512 scripts/jsh-golden.mjs check",
|
|
1652
|
+
"jsh:record": "node --max-old-space-size=512 scripts/jsh-golden.mjs record",
|
|
1653
|
+
release: "semantic-release",
|
|
1654
|
+
trust: "npx fledgling sync -y --skip-publish",
|
|
1655
|
+
"trust:dry": "npx fledgling sync --dry-run -y --skip-publish"
|
|
1656
|
+
},
|
|
1657
|
+
devDependencies: {
|
|
1658
|
+
"@ai-ecoverse/slicc-kernel": "1.59.0",
|
|
1659
|
+
"@ai-ecoverse/wasi-pnpm": "12.9.1-8",
|
|
1660
|
+
"abort-controller": "3.0.0",
|
|
1661
|
+
acorn: "8.19.0",
|
|
1662
|
+
esbuild: "0.28.2",
|
|
1663
|
+
"node-inspect-extracted": "3.3.4",
|
|
1664
|
+
process: "0.11.10",
|
|
1665
|
+
"readable-stream": "4.8.0",
|
|
1666
|
+
"semantic-release": "25.0.9",
|
|
1667
|
+
string_decoder: "1.3.0",
|
|
1668
|
+
ws: "8.22.0"
|
|
1669
|
+
}
|
|
1670
|
+
};
|
|
1671
|
+
|
|
1672
|
+
// src/jsh/parse-flags.mjs
|
|
1673
|
+
function parseFlags(argv) {
|
|
1674
|
+
const positional = [];
|
|
1675
|
+
const flags = {};
|
|
1676
|
+
const passthrough = [];
|
|
1677
|
+
const set = (key, value) => {
|
|
1678
|
+
if (key in flags) {
|
|
1679
|
+
const prev = flags[key];
|
|
1680
|
+
if (Array.isArray(prev)) prev.push(String(value));
|
|
1681
|
+
else flags[key] = [String(prev), String(value)];
|
|
1682
|
+
} else {
|
|
1683
|
+
flags[key] = value;
|
|
1684
|
+
}
|
|
1685
|
+
};
|
|
1686
|
+
let i2 = 2;
|
|
1687
|
+
while (i2 < argv.length) {
|
|
1688
|
+
const arg = argv[i2];
|
|
1689
|
+
if (arg === "--") {
|
|
1690
|
+
passthrough.push(...argv.slice(i2 + 1));
|
|
1691
|
+
break;
|
|
1692
|
+
}
|
|
1693
|
+
if (arg.startsWith("--")) {
|
|
1694
|
+
const body = arg.slice(2);
|
|
1695
|
+
const eq = body.indexOf("=");
|
|
1696
|
+
if (eq !== -1) {
|
|
1697
|
+
set(body.slice(0, eq), body.slice(eq + 1));
|
|
1698
|
+
i2++;
|
|
1699
|
+
continue;
|
|
1700
|
+
}
|
|
1701
|
+
const next = argv[i2 + 1];
|
|
1702
|
+
if (next !== void 0 && !next.startsWith("-")) {
|
|
1703
|
+
set(body, next);
|
|
1704
|
+
i2 += 2;
|
|
1705
|
+
continue;
|
|
1706
|
+
}
|
|
1707
|
+
set(body, true);
|
|
1708
|
+
i2++;
|
|
1709
|
+
continue;
|
|
1710
|
+
}
|
|
1711
|
+
if (arg.startsWith("-") && arg.length > 1) {
|
|
1712
|
+
for (const ch of arg.slice(1)) set(ch, true);
|
|
1713
|
+
i2++;
|
|
1714
|
+
continue;
|
|
1715
|
+
}
|
|
1716
|
+
positional.push(arg);
|
|
1717
|
+
i2++;
|
|
1718
|
+
}
|
|
1719
|
+
const subcommand = positional.length > 0 && /^[a-z][\w-]*$/i.test(positional[0]) ? positional[0] : null;
|
|
1720
|
+
return { positional, flags, subcommand, passthrough };
|
|
1721
|
+
}
|
|
1722
|
+
function attachParseFlags(argv) {
|
|
1723
|
+
if (Object.prototype.hasOwnProperty.call(argv, "parseFlags")) return argv;
|
|
1724
|
+
Object.defineProperty(argv, "parseFlags", {
|
|
1725
|
+
value: () => parseFlags(argv),
|
|
1726
|
+
enumerable: false,
|
|
1727
|
+
writable: false,
|
|
1728
|
+
configurable: true
|
|
1729
|
+
});
|
|
1730
|
+
return argv;
|
|
1731
|
+
}
|
|
1732
|
+
|
|
1733
|
+
// src/jsh/sliccy/exec.mjs
|
|
1734
|
+
var SIGNALS = { SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGKILL: 9, SIGTERM: 15 };
|
|
1735
|
+
function killExitCode(sig = "SIGTERM") {
|
|
1736
|
+
const n = typeof sig === "number" ? sig : SIGNALS[sig] ?? 15;
|
|
1737
|
+
return 128 + n;
|
|
1738
|
+
}
|
|
1739
|
+
function createExec(engine) {
|
|
1740
|
+
const shellArgv = (command, args = []) => [...engine.shell, command, "jsh", ...args];
|
|
1741
|
+
const run = (argv, stdin) => engine.spawn(argv, { stdin }).done;
|
|
1742
|
+
const exec = (command) => {
|
|
1743
|
+
if (typeof command !== "string") throw new TypeError("exec(command): command must be a string");
|
|
1744
|
+
return run(shellArgv(command));
|
|
1745
|
+
};
|
|
1746
|
+
exec.spawn = (argv) => {
|
|
1747
|
+
if (!Array.isArray(argv) || argv.length === 0) {
|
|
1748
|
+
throw new TypeError("exec.spawn(argv): argv must be a non-empty array");
|
|
1749
|
+
}
|
|
1750
|
+
return run(argv.map(String));
|
|
1751
|
+
};
|
|
1752
|
+
exec.start = (commandOrArgv, opts = {}) => {
|
|
1753
|
+
const argv = Array.isArray(commandOrArgv) ? [...commandOrArgv.map(String), ...(opts.args ?? []).map(String)] : shellArgv(String(commandOrArgv), (opts.args ?? []).map(String));
|
|
1754
|
+
const chunks = [];
|
|
1755
|
+
let child = null;
|
|
1756
|
+
let killed = false;
|
|
1757
|
+
let resolveDone;
|
|
1758
|
+
let rejectDone;
|
|
1759
|
+
const done = new Promise((resolve2, reject) => {
|
|
1760
|
+
resolveDone = resolve2;
|
|
1761
|
+
rejectDone = reject;
|
|
1762
|
+
});
|
|
1763
|
+
const fire = () => {
|
|
1764
|
+
if (child || killed) return;
|
|
1765
|
+
const stdin = chunks.length > 0 ? chunks.join("") : opts.stdin;
|
|
1766
|
+
child = engine.spawn(argv, { stdin });
|
|
1767
|
+
child.done.then(resolveDone, rejectDone);
|
|
1768
|
+
};
|
|
1769
|
+
return {
|
|
1770
|
+
kill(sig) {
|
|
1771
|
+
if (child) return Promise.resolve(child.kill(sig ?? "SIGTERM")).then(() => true);
|
|
1772
|
+
killed = true;
|
|
1773
|
+
resolveDone({ stdout: "", stderr: "", exitCode: killExitCode(sig) });
|
|
1774
|
+
return Promise.resolve(true);
|
|
1775
|
+
},
|
|
1776
|
+
stdin: {
|
|
1777
|
+
write(chunk) {
|
|
1778
|
+
if (!child && !killed) chunks.push(String(chunk));
|
|
1779
|
+
},
|
|
1780
|
+
end: () => fire()
|
|
1781
|
+
},
|
|
1782
|
+
done
|
|
1783
|
+
};
|
|
1784
|
+
};
|
|
1785
|
+
exec.exec = exec;
|
|
1786
|
+
return exec;
|
|
1787
|
+
}
|
|
1788
|
+
function dirnameOf(path) {
|
|
1789
|
+
if (!path) return "";
|
|
1790
|
+
const idx = path.lastIndexOf("/");
|
|
1791
|
+
if (idx < 0) return "";
|
|
1792
|
+
if (idx === 0) return "/";
|
|
1793
|
+
return path.slice(0, idx);
|
|
1794
|
+
}
|
|
1795
|
+
function joinChild(dir, name) {
|
|
1796
|
+
if (dir === "") return name;
|
|
1797
|
+
if (dir === "/") return `/${name}`;
|
|
1798
|
+
return `${dir}/${name}`;
|
|
1799
|
+
}
|
|
1800
|
+
function createSkill({ argv, fs, exec }) {
|
|
1801
|
+
const dir = dirnameOf(argv[1] ?? "");
|
|
1802
|
+
const refs = joinChild(dir, "references");
|
|
1803
|
+
const assets = joinChild(dir, "assets");
|
|
1804
|
+
const configPath = joinChild(dir, ".config");
|
|
1805
|
+
async function readConfig() {
|
|
1806
|
+
let text;
|
|
1807
|
+
try {
|
|
1808
|
+
if (!fs.existsSync(configPath)) return null;
|
|
1809
|
+
text = await fs.promises.readFile(configPath, "utf8");
|
|
1810
|
+
} catch {
|
|
1811
|
+
return null;
|
|
1812
|
+
}
|
|
1813
|
+
if (!String(text).trim()) return null;
|
|
1814
|
+
let parsed;
|
|
1815
|
+
try {
|
|
1816
|
+
parsed = JSON.parse(text);
|
|
1817
|
+
} catch (err) {
|
|
1818
|
+
throw new Error(`skill.config(): failed to parse ${configPath}: ${err?.message ?? err}`);
|
|
1819
|
+
}
|
|
1820
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
|
|
1821
|
+
throw new Error(`skill.config(): ${configPath} must contain a JSON object`);
|
|
1822
|
+
}
|
|
1823
|
+
async function config(updates) {
|
|
1824
|
+
const existing = await readConfig();
|
|
1825
|
+
if (updates === void 0) return existing;
|
|
1826
|
+
if (updates === null || typeof updates !== "object" || Array.isArray(updates)) {
|
|
1827
|
+
throw new TypeError("skill.config(updates): updates must be a plain object");
|
|
1828
|
+
}
|
|
1829
|
+
const merged = { ...existing ?? {}, ...updates };
|
|
1830
|
+
await fs.promises.writeFile(configPath, `${JSON.stringify(merged, null, 2)}
|
|
1831
|
+
`);
|
|
1832
|
+
return merged;
|
|
1833
|
+
}
|
|
1834
|
+
async function token(providerId) {
|
|
1835
|
+
if (typeof providerId !== "string" || !providerId.trim()) {
|
|
1836
|
+
throw new TypeError("skill.token(providerId): providerId must be a non-empty string");
|
|
1837
|
+
}
|
|
1838
|
+
const { stdout, stderr, exitCode } = await exec.spawn(["oauth-token", providerId]);
|
|
1839
|
+
if (exitCode !== 0) {
|
|
1840
|
+
const msg = stderr.trim() || `oauth-token exited with code ${exitCode}`;
|
|
1841
|
+
throw new Error(`skill.token('${providerId}'): ${msg}`);
|
|
1842
|
+
}
|
|
1843
|
+
return stdout.replace(/\r?\n+$/, "");
|
|
1844
|
+
}
|
|
1845
|
+
return Object.freeze({ dir, refs, assets, config, token });
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
// src/jsh/sliccy/http.mjs
|
|
1849
|
+
var HttpError = class extends Error {
|
|
1850
|
+
constructor(status, statusText, url, body) {
|
|
1851
|
+
const detail = typeof body === "string" && body ? `: ${body.slice(0, 200)}` : body && typeof body === "object" ? `: ${safeJson(body).slice(0, 200)}` : "";
|
|
1852
|
+
super(`HTTP ${status} ${statusText} ${url}${detail}`);
|
|
1853
|
+
this.name = "HttpError";
|
|
1854
|
+
this.status = status;
|
|
1855
|
+
this.statusText = statusText;
|
|
1856
|
+
this.url = url;
|
|
1857
|
+
this.body = body;
|
|
1858
|
+
}
|
|
1859
|
+
};
|
|
1860
|
+
function safeJson(value) {
|
|
1861
|
+
try {
|
|
1862
|
+
return JSON.stringify(value);
|
|
1863
|
+
} catch {
|
|
1864
|
+
return String(value);
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
var DEFAULT_BACKOFF_BASE_MS = 500;
|
|
1868
|
+
function buildUrl(baseUrl, path, params) {
|
|
1869
|
+
let url;
|
|
1870
|
+
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(path)) url = path;
|
|
1871
|
+
else if (baseUrl) {
|
|
1872
|
+
const base = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
1873
|
+
url = `${base}${path.startsWith("/") ? path : `/${path}`}`;
|
|
1874
|
+
} else url = path;
|
|
1875
|
+
if (!params) return url;
|
|
1876
|
+
const qs = [];
|
|
1877
|
+
const push = (k, v) => qs.push(`${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);
|
|
1878
|
+
for (const [k, v] of Object.entries(params)) {
|
|
1879
|
+
if (v === void 0 || v === null) continue;
|
|
1880
|
+
if (Array.isArray(v)) {
|
|
1881
|
+
for (const item of v) if (item !== void 0 && item !== null) push(k, item);
|
|
1882
|
+
} else push(k, v);
|
|
1883
|
+
}
|
|
1884
|
+
if (qs.length === 0) return url;
|
|
1885
|
+
return url + (url.includes("?") ? "&" : "?") + qs.join("&");
|
|
1886
|
+
}
|
|
1887
|
+
function isJsonContentType(ct) {
|
|
1888
|
+
if (!ct) return false;
|
|
1889
|
+
const lower = ct.toLowerCase();
|
|
1890
|
+
return lower.startsWith("application/json") || /[+/]json(;|$|\s)/.test(lower);
|
|
1891
|
+
}
|
|
1892
|
+
function parseRetryAfter(value) {
|
|
1893
|
+
const trimmed = value?.trim();
|
|
1894
|
+
if (!trimmed) return null;
|
|
1895
|
+
if (/^\d+(\.\d+)?$/.test(trimmed)) {
|
|
1896
|
+
const seconds = Number(trimmed);
|
|
1897
|
+
if (Number.isFinite(seconds) && seconds >= 0) return Math.round(seconds * 1e3);
|
|
1898
|
+
}
|
|
1899
|
+
const date = Date.parse(trimmed);
|
|
1900
|
+
if (Number.isFinite(date)) return Math.max(0, date - Date.now());
|
|
1901
|
+
return null;
|
|
1902
|
+
}
|
|
1903
|
+
async function readBody(resp) {
|
|
1904
|
+
if (isJsonContentType(resp.headers.get("content-type"))) {
|
|
1905
|
+
const text = await resp.text();
|
|
1906
|
+
if (!text) return null;
|
|
1907
|
+
try {
|
|
1908
|
+
return JSON.parse(text);
|
|
1909
|
+
} catch {
|
|
1910
|
+
return text;
|
|
1911
|
+
}
|
|
1912
|
+
}
|
|
1913
|
+
return resp.text();
|
|
1914
|
+
}
|
|
1915
|
+
function serializeBody(body, headers) {
|
|
1916
|
+
if (body === void 0 || body === null) return void 0;
|
|
1917
|
+
if (typeof body === "string") return body;
|
|
1918
|
+
if (body instanceof ArrayBuffer || ArrayBuffer.isView(body) || typeof Blob !== "undefined" && body instanceof Blob || typeof FormData !== "undefined" && body instanceof FormData || typeof URLSearchParams !== "undefined" && body instanceof URLSearchParams || typeof ReadableStream !== "undefined" && body instanceof ReadableStream) {
|
|
1919
|
+
return body;
|
|
1920
|
+
}
|
|
1921
|
+
if (typeof body === "object") {
|
|
1922
|
+
if (!Object.keys(headers).some((k) => k.toLowerCase() === "content-type")) {
|
|
1923
|
+
headers["Content-Type"] = "application/json";
|
|
1924
|
+
}
|
|
1925
|
+
return JSON.stringify(body);
|
|
1926
|
+
}
|
|
1927
|
+
return String(body);
|
|
1928
|
+
}
|
|
1929
|
+
function createHttp({ fetch, sleep = (ms) => new Promise((r) => setTimeout(r, ms)) }) {
|
|
1930
|
+
function makeClient(config = {}) {
|
|
1931
|
+
const retryOn = new Set(config.retry?.on ?? []);
|
|
1932
|
+
const maxAttempts = Math.max(1, Math.trunc(config.retry?.maxAttempts ?? 1));
|
|
1933
|
+
async function request(method, path, opts = {}) {
|
|
1934
|
+
if (typeof fetch !== "function") throw new Error("sliccy:http: fetch is not available");
|
|
1935
|
+
const url = buildUrl(config.baseUrl, path, opts.params);
|
|
1936
|
+
const headers = { ...config.headers ?? {}, ...opts.headers ?? {} };
|
|
1937
|
+
if (config.token) {
|
|
1938
|
+
const tok = await config.token({ method, path, url });
|
|
1939
|
+
if (tok && !Object.keys(headers).some((k) => k.toLowerCase() === "authorization")) {
|
|
1940
|
+
headers.Authorization = `Bearer ${tok}`;
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
const body = serializeBody(opts.body, headers);
|
|
1944
|
+
const init = { method, headers };
|
|
1945
|
+
if (body !== void 0) init.body = body;
|
|
1946
|
+
for (let attempt = 0; ; attempt++) {
|
|
1947
|
+
const timeoutCtl = config.timeoutMs ? new AbortController() : null;
|
|
1948
|
+
const timeoutId = timeoutCtl ? setTimeout(() => timeoutCtl.abort(new Error("timeout")), config.timeoutMs) : null;
|
|
1949
|
+
const signal = opts.signal && timeoutCtl ? AbortSignal.any([opts.signal, timeoutCtl.signal]) : opts.signal ?? timeoutCtl?.signal;
|
|
1950
|
+
let resp;
|
|
1951
|
+
try {
|
|
1952
|
+
resp = await fetch(url, signal ? { ...init, signal } : init);
|
|
1953
|
+
} finally {
|
|
1954
|
+
if (timeoutId !== null) clearTimeout(timeoutId);
|
|
1955
|
+
}
|
|
1956
|
+
if (resp.ok) {
|
|
1957
|
+
const respBody = await readBody(resp);
|
|
1958
|
+
if (opts.raw) {
|
|
1959
|
+
return {
|
|
1960
|
+
body: respBody,
|
|
1961
|
+
headers: Object.fromEntries(resp.headers.entries()),
|
|
1962
|
+
status: resp.status
|
|
1963
|
+
};
|
|
1964
|
+
}
|
|
1965
|
+
return respBody;
|
|
1966
|
+
}
|
|
1967
|
+
if (attempt + 1 >= maxAttempts || !retryOn.has(resp.status)) {
|
|
1968
|
+
const errBody = await readBody(resp).catch(() => null);
|
|
1969
|
+
throw new HttpError(resp.status, resp.statusText, url, errBody);
|
|
1970
|
+
}
|
|
1971
|
+
const retryAfter = parseRetryAfter(resp.headers.get("retry-after"));
|
|
1972
|
+
await sleep(retryAfter ?? DEFAULT_BACKOFF_BASE_MS * 2 ** attempt);
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
return Object.freeze({
|
|
1976
|
+
get: (path, opts) => request("GET", path, opts),
|
|
1977
|
+
post: (path, opts) => request("POST", path, opts),
|
|
1978
|
+
put: (path, opts) => request("PUT", path, opts),
|
|
1979
|
+
patch: (path, opts) => request("PATCH", path, opts),
|
|
1980
|
+
delete: (path, opts) => request("DELETE", path, opts)
|
|
1981
|
+
});
|
|
1982
|
+
}
|
|
1983
|
+
return Object.freeze({ client: makeClient, HttpError });
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
// src/jsh/sliccy/pure.mjs
|
|
1987
|
+
var ANSI = {
|
|
1988
|
+
reset: "\x1B[0m",
|
|
1989
|
+
green: "\x1B[32m",
|
|
1990
|
+
red: "\x1B[31m",
|
|
1991
|
+
yellow: "\x1B[33m",
|
|
1992
|
+
gray: "\x1B[90m",
|
|
1993
|
+
bold: "\x1B[1m",
|
|
1994
|
+
cyan: "\x1B[36m",
|
|
1995
|
+
dim: "\x1B[2m"
|
|
1996
|
+
};
|
|
1997
|
+
function colorEnabled(env, stdoutIsTTY) {
|
|
1998
|
+
const force = env?.FORCE_COLOR;
|
|
1999
|
+
if (force !== void 0) return force !== "" && force !== "0" && force !== "false";
|
|
2000
|
+
if (env?.NO_COLOR) return false;
|
|
2001
|
+
return !!stdoutIsTTY;
|
|
2002
|
+
}
|
|
2003
|
+
function createColor(enabled) {
|
|
2004
|
+
const wrap = (code) => (s) => enabled ? `${code}${s}${ANSI.reset}` : String(s);
|
|
2005
|
+
return Object.freeze({
|
|
2006
|
+
enabled,
|
|
2007
|
+
green: wrap(ANSI.green),
|
|
2008
|
+
red: wrap(ANSI.red),
|
|
2009
|
+
yellow: wrap(ANSI.yellow),
|
|
2010
|
+
gray: wrap(ANSI.gray),
|
|
2011
|
+
bold: wrap(ANSI.bold),
|
|
2012
|
+
cyan: wrap(ANSI.cyan),
|
|
2013
|
+
dim: wrap(ANSI.dim)
|
|
2014
|
+
});
|
|
2015
|
+
}
|
|
2016
|
+
function createCli({ writeStdout, writeStderr, exit, color }) {
|
|
2017
|
+
const toLine = (v) => {
|
|
2018
|
+
if (typeof v === "string") return v;
|
|
2019
|
+
if (v instanceof Error) return v.message;
|
|
2020
|
+
if (v === null || v === void 0) return String(v);
|
|
2021
|
+
try {
|
|
2022
|
+
return JSON.stringify(v);
|
|
2023
|
+
} catch {
|
|
2024
|
+
return String(v);
|
|
2025
|
+
}
|
|
2026
|
+
};
|
|
2027
|
+
const prefixed = (paint, prefix, text, fallback) => {
|
|
2028
|
+
if (prefix === void 0) return `${paint(`${fallback}:`)} ${text}
|
|
2029
|
+
`;
|
|
2030
|
+
if (prefix === "") return `${paint(text)}
|
|
2031
|
+
`;
|
|
2032
|
+
return `${paint(`${prefix}:`)} ${text}
|
|
2033
|
+
`;
|
|
2034
|
+
};
|
|
2035
|
+
const prefixOf = (opts) => typeof opts === "object" && opts !== null && "prefix" in opts ? opts.prefix : void 0;
|
|
2036
|
+
return Object.freeze({
|
|
2037
|
+
die(msg, opts) {
|
|
2038
|
+
const code = typeof opts === "number" ? opts : opts?.exitCode ?? 1;
|
|
2039
|
+
writeStderr(prefixed(color.red, prefixOf(opts), toLine(msg), "Error"));
|
|
2040
|
+
exit(code);
|
|
2041
|
+
throw new Error("unreachable");
|
|
2042
|
+
},
|
|
2043
|
+
out(value) {
|
|
2044
|
+
if (typeof value === "string") {
|
|
2045
|
+
writeStdout(value.endsWith("\n") ? value : `${value}
|
|
2046
|
+
`);
|
|
2047
|
+
return;
|
|
2048
|
+
}
|
|
2049
|
+
try {
|
|
2050
|
+
writeStdout(`${JSON.stringify(value, null, 2)}
|
|
2051
|
+
`);
|
|
2052
|
+
} catch {
|
|
2053
|
+
writeStdout(`${String(value)}
|
|
2054
|
+
`);
|
|
2055
|
+
}
|
|
2056
|
+
},
|
|
2057
|
+
warn(msg, opts) {
|
|
2058
|
+
writeStderr(prefixed(color.yellow, prefixOf(opts), toLine(msg), "Warning"));
|
|
2059
|
+
},
|
|
2060
|
+
help(text) {
|
|
2061
|
+
writeStdout(text.endsWith("\n") ? text : `${text}
|
|
2062
|
+
`);
|
|
2063
|
+
exit(0);
|
|
2064
|
+
throw new Error("unreachable");
|
|
2065
|
+
}
|
|
2066
|
+
});
|
|
2067
|
+
}
|
|
2068
|
+
var ANSI_RE = /\u001b\[[0-9;]*m/g;
|
|
2069
|
+
var stripAnsi = (s) => s.replace(ANSI_RE, "");
|
|
2070
|
+
var visibleLength = (s) => stripAnsi(s).length;
|
|
2071
|
+
var pad2 = (n) => n < 10 ? `0${n}` : String(n);
|
|
2072
|
+
function trunc(s, n) {
|
|
2073
|
+
const text = String(s ?? "");
|
|
2074
|
+
if (n <= 0) return "";
|
|
2075
|
+
if (visibleLength(text) <= n) return text;
|
|
2076
|
+
if (n <= 1) return text.slice(0, n);
|
|
2077
|
+
return `${stripAnsi(text).slice(0, n - 1)}\u2026`;
|
|
2078
|
+
}
|
|
2079
|
+
function col(s, width) {
|
|
2080
|
+
const text = String(s ?? "");
|
|
2081
|
+
const vis = visibleLength(text);
|
|
2082
|
+
if (vis === width) return text;
|
|
2083
|
+
if (vis > width) return trunc(text, width);
|
|
2084
|
+
return text + " ".repeat(width - vis);
|
|
2085
|
+
}
|
|
2086
|
+
function table(rows, widths) {
|
|
2087
|
+
if (!rows.length) return "";
|
|
2088
|
+
const colCount = Math.max(...rows.map((r) => r.length));
|
|
2089
|
+
const computed = [];
|
|
2090
|
+
for (let i2 = 0; i2 < colCount; i2++) {
|
|
2091
|
+
if (widths && widths[i2] !== void 0) {
|
|
2092
|
+
computed[i2] = widths[i2];
|
|
2093
|
+
} else {
|
|
2094
|
+
let max = 0;
|
|
2095
|
+
for (const r of rows) max = Math.max(max, visibleLength(i2 < r.length ? String(r[i2] ?? "") : ""));
|
|
2096
|
+
computed[i2] = max;
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
return rows.map(
|
|
2100
|
+
(r) => computed.map((w, i2) => col(i2 < r.length ? String(r[i2] ?? "") : "", w)).join(" ").replace(/\s+$/, "")
|
|
2101
|
+
).join("\n");
|
|
2102
|
+
}
|
|
2103
|
+
function fmtDate(value, style = "short") {
|
|
2104
|
+
const d = value instanceof Date ? value : new Date(value);
|
|
2105
|
+
if (Number.isNaN(d.getTime())) return String(value);
|
|
2106
|
+
if (style === "iso") return d.toISOString();
|
|
2107
|
+
if (style === "locale") return new Intl.DateTimeFormat(void 0, { dateStyle: "medium" }).format(d);
|
|
2108
|
+
if (style === "human") {
|
|
2109
|
+
const diff = Date.now() - d.getTime();
|
|
2110
|
+
const abs = Math.abs(diff);
|
|
2111
|
+
if (abs < 6e4) return diff >= 0 ? "just now" : "in a moment";
|
|
2112
|
+
const tense = (n, u) => diff >= 0 ? `${n} ${u}${n === 1 ? "" : "s"} ago` : `in ${n} ${u}${n === 1 ? "" : "s"}`;
|
|
2113
|
+
if (abs < 36e5) return tense(Math.round(abs / 6e4), "minute");
|
|
2114
|
+
if (abs < 864e5) return tense(Math.round(abs / 36e5), "hour");
|
|
2115
|
+
if (abs < 26298e5) return tense(Math.round(abs / 864e5), "day");
|
|
2116
|
+
if (abs < 315576e5) return tense(Math.round(abs / 26298e5), "month");
|
|
2117
|
+
return tense(Math.round(abs / 315576e5), "year");
|
|
2118
|
+
}
|
|
2119
|
+
return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`;
|
|
2120
|
+
}
|
|
2121
|
+
var fmt = Object.freeze({ trunc, col, table, date: fmtDate });
|
|
2122
|
+
var DURATION_UNITS_MS = {
|
|
2123
|
+
ms: 1,
|
|
2124
|
+
s: 1e3,
|
|
2125
|
+
m: 6e4,
|
|
2126
|
+
h: 36e5,
|
|
2127
|
+
d: 864e5,
|
|
2128
|
+
w: 6048e5,
|
|
2129
|
+
M: 26298e5,
|
|
2130
|
+
y: 315576e5
|
|
2131
|
+
};
|
|
2132
|
+
function parseDuration(spec) {
|
|
2133
|
+
if (typeof spec === "number" && Number.isFinite(spec)) return Math.trunc(spec);
|
|
2134
|
+
if (typeof spec !== "string") throw new TypeError("time.parseDuration: spec must be string or number");
|
|
2135
|
+
const m = /^([0-9]+(?:\.[0-9]+)?)\s*(ms|s|m|h|d|w|M|y)?$/.exec(spec.trim());
|
|
2136
|
+
if (!m) throw new RangeError(`time.parseDuration: unrecognized spec "${spec}"`);
|
|
2137
|
+
return Math.trunc(Number(m[1]) * DURATION_UNITS_MS[m[2] ?? "ms"]);
|
|
2138
|
+
}
|
|
2139
|
+
var time = Object.freeze({
|
|
2140
|
+
parseDuration,
|
|
2141
|
+
ago(spec, from = /* @__PURE__ */ new Date()) {
|
|
2142
|
+
return new Date(from.getTime() - parseDuration(spec));
|
|
2143
|
+
},
|
|
2144
|
+
range(spec, from = /* @__PURE__ */ new Date()) {
|
|
2145
|
+
const end = new Date(from.getTime());
|
|
2146
|
+
return { start: new Date(end.getTime() - parseDuration(spec)), end };
|
|
2147
|
+
},
|
|
2148
|
+
future(spec, from = /* @__PURE__ */ new Date()) {
|
|
2149
|
+
const start = new Date(from.getTime());
|
|
2150
|
+
return { start, end: new Date(start.getTime() + parseDuration(spec)) };
|
|
2151
|
+
},
|
|
2152
|
+
gmailDate(spec, from = /* @__PURE__ */ new Date()) {
|
|
2153
|
+
const d = new Date(from.getTime() - parseDuration(spec));
|
|
2154
|
+
return `${d.getFullYear()}/${pad2(d.getMonth() + 1)}/${pad2(d.getDate())}`;
|
|
2155
|
+
}
|
|
2156
|
+
});
|
|
2157
|
+
async function pool(concurrency, items, fn) {
|
|
2158
|
+
const n = Math.max(1, Math.trunc(concurrency) || 1);
|
|
2159
|
+
const results = new Array(items.length);
|
|
2160
|
+
let next = 0;
|
|
2161
|
+
const worker = async () => {
|
|
2162
|
+
for (; ; ) {
|
|
2163
|
+
const i2 = next++;
|
|
2164
|
+
if (i2 >= items.length) return;
|
|
2165
|
+
results[i2] = await fn(items[i2], i2);
|
|
2166
|
+
}
|
|
2167
|
+
};
|
|
2168
|
+
const workers = [];
|
|
2169
|
+
for (let w = 0; w < Math.min(n, items.length); w++) workers.push(worker());
|
|
2170
|
+
await Promise.all(workers);
|
|
2171
|
+
return results;
|
|
2172
|
+
}
|
|
2173
|
+
|
|
2174
|
+
// src/jsh/sliccy/index.mjs
|
|
2175
|
+
var SLICC_ONLY = /* @__PURE__ */ new Set(["agent", "usb", "serial", "hid", "computer"]);
|
|
2176
|
+
function isNotFound(err, request) {
|
|
2177
|
+
return err?.code === "MODULE_NOT_FOUND" && String(err.message).includes(`'${request}'`);
|
|
2178
|
+
}
|
|
2179
|
+
function createSliccyResolver({ engine, process: process2, require: require2 }) {
|
|
2180
|
+
let color;
|
|
2181
|
+
let exec;
|
|
2182
|
+
const getColor = () => {
|
|
2183
|
+
color ??= createColor(colorEnabled(process2.env, engine.stdoutIsTTY));
|
|
2184
|
+
return color;
|
|
2185
|
+
};
|
|
2186
|
+
const getExec = () => {
|
|
2187
|
+
exec ??= createExec(engine);
|
|
2188
|
+
return exec;
|
|
2189
|
+
};
|
|
2190
|
+
const factories = {
|
|
2191
|
+
cli: () => createCli({
|
|
2192
|
+
writeStdout: engine.writeStdout,
|
|
2193
|
+
writeStderr: engine.writeStderr,
|
|
2194
|
+
exit: (code) => process2.exit(code),
|
|
2195
|
+
color: getColor()
|
|
2196
|
+
}),
|
|
2197
|
+
color: getColor,
|
|
2198
|
+
exec: getExec,
|
|
2199
|
+
fmt: () => fmt,
|
|
2200
|
+
http: () => createHttp({ fetch: engine.fetch }),
|
|
2201
|
+
pool: () => pool,
|
|
2202
|
+
skill: () => createSkill({ argv: process2.argv, fs: require2("fs"), exec: getExec() }),
|
|
2203
|
+
time: () => time
|
|
2204
|
+
};
|
|
2205
|
+
const cache2 = /* @__PURE__ */ new Map();
|
|
2206
|
+
const lookups = [require2, engine.selfRequire].filter(Boolean);
|
|
2207
|
+
return function requireSliccy(id) {
|
|
2208
|
+
const name = id.slice("sliccy:".length);
|
|
2209
|
+
if (name === "") throw new Error("require('sliccy:'): empty sliccy: module name");
|
|
2210
|
+
if (cache2.has(name)) return cache2.get(name);
|
|
2211
|
+
let value;
|
|
2212
|
+
if (Object.prototype.hasOwnProperty.call(factories, name)) {
|
|
2213
|
+
value = factories[name]();
|
|
2214
|
+
} else {
|
|
2215
|
+
value = findPackage(name, lookups);
|
|
2216
|
+
}
|
|
2217
|
+
if (value === void 0) {
|
|
2218
|
+
if (SLICC_ONLY.has(name)) {
|
|
2219
|
+
throw new Error(`require('${id}'): sliccy:${name} is only available inside SLICC`);
|
|
2220
|
+
}
|
|
2221
|
+
const known = Object.keys(factories).sort().join(", ");
|
|
2222
|
+
throw new Error(
|
|
2223
|
+
`require('${id}'): unknown sliccy: module '${name}'. Known names: ${known}. Install @ai-ecoverse/sliccy-${name} to provide it.`
|
|
2224
|
+
);
|
|
2225
|
+
}
|
|
2226
|
+
cache2.set(name, value);
|
|
2227
|
+
return value;
|
|
2228
|
+
};
|
|
2229
|
+
}
|
|
2230
|
+
function findPackage(name, lookups) {
|
|
2231
|
+
for (const pkg of [`@ai-ecoverse/sliccy-${name}`, `sliccy-${name}`]) {
|
|
2232
|
+
for (const req of lookups) {
|
|
2233
|
+
try {
|
|
2234
|
+
return req(pkg);
|
|
2235
|
+
} catch (err) {
|
|
2236
|
+
if (!isNotFound(err, pkg)) throw err;
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
return void 0;
|
|
2241
|
+
}
|
|
2242
|
+
|
|
2243
|
+
// src/jsh/run.mjs
|
|
2244
|
+
var JSH_VERSION = package_default.version;
|
|
2245
|
+
var JSH_PARAMS = Object.freeze([
|
|
2246
|
+
"process",
|
|
2247
|
+
"console",
|
|
2248
|
+
"require",
|
|
2249
|
+
"module",
|
|
2250
|
+
"exports",
|
|
2251
|
+
"fetch",
|
|
2252
|
+
"__dirname",
|
|
2253
|
+
"__filename"
|
|
2254
|
+
]);
|
|
2255
|
+
var JSH_USAGE = `Usage: jsh [--version | --help] <script.jsh> [args...]
|
|
2256
|
+
|
|
2257
|
+
Runs a .jsh script: the body of an async function with process, console,
|
|
2258
|
+
require, module, exports, fetch, __dirname and __filename in scope.
|
|
2259
|
+
`;
|
|
2260
|
+
function parseJshArgv(args) {
|
|
2261
|
+
let i2 = 0;
|
|
2262
|
+
const first = args[0];
|
|
2263
|
+
if (first === "--version" || first === "-v") return { action: "version" };
|
|
2264
|
+
if (first === "--help" || first === "-h") return { action: "help" };
|
|
2265
|
+
if (first === "--") i2 = 1;
|
|
2266
|
+
else if (first?.startsWith("-") && first !== "-") {
|
|
2267
|
+
return { action: "error", message: `jsh: bad option: ${first}`, status: 9 };
|
|
2268
|
+
}
|
|
2269
|
+
if (i2 >= args.length) return { action: "usage" };
|
|
2270
|
+
return { action: "run", script: args[i2], args: args.slice(i2 + 1) };
|
|
2271
|
+
}
|
|
2272
|
+
function prepareSource(source) {
|
|
2273
|
+
let text = source.charCodeAt(0) === 65279 ? source.slice(1) : source;
|
|
2274
|
+
if (text.startsWith("#!")) {
|
|
2275
|
+
const nl = text.indexOf("\n");
|
|
2276
|
+
text = nl === -1 ? "" : text.slice(nl);
|
|
2277
|
+
}
|
|
2278
|
+
return text;
|
|
2279
|
+
}
|
|
2280
|
+
function dirnameOf2(path) {
|
|
2281
|
+
const idx = path.lastIndexOf("/");
|
|
2282
|
+
if (idx <= 0) return "/";
|
|
2283
|
+
return path.slice(0, idx);
|
|
2284
|
+
}
|
|
2285
|
+
function wrapRequire(baseRequire, requireSliccy, module) {
|
|
2286
|
+
const require2 = (id) => typeof id === "string" && id.startsWith("sliccy:") ? requireSliccy(id) : baseRequire(id);
|
|
2287
|
+
const resolve2 = (id, options) => typeof id === "string" && id.startsWith("sliccy:") ? id : baseRequire.resolve(id, options);
|
|
2288
|
+
resolve2.paths = (id) => baseRequire.resolve.paths?.(id) ?? null;
|
|
2289
|
+
require2.resolve = resolve2;
|
|
2290
|
+
require2.cache = baseRequire.cache;
|
|
2291
|
+
require2.main = module;
|
|
2292
|
+
return require2;
|
|
2293
|
+
}
|
|
2294
|
+
async function runJsh({ filename, engine, process: process2, console: console2 }) {
|
|
2295
|
+
let source;
|
|
2296
|
+
try {
|
|
2297
|
+
source = engine.readSource(filename);
|
|
2298
|
+
} catch (err) {
|
|
2299
|
+
engine.writeStderr(`jsh: cannot open ${filename}: ${err?.code ?? err?.message ?? err}
|
|
2300
|
+
`);
|
|
2301
|
+
return engine.exit(1);
|
|
2302
|
+
}
|
|
2303
|
+
attachParseFlags(process2.argv);
|
|
2304
|
+
try {
|
|
2305
|
+
process2.versions.jsh = JSH_VERSION;
|
|
2306
|
+
} catch {
|
|
2307
|
+
}
|
|
2308
|
+
const dirname2 = dirnameOf2(filename);
|
|
2309
|
+
const module = {
|
|
2310
|
+
id: ".",
|
|
2311
|
+
filename,
|
|
2312
|
+
path: dirname2,
|
|
2313
|
+
exports: {},
|
|
2314
|
+
loaded: false,
|
|
2315
|
+
children: [],
|
|
2316
|
+
paths: []
|
|
2317
|
+
};
|
|
2318
|
+
const baseRequire = engine.createRequire(filename);
|
|
2319
|
+
const requireSliccy = createSliccyResolver({ engine, process: process2, require: baseRequire });
|
|
2320
|
+
const require2 = wrapRequire(baseRequire, requireSliccy, module);
|
|
2321
|
+
try {
|
|
2322
|
+
const fn = engine.compile(prepareSource(source), filename);
|
|
2323
|
+
await fn(process2, console2, require2, module, module.exports, engine.fetch, dirname2, filename);
|
|
2324
|
+
module.loaded = true;
|
|
2325
|
+
} catch (err) {
|
|
2326
|
+
if (engine.isExit(err)) return engine.exit(err.code);
|
|
2327
|
+
engine.writeStderr(`${err?.stack ?? err}
|
|
2328
|
+
`);
|
|
2329
|
+
return engine.exit(1);
|
|
2330
|
+
}
|
|
2331
|
+
return void 0;
|
|
2332
|
+
}
|
|
2333
|
+
|
|
2334
|
+
// src/jsh/kernel.mjs
|
|
2335
|
+
var JSH_HANDOFF = /* @__PURE__ */ Symbol.for("slicc-jsh.kernel");
|
|
2336
|
+
var decoder = new TextDecoder();
|
|
2337
|
+
var encoder = new TextEncoder();
|
|
2338
|
+
var AsyncFunction = Object.getPrototypeOf(async () => {
|
|
2339
|
+
}).constructor;
|
|
2340
|
+
async function readAll(stream) {
|
|
2341
|
+
if (!stream) return new Uint8Array(0);
|
|
2342
|
+
const chunks = [];
|
|
2343
|
+
let size = 0;
|
|
2344
|
+
const reader = stream.getReader();
|
|
2345
|
+
for (; ; ) {
|
|
2346
|
+
const { done, value } = await reader.read();
|
|
2347
|
+
if (done) break;
|
|
2348
|
+
const bytes = typeof value === "string" ? encoder.encode(value) : value;
|
|
2349
|
+
chunks.push(bytes);
|
|
2350
|
+
size += bytes.length;
|
|
2351
|
+
}
|
|
2352
|
+
const out = new Uint8Array(size);
|
|
2353
|
+
let off = 0;
|
|
2354
|
+
for (const c of chunks) {
|
|
2355
|
+
out.set(c, off);
|
|
2356
|
+
off += c.length;
|
|
2357
|
+
}
|
|
2358
|
+
return out;
|
|
2359
|
+
}
|
|
2360
|
+
async function writeAll(stream, data2) {
|
|
2361
|
+
const writer = stream.getWriter();
|
|
2362
|
+
try {
|
|
2363
|
+
await writer.write(typeof data2 === "string" ? encoder.encode(data2) : data2);
|
|
2364
|
+
await writer.close();
|
|
2365
|
+
} catch {
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
function kernelSpawn(ctx, process2) {
|
|
2369
|
+
return (argv, { stdin } = {}) => {
|
|
2370
|
+
let child = null;
|
|
2371
|
+
const done = (async () => {
|
|
2372
|
+
try {
|
|
2373
|
+
child = await ctx.spawn({
|
|
2374
|
+
argv,
|
|
2375
|
+
cwd: process2.cwd(),
|
|
2376
|
+
env: { ...process2.env },
|
|
2377
|
+
stdin: stdin === void 0 ? "null" : "pipe",
|
|
2378
|
+
stdout: "pipe",
|
|
2379
|
+
stderr: "pipe"
|
|
2380
|
+
});
|
|
2381
|
+
} catch (err2) {
|
|
2382
|
+
if (err2?.code === "ENOENT") {
|
|
2383
|
+
return { stdout: "", stderr: `${argv[0]}: command not found
|
|
2384
|
+
`, exitCode: 127 };
|
|
2385
|
+
}
|
|
2386
|
+
return { stdout: "", stderr: `${argv[0]}: ${err2?.message ?? err2}
|
|
2387
|
+
`, exitCode: 126 };
|
|
2388
|
+
}
|
|
2389
|
+
const [out, err, status] = await Promise.all([
|
|
2390
|
+
readAll(child.stdout),
|
|
2391
|
+
readAll(child.stderr),
|
|
2392
|
+
child.wait(),
|
|
2393
|
+
stdin === void 0 ? void 0 : writeAll(child.stdin, stdin)
|
|
2394
|
+
]);
|
|
2395
|
+
return { stdout: decoder.decode(out), stderr: decoder.decode(err), exitCode: status.status };
|
|
2396
|
+
})();
|
|
2397
|
+
return {
|
|
2398
|
+
kill: async (sig = "SIGTERM") => child ? child.kill(sig) : false,
|
|
2399
|
+
done
|
|
2400
|
+
};
|
|
2401
|
+
};
|
|
2402
|
+
}
|
|
2403
|
+
function compiler(rt) {
|
|
2404
|
+
return (body, filename) => {
|
|
2405
|
+
const head = "(async function () {";
|
|
2406
|
+
const { code, changed, binding = "__import" } = rt.rewriteDynamicImports(
|
|
2407
|
+
`${head}${body}
|
|
2408
|
+
})`
|
|
2409
|
+
);
|
|
2410
|
+
const text = changed ? code.slice(head.length, -3) : body;
|
|
2411
|
+
const params = changed ? [...JSH_PARAMS, binding] : [...JSH_PARAMS];
|
|
2412
|
+
const fn = new AsyncFunction(...params, `${text}
|
|
2413
|
+
//# sourceURL=${filename}`);
|
|
2414
|
+
if (!changed) return fn;
|
|
2415
|
+
const importFrom = (specifier) => rt.importModule(specifier, filename);
|
|
2416
|
+
return (...args) => fn(...args.slice(0, JSH_PARAMS.length), importFrom);
|
|
2417
|
+
};
|
|
2418
|
+
}
|
|
2419
|
+
async function runKernelJsh(ctx, rt, filename) {
|
|
2420
|
+
const { process: process2, console: console2 } = rt;
|
|
2421
|
+
let stdoutIsTTY = false;
|
|
2422
|
+
try {
|
|
2423
|
+
stdoutIsTTY = !!await ctx.isatty?.(1);
|
|
2424
|
+
} catch {
|
|
2425
|
+
stdoutIsTTY = false;
|
|
2426
|
+
}
|
|
2427
|
+
const engine = {
|
|
2428
|
+
readSource: (path) => decoder.decode(ctx.sync.fs.readFile(path)),
|
|
2429
|
+
compile: compiler(rt),
|
|
2430
|
+
createRequire: (path) => rt.createRequire(path),
|
|
2431
|
+
selfRequire: rt.createRequire("/node_modules/@ai-ecoverse/slicc-jsh/package.json"),
|
|
2432
|
+
writeStdout: (s) => process2.stdout.write(String(s)),
|
|
2433
|
+
writeStderr: (s) => process2.stderr.write(String(s)),
|
|
2434
|
+
stdoutIsTTY,
|
|
2435
|
+
spawn: kernelSpawn(ctx, process2),
|
|
2436
|
+
shell: ["sh", "-c"],
|
|
2437
|
+
fetch: rt.fetch,
|
|
2438
|
+
isExit: (err) => err instanceof NodeExitError,
|
|
2439
|
+
exit: (code) => process2.exit(code)
|
|
2440
|
+
};
|
|
2441
|
+
await runJsh({ filename, engine, process: process2, console: console2 });
|
|
2442
|
+
}
|
|
2443
|
+
function installJshHandoff(ctx, rt) {
|
|
2444
|
+
const handoff = Object.freeze({
|
|
2445
|
+
version: JSH_VERSION,
|
|
2446
|
+
async runJsh(args) {
|
|
2447
|
+
const { process: process2 } = rt;
|
|
2448
|
+
const parsed = parseJshArgv([...args]);
|
|
2449
|
+
if (parsed.action === "version") return void process2.stdout.write(`${JSH_VERSION}
|
|
2450
|
+
`);
|
|
2451
|
+
if (parsed.action === "help") return void process2.stdout.write(JSH_USAGE);
|
|
2452
|
+
if (parsed.action === "usage") {
|
|
2453
|
+
process2.stderr.write(JSH_USAGE);
|
|
2454
|
+
return process2.exit(2);
|
|
2455
|
+
}
|
|
2456
|
+
if (parsed.action === "error") {
|
|
2457
|
+
process2.stderr.write(`${parsed.message}
|
|
2458
|
+
${JSH_USAGE}`);
|
|
2459
|
+
return process2.exit(parsed.status);
|
|
2460
|
+
}
|
|
2461
|
+
const filename = ctx.resolve(parsed.script);
|
|
2462
|
+
process2.argv = ["jsh", filename, ...parsed.args];
|
|
2463
|
+
return runKernelJsh(ctx, rt, filename);
|
|
2464
|
+
}
|
|
2465
|
+
});
|
|
2466
|
+
try {
|
|
2467
|
+
Object.defineProperty(globalThis, JSH_HANDOFF, {
|
|
2468
|
+
value: handoff,
|
|
2469
|
+
enumerable: false,
|
|
2470
|
+
configurable: true,
|
|
2471
|
+
writable: false
|
|
2472
|
+
});
|
|
2473
|
+
} catch {
|
|
2474
|
+
return () => {
|
|
2475
|
+
};
|
|
2476
|
+
}
|
|
2477
|
+
return () => {
|
|
2478
|
+
try {
|
|
2479
|
+
delete globalThis[JSH_HANDOFF];
|
|
2480
|
+
} catch {
|
|
2481
|
+
}
|
|
2482
|
+
};
|
|
2483
|
+
}
|
|
2484
|
+
|
|
1539
2485
|
// src/runtime/async-handles.mjs
|
|
1540
2486
|
function trackPromise(handles, promise) {
|
|
1541
2487
|
const handle = { kind: "promise" };
|
|
@@ -1592,8 +2538,8 @@ async function drainLoop(handles, nextTick, { onBeforeExit, shouldStop } = {}) {
|
|
|
1592
2538
|
}
|
|
1593
2539
|
|
|
1594
2540
|
// src/runtime/buffer.mjs
|
|
1595
|
-
var
|
|
1596
|
-
var
|
|
2541
|
+
var encoder2 = new TextEncoder();
|
|
2542
|
+
var decoder2 = new TextDecoder();
|
|
1597
2543
|
var INSPECT_CUSTOM = /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom");
|
|
1598
2544
|
function normalizeEncoding(enc) {
|
|
1599
2545
|
if (!enc) return "utf8";
|
|
@@ -1665,7 +2611,7 @@ function asUint8(value, encoding = "utf8") {
|
|
|
1665
2611
|
for (let i2 = 0; i2 < value.length; i2++) out[i2] = value.charCodeAt(i2) & 255;
|
|
1666
2612
|
return out;
|
|
1667
2613
|
}
|
|
1668
|
-
return
|
|
2614
|
+
return encoder2.encode(value);
|
|
1669
2615
|
}
|
|
1670
2616
|
if (typeof value === "number") return new Uint8Array([value & 255]);
|
|
1671
2617
|
if (ArrayBuffer.isView(value)) {
|
|
@@ -1673,7 +2619,7 @@ function asUint8(value, encoding = "utf8") {
|
|
|
1673
2619
|
}
|
|
1674
2620
|
if (value instanceof ArrayBuffer) return new Uint8Array(value);
|
|
1675
2621
|
if (Array.isArray(value)) return Uint8Array.from(value);
|
|
1676
|
-
return
|
|
2622
|
+
return encoder2.encode(String(value));
|
|
1677
2623
|
}
|
|
1678
2624
|
function toStringOf(bytes, encoding = "utf8", start = 0, end = bytes.length) {
|
|
1679
2625
|
const slice = bytes.subarray(start, end);
|
|
@@ -1697,7 +2643,7 @@ function toStringOf(bytes, encoding = "utf8", start = 0, end = bytes.length) {
|
|
|
1697
2643
|
for (const b of slice) out += String.fromCharCode(b);
|
|
1698
2644
|
return out;
|
|
1699
2645
|
}
|
|
1700
|
-
return
|
|
2646
|
+
return decoder2.decode(slice);
|
|
1701
2647
|
}
|
|
1702
2648
|
var float32Array = new Float32Array(1);
|
|
1703
2649
|
var uInt8Float32Array = new Uint8Array(float32Array.buffer);
|
|
@@ -2973,9 +3919,9 @@ function codePointToString(code) {
|
|
|
2973
3919
|
return String.fromCharCode((code >> 10) + 55296, (code & 1023) + 56320);
|
|
2974
3920
|
}
|
|
2975
3921
|
var loneSurrogate = /(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/;
|
|
2976
|
-
var Position = function Position2(line,
|
|
3922
|
+
var Position = function Position2(line, col2) {
|
|
2977
3923
|
this.line = line;
|
|
2978
|
-
this.column =
|
|
3924
|
+
this.column = col2;
|
|
2979
3925
|
};
|
|
2980
3926
|
Position.prototype.offset = function offset(n) {
|
|
2981
3927
|
return new Position(this.line, this.column + n);
|
|
@@ -9847,9 +10793,418 @@ function createEvents() {
|
|
|
9847
10793
|
});
|
|
9848
10794
|
}
|
|
9849
10795
|
|
|
10796
|
+
// src/runtime/builtins/child-process.mjs
|
|
10797
|
+
var SIGNAL_NAMES = {
|
|
10798
|
+
1: "SIGHUP",
|
|
10799
|
+
2: "SIGINT",
|
|
10800
|
+
3: "SIGQUIT",
|
|
10801
|
+
6: "SIGABRT",
|
|
10802
|
+
9: "SIGKILL",
|
|
10803
|
+
10: "SIGUSR1",
|
|
10804
|
+
12: "SIGUSR2",
|
|
10805
|
+
13: "SIGPIPE",
|
|
10806
|
+
14: "SIGALRM",
|
|
10807
|
+
15: "SIGTERM",
|
|
10808
|
+
17: "SIGCHLD",
|
|
10809
|
+
18: "SIGCONT",
|
|
10810
|
+
19: "SIGSTOP",
|
|
10811
|
+
20: "SIGTSTP"
|
|
10812
|
+
};
|
|
10813
|
+
var SIGNAL_NUMBERS = Object.fromEntries(
|
|
10814
|
+
Object.entries(SIGNAL_NAMES).map(([n, name]) => [name, Number(n)])
|
|
10815
|
+
);
|
|
10816
|
+
function notSupported(name) {
|
|
10817
|
+
const err = new Error(`slicc-jsh: child_process.${name} is not supported yet`);
|
|
10818
|
+
err.code = "ERR_NOT_SUPPORTED";
|
|
10819
|
+
throw err;
|
|
10820
|
+
}
|
|
10821
|
+
function normalizeArgs(file, args, options, callback) {
|
|
10822
|
+
if (typeof args === "function") {
|
|
10823
|
+
return { args: [], options: {}, callback: args };
|
|
10824
|
+
}
|
|
10825
|
+
if (typeof options === "function") {
|
|
10826
|
+
return { args: Array.isArray(args) ? args : [], options: {}, callback: options };
|
|
10827
|
+
}
|
|
10828
|
+
if (args != null && !Array.isArray(args) && typeof args === "object") {
|
|
10829
|
+
return { args: [], options: args, callback: typeof options === "function" ? options : callback };
|
|
10830
|
+
}
|
|
10831
|
+
return {
|
|
10832
|
+
args: Array.isArray(args) ? args.map(String) : [],
|
|
10833
|
+
options: options && typeof options === "object" ? options : {},
|
|
10834
|
+
callback: typeof callback === "function" ? callback : void 0
|
|
10835
|
+
};
|
|
10836
|
+
}
|
|
10837
|
+
function normalizeStdio(stdio) {
|
|
10838
|
+
if (stdio === void 0) return ["pipe", "pipe", "pipe"];
|
|
10839
|
+
if (typeof stdio === "string") return [stdio, stdio, stdio];
|
|
10840
|
+
if (Array.isArray(stdio)) {
|
|
10841
|
+
return [stdio[0] ?? "pipe", stdio[1] ?? "pipe", stdio[2] ?? "pipe"];
|
|
10842
|
+
}
|
|
10843
|
+
return ["pipe", "pipe", "pipe"];
|
|
10844
|
+
}
|
|
10845
|
+
function toKernelStdio(mode) {
|
|
10846
|
+
if (mode === "pipe" || mode === "overlapped") return "pipe";
|
|
10847
|
+
if (mode === "ignore" || mode === null || mode === void 0 || mode === "null") return "null";
|
|
10848
|
+
if (mode === "inherit") return "inherit";
|
|
10849
|
+
if (typeof mode === "number") return mode;
|
|
10850
|
+
const err = new Error(`The argument 'stdio' is invalid. Received ${String(mode)}`);
|
|
10851
|
+
err.code = "ERR_INVALID_ARG_VALUE";
|
|
10852
|
+
throw err;
|
|
10853
|
+
}
|
|
10854
|
+
function signalName(sig) {
|
|
10855
|
+
if (sig == null) return null;
|
|
10856
|
+
if (typeof sig === "string") return sig.startsWith("SIG") ? sig : `SIG${sig}`;
|
|
10857
|
+
if (typeof sig === "number") return SIGNAL_NAMES[sig] ?? String(sig);
|
|
10858
|
+
return null;
|
|
10859
|
+
}
|
|
10860
|
+
function spawnError(command, args, code, message) {
|
|
10861
|
+
const err = new Error(message ?? `spawn ${command} ${code}`);
|
|
10862
|
+
err.code = code;
|
|
10863
|
+
err.errno = code === "ENOENT" ? -2 : void 0;
|
|
10864
|
+
err.syscall = "spawn";
|
|
10865
|
+
err.path = command;
|
|
10866
|
+
err.spawnargs = args;
|
|
10867
|
+
return err;
|
|
10868
|
+
}
|
|
10869
|
+
function createChildProcess({ ctx, process: process2, Buffer: Buffer2, handles, getStream }) {
|
|
10870
|
+
class ChildProcess extends EventEmitter {
|
|
10871
|
+
constructor() {
|
|
10872
|
+
super();
|
|
10873
|
+
this.stdin = null;
|
|
10874
|
+
this.stdout = null;
|
|
10875
|
+
this.stderr = null;
|
|
10876
|
+
this.pid = void 0;
|
|
10877
|
+
this.exitCode = null;
|
|
10878
|
+
this.signalCode = null;
|
|
10879
|
+
this.killed = false;
|
|
10880
|
+
this.connected = false;
|
|
10881
|
+
this.spawnfile = "";
|
|
10882
|
+
this.spawnargs = [];
|
|
10883
|
+
this.#kernel = null;
|
|
10884
|
+
this.#handle = null;
|
|
10885
|
+
this.#closing = false;
|
|
10886
|
+
}
|
|
10887
|
+
#kernel;
|
|
10888
|
+
#handle;
|
|
10889
|
+
#closing;
|
|
10890
|
+
kill(signal = "SIGTERM") {
|
|
10891
|
+
const name = signalName(signal) ?? "SIGTERM";
|
|
10892
|
+
this.killed = true;
|
|
10893
|
+
if (!this.#kernel) return false;
|
|
10894
|
+
try {
|
|
10895
|
+
const ret = this.#kernel.kill(name);
|
|
10896
|
+
return ret !== false;
|
|
10897
|
+
} catch {
|
|
10898
|
+
return false;
|
|
10899
|
+
}
|
|
10900
|
+
}
|
|
10901
|
+
ref() {
|
|
10902
|
+
if (this.#handle) handles.add(this.#handle);
|
|
10903
|
+
return this;
|
|
10904
|
+
}
|
|
10905
|
+
unref() {
|
|
10906
|
+
if (this.#handle) handles.delete(this.#handle);
|
|
10907
|
+
return this;
|
|
10908
|
+
}
|
|
10909
|
+
/** @internal */
|
|
10910
|
+
_bindKernel(child) {
|
|
10911
|
+
this.#kernel = child;
|
|
10912
|
+
this.pid = child.pid;
|
|
10913
|
+
this.#handle = { kind: "child", pid: child.pid };
|
|
10914
|
+
handles.add(this.#handle);
|
|
10915
|
+
}
|
|
10916
|
+
/** @internal */
|
|
10917
|
+
_release() {
|
|
10918
|
+
if (this.#handle) {
|
|
10919
|
+
handles.delete(this.#handle);
|
|
10920
|
+
this.#handle = null;
|
|
10921
|
+
}
|
|
10922
|
+
}
|
|
10923
|
+
/** @internal */
|
|
10924
|
+
_markClosing() {
|
|
10925
|
+
this.#closing = true;
|
|
10926
|
+
}
|
|
10927
|
+
get _closing() {
|
|
10928
|
+
return this.#closing;
|
|
10929
|
+
}
|
|
10930
|
+
}
|
|
10931
|
+
function createPipeReadable() {
|
|
10932
|
+
const { Readable } = getStream();
|
|
10933
|
+
const r = new Readable({ read() {
|
|
10934
|
+
} });
|
|
10935
|
+
r._sliccPump = async (webStream) => {
|
|
10936
|
+
if (!webStream) {
|
|
10937
|
+
r.push(null);
|
|
10938
|
+
return;
|
|
10939
|
+
}
|
|
10940
|
+
try {
|
|
10941
|
+
const reader = webStream.getReader();
|
|
10942
|
+
for (; ; ) {
|
|
10943
|
+
const { done, value } = await reader.read();
|
|
10944
|
+
if (done) break;
|
|
10945
|
+
const chunk = value instanceof Uint8Array ? Buffer2.from(value) : Buffer2.from(String(value));
|
|
10946
|
+
r.push(chunk);
|
|
10947
|
+
}
|
|
10948
|
+
r.push(null);
|
|
10949
|
+
} catch (err) {
|
|
10950
|
+
r.destroy(err);
|
|
10951
|
+
}
|
|
10952
|
+
};
|
|
10953
|
+
return r;
|
|
10954
|
+
}
|
|
10955
|
+
function createPipeWritable() {
|
|
10956
|
+
const { Writable } = getStream();
|
|
10957
|
+
let writer = null;
|
|
10958
|
+
const pending = [];
|
|
10959
|
+
let ended = false;
|
|
10960
|
+
const w = new Writable({
|
|
10961
|
+
write(chunk, _enc, cb) {
|
|
10962
|
+
const bytes = typeof chunk === "string" ? Buffer2.from(chunk) : chunk;
|
|
10963
|
+
if (!writer) {
|
|
10964
|
+
pending.push({ bytes, cb });
|
|
10965
|
+
return;
|
|
10966
|
+
}
|
|
10967
|
+
writer.write(bytes).then(() => cb(), cb);
|
|
10968
|
+
},
|
|
10969
|
+
final(cb) {
|
|
10970
|
+
ended = true;
|
|
10971
|
+
if (!writer) {
|
|
10972
|
+
pending.push({ end: true, cb });
|
|
10973
|
+
return;
|
|
10974
|
+
}
|
|
10975
|
+
writer.close().then(() => cb(), cb);
|
|
10976
|
+
},
|
|
10977
|
+
destroy(err, cb) {
|
|
10978
|
+
if (writer) writer.abort(err).then(() => cb(err), () => cb(err));
|
|
10979
|
+
else cb(err);
|
|
10980
|
+
}
|
|
10981
|
+
});
|
|
10982
|
+
w._sliccAttach = (webStream) => {
|
|
10983
|
+
if (!webStream) {
|
|
10984
|
+
for (const p of pending) p.cb?.(new Error("stdin not available"));
|
|
10985
|
+
pending.length = 0;
|
|
10986
|
+
return;
|
|
10987
|
+
}
|
|
10988
|
+
writer = webStream.getWriter();
|
|
10989
|
+
for (const p of pending) {
|
|
10990
|
+
if (p.end) writer.close().then(() => p.cb(), p.cb);
|
|
10991
|
+
else writer.write(p.bytes).then(() => p.cb(), p.cb);
|
|
10992
|
+
}
|
|
10993
|
+
pending.length = 0;
|
|
10994
|
+
if (ended && pending.length === 0) {
|
|
10995
|
+
}
|
|
10996
|
+
};
|
|
10997
|
+
return w;
|
|
10998
|
+
}
|
|
10999
|
+
function prepareStdio(child, stdio) {
|
|
11000
|
+
const [inMode, outMode, errMode] = stdio;
|
|
11001
|
+
if (toKernelStdio(inMode) === "pipe") child.stdin = createPipeWritable();
|
|
11002
|
+
if (toKernelStdio(outMode) === "pipe") child.stdout = createPipeReadable();
|
|
11003
|
+
if (toKernelStdio(errMode) === "pipe") child.stderr = createPipeReadable();
|
|
11004
|
+
}
|
|
11005
|
+
function connectStdio(child, kernelChild) {
|
|
11006
|
+
child.stdin?._sliccAttach?.(kernelChild.stdin);
|
|
11007
|
+
const pumps = [];
|
|
11008
|
+
if (child.stdout?._sliccPump) pumps.push(child.stdout._sliccPump(kernelChild.stdout));
|
|
11009
|
+
if (child.stderr?._sliccPump) pumps.push(child.stderr._sliccPump(kernelChild.stderr));
|
|
11010
|
+
child._stdioPumps = Promise.all(pumps);
|
|
11011
|
+
}
|
|
11012
|
+
function finish(child, code, signal) {
|
|
11013
|
+
if (child._closing) return;
|
|
11014
|
+
child._markClosing();
|
|
11015
|
+
child.exitCode = code;
|
|
11016
|
+
child.signalCode = signal;
|
|
11017
|
+
child.emit("exit", code, signal);
|
|
11018
|
+
const after = child._stdioPumps ?? Promise.resolve();
|
|
11019
|
+
trackPromise(handles, after);
|
|
11020
|
+
after.finally(() => {
|
|
11021
|
+
child.emit("close", code, signal);
|
|
11022
|
+
child._release();
|
|
11023
|
+
handles.notify?.();
|
|
11024
|
+
});
|
|
11025
|
+
}
|
|
11026
|
+
function startSpawn(child, file, args, options, stdio) {
|
|
11027
|
+
const cwd = options.cwd != null ? String(options.cwd) : process2.cwd();
|
|
11028
|
+
const env = options.env ? { ...options.env } : { ...process2.env };
|
|
11029
|
+
const argv = [file, ...args];
|
|
11030
|
+
child.spawnfile = file;
|
|
11031
|
+
child.spawnargs = argv;
|
|
11032
|
+
const spawnPromise = ctx.spawn({
|
|
11033
|
+
argv,
|
|
11034
|
+
cwd,
|
|
11035
|
+
env,
|
|
11036
|
+
stdin: toKernelStdio(stdio[0]),
|
|
11037
|
+
stdout: toKernelStdio(stdio[1]),
|
|
11038
|
+
stderr: toKernelStdio(stdio[2])
|
|
11039
|
+
});
|
|
11040
|
+
trackPromise(handles, spawnPromise);
|
|
11041
|
+
spawnPromise.then(
|
|
11042
|
+
(kernelChild) => {
|
|
11043
|
+
child._bindKernel(kernelChild);
|
|
11044
|
+
connectStdio(child, kernelChild);
|
|
11045
|
+
child.emit("spawn");
|
|
11046
|
+
const waitP = kernelChild.wait();
|
|
11047
|
+
trackPromise(handles, waitP);
|
|
11048
|
+
waitP.then(
|
|
11049
|
+
(status) => {
|
|
11050
|
+
const sigNum = status?.signal;
|
|
11051
|
+
if (sigNum != null && sigNum !== 0) {
|
|
11052
|
+
const name = SIGNAL_NAMES[sigNum] ?? String(sigNum);
|
|
11053
|
+
finish(child, null, name);
|
|
11054
|
+
} else {
|
|
11055
|
+
const code = typeof status?.status === "number" ? status.status : 0;
|
|
11056
|
+
finish(child, code, null);
|
|
11057
|
+
}
|
|
11058
|
+
},
|
|
11059
|
+
(err) => {
|
|
11060
|
+
child.emit("error", err);
|
|
11061
|
+
finish(child, 1, null);
|
|
11062
|
+
}
|
|
11063
|
+
);
|
|
11064
|
+
},
|
|
11065
|
+
(err) => {
|
|
11066
|
+
const code = err?.code === "ENOENT" ? "ENOENT" : err?.code ?? "ERR_SPAWN_FAILED";
|
|
11067
|
+
const error = code === "ENOENT" ? spawnError(file, args, "ENOENT", `spawn ${file} ENOENT`) : spawnError(file, args, code, err?.message ?? String(err));
|
|
11068
|
+
try {
|
|
11069
|
+
child.stdout?.push?.(null);
|
|
11070
|
+
} catch {
|
|
11071
|
+
}
|
|
11072
|
+
try {
|
|
11073
|
+
child.stderr?.push?.(null);
|
|
11074
|
+
} catch {
|
|
11075
|
+
}
|
|
11076
|
+
process2.nextTick(() => {
|
|
11077
|
+
child.emit("error", error);
|
|
11078
|
+
if (code === "ENOENT") {
|
|
11079
|
+
child.exitCode = -2;
|
|
11080
|
+
child.emit("close", -2, null);
|
|
11081
|
+
} else {
|
|
11082
|
+
finish(child, 1, null);
|
|
11083
|
+
}
|
|
11084
|
+
child._release();
|
|
11085
|
+
handles.notify?.();
|
|
11086
|
+
});
|
|
11087
|
+
}
|
|
11088
|
+
);
|
|
11089
|
+
}
|
|
11090
|
+
function spawn(command, args, options) {
|
|
11091
|
+
let file = command;
|
|
11092
|
+
let argv = args;
|
|
11093
|
+
let opts = options;
|
|
11094
|
+
if (argv != null && !Array.isArray(argv) && typeof argv === "object") {
|
|
11095
|
+
opts = argv;
|
|
11096
|
+
argv = [];
|
|
11097
|
+
}
|
|
11098
|
+
argv = Array.isArray(argv) ? argv.map(String) : [];
|
|
11099
|
+
opts = opts && typeof opts === "object" ? opts : {};
|
|
11100
|
+
file = String(file);
|
|
11101
|
+
if (opts.shell) {
|
|
11102
|
+
const shell = typeof opts.shell === "string" ? opts.shell : "sh";
|
|
11103
|
+
const line = argv.length ? [file, ...argv].join(" ") : file;
|
|
11104
|
+
file = shell;
|
|
11105
|
+
argv = ["-c", line];
|
|
11106
|
+
}
|
|
11107
|
+
const stdio = normalizeStdio(opts.stdio);
|
|
11108
|
+
const child = new ChildProcess();
|
|
11109
|
+
prepareStdio(child, stdio);
|
|
11110
|
+
process2.nextTick(() => startSpawn(child, file, argv, opts, stdio));
|
|
11111
|
+
return child;
|
|
11112
|
+
}
|
|
11113
|
+
function execFile(file, args, options, callback) {
|
|
11114
|
+
const norm = normalizeArgs(file, args, options, callback);
|
|
11115
|
+
const opts = { ...norm.options };
|
|
11116
|
+
if (opts.stdio === void 0) opts.stdio = ["pipe", "pipe", "pipe"];
|
|
11117
|
+
const child = spawn(String(file), norm.args, opts);
|
|
11118
|
+
if (!norm.callback) return child;
|
|
11119
|
+
const maxBuffer = opts.maxBuffer ?? 1024 * 1024;
|
|
11120
|
+
let stdout = Buffer2.alloc(0);
|
|
11121
|
+
let stderr = Buffer2.alloc(0);
|
|
11122
|
+
let exited = false;
|
|
11123
|
+
const done = (err) => {
|
|
11124
|
+
if (exited) return;
|
|
11125
|
+
exited = true;
|
|
11126
|
+
const enc = opts.encoding;
|
|
11127
|
+
const out = enc ? stdout.toString(enc) : stdout;
|
|
11128
|
+
const errOut = enc ? stderr.toString(enc) : stderr;
|
|
11129
|
+
norm.callback(err, out, errOut);
|
|
11130
|
+
};
|
|
11131
|
+
if (child.stdout) {
|
|
11132
|
+
child.stdout.on("data", (chunk) => {
|
|
11133
|
+
stdout = Buffer2.concat([stdout, Buffer2.isBuffer(chunk) ? chunk : Buffer2.from(chunk)]);
|
|
11134
|
+
if (stdout.length > maxBuffer) {
|
|
11135
|
+
child.kill();
|
|
11136
|
+
const err = new Error("stdout maxBuffer exceeded");
|
|
11137
|
+
err.code = "ERR_CHILD_PROCESS_STDIO_MAXBUFFER";
|
|
11138
|
+
done(err);
|
|
11139
|
+
}
|
|
11140
|
+
});
|
|
11141
|
+
}
|
|
11142
|
+
if (child.stderr) {
|
|
11143
|
+
child.stderr.on("data", (chunk) => {
|
|
11144
|
+
stderr = Buffer2.concat([stderr, Buffer2.isBuffer(chunk) ? chunk : Buffer2.from(chunk)]);
|
|
11145
|
+
if (stderr.length > maxBuffer) {
|
|
11146
|
+
child.kill();
|
|
11147
|
+
const err = new Error("stderr maxBuffer exceeded");
|
|
11148
|
+
err.code = "ERR_CHILD_PROCESS_STDIO_MAXBUFFER";
|
|
11149
|
+
done(err);
|
|
11150
|
+
}
|
|
11151
|
+
});
|
|
11152
|
+
}
|
|
11153
|
+
child.on("error", (err) => done(err));
|
|
11154
|
+
child.on("close", (code, signal) => {
|
|
11155
|
+
if (exited) return;
|
|
11156
|
+
if (code === 0 && !signal) {
|
|
11157
|
+
done(null);
|
|
11158
|
+
return;
|
|
11159
|
+
}
|
|
11160
|
+
const err = new Error(`Command failed: ${file} ${norm.args.join(" ")}`);
|
|
11161
|
+
err.code = code;
|
|
11162
|
+
err.killed = child.killed;
|
|
11163
|
+
err.signal = signal;
|
|
11164
|
+
err.cmd = `${file} ${norm.args.join(" ")}`.trim();
|
|
11165
|
+
err.stdout = opts.encoding ? stdout.toString(opts.encoding) : stdout;
|
|
11166
|
+
err.stderr = opts.encoding ? stderr.toString(opts.encoding) : stderr;
|
|
11167
|
+
done(err);
|
|
11168
|
+
});
|
|
11169
|
+
return child;
|
|
11170
|
+
}
|
|
11171
|
+
function exec(command, options, callback) {
|
|
11172
|
+
let opts = options;
|
|
11173
|
+
let cb = callback;
|
|
11174
|
+
if (typeof options === "function") {
|
|
11175
|
+
cb = options;
|
|
11176
|
+
opts = {};
|
|
11177
|
+
}
|
|
11178
|
+
opts = opts && typeof opts === "object" ? opts : {};
|
|
11179
|
+
const shell = typeof opts.shell === "string" ? opts.shell : "sh";
|
|
11180
|
+
return execFile(shell, ["-c", String(command)], { ...opts, shell: false }, cb);
|
|
11181
|
+
}
|
|
11182
|
+
return {
|
|
11183
|
+
spawn,
|
|
11184
|
+
execFile,
|
|
11185
|
+
exec,
|
|
11186
|
+
spawnSync() {
|
|
11187
|
+
notSupported("spawnSync");
|
|
11188
|
+
},
|
|
11189
|
+
execSync() {
|
|
11190
|
+
notSupported("execSync");
|
|
11191
|
+
},
|
|
11192
|
+
execFileSync() {
|
|
11193
|
+
notSupported("execFileSync");
|
|
11194
|
+
},
|
|
11195
|
+
fork() {
|
|
11196
|
+
notSupported("fork");
|
|
11197
|
+
},
|
|
11198
|
+
ChildProcess,
|
|
11199
|
+
// Expose for tests / advanced callers
|
|
11200
|
+
_SIGNAL_NAMES: SIGNAL_NAMES,
|
|
11201
|
+
_SIGNAL_NUMBERS: SIGNAL_NUMBERS
|
|
11202
|
+
};
|
|
11203
|
+
}
|
|
11204
|
+
|
|
9850
11205
|
// src/runtime/builtins/fs.mjs
|
|
9851
|
-
var
|
|
9852
|
-
var
|
|
11206
|
+
var encoder3 = new TextEncoder();
|
|
11207
|
+
var decoder3 = new TextDecoder();
|
|
9853
11208
|
var ERRNO = {
|
|
9854
11209
|
ENOENT: -2,
|
|
9855
11210
|
EEXIST: -17,
|
|
@@ -9894,10 +11249,10 @@ function nodeFsError(code, syscall, pathArg, err, dest) {
|
|
|
9894
11249
|
return e;
|
|
9895
11250
|
}
|
|
9896
11251
|
function toBytes(data2) {
|
|
9897
|
-
if (typeof data2 === "string") return
|
|
11252
|
+
if (typeof data2 === "string") return encoder3.encode(data2);
|
|
9898
11253
|
if (data2 instanceof Uint8Array) return data2;
|
|
9899
11254
|
if (ArrayBuffer.isView(data2)) return new Uint8Array(data2.buffer, data2.byteOffset, data2.byteLength);
|
|
9900
|
-
return
|
|
11255
|
+
return encoder3.encode(String(data2));
|
|
9901
11256
|
}
|
|
9902
11257
|
function statView(st) {
|
|
9903
11258
|
const mtimeMs = st.mtimeMs ?? (st.mtime ? Number(st.mtime) : 0);
|
|
@@ -9958,7 +11313,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
|
|
|
9958
11313
|
const track = (p) => handles ? trackPromise(handles, p) : p;
|
|
9959
11314
|
const fdTable = /* @__PURE__ */ new Map();
|
|
9960
11315
|
let nextFd = 3;
|
|
9961
|
-
function
|
|
11316
|
+
function parseFlags2(flags) {
|
|
9962
11317
|
const f = flags == null ? "r" : String(flags);
|
|
9963
11318
|
const readable = f.includes("r") || f === "a+" || f === "w+" || f === "ax+" || f === "wx+";
|
|
9964
11319
|
const writable = f.includes("w") || f.includes("a") || f === "r+" || f === "rs+" || f === "as+" || f === "wx" || f === "ax";
|
|
@@ -10081,11 +11436,11 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
|
|
|
10081
11436
|
try {
|
|
10082
11437
|
if (typeof process2?._readStdinSync === "function") {
|
|
10083
11438
|
const out = process2._readStdinSync();
|
|
10084
|
-
return encoding ?
|
|
11439
|
+
return encoding ? decoder3.decode(out) : wrapBuffer(out);
|
|
10085
11440
|
}
|
|
10086
11441
|
if (typeof process2?.stdin?._readAllSync === "function") {
|
|
10087
11442
|
const out = process2.stdin._readAllSync();
|
|
10088
|
-
return encoding ?
|
|
11443
|
+
return encoding ? decoder3.decode(out) : wrapBuffer(out);
|
|
10089
11444
|
}
|
|
10090
11445
|
if (typeof ctx.sync?.read === "function") {
|
|
10091
11446
|
const chunks = [];
|
|
@@ -10102,7 +11457,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
|
|
|
10102
11457
|
out.set(c, at2);
|
|
10103
11458
|
at2 += c.length;
|
|
10104
11459
|
}
|
|
10105
|
-
return encoding ?
|
|
11460
|
+
return encoding ? decoder3.decode(out) : wrapBuffer(out);
|
|
10106
11461
|
}
|
|
10107
11462
|
} catch {
|
|
10108
11463
|
}
|
|
@@ -10174,7 +11529,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
|
|
|
10174
11529
|
throw e;
|
|
10175
11530
|
}
|
|
10176
11531
|
const bytes = syncFs.readFile(target);
|
|
10177
|
-
if (encoding) return
|
|
11532
|
+
if (encoding) return decoder3.decode(bytes);
|
|
10178
11533
|
return wrapBuffer(bytes);
|
|
10179
11534
|
} catch (err) {
|
|
10180
11535
|
if (err?.code && err.syscall) throw err;
|
|
@@ -10241,6 +11596,21 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
|
|
|
10241
11596
|
throw nodeFsError(err?.code || "ENOENT", "lstat", pathArg, err);
|
|
10242
11597
|
}
|
|
10243
11598
|
},
|
|
11599
|
+
/**
|
|
11600
|
+
* Resolve to a canonical absolute path. Symlink walk is not implemented;
|
|
11601
|
+
* when the path exists we return the normalized absolute form (enough for
|
|
11602
|
+
* pnpm's cmd shims, which only need dirname(realpathSync(argv[1]))).
|
|
11603
|
+
*/
|
|
11604
|
+
realpathSync(p) {
|
|
11605
|
+
const pathArg = p;
|
|
11606
|
+
const target = abs(p);
|
|
11607
|
+
try {
|
|
11608
|
+
syncFs.stat(target);
|
|
11609
|
+
return target;
|
|
11610
|
+
} catch (err) {
|
|
11611
|
+
throw nodeFsError(err?.code || "ENOENT", "realpath", pathArg, err);
|
|
11612
|
+
}
|
|
11613
|
+
},
|
|
10244
11614
|
readdirSync,
|
|
10245
11615
|
mkdirSync,
|
|
10246
11616
|
rmdirSync(p, options = {}) {
|
|
@@ -10297,7 +11667,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
|
|
|
10297
11667
|
if (pathArg === "/dev/stdin" || pathArg === "/dev/fd/0") {
|
|
10298
11668
|
return 0;
|
|
10299
11669
|
}
|
|
10300
|
-
const fl =
|
|
11670
|
+
const fl = parseFlags2(flags);
|
|
10301
11671
|
const target = abs(p);
|
|
10302
11672
|
const exists = syncFs.exists(target);
|
|
10303
11673
|
if (fl.exclusive && exists) throw nodeFsError("EEXIST", "open", pathArg);
|
|
@@ -10342,7 +11712,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
|
|
|
10342
11712
|
);
|
|
10343
11713
|
if (fd === 0) {
|
|
10344
11714
|
const data2 = readStdinSync(null);
|
|
10345
|
-
const src = data2 instanceof Uint8Array ? data2 :
|
|
11715
|
+
const src = data2 instanceof Uint8Array ? data2 : encoder3.encode(String(data2));
|
|
10346
11716
|
const n = Math.min(len, src.length);
|
|
10347
11717
|
buffer.set(src.subarray(0, n), bufOffset);
|
|
10348
11718
|
return n;
|
|
@@ -10465,7 +11835,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
|
|
|
10465
11835
|
const encoding = typeof options === "string" ? options : options?.encoding;
|
|
10466
11836
|
try {
|
|
10467
11837
|
const bytes = await asyncFs.readFile(abs(p));
|
|
10468
|
-
if (encoding) return
|
|
11838
|
+
if (encoding) return decoder3.decode(bytes);
|
|
10469
11839
|
return wrapBuffer(bytes);
|
|
10470
11840
|
} catch (err) {
|
|
10471
11841
|
throw nodeFsError(err?.code || "ENOENT", "open", p, err);
|
|
@@ -10879,6 +12249,7 @@ function createFs({ ctx, path, process: process2, Buffer: Buffer2, handles, getS
|
|
|
10879
12249
|
access: callbackify(syncApi.accessSync),
|
|
10880
12250
|
stat: callbackify(syncApi.statSync),
|
|
10881
12251
|
lstat: callbackify(syncApi.lstatSync),
|
|
12252
|
+
realpath: callbackify(syncApi.realpathSync),
|
|
10882
12253
|
readdir: callbackify(syncApi.readdirSync),
|
|
10883
12254
|
mkdir: callbackify(syncApi.mkdirSync),
|
|
10884
12255
|
rmdir: callbackify(syncApi.rmdirSync),
|
|
@@ -11049,7 +12420,7 @@ function responseHasNoBody(method, statusCode) {
|
|
|
11049
12420
|
if (statusCode >= 100 && statusCode < 200) return true;
|
|
11050
12421
|
return false;
|
|
11051
12422
|
}
|
|
11052
|
-
function
|
|
12423
|
+
function createHttp2({ ctx, process: process2, Buffer: Buffer2, handles, getStream, net }) {
|
|
11053
12424
|
void ctx;
|
|
11054
12425
|
void process2;
|
|
11055
12426
|
const stream = getStream();
|
|
@@ -11739,7 +13110,7 @@ function createHttp({ ctx, process: process2, Buffer: Buffer2, handles, getStrea
|
|
|
11739
13110
|
|
|
11740
13111
|
// src/runtime/builtins/https.mjs
|
|
11741
13112
|
var TLS_CLIENT_OPTS = ["cert", "key", "pfx", "ca"];
|
|
11742
|
-
function
|
|
13113
|
+
function notSupported2(what) {
|
|
11743
13114
|
const err = new Error(`slicc-jsh: '${what}' is not supported yet (no TLS on ctx.net)`);
|
|
11744
13115
|
err.code = "ERR_NOT_SUPPORTED";
|
|
11745
13116
|
return err;
|
|
@@ -11753,7 +13124,7 @@ function isManualRedirectUnsupported(err) {
|
|
|
11753
13124
|
function rejectTlsOptions(options) {
|
|
11754
13125
|
for (const name of TLS_CLIENT_OPTS) {
|
|
11755
13126
|
if (options?.[name] != null) {
|
|
11756
|
-
throw
|
|
13127
|
+
throw notSupported2(`https.request option '${name}'`);
|
|
11757
13128
|
}
|
|
11758
13129
|
}
|
|
11759
13130
|
}
|
|
@@ -11787,7 +13158,7 @@ function createHttps({ ctx, Buffer: Buffer2, http, handles }) {
|
|
|
11787
13158
|
}
|
|
11788
13159
|
}
|
|
11789
13160
|
function createServer() {
|
|
11790
|
-
throw
|
|
13161
|
+
throw notSupported2("https.createServer");
|
|
11791
13162
|
}
|
|
11792
13163
|
class ClientRequest extends EventEmitter {
|
|
11793
13164
|
#ended = false;
|
|
@@ -11878,7 +13249,7 @@ function createHttps({ ctx, Buffer: Buffer2, http, handles }) {
|
|
|
11878
13249
|
if (this.#sent || this.#destroyed) return;
|
|
11879
13250
|
this.#sent = true;
|
|
11880
13251
|
try {
|
|
11881
|
-
if (typeof ctx.fetch !== "function") throw
|
|
13252
|
+
if (typeof ctx.fetch !== "function") throw notSupported2("https.request");
|
|
11882
13253
|
const opts = this.#opts;
|
|
11883
13254
|
const method = (opts.method ?? "GET").toUpperCase();
|
|
11884
13255
|
const host = opts.hostname ?? opts.host ?? "localhost";
|
|
@@ -12499,7 +13870,7 @@ function createQuerystring() {
|
|
|
12499
13870
|
}
|
|
12500
13871
|
|
|
12501
13872
|
// src/runtime/vendor-load.mjs
|
|
12502
|
-
var
|
|
13873
|
+
var decoder4 = new TextDecoder();
|
|
12503
13874
|
var cache = /* @__PURE__ */ new Map();
|
|
12504
13875
|
function evalCjs(source, filename) {
|
|
12505
13876
|
const module = { exports: {} };
|
|
@@ -12515,7 +13886,7 @@ function loadVendorCjs({ ctx, packageRoot, name, globals = {} }) {
|
|
|
12515
13886
|
if (cache.has(key)) return cache.get(key);
|
|
12516
13887
|
const path = `${packageRoot}/dist/vendor/${name}.cjs`;
|
|
12517
13888
|
const bytes = ctx.sync.fs.readFile(path);
|
|
12518
|
-
const source = typeof bytes === "string" ? bytes :
|
|
13889
|
+
const source = typeof bytes === "string" ? bytes : decoder4.decode(bytes);
|
|
12519
13890
|
const saved = {};
|
|
12520
13891
|
for (const [k, v] of Object.entries(globals)) {
|
|
12521
13892
|
saved[k] = globalThis[k];
|
|
@@ -12767,6 +14138,7 @@ var BUILTIN_LIST = [
|
|
|
12767
14138
|
"assert",
|
|
12768
14139
|
"assert/strict",
|
|
12769
14140
|
"buffer",
|
|
14141
|
+
"child_process",
|
|
12770
14142
|
"console",
|
|
12771
14143
|
"events",
|
|
12772
14144
|
"fs",
|
|
@@ -12790,7 +14162,6 @@ var BUILTIN_LIST = [
|
|
|
12790
14162
|
"util/types"
|
|
12791
14163
|
];
|
|
12792
14164
|
var NOT_YET = [
|
|
12793
|
-
"child_process",
|
|
12794
14165
|
"http2",
|
|
12795
14166
|
"crypto",
|
|
12796
14167
|
"zlib",
|
|
@@ -12809,7 +14180,7 @@ var NOT_YET = [
|
|
|
12809
14180
|
"v8",
|
|
12810
14181
|
"was"
|
|
12811
14182
|
];
|
|
12812
|
-
function
|
|
14183
|
+
function notSupported3(id) {
|
|
12813
14184
|
const err = new Error(`slicc-jsh: '${id}' is not supported yet`);
|
|
12814
14185
|
err.code = "ERR_NOT_SUPPORTED";
|
|
12815
14186
|
throw err;
|
|
@@ -12847,7 +14218,7 @@ function createBuiltins({ ctx, process: process2, Buffer: Buffer2, console: cons
|
|
|
12847
14218
|
};
|
|
12848
14219
|
let http;
|
|
12849
14220
|
const getHttp = () => {
|
|
12850
|
-
if (!http) http =
|
|
14221
|
+
if (!http) http = createHttp2({ ctx, process: process2, Buffer: Buffer2, handles, getStream, net: getNet() });
|
|
12851
14222
|
return http;
|
|
12852
14223
|
};
|
|
12853
14224
|
let https;
|
|
@@ -12855,6 +14226,13 @@ function createBuiltins({ ctx, process: process2, Buffer: Buffer2, console: cons
|
|
|
12855
14226
|
if (!https) https = createHttps({ ctx, Buffer: Buffer2, http: getHttp(), handles });
|
|
12856
14227
|
return https;
|
|
12857
14228
|
};
|
|
14229
|
+
let childProcess;
|
|
14230
|
+
const getChildProcess = () => {
|
|
14231
|
+
if (!childProcess) {
|
|
14232
|
+
childProcess = createChildProcess({ ctx, process: process2, Buffer: Buffer2, handles, getStream });
|
|
14233
|
+
}
|
|
14234
|
+
return childProcess;
|
|
14235
|
+
};
|
|
12858
14236
|
let ModuleExport = null;
|
|
12859
14237
|
const implemented = {
|
|
12860
14238
|
process: () => process2,
|
|
@@ -12880,7 +14258,8 @@ function createBuiltins({ ctx, process: process2, Buffer: Buffer2, console: cons
|
|
|
12880
14258
|
"timers/promises": () => timersPromises,
|
|
12881
14259
|
net: () => getNet(),
|
|
12882
14260
|
http: () => getHttp(),
|
|
12883
|
-
https: () => getHttps()
|
|
14261
|
+
https: () => getHttps(),
|
|
14262
|
+
child_process: () => getChildProcess()
|
|
12884
14263
|
};
|
|
12885
14264
|
return {
|
|
12886
14265
|
installModule(Module) {
|
|
@@ -12894,7 +14273,7 @@ function createBuiltins({ ctx, process: process2, Buffer: Buffer2, console: cons
|
|
|
12894
14273
|
},
|
|
12895
14274
|
load(id) {
|
|
12896
14275
|
const bare = id.startsWith("node:") ? id.slice(5) : id;
|
|
12897
|
-
if (NOT_YET.includes(bare))
|
|
14276
|
+
if (NOT_YET.includes(bare)) notSupported3(bare);
|
|
12898
14277
|
const factory = implemented[bare];
|
|
12899
14278
|
if (!factory) {
|
|
12900
14279
|
const err = new Error(`No such built-in module: ${id}`);
|
|
@@ -13201,7 +14580,7 @@ function isBuiltinName(name) {
|
|
|
13201
14580
|
}
|
|
13202
14581
|
|
|
13203
14582
|
// src/runtime/cjs/loader.mjs
|
|
13204
|
-
var
|
|
14583
|
+
var decoder5 = new TextDecoder();
|
|
13205
14584
|
function createCjs({
|
|
13206
14585
|
ctx,
|
|
13207
14586
|
process: process2,
|
|
@@ -13218,7 +14597,7 @@ function createCjs({
|
|
|
13218
14597
|
const readPackageJson = (pkgPath) => {
|
|
13219
14598
|
if (packageCache.has(pkgPath)) return packageCache.get(pkgPath);
|
|
13220
14599
|
try {
|
|
13221
|
-
const text =
|
|
14600
|
+
const text = decoder5.decode(fs.readFile(pkgPath));
|
|
13222
14601
|
const pkg = JSON.parse(text);
|
|
13223
14602
|
packageCache.set(pkgPath, pkg);
|
|
13224
14603
|
return pkg;
|
|
@@ -13305,14 +14684,14 @@ function createCjs({
|
|
|
13305
14684
|
};
|
|
13306
14685
|
Module._extensions = {
|
|
13307
14686
|
".js"(module, filename) {
|
|
13308
|
-
const source =
|
|
14687
|
+
const source = decoder5.decode(fs.readFile(filename));
|
|
13309
14688
|
compile(module, source, filename);
|
|
13310
14689
|
},
|
|
13311
14690
|
".cjs"(module, filename) {
|
|
13312
14691
|
Module._extensions[".js"](module, filename);
|
|
13313
14692
|
},
|
|
13314
14693
|
".json"(module, filename) {
|
|
13315
|
-
module.exports = JSON.parse(
|
|
14694
|
+
module.exports = JSON.parse(decoder5.decode(fs.readFile(filename)));
|
|
13316
14695
|
}
|
|
13317
14696
|
};
|
|
13318
14697
|
Module.Module = Module;
|
|
@@ -13703,7 +15082,7 @@ function renderTable(tabularData, util2) {
|
|
|
13703
15082
|
});
|
|
13704
15083
|
}
|
|
13705
15084
|
const widths = headers.map(
|
|
13706
|
-
(h,
|
|
15085
|
+
(h, col2) => Math.max(h.length, ...rows.map((r) => (r[col2] ?? "").length))
|
|
13707
15086
|
);
|
|
13708
15087
|
const pad = (s, w) => s + " ".repeat(Math.max(0, w - s.length));
|
|
13709
15088
|
const line = (left, mid, right, fill) => left + widths.map((w) => fill.repeat(w + 2)).join(mid) + right;
|
|
@@ -13796,7 +15175,7 @@ function createConsole(writeStdout, writeStderr, util2) {
|
|
|
13796
15175
|
}
|
|
13797
15176
|
|
|
13798
15177
|
// src/runtime/esm/loader.mjs
|
|
13799
|
-
var
|
|
15178
|
+
var decoder6 = new TextDecoder();
|
|
13800
15179
|
var IMPORT_CONDITIONS = ["slicc", "import", "node", "default"];
|
|
13801
15180
|
function pathToFileURL2(filename) {
|
|
13802
15181
|
if (filename.startsWith("file:")) return filename;
|
|
@@ -13840,7 +15219,7 @@ function createEsm({ ctx, process: process2, handles, builtins, cjs, trackPromis
|
|
|
13840
15219
|
const readPackageJson = (pkgPath) => {
|
|
13841
15220
|
if (packageCache.has(pkgPath)) return packageCache.get(pkgPath);
|
|
13842
15221
|
try {
|
|
13843
|
-
const pkg = JSON.parse(
|
|
15222
|
+
const pkg = JSON.parse(decoder6.decode(fs.readFile(pkgPath)));
|
|
13844
15223
|
packageCache.set(pkgPath, pkg);
|
|
13845
15224
|
return pkg;
|
|
13846
15225
|
} catch {
|
|
@@ -13979,7 +15358,7 @@ ${code}`
|
|
|
13979
15358
|
await importModule(spec, filename);
|
|
13980
15359
|
}
|
|
13981
15360
|
};
|
|
13982
|
-
const
|
|
15361
|
+
const AsyncFunction2 = Object.getPrototypeOf(async function() {
|
|
13983
15362
|
}).constructor;
|
|
13984
15363
|
const parts = [
|
|
13985
15364
|
...exportSetup,
|
|
@@ -13988,7 +15367,7 @@ ${code}`
|
|
|
13988
15367
|
bodyCode,
|
|
13989
15368
|
`//# sourceURL=${filename}`
|
|
13990
15369
|
];
|
|
13991
|
-
const fn = new
|
|
15370
|
+
const fn = new AsyncFunction2(
|
|
13992
15371
|
"__meta",
|
|
13993
15372
|
"__importSync",
|
|
13994
15373
|
"__import",
|
|
@@ -14008,13 +15387,13 @@ ${parts.join("\n")}`
|
|
|
14008
15387
|
}
|
|
14009
15388
|
function loadFileSync(filename) {
|
|
14010
15389
|
if (filename.endsWith(".json")) {
|
|
14011
|
-
const data2 = JSON.parse(
|
|
15390
|
+
const data2 = JSON.parse(decoder6.decode(fs.readFile(filename)));
|
|
14012
15391
|
return cjsToNamespace(data2);
|
|
14013
15392
|
}
|
|
14014
15393
|
const cached3 = cache2.get(filename);
|
|
14015
15394
|
if (cached3?.namespace) return cached3.namespace;
|
|
14016
15395
|
if (cached3?.evaluating) return cached3.exportsObj;
|
|
14017
|
-
const source =
|
|
15396
|
+
const source = decoder6.decode(fs.readFile(filename));
|
|
14018
15397
|
if (!isEsmFilename(filename, source)) {
|
|
14019
15398
|
const exports = cjs.loadFile(filename);
|
|
14020
15399
|
const ns = cjsToNamespace(exports);
|
|
@@ -14025,14 +15404,14 @@ ${parts.join("\n")}`
|
|
|
14025
15404
|
}
|
|
14026
15405
|
async function loadFileAsync(filename) {
|
|
14027
15406
|
if (filename.endsWith(".json")) {
|
|
14028
|
-
const data2 = JSON.parse(
|
|
15407
|
+
const data2 = JSON.parse(decoder6.decode(fs.readFile(filename)));
|
|
14029
15408
|
return cjsToNamespace(data2);
|
|
14030
15409
|
}
|
|
14031
15410
|
const cached3 = cache2.get(filename);
|
|
14032
15411
|
if (cached3?.namespace) return cached3.namespace;
|
|
14033
15412
|
if (cached3?.evaluating && evaluatingStack.has(filename)) return cached3.exportsObj;
|
|
14034
15413
|
if (cached3?.promise) return cached3.promise;
|
|
14035
|
-
const source =
|
|
15414
|
+
const source = decoder6.decode(fs.readFile(filename));
|
|
14036
15415
|
if (!isEsmFilename(filename, source)) {
|
|
14037
15416
|
const exports = cjs.loadFile(filename);
|
|
14038
15417
|
const ns = cjsToNamespace(exports);
|
|
@@ -14065,7 +15444,7 @@ ${parts.join("\n")}`
|
|
|
14065
15444
|
return ns;
|
|
14066
15445
|
}
|
|
14067
15446
|
function runMain(filename, source) {
|
|
14068
|
-
const src = source ??
|
|
15447
|
+
const src = source ?? decoder6.decode(fs.readFile(filename));
|
|
14069
15448
|
if (!isEsmFilename(filename, src)) {
|
|
14070
15449
|
return cjs.runMain(filename, src);
|
|
14071
15450
|
}
|
|
@@ -14090,7 +15469,7 @@ ${parts.join("\n")}`
|
|
|
14090
15469
|
const cached3 = cache2.get(filename);
|
|
14091
15470
|
if (cached3?.namespace) return cached3.namespace;
|
|
14092
15471
|
if (cached3?.evaluating) return cached3.exportsObj;
|
|
14093
|
-
const source =
|
|
15472
|
+
const source = decoder6.decode(fs.readFile(filename));
|
|
14094
15473
|
const { hasTopLevelAwait } = transformEsm(source, filename);
|
|
14095
15474
|
if (hasTopLevelAwait) {
|
|
14096
15475
|
const err = new Error(
|
|
@@ -14180,7 +15559,7 @@ function wrapCallSite(frame) {
|
|
|
14180
15559
|
const file = resolveFile(frame, parsed);
|
|
14181
15560
|
const rawLine = frame.getLineNumber?.() ?? parsed?.line;
|
|
14182
15561
|
const line = adjustLine(rawLine);
|
|
14183
|
-
const
|
|
15562
|
+
const col2 = frame.getColumnNumber?.() ?? parsed?.column ?? 0;
|
|
14184
15563
|
const method = frame.getMethodName?.();
|
|
14185
15564
|
const typeName = frame.getTypeName?.();
|
|
14186
15565
|
const userName = frame.getFunctionName?.();
|
|
@@ -14229,7 +15608,7 @@ function wrapCallSite(frame) {
|
|
|
14229
15608
|
getMethodName: () => method,
|
|
14230
15609
|
getFileName: () => file,
|
|
14231
15610
|
getLineNumber: () => line,
|
|
14232
|
-
getColumnNumber: () =>
|
|
15611
|
+
getColumnNumber: () => col2,
|
|
14233
15612
|
getEvalOrigin: () => frame.getEvalOrigin?.(),
|
|
14234
15613
|
isToplevel: () => !!isToplevel,
|
|
14235
15614
|
isEval: () => frame.isEval?.() ?? false,
|
|
@@ -14240,7 +15619,7 @@ function wrapCallSite(frame) {
|
|
|
14240
15619
|
getPromiseIndex: () => frame.getPromiseIndex?.(),
|
|
14241
15620
|
toString() {
|
|
14242
15621
|
const f = file || "unknown";
|
|
14243
|
-
const pos = line != null ? `:${line}:${
|
|
15622
|
+
const pos = line != null ? `:${line}:${col2 ?? 0}` : "";
|
|
14244
15623
|
const label = fn || "Object.<anonymous>";
|
|
14245
15624
|
if (f === "[eval]" || String(f).includes("[eval]")) {
|
|
14246
15625
|
if (label === "Object.<anonymous>") return `${f}${pos}`;
|
|
@@ -14317,20 +15696,20 @@ function snippetFor(ctx, loc, evalCode) {
|
|
|
14317
15696
|
const n = loc.line >= 1 && loc.line <= lines.length ? loc.line : 1;
|
|
14318
15697
|
const text = lines[n - 1];
|
|
14319
15698
|
if (text === void 0) return null;
|
|
14320
|
-
let
|
|
15699
|
+
let col2 = loc.column;
|
|
14321
15700
|
const throwAt = text.search(/\bthrow\b/);
|
|
14322
15701
|
const isAsyncLine = /\basync\b/.test(text);
|
|
14323
15702
|
if (loc.file === "[eval]" && throwAt === 0) {
|
|
14324
|
-
|
|
15703
|
+
col2 = 1;
|
|
14325
15704
|
} else if (throwAt >= 0 && isAsyncLine && /\bthrow\s+new\b/.test(text)) {
|
|
14326
|
-
|
|
15705
|
+
col2 = text.indexOf("new", throwAt) + 1;
|
|
14327
15706
|
} else if (throwAt >= 0) {
|
|
14328
|
-
|
|
14329
|
-
} else if (!(
|
|
14330
|
-
|
|
15707
|
+
col2 = throwAt + 1;
|
|
15708
|
+
} else if (!(col2 >= 1)) {
|
|
15709
|
+
col2 = 1;
|
|
14331
15710
|
}
|
|
14332
|
-
|
|
14333
|
-
return { file: loc.file, lineNo: n, text, caret: `${" ".repeat(
|
|
15711
|
+
col2 = Math.min(Math.max(1, col2), Math.max(1, text.length + 1));
|
|
15712
|
+
return { file: loc.file, lineNo: n, text, caret: `${" ".repeat(col2 - 1)}^` };
|
|
14334
15713
|
}
|
|
14335
15714
|
function assertionHeader(err) {
|
|
14336
15715
|
const msg = err.message || "";
|
|
@@ -14573,52 +15952,6 @@ UnhandledPromiseRejection: ${msg} {
|
|
|
14573
15952
|
return { body: body + trailer };
|
|
14574
15953
|
}
|
|
14575
15954
|
|
|
14576
|
-
// src/runtime/exit.mjs
|
|
14577
|
-
var NodeExitError = class extends Error {
|
|
14578
|
-
constructor(code) {
|
|
14579
|
-
super(`Process exited with code ${code}`);
|
|
14580
|
-
this.name = "NodeExitError";
|
|
14581
|
-
this.code = code;
|
|
14582
|
-
}
|
|
14583
|
-
};
|
|
14584
|
-
function numericExitCode(value) {
|
|
14585
|
-
const n = Number(value);
|
|
14586
|
-
return Number.isFinite(n) ? n & 255 : 0;
|
|
14587
|
-
}
|
|
14588
|
-
function describeReceived(value) {
|
|
14589
|
-
if (typeof value === "string") return `type string ('${value}')`;
|
|
14590
|
-
if (typeof value === "boolean") return `type boolean (${value})`;
|
|
14591
|
-
if (typeof value === "bigint") return `type bigint (${value}n)`;
|
|
14592
|
-
if (Array.isArray(value)) return "an instance of Array";
|
|
14593
|
-
if (typeof value === "object" && value !== null) return "an instance of Object";
|
|
14594
|
-
return `type ${typeof value}`;
|
|
14595
|
-
}
|
|
14596
|
-
function assignProcessExitCode(value) {
|
|
14597
|
-
if (value === null || value === void 0) return void 0;
|
|
14598
|
-
if (typeof value === "string") {
|
|
14599
|
-
const n = Number(value);
|
|
14600
|
-
if (value !== "" && Number.isInteger(n)) return n === 0 ? 0 : n;
|
|
14601
|
-
const err2 = new TypeError(
|
|
14602
|
-
`The "code" argument must be of type number. Received ${describeReceived(value)}`
|
|
14603
|
-
);
|
|
14604
|
-
err2.code = "ERR_INVALID_ARG_TYPE";
|
|
14605
|
-
throw err2;
|
|
14606
|
-
}
|
|
14607
|
-
if (typeof value === "number") {
|
|
14608
|
-
if (Number.isInteger(value)) return value === 0 ? 0 : value;
|
|
14609
|
-
const err2 = new RangeError(
|
|
14610
|
-
`The value of "code" is out of range. It must be an integer. Received ${String(value)}`
|
|
14611
|
-
);
|
|
14612
|
-
err2.code = "ERR_OUT_OF_RANGE";
|
|
14613
|
-
throw err2;
|
|
14614
|
-
}
|
|
14615
|
-
const err = new TypeError(
|
|
14616
|
-
`The "code" argument must be of type number. Received ${describeReceived(value)}`
|
|
14617
|
-
);
|
|
14618
|
-
err.code = "ERR_INVALID_ARG_TYPE";
|
|
14619
|
-
throw err;
|
|
14620
|
-
}
|
|
14621
|
-
|
|
14622
15955
|
// src/runtime/handles.mjs
|
|
14623
15956
|
function createHandleTable() {
|
|
14624
15957
|
const refed = /* @__PURE__ */ new Set();
|
|
@@ -14737,7 +16070,7 @@ function createStdin(ctx, handles, Buffer2) {
|
|
|
14737
16070
|
let encoding = null;
|
|
14738
16071
|
let ended = false;
|
|
14739
16072
|
let started = false;
|
|
14740
|
-
const
|
|
16073
|
+
const decoder8 = new TextDecoder();
|
|
14741
16074
|
const collected = [];
|
|
14742
16075
|
let collectDone = false;
|
|
14743
16076
|
const emitChunk = (bytes) => {
|
|
@@ -14745,7 +16078,7 @@ function createStdin(ctx, handles, Buffer2) {
|
|
|
14745
16078
|
const u8 = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
|
|
14746
16079
|
collected.push(u8);
|
|
14747
16080
|
const chunk = Buffer2 ? Buffer2.from(u8) : u8;
|
|
14748
|
-
const data2 = encoding === "utf8" || encoding === "utf-8" ?
|
|
16081
|
+
const data2 = encoding === "utf8" || encoding === "utf-8" ? decoder8.decode(chunk) : encoding ? chunk.toString?.(encoding) ?? decoder8.decode(chunk) : chunk;
|
|
14749
16082
|
ee.emit("data", data2);
|
|
14750
16083
|
};
|
|
14751
16084
|
const finish = () => {
|
|
@@ -14992,6 +16325,42 @@ var Process = class extends EventEmitter {
|
|
|
14992
16325
|
cwd() {
|
|
14993
16326
|
return this._cwd;
|
|
14994
16327
|
}
|
|
16328
|
+
/** Root (0) until credential plumbing is exposed on process. */
|
|
16329
|
+
getuid() {
|
|
16330
|
+
return 0;
|
|
16331
|
+
}
|
|
16332
|
+
geteuid() {
|
|
16333
|
+
return 0;
|
|
16334
|
+
}
|
|
16335
|
+
getgid() {
|
|
16336
|
+
return 0;
|
|
16337
|
+
}
|
|
16338
|
+
getegid() {
|
|
16339
|
+
return 0;
|
|
16340
|
+
}
|
|
16341
|
+
getgroups() {
|
|
16342
|
+
return [0];
|
|
16343
|
+
}
|
|
16344
|
+
/**
|
|
16345
|
+
* Minimal process.kill: only this process (pid === this.pid). Used by pnpm
|
|
16346
|
+
* cmd shims to re-raise a child's terminating signal. Unknown pids → ESRCH.
|
|
16347
|
+
*/
|
|
16348
|
+
kill(pid, signal = "SIGTERM") {
|
|
16349
|
+
const target = Number(pid);
|
|
16350
|
+
if (target !== this.pid) {
|
|
16351
|
+
const err = new Error(`kill ESRCH`);
|
|
16352
|
+
err.code = "ESRCH";
|
|
16353
|
+
err.errno = -3;
|
|
16354
|
+
err.syscall = "kill";
|
|
16355
|
+
throw err;
|
|
16356
|
+
}
|
|
16357
|
+
const name = typeof signal === "string" ? signal.startsWith("SIG") ? signal : `SIG${signal}` : "SIGTERM";
|
|
16358
|
+
if (name === "SIGTERM" || name === "SIGINT" || name === "SIGHUP" || name === "SIGKILL") {
|
|
16359
|
+
const codes = { SIGTERM: 143, SIGINT: 130, SIGHUP: 129, SIGKILL: 137 };
|
|
16360
|
+
this.exit(codes[name] ?? 1);
|
|
16361
|
+
}
|
|
16362
|
+
return true;
|
|
16363
|
+
}
|
|
14995
16364
|
chdir(path) {
|
|
14996
16365
|
if (typeof path !== "string") {
|
|
14997
16366
|
const err = new TypeError(
|
|
@@ -15460,7 +16829,7 @@ function createWebSocket(ctx, { handles, trackPromise: trackPromise2 } = {}) {
|
|
|
15460
16829
|
}
|
|
15461
16830
|
|
|
15462
16831
|
// src/runtime/run.mjs
|
|
15463
|
-
var
|
|
16832
|
+
var decoder7 = new TextDecoder();
|
|
15464
16833
|
function installJshGlobals(bindings) {
|
|
15465
16834
|
const saved = /* @__PURE__ */ new Map();
|
|
15466
16835
|
for (const name of Object.keys(bindings)) {
|
|
@@ -15499,6 +16868,8 @@ async function runNode(ctx, options = {}) {
|
|
|
15499
16868
|
let lastEvalCode;
|
|
15500
16869
|
let restoreGlobals = () => {
|
|
15501
16870
|
};
|
|
16871
|
+
let removeJshHandoff = () => {
|
|
16872
|
+
};
|
|
15502
16873
|
const removeCtxHooks = [];
|
|
15503
16874
|
const util2 = createUtil();
|
|
15504
16875
|
const printUncaught = (err) => {
|
|
@@ -15718,17 +17089,19 @@ slicc-jsh ${NODE_SHIM_VERSION} (Node-compatible, abi: js)
|
|
|
15718
17089
|
cjs.setRequireEsmHook((filename) => esm.requireEsm(filename));
|
|
15719
17090
|
cjs.setImportModuleHook((specifier, parent) => esm.importModule(specifier, parent));
|
|
15720
17091
|
try {
|
|
17092
|
+
const rt = {
|
|
17093
|
+
process: process2,
|
|
17094
|
+
console: console2,
|
|
17095
|
+
Buffer: Buffer2,
|
|
17096
|
+
fetch,
|
|
17097
|
+
createRequire: cjs.createRequire,
|
|
17098
|
+
importModule: (specifier, parent) => esm.importModule(specifier, parent),
|
|
17099
|
+
rewriteDynamicImports
|
|
17100
|
+
};
|
|
17101
|
+
removeJshHandoff = installJshHandoff(ctx, rt);
|
|
15721
17102
|
if (typeof options.main === "function") {
|
|
15722
17103
|
try {
|
|
15723
|
-
const result = options.main(
|
|
15724
|
-
process: process2,
|
|
15725
|
-
console: console2,
|
|
15726
|
-
Buffer: Buffer2,
|
|
15727
|
-
fetch,
|
|
15728
|
-
createRequire: cjs.createRequire,
|
|
15729
|
-
importModule: (specifier, parent) => esm.importModule(specifier, parent),
|
|
15730
|
-
rewriteDynamicImports
|
|
15731
|
-
});
|
|
17104
|
+
const result = options.main(rt);
|
|
15732
17105
|
if (result != null && typeof result.then === "function") {
|
|
15733
17106
|
trackPromise(handles, result).catch(() => {
|
|
15734
17107
|
});
|
|
@@ -15776,7 +17149,7 @@ slicc-jsh ${NODE_SHIM_VERSION} (Node-compatible, abi: js)
|
|
|
15776
17149
|
merged.set(c, off);
|
|
15777
17150
|
off += c.byteLength;
|
|
15778
17151
|
}
|
|
15779
|
-
const source =
|
|
17152
|
+
const source = decoder7.decode(merged);
|
|
15780
17153
|
lastEvalCode = source;
|
|
15781
17154
|
process2._evalCode = source;
|
|
15782
17155
|
process2.argv[1] = "[stdin]";
|
|
@@ -15859,7 +17232,7 @@ slicc-jsh ${NODE_SHIM_VERSION} (Node-compatible, abi: js)
|
|
|
15859
17232
|
const filePath = ctx.resolve(parsed.script);
|
|
15860
17233
|
let source;
|
|
15861
17234
|
try {
|
|
15862
|
-
source =
|
|
17235
|
+
source = decoder7.decode(ctx.sync.fs.readFile(filePath));
|
|
15863
17236
|
} catch (err) {
|
|
15864
17237
|
const msg = err?.message ?? String(err);
|
|
15865
17238
|
await ctx.write(2, `${ctx.argv[0]}: cannot open ${parsed.script}: ${msg}
|
|
@@ -15948,6 +17321,7 @@ slicc-jsh ${NODE_SHIM_VERSION} (Node-compatible, abi: js)
|
|
|
15948
17321
|
}
|
|
15949
17322
|
try {
|
|
15950
17323
|
restoreGlobals();
|
|
17324
|
+
removeJshHandoff();
|
|
15951
17325
|
} catch {
|
|
15952
17326
|
}
|
|
15953
17327
|
}
|