chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:25:08 +08:00
commit 6bc69ac13e
674 changed files with 92148 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
/**
* @param {{ name: string, version: string, private?: boolean }} pkg
* @param {string | null} registryVersion
* @returns {{ publish: boolean, reason: string }}
*/
export function shouldPublish(pkg, registryVersion) {
if (pkg.private) {
return { publish: false, reason: "private" };
}
if (registryVersion === pkg.version) {
return { publish: false, reason: "already published" };
}
if (registryVersion === null) {
return { publish: true, reason: "new package" };
}
return { publish: true, reason: "version changed" };
}
+106
View File
@@ -0,0 +1,106 @@
/**
* @param {string} version
* @returns {boolean}
*/
export function isValidVersion(version) {
return /^\d+\.\d+\.\d+(-[\w.]+)?$/.test(version);
}
/**
* @param {string[]} packageJsonRaws - Array of raw JSON strings
* @returns {Set<string>}
*/
export function collectWorkspaceNames(packageJsonRaws) {
const names = new Set();
for (const raw of packageJsonRaws) {
const pkg = JSON.parse(raw);
if (pkg.name) names.add(pkg.name);
}
return names;
}
/**
* @param {string} raw - Raw JSON string of a package.json
* @param {string} newVersion
* @param {Set<string>} workspaceNames
* @returns {string | null} Updated JSON string, or null if no change needed
*/
export function updatePackageJson(raw, newVersion, workspaceNames) {
const pkg = JSON.parse(raw);
// Set new version (skip root which has no version field)
if (pkg.version !== undefined) {
pkg.version = newVersion;
}
// Update internal dependency references
for (const depField of ["dependencies", "devDependencies"]) {
if (!pkg[depField]) continue;
for (const [name, value] of Object.entries(pkg[depField])) {
if (!workspaceNames.has(name)) continue;
// Skip wildcard references (used by private apps)
if (value === "*") continue;
pkg[depField][name] = newVersion;
}
}
// Leave peerDependencies ranges untouched
// Preserve original formatting (detect indent)
const indent = raw.match(/^(\s+)"/m)?.[1] ?? " ";
const newRaw = JSON.stringify(pkg, null, indent) + "\n";
return newRaw !== raw ? newRaw : null;
}
const CHANGELOG_REPO_URL = "https://github.com/dicebear/dicebear";
/**
* Promotes the `## [Unreleased]` section of a Keep a Changelog file to a
* released version: the existing entries are moved under a new
* `## [<version>] - <date>` heading, a fresh empty `## [Unreleased]` is kept on
* top, and the bottom link references are updated accordingly.
*
* @param {string} raw - Raw CHANGELOG.md content
* @param {string} newVersion
* @param {string} date - Release date in `YYYY-MM-DD` form
* @returns {string | null} Updated changelog, or null if there is nothing to do
*/
export function updateChangelog(raw, newVersion, date) {
const unreleasedHeading = /^## \[Unreleased\][^\n]*$/m;
if (!unreleasedHeading.test(raw)) {
return null;
}
// Idempotent: if this version was already promoted (e.g. a previous release
// run failed after writing the changelog), don't promote the now-empty
// Unreleased section again. The closing bracket prevents `10.0.1` from
// matching `10.0.10`.
if (raw.includes(`## [${newVersion}]`)) {
return null;
}
// Move the current Unreleased entries under a dated version heading and keep
// a fresh, empty Unreleased section on top.
let result = raw.replace(
unreleasedHeading,
`## [Unreleased]\n\n## [${newVersion}] - ${date}`
);
// Update the bottom link references when they follow the conventional shape.
const unreleasedLink =
/^\[Unreleased\]:\s*\S+\/compare\/v([\w.-]+)\.\.\.HEAD[^\n]*$/m;
const match = result.match(unreleasedLink);
if (match) {
const prevVersion = match[1];
result = result.replace(
unreleasedLink,
`[Unreleased]: ${CHANGELOG_REPO_URL}/compare/v${newVersion}...HEAD\n` +
`[${newVersion}]: ${CHANGELOG_REPO_URL}/compare/v${prevVersion}...v${newVersion}`
);
}
return result !== raw ? result : null;
}
+43
View File
@@ -0,0 +1,43 @@
import { readFileSync, readdirSync, existsSync } from "node:fs";
import { join } from "node:path";
/**
* Resolves workspace patterns from root package.json into absolute paths
* to each workspace's package.json. The root package.json is NOT included.
*
* @param {string} rootDir - Absolute path to the monorepo root
* @returns {string[]} Absolute paths to workspace package.json files
*/
export function resolveWorkspacePackages(rootDir) {
const rootPkg = JSON.parse(readFileSync(join(rootDir, "package.json"), "utf-8"));
const patterns = rootPkg.workspaces?.packages ?? rootPkg.workspaces ?? [];
const results = [];
for (const pattern of patterns) {
const starIdx = pattern.indexOf("*");
if (starIdx === -1) {
// Direct path — no glob
const pkgJson = join(rootDir, pattern, "package.json");
if (existsSync(pkgJson)) {
results.push(pkgJson);
}
} else {
// Expand single trailing `*` via readdirSync
const base = pattern.slice(0, starIdx);
const baseDir = join(rootDir, base);
if (!existsSync(baseDir)) continue;
for (const entry of readdirSync(baseDir, { withFileTypes: true })) {
if (!entry.isDirectory()) continue;
const pkgJson = join(baseDir, entry.name, "package.json");
if (existsSync(pkgJson)) {
results.push(pkgJson);
}
}
}
}
return results;
}