fix(plugins): load official hosted plugins from bundled resources

This commit is contained in:
2026-09-01 18:20:24 +08:00
parent 52e2a97a12
commit 1530ac7740
23 changed files with 835 additions and 48 deletions

View File

@@ -45,6 +45,13 @@ export interface MarketplaceHostedAdmissionResolverOptions {
readonly packageStore: Pick<PluginPackageStore, 'getInstalledRelease'>;
readonly marketplace: Pick<MarketplacePackageClientPort, 'resolve'>;
readonly makeloreVersion: string;
readonly bundledReleases?: Readonly<Record<string, BundledHostedRelease>>;
}
export interface BundledHostedRelease {
readonly releaseId: string;
readonly version: string;
readonly channel: 'stable';
}
function isRecord(value: unknown): value is Record<string, unknown> {
@@ -112,6 +119,24 @@ function matchesFrozenRelease(
return item.sha256 !== null && item.sha256 !== undefined && SHA256_PATTERN.test(item.sha256);
}
function matchesBundledFrozenRelease(
item: MarketplaceResolveItem,
bundled: BundledHostedRelease,
plugin: string,
): item is MarketplaceResolveItem & {
readonly releaseId: string;
readonly releaseAdmissionId: string;
} {
return item.pluginId === plugin
&& item.action === 'keep'
&& releaseId(item.releaseId) === bundled.releaseId
&& item.version === bundled.version
&& item.channel === bundled.channel
&& releaseId(item.releaseAdmissionId) !== null
&& item.sha256 == null
&& item.sizeBytes == null;
}
/**
* Resolves the current account admission for the exact Release frozen into a
* parent worker. Marketplace identity and Release freshness are the only
@@ -129,15 +154,22 @@ export class MarketplaceHostedAdmissionResolver {
if (!plugin || !request) throw unavailable('Hosted Plugin worker identity is unavailable');
if (!frozenRelease) throw unavailable('Hosted Plugin worker Release is unavailable');
let installed: Awaited<ReturnType<PluginPackageStore['getInstalledRelease']>>;
try {
installed = await this.options.packageStore.getInstalledRelease(plugin, frozenRelease);
} catch (error) {
throw this.mapError(error);
}
if (!installed || installed.pluginId !== plugin || installed.releaseId !== frozenRelease
|| installed.unavailableReason || !installed.channel) {
throw unavailable('Installed hosted Plugin Release is unavailable');
const bundled = this.options.bundledReleases?.[plugin];
let installed: Awaited<ReturnType<PluginPackageStore['getInstalledRelease']>> = null;
if (bundled) {
if (releaseId(bundled.releaseId) !== frozenRelease || bundled.channel !== 'stable') {
throw unavailable('Bundled hosted Plugin Release is unavailable');
}
} else {
try {
installed = await this.options.packageStore.getInstalledRelease(plugin, frozenRelease);
} catch (error) {
throw this.mapError(error);
}
if (!installed || installed.pluginId !== plugin || installed.releaseId !== frozenRelease
|| installed.unavailableReason || !installed.channel) {
throw unavailable('Installed hosted Plugin Release is unavailable');
}
}
let resolved;
@@ -145,11 +177,11 @@ export class MarketplaceHostedAdmissionResolver {
resolved = await this.options.marketplace.resolve({
resolveRequestId: request,
makeloreVersion: this.options.makeloreVersion,
channel: installed.channel,
installed: [{
pluginId: installed.pluginId,
releaseId: installed.releaseId,
sha256: installed.sha256,
channel: bundled?.channel ?? installed?.channel ?? 'stable',
installed: bundled ? [] : [{
pluginId: installed!.pluginId,
releaseId: installed!.releaseId,
sha256: installed!.sha256,
}],
});
} catch (error) {
@@ -160,7 +192,10 @@ export class MarketplaceHostedAdmissionResolver {
throw stale('Hosted Plugin worker admission is stale');
}
const item = resolved.items.find(({ pluginId: candidate }) => candidate === plugin);
if (!item || !matchesFrozenRelease(item, installed, plugin)) {
const matches = item && (bundled
? matchesBundledFrozenRelease(item, bundled, plugin)
: matchesFrozenRelease(item, installed, plugin));
if (!matches) {
throw stale('Hosted Plugin worker Release admission is stale');
}
return Object.freeze({