{"version":3,"file":"apply-manifest.cjs","names":["Effect","readText","writeText","OBSOLETE_FILES","fileExists","removePath","listFiles"],"sources":["../../../../../src/services/scaffold/upgrade-audit/steps/apply-manifest.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport type { ImportRewrite } from \"../domain\";\nimport { fileExists, listFiles, readText, removePath, writeText } from \"../fs\";\nimport { OBSOLETE_FILES } from \"../obsolete-files\";\nimport type { StepResult } from \"./author-config\";\n\nconst applyRewrites = (\n  projectDir: string,\n  rewrites: readonly ImportRewrite[],\n  dryRun: boolean,\n): Effect.Effect<string[], Error> =>\n  Effect.gen(function* () {\n    const touched: string[] = [];\n    for (const rewrite of rewrites) {\n      for (const file of rewrite.files) {\n        const source = yield* readText(projectDir, file);\n        const next = source.replaceAll(rewrite.from, rewrite.to);\n        if (next !== source) {\n          touched.push(file);\n          if (!dryRun) yield* writeText(projectDir, file, next);\n        }\n      }\n    }\n    return touched;\n  });\n\nconst applyDeletions = (projectDir: string, dryRun: boolean): Effect.Effect<string[], Error> =>\n  Effect.gen(function* () {\n    const removed: string[] = [];\n    for (const path of OBSOLETE_FILES) {\n      if (yield* fileExists(projectDir, path)) {\n        removed.push(path);\n        if (!dryRun) yield* removePath(projectDir, path);\n      }\n    }\n    return removed;\n  });\n\ninterface PluginDepsResult {\n  readonly added: readonly string[];\n  readonly unresolved: readonly string[];\n}\n\nconst bareSpecifiers = (source: string): string[] => {\n  const specifiers: string[] = [];\n  const importRe =\n    /(?:import|export)[^\"'`]*?from\\s*[\"']([^\"']+)[\"']|import\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)|require\\s*\\(\\s*[\"']([^\"']+)[\"']\\s*\\)/g;\n  for (const match of source.matchAll(importRe)) {\n    const spec = match[1] ?? match[2] ?? match[3];\n    if (spec && !spec.startsWith(\".\") && !spec.startsWith(\"/\")) specifiers.push(spec);\n  }\n  return specifiers;\n};\n\nconst packageNameOf = (specifier: string): string => {\n  if (specifier.startsWith(\"@\")) {\n    const [, scope, name] = specifier.split(\"/\");\n    return scope && name ? `${scope}/${name}` : specifier;\n  }\n  return specifier.split(\"/\")[0];\n};\n\nconst isProtocolSpecifier = (specifier: string): boolean => /^[^/]+:/.test(specifier);\n\nconst memberPackageNames = (projectDir: string): Effect.Effect<Set<string>, Error> =>\n  Effect.gen(function* () {\n    const pkgPaths = yield* listFiles(\n      projectDir,\n      \"{package.json,ui/package.json,api/package.json,plugins/*/package.json}\",\n    );\n    const names = new Set<string>();\n    for (const pkgPath of pkgPaths) {\n      if (pkgPath === \"package.json\") continue;\n      const pkg = JSON.parse(yield* readText(projectDir, pkgPath)) as { name?: string };\n      if (typeof pkg.name === \"string\") names.add(pkg.name);\n    }\n    return names;\n  });\n\nconst declarePluginDeps = (\n  projectDir: string,\n  dryRun: boolean,\n): Effect.Effect<PluginDepsResult, Error> =>\n  Effect.gen(function* () {\n    const rootCatalog = JSON.parse(yield* readText(projectDir, \"package.json\")) as {\n      workspaces?: { catalog?: Record<string, string> };\n    };\n    const catalog = rootCatalog.workspaces?.catalog ?? {};\n    const members = yield* memberPackageNames(projectDir);\n\n    const pluginPkgs = yield* listFiles(projectDir, \"plugins/*/package.json\");\n    const added: string[] = [];\n    const unresolved: string[] = [];\n\n    for (const pkgPath of pluginPkgs) {\n      const pluginDir = pkgPath.slice(0, pkgPath.lastIndexOf(\"/\"));\n      const declared = new Set<string>();\n      const pkg = JSON.parse(yield* readText(projectDir, pkgPath)) as {\n        dependencies?: Record<string, string>;\n        devDependencies?: Record<string, string>;\n      };\n      for (const name of [\n        ...Object.keys(pkg.dependencies ?? {}),\n        ...Object.keys(pkg.devDependencies ?? {}),\n      ]) {\n        declared.add(name);\n      }\n\n      const sources = yield* listFiles(projectDir, `${pluginDir}/src/**/*.{ts,tsx}`);\n      const needed = new Set<string>();\n      for (const source of sources) {\n        const text = yield* readText(projectDir, source);\n        for (const specifier of bareSpecifiers(text)) {\n          if (isProtocolSpecifier(specifier)) continue;\n          needed.add(packageNameOf(specifier));\n        }\n      }\n\n      const nextDeps = { ...(pkg.dependencies ?? {}) };\n      let modified = false;\n      for (const name of needed) {\n        if (declared.has(name) || name === pluginDir.split(\"/\")[1]) continue;\n        // In-repo packages get workspace:* — the catalog holds external deps.\n        if (members.has(name)) {\n          added.push(`${pluginDir}: ${name} (workspace:*)`);\n          nextDeps[name] = \"workspace:*\";\n          modified = true;\n          continue;\n        }\n        if (!(name in catalog)) {\n          unresolved.push(`${pluginDir}: ${name} (not in catalog — declare manually)`);\n          continue;\n        }\n        added.push(`${pluginDir}: ${name}`);\n        nextDeps[name] = \"catalog:\";\n        modified = true;\n      }\n\n      if (modified && !dryRun) {\n        yield* writeText(\n          projectDir,\n          pkgPath,\n          `${JSON.stringify({ ...pkg, dependencies: nextDeps }, null, 2)}\\n`,\n        );\n      }\n    }\n    return { added, unresolved };\n  });\n\nexport const consumerizeRefs = (\n  projectDir: string,\n  dryRun: boolean,\n): Effect.Effect<string[], Error> =>\n  Effect.gen(function* () {\n    const pkgPaths = yield* listFiles(\n      projectDir,\n      \"{package.json,ui/package.json,api/package.json,plugins/*/package.json}\",\n    );\n    // Refs to in-repo packages stay `workspace:*` — pnpm resolves member\n    // packages locally, and the catalog only holds external deps. Only\n    // external `workspace:`/`file:` refs (bun-workspace leftovers pointing\n    // outside the tree) are consumerized to `catalog:`.\n    const memberNames = new Set<string>();\n    for (const pkgPath of pkgPaths) {\n      if (pkgPath === \"package.json\") continue;\n      const pkg = JSON.parse(yield* readText(projectDir, pkgPath)) as { name?: string };\n      if (typeof pkg.name === \"string\") memberNames.add(pkg.name);\n    }\n    const fixed: string[] = [];\n    for (const pkgPath of pkgPaths) {\n      const pkg = JSON.parse(yield* readText(projectDir, pkgPath)) as Record<string, unknown>;\n      let modified = false;\n      for (const field of [\"dependencies\", \"devDependencies\", \"peerDependencies\"]) {\n        const deps = pkg[field];\n        if (deps === null || typeof deps !== \"object\") continue;\n        const record = deps as Record<string, string>;\n        for (const [name, ref] of Object.entries(record)) {\n          if (\n            typeof ref === \"string\" &&\n            (ref.startsWith(\"workspace:\") || ref.startsWith(\"file:\")) &&\n            !memberNames.has(name)\n          ) {\n            record[name] = \"catalog:\";\n            modified = true;\n          }\n        }\n      }\n      if (modified) {\n        fixed.push(pkgPath);\n        if (!dryRun) {\n          yield* writeText(projectDir, pkgPath, `${JSON.stringify(pkg, null, 2)}\\n`);\n        }\n      }\n    }\n    return fixed;\n  });\n\nexport const applyManifest = (\n  projectDir: string,\n  rewrites: readonly ImportRewrite[],\n  dryRun: boolean,\n): Effect.Effect<StepResult, Error> =>\n  Effect.gen(function* () {\n    const rewritten = yield* applyRewrites(projectDir, rewrites, dryRun);\n    const deleted = yield* applyDeletions(projectDir, dryRun);\n    const deps = yield* declarePluginDeps(projectDir, dryRun);\n    const refs = yield* consumerizeRefs(projectDir, dryRun);\n    return {\n      writes: rewritten,\n      deletes: deleted,\n      notes: [\n        ...(refs.length > 0 ? [`workspace:/file: refs → catalog: in ${refs.join(\", \")}`] : []),\n        ...(deps.added.length > 0 ? [`plugin deps added: ${deps.added.join(\", \")}`] : []),\n        ...deps.unresolved,\n      ],\n    };\n  });\n"],"mappings":"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"}