{"version":3,"file":"migrate-pnpm.cjs","names":["CATALOG_PINNED_OVERRIDE_KEYS","frameworkReleaseAgeExcludes","Effect","listFiles","readText","writeText","V2_CATALOG","PNPM_PACKAGE_MANAGER","removePath"],"sources":["../../../../../src/services/scaffold/upgrade-audit/steps/migrate-pnpm.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport {\n  CATALOG_PINNED_OVERRIDE_KEYS,\n  frameworkReleaseAgeExcludes,\n  PNPM_PACKAGE_MANAGER,\n} from \"../../../workspace/catalog-overrides\";\nimport { listFiles, readText, removePath, writeText } from \"../fs\";\nimport type { StepResult } from \"./author-config\";\nimport { V2_CATALOG } from \"./v2-catalog\";\n\nconst YAML_PLAIN_VALUE_RE = /^[A-Za-z0-9^~][A-Za-z0-9.^~*+\\-/]*$/;\n\nconst yamlScalar = (value: string): string =>\n  YAML_PLAIN_VALUE_RE.test(value) ? value : JSON.stringify(value);\n\nconst yamlMap = (entries: ReadonlyArray<readonly [string, string]>, indent: string): string =>\n  entries\n    .map(([key, value]) =>\n      /^[A-Za-z0-9_.-]+$/.test(key)\n        ? `${indent}${key}: ${yamlScalar(value)}`\n        : `${indent}${JSON.stringify(key)}: ${yamlScalar(value)}`,\n    )\n    .join(\"\\n\");\n\ninterface WorkspaceYamlInput {\n  readonly packages: readonly string[];\n  readonly catalog: Readonly<Record<string, string>>;\n}\n\nconst renderWorkspaceYaml = (input: WorkspaceYamlInput): string => {\n  const catalogEntries = Object.entries(input.catalog).map(([key, value]) => [key, value] as const);\n  const catalog = Object.fromEntries(catalogEntries);\n  const overrideEntries = CATALOG_PINNED_OVERRIDE_KEYS.filter((key) => catalog[key]).map(\n    (key) => [key, catalog[key]] as const,\n  );\n  const releaseAgeExcludes = frameworkReleaseAgeExcludes(catalog);\n  const lines = [\n    \"packages:\",\n    ...input.packages.map((pkg) => `  - ${yamlScalar(pkg)}`),\n    \"\",\n    \"allowBuilds:\",\n    \"  esbuild: true\",\n    \"  sharp: true\",\n    \"  protobufjs: true\",\n    \"  '@openapitools/openapi-generator-cli': true\",\n    \"\",\n    ...(overrideEntries.length > 0\n      ? [\n          \"overrides:\",\n          ...overrideEntries.map(([key, value]) => `  ${yamlMap([[key, value]], \"\").trimStart()}`),\n          \"\",\n        ]\n      : []),\n    \"catalog:\",\n    yamlMap(catalogEntries, \"  \"),\n    \"\",\n    ...(releaseAgeExcludes.length > 0\n      ? [\n          \"minimumReleaseAgeExcludePrune: true\",\n          \"minimumReleaseAgeExclude:\",\n          ...releaseAgeExcludes.map((entry) => `  - ${yamlScalar(entry)}`),\n          \"\",\n        ]\n      : []),\n  ];\n  return lines.join(\"\\n\");\n};\n\nconst PLUGIN_TYPECHECK_LOOP =\n  'for dir in plugins/*; do if [ -f \"$dir/package.json\" ]; then pnpm --dir \"$dir\" run typecheck || exit 1; fi; done';\n\nconst PLUGIN_TEST_LOOP =\n  'for d in plugins/*; do if [ -f \"$d/package.json\" ]; then pnpm --dir \"$d\" --if-present run test || exit 1; fi; done';\n\nconst hardenedTypecheck = (dirs: readonly string[]): string =>\n  [\n    \"pnpm run types:gen\",\n    ...dirs.map((dir) => `if [ -d ${dir} ]; then pnpm --dir ${dir} run typecheck || exit 1; fi`),\n    PLUGIN_TYPECHECK_LOOP,\n  ].join(\" && \");\n\nconst hardenedTest = (dirs: readonly string[]): string =>\n  [\n    ...dirs.map((dir) => `pnpm --dir ${dir} --if-present run test || exit 1`),\n    `[ -d plugins ] && ${PLUGIN_TEST_LOOP} || true`,\n  ].join(\" && \");\n\n/** Mechanical bun→pnpm rewrites, safe for any workspace's scripts. */\nconst mechanicalScriptRewrite = (value: string): string =>\n  value\n    .replaceAll(\"bun run --if-present --cwd \", \"pnpm --dir \")\n    .replaceAll(\"bun run --cwd \", \"pnpm --dir \")\n    .replace(/bun run --cwd (\\S+) (.+)/, \"pnpm --dir $1 exec $2\")\n    .replaceAll(\"bun run \", \"pnpm run \")\n    // node cannot execute the .bin shell shims pnpm installs — under pnpm\n    // run, the bin is already on PATH.\n    .replace(/node node_modules\\/\\.bin\\/bos /, \"bos \")\n    .replace(\n      'for d in plugins/*; do [ -f \"$d/package.json\" ] && bun run --if-present --cwd \"$d\" test; done',\n      'for d in plugins/*; do if [ -f \"$d/package.json\" ]; then pnpm --dir \"$d\" --if-present run test || exit 1; fi; done',\n    )\n    .replace(\n      'for dir in plugins/*; do if [ -f \"$dir/package.json\" ]; then bun run --cwd \"$dir\" typecheck; fi; done',\n      'for dir in plugins/*; do if [ -f \"$dir/package.json\" ]; then pnpm --dir \"$dir\" run typecheck || exit 1; fi; done',\n    );\n\nconst rewriteScripts = (scripts: Record<string, string>): Record<string, string> => {\n  const next: Record<string, string> = {};\n  for (const [key, value] of Object.entries(scripts)) {\n    if (key === \"typecheck\") {\n      next[key] = hardenedTypecheck([\"ui\", \"api\"]);\n      continue;\n    }\n    if (key === \"test\") {\n      next[key] = hardenedTest([\"api\", \"ui\"]);\n      continue;\n    }\n    next[key] = mechanicalScriptRewrite(value);\n  }\n  return next;\n};\n\nconst WORKSPACE_PKG_GLOB = \"{ui/package.json,api/package.json,plugins/*/package.json}\";\n\n/**\n * Workspace package.json scripts still speak bun (`bun run build:client`,\n * `bun run --cwd api typecheck`). Rewrite every bun invocation to the pnpm\n * form so the pnpm-only tree (packageManager pin, no bun in CI) works.\n * Unlike the root pass, workspace typecheck/test scripts keep their own\n * bodies — only the bun invocations are mechanically rewritten.\n */\nconst rewriteWorkspaceScripts = (\n  projectDir: string,\n  dryRun: boolean,\n): Effect.Effect<string[], Error> =>\n  Effect.gen(function* () {\n    const pkgPaths = yield* listFiles(projectDir, WORKSPACE_PKG_GLOB);\n    const changed: string[] = [];\n    for (const pkgPath of pkgPaths) {\n      const source = yield* readText(projectDir, pkgPath);\n      if (!source.includes(\"bun \")) continue;\n      const pkg = JSON.parse(source) as { scripts?: Record<string, string> };\n      if (!pkg.scripts) continue;\n      const scripts = Object.fromEntries(\n        Object.entries(pkg.scripts).map(([key, value]) => [key, mechanicalScriptRewrite(value)]),\n      );\n      if (JSON.stringify(scripts) === JSON.stringify(pkg.scripts)) continue;\n      if (!dryRun) {\n        yield* writeText(projectDir, pkgPath, `${JSON.stringify({ ...pkg, scripts }, null, 2)}\\n`);\n      }\n      changed.push(pkgPath);\n    }\n    return changed;\n  });\n\nconst BUN_ARTIFACTS = [\"bun.lock\", \"bunfig.toml\"] as const;\n\nconst RETIRED_FILES = [\"railway.toml\", \"Dockerfile\"] as const;\n\nexport const migratePnpm = (\n  projectDir: string,\n  dryRun: boolean,\n): Effect.Effect<StepResult, Error> =>\n  Effect.gen(function* () {\n    const pkg = JSON.parse(yield* readText(projectDir, \"package.json\")) as {\n      packageManager?: string;\n      scripts?: Record<string, string>;\n      workspaces?: { packages?: string[]; catalog?: Record<string, string> };\n    };\n\n    const catalog = { ...pkg.workspaces?.catalog, ...V2_CATALOG };\n    const packages = pkg.workspaces?.packages ?? [\"api\", \"ui\", \"plugins/*\"];\n    const workspaceYaml = renderWorkspaceYaml({ packages, catalog });\n\n    const nextPkg = {\n      ...pkg,\n      packageManager: PNPM_PACKAGE_MANAGER,\n      scripts: rewriteScripts(pkg.scripts ?? {}),\n      workspaces: undefined,\n    };\n\n    const writes = [\"pnpm-workspace.yaml\", \"package.json\"];\n    const deletes = [...BUN_ARTIFACTS, ...RETIRED_FILES];\n    const notes = [\n      \"catalog now lives in pnpm-workspace.yaml; bos upgrade syncs framework versions from the parent\",\n      \"Dockerfile + railway.toml retired — deploys use ci.image (the upstream runtime image)\",\n    ];\n\n    const workspaceScripts = yield* rewriteWorkspaceScripts(projectDir, dryRun);\n\n    if (dryRun) {\n      return {\n        writes: [...writes, ...workspaceScripts],\n        deletes,\n        notes,\n      };\n    }\n\n    yield* writeText(projectDir, \"pnpm-workspace.yaml\", workspaceYaml);\n    yield* writeText(projectDir, \"package.json\", `${JSON.stringify(nextPkg, null, 2)}\\n`);\n    for (const path of [...BUN_ARTIFACTS, ...RETIRED_FILES]) {\n      yield* removePath(projectDir, path);\n    }\n    return { writes: [...writes, ...workspaceScripts], deletes, notes };\n  });\n"],"mappings":"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"}