{"version":3,"file":"webPluginScan.mjs","names":[],"sources":["../../../src/builders/web/webPluginScan.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\n\nimport {\n  type DeclaredWebPlugin,\n  declaredPluginsOf,\n  orderDeclaredPlugins,\n  WebPluginManifestError,\n} from './webPluginManifest';\n\n/**\n * Reads doompiWeb declarations from explicit package roots.\n *\n * No workspace walking and no hardcoded plugin names: the caller says which\n * packages are in play. At doompi-web's own build time that is just the host\n * package (its built-in plugins); at `doompi sync` time it is the installed\n * composition's package roots. A plugin package whose manifest is malformed\n * or whose entry file is missing is skipped with a notice, so one broken or\n * half-installed package never costs the rest of the cockpit; only the host's\n * own manifest still throws, because that is a build error of this package.\n */\nexport function scanWebPlugins(\n  hostDir: string,\n  pluginRoots: readonly string[] = [],\n  onNotice: (message: string) => void = () => undefined,\n): DeclaredWebPlugin[] {\n  const seen = new Set<string>();\n  const plugins: DeclaredWebPlugin[] = [];\n  const hostResolved = path.resolve(hostDir);\n  for (const root of [hostDir, ...pluginRoots]) {\n    const resolved = path.resolve(root);\n    if (seen.has(resolved)) continue;\n    seen.add(resolved);\n    try {\n      plugins.push(...declaredPluginsIn(resolved, resolved === hostResolved));\n    } catch (error) {\n      if (resolved === hostResolved) throw error;\n      const reason = error instanceof WebPluginManifestError ? error.message : String(error);\n      onNotice(`web plugin package ${resolved} skipped: ${reason}`);\n    }\n  }\n  return orderDeclaredPlugins(plugins, onNotice);\n}\n\nfunction declaredPluginsIn(resolved: string, isHost: boolean): DeclaredWebPlugin[] {\n  let manifest: Record<string, unknown>;\n  try {\n    manifest = JSON.parse(fs.readFileSync(path.join(resolved, 'package.json'), 'utf8')) as Record<string, unknown>;\n  } catch (error) {\n    throw new WebPluginManifestError(resolved, `package.json is unreadable: ${String(error)}`);\n  }\n  const declared = declaredPluginsOf(resolved, manifest, isHost);\n  for (const plugin of declared) {\n    const entryPath = path.join(resolved, plugin.client.entry);\n    if (!fs.existsSync(entryPath)) {\n      throw new WebPluginManifestError(resolved, `client.entry '${plugin.client.entry}' does not exist.`);\n    }\n  }\n  return declared;\n}\n"],"mappings":";;;;;;;;;;;;;;;AAqBA,SAAgB,eACd,SACA,cAAiC,CAAC,GAClC,iBAA4C,KAAA,GACvB;CACrB,MAAM,uBAAO,IAAI,IAAY;CAC7B,MAAM,UAA+B,CAAC;CACtC,MAAM,eAAe,KAAK,QAAQ,OAAO;CACzC,KAAK,MAAM,QAAQ,CAAC,SAAS,GAAG,WAAW,GAAG;EAC5C,MAAM,WAAW,KAAK,QAAQ,IAAI;EAClC,IAAI,KAAK,IAAI,QAAQ,GAAG;EACxB,KAAK,IAAI,QAAQ;EACjB,IAAI;GACF,QAAQ,KAAK,GAAG,kBAAkB,UAAU,aAAa,YAAY,CAAC;EACxE,SAAS,OAAO;GACd,IAAI,aAAa,cAAc,MAAM;GAErC,SAAS,sBAAsB,SAAS,YADzB,iBAAiB,yBAAyB,MAAM,UAAU,OAAO,KAAK,GACzB;EAC9D;CACF;CACA,OAAO,qBAAqB,SAAS,QAAQ;AAC/C;AAEA,SAAS,kBAAkB,UAAkB,QAAsC;CACjF,IAAI;CACJ,IAAI;EACF,WAAW,KAAK,MAAM,GAAG,aAAa,KAAK,KAAK,UAAU,cAAc,GAAG,MAAM,CAAC;CACpF,SAAS,OAAO;EACd,MAAM,IAAI,uBAAuB,UAAU,+BAA+B,OAAO,KAAK,GAAG;CAC3F;CACA,MAAM,WAAW,kBAAkB,UAAU,UAAU,MAAM;CAC7D,KAAK,MAAM,UAAU,UAAU;EAC7B,MAAM,YAAY,KAAK,KAAK,UAAU,OAAO,OAAO,KAAK;EACzD,IAAI,CAAC,GAAG,WAAW,SAAS,GAC1B,MAAM,IAAI,uBAAuB,UAAU,iBAAiB,OAAO,OAAO,MAAM,kBAAkB;CAEtG;CACA,OAAO;AACT"}