UNPKG

everything-dev

Version:

A consolidated product package for building Module Federation apps with oRPC APIs.

1 lines 12 kB
{"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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"}