@covro/covro 0.6.1-dev.3 → 0.6.1-dev.4
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 +2 -2
- package/README.zh-CN.md +2 -2
- package/dist/cli/background.js +10 -7
- package/dist/cli/background.js.map +2 -2
- package/dist/cli/daemon.js +3 -1
- package/dist/cli/daemon.js.map +2 -2
- package/dist/cli/launch-environment.js +5 -2
- package/dist/cli/launch-environment.js.map +2 -2
- package/dist/cli/launchd.js +14 -8
- package/dist/cli/launchd.js.map +2 -2
- package/dist/cli/runtime-launch.js +108 -0
- package/dist/cli/runtime-launch.js.map +7 -0
- package/dist/cli/runtime.js +12 -0
- package/dist/cli/runtime.js.map +7 -0
- package/dist/cli/service.js +7 -4
- package/dist/cli/service.js.map +2 -2
- package/dist/shared/updates.js.map +2 -2
- package/dist/update-worker.cjs +1111 -754
- package/dist/updates/manager.js +89 -8
- package/dist/updates/manager.js.map +2 -2
- package/dist/updates/registry.js +7 -6
- package/dist/updates/registry.js.map +2 -2
- package/dist/updates/runtime.js +183 -0
- package/dist/updates/runtime.js.map +7 -0
- package/dist/updates/transaction.js +8 -4
- package/dist/updates/transaction.js.map +2 -2
- package/dist/updates/worker.js +177 -112
- package/dist/updates/worker.js.map +3 -3
- package/dist/web/assets/{abnfDiagram-WEYOIA3C-BzVXOBcA.js → abnfDiagram-WEYOIA3C--q3UKu-m.js} +1 -1
- package/dist/web/assets/{arc-CyQWAnQd.js → arc-CsDLrA4o.js} +1 -1
- package/dist/web/assets/{architecture-WOLXFQ4H-BEoyxwG0.js → architecture-WOLXFQ4H-6TbwoUek.js} +1 -1
- package/dist/web/assets/{architectureDiagram-ZHVYKT53-CCXl4OZW.js → architectureDiagram-ZHVYKT53-GNeotXgT.js} +1 -1
- package/dist/web/assets/{blockDiagram-RJAE7QA3-D7dGEImG.js → blockDiagram-RJAE7QA3-Ric8Njom.js} +1 -1
- package/dist/web/assets/{c4Diagram-XDPPPE54-DV8znYp0.js → c4Diagram-XDPPPE54-CSFzq9_N.js} +1 -1
- package/dist/web/assets/channel-M3Agpi7p.js +1 -0
- package/dist/web/assets/{chunk-2E7WHVMD-0QrTjfW_.js → chunk-2E7WHVMD-BwjaS8bo.js} +1 -1
- package/dist/web/assets/{chunk-4EMNKR2T-D-zlzBAy.js → chunk-4EMNKR2T-V38rR2JO.js} +1 -1
- package/dist/web/assets/{chunk-55XCU76K-CVHEMROA.js → chunk-55XCU76K-DjF4oGX1.js} +1 -1
- package/dist/web/assets/{chunk-7S6XSTFO-C2rIevGp.js → chunk-7S6XSTFO-5YHKdb3u.js} +1 -1
- package/dist/web/assets/{chunk-AQDTSKZB-DYAv-Riy.js → chunk-AQDTSKZB-BGqebfJY.js} +1 -1
- package/dist/web/assets/{chunk-DSNLSHJZ-DWI7CHhD.js → chunk-DSNLSHJZ-DoWMycRk.js} +1 -1
- package/dist/web/assets/{chunk-HAGFOTED-CO_q1459.js → chunk-HAGFOTED-D23fXc2S.js} +1 -1
- package/dist/web/assets/{chunk-HNE4Q36P-CgksCWEg.js → chunk-HNE4Q36P-BIJsRvPs.js} +1 -1
- package/dist/web/assets/{chunk-NQOKRVIF-BkpxlXF9.js → chunk-NQOKRVIF-C54OjZSl.js} +1 -1
- package/dist/web/assets/{chunk-UHW7PFBP-BMZQKGkg.js → chunk-UHW7PFBP-C0X5au9W.js} +1 -1
- package/dist/web/assets/{chunk-VQ5W62QI-DxCsqxIr.js → chunk-VQ5W62QI-C2vDy1Kl.js} +1 -1
- package/dist/web/assets/{chunk-WQQL4CDK-Drs4qCbY.js → chunk-WQQL4CDK-CcesvmQO.js} +1 -1
- package/dist/web/assets/{chunk-XXDRQBXY--mv0FkSH.js → chunk-XXDRQBXY-EiI0PYcn.js} +1 -1
- package/dist/web/assets/{chunk-YZO67HFG-BrXN1Efx.js → chunk-YZO67HFG-BqeaVf9n.js} +1 -1
- package/dist/web/assets/{chunk-ZAUX2LTX-DWiVb0QN.js → chunk-ZAUX2LTX-DW6sEeTI.js} +1 -1
- package/dist/web/assets/{chunk-ZCHMQSOR-p8m3-BJN.js → chunk-ZCHMQSOR-BrlOBygH.js} +1 -1
- package/dist/web/assets/{classDiagram-v2-4MYWR3UA-lnHHmraY.js → classDiagram-v2-4MYWR3UA-DFpCrr_A.js} +1 -1
- package/dist/web/assets/{cose-bilkent-JH36ORCC-B1BVV8Wv.js → cose-bilkent-JH36ORCC-CAWPSnN6.js} +1 -1
- package/dist/web/assets/{cynefin-EF2NZ3EQ-C4TULYfr.js → cynefin-EF2NZ3EQ-DMeYqL7r.js} +1 -1
- package/dist/web/assets/{cynefinDiagram-WF24UDRP-rExRJUWB.js → cynefinDiagram-WF24UDRP-DI-bFsxF.js} +1 -1
- package/dist/web/assets/{dagre-NK4GIZVX-DI6KC0Pk.js → dagre-NK4GIZVX-CdoitF7O.js} +1 -1
- package/dist/web/assets/{diagram-CBK3MWTC-Don_Jr-E.js → diagram-CBK3MWTC-DVTPnBLF.js} +1 -1
- package/dist/web/assets/{diagram-I5XIIV2D-BW1FwPhX.js → diagram-I5XIIV2D-3eS1TE4r.js} +1 -1
- package/dist/web/assets/{diagram-ODIL2UCW-DxqQXqCa.js → diagram-ODIL2UCW-cLU1ehlH.js} +1 -1
- package/dist/web/assets/{diagram-PFBEJUXE-DeFKndZw.js → diagram-PFBEJUXE-Bd1TAqaL.js} +1 -1
- package/dist/web/assets/{diagram-RJA3I4VV-CM31q1uK.js → diagram-RJA3I4VV-CQqVlBOF.js} +1 -1
- package/dist/web/assets/{diagram-TYUNFSNR-DTq2AOnu.js → diagram-TYUNFSNR-CCGCiVOv.js} +1 -1
- package/dist/web/assets/{dist-V4sbzI-h.js → dist-BE4VEq-n.js} +1 -1
- package/dist/web/assets/{ebnfDiagram-V4P3TTPT-DF58HT_y.js → ebnfDiagram-V4P3TTPT-BGOHdBAS.js} +1 -1
- package/dist/web/assets/{elk-QONTBCTQ-BwrVYRCb.js → elk-QONTBCTQ-D5OlAFYO.js} +1 -1
- package/dist/web/assets/{erDiagram-KYQIGQAA-P1WxHJun.js → erDiagram-KYQIGQAA-DUtlMKNi.js} +1 -1
- package/dist/web/assets/{eventmodeling-K75KTNOO-BtccOmRK.js → eventmodeling-K75KTNOO-DXK-D1Z0.js} +1 -1
- package/dist/web/assets/flowDiagram-IUGLLWBU-4EVBAMrs.js +1 -0
- package/dist/web/assets/{ganttDiagram-R7GPNTJY-D3qJC4vO.js → ganttDiagram-R7GPNTJY-BVGsal-Q.js} +1 -1
- package/dist/web/assets/{gitGraph-VSP46ZUC-BVY9Gtih.js → gitGraph-VSP46ZUC-DV6-WqhO.js} +1 -1
- package/dist/web/assets/{gitGraphDiagram-PDYL7XHY-CZvvvj3Q.js → gitGraphDiagram-PDYL7XHY-0QK_COI_.js} +1 -1
- package/dist/web/assets/{index-B9qAZAx0.js → index-BBPzwzxe.js} +46 -44
- package/dist/web/assets/{index-_yn3Nt0h.css → index-CSpioreu.css} +1 -1
- package/dist/web/assets/{info-OHQRW6UA-BGqiJ9Yx.js → info-OHQRW6UA-BZipuOqr.js} +1 -1
- package/dist/web/assets/{infoDiagram-MVDRKAX5-DxdTuj3n.js → infoDiagram-MVDRKAX5-1db4SZ4k.js} +1 -1
- package/dist/web/assets/{ishikawaDiagram-HPEHV2GE-DbhjLHsb.js → ishikawaDiagram-HPEHV2GE-DTrI4oTY.js} +1 -1
- package/dist/web/assets/{journeyDiagram-BOSHW7O7-DJROkZUW.js → journeyDiagram-BOSHW7O7-Bk5sPpaD.js} +1 -1
- package/dist/web/assets/{kanban-definition-FNSA4HC5-D4HijqrG.js → kanban-definition-FNSA4HC5-smf99L9V.js} +1 -1
- package/dist/web/assets/{line-d2EHEr40.js → line-9F_GFNcI.js} +1 -1
- package/dist/web/assets/{linear-CnT_m8Aq.js → linear-B80ozVj0.js} +1 -1
- package/dist/web/assets/{mermaid-parser.core-BqD0_cdI.js → mermaid-parser.core-DldmXGom.js} +3 -3
- package/dist/web/assets/{mermaid.core-Dd1sHHm2.js → mermaid.core-DIZvVrdE.js} +4 -4
- package/dist/web/assets/{mindmap-definition-6OY57UG3-KPpq2dAV.js → mindmap-definition-6OY57UG3-CLhpt9eO.js} +1 -1
- package/dist/web/assets/{packet-JDAUHWVQ-CXnrw9bC.js → packet-JDAUHWVQ-CL3Q6msP.js} +1 -1
- package/dist/web/assets/{pegDiagram-ECIUJNBX-BIXIhs7W.js → pegDiagram-ECIUJNBX-BeBvMY1a.js} +1 -1
- package/dist/web/assets/{pie-XZMESJXO-TrDzTbhs.js → pie-XZMESJXO-D_fdN7qT.js} +1 -1
- package/dist/web/assets/{pieDiagram-GNMPY74T-D8a4Sfn1.js → pieDiagram-GNMPY74T-DROrBz0o.js} +1 -1
- package/dist/web/assets/{quadrantDiagram-D57K4MC3-Bt2I_ygO.js → quadrantDiagram-D57K4MC3-C57SBgx7.js} +1 -1
- package/dist/web/assets/{radar-ABXABTNO-BZDG4zL1.js → radar-ABXABTNO-B0-FyoLn.js} +1 -1
- package/dist/web/assets/{railroad-I3PHUGI6-CVZI3RsT.js → railroad-I3PHUGI6-_ocCyblF.js} +1 -1
- package/dist/web/assets/{railroad-abnf-LNEFI6M7-BLFBfBsa.js → railroad-abnf-LNEFI6M7-Ct1oCv45.js} +1 -1
- package/dist/web/assets/{railroad-ebnf-DWYD2UWJ-CKhl-KNN.js → railroad-ebnf-DWYD2UWJ-Dz3MdcvL.js} +1 -1
- package/dist/web/assets/{railroad-peg-JR7BVNR7-CaxuMu1-.js → railroad-peg-JR7BVNR7-Ds4ONRXC.js} +1 -1
- package/dist/web/assets/{railroadDiagram-Y72NRBL7-BmN9o9yG.js → railroadDiagram-Y72NRBL7-DqS1adHB.js} +1 -1
- package/dist/web/assets/{requirementDiagram-EQYSW5RA-CytiXIk0.js → requirementDiagram-EQYSW5RA-BReuC0TK.js} +1 -1
- package/dist/web/assets/{sankeyDiagram-SY24JHO5-2oasnbjI.js → sankeyDiagram-SY24JHO5-DDjUr4b9.js} +1 -1
- package/dist/web/assets/{sequenceDiagram-BLEHNHQU-CgKYeJhF.js → sequenceDiagram-BLEHNHQU-D71Uv16-.js} +1 -1
- package/dist/web/assets/{src-DeJ6DlL6.js → src-DiejhDC1.js} +1 -1
- package/dist/web/assets/{stateDiagram-v2-A6IESKWZ-BcBo9Tt9.js → stateDiagram-v2-A6IESKWZ-B8w400YH.js} +1 -1
- package/dist/web/assets/{swimlanes-B3ENRKFQ-DHvDY449.js → swimlanes-B3ENRKFQ-Cx8dbIra.js} +1 -1
- package/dist/web/assets/swimlanesDiagram-AYQRV4AK-DLuNBE0x.js +8 -0
- package/dist/web/assets/{timeline-definition-JXYKGLGB-DHOYx58-.js → timeline-definition-JXYKGLGB-wEhTG9mn.js} +1 -1
- package/dist/web/assets/{treeView-D4JQ5SDB-BKzsH1H3.js → treeView-D4JQ5SDB-J1xTBv_o.js} +1 -1
- package/dist/web/assets/{treemap-SAJKECNS-Dznq3JYy.js → treemap-SAJKECNS-B-HfL4ut.js} +1 -1
- package/dist/web/assets/{usecaseDiagram-WPOLBNNX-B_Qb6GIb.js → usecaseDiagram-WPOLBNNX-Bqvh0bcu.js} +1 -1
- package/dist/web/assets/{vennDiagram-Q3Y3IDCW-DDRYcnZj.js → vennDiagram-Q3Y3IDCW-B2TB6cEs.js} +1 -1
- package/dist/web/assets/{wardley-7MLQ67FV-CwCK5TZf.js → wardley-7MLQ67FV-BF1eXS8d.js} +1 -1
- package/dist/web/assets/{wardleyDiagram-IVAIDKWA-DW68fX4l.js → wardleyDiagram-IVAIDKWA-BZzFLzrU.js} +1 -1
- package/dist/web/assets/{xychartDiagram-4URNHDU4-Cdk5RxaR.js → xychartDiagram-4URNHDU4-Dh0JpuLV.js} +1 -1
- package/dist/web/index.html +2 -2
- package/dist/web/notification-worker.js +33 -0
- package/package.json +3 -3
- package/dist/web/assets/channel-kBOj6wNa.js +0 -1
- package/dist/web/assets/flowDiagram-IUGLLWBU-DnTlbOxw.js +0 -1
- package/dist/web/assets/swimlanesDiagram-AYQRV4AK-2cPOFNNL.js +0 -8
package/dist/updates/manager.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
import { createHash } from "node:crypto";
|
|
7
7
|
import { spawn } from "node:child_process";
|
|
8
8
|
import { copyFile, mkdir, open } from "node:fs/promises";
|
|
9
|
-
import { join } from "node:path";
|
|
9
|
+
import { join, resolve, sep } from "node:path";
|
|
10
10
|
import lockfile from "proper-lockfile";
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
import { AppError } from "../shared/errors.js";
|
|
@@ -17,6 +17,14 @@ import {
|
|
|
17
17
|
import { packageInfo, packageRoot } from "../cli/paths.js";
|
|
18
18
|
import { readJson, saveJson } from "./files.js";
|
|
19
19
|
import { compareVersions, inspectInstallation, lookupRelease } from "./registry.js";
|
|
20
|
+
import {
|
|
21
|
+
assertRuntime,
|
|
22
|
+
resolveRuntimeTarget,
|
|
23
|
+
runtimeChanged as changedRuntime
|
|
24
|
+
} from "./runtime.js";
|
|
25
|
+
import { runningRuntime } from "../cli/runtime.js";
|
|
26
|
+
import { launchRuntime } from "../cli/runtime-launch.js";
|
|
27
|
+
const runtimeChanged = (target) => changedRuntime(target, runningRuntime());
|
|
20
28
|
const settingsSchema = z.object({ channel: z.enum(releaseChannels), automatic: z.boolean() }).strict();
|
|
21
29
|
const updateRequestSchema = z.object({
|
|
22
30
|
clientOperationId: z.uuid(),
|
|
@@ -47,6 +55,8 @@ class UpdateManager {
|
|
|
47
55
|
available;
|
|
48
56
|
checkedAt;
|
|
49
57
|
checkError;
|
|
58
|
+
target;
|
|
59
|
+
runtimeError;
|
|
50
60
|
reason = "\u5F53\u524D\u670D\u52A1\u672A\u901A\u8FC7 covro \u542F\u52A8\uFF0C\u7F51\u9875\u4EC5\u652F\u6301\u7248\u672C\u68C0\u6D4B\uFF1B\u5347\u7EA7\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u3002";
|
|
51
61
|
timer;
|
|
52
62
|
checking;
|
|
@@ -54,6 +64,7 @@ class UpdateManager {
|
|
|
54
64
|
context;
|
|
55
65
|
async initialize() {
|
|
56
66
|
if (!this.context) return;
|
|
67
|
+
await this.loadDirectory();
|
|
57
68
|
const saved = await readJson(join(this.context.directory, "settings.json"));
|
|
58
69
|
if (saved !== void 0) this.settings = settingsSchema.parse(saved);
|
|
59
70
|
this.reason = process.platform === "win32" ? "Windows \u6682\u4E0D\u652F\u6301\u53D7\u7BA1\u81EA\u52A8\u5347\u7EA7\uFF0C\u8BF7\u4F7F\u7528 npm \u66F4\u65B0\u5E76\u91CD\u542F\u3002" : await inspectInstallation(this.context.root) ?? "";
|
|
@@ -63,6 +74,18 @@ class UpdateManager {
|
|
|
63
74
|
void this.automatic().catch(() => {
|
|
64
75
|
});
|
|
65
76
|
}
|
|
77
|
+
async loadDirectory() {
|
|
78
|
+
if (!this.context) return;
|
|
79
|
+
const saved = await readJson(
|
|
80
|
+
join(this.context.location.state, "updates.json")
|
|
81
|
+
);
|
|
82
|
+
if (saved) {
|
|
83
|
+
const directory = resolve(saved.directory);
|
|
84
|
+
if (!directory.startsWith(resolve(this.context.location.home, "updates") + sep))
|
|
85
|
+
throw new Error("\u5347\u7EA7\u8BB0\u5F55\u76EE\u5F55\u4E0D\u5728 Covro \u7BA1\u7406\u76EE\u5F55\u4E2D");
|
|
86
|
+
this.context.directory = directory;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
66
89
|
async status() {
|
|
67
90
|
const run = this.context ? await readJson(join(this.context.directory, "run.json")) : void 0;
|
|
68
91
|
return {
|
|
@@ -79,12 +102,42 @@ class UpdateManager {
|
|
|
79
102
|
} : void 0,
|
|
80
103
|
checkedAt: this.checkedAt,
|
|
81
104
|
checkError: this.checkError,
|
|
82
|
-
run
|
|
105
|
+
run,
|
|
106
|
+
runtime: {
|
|
107
|
+
current: runningRuntime(),
|
|
108
|
+
target: this.target,
|
|
109
|
+
migration: Boolean(this.target && runtimeChanged(this.target)),
|
|
110
|
+
error: this.runtimeError
|
|
111
|
+
}
|
|
83
112
|
};
|
|
84
113
|
}
|
|
85
114
|
async check(channel = this.settings.channel) {
|
|
115
|
+
this.target = void 0;
|
|
116
|
+
this.runtimeError = void 0;
|
|
117
|
+
if (this.context && !this.reason) {
|
|
118
|
+
try {
|
|
119
|
+
this.target = await resolveRuntimeTarget();
|
|
120
|
+
} catch (error) {
|
|
121
|
+
this.runtimeError = error.message;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
86
124
|
try {
|
|
87
|
-
const
|
|
125
|
+
const local = this.target && runtimeChanged(this.target) ? this.target : void 0;
|
|
126
|
+
let release;
|
|
127
|
+
try {
|
|
128
|
+
release = await lookupRelease(channel, this.network.signal);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
if (!local) throw error;
|
|
131
|
+
}
|
|
132
|
+
if (local && (!release || compareVersions(local.version, release.version) >= 0))
|
|
133
|
+
release = {
|
|
134
|
+
version: local.version,
|
|
135
|
+
channel: local.version.includes("-dev.") ? "dev" : local.version.includes("-beta.") ? "beta" : "stable",
|
|
136
|
+
covroCommit: local.covroCommit,
|
|
137
|
+
gitHead: void 0,
|
|
138
|
+
covroCodex: local.covroCodex
|
|
139
|
+
};
|
|
140
|
+
if (!release) throw new Error("\u672A\u627E\u5230\u53EF\u7528\u7248\u672C");
|
|
88
141
|
this.available = {
|
|
89
142
|
version: release.version,
|
|
90
143
|
requestedChannel: channel,
|
|
@@ -109,7 +162,7 @@ class UpdateManager {
|
|
|
109
162
|
}
|
|
110
163
|
async activationPending() {
|
|
111
164
|
const run = (await this.status()).run;
|
|
112
|
-
if (run && !run.committed && run.phase
|
|
165
|
+
if (run && !run.committed && ["failed", "rolledBack"].includes(run.phase) && (run.from !== packageInfo.version || run.runtime && runtimeChanged(run.runtime.from)))
|
|
113
166
|
throw new Error(
|
|
114
167
|
"\u4E0A\u6B21\u5347\u7EA7\u5C1A\u672A\u5B8C\u6210\u6062\u590D\uFF1B\u8BF7\u8FD0\u884C covro update repair \u540E\u518D\u542F\u52A8\uFF0C\u907F\u514D\u5199\u5165\u672A\u6FC0\u6D3B\u7248\u672C\u3002"
|
|
115
168
|
);
|
|
@@ -118,6 +171,7 @@ class UpdateManager {
|
|
|
118
171
|
if (run && !run.committed && run.phase === "verifying") {
|
|
119
172
|
if (run.target !== packageInfo.version)
|
|
120
173
|
throw new Error("\u5347\u7EA7\u5019\u9009\u8EAB\u4EFD\u4E0D\u5339\u914D\uFF0C\u8BF7\u8FD0\u884C covro update repair");
|
|
174
|
+
if (run.runtime) assertRuntime(runningRuntime(), run.runtime.target);
|
|
121
175
|
return true;
|
|
122
176
|
}
|
|
123
177
|
return false;
|
|
@@ -127,6 +181,7 @@ class UpdateManager {
|
|
|
127
181
|
const run = (await this.status()).run;
|
|
128
182
|
if (!run || run.id !== id || run.phase !== "verifying" || run.target !== packageInfo.version)
|
|
129
183
|
throw new Error("\u5347\u7EA7\u8BB0\u5F55\u3001\u7248\u672C\u6216\u8FD0\u884C\u72B6\u6001\u4E0D\u5339\u914D");
|
|
184
|
+
if (run.runtime) assertRuntime(runningRuntime(), run.runtime.target);
|
|
130
185
|
if (!run.codex || run.codex.version !== this.codexVersion())
|
|
131
186
|
throw new Error("Codex \u7248\u672C\u5728\u5347\u7EA7\u671F\u95F4\u53D1\u751F\u53D8\u5316\u6216\u7F3A\u5C11\u6821\u9A8C\u8BB0\u5F55\uFF0C\u62D2\u7EDD\u6FC0\u6D3B");
|
|
132
187
|
requireCodexCompatibility(
|
|
@@ -141,7 +196,8 @@ class UpdateManager {
|
|
|
141
196
|
committed: true,
|
|
142
197
|
phase: "succeeded",
|
|
143
198
|
message: "\u5347\u7EA7\u6210\u529F\uFF0C\u670D\u52A1\u5DF2\u6062\u590D",
|
|
144
|
-
updatedAt: Date.now()
|
|
199
|
+
updatedAt: Date.now(),
|
|
200
|
+
runtime: run.runtime ? { ...run.runtime, actual: runningRuntime() } : void 0
|
|
145
201
|
});
|
|
146
202
|
}
|
|
147
203
|
async start(input) {
|
|
@@ -176,6 +232,13 @@ class UpdateManager {
|
|
|
176
232
|
}
|
|
177
233
|
const channel = request.channel ?? this.settings.channel;
|
|
178
234
|
const checked = await this.check(channel);
|
|
235
|
+
const target = this.target;
|
|
236
|
+
if (this.runtimeError || !target)
|
|
237
|
+
throw new AppError(
|
|
238
|
+
"UPDATE_RUNTIME",
|
|
239
|
+
this.runtimeError ?? "\u65E0\u6CD5\u786E\u8BA4\u76EE\u6807 Node \u73AF\u5883\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u3002",
|
|
240
|
+
409
|
|
241
|
+
);
|
|
179
242
|
if (!checked.available)
|
|
180
243
|
throw new AppError("UPDATE_CHECK_FAILED", checked.checkError ?? "\u672A\u627E\u5230\u53EF\u7528\u7248\u672C", 502);
|
|
181
244
|
if (checked.available.downgrade && !request.allowDowngrade)
|
|
@@ -184,7 +247,7 @@ class UpdateManager {
|
|
|
184
247
|
"\u76EE\u6807\u7248\u672C\u8F83\u65E7\uFF0C\u9700\u8981\u660E\u786E\u5141\u8BB8\u964D\u7EA7\uFF1B\u4ECD\u5C06\u68C0\u67E5\u6570\u636E\u5E93\u517C\u5BB9\u6027\u3002",
|
|
185
248
|
409
|
|
186
249
|
);
|
|
187
|
-
if (compareVersions(checked.available.version, packageInfo.version) === 0) {
|
|
250
|
+
if (compareVersions(checked.available.version, packageInfo.version) === 0 && !runtimeChanged(target)) {
|
|
188
251
|
return this.configure({ ...this.settings, channel });
|
|
189
252
|
}
|
|
190
253
|
const confirmation = request.codexConfirmation;
|
|
@@ -214,9 +277,26 @@ class UpdateManager {
|
|
|
214
277
|
phase: "installing",
|
|
215
278
|
message: "\u6B63\u5728\u5B89\u88C5\u5019\u9009 npm \u5305",
|
|
216
279
|
startedAt: Date.now(),
|
|
217
|
-
updatedAt: Date.now()
|
|
280
|
+
updatedAt: Date.now(),
|
|
281
|
+
runtime: { from: runningRuntime(), target }
|
|
218
282
|
};
|
|
219
|
-
await
|
|
283
|
+
const currentLaunch = await launchRuntime(this.context.location, runningRuntime().entry);
|
|
284
|
+
if (currentLaunch.node !== process.execPath || currentLaunch.entry !== runningRuntime().entry)
|
|
285
|
+
throw new AppError(
|
|
286
|
+
"UPDATE_RUNTIME",
|
|
287
|
+
"\u4FDD\u5B58\u7684\u542F\u52A8\u6765\u6E90\u4E0E\u5F53\u524D\u5B9E\u4F8B\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u6838\u5BF9\u5B9E\u4F8B\u540E\u91CD\u8BD5\u3002",
|
|
288
|
+
409
|
|
289
|
+
);
|
|
290
|
+
const context = {
|
|
291
|
+
...this.context,
|
|
292
|
+
source: currentLaunch,
|
|
293
|
+
target,
|
|
294
|
+
reuseTarget: runtimeChanged(target) && target.root !== this.context.root.replace(/\/$/, "") && target.version === run.target
|
|
295
|
+
};
|
|
296
|
+
await saveJson(join(this.context.directory, "context.json"), context);
|
|
297
|
+
await saveJson(join(this.context.location.state, "updates.json"), {
|
|
298
|
+
directory: this.context.directory
|
|
299
|
+
});
|
|
220
300
|
const worker = join(this.context.directory, "worker.cjs");
|
|
221
301
|
await copyFile(join(packageRoot, "dist/update-worker.cjs"), worker);
|
|
222
302
|
const log = await open(join(this.context.directory, "update.log"), "a", 384);
|
|
@@ -254,6 +334,7 @@ class UpdateManager {
|
|
|
254
334
|
}
|
|
255
335
|
async repair() {
|
|
256
336
|
if (!this.context) throw new Error("\u6CA1\u6709\u53EF\u6062\u590D\u7684\u53D7\u7BA1\u5B89\u88C5");
|
|
337
|
+
await this.loadDirectory();
|
|
257
338
|
const directory = this.context.directory;
|
|
258
339
|
let releaseLock;
|
|
259
340
|
try {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/updates/manager.ts"],
|
|
4
|
-
"sourcesContent": ["import { CODEX_COMPATIBILITY } from '../codex/compatibility.js';\nimport {\n assessCodexCompatibility,\n requireCodexCompatibility,\n} from '../shared/codex-compatibility.js';\nimport { createHash } from 'node:crypto';\nimport { spawn } from 'node:child_process';\nimport { copyFile, mkdir, open } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport lockfile from 'proper-lockfile';\nimport { z } from 'zod';\nimport { AppError } from '../shared/errors.js';\nimport {\n releaseChannels,\n updateActive,\n type UpdateController,\n type UpdateSettings,\n type UpdateRun,\n type UpdateStatus,\n type ReleaseChannel,\n} from '../shared/updates.js';\nimport { packageInfo, packageRoot, type CovroPaths } from '../cli/paths.js';\nimport { readJson, saveJson } from './files.js';\nimport { compareVersions, inspectInstallation, lookupRelease } from './registry.js';\n\nexport const settingsSchema = z\n .object({ channel: z.enum(releaseChannels), automatic: z.boolean() })\n .strict();\nexport const updateRequestSchema = z\n .object({\n clientOperationId: z.uuid(),\n channel: z.enum(releaseChannels).optional(),\n allowDowngrade: z.boolean().optional(),\n codexConfirmation: z\n .object({ version: z.string().max(128), target: z.string().max(128) })\n .strict()\n .optional(),\n })\n .strict();\nexport interface UpdateContext {\n location: CovroPaths;\n dataDir: string;\n root: string;\n directory: string;\n}\nexport class UpdateManager implements UpdateController {\n private settings: UpdateSettings = {\n channel:\n packageInfo.covroChannel ??\n (packageInfo.version?.includes('-dev.')\n ? 'dev'\n : packageInfo.version?.includes('-beta.')\n ? 'beta'\n : 'stable'),\n automatic: false,\n };\n private available?: UpdateStatus['available'];\n private checkedAt?: number;\n private checkError?: string;\n private reason = '\u5F53\u524D\u670D\u52A1\u672A\u901A\u8FC7 covro \u542F\u52A8\uFF0C\u7F51\u9875\u4EC5\u652F\u6301\u7248\u672C\u68C0\u6D4B\uFF1B\u5347\u7EA7\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u3002';\n private timer?: ReturnType<typeof setInterval>;\n private checking?: Promise<UpdateStatus>;\n private readonly network = new AbortController();\n readonly context?: UpdateContext;\n constructor(\n location?: CovroPaths,\n dataDir?: string,\n private readonly codexVersion: () => string | null = () => null,\n ) {\n if (location && dataDir)\n this.context = {\n location,\n dataDir,\n root: packageRoot,\n directory: join(\n location.home,\n 'updates',\n createHash('sha256').update(packageRoot).digest('hex').slice(0, 16),\n ),\n };\n }\n async initialize() {\n if (!this.context) return;\n const saved = await readJson<unknown>(join(this.context.directory, 'settings.json'));\n if (saved !== undefined) this.settings = settingsSchema.parse(saved);\n this.reason =\n process.platform === 'win32'\n ? 'Windows \u6682\u4E0D\u652F\u6301\u53D7\u7BA1\u81EA\u52A8\u5347\u7EA7\uFF0C\u8BF7\u4F7F\u7528 npm \u66F4\u65B0\u5E76\u91CD\u542F\u3002'\n : ((await inspectInstallation(this.context.root)) ?? '');\n this.timer = setInterval(() => void this.automatic().catch(() => {}), 30 * 60_000);\n this.timer.unref();\n // No network request in the startup critical path.\n void this.automatic().catch(() => {});\n }\n async status(): Promise<UpdateStatus> {\n const run = this.context\n ? await readJson<UpdateRun>(join(this.context.directory, 'run.json'))\n : undefined;\n return {\n version: packageInfo.version ?? 'unknown',\n commit: packageInfo.covroCommit,\n source: 'npm',\n codex: assessCodexCompatibility(CODEX_COMPATIBILITY, this.codexVersion()),\n settings: this.settings,\n supported: !this.reason,\n unsupportedReason: this.reason || undefined,\n available: this.available\n ? {\n ...this.available,\n codex: assessCodexCompatibility(this.available.codex.manifest, this.codexVersion()),\n }\n : undefined,\n checkedAt: this.checkedAt,\n checkError: this.checkError,\n run,\n };\n }\n async check(channel: ReleaseChannel = this.settings.channel) {\n try {\n const release = await lookupRelease(channel, this.network.signal);\n this.available = {\n version: release.version,\n requestedChannel: channel,\n channel: release.channel,\n commit: release.covroCommit ?? release.gitHead,\n downgrade: compareVersions(release.version, packageInfo.version) < 0,\n codex: assessCodexCompatibility(release.covroCodex, this.codexVersion()),\n };\n this.checkError = undefined;\n } catch (error) {\n this.available = undefined;\n this.checkError = error instanceof Error ? error.message : '\u65E0\u6CD5\u68C0\u67E5\u66F4\u65B0';\n }\n this.checkedAt = Date.now();\n return this.status();\n }\n async configure(input: UpdateSettings) {\n if (!this.context || this.reason) throw new AppError('UPDATE_UNSUPPORTED', this.reason, 409);\n this.settings = settingsSchema.parse(input);\n await saveJson(join(this.context.directory, 'settings.json'), this.settings);\n return this.status();\n }\n async activationPending() {\n const run = (await this.status()).run;\n if (run && !run.committed && run.phase === 'failed' && run.from !== packageInfo.version)\n throw new Error(\n '\u4E0A\u6B21\u5347\u7EA7\u5C1A\u672A\u5B8C\u6210\u6062\u590D\uFF1B\u8BF7\u8FD0\u884C covro update repair \u540E\u518D\u542F\u52A8\uFF0C\u907F\u514D\u5199\u5165\u672A\u6FC0\u6D3B\u7248\u672C\u3002',\n );\n if (run && !run.committed && run.phase === 'stopping')\n throw new Error('\u5347\u7EA7\u6B63\u5728\u5207\u6362\u5B89\u88C5\uFF0C\u8BF7\u7B49\u5F85\u5347\u7EA7\u5B8C\u6210\uFF1B\u4E0D\u8981\u5E76\u884C\u542F\u52A8\u670D\u52A1\u3002');\n if (run && !run.committed && run.phase === 'verifying') {\n if (run.target !== packageInfo.version)\n throw new Error('\u5347\u7EA7\u5019\u9009\u8EAB\u4EFD\u4E0D\u5339\u914D\uFF0C\u8BF7\u8FD0\u884C covro update repair');\n return true;\n }\n return false;\n }\n async commitActivation(id: string) {\n if (!this.context) throw new Error('\u5F53\u524D\u4E0D\u662F\u53D7\u7BA1\u5B89\u88C5');\n const run = (await this.status()).run;\n if (!run || run.id !== id || run.phase !== 'verifying' || run.target !== packageInfo.version)\n throw new Error('\u5347\u7EA7\u8BB0\u5F55\u3001\u7248\u672C\u6216\u8FD0\u884C\u72B6\u6001\u4E0D\u5339\u914D');\n if (!run.codex || run.codex.version !== this.codexVersion())\n throw new Error('Codex \u7248\u672C\u5728\u5347\u7EA7\u671F\u95F4\u53D1\u751F\u53D8\u5316\u6216\u7F3A\u5C11\u6821\u9A8C\u8BB0\u5F55\uFF0C\u62D2\u7EDD\u6FC0\u6D3B');\n requireCodexCompatibility(\n CODEX_COMPATIBILITY,\n this.codexVersion(),\n run.codex.confirmedUnverified,\n );\n this.settings = { ...this.settings, channel: run.channel };\n await saveJson(join(this.context.directory, 'settings.json'), this.settings);\n await saveJson(join(this.context.directory, 'run.json'), {\n ...run,\n committed: true,\n phase: 'succeeded',\n message: '\u5347\u7EA7\u6210\u529F\uFF0C\u670D\u52A1\u5DF2\u6062\u590D',\n updatedAt: Date.now(),\n });\n }\n async start(input: z.infer<typeof updateRequestSchema>) {\n const request = updateRequestSchema.parse(input);\n if (!this.context || this.reason) throw new AppError('UPDATE_UNSUPPORTED', this.reason, 409);\n await mkdir(this.context.directory, { recursive: true, mode: 0o700 });\n let releaseLock: () => Promise<void>;\n try {\n releaseLock = await lockfile.lock(this.context.directory, {\n retries: 0,\n stale: 10_000,\n update: 2_000,\n });\n } catch {\n return this.status();\n }\n try {\n const before = await this.status();\n if (\n await readJson(\n join(this.context.directory, 'requests', `${request.clientOperationId}.json`),\n )\n )\n return before;\n if (before.run?.id === request.clientOperationId) return before;\n if (updateActive(before.run)) {\n if (Date.now() - before.run!.updatedAt > 120_000)\n throw new AppError(\n 'UPDATE_INTERRUPTED',\n '\u4E0A\u6B21\u5347\u7EA7\u8FDB\u7A0B\u5DF2\u5931\u8054\u3002\u8BF7\u4F7F\u7528 covro update repair \u6062\u590D\uFF0C\u4FDD\u7559\u5F53\u524D\u5B89\u88C5\u548C\u5907\u4EFD\u3002',\n 409,\n );\n return before;\n }\n const channel = request.channel ?? this.settings.channel;\n const checked = await this.check(channel);\n if (!checked.available)\n throw new AppError('UPDATE_CHECK_FAILED', checked.checkError ?? '\u672A\u627E\u5230\u53EF\u7528\u7248\u672C', 502);\n if (checked.available.downgrade && !request.allowDowngrade)\n throw new AppError(\n 'UPDATE_DOWNGRADE',\n '\u76EE\u6807\u7248\u672C\u8F83\u65E7\uFF0C\u9700\u8981\u660E\u786E\u5141\u8BB8\u964D\u7EA7\uFF1B\u4ECD\u5C06\u68C0\u67E5\u6570\u636E\u5E93\u517C\u5BB9\u6027\u3002',\n 409,\n );\n if (compareVersions(checked.available.version, packageInfo.version) === 0) {\n return this.configure({ ...this.settings, channel });\n }\n const confirmation = request.codexConfirmation;\n const codex = checked.available.codex;\n const confirmedUnverified = Boolean(\n confirmation &&\n confirmation.target === checked.available.version &&\n confirmation.version === codex.version,\n );\n if (confirmation && !confirmedUnverified)\n throw new AppError(\n 'UPDATE_CODEX_CHANGED',\n '\u76EE\u6807\u7248\u672C\u6216 Codex \u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u5E76\u786E\u8BA4\u3002',\n 409,\n );\n try {\n requireCodexCompatibility(codex.manifest, codex.version, confirmedUnverified);\n } catch (error) {\n throw new AppError('UPDATE_CODEX_INCOMPATIBLE', (error as Error).message, 409);\n }\n const run: UpdateRun = {\n id: request.clientOperationId,\n from: packageInfo.version,\n target: checked.available.version,\n channel,\n sourceChannel: checked.available.channel,\n commit: checked.available.commit,\n codex: { version: codex.version!, manifest: codex.manifest!, confirmedUnverified },\n phase: 'installing',\n message: '\u6B63\u5728\u5B89\u88C5\u5019\u9009 npm \u5305',\n startedAt: Date.now(),\n updatedAt: Date.now(),\n };\n await saveJson(join(this.context.directory, 'context.json'), this.context);\n const worker = join(this.context.directory, 'worker.cjs');\n await copyFile(join(packageRoot, 'dist/update-worker.cjs'), worker);\n const log = await open(join(this.context.directory, 'update.log'), 'a', 0o600);\n try {\n await saveJson(join(this.context.directory, 'run.json'), run);\n await saveJson(\n join(this.context.directory, 'requests', `${request.clientOperationId}.json`),\n { target: run.target, channel: run.channel },\n );\n const child = spawn(process.execPath, [worker, this.context.directory], {\n detached: true,\n stdio: ['ignore', log.fd, log.fd],\n windowsHide: true,\n });\n await new Promise<void>((done, reject) => {\n child.once('spawn', done);\n child.once('error', reject);\n });\n child.unref();\n } catch (error) {\n await saveJson(join(this.context.directory, 'run.json'), {\n ...run,\n phase: 'failed',\n message: String(error),\n updatedAt: Date.now(),\n });\n throw error;\n } finally {\n await log.close();\n }\n return this.status();\n } finally {\n await releaseLock();\n }\n }\n async repair() {\n if (!this.context) throw new Error('\u6CA1\u6709\u53EF\u6062\u590D\u7684\u53D7\u7BA1\u5B89\u88C5');\n const directory = this.context.directory;\n let releaseLock: () => Promise<void>;\n try {\n releaseLock = await lockfile.lock(directory, { retries: 0, stale: 10_000, update: 2_000 });\n } catch {\n throw new Error('\u5347\u7EA7\u8FDB\u7A0B\u4ECD\u6301\u6709\u9501\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210\u540E\u518D\u6062\u590D');\n }\n try {\n const run = (await this.status()).run;\n if (!run) throw new Error('\u6CA1\u6709\u53EF\u6062\u590D\u7684\u5347\u7EA7\u8BB0\u5F55');\n if (run.committed || run.phase === 'succeeded') return this.status();\n if (updateActive(run) && Date.now() - run.updatedAt < 30_000)\n throw new Error('\u5347\u7EA7\u521A\u5F00\u59CB\uFF0C\u8BF7\u7B49\u5F85\u81F3\u5C11 30 \u79D2\u540E\u518D\u6062\u590D\u5931\u8054\u8FDB\u7A0B');\n const log = await open(join(directory, 'update.log'), 'a', 0o600);\n try {\n const child = spawn(\n process.execPath,\n [join(directory, 'worker.cjs'), directory, '--repair'],\n {\n detached: true,\n stdio: ['ignore', log.fd, log.fd],\n windowsHide: true,\n },\n );\n await new Promise<void>((done, reject) => {\n child.once('spawn', done);\n child.once('error', reject);\n });\n child.unref();\n } finally {\n await log.close();\n }\n return this.status();\n } finally {\n await releaseLock();\n }\n }\n private async automatic() {\n if (!this.context || this.reason || this.checking) return;\n this.checking = (async () => {\n const result = await this.check();\n if (\n this.settings.automatic &&\n result.available &&\n result.available.codex.status === 'verified' &&\n !result.available.downgrade &&\n compareVersions(result.available.version, packageInfo.version) > 0 &&\n result.run?.target !== result.available.version &&\n !updateActive(result.run)\n )\n return this.start({ clientOperationId: crypto.randomUUID() });\n return result;\n })();\n try {\n await this.checking;\n } finally {\n this.checking = undefined;\n }\n }\n close() {\n this.network.abort();\n clearInterval(this.timer);\n }\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,2BAA2B;AACpC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAC3B,SAAS,aAAa;AACtB,SAAS,UAAU,OAAO,YAAY;AACtC,SAAS,
|
|
4
|
+
"sourcesContent": ["import { CODEX_COMPATIBILITY } from '../codex/compatibility.js';\nimport {\n assessCodexCompatibility,\n requireCodexCompatibility,\n} from '../shared/codex-compatibility.js';\nimport { createHash } from 'node:crypto';\nimport { spawn } from 'node:child_process';\nimport { copyFile, mkdir, open } from 'node:fs/promises';\nimport { join, resolve, sep } from 'node:path';\nimport lockfile from 'proper-lockfile';\nimport { z } from 'zod';\nimport { AppError } from '../shared/errors.js';\nimport {\n releaseChannels,\n updateActive,\n type UpdateController,\n type UpdateSettings,\n type UpdateRun,\n type UpdateStatus,\n type ReleaseChannel,\n} from '../shared/updates.js';\nimport { packageInfo, packageRoot, type CovroPaths } from '../cli/paths.js';\nimport { readJson, saveJson } from './files.js';\nimport { compareVersions, inspectInstallation, lookupRelease } from './registry.js';\nimport {\n assertRuntime,\n resolveRuntimeTarget,\n runtimeChanged as changedRuntime,\n type RuntimeTarget,\n} from './runtime.js';\nimport { runningRuntime } from '../cli/runtime.js';\nimport { launchRuntime, type LaunchRuntime } from '../cli/runtime-launch.js';\nconst runtimeChanged = (target: Parameters<typeof changedRuntime>[0]) =>\n changedRuntime(target, runningRuntime());\n\nexport const settingsSchema = z\n .object({ channel: z.enum(releaseChannels), automatic: z.boolean() })\n .strict();\nexport const updateRequestSchema = z\n .object({\n clientOperationId: z.uuid(),\n channel: z.enum(releaseChannels).optional(),\n allowDowngrade: z.boolean().optional(),\n codexConfirmation: z\n .object({ version: z.string().max(128), target: z.string().max(128) })\n .strict()\n .optional(),\n })\n .strict();\nexport interface UpdateContext {\n location: CovroPaths;\n dataDir: string;\n root: string;\n directory: string;\n target?: RuntimeTarget;\n reuseTarget?: boolean;\n source?: LaunchRuntime;\n}\nexport class UpdateManager implements UpdateController {\n private settings: UpdateSettings = {\n channel:\n packageInfo.covroChannel ??\n (packageInfo.version?.includes('-dev.')\n ? 'dev'\n : packageInfo.version?.includes('-beta.')\n ? 'beta'\n : 'stable'),\n automatic: false,\n };\n private available?: UpdateStatus['available'];\n private checkedAt?: number;\n private checkError?: string;\n private target?: RuntimeTarget;\n private runtimeError?: string;\n private reason = '\u5F53\u524D\u670D\u52A1\u672A\u901A\u8FC7 covro \u542F\u52A8\uFF0C\u7F51\u9875\u4EC5\u652F\u6301\u7248\u672C\u68C0\u6D4B\uFF1B\u5347\u7EA7\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u3002';\n private timer?: ReturnType<typeof setInterval>;\n private checking?: Promise<UpdateStatus>;\n private readonly network = new AbortController();\n readonly context?: UpdateContext;\n constructor(\n location?: CovroPaths,\n dataDir?: string,\n private readonly codexVersion: () => string | null = () => null,\n ) {\n if (location && dataDir)\n this.context = {\n location,\n dataDir,\n root: packageRoot,\n directory: join(\n location.home,\n 'updates',\n createHash('sha256').update(packageRoot).digest('hex').slice(0, 16),\n ),\n };\n }\n async initialize() {\n if (!this.context) return;\n await this.loadDirectory();\n const saved = await readJson<unknown>(join(this.context.directory, 'settings.json'));\n if (saved !== undefined) this.settings = settingsSchema.parse(saved);\n this.reason =\n process.platform === 'win32'\n ? 'Windows \u6682\u4E0D\u652F\u6301\u53D7\u7BA1\u81EA\u52A8\u5347\u7EA7\uFF0C\u8BF7\u4F7F\u7528 npm \u66F4\u65B0\u5E76\u91CD\u542F\u3002'\n : ((await inspectInstallation(this.context.root)) ?? '');\n this.timer = setInterval(() => void this.automatic().catch(() => {}), 30 * 60_000);\n this.timer.unref();\n // No network request in the startup critical path.\n void this.automatic().catch(() => {});\n }\n private async loadDirectory() {\n if (!this.context) return;\n const saved = await readJson<{ directory: string }>(\n join(this.context.location.state, 'updates.json'),\n );\n if (saved) {\n const directory = resolve(saved.directory);\n if (!directory.startsWith(resolve(this.context.location.home, 'updates') + sep))\n throw new Error('\u5347\u7EA7\u8BB0\u5F55\u76EE\u5F55\u4E0D\u5728 Covro \u7BA1\u7406\u76EE\u5F55\u4E2D');\n this.context.directory = directory;\n }\n }\n async status(): Promise<UpdateStatus> {\n const run = this.context\n ? await readJson<UpdateRun>(join(this.context.directory, 'run.json'))\n : undefined;\n return {\n version: packageInfo.version ?? 'unknown',\n commit: packageInfo.covroCommit,\n source: 'npm',\n codex: assessCodexCompatibility(CODEX_COMPATIBILITY, this.codexVersion()),\n settings: this.settings,\n supported: !this.reason,\n unsupportedReason: this.reason || undefined,\n available: this.available\n ? {\n ...this.available,\n codex: assessCodexCompatibility(this.available.codex.manifest, this.codexVersion()),\n }\n : undefined,\n checkedAt: this.checkedAt,\n checkError: this.checkError,\n run,\n runtime: {\n current: runningRuntime(),\n target: this.target,\n migration: Boolean(this.target && runtimeChanged(this.target)),\n error: this.runtimeError,\n },\n };\n }\n async check(channel: ReleaseChannel = this.settings.channel) {\n this.target = undefined;\n this.runtimeError = undefined;\n if (this.context && !this.reason) {\n try {\n this.target = await resolveRuntimeTarget();\n } catch (error) {\n this.runtimeError = (error as Error).message;\n }\n }\n try {\n const local = this.target && runtimeChanged(this.target) ? this.target : undefined;\n let release;\n try {\n release = await lookupRelease(channel, this.network.signal);\n } catch (error) {\n if (!local) throw error;\n }\n // A preinstalled newer target must never be overwritten by an older channel tag.\n if (local && (!release || compareVersions(local.version, release.version) >= 0))\n release = {\n version: local.version,\n channel: (local.version.includes('-dev.')\n ? 'dev'\n : local.version.includes('-beta.')\n ? 'beta'\n : 'stable') as ReleaseChannel,\n covroCommit: local.covroCommit,\n gitHead: undefined,\n covroCodex: local.covroCodex,\n };\n if (!release) throw new Error('\u672A\u627E\u5230\u53EF\u7528\u7248\u672C');\n this.available = {\n version: release.version,\n requestedChannel: channel,\n channel: release.channel,\n commit: release.covroCommit ?? release.gitHead,\n downgrade: compareVersions(release.version, packageInfo.version) < 0,\n codex: assessCodexCompatibility(release.covroCodex, this.codexVersion()),\n };\n this.checkError = undefined;\n } catch (error) {\n this.available = undefined;\n this.checkError = error instanceof Error ? error.message : '\u65E0\u6CD5\u68C0\u67E5\u66F4\u65B0';\n }\n this.checkedAt = Date.now();\n return this.status();\n }\n async configure(input: UpdateSettings) {\n if (!this.context || this.reason) throw new AppError('UPDATE_UNSUPPORTED', this.reason, 409);\n this.settings = settingsSchema.parse(input);\n await saveJson(join(this.context.directory, 'settings.json'), this.settings);\n return this.status();\n }\n async activationPending() {\n const run = (await this.status()).run;\n if (\n run &&\n !run.committed &&\n ['failed', 'rolledBack'].includes(run.phase) &&\n (run.from !== packageInfo.version || (run.runtime && runtimeChanged(run.runtime.from)))\n )\n throw new Error(\n '\u4E0A\u6B21\u5347\u7EA7\u5C1A\u672A\u5B8C\u6210\u6062\u590D\uFF1B\u8BF7\u8FD0\u884C covro update repair \u540E\u518D\u542F\u52A8\uFF0C\u907F\u514D\u5199\u5165\u672A\u6FC0\u6D3B\u7248\u672C\u3002',\n );\n if (run && !run.committed && run.phase === 'stopping')\n throw new Error('\u5347\u7EA7\u6B63\u5728\u5207\u6362\u5B89\u88C5\uFF0C\u8BF7\u7B49\u5F85\u5347\u7EA7\u5B8C\u6210\uFF1B\u4E0D\u8981\u5E76\u884C\u542F\u52A8\u670D\u52A1\u3002');\n if (run && !run.committed && run.phase === 'verifying') {\n if (run.target !== packageInfo.version)\n throw new Error('\u5347\u7EA7\u5019\u9009\u8EAB\u4EFD\u4E0D\u5339\u914D\uFF0C\u8BF7\u8FD0\u884C covro update repair');\n if (run.runtime) assertRuntime(runningRuntime(), run.runtime.target);\n return true;\n }\n return false;\n }\n async commitActivation(id: string) {\n if (!this.context) throw new Error('\u5F53\u524D\u4E0D\u662F\u53D7\u7BA1\u5B89\u88C5');\n const run = (await this.status()).run;\n if (!run || run.id !== id || run.phase !== 'verifying' || run.target !== packageInfo.version)\n throw new Error('\u5347\u7EA7\u8BB0\u5F55\u3001\u7248\u672C\u6216\u8FD0\u884C\u72B6\u6001\u4E0D\u5339\u914D');\n if (run.runtime) assertRuntime(runningRuntime(), run.runtime.target);\n if (!run.codex || run.codex.version !== this.codexVersion())\n throw new Error('Codex \u7248\u672C\u5728\u5347\u7EA7\u671F\u95F4\u53D1\u751F\u53D8\u5316\u6216\u7F3A\u5C11\u6821\u9A8C\u8BB0\u5F55\uFF0C\u62D2\u7EDD\u6FC0\u6D3B');\n requireCodexCompatibility(\n CODEX_COMPATIBILITY,\n this.codexVersion(),\n run.codex.confirmedUnverified,\n );\n this.settings = { ...this.settings, channel: run.channel };\n await saveJson(join(this.context.directory, 'settings.json'), this.settings);\n await saveJson(join(this.context.directory, 'run.json'), {\n ...run,\n committed: true,\n phase: 'succeeded',\n message: '\u5347\u7EA7\u6210\u529F\uFF0C\u670D\u52A1\u5DF2\u6062\u590D',\n updatedAt: Date.now(),\n runtime: run.runtime ? { ...run.runtime, actual: runningRuntime() } : undefined,\n });\n }\n async start(input: z.infer<typeof updateRequestSchema>) {\n const request = updateRequestSchema.parse(input);\n if (!this.context || this.reason) throw new AppError('UPDATE_UNSUPPORTED', this.reason, 409);\n await mkdir(this.context.directory, { recursive: true, mode: 0o700 });\n let releaseLock: () => Promise<void>;\n try {\n releaseLock = await lockfile.lock(this.context.directory, {\n retries: 0,\n stale: 10_000,\n update: 2_000,\n });\n } catch {\n return this.status();\n }\n try {\n const before = await this.status();\n if (\n await readJson(\n join(this.context.directory, 'requests', `${request.clientOperationId}.json`),\n )\n )\n return before;\n if (before.run?.id === request.clientOperationId) return before;\n if (updateActive(before.run)) {\n if (Date.now() - before.run!.updatedAt > 120_000)\n throw new AppError(\n 'UPDATE_INTERRUPTED',\n '\u4E0A\u6B21\u5347\u7EA7\u8FDB\u7A0B\u5DF2\u5931\u8054\u3002\u8BF7\u4F7F\u7528 covro update repair \u6062\u590D\uFF0C\u4FDD\u7559\u5F53\u524D\u5B89\u88C5\u548C\u5907\u4EFD\u3002',\n 409,\n );\n return before;\n }\n const channel = request.channel ?? this.settings.channel;\n const checked = await this.check(channel);\n const target = this.target;\n if (this.runtimeError || !target)\n throw new AppError(\n 'UPDATE_RUNTIME',\n this.runtimeError ?? '\u65E0\u6CD5\u786E\u8BA4\u76EE\u6807 Node \u73AF\u5883\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u3002',\n 409,\n );\n if (!checked.available)\n throw new AppError('UPDATE_CHECK_FAILED', checked.checkError ?? '\u672A\u627E\u5230\u53EF\u7528\u7248\u672C', 502);\n if (checked.available.downgrade && !request.allowDowngrade)\n throw new AppError(\n 'UPDATE_DOWNGRADE',\n '\u76EE\u6807\u7248\u672C\u8F83\u65E7\uFF0C\u9700\u8981\u660E\u786E\u5141\u8BB8\u964D\u7EA7\uFF1B\u4ECD\u5C06\u68C0\u67E5\u6570\u636E\u5E93\u517C\u5BB9\u6027\u3002',\n 409,\n );\n if (\n compareVersions(checked.available.version, packageInfo.version) === 0 &&\n !runtimeChanged(target)\n ) {\n return this.configure({ ...this.settings, channel });\n }\n const confirmation = request.codexConfirmation;\n const codex = checked.available.codex;\n const confirmedUnverified = Boolean(\n confirmation &&\n confirmation.target === checked.available.version &&\n confirmation.version === codex.version,\n );\n if (confirmation && !confirmedUnverified)\n throw new AppError(\n 'UPDATE_CODEX_CHANGED',\n '\u76EE\u6807\u7248\u672C\u6216 Codex \u5DF2\u53D8\u5316\uFF0C\u8BF7\u91CD\u65B0\u68C0\u67E5\u5E76\u786E\u8BA4\u3002',\n 409,\n );\n try {\n requireCodexCompatibility(codex.manifest, codex.version, confirmedUnverified);\n } catch (error) {\n throw new AppError('UPDATE_CODEX_INCOMPATIBLE', (error as Error).message, 409);\n }\n const run: UpdateRun = {\n id: request.clientOperationId,\n from: packageInfo.version,\n target: checked.available.version,\n channel,\n sourceChannel: checked.available.channel,\n commit: checked.available.commit,\n codex: { version: codex.version!, manifest: codex.manifest!, confirmedUnverified },\n phase: 'installing',\n message: '\u6B63\u5728\u5B89\u88C5\u5019\u9009 npm \u5305',\n startedAt: Date.now(),\n updatedAt: Date.now(),\n runtime: { from: runningRuntime(), target: target },\n };\n const currentLaunch = await launchRuntime(this.context.location, runningRuntime().entry);\n if (currentLaunch.node !== process.execPath || currentLaunch.entry !== runningRuntime().entry)\n throw new AppError(\n 'UPDATE_RUNTIME',\n '\u4FDD\u5B58\u7684\u542F\u52A8\u6765\u6E90\u4E0E\u5F53\u524D\u5B9E\u4F8B\u4E0D\u4E00\u81F4\uFF0C\u8BF7\u6838\u5BF9\u5B9E\u4F8B\u540E\u91CD\u8BD5\u3002',\n 409,\n );\n const context = {\n ...this.context,\n source: currentLaunch,\n target: target,\n reuseTarget:\n runtimeChanged(target) &&\n target.root !== this.context.root.replace(/\\/$/, '') &&\n target.version === run.target,\n };\n await saveJson(join(this.context.directory, 'context.json'), context);\n await saveJson(join(this.context.location.state, 'updates.json'), {\n directory: this.context.directory,\n });\n const worker = join(this.context.directory, 'worker.cjs');\n await copyFile(join(packageRoot, 'dist/update-worker.cjs'), worker);\n const log = await open(join(this.context.directory, 'update.log'), 'a', 0o600);\n try {\n await saveJson(join(this.context.directory, 'run.json'), run);\n await saveJson(\n join(this.context.directory, 'requests', `${request.clientOperationId}.json`),\n { target: run.target, channel: run.channel },\n );\n const child = spawn(process.execPath, [worker, this.context.directory], {\n detached: true,\n stdio: ['ignore', log.fd, log.fd],\n windowsHide: true,\n });\n await new Promise<void>((done, reject) => {\n child.once('spawn', done);\n child.once('error', reject);\n });\n child.unref();\n } catch (error) {\n await saveJson(join(this.context.directory, 'run.json'), {\n ...run,\n phase: 'failed',\n message: String(error),\n updatedAt: Date.now(),\n });\n throw error;\n } finally {\n await log.close();\n }\n return this.status();\n } finally {\n await releaseLock();\n }\n }\n async repair() {\n if (!this.context) throw new Error('\u6CA1\u6709\u53EF\u6062\u590D\u7684\u53D7\u7BA1\u5B89\u88C5');\n await this.loadDirectory();\n const directory = this.context.directory;\n let releaseLock: () => Promise<void>;\n try {\n releaseLock = await lockfile.lock(directory, { retries: 0, stale: 10_000, update: 2_000 });\n } catch {\n throw new Error('\u5347\u7EA7\u8FDB\u7A0B\u4ECD\u6301\u6709\u9501\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210\u540E\u518D\u6062\u590D');\n }\n try {\n const run = (await this.status()).run;\n if (!run) throw new Error('\u6CA1\u6709\u53EF\u6062\u590D\u7684\u5347\u7EA7\u8BB0\u5F55');\n if (run.committed || run.phase === 'succeeded') return this.status();\n if (updateActive(run) && Date.now() - run.updatedAt < 30_000)\n throw new Error('\u5347\u7EA7\u521A\u5F00\u59CB\uFF0C\u8BF7\u7B49\u5F85\u81F3\u5C11 30 \u79D2\u540E\u518D\u6062\u590D\u5931\u8054\u8FDB\u7A0B');\n const log = await open(join(directory, 'update.log'), 'a', 0o600);\n try {\n const child = spawn(\n process.execPath,\n [join(directory, 'worker.cjs'), directory, '--repair'],\n {\n detached: true,\n stdio: ['ignore', log.fd, log.fd],\n windowsHide: true,\n },\n );\n await new Promise<void>((done, reject) => {\n child.once('spawn', done);\n child.once('error', reject);\n });\n child.unref();\n } finally {\n await log.close();\n }\n return this.status();\n } finally {\n await releaseLock();\n }\n }\n private async automatic() {\n if (!this.context || this.reason || this.checking) return;\n this.checking = (async () => {\n const result = await this.check();\n if (\n this.settings.automatic &&\n result.available &&\n result.available.codex.status === 'verified' &&\n !result.available.downgrade &&\n compareVersions(result.available.version, packageInfo.version) > 0 &&\n result.run?.target !== result.available.version &&\n !updateActive(result.run)\n )\n return this.start({ clientOperationId: crypto.randomUUID() });\n return result;\n })();\n try {\n await this.checking;\n } finally {\n this.checking = undefined;\n }\n }\n close() {\n this.network.abort();\n clearInterval(this.timer);\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/updates/registry.js
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import { npmPackageName } from "../shared/package.js";
|
|
2
2
|
import { validVersion, compareVersions } from "../shared/versions.js";
|
|
3
3
|
import { validVersion as validVersion2, compareVersions as compareVersions2 } from "../shared/versions.js";
|
|
4
|
-
import { execFile } from "node:child_process";
|
|
5
|
-
import { promisify } from "node:util";
|
|
6
4
|
import { realpath, access, lstat } from "node:fs/promises";
|
|
7
5
|
import { constants } from "node:fs";
|
|
8
|
-
import { join } from "node:path";
|
|
6
|
+
import { dirname, join, resolve } from "node:path";
|
|
9
7
|
import { z } from "zod";
|
|
10
|
-
const run = promisify(execFile);
|
|
11
8
|
const registry = "https://registry.npmjs.org";
|
|
12
9
|
const npmTags = {
|
|
13
10
|
stable: "latest",
|
|
@@ -51,8 +48,12 @@ async function lookupRelease(channel, signal) {
|
|
|
51
48
|
}
|
|
52
49
|
async function inspectInstallation(root) {
|
|
53
50
|
try {
|
|
54
|
-
const
|
|
55
|
-
|
|
51
|
+
const globalRoot = dirname(dirname(resolve(root)));
|
|
52
|
+
if (!globalRoot.endsWith("/lib/node_modules"))
|
|
53
|
+
return "\u5F53\u524D\u4E3A\u975E npm \u5168\u5C40\u5B89\u88C5\uFF1B\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u66F4\u65B0\u3002";
|
|
54
|
+
if (await realpath(join(dirname(dirname(globalRoot)), "bin/covro")) !== join(resolve(root), "bin/covro.mjs"))
|
|
55
|
+
return "\u5F53\u524D Covro \u5165\u53E3\u4E0E npm \u5168\u5C40\u5B89\u88C5\u6765\u6E90\u4E0D\u5339\u914D\uFF1B\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u66F4\u65B0\u3002";
|
|
56
|
+
return await inspectPackageDirectory(root, globalRoot);
|
|
56
57
|
} catch {
|
|
57
58
|
return "\u65E0\u6CD5\u786E\u8BA4\u53EF\u5199\u7684 npm \u5168\u5C40\u5B89\u88C5\uFF1B\u8BF7\u68C0\u67E5 npm\u3001\u5B89\u88C5\u76EE\u5F55\u6743\u9650\u53CA\u540E\u53F0 PATH\u3002";
|
|
58
59
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/updates/registry.ts"],
|
|
4
|
-
"sourcesContent": ["import { npmPackageName } from '../shared/package.js';\nimport { validVersion, compareVersions } from '../shared/versions.js';\nexport { validVersion, compareVersions } from '../shared/versions.js';\nimport {
|
|
5
|
-
"mappings": "AAAA,SAAS,sBAAsB;AAC/B,SAAS,cAAc,uBAAuB;AAC9C,SAAS,gBAAAA,eAAc,mBAAAC,wBAAuB;AAC9C,SAAS,
|
|
4
|
+
"sourcesContent": ["import { npmPackageName } from '../shared/package.js';\nimport { validVersion, compareVersions } from '../shared/versions.js';\nexport { validVersion, compareVersions } from '../shared/versions.js';\nimport { realpath, access, lstat } from 'node:fs/promises';\nimport { constants } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { z } from 'zod';\nimport type { ReleaseChannel } from '../shared/updates.js';\n\nexport const registry = 'https://registry.npmjs.org';\nexport const npmTags: Record<ReleaseChannel, string> = {\n stable: 'latest',\n beta: 'beta',\n dev: 'dev',\n};\nexport const releaseSchema = z.object({\n name: z.literal(npmPackageName),\n version: z.string().refine(validVersion),\n gitHead: z.string().optional(),\n covroCommit: z.string().optional(),\n covroCodex: z.unknown().optional(),\n});\nexport function packageMetadataUrl(selector?: string) {\n const url = `${registry}/${encodeURIComponent(npmPackageName)}`;\n return selector === undefined ? url : `${url}/${encodeURIComponent(selector)}`;\n}\nasync function lookupTag(channel: ReleaseChannel, signal?: AbortSignal) {\n const response = await fetch(packageMetadataUrl(npmTags[channel]), {\n signal: signal\n ? AbortSignal.any([signal, AbortSignal.timeout(15_000)])\n : AbortSignal.timeout(15_000),\n headers: { accept: 'application/json' },\n });\n if (response.status === 404) return undefined;\n if (!response.ok) throw new Error(`npm ${npmTags[channel]} \u67E5\u8BE2\u5931\u8D25\uFF08${response.status}\uFF09`);\n const body = await response.text();\n if (body.length > 2 * 1024 * 1024) throw new Error('npm \u5143\u6570\u636E\u8FC7\u5927');\n return { ...releaseSchema.parse(JSON.parse(body)), channel };\n}\nexport async function lookupRelease(channel: ReleaseChannel, signal?: AbortSignal) {\n // Resolve every allowed source once, then bind the chosen version and its metadata.\n // Stable wins equal precedence; a newer prerelease still wins over an older stable.\n const sources: ReleaseChannel[] = channel === 'stable' ? ['stable'] : ['stable', channel];\n const releases = await Promise.all(sources.map((source) => lookupTag(source, signal)));\n let selected: Awaited<ReturnType<typeof lookupTag>>;\n for (const release of releases)\n if (release && (!selected || compareVersions(release.version, selected.version) > 0))\n selected = release;\n if (!selected)\n throw new Error(\n `npm \u5C1A\u672A\u53D1\u5E03 Covro \u7684\u53EF\u7528\u7248\u672C\uFF08${sources.map((source) => npmTags[source]).join('\u3001')}\uFF09`,\n );\n return selected;\n}\nexport async function inspectInstallation(root: string): Promise<string | undefined> {\n try {\n const globalRoot = dirname(dirname(resolve(root)));\n if (!globalRoot.endsWith('/lib/node_modules'))\n return '\u5F53\u524D\u4E3A\u975E npm \u5168\u5C40\u5B89\u88C5\uFF1B\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u66F4\u65B0\u3002';\n if (\n (await realpath(join(dirname(dirname(globalRoot)), 'bin/covro'))) !==\n join(resolve(root), 'bin/covro.mjs')\n )\n return '\u5F53\u524D Covro \u5165\u53E3\u4E0E npm \u5168\u5C40\u5B89\u88C5\u6765\u6E90\u4E0D\u5339\u914D\uFF1B\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u66F4\u65B0\u3002';\n return await inspectPackageDirectory(root, globalRoot);\n } catch {\n return '\u65E0\u6CD5\u786E\u8BA4\u53EF\u5199\u7684 npm \u5168\u5C40\u5B89\u88C5\uFF1B\u8BF7\u68C0\u67E5 npm\u3001\u5B89\u88C5\u76EE\u5F55\u6743\u9650\u53CA\u540E\u53F0 PATH\u3002';\n }\n}\n\nexport async function inspectPackageDirectory(root: string, globalRoot: string) {\n const expected = join(await realpath(globalRoot), npmPackageName);\n // npm link and pnpm global point outside the package directory. Following\n // that link would let the worker rename a developer's source checkout.\n if ((await lstat(expected)).isSymbolicLink() || (await realpath(root)) !== expected)\n return '\u5F53\u524D\u4E3A\u6E90\u7801\u3001\u94FE\u63A5\u6216\u975E npm \u5168\u5C40\u5B89\u88C5\uFF1B\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u66F4\u65B0\u3002';\n try {\n await lstat(join(expected, '.git'));\n return '\u5F53\u524D\u5B89\u88C5\u5305\u542B Git \u5DE5\u4F5C\u533A\uFF1B\u8BF7\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u66F4\u65B0\u3002';\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n await access(root, constants.W_OK);\n return undefined;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["validVersion", "compareVersions"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { homedir, userInfo } from "node:os";
|
|
4
|
+
import { access, lstat, readFile, realpath } from "node:fs/promises";
|
|
5
|
+
import { constants } from "node:fs";
|
|
6
|
+
import { basename, delimiter, dirname, isAbsolute, join } from "node:path";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { npmPackageName } from "../shared/package.js";
|
|
9
|
+
import { compareVersions, validVersion } from "../shared/versions.js";
|
|
10
|
+
import { inspectPackageDirectory } from "./registry.js";
|
|
11
|
+
const exec = promisify(execFile);
|
|
12
|
+
const runtimeChanged = (target, current) => target.node !== current.node || target.nodeVersion !== current.nodeVersion || target.root !== current.root;
|
|
13
|
+
function assertRuntime(actual, expected) {
|
|
14
|
+
if (!actual || actual.node !== expected.node || actual.nodeVersion !== expected.nodeVersion || actual.root !== expected.root || actual.entry !== expected.entry)
|
|
15
|
+
throw new Error(
|
|
16
|
+
"\u5B9E\u9645 Node \u6216 Covro \u5B89\u88C5\u6765\u6E90\u4E0E\u76EE\u6807\u4E0D\u5339\u914D\uFF1B\u62D2\u7EDD\u6FC0\u6D3B\uFF0C\u8BF7\u67E5\u770B\u5347\u7EA7\u65E5\u5FD7\u5E76\u8FD0\u884C covro update repair\u3002"
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
async function verifyRuntimeExecutable(runtime) {
|
|
20
|
+
const { stdout } = await exec(
|
|
21
|
+
runtime.node,
|
|
22
|
+
["-p", "JSON.stringify({node:process.execPath,nodeVersion:process.versions.node})"],
|
|
23
|
+
{ env: targetNpmEnvironment(process.env.PATH ?? "/usr/bin:/bin"), timeout: 15e3 }
|
|
24
|
+
);
|
|
25
|
+
const actual = JSON.parse(stdout);
|
|
26
|
+
if (actual.node !== runtime.node || actual.nodeVersion !== runtime.nodeVersion)
|
|
27
|
+
throw new Error(
|
|
28
|
+
"\u65E7 Node \u7684\u78C1\u76D8\u8DEF\u5F84\u5DF2\u88AB\u66FF\u6362\uFF0C\u65E0\u6CD5\u4FDD\u8BC1\u56DE\u6EDA\uFF1B\u8BF7\u4FDD\u7559\u65E7 Node \u5B89\u88C5\u5E76\u6838\u5BF9\u542F\u52A8\u6765\u6E90\u540E\u91CD\u8BD5\u3002"
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
const probeSchema = z.object({
|
|
32
|
+
node: z.string(),
|
|
33
|
+
nodeVersion: z.string(),
|
|
34
|
+
path: z.string(),
|
|
35
|
+
npmConfig: z.record(z.string(), z.string()).optional()
|
|
36
|
+
});
|
|
37
|
+
const marker = "COVRO_RUNTIME_281=";
|
|
38
|
+
const npmConfigKeys = ["prefix", "userconfig", "globalconfig"];
|
|
39
|
+
const probe = `process.stdout.write('${marker}'+JSON.stringify({node:process.execPath,nodeVersion:process.versions.node,path:process.env.PATH,npmConfig:Object.fromEntries(${JSON.stringify(npmConfigKeys)}.flatMap(k=>{const v=process.env['npm_config_'+k]??process.env['NPM_CONFIG_'+k.toUpperCase()];return v===undefined?[]:[[k,v]]}))})+'\\n')`;
|
|
40
|
+
function targetNpmEnvironment(path, config = {}) {
|
|
41
|
+
const env = { ...process.env, PATH: path, NODE_OPTIONS: "", NODE_PATH: "" };
|
|
42
|
+
for (const key of npmConfigKeys) {
|
|
43
|
+
delete env[`NPM_CONFIG_${key.toUpperCase()}`];
|
|
44
|
+
delete env[`npm_config_${key}`];
|
|
45
|
+
if (config[key]) env[`npm_config_${key}`] = config[key];
|
|
46
|
+
}
|
|
47
|
+
return env;
|
|
48
|
+
}
|
|
49
|
+
const quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
50
|
+
async function defaultNodeEnvironment() {
|
|
51
|
+
const shell = userInfo().shell;
|
|
52
|
+
if (!shell || !["bash", "zsh", "sh", "dash", "fish"].includes(basename(shell)))
|
|
53
|
+
throw new Error(
|
|
54
|
+
"\u65E0\u6CD5\u8BC6\u522B\u9ED8\u8BA4\u767B\u5F55 shell\uFF1B\u8BF7\u5728\u76EE\u6807 Node \u7684\u7EC8\u7AEF\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u66F4\u65B0\u5E76\u91CD\u65B0\u5B89\u88C5\u767B\u5F55\u670D\u52A1\u3002"
|
|
55
|
+
);
|
|
56
|
+
const oldBin = dirname(process.execPath);
|
|
57
|
+
const path = (process.env.PATH ?? "").split(delimiter).filter(
|
|
58
|
+
(part) => part && part !== oldBin && !/fnm_multishells|\/node-versions\/|\/\.nvm\/versions\/node\//.test(part)
|
|
59
|
+
);
|
|
60
|
+
const env = {
|
|
61
|
+
...process.env,
|
|
62
|
+
PATH: [.../* @__PURE__ */ new Set([...path, "/usr/local/bin", "/opt/homebrew/bin", "/usr/bin", "/bin"])].join(
|
|
63
|
+
delimiter
|
|
64
|
+
)
|
|
65
|
+
};
|
|
66
|
+
for (const key of ["FNM_MULTISHELL_PATH", "NVM_BIN", "NVM_INC", "NODE_OPTIONS", "NODE_PATH"])
|
|
67
|
+
delete env[key];
|
|
68
|
+
for (const key of npmConfigKeys) {
|
|
69
|
+
delete env[`npm_config_${key}`];
|
|
70
|
+
delete env[`NPM_CONFIG_${key.toUpperCase()}`];
|
|
71
|
+
}
|
|
72
|
+
const { stdout } = await exec(shell, ["-ilc", `node -e ${quote(probe)}`], {
|
|
73
|
+
cwd: homedir(),
|
|
74
|
+
env,
|
|
75
|
+
timeout: 15e3,
|
|
76
|
+
maxBuffer: 256 * 1024
|
|
77
|
+
});
|
|
78
|
+
const lines = stdout.split(/\r?\n/).filter((line) => line.startsWith(marker));
|
|
79
|
+
if (lines.length !== 1)
|
|
80
|
+
throw new Error("\u767B\u5F55 shell \u672A\u8FD4\u56DE\u552F\u4E00\u7684\u9ED8\u8BA4 Node\uFF1B\u8BF7\u68C0\u67E5 shell \u542F\u52A8\u914D\u7F6E\u540E\u91CD\u8BD5\u3002");
|
|
81
|
+
return probeSchema.parse(JSON.parse(lines[0].slice(marker.length)));
|
|
82
|
+
}
|
|
83
|
+
async function executable(name, path) {
|
|
84
|
+
for (const directory of path.split(delimiter)) {
|
|
85
|
+
if (!isAbsolute(directory)) continue;
|
|
86
|
+
const filename = join(directory, name);
|
|
87
|
+
try {
|
|
88
|
+
await access(filename, constants.X_OK);
|
|
89
|
+
return await realpath(filename);
|
|
90
|
+
} catch (error) {
|
|
91
|
+
if (!["ENOENT", "EACCES", "ENOTDIR"].includes(error.code ?? ""))
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
throw new Error(
|
|
96
|
+
`\u76EE\u6807 Node \u73AF\u5883\u4E2D\u627E\u4E0D\u5230 ${name}\uFF1B\u8BF7\u5728\u65B0\u7EC8\u7AEF\u68C0\u67E5 node\u3001npm \u548C npm install -g ${npmPackageName}\u3002`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
async function resolveRuntimeTarget(environment = defaultNodeEnvironment) {
|
|
100
|
+
const found = await environment();
|
|
101
|
+
const node = await realpath(found.node);
|
|
102
|
+
await access(node, constants.X_OK);
|
|
103
|
+
const { stdout } = await exec(node, ["-p", "process.versions.node"], {
|
|
104
|
+
env: targetNpmEnvironment(found.path, found.npmConfig),
|
|
105
|
+
timeout: 15e3
|
|
106
|
+
});
|
|
107
|
+
const nodeVersion = stdout.trim();
|
|
108
|
+
if (nodeVersion !== found.nodeVersion || !validVersion(nodeVersion) || compareVersions(nodeVersion, "24.19.0") < 0 || compareVersions(nodeVersion, "25.0.0") >= 0)
|
|
109
|
+
throw new Error(
|
|
110
|
+
`\u76EE\u6807 Node ${nodeVersion} \u4E0D\u53D7\u652F\u6301\uFF1B\u9700\u8981 >=24.19.0 <25\uFF0C\u8BF7\u8C03\u6574\u9ED8\u8BA4 Node \u540E\u91CD\u8BD5\u3002`
|
|
111
|
+
);
|
|
112
|
+
const npm = await executable("npm", found.path);
|
|
113
|
+
if (await realpath(join(dirname(node), "npm")).catch(() => void 0) !== npm)
|
|
114
|
+
throw new Error("\u9ED8\u8BA4 Node \u548C npm \u6765\u81EA\u4E0D\u540C\u5B89\u88C5\uFF1B\u8BF7\u4FEE\u590D\u767B\u5F55 shell \u7684 PATH \u540E\u91CD\u65B0\u68C0\u67E5\u3002");
|
|
115
|
+
const npmInfo = JSON.parse(await readFile(join(dirname(npm), "../package.json"), "utf8"));
|
|
116
|
+
if (basename(npm) !== "npm-cli.js" || npmInfo.name !== "npm")
|
|
117
|
+
throw new Error(
|
|
118
|
+
"\u76EE\u6807 npm \u662F\u65E0\u6CD5\u786E\u8BA4\u7684 shim\uFF1B\u8BF7\u8BA9\u767B\u5F55 shell \u7684 PATH \u6307\u5411\u76EE\u6807 Node \u81EA\u5E26\u7684 npm \u540E\u91CD\u8BD5\u3002"
|
|
119
|
+
);
|
|
120
|
+
const directories = await Promise.all(
|
|
121
|
+
found.path.split(delimiter).filter(isAbsolute).map((part) => realpath(part).catch(() => void 0))
|
|
122
|
+
);
|
|
123
|
+
const path = [
|
|
124
|
+
.../* @__PURE__ */ new Set([dirname(node), ...directories.filter((part) => Boolean(part))])
|
|
125
|
+
].join(delimiter);
|
|
126
|
+
const options = {
|
|
127
|
+
env: targetNpmEnvironment(path, found.npmConfig),
|
|
128
|
+
cwd: homedir(),
|
|
129
|
+
timeout: 15e3
|
|
130
|
+
};
|
|
131
|
+
const [prefixResult, rootResult, npmVersionResult] = await Promise.all([
|
|
132
|
+
exec(node, [npm, "prefix", "--global"], options),
|
|
133
|
+
exec(node, [npm, "root", "--global"], options),
|
|
134
|
+
exec(node, [npm, "--version"], options)
|
|
135
|
+
]);
|
|
136
|
+
const prefix = await realpath(prefixResult.stdout.trim());
|
|
137
|
+
const globalRoot = await realpath(rootResult.stdout.trim());
|
|
138
|
+
if (globalRoot !== join(prefix, "lib/node_modules"))
|
|
139
|
+
throw new Error("\u76EE\u6807 npm \u5168\u5C40\u76EE\u5F55\u5E03\u5C40\u4E0D\u53D7\u652F\u6301\u3002");
|
|
140
|
+
const root = join(globalRoot, npmPackageName);
|
|
141
|
+
const npmVersion = npmVersionResult.stdout.trim();
|
|
142
|
+
if (!validVersion(npmVersion))
|
|
143
|
+
throw new Error("\u76EE\u6807 npm \u672A\u8FD4\u56DE\u6709\u6548\u7248\u672C\uFF0C\u8BF7\u68C0\u67E5 npm \u5B89\u88C5\u540E\u91CD\u8BD5\u3002");
|
|
144
|
+
try {
|
|
145
|
+
const reason = await inspectPackageDirectory(root, globalRoot);
|
|
146
|
+
if (reason) throw new Error(reason);
|
|
147
|
+
const entry = join(root, "bin/covro.mjs");
|
|
148
|
+
if ((await lstat(entry)).isSymbolicLink() || await realpath(join(prefix, "bin/covro")) !== entry)
|
|
149
|
+
throw new Error("\u5168\u5C40 covro \u5165\u53E3\u4E0E npm \u5B89\u88C5\u76EE\u5F55\u4E0D\u5339\u914D");
|
|
150
|
+
const metadata = JSON.parse(await readFile(join(root, "package.json"), "utf8"));
|
|
151
|
+
if (metadata.name !== npmPackageName || !validVersion(metadata.version))
|
|
152
|
+
throw new Error("Covro \u5305\u8EAB\u4EFD\u65E0\u6548");
|
|
153
|
+
return {
|
|
154
|
+
node,
|
|
155
|
+
nodeVersion,
|
|
156
|
+
npm,
|
|
157
|
+
npmVersion,
|
|
158
|
+
prefix,
|
|
159
|
+
globalRoot,
|
|
160
|
+
root,
|
|
161
|
+
entry,
|
|
162
|
+
path,
|
|
163
|
+
version: metadata.version,
|
|
164
|
+
covroCodex: metadata.covroCodex,
|
|
165
|
+
covroCommit: metadata.covroCommit ?? metadata.gitHead,
|
|
166
|
+
npmConfig: found.npmConfig
|
|
167
|
+
};
|
|
168
|
+
} catch (error) {
|
|
169
|
+
throw new Error(
|
|
170
|
+
`\u76EE\u6807 Node ${nodeVersion} \u7684\u5168\u5C40 Covro \u4E0D\u53EF\u7528\uFF1A${error.message}\u3002\u8BF7\u5728\u65B0\u7EC8\u7AEF\u6267\u884C npm install -g ${npmPackageName} \u540E\u91CD\u8BD5\uFF1B\u5F53\u524D\u670D\u52A1\u4FDD\u6301\u8FD0\u884C\u3002`,
|
|
171
|
+
{ cause: error }
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
export {
|
|
176
|
+
assertRuntime,
|
|
177
|
+
defaultNodeEnvironment,
|
|
178
|
+
resolveRuntimeTarget,
|
|
179
|
+
runtimeChanged,
|
|
180
|
+
targetNpmEnvironment,
|
|
181
|
+
verifyRuntimeExecutable
|
|
182
|
+
};
|
|
183
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/updates/runtime.ts"],
|
|
4
|
+
"sourcesContent": ["import { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { homedir, userInfo } from 'node:os';\nimport { access, lstat, readFile, realpath } from 'node:fs/promises';\nimport { constants } from 'node:fs';\nimport { basename, delimiter, dirname, isAbsolute, join } from 'node:path';\nimport { z } from 'zod';\nimport { npmPackageName } from '../shared/package.js';\nimport { compareVersions, validVersion } from '../shared/versions.js';\nimport type { RuntimeIdentity } from '../shared/updates.js';\nimport { inspectPackageDirectory } from './registry.js';\n\nconst exec = promisify(execFile);\nexport interface RuntimeTarget extends RuntimeIdentity {\n npm: string;\n npmVersion: string;\n prefix: string;\n globalRoot: string;\n path: string;\n version: string;\n covroCodex?: unknown;\n covroCommit?: string;\n npmConfig?: Record<string, string>;\n}\nexport const runtimeChanged = (target: RuntimeIdentity, current: RuntimeIdentity) =>\n target.node !== current.node ||\n target.nodeVersion !== current.nodeVersion ||\n target.root !== current.root;\nexport function assertRuntime(actual: RuntimeIdentity | undefined, expected: RuntimeIdentity) {\n if (\n !actual ||\n actual.node !== expected.node ||\n actual.nodeVersion !== expected.nodeVersion ||\n actual.root !== expected.root ||\n actual.entry !== expected.entry\n )\n throw new Error(\n '\u5B9E\u9645 Node \u6216 Covro \u5B89\u88C5\u6765\u6E90\u4E0E\u76EE\u6807\u4E0D\u5339\u914D\uFF1B\u62D2\u7EDD\u6FC0\u6D3B\uFF0C\u8BF7\u67E5\u770B\u5347\u7EA7\u65E5\u5FD7\u5E76\u8FD0\u884C covro update repair\u3002',\n );\n}\nexport async function verifyRuntimeExecutable(runtime: RuntimeIdentity) {\n const { stdout } = await exec(\n runtime.node,\n ['-p', 'JSON.stringify({node:process.execPath,nodeVersion:process.versions.node})'],\n { env: targetNpmEnvironment(process.env.PATH ?? '/usr/bin:/bin'), timeout: 15_000 },\n );\n const actual = JSON.parse(stdout) as { node: string; nodeVersion: string };\n if (actual.node !== runtime.node || actual.nodeVersion !== runtime.nodeVersion)\n throw new Error(\n '\u65E7 Node \u7684\u78C1\u76D8\u8DEF\u5F84\u5DF2\u88AB\u66FF\u6362\uFF0C\u65E0\u6CD5\u4FDD\u8BC1\u56DE\u6EDA\uFF1B\u8BF7\u4FDD\u7559\u65E7 Node \u5B89\u88C5\u5E76\u6838\u5BF9\u542F\u52A8\u6765\u6E90\u540E\u91CD\u8BD5\u3002',\n );\n}\n\nconst probeSchema = z.object({\n node: z.string(),\n nodeVersion: z.string(),\n path: z.string(),\n npmConfig: z.record(z.string(), z.string()).optional(),\n});\n// Startup files may print banners. Only accept the single explicitly framed Node response.\nconst marker = 'COVRO_RUNTIME_281=';\nconst npmConfigKeys = ['prefix', 'userconfig', 'globalconfig'] as const;\nconst probe = `process.stdout.write('${marker}'+JSON.stringify({node:process.execPath,nodeVersion:process.versions.node,path:process.env.PATH,npmConfig:Object.fromEntries(${JSON.stringify(npmConfigKeys)}.flatMap(k=>{const v=process.env['npm_config_'+k]??process.env['NPM_CONFIG_'+k.toUpperCase()];return v===undefined?[]:[[k,v]]}))})+'\\\\n')`;\nexport function targetNpmEnvironment(path: string, config: Record<string, string> = {}) {\n const env: NodeJS.ProcessEnv = { ...process.env, PATH: path, NODE_OPTIONS: '', NODE_PATH: '' };\n for (const key of npmConfigKeys) {\n delete env[`NPM_CONFIG_${key.toUpperCase()}`];\n delete env[`npm_config_${key}`];\n if (config[key]) env[`npm_config_${key}`] = config[key];\n }\n return env;\n}\nconst quote = (value: string) => `'${value.replaceAll(\"'\", \"'\\\\''\")}'`;\n\nexport async function defaultNodeEnvironment() {\n const shell = userInfo().shell;\n if (!shell || !['bash', 'zsh', 'sh', 'dash', 'fish'].includes(basename(shell)))\n throw new Error(\n '\u65E0\u6CD5\u8BC6\u522B\u9ED8\u8BA4\u767B\u5F55 shell\uFF1B\u8BF7\u5728\u76EE\u6807 Node \u7684\u7EC8\u7AEF\u4F7F\u7528\u539F\u90E8\u7F72\u65B9\u5F0F\u66F4\u65B0\u5E76\u91CD\u65B0\u5B89\u88C5\u767B\u5F55\u670D\u52A1\u3002',\n );\n // Do not carry an old nvm/fnm activation into the fresh login. Keep custom tool directories\n // so the user's existing version manager can initialize, but discard concrete Node bins.\n const oldBin = dirname(process.execPath);\n const path = (process.env.PATH ?? '')\n .split(delimiter)\n .filter(\n (part) =>\n part &&\n part !== oldBin &&\n !/fnm_multishells|\\/node-versions\\/|\\/\\.nvm\\/versions\\/node\\//.test(part),\n );\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n PATH: [...new Set([...path, '/usr/local/bin', '/opt/homebrew/bin', '/usr/bin', '/bin'])].join(\n delimiter,\n ),\n };\n for (const key of ['FNM_MULTISHELL_PATH', 'NVM_BIN', 'NVM_INC', 'NODE_OPTIONS', 'NODE_PATH'])\n delete env[key];\n for (const key of npmConfigKeys) {\n delete env[`npm_config_${key}`];\n delete env[`NPM_CONFIG_${key.toUpperCase()}`];\n }\n const { stdout } = await exec(shell, ['-ilc', `node -e ${quote(probe)}`], {\n cwd: homedir(),\n env,\n timeout: 15_000,\n maxBuffer: 256 * 1024,\n });\n const lines = stdout.split(/\\r?\\n/).filter((line) => line.startsWith(marker));\n if (lines.length !== 1)\n throw new Error('\u767B\u5F55 shell \u672A\u8FD4\u56DE\u552F\u4E00\u7684\u9ED8\u8BA4 Node\uFF1B\u8BF7\u68C0\u67E5 shell \u542F\u52A8\u914D\u7F6E\u540E\u91CD\u8BD5\u3002');\n return probeSchema.parse(JSON.parse(lines[0]!.slice(marker.length)));\n}\n\nasync function executable(name: string, path: string) {\n for (const directory of path.split(delimiter)) {\n if (!isAbsolute(directory)) continue;\n const filename = join(directory, name);\n try {\n await access(filename, constants.X_OK);\n return await realpath(filename);\n } catch (error) {\n if (!['ENOENT', 'EACCES', 'ENOTDIR'].includes((error as NodeJS.ErrnoException).code ?? ''))\n throw error;\n }\n }\n throw new Error(\n `\u76EE\u6807 Node \u73AF\u5883\u4E2D\u627E\u4E0D\u5230 ${name}\uFF1B\u8BF7\u5728\u65B0\u7EC8\u7AEF\u68C0\u67E5 node\u3001npm \u548C npm install -g ${npmPackageName}\u3002`,\n );\n}\n\n/** No installs, shell aliases, or inherited npm shebangs participate in target selection. */\nexport async function resolveRuntimeTarget(\n environment = defaultNodeEnvironment,\n): Promise<RuntimeTarget> {\n const found = await environment();\n const node = await realpath(found.node);\n await access(node, constants.X_OK);\n const { stdout } = await exec(node, ['-p', 'process.versions.node'], {\n env: targetNpmEnvironment(found.path, found.npmConfig),\n timeout: 15_000,\n });\n const nodeVersion = stdout.trim();\n // This release supports the same explicit range as package.json. Never silently accept a new major.\n if (\n nodeVersion !== found.nodeVersion ||\n !validVersion(nodeVersion) ||\n compareVersions(nodeVersion, '24.19.0') < 0 ||\n compareVersions(nodeVersion, '25.0.0') >= 0\n )\n throw new Error(\n `\u76EE\u6807 Node ${nodeVersion} \u4E0D\u53D7\u652F\u6301\uFF1B\u9700\u8981 >=24.19.0 <25\uFF0C\u8BF7\u8C03\u6574\u9ED8\u8BA4 Node \u540E\u91CD\u8BD5\u3002`,\n );\n const npm = await executable('npm', found.path);\n if ((await realpath(join(dirname(node), 'npm')).catch(() => undefined)) !== npm)\n throw new Error('\u9ED8\u8BA4 Node \u548C npm \u6765\u81EA\u4E0D\u540C\u5B89\u88C5\uFF1B\u8BF7\u4FEE\u590D\u767B\u5F55 shell \u7684 PATH \u540E\u91CD\u65B0\u68C0\u67E5\u3002');\n const npmInfo = JSON.parse(await readFile(join(dirname(npm), '../package.json'), 'utf8')) as {\n name?: string;\n };\n if (basename(npm) !== 'npm-cli.js' || npmInfo.name !== 'npm')\n throw new Error(\n '\u76EE\u6807 npm \u662F\u65E0\u6CD5\u786E\u8BA4\u7684 shim\uFF1B\u8BF7\u8BA9\u767B\u5F55 shell \u7684 PATH \u6307\u5411\u76EE\u6807 Node \u81EA\u5E26\u7684 npm \u540E\u91CD\u8BD5\u3002',\n );\n const directories = await Promise.all(\n found.path\n .split(delimiter)\n .filter(isAbsolute)\n .map((part) => realpath(part).catch(() => undefined)),\n );\n const path = [\n ...new Set([dirname(node), ...directories.filter((part): part is string => Boolean(part))]),\n ].join(delimiter);\n const options = {\n env: targetNpmEnvironment(path, found.npmConfig),\n cwd: homedir(),\n timeout: 15_000,\n };\n const [prefixResult, rootResult, npmVersionResult] = await Promise.all([\n exec(node, [npm, 'prefix', '--global'], options),\n exec(node, [npm, 'root', '--global'], options),\n exec(node, [npm, '--version'], options),\n ]);\n const prefix = await realpath(prefixResult.stdout.trim());\n const globalRoot = await realpath(rootResult.stdout.trim());\n if (globalRoot !== join(prefix, 'lib/node_modules'))\n throw new Error('\u76EE\u6807 npm \u5168\u5C40\u76EE\u5F55\u5E03\u5C40\u4E0D\u53D7\u652F\u6301\u3002');\n const root = join(globalRoot, npmPackageName);\n const npmVersion = npmVersionResult.stdout.trim();\n if (!validVersion(npmVersion))\n throw new Error('\u76EE\u6807 npm \u672A\u8FD4\u56DE\u6709\u6548\u7248\u672C\uFF0C\u8BF7\u68C0\u67E5 npm \u5B89\u88C5\u540E\u91CD\u8BD5\u3002');\n try {\n const reason = await inspectPackageDirectory(root, globalRoot);\n if (reason) throw new Error(reason);\n const entry = join(root, 'bin/covro.mjs');\n if (\n (await lstat(entry)).isSymbolicLink() ||\n (await realpath(join(prefix, 'bin/covro'))) !== entry\n )\n throw new Error('\u5168\u5C40 covro \u5165\u53E3\u4E0E npm \u5B89\u88C5\u76EE\u5F55\u4E0D\u5339\u914D');\n const metadata = JSON.parse(await readFile(join(root, 'package.json'), 'utf8')) as {\n name: string;\n version: string;\n covroCodex?: unknown;\n covroCommit?: string;\n gitHead?: string;\n };\n if (metadata.name !== npmPackageName || !validVersion(metadata.version))\n throw new Error('Covro \u5305\u8EAB\u4EFD\u65E0\u6548');\n return {\n node,\n nodeVersion,\n npm,\n npmVersion,\n prefix,\n globalRoot,\n root,\n entry,\n path,\n version: metadata.version,\n covroCodex: metadata.covroCodex,\n covroCommit: metadata.covroCommit ?? metadata.gitHead,\n npmConfig: found.npmConfig,\n };\n } catch (error) {\n throw new Error(\n `\u76EE\u6807 Node ${nodeVersion} \u7684\u5168\u5C40 Covro \u4E0D\u53EF\u7528\uFF1A${(error as Error).message}\u3002\u8BF7\u5728\u65B0\u7EC8\u7AEF\u6267\u884C npm install -g ${npmPackageName} \u540E\u91CD\u8BD5\uFF1B\u5F53\u524D\u670D\u52A1\u4FDD\u6301\u8FD0\u884C\u3002`,\n { cause: error },\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|