/** * Web Manifest Source * * Fetches plugin information from custom JSON manifest files * Used for self-hosted plugin repositories — the answer for self-built, * private, and off-market plugins (owner libs/forks, raw files like * zrips.net/cmii) that no store API will ever cover. * * ## Identifier contract (Phase 3 W1b) * * `getPluginInfo` / `getLatestVersion` accept a composite identifier * `|` (see `parseWebIdentifier` in * core/types/plugin.ts) so each plugin can point at its own manifest via * `plugin.sourceUrl` — `getSourceIdentifier` emits the composite form. A bare * plugin name falls back to the instance's own `manifestUrl` (a sources.json * web entry's `url`), which may be empty when the instance acts purely as a * composite-identifier resolver. */ import { z } from 'zod'; import type { PluginInfo, PluginSourceType } from '../types/index.js'; import { BasePluginSource } from './base.js'; /** * Top-level manifest schema. Exported for the `pluginator manifest` * authoring/validation CLI (cli-manifest-helpers.ts) so scaffolded manifests * are checked against EXACTLY what the source will accept at fetch time. */ export declare const WebManifestSchema: z.ZodObject<{ $schema: z.ZodOptional; version: z.ZodString; name: z.ZodString; description: z.ZodOptional; lastUpdated: z.ZodString; plugins: z.ZodArray; author: z.ZodOptional; minecraftVersion: z.ZodOptional; minecraftVersions: z.ZodOptional>; dependencies: z.ZodOptional>; downloadUrl: z.ZodString; checksums: z.ZodOptional; sha1: z.ZodOptional; md5: z.ZodOptional; }, "strip", z.ZodTypeAny, { sha256?: string | undefined; md5?: string | undefined; sha1?: string | undefined; }, { sha256?: string | undefined; md5?: string | undefined; sha1?: string | undefined; }>>; releaseDate: z.ZodOptional; tags: z.ZodOptional>; license: z.ZodOptional; fileSize: z.ZodOptional; changelog: z.ZodOptional; }, "strip", z.ZodTypeAny, { name: string; version: string; downloadUrl: string; description?: string | undefined; author?: string | undefined; minecraftVersion?: string | undefined; minecraftVersions?: string[] | undefined; dependencies?: string[] | undefined; tags?: string[] | undefined; releaseDate?: string | undefined; changelog?: string | undefined; license?: string | undefined; fileSize?: number | undefined; checksums?: { sha256?: string | undefined; md5?: string | undefined; sha1?: string | undefined; } | undefined; }, { name: string; version: string; downloadUrl: string; description?: string | undefined; author?: string | undefined; minecraftVersion?: string | undefined; minecraftVersions?: string[] | undefined; dependencies?: string[] | undefined; tags?: string[] | undefined; releaseDate?: string | undefined; changelog?: string | undefined; license?: string | undefined; fileSize?: number | undefined; checksums?: { sha256?: string | undefined; md5?: string | undefined; sha1?: string | undefined; } | undefined; }>, "many">; }, "strip", z.ZodTypeAny, { name: string; version: string; lastUpdated: string; plugins: { name: string; version: string; downloadUrl: string; description?: string | undefined; author?: string | undefined; minecraftVersion?: string | undefined; minecraftVersions?: string[] | undefined; dependencies?: string[] | undefined; tags?: string[] | undefined; releaseDate?: string | undefined; changelog?: string | undefined; license?: string | undefined; fileSize?: number | undefined; checksums?: { sha256?: string | undefined; md5?: string | undefined; sha1?: string | undefined; } | undefined; }[]; description?: string | undefined; $schema?: string | undefined; }, { name: string; version: string; lastUpdated: string; plugins: { name: string; version: string; downloadUrl: string; description?: string | undefined; author?: string | undefined; minecraftVersion?: string | undefined; minecraftVersions?: string[] | undefined; dependencies?: string[] | undefined; tags?: string[] | undefined; releaseDate?: string | undefined; changelog?: string | undefined; license?: string | undefined; fileSize?: number | undefined; checksums?: { sha256?: string | undefined; md5?: string | undefined; sha1?: string | undefined; } | undefined; }[]; description?: string | undefined; $schema?: string | undefined; }>; export type WebManifest = z.infer; /** * WebManifestSource implementation */ export declare class WebManifestSource extends BasePluginSource { readonly id: string; readonly name: string; readonly type: PluginSourceType; private manifestUrl; private manifestCache; private cacheExpiry; /** * @param manifestUrl Default manifest for bare-name identifiers. May be '' * (resolver mode): the instance then only serves composite * `|` identifiers — how the source factory * registers it, since per-plugin manifests need no source-level URL. */ constructor(id: string, name: string, manifestUrl?: string, cacheTtlSeconds?: number); /** * Get plugin info by identifier: either a composite * `|` (per-plugin manifest from * `plugin.sourceUrl`) or a bare plugin name resolved against this * instance's default manifest URL. See the module doc for the contract. */ getPluginInfo(identifier: string): Promise; /** * Search for plugins in the manifest */ searchPlugins(query: string, limit?: number): Promise; /** * Get latest version for a plugin. Accepts the same composite or bare * identifier as {@link getPluginInfo}. */ getLatestVersion(identifier: string): Promise; /** * Get all plugins from the manifest */ listPlugins(): Promise; /** * Get the manifest URL */ getManifestUrl(): string; /** * Set a new manifest URL */ setManifestUrl(url: string): void; /** * Load and cache a manifest, keyed per URL (one instance can serve many * per-plugin manifests via composite identifiers). Strictly validated * against `WebManifestSchema` (Phase 3 audit P0 #4 / LOW): caps string * lengths, plugin counts, and checksum sizes to prevent crafted manifests * from corrupting UI or exhausting memory. SSRF guard: `fetchJson` * (BasePluginSource) runs `validateExternalUrl` on every URL BEFORE * fetching — composite-identifier URLs are user-supplied and blocked * here if they target private/internal addresses. */ private loadManifest; /** * Parse manifest plugin into PluginInfo */ private parsePlugin; } //# sourceMappingURL=web-manifest.d.ts.map