{"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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"}