
























@@ -0,0 +1,104 @@
1+import type { PluginInstallRecord } from "../config/types.plugins.js";
2+import type {
3+InstalledPluginIndex,
4+InstalledPluginInstallRecordInfo,
5+} from "./installed-plugin-index-types.js";
6+7+function setInstallStringField<Key extends keyof Omit<InstalledPluginInstallRecordInfo, "source">>(
8+target: InstalledPluginInstallRecordInfo,
9+key: Key,
10+value: PluginInstallRecord[Key],
11+): void {
12+if (typeof value !== "string") {
13+return;
14+}
15+const normalized = value.trim();
16+if (normalized) {
17+target[key] = normalized as InstalledPluginInstallRecordInfo[Key];
18+}
19+}
20+21+function normalizeInstallRecord(
22+record: PluginInstallRecord | undefined,
23+): InstalledPluginInstallRecordInfo | undefined {
24+if (!record) {
25+return undefined;
26+}
27+const normalized: InstalledPluginInstallRecordInfo = {
28+source: record.source,
29+};
30+setInstallStringField(normalized, "spec", record.spec);
31+setInstallStringField(normalized, "sourcePath", record.sourcePath);
32+setInstallStringField(normalized, "installPath", record.installPath);
33+setInstallStringField(normalized, "version", record.version);
34+setInstallStringField(normalized, "resolvedName", record.resolvedName);
35+setInstallStringField(normalized, "resolvedVersion", record.resolvedVersion);
36+setInstallStringField(normalized, "resolvedSpec", record.resolvedSpec);
37+setInstallStringField(normalized, "integrity", record.integrity);
38+setInstallStringField(normalized, "shasum", record.shasum);
39+setInstallStringField(normalized, "resolvedAt", record.resolvedAt);
40+setInstallStringField(normalized, "installedAt", record.installedAt);
41+setInstallStringField(normalized, "clawhubUrl", record.clawhubUrl);
42+setInstallStringField(normalized, "clawhubPackage", record.clawhubPackage);
43+setInstallStringField(normalized, "clawhubFamily", record.clawhubFamily);
44+setInstallStringField(normalized, "clawhubChannel", record.clawhubChannel);
45+setInstallStringField(normalized, "marketplaceName", record.marketplaceName);
46+setInstallStringField(normalized, "marketplaceSource", record.marketplaceSource);
47+setInstallStringField(normalized, "marketplacePlugin", record.marketplacePlugin);
48+return normalized;
49+}
50+51+function restoreInstallRecord(
52+record: InstalledPluginInstallRecordInfo | undefined,
53+): PluginInstallRecord | undefined {
54+if (!record?.source) {
55+return undefined;
56+}
57+return structuredClone(record) as PluginInstallRecord;
58+}
59+60+export function normalizeInstallRecordMap(
61+records: Record<string, PluginInstallRecord> | undefined,
62+): Record<string, InstalledPluginInstallRecordInfo> {
63+const normalized: Record<string, InstalledPluginInstallRecordInfo> = {};
64+for (const [pluginId, record] of Object.entries(records ?? {}).toSorted(([left], [right]) =>
65+left.localeCompare(right),
66+)) {
67+const installRecord = normalizeInstallRecord(record);
68+if (installRecord) {
69+normalized[pluginId] = installRecord;
70+}
71+}
72+return normalized;
73+}
74+75+function restoreInstallRecordMap(
76+records: Readonly<Record<string, InstalledPluginInstallRecordInfo>> | undefined,
77+): Record<string, PluginInstallRecord> {
78+const restored: Record<string, PluginInstallRecord> = {};
79+for (const [pluginId, record] of Object.entries(records ?? {}).toSorted(([left], [right]) =>
80+left.localeCompare(right),
81+)) {
82+const installRecord = restoreInstallRecord(record);
83+if (installRecord) {
84+restored[pluginId] = installRecord;
85+}
86+}
87+return restored;
88+}
89+90+export function extractPluginInstallRecordsFromInstalledPluginIndex(
91+index: InstalledPluginIndex | null | undefined,
92+): Record<string, PluginInstallRecord> {
93+if (index && Object.prototype.hasOwnProperty.call(index, "installRecords")) {
94+return restoreInstallRecordMap(index.installRecords);
95+}
96+const records: Record<string, PluginInstallRecord> = {};
97+for (const plugin of index?.plugins ?? []) {
98+const record = restoreInstallRecord(plugin.installRecord);
99+if (record) {
100+records[plugin.pluginId] = record;
101+}
102+}
103+return records;
104+}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。