fix: close marketplace client review findings

This commit is contained in:
2026-08-28 21:01:51 +08:00
parent 8dfa542860
commit 1614f7efc1
25 changed files with 1224 additions and 143 deletions

View File

@@ -101,6 +101,7 @@ export interface CodingPluginMarketplaceService {
acquire(pluginId: string): Promise<PublicPluginLibrary>;
remove(pluginId: string): Promise<PublicPluginLibrary>;
install(pluginId: string): Promise<PublicPluginInstallation>;
installBeta(pluginId: string): Promise<PublicPluginInstallation>;
update(pluginId: string): Promise<PublicPluginInstallation>;
uninstall(pluginId: string): Promise<PublicPluginInstallation>;
}
@@ -127,25 +128,33 @@ function publicInstallation(snapshot: InstallationSnapshot): PublicPluginInstall
async function publicLibrary(
library: MarketplaceLibrarySnapshot,
packageStore: Pick<PluginPackageStore, 'readInstalledIndex'>,
packageStore: Pick<PluginPackageStore, 'getInstalled'>,
): Promise<PublicPluginLibrary> {
const libraryPluginIds = new Set(library.items.map(({ pluginId }) => pluginId));
const latest = new Map<string, Awaited<ReturnType<PluginPackageStore['readInstalledIndex']>>[number]>();
for (const record of await packageStore.readInstalledIndex()) {
if (!libraryPluginIds.has(record.pluginId)) continue;
const current = latest.get(record.pluginId);
if (!current || record.installedAt >= current.installedAt) latest.set(record.pluginId, record);
}
return {
library,
installations: [...latest.values()]
.sort((left, right) => left.pluginId.localeCompare(right.pluginId))
.map((record) => ({
status: 'installed',
const installations = await Promise.all(library.items.map(async ({ pluginId }) => {
try {
const record = await packageStore.getInstalled(pluginId);
return record ? {
status: 'installed' as const,
pluginId: record.pluginId,
releaseId: record.releaseId,
version: record.version,
})),
} : null;
} catch (error) {
const candidate = error && typeof error === 'object' && 'code' in error
&& typeof error.code === 'string'
? error.code
: '';
const reason = /^[a-z][a-z0-9_]{0,63}$/u.test(candidate)
? candidate
: 'plugin_backend_unavailable';
return { status: 'unavailable' as const, pluginId, reason };
}
}));
return {
library,
installations: installations
.filter((installation): installation is NonNullable<typeof installation> => installation !== null)
.sort((left, right) => left.pluginId.localeCompare(right.pluginId)),
};
}
@@ -161,8 +170,18 @@ export function createCodingPluginMarketplaceService(
await options.onChanged?.({ pluginId, kind });
return publicInstallation(snapshot);
};
const installBeta = async (pluginId: string): Promise<PublicPluginInstallation> => {
const snapshot = await options.packageStore.resolveAndInstall({
pluginId,
makeloreVersion: options.clientVersion,
channel: 'beta',
explicitBeta: true,
});
await options.onChanged?.({ pluginId, kind: 'install' });
return publicInstallation(snapshot);
};
const uninstall = async (pluginId: string): Promise<PublicPluginInstallation> => {
const snapshot = await options.packageStore.removeUnused(pluginId);
const snapshot = await options.packageStore.uninstall(pluginId);
await options.onChanged?.({ pluginId, kind: 'uninstall' });
return publicInstallation(snapshot);
};
@@ -181,6 +200,7 @@ export function createCodingPluginMarketplaceService(
return publicLibrary(snapshot, options.packageStore);
},
install: (pluginId) => install(pluginId, 'install'),
installBeta,
update: (pluginId) => install(pluginId, 'update'),
uninstall,
};