@epicdm/flowstate-extension-core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +1972 -0
- package/dist/index.d.ts +1972 -0
- package/dist/index.js +1042 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1012 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/manifest-adapter.ts","../src/vsix-scanner.ts","../src/compatibility-scorer.ts","../src/dependency-resolver.ts","../src/openvsx-client.ts","../src/federation-client.ts"],"names":["unzipSync"],"mappings":"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","file":"index.js","sourcesContent":["// Copyright 2026 Epic Digital Interactive Media LLC\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Manifest adapter for bidirectional translation between VS Code and FlowState formats.\n *\n * - `vsCodeToFlowState()` — converts VS Code `package.json` → `FlowStateManifest`\n * - `flowStateToVsCode()` — converts `FlowStateManifest` → `Partial<VSCodeExtensionManifest>`\n *\n * Both functions are pure, deterministic, and side-effect free.\n */\n\nimport type {\n ExtensionCategory,\n VSCodeContributes,\n VSCodeExtensionManifest,\n} from './types/vscode-manifest'\nimport type { FlowStateManifest } from './types/installed-extension'\n\n// ---------------------------------------------------------------------------\n// Category mapping\n// ---------------------------------------------------------------------------\n\n/**\n * Maps VS Code marketplace categories to kebab-case FlowState categories.\n */\nconst CATEGORY_MAP: Record<string, string> = {\n 'Azure': 'azure',\n 'Data Science': 'data-science',\n 'Debuggers': 'debuggers',\n 'Education': 'education',\n 'Extension Packs': 'extension-packs',\n 'Formatters': 'formatters',\n 'Keymaps': 'keymaps',\n 'Language Packs': 'language-packs',\n 'Linters': 'linters',\n 'Machine Learning': 'machine-learning',\n 'Notebooks': 'notebooks',\n 'Other': 'other',\n 'Programming Languages': 'programming-languages',\n 'SCM Providers': 'scm-providers',\n 'Snippets': 'snippets',\n 'Testing': 'testing',\n 'Themes': 'themes',\n 'Visualization': 'visualization',\n}\n\n/**\n * Map a VS Code marketplace category to its FlowState equivalent.\n *\n * @param vsCodeCategory - The VS Code category string (e.g., `'Programming Languages'`)\n * @returns The kebab-case FlowState category, or `undefined` if unmapped\n */\nexport function mapCategory(vsCodeCategory: string | undefined): string | undefined {\n if (vsCodeCategory === undefined) return undefined\n return CATEGORY_MAP[vsCodeCategory]\n}\n\n// ---------------------------------------------------------------------------\n// Activation event mapping\n// ---------------------------------------------------------------------------\n\n/**\n * Map VS Code activation events to FlowState activation events.\n *\n * Most events pass through as-is. The notable mapping is:\n * - `onStartupFinished` → `onStartup`\n *\n * @param manifest - The VS Code extension manifest\n * @returns Array of FlowState activation event strings\n */\nexport function mapActivationEvents(manifest: VSCodeExtensionManifest): string[] {\n const events = manifest.activationEvents\n if (!events || events.length === 0) return []\n\n return events.map((event) => {\n if (event === 'onStartupFinished') return 'onStartup'\n return event\n })\n}\n\n// ---------------------------------------------------------------------------\n// Extension kind mapping\n// ---------------------------------------------------------------------------\n\n/**\n * Infer the FlowState extension type from a VS Code manifest.\n *\n * Uses the following heuristics:\n * 1. If the extension only contributes `themes`, `iconThemes`, or `productIconThemes` → `'theme'`\n * 2. If the extension contributes `localizations` → `'pack'` (language pack)\n * 3. If `extensionKind` includes `'workspace'` → `'app'`\n * 4. Default → `'ui-extension'`\n *\n * @param manifest - The VS Code extension manifest\n * @returns The FlowState extension type string\n */\nexport function mapExtensionKind(manifest: VSCodeExtensionManifest): string {\n const contributes = manifest.contributes\n\n if (contributes) {\n // Check for theme-only extensions\n const contributionKeys = Object.keys(contributes).filter(\n (key) => contributes[key as keyof typeof contributes] !== undefined\n )\n\n const themeKeys = new Set(['themes', 'iconThemes', 'productIconThemes', 'colors'])\n const isThemeOnly =\n contributionKeys.length > 0 && contributionKeys.every((key) => themeKeys.has(key))\n\n if (isThemeOnly) return 'theme'\n\n // Check for language pack extensions\n if (contributes.localizations && contributes.localizations.length > 0) {\n return 'pack'\n }\n }\n\n // Check extensionKind\n if (manifest.extensionKind?.includes('workspace')) {\n return 'app'\n }\n\n return 'ui-extension'\n}\n\n// ---------------------------------------------------------------------------\n// Main adapter function\n// ---------------------------------------------------------------------------\n\n/**\n * Translate a VS Code extension manifest to a FlowState manifest.\n *\n * This is a pure function that maps VS Code `package.json` fields to the\n * equivalent FlowState `FlowStateManifest` shape. The translation is:\n *\n * - **Lossless** for declarative fields (themes, snippets, grammars, etc.)\n * - **Deterministic** — same input always produces same output\n * - **Side-effect free** — no I/O, no mutations\n *\n * @param manifest - A VS Code extension package.json parsed as `VSCodeExtensionManifest`\n * @returns A `FlowStateManifest` suitable for FlowState's extension system\n *\n * @example\n * ```typescript\n * const vsCodeManifest: VSCodeExtensionManifest = {\n * name: 'prettier-vscode',\n * publisher: 'esbenp',\n * version: '10.1.0',\n * engines: { vscode: '^1.80.0' },\n * main: './dist/extension.js',\n * };\n *\n * const flowstateManifest = vsCodeToFlowState(vsCodeManifest);\n * // { id: 'esbenp.prettier-vscode', displayName: 'prettier-vscode', ... }\n * ```\n */\nexport function vsCodeToFlowState(manifest: VSCodeExtensionManifest): FlowStateManifest {\n const displayName =\n typeof manifest.displayName === 'string'\n ? manifest.displayName\n : manifest.displayName?.value ?? manifest.name\n\n const result: FlowStateManifest = {\n id: `${manifest.publisher}.${manifest.name}`,\n displayName,\n version: manifest.version,\n publisher: manifest.publisher,\n main: manifest.main ?? manifest.browser ?? '',\n }\n\n if (manifest.browser !== undefined) {\n result.browser = manifest.browser\n }\n\n const category = mapCategory(manifest.categories?.[0])\n if (category !== undefined) {\n result.category = category\n }\n\n const extensionType = mapExtensionKind(manifest)\n if (extensionType !== 'ui-extension') {\n result.extensionType = extensionType\n }\n\n const activationEvents = mapActivationEvents(manifest)\n if (activationEvents.length > 0) {\n result.activationEvents = activationEvents\n }\n\n if (manifest.contributes !== undefined) {\n result.contributes = manifest.contributes as Record<string, unknown>\n }\n\n return result\n}\n\n// ---------------------------------------------------------------------------\n// Reverse mapping: FlowState → VS Code\n// ---------------------------------------------------------------------------\n\n/**\n * Reverse lookup from kebab-case FlowState categories to VS Code Title Case.\n */\nconst REVERSE_CATEGORY_MAP: Record<string, string> = Object.fromEntries(\n Object.entries(CATEGORY_MAP).map(([vsCode, flowstate]) => [flowstate, vsCode])\n)\n\n/**\n * Map a FlowState category back to its VS Code marketplace equivalent.\n *\n * @param flowstateCategory - The kebab-case FlowState category (e.g., `'programming-languages'`)\n * @returns The VS Code Title Case category, or `undefined` if unmapped\n */\nexport function reverseCategory(flowstateCategory: string | undefined): string | undefined {\n if (flowstateCategory === undefined) return undefined\n return REVERSE_CATEGORY_MAP[flowstateCategory]\n}\n\n/**\n * Reverse map FlowState activation events back to VS Code format.\n *\n * - `onStartup` → `onStartupFinished`\n * - All other events pass through as-is\n *\n * @param events - FlowState activation event strings\n * @returns Array of VS Code activation event strings\n */\nexport function reverseActivationEvents(events: string[] | undefined): string[] {\n if (!events || events.length === 0) return []\n\n return events.map((event) => {\n if (event === 'onStartup') return 'onStartupFinished'\n return event\n })\n}\n\n/**\n * Map a FlowState extension type back to VS Code `extensionKind`.\n *\n * - `'app'` → `['workspace']`\n * - `'theme'` → `['ui']`\n * - `'pack'` → `['ui']`\n * - `'ui-extension'` or `undefined` → `undefined` (VS Code default)\n *\n * @param extensionType - The FlowState extension type\n * @returns VS Code `extensionKind` array, or `undefined` for default\n */\nexport function reverseExtensionKind(\n extensionType: string | undefined\n): Array<'ui' | 'workspace'> | undefined {\n switch (extensionType) {\n case 'app':\n return ['workspace']\n case 'theme':\n case 'pack':\n return ['ui']\n default:\n return undefined\n }\n}\n\n/**\n * Translate a FlowState manifest back to a VS Code extension manifest.\n *\n * This is a pure function that maps `FlowStateManifest` fields to the\n * equivalent VS Code `package.json` shape. The result is `Partial` because\n * some required VS Code fields (like `engines.vscode`) cannot be inferred\n * from a FlowState manifest alone.\n *\n * FlowState-specific metadata is stored under the `flowstate` key in the\n * output for round-trip preservation.\n *\n * @param manifest - A FlowState manifest\n * @returns A partial VS Code extension manifest suitable for cross-publishing\n *\n * @example\n * ```typescript\n * const fsManifest: FlowStateManifest = {\n * id: 'esbenp.prettier-vscode',\n * displayName: 'Prettier',\n * version: '10.1.0',\n * main: './dist/extension.js',\n * };\n *\n * const vsCodeManifest = flowStateToVsCode(fsManifest);\n * // { name: 'prettier-vscode', publisher: 'esbenp', version: '10.1.0', ... }\n * ```\n */\nexport function flowStateToVsCode(\n manifest: FlowStateManifest\n): Partial<VSCodeExtensionManifest> {\n // Split id into publisher and name\n const dotIndex = manifest.id.indexOf('.')\n const name = dotIndex >= 0 ? manifest.id.slice(dotIndex + 1) : manifest.id\n const publisher = manifest.publisher ?? (dotIndex >= 0 ? manifest.id.slice(0, dotIndex) : '')\n\n const result: Partial<VSCodeExtensionManifest> = {\n name,\n publisher,\n version: manifest.version,\n displayName: manifest.displayName,\n }\n\n if (manifest.main) {\n result.main = manifest.main\n }\n\n if (manifest.browser !== undefined) {\n result.browser = manifest.browser\n }\n\n const vsCodeCategory = reverseCategory(manifest.category)\n if (vsCodeCategory !== undefined) {\n result.categories = [vsCodeCategory as ExtensionCategory]\n }\n\n const extensionKind = reverseExtensionKind(manifest.extensionType)\n if (extensionKind !== undefined) {\n result.extensionKind = extensionKind\n }\n\n const activationEvents = reverseActivationEvents(manifest.activationEvents)\n if (activationEvents.length > 0) {\n result.activationEvents = activationEvents\n }\n\n if (manifest.contributes !== undefined) {\n result.contributes = manifest.contributes as VSCodeContributes\n }\n\n return result\n}\n","// Copyright 2026 Epic Digital Interactive Media LLC\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * VSIX scanner — unpacks VS Code extension archives, extracts and validates\n * manifests, classifies extensions, and detects API namespace usage.\n *\n * Uses `fflate` for cross-platform ZIP decompression (browser + Node.js).\n */\n\nimport { unzipSync } from 'fflate'\nimport type { VSCodeExtensionManifest } from './types/vscode-manifest'\nimport type { CompatibilityReport, VsixScanResult } from './types/installed-extension'\nimport { vsCodeToFlowState } from './manifest-adapter'\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Contribution point keys that are purely declarative (no runtime code needed).\n *\n * Extensions using only these contribution points can run in FlowState without\n * a VS Code extension host.\n */\nexport const DECLARATIVE_CONTRIBUTION_POINTS = new Set([\n 'themes',\n 'iconThemes',\n 'productIconThemes',\n 'colors',\n 'grammars',\n 'snippets',\n 'languages',\n 'keybindings',\n 'configuration',\n 'configurationDefaults',\n 'jsonValidation',\n 'localizations',\n 'semanticTokenTypes',\n 'semanticTokenModifiers',\n 'semanticTokenScopes',\n])\n\n// ---------------------------------------------------------------------------\n// Error types\n// ---------------------------------------------------------------------------\n\n/** Error codes for VSIX scanning failures. */\nexport type VsixScanErrorCode = 'INVALID_ZIP' | 'MISSING_MANIFEST' | 'INVALID_MANIFEST'\n\n/**\n * Typed error thrown by the VSIX scanner.\n */\nexport class VsixScanError extends Error {\n readonly code: VsixScanErrorCode\n\n constructor(code: VsixScanErrorCode, message: string) {\n super(message)\n Object.setPrototypeOf(this, VsixScanError.prototype)\n this.name = 'VsixScanError'\n this.code = code\n }\n}\n\n// ---------------------------------------------------------------------------\n// Classification helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Determine whether an extension uses only declarative contribution points.\n *\n * An extension is declarative if:\n * 1. It has no `main` or `browser` entry point\n * 2. All of its contribution point keys are in the declarative set\n *\n * @param manifest - The VS Code extension manifest\n * @returns `true` if the extension is purely declarative\n */\nexport function classifyDeclarative(manifest: VSCodeExtensionManifest): boolean {\n // Extensions with entry points always require runtime\n if (manifest.main || manifest.browser) return false\n\n const contributes = manifest.contributes\n if (!contributes) return true\n\n const keys = Object.keys(contributes).filter(\n (key) => contributes[key as keyof typeof contributes] !== undefined\n )\n\n if (keys.length === 0) return true\n\n return keys.every((key) => DECLARATIVE_CONTRIBUTION_POINTS.has(key))\n}\n\n/**\n * Enumerate all active contribution point keys from a manifest.\n *\n * @param manifest - The VS Code extension manifest\n * @returns Sorted array of contribution point keys with non-empty values\n */\nexport function enumerateContributionPoints(manifest: VSCodeExtensionManifest): string[] {\n const contributes = manifest.contributes\n if (!contributes) return []\n\n return Object.keys(contributes)\n .filter((key) => {\n const value = contributes[key as keyof typeof contributes]\n if (value === undefined || value === null) return false\n if (Array.isArray(value) && value.length === 0) return false\n if (typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0)\n return false\n return true\n })\n .sort()\n}\n\n// ---------------------------------------------------------------------------\n// API namespace detection\n// ---------------------------------------------------------------------------\n\nconst textDecoder = new TextDecoder()\n\n/**\n * Regex patterns for detecting VS Code API namespace access.\n *\n * Matches patterns like:\n * - `vscode.window`\n * - `vscode.workspace`\n * - `vscode.commands`\n */\nconst VSCODE_NAMESPACE_PATTERN = /\\bvscode\\.(\\w+)/g\n\n/**\n * Scan JS files in an asset map for VS Code API namespace usage.\n *\n * This is best-effort static analysis using regex matching, not a full parser.\n * It looks for `vscode.<namespace>` patterns in `.js` files.\n *\n * @param assets - Map of relative file paths to file contents\n * @returns Deduplicated, sorted array of `vscode.<namespace>` strings\n */\nexport function detectApiNamespaces(assets: Map<string, Uint8Array>): string[] {\n const namespaces = new Set<string>()\n\n for (const [path, content] of assets) {\n if (!/\\.[cm]?js$/.test(path)) continue\n\n const text = textDecoder.decode(content)\n let match: RegExpExecArray | null\n VSCODE_NAMESPACE_PATTERN.lastIndex = 0\n\n while ((match = VSCODE_NAMESPACE_PATTERN.exec(text)) !== null) {\n namespaces.add(`vscode.${match[1]}`)\n }\n }\n\n return Array.from(namespaces).sort()\n}\n\n// ---------------------------------------------------------------------------\n// Compatibility report builder\n// ---------------------------------------------------------------------------\n\n/**\n * Build a compatibility report from manifest analysis and API detection.\n *\n * @param manifest - The VS Code extension manifest\n * @param apiNamespaces - Detected API namespace strings\n * @returns A complete `CompatibilityReport`\n */\nexport function buildCompatibilityReport(\n manifest: VSCodeExtensionManifest,\n apiNamespaces: string[]\n): CompatibilityReport {\n const contributionKeys = enumerateContributionPoints(manifest)\n\n const supported = contributionKeys.filter((key) => DECLARATIVE_CONTRIBUTION_POINTS.has(key))\n const unsupported = contributionKeys.filter((key) => !DECLARATIVE_CONTRIBUTION_POINTS.has(key))\n\n const warnings: string[] = []\n\n if (manifest.main || manifest.browser) {\n warnings.push('Extension has a code entry point and requires an extension host to run.')\n }\n\n if (unsupported.length > 0) {\n warnings.push(\n `Unsupported contribution points: ${unsupported.join(', ')}. These require a VS Code extension host.`\n )\n }\n\n if (apiNamespaces.length > 0) {\n warnings.push(`Uses VS Code API namespaces: ${apiNamespaces.join(', ')}.`)\n }\n\n // Determine compatibility level:\n // 1. No entry points, no API usage, only declarative contributions → declarative-only\n // 2. Has some declarative contributions alongside runtime needs → partial\n // 3. Everything else (only runtime contributions, or nothing at all) → unsupported\n const hasEntryPoint = Boolean(manifest.main || manifest.browser)\n const needsRuntime = hasEntryPoint || apiNamespaces.length > 0 || unsupported.length > 0\n\n let level: CompatibilityReport['level']\n\n if (!needsRuntime && supported.length > 0) {\n level = 'declarative-only'\n } else if (needsRuntime && supported.length > 0) {\n level = 'partial'\n } else {\n level = 'unsupported'\n }\n\n return {\n level,\n supported,\n unsupported,\n apiNamespacesUsed: apiNamespaces,\n warnings,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Main scanner\n// ---------------------------------------------------------------------------\n\n/** Prefix for extension files within a VSIX archive. */\nconst EXTENSION_PREFIX = 'extension/'\n\n/**\n * Scan a VSIX archive and produce a complete scan result.\n *\n * @param data - The raw VSIX file contents as a `Uint8Array`\n * @returns A `VsixScanResult` with manifest, classification, and compatibility data\n *\n * @throws {VsixScanError} With code `'INVALID_ZIP'` if decompression fails\n * @throws {VsixScanError} With code `'MISSING_MANIFEST'` if `extension/package.json` not found\n * @throws {VsixScanError} With code `'INVALID_MANIFEST'` if manifest JSON is invalid or missing required fields\n *\n * @example\n * ```typescript\n * const vsixData = await fetch(vsixUrl).then(r => r.arrayBuffer());\n * const result = scanVsix(new Uint8Array(vsixData));\n * console.log(result.isDeclarative); // true for theme extensions\n * ```\n */\nexport function scanVsix(data: Uint8Array): VsixScanResult {\n // 1. Decompress the ZIP archive\n let entries: Record<string, Uint8Array>\n try {\n entries = unzipSync(data)\n } catch {\n throw new VsixScanError('INVALID_ZIP', 'Failed to decompress VSIX archive: invalid ZIP data.')\n }\n\n // 2. Build assets map from extension/ entries\n const assets = new Map<string, Uint8Array>()\n for (const [path, content] of Object.entries(entries)) {\n if (path.startsWith(EXTENSION_PREFIX)) {\n const relativePath = path.slice(EXTENSION_PREFIX.length)\n if (relativePath.length > 0) {\n assets.set(relativePath, content)\n }\n }\n }\n\n // 3. Extract manifest\n const manifestData = assets.get('package.json')\n if (!manifestData) {\n throw new VsixScanError(\n 'MISSING_MANIFEST',\n 'VSIX archive does not contain extension/package.json.'\n )\n }\n\n // 4. Parse manifest JSON\n let rawManifest: Record<string, unknown>\n try {\n rawManifest = JSON.parse(textDecoder.decode(manifestData)) as Record<string, unknown>\n } catch {\n throw new VsixScanError(\n 'INVALID_MANIFEST',\n 'Failed to parse extension/package.json: invalid JSON.'\n )\n }\n\n // 5. Validate required fields\n const engines = rawManifest['engines']\n if (\n typeof rawManifest['name'] !== 'string' ||\n typeof rawManifest['publisher'] !== 'string' ||\n typeof rawManifest['version'] !== 'string' ||\n typeof engines !== 'object' ||\n engines === null ||\n typeof (engines as Record<string, unknown>)['vscode'] !== 'string'\n ) {\n throw new VsixScanError(\n 'INVALID_MANIFEST',\n 'Extension manifest missing required fields: name, publisher, version, and engines.vscode are required.'\n )\n }\n\n // 6. Cast to typed manifest\n const vsCodeManifest = rawManifest as unknown as VSCodeExtensionManifest\n\n // 7. Translate to FlowState manifest\n const flowstateManifest = vsCodeToFlowState(vsCodeManifest)\n\n // 8-10. Classification, enumeration, and detection\n const isDeclarative = classifyDeclarative(vsCodeManifest)\n const contributionPoints = enumerateContributionPoints(vsCodeManifest)\n const apiNamespaces = detectApiNamespaces(assets)\n\n // 11. Compatibility report\n const compatibility = buildCompatibilityReport(vsCodeManifest, apiNamespaces)\n\n // 12. Return result\n return {\n vsCodeManifest,\n flowstateManifest,\n isDeclarative,\n contributionPoints,\n assets,\n compatibility,\n }\n}\n","// Copyright 2026 Epic Digital Interactive Media LLC\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Platform-aware compatibility scoring for VS Code extensions.\n *\n * Evaluates extensions against FlowState's supported capabilities per platform\n * (desktop, web, mobile) and produces a numeric score, compatibility level,\n * per-contribution-point breakdown, and actionable recommendations.\n */\n\nimport type { VSCodeExtensionManifest } from './types/vscode-manifest'\nimport type { CompatibilityLevel, CompatibilityReport } from './types/installed-extension'\nimport { enumerateContributionPoints, buildCompatibilityReport } from './vsix-scanner'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Target platform for compatibility evaluation. */\nexport type Platform = 'desktop' | 'web' | 'mobile'\n\n/** Support status for a contribution point on a given platform. */\nexport type SupportStatus = 'native' | 'polyfill' | 'partial' | 'unsupported'\n\n/** Compatibility score for a single contribution point. */\nexport interface ContributionPointScore {\n /** The contribution point key (e.g., `'themes'`, `'commands'`). */\n key: string\n /** Support status on the target platform. */\n status: SupportStatus\n /** Numeric weight derived from the support status (0–1). */\n weight: number\n}\n\n/** Complete compatibility score for an extension on a target platform. */\nexport interface CompatibilityScore {\n /** Numeric score from 0 to 100. */\n score: number\n /** Compatibility level derived from the numeric score. */\n level: CompatibilityLevel\n /** The platform this score was computed for. */\n platform: Platform\n /** Per-contribution-point breakdown. */\n breakdown: ContributionPointScore[]\n /** Base compatibility report from the scanner. */\n report: CompatibilityReport\n /** Actionable recommendations for improving compatibility. */\n recommendations: string[]\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Numeric weights for each support status.\n *\n * - `native` = 1.0 — FlowState handles this natively\n * - `polyfill` = 0.8 — Works via compatibility layer\n * - `partial` = 0.5 — Some features work\n * - `unsupported` = 0 — Cannot run\n */\nexport const SUPPORT_WEIGHTS: Record<SupportStatus, number> = {\n native: 1.0,\n polyfill: 0.8,\n partial: 0.5,\n unsupported: 0,\n}\n\n/**\n * Platform support matrix mapping each contribution point to its support\n * status per platform.\n *\n * Desktop (Tauri) supports the most contribution points.\n * Web (Next.js) supports declarative + some UI contributions.\n * Mobile supports only basic declarative contributions.\n */\nexport const PLATFORM_SUPPORT: Record<Platform, Record<string, SupportStatus>> = {\n desktop: {\n themes: 'native',\n iconThemes: 'native',\n productIconThemes: 'native',\n colors: 'native',\n grammars: 'native',\n snippets: 'native',\n languages: 'native',\n keybindings: 'native',\n configuration: 'native',\n configurationDefaults: 'native',\n jsonValidation: 'native',\n localizations: 'native',\n semanticTokenTypes: 'native',\n semanticTokenModifiers: 'native',\n semanticTokenScopes: 'native',\n commands: 'polyfill',\n menus: 'polyfill',\n views: 'partial',\n viewsContainers: 'partial',\n },\n web: {\n themes: 'native',\n iconThemes: 'native',\n productIconThemes: 'native',\n colors: 'native',\n grammars: 'native',\n snippets: 'native',\n languages: 'native',\n keybindings: 'native',\n configuration: 'native',\n configurationDefaults: 'native',\n jsonValidation: 'native',\n localizations: 'native',\n semanticTokenTypes: 'native',\n semanticTokenModifiers: 'native',\n semanticTokenScopes: 'native',\n },\n mobile: {\n themes: 'native',\n colors: 'native',\n snippets: 'native',\n languages: 'native',\n keybindings: 'partial',\n configuration: 'native',\n configurationDefaults: 'native',\n localizations: 'native',\n },\n}\n\n/** Platforms that have an extension host capable of running JS entry points. */\nconst PLATFORMS_WITH_EXTENSION_HOST = new Set<Platform>(['desktop'])\n\n/** Penalty multiplier applied when an extension has entry points on a platform without an extension host. */\nconst ENTRY_POINT_PENALTY = 0.5\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Returns the support matrix for a given platform.\n *\n * Contribution points not present in the matrix are considered `'unsupported'`.\n *\n * @param platform - The target platform\n * @returns Map of contribution point keys to their support status\n */\nexport function getPlatformSupport(platform: Platform): Record<string, SupportStatus> {\n return { ...PLATFORM_SUPPORT[platform] }\n}\n\n/**\n * Score a VS Code extension's compatibility with a target platform.\n *\n * @param manifest - The VS Code extension manifest\n * @param platform - The target platform to score against\n * @param apiNamespaces - Optional array of detected API namespace strings\n * @returns A complete `CompatibilityScore`\n */\nexport function scoreExtension(\n manifest: VSCodeExtensionManifest,\n platform: Platform,\n apiNamespaces: string[] = []\n): CompatibilityScore {\n // 1. Get contribution points from manifest\n const contributionKeys = enumerateContributionPoints(manifest)\n\n // 2. Build per-point breakdown\n const platformSupport = PLATFORM_SUPPORT[platform]\n const breakdown: ContributionPointScore[] = contributionKeys.map((key) => {\n const status: SupportStatus = platformSupport[key] ?? 'unsupported'\n return {\n key,\n status,\n weight: SUPPORT_WEIGHTS[status],\n }\n })\n\n // 3. Calculate weighted average score (0–100)\n let score: number\n if (breakdown.length === 0) {\n score = 0\n } else {\n const totalWeight = breakdown.reduce((sum, point) => sum + point.weight, 0)\n score = Math.round((totalWeight / breakdown.length) * 100)\n }\n\n // 4. Apply entry point penalty if platform lacks extension host\n const hasEntryPoint = Boolean(manifest.main || manifest.browser)\n if (hasEntryPoint && !PLATFORMS_WITH_EXTENSION_HOST.has(platform)) {\n score = Math.round(score * ENTRY_POINT_PENALTY)\n }\n\n // 5. Derive level from score\n const level = deriveLevel(score)\n\n // 6. Generate recommendations\n const recommendations = generateRecommendations(breakdown, manifest, platform)\n\n // 7. Build base report\n const report = buildCompatibilityReport(manifest, apiNamespaces)\n\n return {\n score,\n level,\n platform,\n breakdown,\n report,\n recommendations,\n }\n}\n\n/**\n * Generate actionable recommendations based on the scoring breakdown.\n *\n * @param breakdown - Per-contribution-point score breakdown\n * @param manifest - The VS Code extension manifest\n * @param platform - The target platform\n * @returns Array of recommendation strings\n */\nexport function generateRecommendations(\n breakdown: ContributionPointScore[],\n manifest: VSCodeExtensionManifest,\n platform: Platform\n): string[] {\n const recommendations: string[] = []\n\n const hasEntryPoint = Boolean(manifest.main || manifest.browser)\n const unsupportedPoints = breakdown.filter((p) => p.status === 'unsupported')\n const partialPoints = breakdown.filter((p) => p.status === 'partial')\n const allNative = breakdown.length > 0 && breakdown.every((p) => p.status === 'native')\n\n // Entry point warning for platforms without extension host\n if (hasEntryPoint && !PLATFORMS_WITH_EXTENSION_HOST.has(platform)) {\n recommendations.push(\n 'This extension requires an extension host — only declarative contributions will work on this platform.'\n )\n }\n\n // Suggest desktop for extensions with unsupported points\n if (unsupportedPoints.length > 0 && platform !== 'desktop') {\n const pointNames = unsupportedPoints.map((p) => p.key).join(', ')\n recommendations.push(\n `Consider using the desktop platform for full support of: ${pointNames}.`\n )\n }\n\n // Note partial support\n if (partialPoints.length > 0) {\n const pointNames = partialPoints.map((p) => p.key).join(', ')\n recommendations.push(\n `Partial support for: ${pointNames}. Some features may not work as expected.`\n )\n }\n\n // All-clear message — covers both pure declarative and extensions with entry points on platforms with an extension host\n if (allNative && (!hasEntryPoint || PLATFORMS_WITH_EXTENSION_HOST.has(platform))) {\n recommendations.push('All contribution points are natively supported on this platform.')\n }\n\n return recommendations\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Derive a compatibility level from a numeric score.\n *\n * - `score >= 90` → `'full'`\n * - `score >= 50` → `'partial'`\n * - `score > 0` → `'declarative-only'`\n * - `score === 0` → `'unsupported'`\n */\nfunction deriveLevel(score: number): CompatibilityLevel {\n if (score >= 90) return 'full'\n if (score >= 50) return 'partial'\n if (score > 0) return 'declarative-only'\n return 'unsupported'\n}\n","// Copyright 2026 Epic Digital Interactive Media LLC\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Extension dependency resolver — builds a dependency graph from VS Code\n * extension manifests and produces a topologically sorted installation order.\n *\n * Handles both `extensionDependencies` (hard dependencies) and `extensionPack`\n * (pack members). Detects circular dependencies using Kahn's algorithm.\n */\n\nimport type { VSCodeExtensionManifest } from './types/vscode-manifest'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** A node in the dependency graph representing a single extension. */\nexport interface ExtensionNode {\n /** Normalized `publisher.name` identifier. */\n id: string\n /** Hard dependency extension IDs. */\n extensionDependencies: string[]\n /** Pack member extension IDs. */\n extensionPack: string[]\n}\n\n/** A directed edge in the dependency graph. */\nexport interface DependencyEdge {\n /** The dependent extension (the one that requires the other). */\n from: string\n /** The dependency (the one that must be installed first). */\n to: string\n /** Edge type — `'dependency'` for hard deps, `'pack'` for pack members. */\n type: 'dependency' | 'pack'\n}\n\n/** The complete dependency graph structure. */\nexport interface DependencyGraph {\n /** All known extension nodes keyed by normalized ID. */\n nodes: Map<string, ExtensionNode>\n /** All directed edges in the graph. */\n edges: DependencyEdge[]\n /** Adjacency list: extension ID → set of IDs it depends on. */\n adjacency: Map<string, Set<string>>\n}\n\n/** Successful resolution with a sorted installation order. */\nexport interface DependencyResolutionSuccess {\n ok: true\n /** Extension IDs in topological order (install first → last). */\n order: string[]\n /** The underlying dependency graph. */\n graph: DependencyGraph\n}\n\n/** Failed resolution due to circular dependencies. */\nexport interface DependencyResolutionError {\n ok: false\n /** The type of error. */\n error: 'circular-dependency'\n /** Extension IDs involved in the cycle(s). */\n participants: string[]\n /** The underlying dependency graph. */\n graph: DependencyGraph\n}\n\n/** Result of dependency resolution — either success or error. */\nexport type DependencyResolution = DependencyResolutionSuccess | DependencyResolutionError\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize an extension ID for case-insensitive matching.\n *\n * VS Code marketplace treats extension IDs as case-insensitive.\n *\n * @param id - The extension ID (e.g., `'EsbenP.prettier-vscode'`)\n * @returns Lowercased ID (e.g., `'esbenp.prettier-vscode'`)\n */\nexport function normalizeExtensionId(id: string): string {\n return id.toLowerCase()\n}\n\n/**\n * Extract an `ExtensionNode` from a VS Code extension manifest.\n *\n * @param manifest - The VS Code extension manifest\n * @returns An `ExtensionNode` with normalized IDs\n */\nexport function extractDependencyNode(manifest: VSCodeExtensionManifest): ExtensionNode {\n const id = normalizeExtensionId(`${manifest.publisher}.${manifest.name}`)\n const extensionDependencies = (manifest.extensionDependencies ?? []).map(normalizeExtensionId)\n const extensionPack = (manifest.extensionPack ?? []).map(normalizeExtensionId)\n\n return { id, extensionDependencies, extensionPack }\n}\n\n/**\n * Build a dependency graph from an array of extension nodes.\n *\n * Dependencies that reference extensions not in the input set are added\n * as leaf nodes (no dependencies of their own).\n *\n * @param nodes - Array of extension nodes\n * @returns A complete `DependencyGraph`\n */\nexport function buildDependencyGraph(nodes: ExtensionNode[]): DependencyGraph {\n const nodeMap = new Map<string, ExtensionNode>()\n const edges: DependencyEdge[] = []\n const adjacency = new Map<string, Set<string>>()\n\n // Register all known nodes\n for (const node of nodes) {\n nodeMap.set(node.id, node)\n if (!adjacency.has(node.id)) {\n adjacency.set(node.id, new Set())\n }\n }\n\n // Build edges and discover unknown dependency nodes\n for (const node of nodes) {\n for (const dep of node.extensionDependencies) {\n edges.push({ from: node.id, to: dep, type: 'dependency' })\n adjacency.get(node.id)!.add(dep)\n\n // Ensure the dependency exists as a node (leaf if unknown)\n if (!nodeMap.has(dep)) {\n nodeMap.set(dep, { id: dep, extensionDependencies: [], extensionPack: [] })\n adjacency.set(dep, new Set())\n }\n }\n\n for (const member of node.extensionPack) {\n edges.push({ from: node.id, to: member, type: 'pack' })\n adjacency.get(node.id)!.add(member)\n\n // Ensure the pack member exists as a node (leaf if unknown)\n if (!nodeMap.has(member)) {\n nodeMap.set(member, { id: member, extensionDependencies: [], extensionPack: [] })\n adjacency.set(member, new Set())\n }\n }\n }\n\n return { nodes: nodeMap, edges, adjacency }\n}\n\n/**\n * Resolve dependencies and produce a topologically sorted installation order.\n *\n * Uses Kahn's algorithm (BFS-based topological sort) for deterministic ordering\n * and straightforward cycle detection. Extensions with no dependencies appear\n * first in the result.\n *\n * @param nodes - Array of extension nodes to resolve\n * @returns A `DependencyResolution` — either success with sorted order, or error with cycle participants\n */\nexport function resolveDependencies(nodes: ExtensionNode[]): DependencyResolution {\n const graph = buildDependencyGraph(nodes)\n\n if (graph.nodes.size === 0) {\n return { ok: true, order: [], graph }\n }\n\n // Build reverse adjacency: dependency → set of dependents\n // If A depends on B, reverseAdj maps B → {A}\n const reverseAdj = new Map<string, Set<string>>()\n for (const id of graph.nodes.keys()) {\n reverseAdj.set(id, new Set())\n }\n for (const [id, deps] of graph.adjacency) {\n for (const dep of deps) {\n reverseAdj.get(dep)!.add(id)\n }\n }\n\n // Kahn's algorithm: in-degree of each node = number of its dependencies\n const inDegree = new Map<string, number>()\n for (const [id, deps] of graph.adjacency) {\n inDegree.set(id, deps.size)\n }\n\n // Start with nodes that have no dependencies (in-degree 0)\n const queue: string[] = []\n for (const [id, degree] of inDegree) {\n if (degree === 0) {\n queue.push(id)\n }\n }\n queue.sort()\n\n const order: string[] = []\n let queueIdx = 0\n\n while (queueIdx < queue.length) {\n const current = queue[queueIdx++]!\n order.push(current)\n\n // Collect newly freed dependents, then batch-sort\n const freed: string[] = []\n for (const dependent of reverseAdj.get(current)!) {\n const newDegree = inDegree.get(dependent)! - 1\n inDegree.set(dependent, newDegree)\n if (newDegree === 0) {\n freed.push(dependent)\n }\n }\n if (freed.length > 0) {\n freed.sort()\n queue.push(...freed)\n }\n }\n\n // If not all nodes were visited, there are cycles\n if (order.length < graph.nodes.size) {\n const visited = new Set(order)\n const participants = Array.from(graph.nodes.keys())\n .filter((id) => !visited.has(id))\n .sort()\n\n return { ok: false, error: 'circular-dependency', participants, graph }\n }\n\n return { ok: true, order, graph }\n}\n","// Copyright 2026 Epic Digital Interactive Media LLC\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Typed client for the Open VSX Registry REST API.\n *\n * Provides typed methods for searching, querying, and fetching extension\n * metadata from Open VSX. Uses the global `fetch` API with an injectable\n * override for testing.\n *\n * @see https://open-vsx.org/api\n * @see https://github.com/eclipse/openvsx/wiki/Using-the-Registry-API\n */\n\nimport type {\n OpenVSXApiResult,\n OpenVSXExtension,\n OpenVSXNamespace,\n OpenVSXNamespaceDetails,\n OpenVSXQueryParams,\n OpenVSXQueryResult,\n OpenVSXReviewList,\n OpenVSXSearchParams,\n OpenVSXSearchResult,\n OpenVSXVersionReferencesResult,\n OpenVSXVersionsResult,\n} from './types/openvsx-api'\n\n// ---------------------------------------------------------------------------\n// Client options\n// ---------------------------------------------------------------------------\n\n/** Configuration options for the Open VSX client. */\nexport interface OpenVSXClientOptions {\n /** Base URL for the Open VSX API (default: `'https://open-vsx.org/api'`). */\n baseUrl?: string\n /** Custom `fetch` implementation (default: `globalThis.fetch`). */\n fetch?: typeof globalThis.fetch\n}\n\n// ---------------------------------------------------------------------------\n// Default configuration\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_BASE_URL = 'https://open-vsx.org/api'\n\n// ---------------------------------------------------------------------------\n// Client\n// ---------------------------------------------------------------------------\n\n/**\n * Typed client for the Open VSX Registry REST API.\n *\n * All methods return a discriminated union `OpenVSXApiResult<T>` — either\n * `{ ok: true, data: T }` on success or `{ ok: false, statusCode, error }`\n * on failure. No exceptions are thrown for API or network errors.\n *\n * @example\n * ```typescript\n * const client = new OpenVSXClient()\n * const result = await client.search({ query: 'python' })\n * if (result.ok) {\n * console.log(result.data.extensions)\n * }\n * ```\n */\nexport class OpenVSXClient {\n private readonly baseUrl: string\n private readonly fetch: typeof globalThis.fetch\n\n constructor(options?: OpenVSXClientOptions) {\n // Normalize base URL: strip trailing slash\n const raw = options?.baseUrl ?? DEFAULT_BASE_URL\n this.baseUrl = raw.endsWith('/') ? raw.slice(0, -1) : raw\n this.fetch = options?.fetch ?? globalThis.fetch\n }\n\n // -------------------------------------------------------------------------\n // Search & query\n // -------------------------------------------------------------------------\n\n /**\n * Search extensions by text query.\n *\n * @param params - Search parameters (query, category, sort, pagination)\n * @returns Paginated search results\n */\n async search(params?: OpenVSXSearchParams): Promise<OpenVSXApiResult<OpenVSXSearchResult>> {\n const queryParams: Record<string, string> = {}\n if (params) {\n if (params.query !== undefined) queryParams['query'] = params.query\n if (params.category !== undefined) queryParams['category'] = params.category\n if (params.targetPlatform !== undefined) queryParams['targetPlatform'] = params.targetPlatform\n if (params.size !== undefined) queryParams['size'] = String(params.size)\n if (params.offset !== undefined) queryParams['offset'] = String(params.offset)\n if (params.sortOrder !== undefined) queryParams['sortOrder'] = params.sortOrder\n if (params.sortBy !== undefined) queryParams['sortBy'] = params.sortBy\n if (params.includeAllVersions !== undefined)\n queryParams['includeAllVersions'] = String(params.includeAllVersions)\n }\n return this._get<OpenVSXSearchResult>('/-/search', queryParams)\n }\n\n /**\n * Query extensions with structured field matching.\n *\n * @param params - Query parameters (namespace, extension name, ID, UUID, etc.)\n * @returns Paginated query results with full extension metadata\n */\n async query(params?: OpenVSXQueryParams): Promise<OpenVSXApiResult<OpenVSXQueryResult>> {\n const queryParams: Record<string, string> = {}\n if (params) {\n if (params.namespaceName !== undefined) queryParams['namespaceName'] = params.namespaceName\n if (params.extensionName !== undefined) queryParams['extensionName'] = params.extensionName\n if (params.extensionVersion !== undefined)\n queryParams['extensionVersion'] = params.extensionVersion\n if (params.extensionId !== undefined) queryParams['extensionId'] = params.extensionId\n if (params.extensionUuid !== undefined) queryParams['extensionUuid'] = params.extensionUuid\n if (params.namespaceUuid !== undefined) queryParams['namespaceUuid'] = params.namespaceUuid\n if (params.includeAllVersions !== undefined)\n queryParams['includeAllVersions'] = String(params.includeAllVersions)\n if (params.targetPlatform !== undefined) queryParams['targetPlatform'] = params.targetPlatform\n if (params.size !== undefined) queryParams['size'] = String(params.size)\n if (params.offset !== undefined) queryParams['offset'] = String(params.offset)\n }\n return this._get<OpenVSXQueryResult>('/-/query', queryParams)\n }\n\n // -------------------------------------------------------------------------\n // Extension metadata\n // -------------------------------------------------------------------------\n\n /**\n * Get extension metadata (latest version or specific version).\n *\n * @param namespace - Publisher namespace (e.g., `'ms-python'`)\n * @param name - Extension name (e.g., `'python'`)\n * @param version - Specific version string (omit for latest)\n * @param targetPlatform - Target platform filter\n * @returns Full extension metadata\n */\n async getExtension(\n namespace: string,\n name: string,\n version?: string,\n targetPlatform?: string,\n ): Promise<OpenVSXApiResult<OpenVSXExtension>> {\n let path = `/${encodeURIComponent(namespace)}/${encodeURIComponent(name)}`\n if (targetPlatform) {\n path += `/${encodeURIComponent(targetPlatform)}`\n }\n if (version) {\n path += `/${encodeURIComponent(version)}`\n }\n return this._get<OpenVSXExtension>(path)\n }\n\n // -------------------------------------------------------------------------\n // Namespace\n // -------------------------------------------------------------------------\n\n /**\n * Get namespace information with extension listing.\n *\n * @param namespace - Namespace name (e.g., `'ms-python'`)\n * @returns Namespace with map of extension name → API URL\n */\n async getNamespace(namespace: string): Promise<OpenVSXApiResult<OpenVSXNamespace>> {\n return this._get<OpenVSXNamespace>(`/${encodeURIComponent(namespace)}`)\n }\n\n /**\n * Get namespace details including display name, social links, and extensions.\n *\n * @param namespace - Namespace name\n * @returns Namespace details with social links and extension summaries\n */\n async getNamespaceDetails(\n namespace: string,\n ): Promise<OpenVSXApiResult<OpenVSXNamespaceDetails>> {\n return this._get<OpenVSXNamespaceDetails>(`/${encodeURIComponent(namespace)}/details`)\n }\n\n // -------------------------------------------------------------------------\n // Versions\n // -------------------------------------------------------------------------\n\n /**\n * List extension versions with pagination.\n *\n * @param namespace - Publisher namespace\n * @param name - Extension name\n * @param params - Pagination and platform filter options\n * @returns Paginated version listing (version string → API URL)\n */\n async getVersions(\n namespace: string,\n name: string,\n params?: { size?: number; offset?: number; targetPlatform?: string },\n ): Promise<OpenVSXApiResult<OpenVSXVersionsResult>> {\n let path = `/${encodeURIComponent(namespace)}/${encodeURIComponent(name)}`\n if (params?.targetPlatform) {\n path += `/${encodeURIComponent(params.targetPlatform)}`\n }\n path += '/versions'\n\n const queryParams: Record<string, string> = {}\n if (params?.size !== undefined) queryParams['size'] = String(params.size)\n if (params?.offset !== undefined) queryParams['offset'] = String(params.offset)\n\n return this._get<OpenVSXVersionsResult>(path, queryParams)\n }\n\n /**\n * List version references with engine compatibility and file URLs.\n *\n * @param namespace - Publisher namespace\n * @param name - Extension name\n * @param params - Pagination and platform filter options\n * @returns Paginated version references\n */\n async getVersionReferences(\n namespace: string,\n name: string,\n params?: { size?: number; offset?: number; targetPlatform?: string },\n ): Promise<OpenVSXApiResult<OpenVSXVersionReferencesResult>> {\n let path = `/${encodeURIComponent(namespace)}/${encodeURIComponent(name)}`\n if (params?.targetPlatform) {\n path += `/${encodeURIComponent(params.targetPlatform)}`\n }\n path += '/version-references'\n\n const queryParams: Record<string, string> = {}\n if (params?.size !== undefined) queryParams['size'] = String(params.size)\n if (params?.offset !== undefined) queryParams['offset'] = String(params.offset)\n\n return this._get<OpenVSXVersionReferencesResult>(path, queryParams)\n }\n\n // -------------------------------------------------------------------------\n // Reviews\n // -------------------------------------------------------------------------\n\n /**\n * Get all reviews for an extension.\n *\n * @param namespace - Publisher namespace\n * @param name - Extension name\n * @returns Review list with all reviews (not paginated)\n */\n async getReviews(\n namespace: string,\n name: string,\n ): Promise<OpenVSXApiResult<OpenVSXReviewList>> {\n return this._get<OpenVSXReviewList>(\n `/${encodeURIComponent(namespace)}/${encodeURIComponent(name)}/reviews`,\n )\n }\n\n // -------------------------------------------------------------------------\n // URL builders (pure, no fetch)\n // -------------------------------------------------------------------------\n\n /**\n * Build a VSIX download URL for a specific extension version.\n *\n * This is a pure URL builder — no network request is made.\n *\n * @param namespace - Publisher namespace\n * @param name - Extension name\n * @param version - Version string\n * @param targetPlatform - Target platform (omit for universal)\n * @returns Full download URL\n */\n getDownloadUrl(\n namespace: string,\n name: string,\n version: string,\n targetPlatform?: string,\n ): string {\n let path = `/${encodeURIComponent(namespace)}/${encodeURIComponent(name)}`\n if (targetPlatform) {\n path += `/${encodeURIComponent(targetPlatform)}`\n }\n path += `/${encodeURIComponent(version)}/file/${encodeURIComponent(namespace)}.${encodeURIComponent(name)}-${encodeURIComponent(version)}.vsix`\n return `${this.baseUrl}${path}`\n }\n\n /**\n * Build a URL for accessing an extension file (README, icon, etc.).\n *\n * This is a pure URL builder — no network request is made.\n *\n * @param namespace - Publisher namespace\n * @param name - Extension name\n * @param version - Version string\n * @param filePath - Relative file path within the extension\n * @param targetPlatform - Target platform (omit for universal)\n * @returns Full file URL\n */\n resolveFileUrl(\n namespace: string,\n name: string,\n version: string,\n filePath: string,\n targetPlatform?: string,\n ): string {\n let path = `/${encodeURIComponent(namespace)}/${encodeURIComponent(name)}`\n if (targetPlatform) {\n path += `/${encodeURIComponent(targetPlatform)}`\n }\n const encodedFilePath = filePath.split('/').map(encodeURIComponent).join('/')\n path += `/${encodeURIComponent(version)}/file/${encodedFilePath}`\n return `${this.baseUrl}${path}`\n }\n\n // -------------------------------------------------------------------------\n // Private helpers\n // -------------------------------------------------------------------------\n\n /** Build a full URL with optional query parameters. */\n private _buildUrl(path: string, params?: Record<string, string>): string {\n const url = `${this.baseUrl}${path}`\n if (!params || Object.keys(params).length === 0) {\n return url\n }\n const searchParams = new URLSearchParams(params)\n return `${url}?${searchParams.toString()}`\n }\n\n /** Execute a GET request and return a typed result. */\n private async _get<T>(\n path: string,\n params?: Record<string, string>,\n ): Promise<OpenVSXApiResult<T>> {\n const url = this._buildUrl(path, params)\n\n let response: Response\n try {\n response = await this.fetch(url)\n } catch (err) {\n return {\n ok: false,\n statusCode: 0,\n error: err instanceof Error ? err.message : 'Network error',\n }\n }\n\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}`\n try {\n const body = (await response.json()) as Record<string, unknown>\n if (typeof body['error'] === 'string') {\n errorMessage = body['error']\n }\n } catch {\n // Non-JSON error response — use HTTP status\n }\n return { ok: false, statusCode: response.status, error: errorMessage }\n }\n\n let data: T\n try {\n data = (await response.json()) as T\n } catch {\n return { ok: false, statusCode: response.status, error: 'Invalid JSON response' }\n }\n\n return { ok: true, data }\n }\n}\n","// Copyright 2026 Epic Digital Interactive Media LLC\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Federation protocol client — mediates between FlowState and upstream\n * Open VSX registries with configurable mode, filters, and cache key\n * generation.\n *\n * Three federation modes:\n * - `proxy` — Forward unresolved requests to upstream Open VSX\n * - `mirror` — Pre-sync a subset of extensions (metadata only)\n * - `standalone` — No upstream calls; only local/FlowState registry\n *\n * Filters are applied client-side after fetching from upstream:\n * - `declarativeOnly` — Only pass through declarative extensions\n * - `allowedCategories` — Whitelist of extension categories\n * - `blockedPublishers` — Blacklist of publisher namespaces\n */\n\nimport { DECLARATIVE_CONTRIBUTION_POINTS } from './vsix-scanner'\nimport { OpenVSXClient } from './openvsx-client'\nimport type {\n OpenVSXApiResult,\n OpenVSXExtension,\n OpenVSXSearchEntry,\n OpenVSXSearchParams,\n} from './types/openvsx-api'\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Federation mode determining upstream behavior. */\nexport type FederationMode = 'proxy' | 'mirror' | 'standalone'\n\n/** Filter criteria applied to upstream extensions. */\nexport interface FederationFilter {\n /**\n * Only allow declarative extensions (no runtime code needed).\n *\n * **Note:** This filter requires `contributionPoints` to be supplied\n * externally (e.g., from VSIX scanning). When contribution points are\n * not available (as in `search()` and `getExtension()` which only have\n * API metadata), this filter is skipped for that extension.\n */\n declarativeOnly?: boolean\n /** Whitelist of allowed categories (empty array = all allowed). */\n allowedCategories?: string[]\n /** Blacklist of publisher namespaces. */\n blockedPublishers?: string[]\n}\n\n/** Federation client configuration. */\nexport interface FederationConfig {\n /** Federation mode. */\n mode: FederationMode\n /** Upstream registry URL (default: `'https://open-vsx.org/api'`). */\n upstream?: string\n /** Filter configuration. */\n filter?: FederationFilter\n /** Cache TTL hint in seconds for consumers (default: 3600). */\n cacheTtlSeconds?: number\n}\n\n/** A deterministic cache key with suggested TTL. */\nexport interface FederationCacheKey {\n /** Deterministic cache key string. */\n key: string\n /** Suggested TTL in seconds. */\n ttlSeconds: number\n}\n\n/** Result of a federated search operation. */\nexport interface FederatedSearchResult {\n /** Extensions that passed all filters. */\n extensions: OpenVSXSearchEntry[]\n /** Total result count from upstream (before filtering). */\n totalSize: number\n /** Count of extensions removed by filters. */\n filtered: number\n /** Where the data came from. */\n source: 'upstream' | 'cache' | 'local'\n /** Cache key for this request. */\n cacheKey: FederationCacheKey\n}\n\n/** Result of a federated extension lookup. */\nexport interface FederatedExtensionResult {\n /** The extension, or null if not found or filtered. */\n extension: OpenVSXExtension | null\n /** Whether the extension was blocked by filters. */\n filtered: boolean\n /** Reason the extension was filtered. */\n filterReason?: string\n /** Where the data came from. */\n source: 'upstream' | 'cache' | 'local'\n /** Cache key for this request. */\n cacheKey: FederationCacheKey\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_CACHE_TTL_SECONDS = 3600\n\n// ---------------------------------------------------------------------------\n// Pure functions\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a deterministic cache key from an endpoint and sorted params.\n *\n * @param endpoint - API endpoint name (e.g., `'search'`, `'extension'`)\n * @param params - Key-value parameters to include in the key\n * @returns Deterministic cache key string\n */\nexport function generateCacheKey(endpoint: string, params: Record<string, string> = {}): string {\n const sortedEntries = Object.entries(params).sort(([a], [b]) => a.localeCompare(b))\n const paramString = sortedEntries.map(([k, v]) => `${k}=${v}`).join('&')\n return `${endpoint}:${paramString}`\n}\n\n/**\n * Check if an extension passes all filter criteria.\n *\n * @param extension - Extension metadata to check\n * @param filter - Filter criteria to apply\n * @param contributionPoints - Contribution point keys from the extension manifest\n * @returns Whether the extension is allowed and the reason if not\n */\nexport function matchesFilter(\n extension: { categories?: string[]; namespace?: string; name?: string },\n filter: FederationFilter,\n contributionPoints?: string[],\n): { allowed: boolean; reason?: string } {\n // Check blockedPublishers first (case-insensitive)\n if (\n filter.blockedPublishers &&\n filter.blockedPublishers.length > 0 &&\n extension.namespace\n ) {\n const ns = extension.namespace.toLowerCase()\n if (filter.blockedPublishers.some((bp) => bp.toLowerCase() === ns)) {\n return { allowed: false, reason: `Publisher '${extension.namespace}' is blocked` }\n }\n }\n\n // Check allowedCategories (case-insensitive)\n if (filter.allowedCategories && filter.allowedCategories.length > 0) {\n const categories = extension.categories ?? []\n const allowedLower = filter.allowedCategories.map((c) => c.toLowerCase())\n const hasAllowedCategory = categories.some((cat) => allowedLower.includes(cat.toLowerCase()))\n if (!hasAllowedCategory) {\n return {\n allowed: false,\n reason: `No matching category (has: ${categories.join(', ')}; allowed: ${filter.allowedCategories.join(', ')})`,\n }\n }\n }\n\n // Check declarativeOnly\n if (filter.declarativeOnly && contributionPoints) {\n if (!isDeclarativeExtension(contributionPoints)) {\n return {\n allowed: false,\n reason: 'Extension uses non-declarative contribution points',\n }\n }\n }\n\n return { allowed: true }\n}\n\n/**\n * Check if an extension uses only declarative contribution points.\n *\n * @param contributionPoints - Contribution point keys from the extension manifest\n * @returns True if all contribution points are declarative\n */\nexport function isDeclarativeExtension(contributionPoints: string[]): boolean {\n return contributionPoints.every((cp) => DECLARATIVE_CONTRIBUTION_POINTS.has(cp))\n}\n\n// ---------------------------------------------------------------------------\n// FederationClient\n// ---------------------------------------------------------------------------\n\n/**\n * Federation protocol client that wraps `OpenVSXClient` with mode-based\n * behavior, filter application, and cache key generation.\n */\nexport class FederationClient {\n private readonly config: FederationConfig\n private readonly upstream: OpenVSXClient | null\n private readonly cacheTtl: number\n\n /**\n * Create a new federation client.\n *\n * @param config - Federation configuration\n * @param upstreamClient - Optional pre-configured OpenVSXClient (created from config if not provided)\n */\n constructor(config: FederationConfig, upstreamClient?: OpenVSXClient) {\n this.config = config\n this.cacheTtl = config.cacheTtlSeconds ?? DEFAULT_CACHE_TTL_SECONDS\n\n if (config.mode === 'standalone') {\n this.upstream = null\n } else if (upstreamClient) {\n this.upstream = upstreamClient\n } else {\n this.upstream = new OpenVSXClient(\n config.upstream ? { baseUrl: config.upstream } : undefined,\n )\n }\n }\n\n /**\n * Search extensions with filters applied.\n *\n * In standalone mode, returns empty results. In proxy/mirror mode,\n * delegates to upstream and applies filters.\n */\n async search(\n params?: OpenVSXSearchParams,\n ): Promise<OpenVSXApiResult<FederatedSearchResult>> {\n const cacheKey = this.getCacheKey('search', params ? this._searchParamsToRecord(params) : undefined)\n\n // Standalone mode — no upstream calls\n if (!this.upstream) {\n return {\n ok: true,\n data: {\n extensions: [],\n totalSize: 0,\n filtered: 0,\n source: 'local',\n cacheKey,\n },\n }\n }\n\n // Proxy/mirror mode — fetch from upstream\n const result = await this.upstream.search(params)\n if (!result.ok) {\n return result\n }\n\n const { extensions, totalSize } = result.data\n const filter = this.config.filter\n\n // Apply filters\n if (filter) {\n const passed: OpenVSXSearchEntry[] = []\n let filteredCount = 0\n\n for (const ext of extensions) {\n // OpenVSXSearchEntry doesn't have categories, but upstream may include them\n const extWithCategories = ext as OpenVSXSearchEntry & { categories?: string[] }\n const categories = extWithCategories.categories\n const check = matchesFilter(\n categories\n ? { categories, namespace: ext.namespace, name: ext.name }\n : { namespace: ext.namespace, name: ext.name },\n filter,\n )\n if (check.allowed) {\n passed.push(ext)\n } else {\n filteredCount++\n }\n }\n\n return {\n ok: true,\n data: {\n extensions: passed,\n totalSize,\n filtered: filteredCount,\n source: 'upstream',\n cacheKey,\n },\n }\n }\n\n return {\n ok: true,\n data: {\n extensions,\n totalSize,\n filtered: 0,\n source: 'upstream',\n cacheKey,\n },\n }\n }\n\n /**\n * Get a single extension with filter check.\n *\n * In standalone mode, returns null. In proxy/mirror mode,\n * fetches from upstream and checks against filters.\n */\n async getExtension(\n namespace: string,\n name: string,\n version?: string,\n ): Promise<OpenVSXApiResult<FederatedExtensionResult>> {\n const params: Record<string, string> = { namespace, name }\n if (version) {\n params['version'] = version\n }\n const cacheKey = this.getCacheKey('extension', params)\n\n // Standalone mode — no upstream calls\n if (!this.upstream) {\n return {\n ok: true,\n data: {\n extension: null,\n filtered: false,\n source: 'local',\n cacheKey,\n },\n }\n }\n\n // Proxy/mirror mode — fetch from upstream\n const result = await this.upstream.getExtension(namespace, name, version)\n if (!result.ok) {\n return result\n }\n\n const ext = result.data\n const filter = this.config.filter\n\n // Apply filters\n if (filter) {\n const check = matchesFilter(\n {\n categories: ext.categories,\n namespace: ext.namespace,\n name: ext.name,\n },\n filter,\n )\n if (!check.allowed) {\n const data: FederatedExtensionResult = {\n extension: null,\n filtered: true,\n source: 'upstream',\n cacheKey,\n }\n if (check.reason) {\n data.filterReason = check.reason\n }\n return { ok: true as const, data }\n }\n }\n\n return {\n ok: true,\n data: {\n extension: ext,\n filtered: false,\n source: 'upstream',\n cacheKey,\n },\n }\n }\n\n /**\n * Get a VSIX download URL for a specific extension version.\n *\n * Returns null in standalone mode (no upstream available).\n */\n getDownloadUrl(\n namespace: string,\n name: string,\n version: string,\n targetPlatform?: string,\n ): string | null {\n if (!this.upstream) {\n return null\n }\n return this.upstream.getDownloadUrl(namespace, name, version, targetPlatform)\n }\n\n /**\n * Build a cache key for a given endpoint and parameters.\n */\n getCacheKey(endpoint: string, params?: Record<string, string>): FederationCacheKey {\n const raw = generateCacheKey(endpoint, params)\n let key = `federation:${this.config.mode}:${raw}`\n if (this.config.filter) {\n const f = this.config.filter\n const parts: string[] = []\n if (f.declarativeOnly) parts.push('d=1')\n if (f.allowedCategories && f.allowedCategories.length > 0) {\n parts.push(`ac=${[...f.allowedCategories].sort().join(',')}`)\n }\n if (f.blockedPublishers && f.blockedPublishers.length > 0) {\n parts.push(`bp=${[...f.blockedPublishers].sort().join(',')}`)\n }\n if (parts.length > 0) {\n key += `:f(${parts.join(';')})`\n }\n }\n return { key, ttlSeconds: this.cacheTtl }\n }\n\n /**\n * Get a readonly copy of the current federation configuration.\n */\n getConfig(): Readonly<FederationConfig> {\n const copy: FederationConfig = { ...this.config }\n if (this.config.filter) {\n copy.filter = { ...this.config.filter }\n if (this.config.filter.allowedCategories) {\n copy.filter.allowedCategories = [...this.config.filter.allowedCategories]\n }\n if (this.config.filter.blockedPublishers) {\n copy.filter.blockedPublishers = [...this.config.filter.blockedPublishers]\n }\n }\n return copy\n }\n\n // -------------------------------------------------------------------------\n // Private helpers\n // -------------------------------------------------------------------------\n\n /** Convert search params to a plain Record for cache key generation. */\n private _searchParamsToRecord(params: OpenVSXSearchParams): Record<string, string> {\n const record: Record<string, string> = {}\n if (params.query !== undefined) record['query'] = params.query\n if (params.category !== undefined) record['category'] = params.category\n if (params.targetPlatform !== undefined) record['targetPlatform'] = params.targetPlatform\n if (params.size !== undefined) record['size'] = String(params.size)\n if (params.offset !== undefined) record['offset'] = String(params.offset)\n if (params.sortOrder !== undefined) record['sortOrder'] = params.sortOrder\n if (params.sortBy !== undefined) record['sortBy'] = params.sortBy\n if (params.includeAllVersions !== undefined)\n record['includeAllVersions'] = String(params.includeAllVersions)\n return record\n }\n}\n"]}
|