{"version":3,"file":"manifest-normalizer.mjs","names":[],"sources":["../../src/internal/manifest-normalizer.ts"],"sourcesContent":["import { cpSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative, sep } from \"node:path\";\nimport { glob } from \"glob\";\n\nconst FRAMEWORK_PACKAGES = [\"every-plugin\", \"everything-dev\"] as const;\n\nconst CATALOG_TOOL_PACKAGES = [\n  \"@rspack/core\",\n  \"@rspack/cli\",\n  \"@rsbuild/core\",\n  \"@rsbuild/plugin-react\",\n  \"@module-federation/enhanced\",\n  \"@module-federation/node\",\n  \"@module-federation/rsbuild-plugin\",\n  \"@module-federation/runtime-core\",\n  \"@module-federation/sdk\",\n  \"@module-federation/dts-plugin\",\n] as const;\n\ntype PackageJson = Record<string, unknown>;\n\ntype NormalizationSpec = {\n  rootCatalog: Record<string, string>;\n  frameworkVersions: Record<string, string>;\n};\n\ntype NormalizeManifestOptions = {\n  resolveCatalogRefs: boolean;\n  preserveCatalogRefs?: boolean;\n  excludeFrameworkWorkspaces?: boolean;\n  removeWorkspaceDeps?: string[];\n  removeWorkspaces?: boolean;\n  removePublishScripts?: boolean;\n};\n\nexport type NormalizeTreeOptions = NormalizeManifestOptions & {\n  sourceRootDir: string;\n  targetDir: string;\n};\n\nfunction readJson<T>(filePath: string): T {\n  return JSON.parse(readFileSync(filePath, \"utf-8\")) as T;\n}\n\nfunction extractExactVersion(input: string | undefined): string | null {\n  if (!input) return null;\n  const match = input.match(/\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?/);\n  return match ? match[0] : null;\n}\n\nfunction writeJson(filePath: string, value: PackageJson) {\n  writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\\n`);\n}\n\nexport function loadManifestNormalizationSpec(sourceRootDir: string): NormalizationSpec {\n  const rootPackage = readJson<PackageJson>(join(sourceRootDir, \"package.json\"));\n  const rootCatalog = {\n    ...(((rootPackage.workspaces as { catalog?: Record<string, string> } | undefined)?.catalog ??\n      {}) as Record<string, string>),\n  };\n  const frameworkVersions: Record<string, string> = {};\n\n  for (const packageName of FRAMEWORK_PACKAGES) {\n    const sourcePackagePath = join(sourceRootDir, \"packages\", packageName, \"package.json\");\n    const localPackagePath = join(import.meta.dirname, \"..\", \"..\", packageName, \"package.json\");\n    const packageVersion = existsSync(localPackagePath)\n      ? readJson<{ version: string }>(localPackagePath).version\n      : existsSync(sourcePackagePath)\n        ? readJson<{ version: string }>(sourcePackagePath).version\n        : extractExactVersion(rootCatalog[packageName]);\n\n    if (!packageVersion) {\n      throw new Error(`Could not resolve version for ${packageName}`);\n    }\n\n    frameworkVersions[packageName] = packageVersion;\n    rootCatalog[packageName] = `^${packageVersion}`;\n  }\n\n  return { rootCatalog, frameworkVersions };\n}\n\nfunction normalizeDependencyMap(\n  map: Record<string, string>,\n  spec: NormalizationSpec,\n  options: NormalizeManifestOptions,\n) {\n  const catalogPackages = new Set<string>([...FRAMEWORK_PACKAGES, ...CATALOG_TOOL_PACKAGES]);\n\n  let modified = false;\n\n  for (const [name, version] of Object.entries(map)) {\n    if (options.preserveCatalogRefs && catalogPackages.has(name)) {\n      if (version !== \"catalog:\") {\n        map[name] = \"catalog:\";\n        modified = true;\n      }\n      continue;\n    }\n\n    if (version === \"workspace:*\") {\n      const frameworkVersion = spec.frameworkVersions[name];\n      if (frameworkVersion) {\n        map[name] = `^${frameworkVersion}`;\n        modified = true;\n        continue;\n      }\n\n      if (options.removeWorkspaceDeps?.includes(name)) {\n        delete map[name];\n        modified = true;\n      }\n      continue;\n    }\n\n    if (options.resolveCatalogRefs && version.startsWith(\"catalog:\")) {\n      const resolved = spec.rootCatalog[name];\n      if (resolved) {\n        map[name] = resolved;\n        modified = true;\n      }\n    }\n  }\n\n  return modified;\n}\n\nexport function normalizePackageManifest(\n  pkg: PackageJson,\n  spec: NormalizationSpec,\n  options: NormalizeManifestOptions,\n) {\n  let modified = false;\n\n  for (const depField of [\"dependencies\", \"devDependencies\", \"peerDependencies\"]) {\n    const deps = pkg[depField];\n    if (!deps || typeof deps !== \"object\") continue;\n    if (normalizeDependencyMap(deps as Record<string, string>, spec, options)) {\n      modified = true;\n    }\n  }\n\n  if (pkg.workspaces && typeof pkg.workspaces === \"object\") {\n    const workspaces = pkg.workspaces as {\n      packages?: string[];\n      catalog?: Record<string, string>;\n    };\n\n    if (options.excludeFrameworkWorkspaces && Array.isArray(workspaces.packages)) {\n      const nextPackages = workspaces.packages.filter(\n        (entry) => !FRAMEWORK_PACKAGES.some((name) => entry === `packages/${name}`),\n      );\n      if (nextPackages.length !== workspaces.packages.length) {\n        workspaces.packages = nextPackages;\n        modified = true;\n      }\n    }\n\n    if (workspaces.catalog && typeof workspaces.catalog === \"object\") {\n      for (const [name, version] of Object.entries(workspaces.catalog)) {\n        const resolved = spec.rootCatalog[name];\n        if (resolved && resolved !== version) {\n          workspaces.catalog[name] = resolved;\n          modified = true;\n          continue;\n        }\n\n        if (version === \"workspace:*\" && spec.frameworkVersions[name]) {\n          workspaces.catalog[name] = `^${spec.frameworkVersions[name]}`;\n          modified = true;\n        }\n      }\n    }\n  }\n\n  if (options.removeWorkspaces && \"workspaces\" in pkg) {\n    delete pkg.workspaces;\n    modified = true;\n  }\n\n  if (options.removePublishScripts && pkg.scripts && typeof pkg.scripts === \"object\") {\n    const scripts = pkg.scripts as Record<string, string>;\n    let scriptsModified = false;\n    for (const key of [\"prepublishOnly\", \"prepack\", \"prepare\", \"postpack\"]) {\n      if (key in scripts) {\n        delete scripts[key];\n        scriptsModified = true;\n      }\n    }\n    if (scriptsModified) {\n      modified = true;\n      if (Object.keys(scripts).length === 0) {\n        delete pkg.scripts;\n      }\n    }\n  }\n\n  return modified;\n}\n\nexport async function normalizePackageManifestsInTree(opts: NormalizeTreeOptions) {\n  const spec = loadManifestNormalizationSpec(opts.sourceRootDir);\n  const files = await glob(\"**/package.json\", {\n    cwd: opts.targetDir,\n    nodir: true,\n    dot: false,\n    absolute: true,\n    ignore: [\"**/node_modules/**\"],\n  });\n\n  const updatedFiles: string[] = [];\n\n  for (const filePath of files) {\n    const pkg = readJson<PackageJson>(filePath);\n    if (normalizePackageManifest(pkg, spec, opts)) {\n      writeJson(filePath, pkg);\n      updatedFiles.push(filePath);\n    }\n  }\n\n  return updatedFiles;\n}\n\nfunction shouldCopyPackageFile(sourceDir: string, filePath: string) {\n  const relPath = relative(sourceDir, filePath);\n  if (!relPath) return true;\n  const segments = relPath.split(sep);\n  return !segments.includes(\"node_modules\") && !segments.includes(\"tests\");\n}\n\nfunction stripDevelopmentExports(pkg: PackageJson) {\n  const exports = pkg.exports;\n  if (!exports || typeof exports !== \"object\") return;\n\n  for (const key of Object.keys(exports as Record<string, unknown>)) {\n    const entry = (exports as Record<string, unknown>)[key];\n    if (entry && typeof entry === \"object\") {\n      delete (entry as Record<string, unknown>).development;\n    }\n  }\n}\n\nexport function stageReleasePackage(opts: {\n  repoRoot: string;\n  packageName: string;\n  outDir: string;\n}) {\n  const sourceDir = join(opts.repoRoot, \"packages\", opts.packageName);\n\n  rmSync(opts.outDir, { recursive: true, force: true });\n  mkdirSync(dirname(opts.outDir), { recursive: true });\n  cpSync(sourceDir, opts.outDir, {\n    recursive: true,\n    filter: (filePath) => shouldCopyPackageFile(sourceDir, filePath),\n  });\n  rmSync(join(opts.outDir, \"tests\"), { recursive: true, force: true });\n\n  const packageJsonPath = join(opts.outDir, \"package.json\");\n  const spec = loadManifestNormalizationSpec(opts.repoRoot);\n  const pkg = readJson<PackageJson>(packageJsonPath);\n\n  normalizePackageManifest(pkg, spec, {\n    resolveCatalogRefs: true,\n    preserveCatalogRefs: false,\n    removeWorkspaces: true,\n    removePublishScripts: true,\n  });\n\n  stripDevelopmentExports(pkg);\n\n  writeJson(packageJsonPath, pkg);\n}\n\nexport function stageReleasePackages(opts: {\n  repoRoot: string;\n  outDir: string;\n  packageNames?: string[];\n}) {\n  const packageNames = opts.packageNames ?? [...FRAMEWORK_PACKAGES];\n  rmSync(opts.outDir, { recursive: true, force: true });\n  mkdirSync(opts.outDir, { recursive: true });\n\n  for (const packageName of packageNames) {\n    stageReleasePackage({\n      repoRoot: opts.repoRoot,\n      packageName,\n      outDir: join(opts.outDir, packageName),\n    });\n  }\n}\n"],"mappings":"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"}