feat: add plugin marketplace renderer
This commit is contained in:
@@ -88,13 +88,18 @@ export type PublicPluginInstallation = Readonly<{
|
||||
reason?: string;
|
||||
}>;
|
||||
|
||||
export type PublicPluginLibrary = Readonly<{
|
||||
library: MarketplaceLibrarySnapshot;
|
||||
installations: readonly PublicPluginInstallation[];
|
||||
}>;
|
||||
|
||||
/** Main-owned Marketplace facade. It never exposes package roots or manifests. */
|
||||
export interface CodingPluginMarketplaceService {
|
||||
readCatalog(input?: CatalogQuery): Promise<CatalogPage>;
|
||||
readDetail(pluginId: string): Promise<PluginDetail>;
|
||||
readLibrary(): Promise<MarketplaceLibrarySnapshot>;
|
||||
acquire(pluginId: string): Promise<MarketplaceLibrarySnapshot>;
|
||||
remove(pluginId: string): Promise<MarketplaceLibrarySnapshot>;
|
||||
readLibrary(): Promise<PublicPluginLibrary>;
|
||||
acquire(pluginId: string): Promise<PublicPluginLibrary>;
|
||||
remove(pluginId: string): Promise<PublicPluginLibrary>;
|
||||
install(pluginId: string): Promise<PublicPluginInstallation>;
|
||||
update(pluginId: string): Promise<PublicPluginInstallation>;
|
||||
uninstall(pluginId: string): Promise<PublicPluginInstallation>;
|
||||
@@ -120,6 +125,30 @@ function publicInstallation(snapshot: InstallationSnapshot): PublicPluginInstall
|
||||
};
|
||||
}
|
||||
|
||||
async function publicLibrary(
|
||||
library: MarketplaceLibrarySnapshot,
|
||||
packageStore: Pick<PluginPackageStore, 'readInstalledIndex'>,
|
||||
): 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',
|
||||
pluginId: record.pluginId,
|
||||
releaseId: record.releaseId,
|
||||
version: record.version,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
export function createCodingPluginMarketplaceService(
|
||||
options: CreateCodingPluginMarketplaceServiceOptions,
|
||||
): CodingPluginMarketplaceService {
|
||||
@@ -140,16 +169,16 @@ export function createCodingPluginMarketplaceService(
|
||||
return {
|
||||
readCatalog: (input = {}) => options.marketplace.readCatalog(input),
|
||||
readDetail: (pluginId) => options.marketplace.readDetail(pluginId),
|
||||
readLibrary: () => options.marketplace.readLibrary(),
|
||||
readLibrary: async () => publicLibrary(await options.marketplace.readLibrary(), options.packageStore),
|
||||
acquire: async (pluginId) => {
|
||||
const snapshot = await options.marketplace.acquire(pluginId);
|
||||
await options.onChanged?.({ pluginId, kind: 'acquire' });
|
||||
return snapshot;
|
||||
return publicLibrary(snapshot, options.packageStore);
|
||||
},
|
||||
remove: async (pluginId) => {
|
||||
const snapshot = await options.marketplace.remove(pluginId);
|
||||
await options.onChanged?.({ pluginId, kind: 'remove' });
|
||||
return snapshot;
|
||||
return publicLibrary(snapshot, options.packageStore);
|
||||
},
|
||||
install: (pluginId) => install(pluginId, 'install'),
|
||||
update: (pluginId) => install(pluginId, 'update'),
|
||||
@@ -185,6 +214,7 @@ export interface CodingPluginProjectProjection {
|
||||
durableProjectId: string | null;
|
||||
};
|
||||
policyStatus: PluginPolicyAvailability;
|
||||
unknownPluginIds: string[];
|
||||
items: Array<{
|
||||
id: string;
|
||||
version: string;
|
||||
@@ -470,6 +500,9 @@ export function createCodingProjectPluginService(
|
||||
schemaVersion: 1,
|
||||
project: { localProjectId: localProject.id, durableProjectId },
|
||||
policyStatus: policy.status,
|
||||
unknownPluginIds: [...new Set(selection.filter((id) => (
|
||||
!pluginDefinitions.some((definition) => definition.id === id)
|
||||
)))].sort(),
|
||||
items,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user