import type { MarketplaceResolveItem } from './account-plugin-cache'; import type { MarketplacePackageClientPort, PluginPackageStore } from './package-store'; const PLUGIN_ID_PATTERN = /^[a-z][a-z0-9.-]{0,127}$/u; const RELEASE_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u; const REQUEST_ID_PATTERN = /^[\x21-\x7e]{1,128}$/u; const SHA256_PATTERN = /^[a-f0-9]{64}$/u; export interface HostedAdmissionWorkerSnapshot { /** Main-issued identity for the logical worker operation. */ readonly requestId: string; /** Release frozen into this parent worker's effective snapshot. */ readonly pluginReleaseId?: string; } export interface MarketplaceHostedAdmissionInput { readonly pluginId: string; readonly workerSnapshot: HostedAdmissionWorkerSnapshot; } export interface MarketplaceHostedAdmission { readonly releaseId: string; readonly releaseAdmissionId: string; } export type MarketplaceHostedAdmissionErrorCode = | 'plugin_release_unavailable' | 'plugin_runtime_stale' | 'plugin_account_changed' | 'plugin_backend_unavailable'; export class MarketplaceHostedAdmissionError extends Error { constructor( readonly code: MarketplaceHostedAdmissionErrorCode, readonly status: number, readonly retryable: boolean, message: string, ) { super(message); this.name = 'MarketplaceHostedAdmissionError'; } } export interface MarketplaceHostedAdmissionResolverOptions { readonly packageStore: Pick; readonly marketplace: Pick; readonly makeloreVersion: string; readonly bundledReleases?: Readonly>; } export interface BundledHostedRelease { readonly releaseId: string; readonly version: string; readonly channel: 'stable'; } function isRecord(value: unknown): value is Record { return value !== null && typeof value === 'object' && !Array.isArray(value); } function errorCode(value: unknown): unknown { return isRecord(value) ? value.code : undefined; } function releaseId(value: unknown): string | null { return typeof value === 'string' && RELEASE_ID_PATTERN.test(value) ? value : null; } function pluginId(value: unknown): string | null { return typeof value === 'string' && PLUGIN_ID_PATTERN.test(value) ? value : null; } function requestId(value: unknown): string | null { return typeof value === 'string' && REQUEST_ID_PATTERN.test(value) ? value : null; } function stale(message: string): MarketplaceHostedAdmissionError { return new MarketplaceHostedAdmissionError('plugin_runtime_stale', 409, false, message); } function unavailable(message: string): MarketplaceHostedAdmissionError { return new MarketplaceHostedAdmissionError('plugin_release_unavailable', 409, false, message); } function backendUnavailable(): MarketplaceHostedAdmissionError { return new MarketplaceHostedAdmissionError( 'plugin_backend_unavailable', 503, true, 'Hosted Plugin admission service is temporarily unavailable', ); } function accountChanged(): MarketplaceHostedAdmissionError { return new MarketplaceHostedAdmissionError( 'plugin_account_changed', 409, false, 'Marketplace account changed while resolving hosted Plugin admission', ); } function matchesFrozenRelease( item: MarketplaceResolveItem, installed: Awaited>, plugin: string, ): item is MarketplaceResolveItem & { readonly releaseId: string; readonly releaseAdmissionId: string; } { if (!installed) return false; if (item.pluginId !== plugin || (item.action !== 'keep' && item.action !== 'install')) return false; if (releaseId(item.releaseId) !== installed.releaseId || releaseId(item.releaseAdmissionId) === null || item.releaseAdmissionId === undefined || item.releaseAdmissionId === null) return false; if (item.version !== installed.version || item.sha256 !== installed.sha256) return false; if (item.sizeBytes !== installed.sizeBytes || item.channel !== installed.channel) return false; 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 * concerns here; provider, payload, billing, and transport routes remain * outside this boundary. */ export class MarketplaceHostedAdmissionResolver { constructor(private readonly options: MarketplaceHostedAdmissionResolverOptions) {} async resolve(input: MarketplaceHostedAdmissionInput): Promise { const plugin = pluginId(input?.pluginId); const worker = input?.workerSnapshot; const request = requestId(worker?.requestId); const frozenRelease = releaseId(worker?.pluginReleaseId); if (!plugin || !request) throw unavailable('Hosted Plugin worker identity is unavailable'); if (!frozenRelease) throw unavailable('Hosted Plugin worker Release is unavailable'); const bundled = this.options.bundledReleases?.[plugin]; let installed: Awaited> = 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; try { resolved = await this.options.marketplace.resolve({ resolveRequestId: request, makeloreVersion: this.options.makeloreVersion, channel: bundled?.channel ?? installed?.channel ?? 'stable', installed: bundled ? [] : [{ pluginId: installed!.pluginId, releaseId: installed!.releaseId, sha256: installed!.sha256, }], }); } catch (error) { throw this.mapError(error); } if (resolved.stale || resolved.resolveRequestId !== request) { throw stale('Hosted Plugin worker admission is stale'); } const item = resolved.items.find(({ pluginId: candidate }) => candidate === plugin); if (item?.action === 'unavailable') { throw unavailable('Hosted Plugin Release is unavailable'); } 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({ releaseId: item.releaseId, releaseAdmissionId: item.releaseAdmissionId, }); } private mapError(error: unknown): MarketplaceHostedAdmissionError { if (error instanceof MarketplaceHostedAdmissionError) return error; const code = errorCode(error); if (code === 'marketplace_account_changed' || code === 'plugin_account_changed') return accountChanged(); return backendUnavailable(); } } export function createMarketplaceHostedAdmissionResolver( options: MarketplaceHostedAdmissionResolverOptions, ): MarketplaceHostedAdmissionResolver { return new MarketplaceHostedAdmissionResolver(options); }