@dsh-workbench/core 0.1.7 → 0.1.9
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/client.js +858 -408
- package/dist/client/client.body.js +858 -408
- package/dist/client/index.js +858 -408
- package/dist/host/index.js +154 -6
- package/dist/types/app/client.d.ts +78 -15
- package/dist/types/app/layouts/env-gate/__tests__/gate-deadline.test.d.ts +1 -0
- package/dist/types/app/layouts/env-gate/gate-deadline.d.ts +4 -0
- package/dist/types/app/layouts/rightbar/ColumnSwitch.d.ts +10 -0
- package/dist/types/app/layouts/rightbar/MarketStates.d.ts +7 -0
- package/dist/types/app/layouts/rightbar/MarketView.d.ts +2 -1
- package/dist/types/app/layouts/rightbar/Rightbar.d.ts +3 -1
- package/dist/types/app/layouts/rightbar/SharedSection.d.ts +11 -0
- package/dist/types/app/layouts/rightbar/__tests__/market-change.test.d.ts +1 -0
- package/dist/types/app/layouts/rightbar/__tests__/market-live.test.d.ts +1 -0
- package/dist/types/app/layouts/rightbar/__tests__/market-settle.test.d.ts +1 -0
- package/dist/types/app/layouts/rightbar/dsh-column-source.d.ts +6 -0
- package/dist/types/app/layouts/rightbar/dsh-column-source.test.d.ts +1 -0
- package/dist/types/app/layouts/rightbar/market-change.d.ts +4 -0
- package/dist/types/app/layouts/rightbar/market-rows.d.ts +3 -1
- package/dist/types/app/layouts/rightbar/market-settle.d.ts +2 -0
- package/dist/types/app/layouts/rightbar/market-view-text.d.ts +10 -0
- package/dist/types/app/layouts/rightbar/presentation.d.ts +9 -0
- package/dist/types/app/layouts/rightbar/presentation.test.d.ts +1 -0
- package/dist/types/app/layouts/rightbar/store.d.ts +9 -0
- package/dist/types/modules/panels/__tests__/market-registries.test.d.ts +1 -0
- package/dist/types/modules/panels/model/market.d.ts +2 -0
- package/dist/types/shared/api/host/__tests__/profile-registries.test.d.ts +1 -0
- package/dist/types/shared/api/host/profile-registries.d.ts +21 -0
- package/docs/OPERATIONS.md +2 -0
- package/package.json +2 -2
- package/dist/types/app/layouts/rightbar/ExpandButton.d.ts +0 -9
package/dist/host/index.js
CHANGED
|
@@ -1380,7 +1380,7 @@ function readBundleManager(ctx) {
|
|
|
1380
1380
|
}
|
|
1381
1381
|
//#endregion
|
|
1382
1382
|
//#region src/shared/api/host/installed-module.ts
|
|
1383
|
-
var PACKAGE_NAME = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/;
|
|
1383
|
+
var PACKAGE_NAME$1 = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/;
|
|
1384
1384
|
function asRecord$1(value) {
|
|
1385
1385
|
return typeof value === "object" && value !== null ? value : void 0;
|
|
1386
1386
|
}
|
|
@@ -1388,7 +1388,7 @@ function asText$1(value) {
|
|
|
1388
1388
|
return typeof value === "string" ? value : "";
|
|
1389
1389
|
}
|
|
1390
1390
|
function isPackageName(value) {
|
|
1391
|
-
return value.length <= 214 && PACKAGE_NAME.test(value);
|
|
1391
|
+
return value.length <= 214 && PACKAGE_NAME$1.test(value);
|
|
1392
1392
|
}
|
|
1393
1393
|
function profileDirOf(ctx) {
|
|
1394
1394
|
const profile = ctx.get("profileContext");
|
|
@@ -1477,6 +1477,118 @@ function readInstalledModule(profileDir, pkg) {
|
|
|
1477
1477
|
};
|
|
1478
1478
|
}
|
|
1479
1479
|
//#endregion
|
|
1480
|
+
//#region src/shared/api/host/profile-registries.ts
|
|
1481
|
+
var REGISTRY_MARKER = "# dsh-workbench 写的:这一行的包只在这个源上(dsh 卸载没有源参数,pnpm 得问得到)";
|
|
1482
|
+
function scopeOf(pkg) {
|
|
1483
|
+
const slash = pkg.indexOf("/");
|
|
1484
|
+
return pkg.startsWith("@") && slash > 1 ? pkg.slice(0, slash) : null;
|
|
1485
|
+
}
|
|
1486
|
+
function normalizeRegistry(url) {
|
|
1487
|
+
const trimmed = url.trim();
|
|
1488
|
+
return trimmed.endsWith("/") ? trimmed : `${trimmed}/`;
|
|
1489
|
+
}
|
|
1490
|
+
function sameRegistry(a, b) {
|
|
1491
|
+
if (a === null || a === void 0 || b === null || b === void 0) return false;
|
|
1492
|
+
if (a.trim() === "" || b.trim() === "") return false;
|
|
1493
|
+
return normalizeRegistry(a) === normalizeRegistry(b);
|
|
1494
|
+
}
|
|
1495
|
+
function registryRootOf(name, tarball) {
|
|
1496
|
+
const at = tarball.indexOf(`/${name}/-/`);
|
|
1497
|
+
if (at > 0) return normalizeRegistry(tarball.slice(0, at));
|
|
1498
|
+
try {
|
|
1499
|
+
return normalizeRegistry(new URL(tarball).origin);
|
|
1500
|
+
} catch {
|
|
1501
|
+
return null;
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
var PACKAGE_KEY = /^ {2}'?(\S+)'?:\s*$/;
|
|
1505
|
+
var PACKAGE_NAME = /^(?:@[^/\s]+\/)?[^/\s@]+$/;
|
|
1506
|
+
var TARBALL = /tarball:\s*(\S+?)\}?\s*$/;
|
|
1507
|
+
function sourcesFromLockfile(text) {
|
|
1508
|
+
const found = /* @__PURE__ */ new Map();
|
|
1509
|
+
let name = null;
|
|
1510
|
+
for (const line of text.split("\n")) {
|
|
1511
|
+
const key = PACKAGE_KEY.exec(line);
|
|
1512
|
+
if (key !== null) {
|
|
1513
|
+
const raw = key[1] ?? "";
|
|
1514
|
+
const at = raw.lastIndexOf("@");
|
|
1515
|
+
const candidate = at > 0 ? raw.slice(0, at) : "";
|
|
1516
|
+
name = PACKAGE_NAME.test(candidate) ? candidate : null;
|
|
1517
|
+
continue;
|
|
1518
|
+
}
|
|
1519
|
+
if (name === null) continue;
|
|
1520
|
+
const tarball = TARBALL.exec(line);
|
|
1521
|
+
if (tarball === null) continue;
|
|
1522
|
+
const scope = scopeOf(name);
|
|
1523
|
+
const root = registryRootOf(name, tarball[1] ?? "");
|
|
1524
|
+
name = null;
|
|
1525
|
+
if (scope === null || root === null) continue;
|
|
1526
|
+
const seen = found.get(scope);
|
|
1527
|
+
if (seen === void 0) found.set(scope, root);
|
|
1528
|
+
else if (!sameRegistry(seen, root)) found.set(scope, null);
|
|
1529
|
+
}
|
|
1530
|
+
return [...found.entries()].filter((entry) => entry[1] !== null).map(([scope, registry]) => ({
|
|
1531
|
+
scope,
|
|
1532
|
+
registry
|
|
1533
|
+
}));
|
|
1534
|
+
}
|
|
1535
|
+
function mergeRegistryConfig(text, entries) {
|
|
1536
|
+
const lines = text.split("\n");
|
|
1537
|
+
const present = (key) => lines.some((line) => line.trim().startsWith(`${key}=`));
|
|
1538
|
+
const appended = [];
|
|
1539
|
+
const added = [];
|
|
1540
|
+
for (const entry of entries) {
|
|
1541
|
+
const key = `${entry.scope}:registry`;
|
|
1542
|
+
if (entry.registry.trim() === "" || present(key)) continue;
|
|
1543
|
+
lines.push(`${key}=${normalizeRegistry(entry.registry)}`);
|
|
1544
|
+
appended.push(`${key}=${normalizeRegistry(entry.registry)}`);
|
|
1545
|
+
added.push(key);
|
|
1546
|
+
}
|
|
1547
|
+
if (appended.length === 0) return {
|
|
1548
|
+
text,
|
|
1549
|
+
added: []
|
|
1550
|
+
};
|
|
1551
|
+
const base = text === "" ? "" : text.endsWith("\n") ? text : `${text}\n`;
|
|
1552
|
+
return {
|
|
1553
|
+
text: `${base}${base.includes("# dsh-workbench 写的:这一行的包只在这个源上(dsh 卸载没有源参数,pnpm 得问得到)") ? "" : `${REGISTRY_MARKER}\n`}${appended.join("\n")}\n`,
|
|
1554
|
+
added
|
|
1555
|
+
};
|
|
1556
|
+
}
|
|
1557
|
+
function registryFailure(change) {
|
|
1558
|
+
if (change.application !== "failed") return false;
|
|
1559
|
+
if (change.packageResult?.kind === "not-found") return true;
|
|
1560
|
+
const output = change.packageResult?.output ?? change.errorDetail ?? "";
|
|
1561
|
+
return /ERR_PNPM_[A-Z_]*FETCH/.test(output);
|
|
1562
|
+
}
|
|
1563
|
+
function createRegistryNotebook(dir) {
|
|
1564
|
+
return {
|
|
1565
|
+
sources() {
|
|
1566
|
+
if (dir === null) return [];
|
|
1567
|
+
try {
|
|
1568
|
+
return sourcesFromLockfile(fs.readFileSync(path.join(dir, "pnpm-lock.yaml"), "utf8"));
|
|
1569
|
+
} catch {
|
|
1570
|
+
return [];
|
|
1571
|
+
}
|
|
1572
|
+
},
|
|
1573
|
+
remember(entries) {
|
|
1574
|
+
if (dir === null || entries.length === 0) return [];
|
|
1575
|
+
const file = path.join(dir, ".npmrc");
|
|
1576
|
+
let before;
|
|
1577
|
+
try {
|
|
1578
|
+
before = fs.readFileSync(file, "utf8");
|
|
1579
|
+
} catch {
|
|
1580
|
+
before = "";
|
|
1581
|
+
}
|
|
1582
|
+
const merged = mergeRegistryConfig(before, entries);
|
|
1583
|
+
if (merged.added.length === 0) return [];
|
|
1584
|
+
const temp = `${file}.dsh-workbench.tmp`;
|
|
1585
|
+
fs.writeFileSync(temp, merged.text, { mode: 384 });
|
|
1586
|
+
fs.renameSync(temp, file);
|
|
1587
|
+
return merged.added;
|
|
1588
|
+
}
|
|
1589
|
+
};
|
|
1590
|
+
}
|
|
1591
|
+
//#endregion
|
|
1480
1592
|
//#region src/shared/api/host/release.ts
|
|
1481
1593
|
function parseLedgerVersion(stdout, name) {
|
|
1482
1594
|
const parsed = parseJsonLoose(stdout);
|
|
@@ -1703,7 +1815,7 @@ function bundleNameOf(change, spec) {
|
|
|
1703
1815
|
return at > 0 ? spec.slice(0, at) : spec;
|
|
1704
1816
|
}
|
|
1705
1817
|
function createMarketService(options) {
|
|
1706
|
-
const { manifests, manifestsNow, probe, shell, logger, onInstalled, onUninstalled, isReleased, bundles, installed, modules } = options;
|
|
1818
|
+
const { manifests, manifestsNow, probe, shell, logger, onInstalled, onUninstalled, isReleased, bundles, installed, modules, registries } = options;
|
|
1707
1819
|
const command = options.command ?? "opencli";
|
|
1708
1820
|
const catalog = () => (manifestsNow?.() ?? manifests).filter((manifest) => (manifest.env?.plugins ?? []).length > 0 || (manifest.env?.libs ?? []).length > 0);
|
|
1709
1821
|
function requireEntry(unit) {
|
|
@@ -1850,6 +1962,38 @@ function createMarketService(options) {
|
|
|
1850
1962
|
};
|
|
1851
1963
|
}
|
|
1852
1964
|
}
|
|
1965
|
+
async function rememberInstalledSource(manager, pkg, registry) {
|
|
1966
|
+
if (registries === void 0 || registry === void 0) return;
|
|
1967
|
+
const scope = scopeOf(pkg);
|
|
1968
|
+
if (scope === null) return;
|
|
1969
|
+
const known = await manager.registries().catch(() => null);
|
|
1970
|
+
if (known !== null && sameRegistry(known.resolved, registry)) return;
|
|
1971
|
+
try {
|
|
1972
|
+
const added = registries.remember([{
|
|
1973
|
+
scope,
|
|
1974
|
+
registry
|
|
1975
|
+
}]);
|
|
1976
|
+
if (added.length > 0) logger?.info?.(`[dsh-workbench] 把 ${added.join("、")} 记进 profile 的 .npmrc(卸载只认 pnpm 的配置)`);
|
|
1977
|
+
} catch (error) {
|
|
1978
|
+
logger?.warn?.(`[dsh-workbench] 记这个 scope 的源失败:${String(error)}`);
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
async function retryAfterRegistryFix(manager, pkg, change) {
|
|
1982
|
+
if (registries === void 0 || !registryFailure(change)) return change;
|
|
1983
|
+
const known = await manager.registries().catch(() => null);
|
|
1984
|
+
const missing = registries.sources().filter((entry) => !sameRegistry(entry.registry, known?.resolved ?? null));
|
|
1985
|
+
if (missing.length === 0) return change;
|
|
1986
|
+
let added;
|
|
1987
|
+
try {
|
|
1988
|
+
added = registries.remember(missing);
|
|
1989
|
+
} catch (error) {
|
|
1990
|
+
logger?.warn?.(`[dsh-workbench] 卸 ${pkg} 撞上源,但补配置失败:${String(error)}`);
|
|
1991
|
+
return change;
|
|
1992
|
+
}
|
|
1993
|
+
if (added.length === 0) return change;
|
|
1994
|
+
logger?.warn?.(`[dsh-workbench] 卸 ${pkg} 撞上源:补 ${added.join("、")} 后重试一次`);
|
|
1995
|
+
return await manager.remove(pkg).catch(() => null) ?? change;
|
|
1996
|
+
}
|
|
1853
1997
|
const service = {
|
|
1854
1998
|
async list() {
|
|
1855
1999
|
return snapshot();
|
|
@@ -1955,7 +2099,8 @@ function createMarketService(options) {
|
|
|
1955
2099
|
};
|
|
1956
2100
|
},
|
|
1957
2101
|
async installBundle(spec, options) {
|
|
1958
|
-
const
|
|
2102
|
+
const manager = requireBundles();
|
|
2103
|
+
const change = await manager.install({
|
|
1959
2104
|
spec,
|
|
1960
2105
|
...options?.registry === void 0 ? {} : { registry: options.registry },
|
|
1961
2106
|
...options?.requestId === void 0 ? {} : { requestId: options.requestId },
|
|
@@ -1967,6 +2112,7 @@ function createMarketService(options) {
|
|
|
1967
2112
|
kind: "unknown",
|
|
1968
2113
|
pkg
|
|
1969
2114
|
};
|
|
2115
|
+
await rememberInstalledSource(manager, pkg, options?.registry);
|
|
1970
2116
|
return {
|
|
1971
2117
|
change,
|
|
1972
2118
|
module,
|
|
@@ -1982,8 +2128,9 @@ function createMarketService(options) {
|
|
|
1982
2128
|
const unit = module.kind === "module" ? module.unit : void 0;
|
|
1983
2129
|
const manifest = unit === void 0 ? void 0 : catalog().find((item) => item.id === unit);
|
|
1984
2130
|
const before = unit === void 0 ? void 0 : await capabilityOf(unit, true);
|
|
1985
|
-
const
|
|
1986
|
-
if (
|
|
2131
|
+
const first = await manager.remove(pkg);
|
|
2132
|
+
if (first === null) throw new Error("插件管理器回的卸载结果看不懂。");
|
|
2133
|
+
const change = await retryAfterRegistryFix(manager, pkg, first);
|
|
1987
2134
|
if (change.application !== "applied" || unit === void 0) return {
|
|
1988
2135
|
change,
|
|
1989
2136
|
keptFor: []
|
|
@@ -2682,6 +2829,7 @@ var HOST_UNITS = [{
|
|
|
2682
2829
|
bundles: readBundleManager(ctx),
|
|
2683
2830
|
installed: (pkg) => readInstalledModule(profileDir, pkg),
|
|
2684
2831
|
modules: () => profileModules(profileDir),
|
|
2832
|
+
registries: createRegistryNotebook(profileDir),
|
|
2685
2833
|
onUninstalled: (unit) => {
|
|
2686
2834
|
panels.release(unit);
|
|
2687
2835
|
},
|