breakage 0.8.5 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +163 -47
- package/dist/{breakage-B7dJsgcu.js → breakage-DIY49fzP.js} +331 -217
- package/dist/breakage-DIY49fzP.js.map +1 -0
- package/dist/breakage.d.ts +111 -55
- package/dist/breakage.d.ts.map +1 -1
- package/dist/breakage.js +3 -1
- package/dist/breakage.x.js +78 -80
- package/dist/breakage.x.js.map +1 -1
- package/dist/changesets.d.ts +8 -0
- package/dist/changesets.d.ts.map +1 -0
- package/dist/changesets.js +27 -0
- package/dist/changesets.js.map +1 -0
- package/dist/release-BsdIDT4g.js +69 -0
- package/dist/release-BsdIDT4g.js.map +1 -0
- package/dist/release-D47BqRuB.d.ts +40 -0
- package/dist/release-D47BqRuB.d.ts.map +1 -0
- package/npm.md +55 -33
- package/package.json +45 -6
- package/src/breakage.ts +125 -73
- package/src/breakage.x.ts +148 -127
- package/src/changesets.ts +51 -0
- package/src/config.ts +128 -0
- package/src/npm/check.ts +51 -50
- package/src/npm/cli.ts +26 -22
- package/src/npm/config.ts +38 -6
- package/src/npm/environment.ts +10 -10
- package/src/npm/release.ts +9 -25
- package/src/npm/types.ts +5 -45
- package/src/release.ts +153 -0
- package/src/{npm/command.ts → task.ts} +2 -0
- package/dist/breakage-B7dJsgcu.js.map +0 -1
- package/dist/breakage.$configPath.schema.json +0 -33
- package/dist/breakage.help.schema.json +0 -6
- package/dist/breakage.main.schema.json +0 -33
- package/dist/breakage.npm.check.schema.json +0 -16
- package/dist/breakage.npm.help.schema.json +0 -6
- package/dist/breakage.npm.schema.json +0 -6
- package/dist/breakage.npm.test.$peer.$range.schema.json +0 -16
- package/dist/breakage.npm.test.schema.json +0 -16
- package/dist/breakage.prelude.$configPath.schema.json +0 -31
- package/dist/breakage.prelude.schema.json +0 -31
- package/dist/breakage.schema.schema.json +0 -10
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breakage-DIY49fzP.js","names":["latestReleaseTag","selectLatestReleaseTag"],"sources":["../src/task.ts","../src/npm/manifest.ts","../src/directory-lock.ts","../src/release-tag.ts","../src/baseline.ts","../src/test-file-state.ts","../src/npm/config.ts","../src/config.ts","../src/npm/release.ts","../src/npm/environment.ts","../src/npm/check.ts","../src/breakage.ts"],"sourcesContent":["import { spawn } from \"node:child_process\"\nimport path from \"node:path\"\n\nexport type CommandResult = { code: number; output: string }\n\n/** Capture output per environment so parallel runs cannot interleave their reports. */\nexport async function command(\n\tcommandLine: string,\n\tcwd: string,\n): Promise<CommandResult> {\n\tif (typeof commandLine !== `string` || !commandLine.trim())\n\t\tthrow new Error(`Commands must be nonempty shell strings.`)\n\treturn await new Promise((resolve, reject) => {\n\t\tconst child = spawn(commandLine, {\n\t\t\tcwd,\n\t\t\tshell: true,\n\t\t\tenv: {\n\t\t\t\t...process.env,\n\t\t\t\tNODE_PATH: ``,\n\t\t\t\tPATH: [\n\t\t\t\t\tpath.join(cwd, `node_modules/.bin`),\n\t\t\t\t\tpath.join(cwd, `../node_modules/.bin`),\n\t\t\t\t\tprocess.env.PATH,\n\t\t\t\t].join(path.delimiter),\n\t\t\t},\n\t\t\tstdio: [`ignore`, `pipe`, `pipe`],\n\t\t})\n\t\tlet output = ``\n\t\tconst collect = (chunk: Buffer): void => {\n\t\t\t// Bound diagnostics without interrupting a command that emits lots of output.\n\t\t\toutput = (output + chunk.toString()).slice(-1_000_000)\n\t\t}\n\t\tchild.stdout.on(`data`, collect)\n\t\tchild.stderr.on(`data`, collect)\n\t\tchild.on(`error`, reject)\n\t\tchild.on(`close`, (code, signal) =>\n\t\t\tresolve({ code: signal ? 2 : (code ?? 2), output }),\n\t\t)\n\t})\n}\n\nexport async function prepare(commandLine: string, cwd: string): Promise<void> {\n\tconst result = await command(commandLine, cwd)\n\tif (result.code !== 0)\n\t\tthrow new Error(\n\t\t\t`Command failed (${result.code}) in ${cwd}: ${commandLine}\\n${result.output}`,\n\t\t)\n}\n\nexport function errorMessage(error: unknown): string {\n\treturn error instanceof Error\n\t\t? `${error.message}${error.cause ? `\\n${errorMessage(error.cause)}` : ``}`\n\t\t: String(error)\n}\n","import { readFile } from \"node:fs/promises\"\n\nimport semver from \"semver\"\n\nexport type Manifest = {\n\tname: string\n\tversion: string\n\ttype?: string\n\tdependencies?: Record<string, string>\n\toptionalDependencies?: Record<string, string>\n\tdevDependencies?: Record<string, string>\n\tpeerDependencies?: Record<string, string>\n\tpeerDependenciesMeta?: Record<string, { optional?: boolean }>\n\tbreakage?: { candidates?: string[] }\n}\n\nexport function record(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === `object` && value !== null && !Array.isArray(value)\n}\n\nexport function packageName(value: string): boolean {\n\treturn /^(?:@[a-z0-9._-]+\\/)?[a-z0-9][a-z0-9._-]*$/.test(value)\n}\n\nexport function parseManifest(value: unknown, label: string): Manifest {\n\tif (\n\t\t!record(value) ||\n\t\ttypeof value.name !== `string` ||\n\t\t!packageName(value.name) ||\n\t\ttypeof value.version !== `string` ||\n\t\t!semver.valid(value.version)\n\t) {\n\t\tthrow new Error(`Invalid package identity in ${label}.`)\n\t}\n\tif (\n\t\tvalue.peerDependenciesMeta !== undefined &&\n\t\t(!record(value.peerDependenciesMeta) ||\n\t\t\tObject.values(value.peerDependenciesMeta).some(\n\t\t\t\t(entry) =>\n\t\t\t\t\t!record(entry) ||\n\t\t\t\t\t(entry.optional !== undefined && typeof entry.optional !== `boolean`),\n\t\t\t))\n\t) {\n\t\tthrow new Error(`Invalid peerDependenciesMeta in ${label}.`)\n\t}\n\tfor (const field of [\n\t\t`dependencies`,\n\t\t`optionalDependencies`,\n\t\t`devDependencies`,\n\t\t`peerDependencies`,\n\t] as const) {\n\t\tconst entries = value[field]\n\t\tif (\n\t\t\tentries !== undefined &&\n\t\t\t(!record(entries) ||\n\t\t\t\tObject.entries(entries).some(\n\t\t\t\t\t([name, spec]) => !packageName(name) || typeof spec !== `string`,\n\t\t\t\t))\n\t\t) {\n\t\t\tthrow new Error(`Invalid ${field} in ${label}.`)\n\t\t}\n\t}\n\tif (\n\t\tvalue.breakage !== undefined &&\n\t\t(!record(value.breakage) ||\n\t\t\t(value.breakage.candidates !== undefined &&\n\t\t\t\t(!Array.isArray(value.breakage.candidates) ||\n\t\t\t\t\tvalue.breakage.candidates.some(\n\t\t\t\t\t\t(name: unknown) => typeof name !== `string` || !packageName(name),\n\t\t\t\t\t))))\n\t) {\n\t\tthrow new Error(`Invalid candidate peers in ${label}.`)\n\t}\n\treturn value as Manifest\n}\n\nexport async function readManifest(filename: string): Promise<Manifest> {\n\treturn parseManifest(JSON.parse(await readFile(filename, `utf8`)), filename)\n}\n\n/** Current support is authored explicitly; only historical shorthand is resolved. */\nexport async function normalizeWorkspacePeers(\n\tmanifest: Manifest,\n\tversionAtBaseline?: (peer: string) => Promise<string>,\n): Promise<Manifest> {\n\tif (!manifest.peerDependencies) return manifest\n\tconst entries = await Promise.all(\n\t\tObject.entries(manifest.peerDependencies).map(async ([peer, range]) => {\n\t\t\tif (!range.startsWith(`workspace:`)) return [peer, range] as const\n\t\t\tconst requested = range.slice(`workspace:`.length)\n\t\t\tif ([``, `*`, `^`, `~`].includes(requested)) {\n\t\t\t\tif (!versionAtBaseline)\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Moving workspace peer range ${peer}: ${range} in ${manifest.name}. Declare explicit support eras, for example ^1.0.0 || ^2.0.0, so local version changes cannot change the support promise.`,\n\t\t\t\t\t)\n\t\t\t\tconst version = await versionAtBaseline(peer)\n\t\t\t\tif (!semver.valid(version))\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Invalid historical workspace version for ${peer}: ${version}.`,\n\t\t\t\t\t)\n\t\t\t\treturn [\n\t\t\t\t\tpeer,\n\t\t\t\t\t`${requested === `^` || requested === `~` ? requested : ``}${version}`,\n\t\t\t\t] as const\n\t\t\t}\n\t\t\ttry {\n\t\t\t\teras(requested)\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Unsupported workspace peer range for ${peer}: ${range}.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn [peer, requested] as const\n\t\t}),\n\t)\n\treturn { ...manifest, peerDependencies: Object.fromEntries(entries) }\n}\n\nexport function eras(range: string): string[] {\n\tconst parts = range.split(`||`).map((part) => part.trim())\n\tif (parts.some((part) => !part || semver.validRange(part) === null)) {\n\t\tthrow new Error(`Invalid peer range: ${range}.`)\n\t}\n\treturn parts\n}\n\n/** Previews only represent an explicitly enrolled exact preview. */\nexport function matches(version: string, range: string): boolean {\n\treturn eras(range).some((era) =>\n\t\tsemver.prerelease(version)\n\t\t\t? semver.valid(era.replace(/^=\\s*/, ``)) === semver.valid(version)\n\t\t\t: semver.satisfies(version, era),\n\t)\n}\n","import { mkdir, rmdir } from \"node:fs/promises\"\nimport { setTimeout } from \"node:timers/promises\"\n\nexport async function withDirectoryLock<T>(\n\tlock: string,\n\taction: () => Promise<T>,\n\twaitForCleanup = false,\n): Promise<T> {\n\tconst deadline = Date.now() + 60_000\n\tfor (;;) {\n\t\ttry {\n\t\t\tawait mkdir(lock)\n\t\t\tbreak\n\t\t} catch (thrown) {\n\t\t\tif ((thrown as NodeJS.ErrnoException).code !== `EEXIST`) throw thrown\n\t\t\tif (!waitForCleanup && Date.now() >= deadline) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Timed out waiting for ${lock}. Check for an interrupted operation before removing this lock.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tawait setTimeout(20)\n\t\t}\n\t}\n\ttry {\n\t\treturn await action()\n\t} finally {\n\t\tawait rmdir(lock)\n\t}\n}\n","type Release = { ref: string; core: string[]; prerelease: string[] }\n\nfunction compareInteger(a: string, b: string): number {\n\treturn a.length - b.length || (a > b ? 1 : a < b ? -1 : 0)\n}\n\nfunction compareRelease(a: Release, b: Release): number {\n\tfor (let index = 0; index < 3; index++) {\n\t\tconst difference = compareInteger(a.core[index]!, b.core[index]!)\n\t\tif (difference) return difference\n\t}\n\tif (!a.prerelease.length || !b.prerelease.length) {\n\t\treturn Number(!a.prerelease.length) - Number(!b.prerelease.length)\n\t}\n\tfor (\n\t\tlet index = 0;\n\t\tindex < Math.min(a.prerelease.length, b.prerelease.length);\n\t\tindex++\n\t) {\n\t\tconst left = a.prerelease[index]!\n\t\tconst right = b.prerelease[index]!\n\t\tconst leftNumeric = /^\\d+$/.test(left)\n\t\tconst rightNumeric = /^\\d+$/.test(right)\n\t\tconst difference =\n\t\t\tleftNumeric && rightNumeric\n\t\t\t\t? compareInteger(left, right)\n\t\t\t\t: leftNumeric !== rightNumeric\n\t\t\t\t\t? Number(rightNumeric) - Number(leftNumeric)\n\t\t\t\t\t: left > right\n\t\t\t\t\t\t? 1\n\t\t\t\t\t\t: left < right\n\t\t\t\t\t\t\t? -1\n\t\t\t\t\t\t\t: 0\n\t\tif (difference) return difference\n\t}\n\treturn a.prerelease.length - b.prerelease.length\n}\n\nexport function latestReleaseTag(\n\tremoteTags: string,\n\ttagPattern?: string,\n): string | undefined {\n\tconst pattern = tagPattern ? new RegExp(tagPattern) : undefined\n\tlet latest: Release | undefined\n\tfor (const line of remoteTags.split(`\\n`)) {\n\t\tif (pattern && !pattern.test(line)) continue\n\t\tconst ref = line.split(`\\t`)[1]?.replace(/\\^\\{\\}$/, ``)\n\t\tif (!ref?.startsWith(`refs/tags/`)) continue\n\t\tconst name = ref.slice(`refs/tags/`.length)\n\t\tconst version = name.slice(name.lastIndexOf(`@`) + 1)\n\t\tconst match =\n\t\t\t/^v?(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*))?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/.exec(\n\t\t\t\tversion,\n\t\t\t)\n\t\tif (!match) continue\n\t\tconst prerelease = match[4]?.split(`.`) ?? []\n\t\tif (prerelease.some((identifier) => /^0\\d+$/.test(identifier))) continue\n\t\tconst release: Release = { ref, core: match.slice(1, 4), prerelease }\n\t\tif (!latest || compareRelease(release, latest) > 0) latest = release\n\t}\n\treturn latest?.ref\n}\n","import { randomUUID } from \"node:crypto\"\nimport { mkdir, readFile, rename, rm, writeFile } from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport type { SimpleGit } from \"simple-git\"\nimport { simpleGit } from \"simple-git\"\n\nimport { withDirectoryLock } from \"./directory-lock.ts\"\nimport { latestReleaseTag } from \"./release-tag.ts\"\n\nexport type BaselineOptions = {\n\ttagPattern?: string | undefined\n\tbaseDirname?: string\n}\n\nexport type BreakagePreludeOptions = BaselineOptions & { out: string }\n\nexport type BreakageBaseline = {\n\tversion: 1\n\ttagPattern: string | null\n\tpackageDirectory: string\n\tref: string\n\tcommit: string\n}\n\nconst objectId = /^[a-f0-9]{40}(?:[a-f0-9]{24})?$/\n\nfunction isBaseline(value: unknown): value is BreakageBaseline {\n\tif (typeof value !== `object` || value === null) return false\n\tconst record = value as Partial<BreakageBaseline>\n\treturn (\n\t\trecord.version === 1 &&\n\t\t(record.tagPattern === null || typeof record.tagPattern === `string`) &&\n\t\ttypeof record.packageDirectory === `string` &&\n\t\ttypeof record.ref === `string` &&\n\t\trecord.ref.startsWith(`refs/tags/`) &&\n\t\ttypeof record.commit === `string` &&\n\t\tobjectId.test(record.commit)\n\t)\n}\n\n/** Resolve and fetch a release without running tests or changing the worktree. */\nexport async function breakagePrelude({\n\tout,\n\ttagPattern,\n\tbaseDirname = process.cwd(),\n}: BreakagePreludeOptions): Promise<BreakageBaseline> {\n\tconst filename = path.resolve(baseDirname, out)\n\tconst temporaryPath = `${filename}.${randomUUID()}.tmp`\n\tlet canInvalidate = false\n\ttry {\n\t\tconst git = simpleGit(baseDirname)\n\t\t// An ignored, untracked snapshot cannot make the compatibility check dirty.\n\t\tif (!(await git.raw([`check-ignore`, `--`, filename])).trim()) {\n\t\t\tthrow new Error(`Baseline output must be gitignored: ${filename}.`)\n\t\t}\n\t\tcanInvalidate = true\n\t\tconst remoteTags = await git.listRemote([`--tags`, `origin`])\n\t\tconst ref = latestReleaseTag(remoteTags, tagPattern)\n\t\tif (!ref) {\n\t\t\tthrow new Error(`No tags found matching the pattern \"${tagPattern}\".`)\n\t\t}\n\t\tconst refs = new Map(\n\t\t\tremoteTags\n\t\t\t\t.trim()\n\t\t\t\t.split(`\\n`)\n\t\t\t\t.map((line) => {\n\t\t\t\t\tconst [sha, name] = line.split(`\\t`)\n\t\t\t\t\treturn [name, sha]\n\t\t\t\t}),\n\t\t)\n\t\t// ls-remote supplies the peeled commit for annotated tags.\n\t\tconst commit = refs.get(`${ref}^{}`) ?? refs.get(ref)\n\t\tif (!commit || !objectId.test(commit)) {\n\t\t\tthrow new Error(`Could not resolve the release commit for ${ref}.`)\n\t\t}\n\t\tconst commonGitDirectory = await git.revparse([\n\t\t\t`--path-format=absolute`,\n\t\t\t`--git-common-dir`,\n\t\t])\n\t\tawait withDirectoryLock(\n\t\t\tpath.join(commonGitDirectory, `breakage-fetch.lock`),\n\t\t\t() => git.fetch([`origin`, commit, `--no-tags`, `--no-write-fetch-head`]),\n\t\t)\n\t\tif ((await git.raw([`cat-file`, `-t`, commit])).trim() !== `commit`) {\n\t\t\tthrow new Error(`Release ${ref} does not resolve to a commit.`)\n\t\t}\n\t\tconst baseline: BreakageBaseline = {\n\t\t\tversion: 1,\n\t\t\ttagPattern: tagPattern ?? null,\n\t\t\tpackageDirectory: await git.revparse([`--show-prefix`]),\n\t\t\tref,\n\t\t\tcommit,\n\t\t}\n\t\tawait mkdir(path.dirname(filename), { recursive: true })\n\t\tawait writeFile(temporaryPath, `${JSON.stringify(baseline, null, 2)}\\n`, {\n\t\t\tflag: `wx`,\n\t\t})\n\t\tawait rename(temporaryPath, filename)\n\t\treturn baseline\n\t} catch (cause) {\n\t\t// A failed refresh must never leave an older snapshot available as fallback.\n\t\tif (canInvalidate) await rm(filename, { force: true })\n\t\tthrow new Error(`Failed to prepare baseline ${filename}.`, { cause })\n\t} finally {\n\t\tawait rm(temporaryPath, { force: true })\n\t}\n}\n\nexport async function readBaseline(\n\tgit: SimpleGit,\n\tfilename: string,\n\t{ tagPattern }: BaselineOptions,\n): Promise<BreakageBaseline> {\n\ttry {\n\t\tconst baseline: unknown = JSON.parse(await readFile(filename, `utf8`))\n\t\tif (!isBaseline(baseline)) throw new Error(`Invalid baseline fields.`)\n\t\tif (\n\t\t\tbaseline.tagPattern !== (tagPattern ?? null) ||\n\t\t\tbaseline.packageDirectory !== (await git.revparse([`--show-prefix`]))\n\t\t) {\n\t\t\tthrow new Error(`Baseline belongs to a different package or tag pattern.`)\n\t\t}\n\t\tif (\n\t\t\t(\n\t\t\t\tawait git.raw([`check-ref-format`, `--normalize`, baseline.ref])\n\t\t\t).trim() !== baseline.ref\n\t\t) {\n\t\t\tthrow new Error(`Invalid release ref.`)\n\t\t}\n\t\tif (\n\t\t\t(await git.raw([`cat-file`, `-t`, baseline.commit])).trim() !== `commit`\n\t\t) {\n\t\t\tthrow new Error(`Pinned object is not a locally available commit.`)\n\t\t}\n\t\treturn baseline\n\t} catch (cause) {\n\t\tthrow new Error(\n\t\t\t`Missing, invalid, or unusable baseline ${filename}. Run breakage prelude again.`,\n\t\t\t{ cause },\n\t\t)\n\t}\n}\n","import { randomUUID } from \"node:crypto\"\nimport {\n\tchmod,\n\tlstat,\n\tmkdir,\n\treaddir,\n\treadFile,\n\trealpath,\n\trename,\n\trm,\n\twriteFile,\n} from \"node:fs/promises\"\nimport path from \"node:path\"\n\nimport type { SimpleGit } from \"simple-git\"\nimport { simpleGit } from \"simple-git\"\n\nimport { withDirectoryLock } from \"./directory-lock.ts\"\n\ntype ActiveCheck = {\n\tpid: number\n\tpaths: string[]\n\thead: string\n\trecoveryRequired?: boolean\n}\n\nfunction isActiveCheck(value: unknown): value is ActiveCheck {\n\tif (typeof value !== `object` || value === null) return false\n\tconst record = value as Partial<ActiveCheck>\n\treturn (\n\t\ttypeof record.pid === `number` &&\n\t\tNumber.isSafeInteger(record.pid) &&\n\t\trecord.pid > 0 &&\n\t\ttypeof record.head === `string` &&\n\t\t/^[a-f0-9]{40}(?:[a-f0-9]{24})?$/.test(record.head) &&\n\t\t(record.recoveryRequired === undefined ||\n\t\t\ttypeof record.recoveryRequired === `boolean`) &&\n\t\tArray.isArray(record.paths) &&\n\t\trecord.paths.length > 0 &&\n\t\trecord.paths.every(\n\t\t\t(file) =>\n\t\t\t\ttypeof file === `string` &&\n\t\t\t\t!path.isAbsolute(file) &&\n\t\t\t\t!path.win32.isAbsolute(file) &&\n\t\t\t\tfile\n\t\t\t\t\t.split(`/`)\n\t\t\t\t\t.every((part) => part !== `` && part !== `.` && part !== `..`),\n\t\t)\n\t)\n}\n\nasync function readRecoveryRecord(recordPath: string): Promise<ActiveCheck> {\n\ttry {\n\t\tconst record: unknown = JSON.parse(await readFile(recordPath, `utf8`))\n\t\tif (!isActiveCheck(record))\n\t\t\tthrow new TypeError(`Invalid recovery record fields`)\n\t\treturn record\n\t} catch (cause) {\n\t\tthrow new Error(\n\t\t\t`A breakage run needs recovery. The record ${recordPath} is unreadable or invalid. Verify no check is running and recover its test files before removing this record.`,\n\t\t\t{ cause },\n\t\t)\n\t}\n}\n\nasync function writeRecoveryRecord(\n\trecordPath: string,\n\trecord: ActiveCheck,\n): Promise<void> {\n\tconst temporaryPath = `${recordPath}.${randomUUID()}.tmp`\n\ttry {\n\t\tawait writeFile(temporaryPath, JSON.stringify(record), { flag: `wx` })\n\t\tawait rename(temporaryPath, recordPath)\n\t} finally {\n\t\tawait rm(temporaryPath, { force: true })\n\t}\n}\n\ntype TestFileState = {\n\tisClean: () => Promise<boolean>\n\treplaceTests: (\n\t\trelease: string,\n\t\tfiles: string[],\n\t) => Promise<() => Promise<void>>\n}\n\nfunction assertContained(root: string, filename: string): void {\n\tconst relative = path.relative(root, filename)\n\tif (\n\t\trelative === `..` ||\n\t\trelative.startsWith(`..${path.sep}`) ||\n\t\tpath.isAbsolute(relative)\n\t) {\n\t\tthrow new Error(`Cannot replace tests outside the worktree: ${filename}.`)\n\t}\n}\n\nasync function validateParents(\n\troot: string,\n\tfilenames: string[],\n): Promise<void> {\n\tconst checked = new Set<string>()\n\tfor (const filename of filenames) {\n\t\tassertContained(root, filename)\n\t\tfor (let parent = path.dirname(filename); ; parent = path.dirname(parent)) {\n\t\t\tif (checked.has(parent)) break\n\t\t\tconst stats = await lstat(parent).catch(\n\t\t\t\t(thrown: NodeJS.ErrnoException) => {\n\t\t\t\t\tif (thrown.code !== `ENOENT`) throw thrown\n\t\t\t\t},\n\t\t\t)\n\t\t\tif (stats && !stats.isDirectory())\n\t\t\t\tthrow new Error(`Cannot replace tests through ${parent}.`)\n\t\t\tchecked.add(parent)\n\t\t\tif (parent === root) break\n\t\t}\n\t}\n}\n\n// This lock covers Git setup and restoration only. Commands run after it is released.\nexport async function withTestFileState<T>(\n\tgit: SimpleGit,\n\tbaseDirname: string,\n\taction: (state: TestFileState) => Promise<T>,\n): Promise<T> {\n\tconst root = await realpath(await git.revparse([`--show-toplevel`]))\n\tbaseDirname = await realpath(baseDirname)\n\tassertContained(root, baseDirname)\n\tconst stateDirectory = path.join(\n\t\tawait git.revparse([`--absolute-git-dir`]),\n\t\t`breakage`,\n\t)\n\tawait mkdir(stateDirectory, { recursive: true })\n\tconst lock = path.join(stateDirectory, `lock`)\n\treturn withDirectoryLock(lock, async () => {\n\t\tconst activeChecks: ActiveCheck[] = []\n\t\tfor (const entry of await readdir(stateDirectory)) {\n\t\t\tif (!entry.endsWith(`.json`)) continue\n\t\t\tconst recordPath = path.join(stateDirectory, entry)\n\t\t\tconst record = await readRecoveryRecord(recordPath)\n\t\t\tlet interrupted = record.recoveryRequired\n\t\t\ttry {\n\t\t\t\tprocess.kill(record.pid, 0)\n\t\t\t} catch (thrown) {\n\t\t\t\tif ((thrown as NodeJS.ErrnoException).code !== `EPERM`)\n\t\t\t\t\tinterrupted = true\n\t\t\t}\n\t\t\tif (interrupted)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`A breakage run needs recovery. Restore the test paths recorded in ${recordPath} before removing that record.`,\n\t\t\t\t)\n\t\t\tactiveChecks.push(record)\n\t\t}\n\t\tconst activePaths = activeChecks.flatMap((record) => record.paths)\n\t\treturn action({\n\t\t\tisClean: async () =>\n\t\t\t\t!(await simpleGit(root).raw([\n\t\t\t\t\t`--no-optional-locks`,\n\t\t\t\t\t`status`,\n\t\t\t\t\t`--porcelain`,\n\t\t\t\t\t`--untracked-files=all`,\n\t\t\t\t\t`--`,\n\t\t\t\t\t`.`,\n\t\t\t\t\t...activePaths.map((file) => `:(top,literal,exclude)${file}`),\n\t\t\t\t])),\n\t\t\treplaceTests: async (release, files) => {\n\t\t\t\tconst paths = files.map((file) =>\n\t\t\t\t\tpath\n\t\t\t\t\t\t.relative(root, path.resolve(baseDirname, file))\n\t\t\t\t\t\t.split(path.sep)\n\t\t\t\t\t\t.join(`/`),\n\t\t\t\t)\n\t\t\t\tfor (const file of paths) {\n\t\t\t\t\tif (\n\t\t\t\t\t\tactivePaths.some(\n\t\t\t\t\t\t\t(active) =>\n\t\t\t\t\t\t\t\tfile === active ||\n\t\t\t\t\t\t\t\tfile.startsWith(`${active}/`) ||\n\t\t\t\t\t\t\t\tactive.startsWith(`${file}/`),\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Another breakage run is using ${file}. Concurrent checks must use disjoint test paths.`,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst head = await git.revparse([`HEAD`])\n\t\t\t\tconst currentFiles = new Set(\n\t\t\t\t\t(await git.raw([`ls-tree`, `-r`, `--name-only`, `-z`, head]))\n\t\t\t\t\t\t.split(`\\0`)\n\t\t\t\t\t\t.filter(Boolean),\n\t\t\t\t)\n\t\t\t\tconst existing = files.filter((file) => currentFiles.has(file))\n\t\t\t\tconst absent = files.filter((file) => !currentFiles.has(file))\n\t\t\t\tconst modes = new Map<string, number>()\n\t\t\t\tconst filenames = files.map((file) => path.resolve(baseDirname, file))\n\t\t\t\tawait validateParents(root, filenames)\n\t\t\t\tfor (const file of files) {\n\t\t\t\t\tconst filename = path.resolve(baseDirname, file)\n\n\t\t\t\t\tconst stats = await lstat(filename).catch(\n\t\t\t\t\t\t(thrown: NodeJS.ErrnoException) => {\n\t\t\t\t\t\t\tif (thrown.code !== `ENOENT`) throw thrown\n\t\t\t\t\t\t},\n\t\t\t\t\t)\n\t\t\t\t\tif (!currentFiles.has(file) && stats)\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Cannot overwrite the existing untracked path ${filename}.`,\n\t\t\t\t\t\t)\n\t\t\t\t\tif (stats?.isFile()) modes.set(filename, stats.mode)\n\t\t\t\t}\n\t\t\t\tconst recordPath = path.join(stateDirectory, `${randomUUID()}.json`)\n\t\t\t\tconst record: ActiveCheck = { pid: process.pid, paths, head }\n\t\t\t\tawait writeRecoveryRecord(recordPath, record)\n\t\t\t\tconst restore = async () => {\n\t\t\t\t\tawait writeRecoveryRecord(recordPath, {\n\t\t\t\t\t\t...record,\n\t\t\t\t\t\trecoveryRequired: true,\n\t\t\t\t\t})\n\t\t\t\t\tawait validateParents(root, filenames)\n\t\t\t\t\tif (existing.length)\n\t\t\t\t\t\tawait git.raw([\n\t\t\t\t\t\t\t`--literal-pathspecs`,\n\t\t\t\t\t\t\t`restore`,\n\t\t\t\t\t\t\t`--source=${head}`,\n\t\t\t\t\t\t\t`--worktree`,\n\t\t\t\t\t\t\t`--`,\n\t\t\t\t\t\t\t...existing,\n\t\t\t\t\t\t])\n\t\t\t\t\tfor (const file of absent)\n\t\t\t\t\t\tawait rm(path.resolve(baseDirname, file), { force: true })\n\t\t\t\t\tfor (const [filename, mode] of modes) await chmod(filename, mode)\n\t\t\t\t\tawait rm(recordPath)\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait git.raw([\n\t\t\t\t\t\t`--literal-pathspecs`,\n\t\t\t\t\t\t`restore`,\n\t\t\t\t\t\t`--source=${release}`,\n\t\t\t\t\t\t`--worktree`,\n\t\t\t\t\t\t`--`,\n\t\t\t\t\t\t...files,\n\t\t\t\t\t])\n\t\t\t\t} catch (thrown) {\n\t\t\t\t\tawait restore()\n\t\t\t\t\tthrow thrown\n\t\t\t\t}\n\t\t\t\treturn () => withDirectoryLock(lock, restore, true)\n\t\t\t},\n\t\t})\n\t})\n}\n","import path from \"node:path\"\nimport { type } from \"arktype\"\n\nimport { releaseSchema, rejectCertificationOptions } from \"../release.ts\"\n\nimport { eras, packageName, record } from \"./manifest.ts\"\nimport type { NpmConfig } from \"./types.ts\"\n\nexport const npmSuiteSchema = type({\n\t\"+\": `reject`,\n\tfiles: `string[]`,\n\tcommand: `string`,\n})\nexport const npmConfigSchema = type({\n\t\"+\": `reject`,\n\t\"release?\": releaseSchema,\n\t\"packageDirectory?\": `string`,\n\tartifact: `string`,\n\trepresentatives: `string | string[]`,\n\tlockfile: `string`,\n\tprepareCommand: `string`,\n\t\"installCommand?\": `string`,\n\tsuites: { \"[string]\": npmSuiteSchema },\n\t\"localPeers?\": {\n\t\t\"[string]\": { \"+\": `reject`, directory: `string`, artifact: `string` },\n\t},\n\tbaseline: type({ \"+\": `reject`, firstRelease: `true` }).or({\n\t\t\"+\": `reject`,\n\t\t\"tagPattern?\": `string`,\n\t\t\"baselineFile?\": `string`,\n\t}),\n})\n\nfunction nonempty(value: unknown): value is string {\n\treturn typeof value === `string` && value.trim().length > 0\n}\n\nexport function validateConfig(value: unknown): asserts value is NpmConfig {\n\tif (!record(value)) throw new Error(`Configuration must have an npm object.`)\n\trejectCertificationOptions(value)\n\tnpmConfigSchema.assert(value)\n\tfor (const key of [`artifact`, `lockfile`] as const) {\n\t\tif (!nonempty(value[key]))\n\t\t\tthrow new Error(`npm.${key} must be a nonempty string.`)\n\t}\n\tif (\n\t\tpath.isAbsolute(value.lockfile as string) ||\n\t\t(value.lockfile as string).split(/[\\\\/]/).includes(`..`)\n\t) {\n\t\tthrow new Error(`npm.lockfile must stay inside each representative.`)\n\t}\n\tif (!nonempty(value.prepareCommand))\n\t\tthrow new Error(\n\t\t\t`npm.prepareCommand must be a nonempty shell command string.`,\n\t\t)\n\tif (value.installCommand !== undefined && !nonempty(value.installCommand))\n\t\tthrow new Error(`Invalid npm.installCommand.`)\n\tfor (const key of [`packageDirectory`] as const) {\n\t\tif (value[key] !== undefined && !nonempty(value[key]))\n\t\t\tthrow new Error(`Invalid npm.${key}.`)\n\t}\n\tconst globs =\n\t\ttypeof value.representatives === `string`\n\t\t\t? [value.representatives]\n\t\t\t: value.representatives\n\tif (\n\t\t!Array.isArray(globs) ||\n\t\t!globs.length ||\n\t\tglobs.some((glob: unknown) => !nonempty(glob))\n\t) {\n\t\tthrow new Error(`npm.representatives must contain directory globs.`)\n\t}\n\tif (!record(value.suites) || !Object.keys(value.suites).length)\n\t\tthrow new Error(`Configure at least one npm peer suite.`)\n\tfor (const [peer, suite] of Object.entries(value.suites)) {\n\t\tif (\n\t\t\t!packageName(peer) ||\n\t\t\t!record(suite) ||\n\t\t\t!nonempty(suite.command) ||\n\t\t\t!Array.isArray(suite.files) ||\n\t\t\t!suite.files.length ||\n\t\t\tsuite.files.some((file: unknown) => !nonempty(file))\n\t\t) {\n\t\t\tthrow new Error(`Invalid npm suite for ${peer}.`)\n\t\t}\n\t}\n\tif (\n\t\t!record(value.baseline) ||\n\t\t(`firstRelease` in value.baseline\n\t\t\t? value.baseline.firstRelease !== true ||\n\t\t\t\tObject.keys(value.baseline).length !== 1\n\t\t\t: Object.entries(value.baseline).some(\n\t\t\t\t\t([key, item]) =>\n\t\t\t\t\t\t![`tagPattern`, `baselineFile`].includes(key) || !nonempty(item),\n\t\t\t\t))\n\t) {\n\t\tthrow new Error(\n\t\t\t`Configure npm.baseline with tagPattern/baselineFile or { firstRelease: true }.`,\n\t\t)\n\t}\n\tif (value.localPeers !== undefined) {\n\t\tif (!record(value.localPeers)) throw new Error(`Invalid npm.localPeers.`)\n\t\tfor (const [peer, local] of Object.entries(value.localPeers)) {\n\t\t\tif (\n\t\t\t\t!packageName(peer) ||\n\t\t\t\t!record(local) ||\n\t\t\t\t!nonempty(local.directory) ||\n\t\t\t\t!nonempty(local.artifact)\n\t\t\t) {\n\t\t\t\tthrow new Error(`Invalid local peer ${peer}.`)\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport function validatePeerRanges(peers: Record<string, string>): void {\n\tfor (const range of Object.values(peers)) eras(range)\n}\n","import { existsSync } from \"node:fs\"\nimport path from \"node:path\"\n\nimport { type } from \"arktype\"\nimport { cli, options, type ConfigInput } from \"comline\"\n\nimport { npmConfigSchema } from \"./npm/config.ts\"\nimport {\n\treleaseSchema,\n\tvalidateRelease,\n\trejectCertificationOptions,\n} from \"./release.ts\"\n\n// Reuse these field schemas for CLI metadata even though hooks cannot become JSON Schema.\nexport const configFields = {\n\ttagPattern: type(`string`),\n\tbaselineFile: type(`string`),\n\ttestPattern: type(`string`),\n\ttestCommand: type(`string`),\n\ttest: type(`string`),\n\tbaseDirname: type(`string`),\n\tverbose: type(`boolean`),\n\tout: type(`string`),\n}\nexport const configSchema = type({\n\t\"+\": `reject`,\n\t\"tagPattern?\": configFields.tagPattern.or(`undefined`),\n\t\"baselineFile?\": configFields.baselineFile.or(`undefined`),\n\t\"testPattern?\": configFields.testPattern,\n\t\"testCommand?\": configFields.testCommand,\n\t\"test?\": configFields.test,\n\t\"baseDirname?\": configFields.baseDirname,\n\t\"verbose?\": configFields.verbose.or(`undefined`),\n\t\"out?\": configFields.out,\n\t\"release?\": releaseSchema,\n\t\"npm?\": npmConfigSchema,\n})\n\n/** The complete config, with no fields exposed to argv by this loader. */\nexport const configOptions = options(`Breakage configuration`, configSchema, {\n\ttagPattern: { configOnly: true },\n\tbaselineFile: { configOnly: true },\n\ttestPattern: { configOnly: true },\n\ttestCommand: { configOnly: true },\n\ttest: { configOnly: true },\n\tbaseDirname: { configOnly: true },\n\tverbose: { configOnly: true },\n\tout: { configOnly: true },\n\trelease: { configOnly: true },\n\tnpm: { configOnly: true },\n})\nexport type BreakageConfig = ConfigInput<typeof configOptions>\n\n/** Share the root release model with npm checks unless they supply their own. */\nexport function defineConfig(config: BreakageConfig): BreakageConfig {\n\tif (config && typeof config === `object`) {\n\t\trejectCertificationOptions(config)\n\t\tif (config.npm) rejectCertificationOptions(config.npm)\n\t\tif (config.release !== undefined) validateRelease(config.release)\n\t\tif (config.npm?.release !== undefined) validateRelease(config.npm.release)\n\t}\n\tconfigSchema.assert(config)\n\treturn {\n\t\t...config,\n\t\t...(config.npm\n\t\t\t? {\n\t\t\t\t\tnpm: {\n\t\t\t\t\t\t...config.npm,\n\t\t\t\t\t\t...(config.release && config.npm.release === undefined\n\t\t\t\t\t\t\t? { release: config.release }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: {}),\n\t}\n}\n\nexport function defaultConfig(directory: string): string {\n\tconst filename = path.join(directory, `breakage.config.ts`)\n\tif (\n\t\t!existsSync(filename) &&\n\t\texistsSync(path.join(directory, `breakage.config.json`))\n\t)\n\t\tthrow new Error(\n\t\t\t`JSON configuration was removed. Migrate breakage.config.json to breakage.config.ts.`,\n\t\t)\n\treturn filename\n}\n\n/** Comline ignores absent discovered files; explicit paths must exist. */\nexport function configPath(filename: string, required = true): string {\n\tconst absolute = path.resolve(filename)\n\tif (path.extname(absolute) !== `.ts`)\n\t\tthrow new Error(\n\t\t\t`Configuration must be a .ts module with a default export; JSON configuration was removed.`,\n\t\t)\n\tif (required && !existsSync(absolute))\n\t\tthrow new Error(`Configuration file does not exist: ${absolute}`)\n\treturn absolute\n}\n\n/** Apply application semantics after Comline validates and merges configuration. */\nexport function resolveConfig(\n\tconfig: BreakageConfig,\n\tfilename?: string,\n): BreakageConfig {\n\treturn {\n\t\t...defineConfig(config),\n\t\tbaseDirname: path.resolve(\n\t\t\tfilename ? path.dirname(filename) : process.cwd(),\n\t\t\tconfig.baseDirname ?? `.`,\n\t\t),\n\t}\n}\n\n/** Use Comline's module loading and full-schema validation for programmatic and npm consumers. */\nexport async function loadConfig(filename: string): Promise<BreakageConfig> {\n\tconst absolute = configPath(filename)\n\tconst parse = cli({\n\t\tcliName: `breakage`,\n\t\trouteOptions: { \"\": configOptions },\n\t\tdiscoverConfigPath: () => absolute,\n\t})\n\treturn resolveConfig(\n\t\t(await parse.async([process.execPath, `breakage`])).inputs.opts,\n\t\tabsolute,\n\t)\n}\n","import path from \"node:path\"\n\nimport semver from \"semver\"\nimport { simpleGit } from \"simple-git\"\n\nimport { resolveReleaseDelta, type ReleaseDeltaContext } from \"../release.ts\"\nimport { readBaseline } from \"../baseline.ts\"\nimport { withDirectoryLock } from \"../directory-lock.ts\"\nimport { latestReleaseTag } from \"../release-tag.ts\"\nimport { validatePeerRanges } from \"./config.ts\"\nimport type { Manifest } from \"./manifest.ts\"\nimport { normalizeWorkspacePeers, parseManifest } from \"./manifest.ts\"\nimport type { NpmConfig, SupportChange } from \"./types.ts\"\n\nexport async function releaseVersion(\n\tconfig: NpmConfig,\n\tcontext: ReleaseDeltaContext,\n): Promise<string | undefined> {\n\treturn config.release\n\t\t? (await resolveReleaseDelta(config.release, context))?.version\n\t\t: undefined\n}\n\n/**\n * Compare the union, including adjacent alternatives. semver.subset compares each\n * conjunction to a single conjunction and cannot prove coverage by their union.\n * Membership can change only at comparator boundaries or prerelease tuple gates.\n */\nexport function includesRange(current: string, previous: string): boolean {\n\tconst ranges = [new semver.Range(previous), new semver.Range(current)]\n\tconst samples = new Set<string>([`0.0.0`, `0.0.0-0`])\n\tfor (const range of ranges) {\n\t\tfor (const conjunction of range.set) {\n\t\t\tfor (const comparator of conjunction) {\n\t\t\t\tconst version = comparator.semver\n\t\t\t\tif (typeof version === `symbol`) continue\n\t\t\t\tconst base = `${version.major}.${version.minor}.${version.patch}`\n\t\t\t\tsamples.add(version.version)\n\t\t\t\tsamples.add(base)\n\t\t\t\tsamples.add(`${base}-0`)\n\t\t\t\t// The immediate successor in a prerelease sequence appends numeric zero.\n\t\t\t\tif (version.prerelease.length) samples.add(`${version.version}.0`)\n\t\t\t\t// Stable versions are discrete; the next patch starts another tuple gate.\n\t\t\t\tconst next = semver.inc(base, `patch`)\n\t\t\t\tif (next) {\n\t\t\t\t\tsamples.add(next)\n\t\t\t\t\tsamples.add(`${next}-0`)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn [...samples].every(\n\t\t(version) =>\n\t\t\t!semver.satisfies(version, previous) ||\n\t\t\tsemver.satisfies(version, current),\n\t)\n}\n\nexport function supportChanges(\n\tprevious: Manifest,\n\tcurrent: Manifest,\n): SupportChange[] {\n\tconst before = previous.peerDependencies ?? {}\n\tconst after = current.peerDependencies ?? {}\n\tvalidatePeerRanges(before)\n\tvalidatePeerRanges(after)\n\treturn Object.entries(after).flatMap(([peer, range]) => {\n\t\tconst old = before[peer]\n\t\tconst wasOptional = previous.peerDependenciesMeta?.[peer]?.optional === true\n\t\tconst isOptional = current.peerDependenciesMeta?.[peer]?.optional === true\n\t\t// Absence scenarios are not generated, but making an optional peer required\n\t\t// still changes the installation contract for existing consumers.\n\t\treturn (old === undefined && isOptional) ||\n\t\t\t(old !== undefined &&\n\t\t\t\tincludesRange(range, old) &&\n\t\t\t\t!(wasOptional && !isOptional))\n\t\t\t? []\n\t\t\t: [\n\t\t\t\t\t{\n\t\t\t\t\t\tpeer,\n\t\t\t\t\t\treason:\n\t\t\t\t\t\t\told === undefined || (wasOptional && !isOptional)\n\t\t\t\t\t\t\t\t? (`required-peer` as const)\n\t\t\t\t\t\t\t\t: (`narrowed-range` as const),\n\t\t\t\t\t\tprevious: old ?? null,\n\t\t\t\t\t\tcurrent: range,\n\t\t\t\t\t},\n\t\t\t\t]\n\t})\n}\n\nexport async function previousManifest(\n\tconfig: NpmConfig,\n\tdirectory: string,\n): Promise<Manifest | undefined> {\n\tif (`firstRelease` in config.baseline) return undefined\n\tconst git = simpleGit(directory)\n\tlet commit: string\n\tif (config.baseline.baselineFile) {\n\t\tcommit = (\n\t\t\tawait readBaseline(\n\t\t\t\tgit,\n\t\t\t\tpath.resolve(directory, config.baseline.baselineFile),\n\t\t\t\tconfig.baseline,\n\t\t\t)\n\t\t).commit\n\t} else {\n\t\tconst tags = await git.listRemote([`--tags`, `origin`])\n\t\tconst ref = latestReleaseTag(tags, config.baseline.tagPattern)\n\t\tif (!ref)\n\t\t\tthrow new Error(\n\t\t\t\t`No npm release baseline found; configure a tag pattern or explicitly declare firstRelease.`,\n\t\t\t)\n\t\tconst refs = new Map(\n\t\t\ttags\n\t\t\t\t.trim()\n\t\t\t\t.split(`\\n`)\n\t\t\t\t.map((line) => {\n\t\t\t\t\tconst [sha, name] = line.split(`\\t`)\n\t\t\t\t\treturn [name, sha]\n\t\t\t\t}),\n\t\t)\n\t\tconst resolved = refs.get(`${ref}^{}`) ?? refs.get(ref)\n\t\tif (!resolved || !/^[a-f0-9]{40}(?:[a-f0-9]{24})?$/.test(resolved))\n\t\t\tthrow new Error(`Invalid release commit for ${ref}.`)\n\t\tcommit = resolved\n\t\tconst common = await git.revparse([\n\t\t\t`--path-format=absolute`,\n\t\t\t`--git-common-dir`,\n\t\t])\n\t\tawait withDirectoryLock(path.join(common, `breakage-fetch.lock`), () =>\n\t\t\tgit.fetch([`origin`, commit, `--no-tags`, `--no-write-fetch-head`]),\n\t\t)\n\t}\n\tconst prefix = await git.revparse([`--show-prefix`])\n\tconst manifest = parseManifest(\n\t\tJSON.parse(await git.show([`${commit}:${prefix}package.json`])),\n\t\t`release ${commit}`,\n\t)\n\treturn await normalizeWorkspacePeers(manifest, async (peer) => {\n\t\tconst local = config.localPeers?.[peer]\n\t\tif (!local)\n\t\t\tthrow new Error(\n\t\t\t\t`Historical workspace peer ${peer} needs a localPeers directory to resolve release ${commit}.`,\n\t\t\t)\n\t\tconst root = await git.revparse([`--show-toplevel`])\n\t\tconst relative = path.relative(\n\t\t\troot,\n\t\t\tpath.resolve(directory, local.directory),\n\t\t)\n\t\tif (\n\t\t\trelative === `..` ||\n\t\t\trelative.startsWith(`..${path.sep}`) ||\n\t\t\tpath.isAbsolute(relative)\n\t\t)\n\t\t\tthrow new Error(\n\t\t\t\t`Historical workspace peer ${peer} escapes the release repository.`,\n\t\t\t)\n\t\tconst filename = path\n\t\t\t.join(relative, `package.json`)\n\t\t\t.split(path.sep)\n\t\t\t.join(`/`)\n\t\tconst historical = parseManifest(\n\t\t\tJSON.parse(await git.show([`${commit}:${filename}`])),\n\t\t\t`release ${commit}:${filename}`,\n\t\t)\n\t\tif (historical.name !== peer)\n\t\t\tthrow new Error(\n\t\t\t\t`Historical workspace peer identity mismatch for ${peer}.`,\n\t\t\t)\n\t\treturn historical.version\n\t})\n}\n","import { randomUUID } from \"node:crypto\"\nimport * as fs from \"node:fs/promises\"\nimport {\n\tcopyFile,\n\tlstat,\n\tmkdir,\n\treadFile,\n\trealpath,\n\trename,\n\trm,\n\twriteFile,\n} from \"node:fs/promises\"\nimport { createRequire } from \"node:module\"\nimport path from \"node:path\"\n\nimport semver from \"semver\"\nimport { simpleGit } from \"simple-git\"\n\nimport { prepare } from \"../task.ts\"\nimport { validatePeerRanges } from \"./config.ts\"\nimport type { Manifest } from \"./manifest.ts\"\nimport { matches, normalizeWorkspacePeers, readManifest } from \"./manifest.ts\"\nimport { releaseVersion } from \"./release.ts\"\nimport type { NpmConfig, NpmPeerEvidence, NpmSuite } from \"./types.ts\"\n\nexport type Environment = {\n\tdirectory: string\n\tstage: string\n\tmanifest: Manifest\n\tpeers: Record<string, NpmPeerEvidence>\n\tcandidates: Record<\n\t\tstring,\n\t\t{\n\t\t\tdirectory: string\n\t\t\tartifact: string\n\t\t\tcurrentVersion: string\n\t\t\tversion: string\n\t\t\tmanifest: Manifest\n\t\t}\n\t>\n}\n\nexport function within(parent: string, child: string): boolean {\n\tconst relative = path.relative(parent, child)\n\treturn (\n\t\trelative === `` ||\n\t\t(!relative.startsWith(`..${path.sep}`) &&\n\t\t\trelative !== `..` &&\n\t\t\t!path.isAbsolute(relative))\n\t)\n}\n\nasync function exists(filename: string): Promise<boolean> {\n\ttry {\n\t\tawait lstat(filename)\n\t\treturn true\n\t} catch (error) {\n\t\tif ((error as NodeJS.ErrnoException).code === `ENOENT`) return false\n\t\tthrow error\n\t}\n}\n\nexport async function discover(\n\tconfig: NpmConfig,\n\tbase: string,\n): Promise<string[]> {\n\tconst found = new Set<string>()\n\tfor await (const name of fs.glob(config.representatives, {\n\t\tcwd: base,\n\t\texclude: [`**/node_modules/**`, `**/test/**`, `**/.git/**`],\n\t})) {\n\t\tconst directory = path.resolve(base, name)\n\t\tif (!(await lstat(directory)).isDirectory())\n\t\t\tthrow new Error(`Representative is not a directory: ${name}.`)\n\t\tfound.add(directory)\n\t}\n\tif (!found.size)\n\t\tthrow new Error(\n\t\t\t`No representative directories matched the configured globs.`,\n\t\t)\n\treturn [...found].sort()\n}\n\n/** A freshly created ignored stage is also the exclusive ownership lock. */\nexport async function withStage<T>(\n\tdirectory: string,\n\taction: (stage: string) => Promise<T>,\n): Promise<T> {\n\tconst stage = path.join(directory, `test`)\n\tconst git = simpleGit(directory)\n\tconst root = await git.revparse([`--show-toplevel`])\n\tif (!within(await realpath(root), await realpath(directory)))\n\t\tthrow new Error(`Representative escapes the repository: ${directory}.`)\n\tif (\n\t\t!(await git.raw([`check-ignore`, `--`, `${stage}/`])).trim() ||\n\t\t(await git.raw([`ls-files`, `--`, stage])).trim()\n\t) {\n\t\tthrow new Error(\n\t\t\t`Representative test/ must be gitignored and contain no tracked files: ${stage}.`,\n\t\t)\n\t}\n\ttry {\n\t\tawait mkdir(stage)\n\t} catch (cause) {\n\t\tthrow new Error(\n\t\t\t`Cannot own ${stage}; another run or preexisting files may be present. Remove it only after checking ownership.`,\n\t\t\t{ cause },\n\t\t)\n\t}\n\ttry {\n\t\treturn await action(stage)\n\t} finally {\n\t\tawait rm(stage, { recursive: true, force: true })\n\t}\n}\n\nasync function installed(\n\tdirectory: string,\n\tpeer: string,\n): Promise<NpmPeerEvidence> {\n\tconst location = path.join(directory, `node_modules`, peer)\n\tconst physical = await realpath(location)\n\t// Support pnpm's store links, while rejecting arbitrary workspace source links.\n\tif (!physical.split(path.sep).includes(`node_modules`))\n\t\tthrow new Error(`Peer ${peer} resolves to workspace source: ${physical}.`)\n\tconst manifest = await readManifest(path.join(physical, `package.json`))\n\tif (manifest.name !== peer)\n\t\tthrow new Error(`Expected ${peer}, found ${manifest.name} in ${location}.`)\n\treturn { version: manifest.version, path: physical, source: `installed` }\n}\n\nfunction representativeDeclarations(\n\tmanifest: Manifest,\n): Record<string, string> {\n\tfor (const field of [\n\t\t`dependencies`,\n\t\t`devDependencies`,\n\t\t`optionalDependencies`,\n\t\t`peerDependencies`,\n\t] as const) {\n\t\tfor (const [name, specifier] of Object.entries(manifest[field] ?? {})) {\n\t\t\tconst version = semver.parse(specifier)\n\t\t\t// Semver's normalized version omits build metadata; exact pins retain it.\n\t\t\tconst exact =\n\t\t\t\tversion &&\n\t\t\t\t`${version.version}${version.build.length ? `+${version.build.join(`.`)}` : ``}`\n\t\t\tif (!exact || specifier !== exact)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Representative ${manifest.name} must pin ${field}.${name} to an exact version, such as 1.0.0; received ${JSON.stringify(specifier)}. Declare support ranges in the package under test, and use breakage.candidates for coordinated local releases.`,\n\t\t\t\t)\n\t\t}\n\t}\n\tfor (const [peer, development] of Object.entries(\n\t\tmanifest.devDependencies ?? {},\n\t)) {\n\t\tfor (const field of [`dependencies`, `optionalDependencies`] as const) {\n\t\t\tconst runtime = manifest[field]?.[peer]\n\t\t\tif (runtime !== undefined && runtime !== development)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Conflicting representative declarations for ${peer}: devDependencies has ${development}, but ${field} has ${runtime}. Use one consistent requirement.`,\n\t\t\t\t)\n\t\t}\n\t}\n\t// Optional runtime declarations retain npm's override of required ones.\n\treturn {\n\t\t...manifest.devDependencies,\n\t\t...manifest.dependencies,\n\t\t...manifest.optionalDependencies,\n\t}\n}\n\n/** Select exact pins without acquiring or preparing their stages. */\nexport async function maySelectEnvironment(\n\tconfig: NpmConfig,\n\tbase: string,\n\tdirectory: string,\n\tpackageManifest: Manifest,\n\tselection: { peer: string; range: string },\n): Promise<boolean> {\n\tconst manifest = await readManifest(path.join(directory, `package.json`))\n\tconst declarations = representativeDeclarations(manifest)\n\tconst { peer, range } = selection\n\tif (peer === packageManifest.name)\n\t\treturn matches(packageManifest.version, range)\n\tif (manifest.breakage?.candidates?.includes(peer)) {\n\t\tconst local = config.localPeers?.[peer]\n\t\tif (!local)\n\t\t\tthrow new Error(`Candidate ${peer} has no localPeers configuration.`)\n\t\tconst packageDirectory = path.resolve(base, local.directory)\n\t\tconst current = await readManifest(\n\t\t\tpath.join(packageDirectory, `package.json`),\n\t\t)\n\t\tif (current.name !== peer)\n\t\t\tthrow new Error(`Local peer identity mismatch for ${peer}.`)\n\t\tconst release = await releaseVersion(config, {\n\t\t\tpackageName: peer,\n\t\t\tpackageDirectory,\n\t\t\tcurrentVersion: current.version,\n\t\t})\n\t\tif (release === undefined)\n\t\t\tthrow new Error(`Candidate ${peer} has no release version.`)\n\t\treturn matches(release, range)\n\t}\n\tconst declared = declarations[peer]\n\treturn declared !== undefined && matches(declared, range)\n}\n\nexport async function prepareEnvironment(\n\tconfig: NpmConfig,\n\tbase: string,\n\tdirectory: string,\n\tstage: string,\n\tpackageManifest: Manifest,\n): Promise<Environment> {\n\tconst peerNames = Object.keys(packageManifest.peerDependencies ?? {})\n\tconst filename = path.join(directory, `package.json`)\n\tconst lockfile = path.join(directory, config.lockfile)\n\tfor (const input of [filename, lockfile]) {\n\t\tif (\n\t\t\t!(await lstat(input)).isFile() ||\n\t\t\t!within(directory, await realpath(input))\n\t\t)\n\t\t\tthrow new Error(\n\t\t\t\t`Installation inputs must be regular files inside the representative: ${input}.`,\n\t\t\t)\n\t}\n\tconst inputs = await Promise.all([readFile(filename), readFile(lockfile)])\n\tconst manifest = await readManifest(filename)\n\tconst declarations = representativeDeclarations(manifest)\n\tconst candidates: Environment[`candidates`] = {}\n\tfor (const peer of manifest.breakage?.candidates ?? []) {\n\t\tif (!peerNames.includes(peer))\n\t\t\tthrow new Error(\n\t\t\t\t`Candidate ${peer} is not a declared peer of the package under test.`,\n\t\t\t)\n\t\tconst local = config.localPeers?.[peer]\n\t\tif (!local)\n\t\t\tthrow new Error(`Candidate ${peer} has no localPeers configuration.`)\n\t\tconst localDirectory = path.resolve(base, local.directory)\n\t\tconst localManifest = await normalizeWorkspacePeers(\n\t\t\tawait readManifest(path.join(localDirectory, `package.json`)),\n\t\t)\n\t\tif (localManifest.name !== peer)\n\t\t\tthrow new Error(`Local peer identity mismatch for ${peer}.`)\n\t\tvalidatePeerRanges(localManifest.peerDependencies ?? {})\n\t\tconst evidence = await releaseVersion(config, {\n\t\t\tpackageName: peer,\n\t\t\tpackageDirectory: localDirectory,\n\t\t\tcurrentVersion: localManifest.version,\n\t\t})\n\t\tif (evidence === undefined)\n\t\t\tthrow new Error(`Candidate ${peer} has no release version.`)\n\t\tcandidates[peer] = {\n\t\t\tdirectory: localDirectory,\n\t\t\tartifact: path.resolve(base, local.artifact),\n\t\t\tcurrentVersion: localManifest.version,\n\t\t\tversion: evidence,\n\t\t\tmanifest: localManifest,\n\t\t}\n\t}\n\tconst relevant = [\n\t\t...new Set([\n\t\t\t...peerNames,\n\t\t\t...Object.values(candidates).flatMap((candidate) =>\n\t\t\t\tObject.keys(candidate.manifest.peerDependencies ?? {}),\n\t\t\t),\n\t\t]),\n\t].filter(\n\t\t(peer) =>\n\t\t\tpeer === packageManifest.name ||\n\t\t\tdeclarations[peer] !== undefined ||\n\t\t\tcandidates[peer] !== undefined,\n\t)\n\tconst before: Record<string, string> = {}\n\tfor (const peer of relevant) {\n\t\tif (\n\t\t\tpeer !== packageManifest.name &&\n\t\t\t!candidates[peer] &&\n\t\t\t(await exists(path.join(directory, `node_modules`, peer)))\n\t\t)\n\t\t\tbefore[peer] = (await installed(directory, peer)).version\n\t}\n\tconst preparation = await prepare(config.prepareCommand, directory).then(\n\t\t() => ({ ok: true as const }),\n\t\t(error: unknown) => ({ ok: false as const, error }),\n\t)\n\tconst after = await Promise.all(\n\t\t[filename, lockfile].map((input) =>\n\t\t\treadFile(input).catch(() => Buffer.alloc(0)),\n\t\t),\n\t)\n\tif (inputs.some((input, index) => !input.equals(after[index]!))) {\n\t\tawait Promise.all(\n\t\t\t[filename, lockfile].map(async (input, index) => {\n\t\t\t\t// Recreate an input rather than writing through a link introduced by a command.\n\t\t\t\tawait rm(input, { force: true })\n\t\t\t\tawait writeFile(input, inputs[index]!, { flag: `wx` })\n\t\t\t}),\n\t\t)\n\t\tthrow new Error(\n\t\t\t`Frozen preparation changed the manifest or lockfile in ${directory}; restored the original inputs.`,\n\t\t\t{ cause: preparation.ok ? undefined : preparation.error },\n\t\t)\n\t}\n\tif (!preparation.ok) throw preparation.error\n\tconst peers: Environment[`peers`] = {}\n\tfor (const peer of relevant) {\n\t\tconst candidate = candidates[peer]\n\t\tconst staged = candidate !== undefined || peer === packageManifest.name\n\t\tif (\n\t\t\t!staged &&\n\t\t\tObject.hasOwn(manifest.optionalDependencies ?? {}, peer) &&\n\t\t\t!(await exists(path.join(directory, `node_modules`, peer)))\n\t\t)\n\t\t\tcontinue\n\t\tconst evidence: NpmPeerEvidence = staged\n\t\t\t? {\n\t\t\t\t\tversion: candidate?.version ?? packageManifest.version,\n\t\t\t\t\tpath: path.join(stage, `node_modules`, peer),\n\t\t\t\t\tsource: `candidate`,\n\t\t\t\t}\n\t\t\t: await installed(directory, peer)\n\t\tconst specifier = declarations[peer]\n\t\tif (\n\t\t\t!(staged && specifier === undefined) &&\n\t\t\tevidence.version !== specifier\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`Representative ${peer}@${evidence.version} does not match its manifest pin ${specifier ?? `(missing)`}.`,\n\t\t\t)\n\t\t}\n\t\tif (before[peer] && before[peer] !== evidence.version)\n\t\t\tthrow new Error(\n\t\t\t\t`Stale installed ${peer}: frozen preparation changed ${before[peer]} to ${evidence.version}.`,\n\t\t\t)\n\t\tfor (const [localPeer, local] of Object.entries(config.localPeers ?? {})) {\n\t\t\tif (staged) continue\n\t\t\tconst localDirectory = path.resolve(base, local.directory)\n\t\t\t// Historical-only registrations need not exist in today's checkout.\n\t\t\tif (\n\t\t\t\t!peerNames.includes(localPeer) &&\n\t\t\t\t!relevant.includes(localPeer) &&\n\t\t\t\t!(await exists(localDirectory))\n\t\t\t)\n\t\t\t\tcontinue\n\t\t\tif (within(await realpath(localDirectory), evidence.path))\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Released peer ${peer} resolves into a local workspace package.`,\n\t\t\t\t)\n\t\t}\n\t\tpeers[peer] = evidence\n\t}\n\treturn { directory, stage, manifest, peers, candidates }\n}\n\n/** Validate the complete coordinated formulation before an audit or execution. */\nexport function checkCandidatePeers(\n\tenvironment: Environment,\n\tfocused: boolean,\n): string[] {\n\tconst conflicts: string[] = []\n\tfor (const [name, candidate] of Object.entries(environment.candidates)) {\n\t\tfor (const [peer, range] of Object.entries(\n\t\t\tcandidate.manifest.peerDependencies ?? {},\n\t\t)) {\n\t\t\tconst evidence = environment.peers[peer]\n\t\t\tif (!evidence) {\n\t\t\t\tif (candidate.manifest.peerDependenciesMeta?.[peer]?.optional) continue\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Complete representative is missing required peer ${peer}: ${range} of coordinated candidate ${name}@${candidate.version}.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\t// This is declaration membership; exact-preview coverage is audited separately.\n\t\t\tif (!semver.satisfies(evidence.version, range))\n\t\t\t\tconflicts.push(\n\t\t\t\t\t`Coordinated candidate ${name}@${candidate.version} requires ${peer}: ${range}, but the representative provides ${peer}@${evidence.version}.`,\n\t\t\t\t)\n\t\t}\n\t}\n\tif (conflicts.length && !focused) throw new Error(conflicts.join(`\\n`))\n\treturn conflicts.map(\n\t\t(conflict) =>\n\t\t\t`${conflict} Running focused exploration outside declared support.`,\n\t)\n}\n\nasync function copySuite(\n\tbase: string,\n\tstage: string,\n\tsuite: NpmSuite,\n): Promise<void> {\n\tfor (const pattern of suite.files) {\n\t\tif (path.isAbsolute(pattern) || pattern.split(/[\\\\/]/).includes(`..`))\n\t\t\tthrow new Error(`Suite pattern must stay inside the package: ${pattern}.`)\n\t\tlet count = 0\n\t\tfor await (const filename of fs.glob(pattern, {\n\t\t\tcwd: base,\n\t\t\texclude: [\n\t\t\t\t`**/node_modules/**`,\n\t\t\t\t`**/.git/**`,\n\t\t\t\tpath.relative(base, stage),\n\t\t\t\t`${path.relative(base, stage)}/**`,\n\t\t\t],\n\t\t})) {\n\t\t\tconst source = path.resolve(base, filename)\n\t\t\tconst stat = await lstat(source)\n\t\t\tif (stat.isDirectory()) continue\n\t\t\tif (\n\t\t\t\t!stat.isFile() ||\n\t\t\t\t!within(await realpath(base), await realpath(source))\n\t\t\t)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Suite inputs must be regular package files: ${filename}.`,\n\t\t\t\t)\n\t\t\t// Refuse a symlink anywhere in the source path, even if its target is internal.\n\t\t\tlet segment = base\n\t\t\tfor (const part of filename.split(path.sep)) {\n\t\t\t\tsegment = path.join(segment, part)\n\t\t\t\tif ((await lstat(segment)).isSymbolicLink())\n\t\t\t\t\tthrow new Error(`Suite inputs cannot follow symlinks: ${filename}.`)\n\t\t\t}\n\t\t\tif (\n\t\t\t\t[\n\t\t\t\t\t`package.json`,\n\t\t\t\t\t`package-lock.json`,\n\t\t\t\t\t`npm-shrinkwrap.json`,\n\t\t\t\t\t`.npmrc`,\n\t\t\t\t].includes(filename) ||\n\t\t\t\tfilename.split(path.sep).includes(`node_modules`)\n\t\t\t) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Suite input collides with the consumer installation: ${filename}.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tconst destination = path.resolve(stage, filename)\n\t\t\tif (!within(stage, destination))\n\t\t\t\tthrow new Error(`Suite path escapes its stage: ${filename}.`)\n\t\t\tawait mkdir(path.dirname(destination), { recursive: true })\n\t\t\tawait copyFile(source, destination)\n\t\t\tcount++\n\t\t}\n\t\tif (!count) throw new Error(`Suite pattern matched no files: ${pattern}.`)\n\t}\n}\n\nasync function findPackage(\n\tfrom: string,\n\tname: string,\n\tinstallation: string,\n): Promise<string | undefined> {\n\tconst origin = await realpath(from)\n\t// A linked store package may resolve siblings in its own installation namespace.\n\t// Never grant access to the store's or checkout's unrelated ancestor installs.\n\tconst parts = origin.split(path.sep)\n\tconst modules = parts.lastIndexOf(`node_modules`)\n\tconst boundary = within(installation, origin)\n\t\t? installation\n\t\t: modules < 0\n\t\t\t? origin\n\t\t\t: parts.slice(0, modules + 1).join(path.sep)\n\tconst lookup =\n\t\tcreateRequire(path.join(origin, `__breakage_probe__.ts`)).resolve.paths(\n\t\t\tname,\n\t\t) ?? []\n\tfor (const directory of lookup) {\n\t\tconst location = path.join(directory, name)\n\t\t// An installed but broken package must fail verification, not look absent.\n\t\tif (await exists(location)) {\n\t\t\tif (!within(installation, directory) && !within(boundary, directory))\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Dependency ${name} resolves outside the representative installation: ${location}.`,\n\t\t\t\t)\n\t\t\treturn await realpath(location)\n\t\t}\n\t}\n\treturn undefined\n}\n\nasync function resolvePackage(\n\tfrom: string,\n\tname: string,\n\tinstallation: string,\n): Promise<string> {\n\tconst location = await findPackage(from, name, installation)\n\tif (location !== undefined) return location\n\tthrow new Error(`Cannot resolve ${name} from ${from}.`)\n}\n\nexport async function stageCandidate(\n\tconfig: NpmConfig,\n\tbase: string,\n\tmanifest: Manifest,\n\tenvironment: Environment,\n\tsuites: NpmSuite[],\n): Promise<void> {\n\tconst { stage, candidates } = environment\n\tconst artifacts = {\n\t\t[manifest.name]: path.resolve(base, config.artifact),\n\t\t...Object.fromEntries(\n\t\t\tObject.entries(candidates).map(([name, entry]) => [name, entry.artifact]),\n\t\t),\n\t}\n\tif (candidates[manifest.name])\n\t\tthrow new Error(\n\t\t\t`The package under test cannot also be its own candidate peer.`,\n\t\t)\n\tfor (const artifact of Object.values(artifacts)) {\n\t\tif (!(await lstat(artifact)).isFile())\n\t\t\tthrow new Error(`Candidate artifact must be a packed file: ${artifact}.`)\n\t}\n\tawait writeFile(\n\t\tpath.join(stage, `package.json`),\n\t\tJSON.stringify({\n\t\t\tname: `breakage-consumer`,\n\t\t\tversion: `0.0.0`,\n\t\t\tprivate: true,\n\t\t\ttype: environment.manifest.type ?? `module`,\n\t\t\tdependencies: Object.fromEntries(\n\t\t\t\tObject.entries(artifacts).map(([name, artifact]) => [\n\t\t\t\t\tname,\n\t\t\t\t\t`file:${artifact}`,\n\t\t\t\t]),\n\t\t\t),\n\t\t}),\n\t)\n\tawait prepare(\n\t\tconfig.installCommand ??\n\t\t\t`npm install --prefix . --workspaces=false --ignore-scripts --legacy-peer-deps --package-lock=false --no-audit --no-fund`,\n\t\tstage,\n\t)\n\tfor (const [name] of Object.entries(artifacts)) {\n\t\tconst directory = path.join(stage, `node_modules`, name)\n\t\tif (!within(stage, await realpath(directory)))\n\t\t\tthrow new Error(\n\t\t\t\t`Candidate ${name} must be installed inside the test stage.`,\n\t\t\t)\n\t\tconst filename = path.join(directory, `package.json`)\n\t\tconst packed = await readManifest(filename)\n\t\tconst candidate = candidates[name]\n\t\tif (\n\t\t\tpacked.name !== name ||\n\t\t\t(candidate\n\t\t\t\t? ![candidate.currentVersion, candidate.version].includes(\n\t\t\t\t\t\tpacked.version,\n\t\t\t\t\t)\n\t\t\t\t: packed.version !== manifest.version)\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`Candidate archive identity/version mismatch for ${name}@${packed.version}.`,\n\t\t\t)\n\t\t}\n\t\tconst expectedManifest = candidate?.manifest ?? manifest\n\t\tif (\n\t\t\tObject.keys({\n\t\t\t\t...packed.peerDependencies,\n\t\t\t\t...expectedManifest.peerDependencies,\n\t\t\t}).some(\n\t\t\t\t(peer) =>\n\t\t\t\t\tpacked.peerDependencies?.[peer] !==\n\t\t\t\t\t\texpectedManifest.peerDependencies?.[peer] ||\n\t\t\t\t\tBoolean(packed.peerDependenciesMeta?.[peer]?.optional) !==\n\t\t\t\t\t\tBoolean(expectedManifest.peerDependenciesMeta?.[peer]?.optional),\n\t\t\t)\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`Candidate archive has stale peer declarations; rebuild and pack ${name}.`,\n\t\t\t)\n\t\t}\n\t\tif (candidate) {\n\t\t\tconst evidence = environment.peers[name]\n\t\t\tif (evidence) evidence.archiveVersion = packed.version\n\t\t\tif (packed.version !== candidate.version) {\n\t\t\t\t// Replace the entry: installed files may share an inode with a cache.\n\t\t\t\tconst raw = JSON.parse(await readFile(filename, `utf8`)) as Record<\n\t\t\t\t\tstring,\n\t\t\t\t\tunknown\n\t\t\t\t>\n\t\t\t\tconst temporary = path.join(\n\t\t\t\t\tpath.dirname(filename),\n\t\t\t\t\t`.breakage-${randomUUID()}.json`,\n\t\t\t\t)\n\t\t\t\tawait writeFile(\n\t\t\t\t\ttemporary,\n\t\t\t\t\tJSON.stringify({ ...raw, version: candidate.version }),\n\t\t\t\t\t{ flag: `wx` },\n\t\t\t\t)\n\t\t\t\ttry {\n\t\t\t\t\tawait rename(temporary, filename)\n\t\t\t\t} finally {\n\t\t\t\t\tawait rm(temporary, { force: true })\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tfor (const suite of suites) await copySuite(base, stage, suite)\n\tawait verifyResolution(manifest, environment)\n}\n\nexport async function verifyResolution(\n\tmanifest: Manifest,\n\tenvironment: Environment,\n): Promise<void> {\n\tconst { stage, peers } = environment\n\tconst installation = await realpath(environment.directory)\n\tconst packages = [manifest.name, ...Object.keys(environment.candidates)]\n\tfor (const [peer, evidence] of Object.entries(peers)) {\n\t\tconst expected = await realpath(evidence.path)\n\t\tif ((await resolvePackage(stage, peer, installation)) !== expected)\n\t\t\tthrow new Error(`Tests resolve a shadow copy of ${peer}.`)\n\t\tfor (const name of packages) {\n\t\t\tif (name === peer) continue\n\t\t\tconst origin = path.join(stage, `node_modules`, name)\n\t\t\tif ((await resolvePackage(origin, peer, installation)) !== expected)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Candidate ${name} resolves a different instance of ${peer} than its tests.`,\n\t\t\t\t)\n\t\t}\n\t\tconst actual = await readManifest(path.join(expected, `package.json`))\n\t\tif (actual.name !== peer || actual.version !== evidence.version)\n\t\t\tthrow new Error(`Peer identity changed during execution: ${peer}.`)\n\t}\n\t// Runtime dependency peers can be singletons too (for example a React helper).\n\tconst visited = new Set<string>()\n\tconst pending = packages.map((name) => path.join(stage, `node_modules`, name))\n\twhile (pending.length) {\n\t\tconst directory = await realpath(pending.pop()!)\n\t\tif (visited.has(directory)) continue\n\t\tif (!directory.split(path.sep).includes(`node_modules`))\n\t\t\tthrow new Error(\n\t\t\t\t`Runtime dependency resolves to workspace source: ${directory}.`,\n\t\t\t)\n\t\tvisited.add(directory)\n\t\tconst installedManifest = await readManifest(\n\t\t\tpath.join(directory, `package.json`),\n\t\t)\n\t\tfor (const peer of Object.keys(installedManifest.peerDependencies ?? {})) {\n\t\t\tconst evidence = peers[peer]\n\t\t\tif (\n\t\t\t\tevidence &&\n\t\t\t\t(await resolvePackage(directory, peer, installation)) !==\n\t\t\t\t\t(await realpath(evidence.path))\n\t\t\t)\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Runtime dependency ${installedManifest.name} resolves a different instance of ${peer}.`,\n\t\t\t\t)\n\t\t}\n\t\tconst optional = installedManifest.optionalDependencies ?? {}\n\t\tfor (const dependency of Object.keys({\n\t\t\t...installedManifest.dependencies,\n\t\t\t...optional,\n\t\t})) {\n\t\t\t// npm lets optionalDependencies override dependencies of the same name.\n\t\t\tif (Object.hasOwn(optional, dependency)) {\n\t\t\t\tconst location = await findPackage(directory, dependency, installation)\n\t\t\t\tif (location !== undefined) pending.push(location)\n\t\t\t} else {\n\t\t\t\tpending.push(await resolvePackage(directory, dependency, installation))\n\t\t\t}\n\t\t}\n\t}\n}\n","import path from \"node:path\"\n\nimport {\n\tresolveReleaseDelta,\n\tversionDelta,\n\ttype ReleaseDeltaContext,\n\ttype VersionTransition,\n} from \"../release.ts\"\nimport { command, errorMessage } from \"../task.ts\"\nimport { validateConfig, validatePeerRanges } from \"./config.ts\"\nimport {\n\tcheckCandidatePeers,\n\tdiscover,\n\tmaySelectEnvironment,\n\tprepareEnvironment,\n\tstageCandidate,\n\tverifyResolution,\n\twithStage,\n} from \"./environment.ts\"\nimport type { Manifest } from \"./manifest.ts\"\nimport {\n\teras,\n\tmatches,\n\tnormalizeWorkspacePeers,\n\treadManifest,\n} from \"./manifest.ts\"\nimport { releaseVersion, previousManifest, supportChanges } from \"./release.ts\"\nimport type {\n\tNpmConfig,\n\tNpmReport,\n\tNpmRepresentativeResult,\n\tNpmTestSelection,\n} from \"./types.ts\"\n\nasync function checkSupport(\n\tconfig: NpmConfig,\n\tbase: string,\n\tmanifest: Manifest,\n): Promise<NpmReport[`support`]> {\n\ttry {\n\t\tconst previous = await previousManifest(config, base)\n\t\tif (!previous) return { status: `first-release`, changes: [] }\n\t\tif (previous.name !== manifest.name)\n\t\t\tthrow new Error(\n\t\t\t\t`Release baseline belongs to ${previous.name}, not ${manifest.name}.`,\n\t\t\t)\n\t\tconst changes = supportChanges(previous, manifest)\n\t\tif (!changes.length)\n\t\t\treturn { status: `unchanged`, previousVersion: previous.version, changes }\n\t\tconst evidence = config.release\n\t\t\t? await resolveReleaseDelta(config.release, {\n\t\t\t\t\tpackageName: manifest.name,\n\t\t\t\t\tpackageDirectory: base,\n\t\t\t\t\tcurrentVersion: manifest.version,\n\t\t\t\t\tbaseline: { version: previous.version },\n\t\t\t\t})\n\t\t\t: undefined\n\t\tif (evidence === undefined)\n\t\t\treturn {\n\t\t\t\tstatus: `end-of-support`,\n\t\t\t\tpreviousVersion: previous.version,\n\t\t\t\tchanges,\n\t\t\t}\n\t\tconst release = versionDelta(\n\t\t\tevidence.previousVersion,\n\t\t\tevidence.version,\n\t\t\tconfig.release?.policy,\n\t\t)\n\n\t\treturn {\n\t\t\tstatus: release.breaking ? `breaking-release` : `end-of-support`,\n\t\t\tpreviousVersion: previous.version,\n\t\t\tchanges,\n\t\t\trelease,\n\t\t}\n\t} catch (error) {\n\t\treturn { status: `setup-error`, changes: [], error: errorMessage(error) }\n\t}\n}\n\nasync function checkLocalReleases(\n\tconfig: NpmConfig,\n\tbase: string,\n\tmanifest: Manifest,\n\trepresentatives: NpmRepresentativeResult[],\n): Promise<string[]> {\n\tconst findings = await Promise.all(\n\t\tObject.entries(config.localPeers ?? {}).map(async ([peer, local]) => {\n\t\t\tconst range = manifest.peerDependencies?.[peer]\n\t\t\t// A registration may be retained solely to resolve an older baseline.\n\t\t\tif (range === undefined) return []\n\t\t\ttry {\n\t\t\t\tconst directory = path.resolve(base, local.directory)\n\t\t\t\tconst current = await readManifest(path.join(directory, `package.json`))\n\t\t\t\tif (current.name !== peer)\n\t\t\t\t\tthrow new Error(`Local peer identity mismatch for ${peer}.`)\n\t\t\t\tconst release = await releaseVersion(config, {\n\t\t\t\t\tpackageName: peer,\n\t\t\t\t\tpackageDirectory: directory,\n\t\t\t\t\tcurrentVersion: current.version,\n\t\t\t\t})\n\t\t\t\tif (release === undefined) return []\n\t\t\t\tif (!matches(release, range))\n\t\t\t\t\treturn [\n\t\t\t\t\t\t`Declared support for ${peer}: ${range} does not include its planned local release ${release}. Update the peer range to include the intended version.`,\n\t\t\t\t\t]\n\t\t\t\tif (\n\t\t\t\t\t!representatives.some(\n\t\t\t\t\t\t(result) =>\n\t\t\t\t\t\t\tresult.peers[peer]?.source === `candidate` &&\n\t\t\t\t\t\t\tresult.peers[peer]?.version === release &&\n\t\t\t\t\t\t\tresult.suites.some((suite) => suite.peer === peer),\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t\t\treturn [\n\t\t\t\t\t\t`No coordinated representative covers planned local peer ${peer}@${release}. Enroll ${peer} with breakage.candidates and configure its relationship suite.`,\n\t\t\t\t\t]\n\t\t\t\treturn []\n\t\t\t} catch (error) {\n\t\t\t\treturn [\n\t\t\t\t\t`Cannot inspect planned local release for ${peer}: ${errorMessage(error)}`,\n\t\t\t\t]\n\t\t\t}\n\t\t}),\n\t)\n\treturn findings.flat()\n}\n\nasync function runRepresentative(\n\tconfig: NpmConfig,\n\tbase: string,\n\tmanifest: Manifest,\n\tdirectory: string,\n\tcoverageOnly: boolean,\n\tselection?: NpmTestSelection,\n): Promise<NpmRepresentativeResult> {\n\tconst label = path.relative(base, directory).split(path.sep).join(`/`)\n\tconst result: NpmRepresentativeResult = {\n\t\tpath: label,\n\t\tstatus: `skipped`,\n\t\tpeers: {},\n\t\tsuites: [],\n\t\twarnings: [],\n\t}\n\tif (\n\t\tselection &&\n\t\t`representative` in selection &&\n\t\tpath.resolve(base, selection.representative) !== directory\n\t)\n\t\treturn result\n\ttry {\n\t\tif (\n\t\t\tselection &&\n\t\t\t`peer` in selection &&\n\t\t\t!(await maySelectEnvironment(\n\t\t\t\tconfig,\n\t\t\t\tbase,\n\t\t\t\tdirectory,\n\t\t\t\tmanifest,\n\t\t\t\tselection,\n\t\t\t))\n\t\t)\n\t\t\treturn result\n\t\treturn await withStage(directory, async (stage) => {\n\t\t\tconst environment = await prepareEnvironment(\n\t\t\t\tconfig,\n\t\t\t\tbase,\n\t\t\t\tdirectory,\n\t\t\t\tstage,\n\t\t\t\tmanifest,\n\t\t\t)\n\t\t\tresult.peers = environment.peers\n\t\t\tfor (const peer of Object.keys(manifest.peerDependencies ?? {})) {\n\t\t\t\tif (\n\t\t\t\t\t!result.peers[peer] &&\n\t\t\t\t\t!manifest.peerDependenciesMeta?.[peer]?.optional\n\t\t\t\t)\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Complete representative is missing required peer ${peer}.`,\n\t\t\t\t\t)\n\t\t\t}\n\t\t\tfor (const [peer, evidence] of Object.entries(result.peers)) {\n\t\t\t\tconst range = manifest.peerDependencies?.[peer]\n\t\t\t\tif (range !== undefined && !matches(evidence.version, range))\n\t\t\t\t\tresult.warnings.push(\n\t\t\t\t\t\t`${peer}@${evidence.version} is outside declared support.`,\n\t\t\t\t\t)\n\t\t\t}\n\t\t\tif (\n\t\t\t\tselection &&\n\t\t\t\t`peer` in selection &&\n\t\t\t\t(!result.peers[selection.peer] ||\n\t\t\t\t\t!matches(result.peers[selection.peer]!.version, selection.range))\n\t\t\t)\n\t\t\t\treturn result\n\t\t\tconst peers = Object.keys(config.suites).filter((peer) => {\n\t\t\t\tconst evidence = result.peers[peer]\n\t\t\t\tif (!evidence) return false\n\t\t\t\tif (selection && `peer` in selection) return peer === selection.peer\n\t\t\t\tif (selection && `representative` in selection) return true\n\t\t\t\treturn matches(evidence.version, manifest.peerDependencies![peer]!)\n\t\t\t})\n\t\t\tresult.suites = peers.map((peer) => ({ peer, status: `not-run` }))\n\t\t\tif (!peers.length) return result\n\t\t\tresult.warnings.push(...checkCandidatePeers(environment, !!selection))\n\t\t\tif (coverageOnly) {\n\t\t\t\tresult.status = `audited`\n\t\t\t\treturn result\n\t\t\t}\n\t\t\tawait stageCandidate(\n\t\t\t\tconfig,\n\t\t\t\tbase,\n\t\t\t\tmanifest,\n\t\t\t\tenvironment,\n\t\t\t\tpeers.map((peer) => config.suites[peer]!),\n\t\t\t)\n\t\t\tfor (const suite of result.suites) {\n\t\t\t\ttry {\n\t\t\t\t\tawait verifyResolution(manifest, environment)\n\t\t\t\t\tconst execution = await command(\n\t\t\t\t\t\tconfig.suites[suite.peer]!.command,\n\t\t\t\t\t\tstage,\n\t\t\t\t\t)\n\t\t\t\t\tawait verifyResolution(manifest, environment)\n\t\t\t\t\tsuite.status =\n\t\t\t\t\t\texecution.code === 0\n\t\t\t\t\t\t\t? `passed`\n\t\t\t\t\t\t\t: execution.code === 1\n\t\t\t\t\t\t\t\t? `compatibility-failure`\n\t\t\t\t\t\t\t\t: `setup-error`\n\t\t\t\t\tif (execution.output) suite.output = execution.output\n\t\t\t\t} catch (error) {\n\t\t\t\t\tsuite.status = `setup-error`\n\t\t\t\t\tsuite.output = errorMessage(error)\n\t\t\t\t}\n\t\t\t}\n\t\t\tresult.status = result.suites.some(\n\t\t\t\t(suite) => suite.status === `setup-error`,\n\t\t\t)\n\t\t\t\t? `setup-error`\n\t\t\t\t: result.suites.some(\n\t\t\t\t\t\t\t(suite) => suite.status === `compatibility-failure`,\n\t\t\t\t\t )\n\t\t\t\t\t? `compatibility-failure`\n\t\t\t\t\t: `passed`\n\t\t\treturn result\n\t\t})\n\t} catch (error) {\n\t\tresult.status = `setup-error`\n\t\tresult.error = errorMessage(error)\n\t\treturn result\n\t}\n}\n\nasync function run(\n\tconfig: NpmConfig,\n\tbaseDirectory: string,\n\tcoverageOnly: boolean,\n\tselection?: NpmTestSelection,\n): Promise<NpmReport> {\n\tconst report: NpmReport = {\n\t\tpackage: { name: `(unresolved)`, version: `(unresolved)` },\n\t\tmode: selection ? `test` : coverageOnly ? `coverage-only` : `check`,\n\t\texitCode: 0,\n\t\trepresentatives: [],\n\t\tcoverage: [],\n\t\tsupport: { status: `not-checked`, changes: [] },\n\t\terrors: [],\n\t}\n\ttry {\n\t\tvalidateConfig(config)\n\t\tconst base = path.resolve(baseDirectory, config.packageDirectory ?? `.`)\n\t\tconst manifest = await normalizeWorkspacePeers(\n\t\t\tawait readManifest(path.join(base, `package.json`)),\n\t\t)\n\t\treport.package = { name: manifest.name, version: manifest.version }\n\t\tvalidatePeerRanges(manifest.peerDependencies ?? {})\n\t\tfor (const peer of Object.keys(config.suites)) {\n\t\t\tif (!manifest.peerDependencies?.[peer])\n\t\t\t\tthrow new Error(`Suite ${peer} has no peerDependencies declaration.`)\n\t\t}\n\t\tfor (const peer of Object.keys(config.localPeers ?? {})) {\n\t\t\tif (manifest.peerDependencies?.[peer] && !config.suites[peer])\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Declared local peer ${peer} needs a relationship suite.`,\n\t\t\t\t)\n\t\t}\n\t\tif (selection && `peer` in selection) {\n\t\t\tif (!config.suites[selection.peer])\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No relationship suite configured for ${selection.peer}.`,\n\t\t\t\t)\n\t\t\teras(selection.range)\n\t\t}\n\t\t// One piece of release evidence per package and baseline per invocation, including failures.\n\t\tconst releases = new Map<string, Promise<VersionTransition | undefined>>()\n\t\tconst resolveDelta = (\n\t\t\tcontext: ReleaseDeltaContext,\n\t\t): Promise<VersionTransition | undefined> => {\n\t\t\tconst key = JSON.stringify([\n\t\t\t\tcontext.packageDirectory,\n\t\t\t\tcontext.currentVersion,\n\t\t\t\tcontext.baseline,\n\t\t\t])\n\t\t\tlet pending = releases.get(key)\n\t\t\tif (!pending) {\n\t\t\t\tpending = resolveReleaseDelta(config.release!, context)\n\t\t\t\treleases.set(key, pending)\n\t\t\t}\n\t\t\treturn pending\n\t\t}\n\t\tconst effective: NpmConfig = {\n\t\t\t...config,\n\t\t\t...(config.release\n\t\t\t\t? { release: { ...config.release, resolveDelta } }\n\t\t\t\t: {}),\n\t\t}\n\n\t\tconst directories = await discover(config, base)\n\t\tconst [support, representatives] = await Promise.all([\n\t\t\tselection\n\t\t\t\t? Promise.resolve(report.support)\n\t\t\t\t: checkSupport(effective, base, manifest),\n\t\t\tPromise.all(\n\t\t\t\tdirectories.map((directory) =>\n\t\t\t\t\trunRepresentative(\n\t\t\t\t\t\teffective,\n\t\t\t\t\t\tbase,\n\t\t\t\t\t\tmanifest,\n\t\t\t\t\t\tdirectory,\n\t\t\t\t\t\tcoverageOnly,\n\t\t\t\t\t\tselection,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t),\n\t\t])\n\t\treport.support = support\n\t\treport.representatives = representatives\n\t\tif (!selection) {\n\t\t\treport.errors.push(\n\t\t\t\t...(await checkLocalReleases(\n\t\t\t\t\teffective,\n\t\t\t\t\tbase,\n\t\t\t\t\tmanifest,\n\t\t\t\t\trepresentatives,\n\t\t\t\t)),\n\t\t\t)\n\t\t\tfor (const peer of Object.keys(config.suites)) {\n\t\t\t\tfor (const era of eras(manifest.peerDependencies![peer]!)) {\n\t\t\t\t\tconst matching = representatives\n\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t(representative) =>\n\t\t\t\t\t\t\t\trepresentative.peers[peer] &&\n\t\t\t\t\t\t\t\tmatches(representative.peers[peer]!.version, era),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.map((representative) => representative.path)\n\t\t\t\t\treport.coverage.push({ peer, era, representatives: matching })\n\t\t\t\t\tif (!matching.length)\n\t\t\t\t\t\treport.errors.push(`No representative covers ${peer}: ${era}.`)\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (\n\t\t\t!representatives.some(\n\t\t\t\t(representative) => representative.suites.length > 0,\n\t\t\t)\n\t\t) {\n\t\t\treport.errors.push(\n\t\t\t\t`No representative matched the requested test selection.`,\n\t\t\t)\n\t\t}\n\t\tif (\n\t\t\tsupport.status === `setup-error` ||\n\t\t\treport.errors.length ||\n\t\t\trepresentatives.some((result) => result.status === `setup-error`)\n\t\t)\n\t\t\treport.exitCode = 2\n\t\telse if (\n\t\t\tsupport.status === `end-of-support` ||\n\t\t\trepresentatives.some(\n\t\t\t\t(result) => result.status === `compatibility-failure`,\n\t\t\t)\n\t\t)\n\t\t\treport.exitCode = 1\n\t} catch (error) {\n\t\treport.errors.push(errorMessage(error))\n\t\treport.exitCode = 2\n\t}\n\treturn report\n}\n\nexport async function npmCheck(\n\tconfig: NpmConfig,\n\toptions: { baseDirectory?: string; coverageOnly?: boolean } = {},\n): Promise<NpmReport> {\n\treturn await run(\n\t\tconfig,\n\t\toptions.baseDirectory ?? process.cwd(),\n\t\toptions.coverageOnly ?? false,\n\t)\n}\n\nexport async function npmTest(\n\tconfig: NpmConfig,\n\tselection: NpmTestSelection,\n\toptions: { baseDirectory?: string } = {},\n): Promise<NpmReport> {\n\treturn await run(\n\t\tconfig,\n\t\toptions.baseDirectory ?? process.cwd(),\n\t\tfalse,\n\t\tselection,\n\t)\n}\n\nexport function formatNpmReport(report: NpmReport): string {\n\tconst lines = [\n\t\t`${report.package.name}@${report.package.version} — npm ${report.mode}`,\n\t]\n\tfor (const result of report.representatives) {\n\t\tlines.push(`${result.path}: ${result.status}`)\n\t\tfor (const [peer, evidence] of Object.entries(result.peers)) {\n\t\t\tlines.push(\n\t\t\t\t` ${peer}@${evidence.version}${evidence.source === `candidate` ? ` (conditional on publication)` : ` (installed)`}`,\n\t\t\t)\n\t\t}\n\t\tfor (const suite of result.suites) {\n\t\t\tlines.push(` ${suite.peer}: ${suite.status}`)\n\t\t\tif (suite.status !== `passed` && suite.output) lines.push(suite.output)\n\t\t}\n\t\tfor (const warning of result.warnings) lines.push(` Warning: ${warning}`)\n\t\tif (result.error) lines.push(` ${result.error}`)\n\t}\n\tlines.push(`Support: ${report.support.status}`)\n\tfor (const change of report.support.changes)\n\t\tlines.push(\n\t\t\t` ${change.peer}: ${change.previous ?? `(unrestricted)`} → ${change.current ?? `(unrestricted)`} (${change.reason})`,\n\t\t)\n\tif (report.support.release)\n\t\tlines.push(\n\t\t\t` Intended release: ${report.support.release.version} (${report.support.release.delta})`,\n\t\t)\n\tif (report.support.error) lines.push(report.support.error)\n\tlines.push(...report.errors)\n\tif (report.mode === `coverage-only`)\n\t\tlines.push(\n\t\t\t`Coverage audit only; compatibility assertions were not executed.`,\n\t\t)\n\treturn `${lines.join(`\\n`)}\\n`\n}\n","import path from \"node:path\"\n\nimport { minimatch } from \"minimatch\"\nimport { simpleGit } from \"simple-git\"\nimport type { Chronicle } from \"takua\"\nimport logger from \"takua\"\n\nimport { command, errorMessage } from \"./task.ts\"\nimport { readManifest, parseManifest } from \"./npm/manifest.ts\"\nimport {\n\tresolveReleaseDelta,\n\tversionDelta,\n\tvalidateRelease,\n\trejectCertificationOptions,\n} from \"./release.ts\"\nimport type { ReleaseConfig, VersionDelta } from \"./release.ts\"\nimport { readBaseline } from \"./baseline.ts\"\nimport { withDirectoryLock } from \"./directory-lock.ts\"\nimport { latestReleaseTag as selectLatestReleaseTag } from \"./release-tag.ts\"\nimport { withTestFileState } from \"./test-file-state.ts\"\n\nexport { defineConfig, loadConfig } from \"./config.ts\"\nexport type { BreakageConfig } from \"./config.ts\"\nexport {\n\tsemverPolicy,\n\tversionTransition,\n\tversionDelta,\n\tresolveReleaseDelta,\n} from \"./release.ts\"\nexport type {\n\tReleaseConfig,\n\tReleasePolicy,\n\tReleasePolicyFunction,\n\tSemverPolicyOptions,\n\tVersionTransition,\n\tReleaseDeltaResolver,\n\tReleaseDeltaContext,\n\tVersionDelta,\n} from \"./release.ts\"\nexport type { CommandResult } from \"./task.ts\"\n\nexport type { BreakageBaseline, BreakagePreludeOptions } from \"./baseline.ts\"\nexport { breakagePrelude } from \"./baseline.ts\"\nexport { formatNpmReport, npmCheck, npmTest } from \"./npm/check.ts\"\nexport type {\n\tNpmConfig,\n\tNpmPeerEvidence,\n\tNpmReport,\n\tNpmRepresentativeResult,\n\tNpmSuite,\n\tNpmSuiteResult,\n\tNpmTestSelection,\n\tSupportChange,\n} from \"./npm/types.ts\"\n\nexport type BreakageOptions = {\n\ttagPattern?: string | undefined\n\tbaselineFile?: string | undefined\n\ttestPattern: string\n\ttestCommand?: string\n\t/** Shell command. Do not combine with testCommand. */\n\ttest?: string\n\trelease?: ReleaseConfig\n\tbaseDirname?: string\n\tverbose?: boolean | undefined\n}\n\nexport type BreakageOutcome =\n\t| { gitWasClean: false }\n\t| { gitWasClean: true; setupError: string }\n\t| {\n\t\t\tgitWasClean: true\n\t\t\tlastReleaseFound: false\n\t }\n\t| {\n\t\t\tgitWasClean: true\n\t\t\tlastReleaseFound: true\n\t\t\tlastReleaseTag: string\n\t\t\ttestsWereFound: false\n\t }\n\t| {\n\t\t\tgitWasClean: true\n\t\t\tlastReleaseFound: true\n\t\t\tlastReleaseTag: string\n\t\t\ttestsWereFound: true\n\t\t\ttestsFound: string[]\n\t\t\tbreakingChangesFound: false\n\t\t\trelease?: VersionDelta\n\t }\n\t| {\n\t\t\tgitWasClean: true\n\t\t\tlastReleaseFound: true\n\t\t\tlastReleaseTag: string\n\t\t\ttestsWereFound: true\n\t\t\ttestsFound: string[]\n\t\t\tbreakingChangesFound: true\n\t\t\ttestResult: string\n\t\t\trelease?: VersionDelta\n\t }\n\nexport async function breakage(\n\toptions: BreakageOptions,\n): Promise<BreakageOutcome & { summary: string }> {\n\trejectCertificationOptions(options)\n\tconst {\n\t\ttagPattern,\n\t\tbaselineFile,\n\t\ttestPattern,\n\t\ttestCommand,\n\t\ttest,\n\t\trelease,\n\t\tbaseDirname = process.cwd(),\n\t\tverbose = false,\n\t} = options\n\tif (!testPattern || (!test && !testCommand))\n\t\tthrow new Error(\n\t\t\t`required arguments were not provided: testPattern and test or testCommand.`,\n\t\t)\n\tif (test !== undefined && testCommand !== undefined)\n\t\tthrow new Error(`Choose test or testCommand, not both.`)\n\tif (\n\t\ttypeof (test ?? testCommand) !== `string` ||\n\t\t!(test ?? testCommand)!.trim()\n\t)\n\t\tthrow new Error(`test must be a nonempty shell command string.`)\n\tif (release !== undefined) validateRelease(release)\n\tlet mark: Chronicle[`mark`] | undefined\n\tlet logMarks: Chronicle[`logMarks`] | undefined\n\tif (verbose) {\n\t\tconst chronicle = logger.makeChronicle()\n\t\tmark = chronicle.mark\n\t\tlogMarks = chronicle.logMarks\n\t}\n\tmark?.(`breakage`)\n\tconst git = simpleGit(baseDirname)\n\tmark?.(`spawn git`)\n\tconst isGitRepo = await git.checkIsRepo()\n\tmark?.(`is git repository`)\n\tif (!isGitRepo) {\n\t\treturn {\n\t\t\tsummary: `The git repository must be clean to run this command.`,\n\t\t\tgitWasClean: false,\n\t\t}\n\t}\n\tif (\n\t\t!(await withTestFileState(git, baseDirname, (state) => state.isClean()))\n\t) {\n\t\treturn {\n\t\t\tsummary: `The git repository must be clean to run this command.`,\n\t\t\tgitWasClean: false,\n\t\t}\n\t}\n\tlet latestReleaseTag: string | undefined\n\tlet releaseCommit: string\n\tif (baselineFile !== undefined) {\n\t\tconst baseline = await readBaseline(\n\t\t\tgit,\n\t\t\tpath.resolve(baseDirname, baselineFile),\n\t\t\t{ tagPattern },\n\t\t)\n\t\tlatestReleaseTag = baseline.ref\n\t\treleaseCommit = baseline.commit\n\t\tmark?.(`read pinned release baseline`)\n\t} else {\n\t\tconst tagsRemote = await git.listRemote([`--tags`, `origin`])\n\n\t\tmark?.(`list remote tags`)\n\t\tlatestReleaseTag = selectLatestReleaseTag(tagsRemote, tagPattern)\n\t\tmark?.(`found latest release tag`)\n\t\tif (!latestReleaseTag) {\n\t\t\treturn {\n\t\t\t\tsummary: `No tags found matching the pattern \"${tagPattern}\".`,\n\t\t\t\tgitWasClean: true,\n\t\t\t\tlastReleaseFound: false,\n\t\t\t} as const\n\t\t}\n\t\tconst commonGitDirectory = await git.revparse([\n\t\t\t`--path-format=absolute`,\n\t\t\t`--git-common-dir`,\n\t\t])\n\t\tawait withDirectoryLock(\n\t\t\tpath.join(commonGitDirectory, `breakage-fetch.lock`),\n\t\t\t() =>\n\t\t\t\tgit.fetch([\n\t\t\t\t\t`origin`,\n\t\t\t\t\t`${latestReleaseTag}:${latestReleaseTag}`,\n\t\t\t\t\t`--no-tags`,\n\t\t\t\t\t`--no-write-fetch-head`,\n\t\t\t\t]),\n\t\t)\n\n\t\treleaseCommit = await git.revparse([`${latestReleaseTag}^{commit}`])\n\t\tmark?.(`fetched latest release tag`)\n\t}\n\n\tlet productionFiles: string[]\n\ttry {\n\t\tproductionFiles = (\n\t\t\tawait git.raw([`ls-tree`, `-r`, `--name-only`, `-z`, releaseCommit])\n\t\t)\n\t\t\t.split(`\\0`)\n\t\t\t.filter(Boolean)\n\t} catch (thrown) {\n\t\tmark?.(`failed to list production files`)\n\t\tconst message =\n\t\t\tthrown instanceof Error\n\t\t\t\t? thrown.message\n\t\t\t\t: typeof thrown === `string`\n\t\t\t\t\t? thrown\n\t\t\t\t\t: undefined\n\t\tconst summary = `Failed to list production files${\n\t\t\tmessage ? `: ${message}` : `.`\n\t\t}`\n\t\treturn {\n\t\t\tsummary,\n\t\t\tgitWasClean: true,\n\t\t\tlastReleaseFound: true,\n\t\t\tlastReleaseTag: latestReleaseTag,\n\t\t\ttestsWereFound: false,\n\t\t} as const\n\t}\n\tmark?.(`listed all files checked into git`)\n\tconst productionTestFiles = productionFiles.filter((file) =>\n\t\tminimatch(file, testPattern),\n\t)\n\tmark?.(`filtered to public test files`)\n\n\tlet releaseEvidence: VersionDelta | undefined\n\tif (release) {\n\t\tconst current = await readManifest(path.join(baseDirname, `package.json`))\n\t\tconst prefix = await git.revparse([`--show-prefix`])\n\t\tconst previous = parseManifest(\n\t\t\tJSON.parse(await git.show([`${releaseCommit}:${prefix}package.json`])),\n\t\t\t`baseline`,\n\t\t)\n\t\tif (previous.name !== current.name)\n\t\t\tthrow new Error(`Release baseline belongs to another package.`)\n\t\tconst transition = await resolveReleaseDelta(release, {\n\t\t\tpackageName: current.name,\n\t\t\tpackageDirectory: path.resolve(baseDirname),\n\t\t\tcurrentVersion: current.version,\n\t\t\tbaseline: {\n\t\t\t\tversion: previous.version,\n\t\t\t\tref: latestReleaseTag,\n\t\t\t\tcommit: releaseCommit,\n\t\t\t},\n\t\t})\n\t\tif (transition !== undefined)\n\t\t\treleaseEvidence = versionDelta(\n\t\t\t\ttransition.previousVersion,\n\t\t\t\ttransition.version,\n\t\t\t\trelease.policy,\n\t\t\t)\n\t}\n\n\tconst prepared = await withTestFileState(git, baseDirname, async (state) => {\n\t\tif (!(await state.isClean())) {\n\t\t\treturn {\n\t\t\t\tsummary: `The git repository must be clean to run this command.`,\n\t\t\t\tgitWasClean: false,\n\t\t\t} as const\n\t\t}\n\n\t\tif (productionTestFiles.length === 0) {\n\t\t\treturn {\n\t\t\t\tsummary: `No tests were found matching the pattern \"${testPattern}\".`,\n\t\t\t\tgitWasClean: true,\n\t\t\t\tlastReleaseFound: true,\n\t\t\t\tlastReleaseTag: latestReleaseTag,\n\t\t\t\ttestsWereFound: false,\n\t\t\t} as const\n\t\t}\n\t\tconst restore = await state.replaceTests(releaseCommit, productionTestFiles)\n\t\tmark?.(`restored public tests from latest release tag`)\n\t\treturn { latestReleaseTag, productionTestFiles, restore }\n\t})\n\tif (prepared.summary !== undefined) return prepared\n\tconst { restore } = prepared\n\n\ttry {\n\t\tconst result = await command(test ?? testCommand!, baseDirname)\n\t\tif (result.code > 1)\n\t\t\treturn {\n\t\t\t\tgitWasClean: true,\n\t\t\t\tsetupError: result.output,\n\t\t\t\tsummary: `Public test setup failed (${result.code}).`,\n\t\t\t}\n\t\tconst common = {\n\t\t\tgitWasClean: true as const,\n\t\t\tlastReleaseFound: true as const,\n\t\t\tlastReleaseTag: latestReleaseTag,\n\t\t\ttestsWereFound: true as const,\n\t\t\ttestsFound: productionTestFiles,\n\t\t\t...(releaseEvidence ? { release: releaseEvidence } : {}),\n\t\t}\n\t\tif (result.code === 0)\n\t\t\treturn {\n\t\t\t\t...common,\n\t\t\t\tbreakingChangesFound: false,\n\t\t\t\tsummary: `No breaking changes were detected.`,\n\t\t\t}\n\t\treturn {\n\t\t\t...common,\n\t\t\tbreakingChangesFound: true,\n\t\t\ttestResult: result.output,\n\t\t\tsummary: releaseEvidence?.breaking\n\t\t\t\t? `Breaking changes are covered by release ${releaseEvidence.previousVersion} → ${releaseEvidence.version}.`\n\t\t\t\t: `Breaking changes require a breaking release.`,\n\t\t}\n\t} catch (error) {\n\t\treturn {\n\t\t\tgitWasClean: true,\n\t\t\tsetupError: errorMessage(error),\n\t\t\tsummary: `Public test setup failed: ${errorMessage(error)}`,\n\t\t}\n\t} finally {\n\t\tawait restore()\n\t\tmark?.(`restored original public tests`)\n\t\tlogMarks?.()\n\t}\n}\n"],"mappings":"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"}
|
package/dist/breakage.d.ts
CHANGED
|
@@ -1,5 +1,75 @@
|
|
|
1
|
+
import { a as ReleasePolicyFunction, c as VersionTransition, d as versionDelta, f as versionTransition, i as ReleasePolicy, l as resolveReleaseDelta, n as ReleaseDeltaContext, o as SemverPolicyOptions, r as ReleaseDeltaResolver, s as VersionDelta, t as ReleaseConfig, u as semverPolicy } from "./release-D47BqRuB.js";
|
|
1
2
|
import "simple-git";
|
|
2
|
-
|
|
3
|
+
import { ConfigInput } from "comline";
|
|
4
|
+
/** The complete config, with no fields exposed to argv by this loader. */
|
|
5
|
+
declare const configOptions: {
|
|
6
|
+
description: string;
|
|
7
|
+
optionsSchema: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
8
|
+
tagPattern?: string | undefined;
|
|
9
|
+
baselineFile?: string | undefined;
|
|
10
|
+
testPattern?: string;
|
|
11
|
+
testCommand?: string;
|
|
12
|
+
test?: string;
|
|
13
|
+
baseDirname?: string;
|
|
14
|
+
verbose?: boolean | undefined;
|
|
15
|
+
out?: string;
|
|
16
|
+
release?: {
|
|
17
|
+
resolveDelta?: ReleaseDeltaResolver;
|
|
18
|
+
policy?: ReleasePolicyFunction;
|
|
19
|
+
};
|
|
20
|
+
npm?: {
|
|
21
|
+
release?: {
|
|
22
|
+
resolveDelta?: ReleaseDeltaResolver;
|
|
23
|
+
policy?: ReleasePolicyFunction;
|
|
24
|
+
};
|
|
25
|
+
packageDirectory?: string;
|
|
26
|
+
artifact: string;
|
|
27
|
+
representatives: string | string[];
|
|
28
|
+
lockfile: string;
|
|
29
|
+
prepareCommand: string;
|
|
30
|
+
installCommand?: string;
|
|
31
|
+
suites: {
|
|
32
|
+
[x: string]: {
|
|
33
|
+
files: string[];
|
|
34
|
+
command: string;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
localPeers?: {
|
|
38
|
+
[x: string]: {
|
|
39
|
+
directory: string;
|
|
40
|
+
artifact: string;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
baseline: {
|
|
44
|
+
firstRelease: true;
|
|
45
|
+
} | {
|
|
46
|
+
tagPattern?: string;
|
|
47
|
+
baselineFile?: string;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
}, {}>;
|
|
51
|
+
optionConfigs: {
|
|
52
|
+
tagPattern: import("comline").ConfigOnlyOption;
|
|
53
|
+
baselineFile: import("comline").ConfigOnlyOption;
|
|
54
|
+
testPattern: import("comline").ConfigOnlyOption;
|
|
55
|
+
testCommand: import("comline").ConfigOnlyOption;
|
|
56
|
+
test: import("comline").ConfigOnlyOption;
|
|
57
|
+
baseDirname: import("comline").ConfigOnlyOption;
|
|
58
|
+
verbose: import("comline").ConfigOnlyOption;
|
|
59
|
+
out: import("comline").ConfigOnlyOption;
|
|
60
|
+
release: import("comline").ConfigOnlyOption;
|
|
61
|
+
npm: import("comline").ConfigOnlyOption;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
type BreakageConfig = ConfigInput<typeof configOptions>;
|
|
65
|
+
/** Share the root release model with npm checks unless they supply their own. */
|
|
66
|
+
export declare function defineConfig(config: BreakageConfig): BreakageConfig;
|
|
67
|
+
/** Use Comline's module loading and full-schema validation for programmatic and npm consumers. */
|
|
68
|
+
export declare function loadConfig(filename: string): Promise<BreakageConfig>;
|
|
69
|
+
type CommandResult = {
|
|
70
|
+
code: number;
|
|
71
|
+
output: string;
|
|
72
|
+
};
|
|
3
73
|
type BaselineOptions = {
|
|
4
74
|
tagPattern?: string | undefined;
|
|
5
75
|
baseDirname?: string;
|
|
@@ -16,61 +86,48 @@ type BreakageBaseline = {
|
|
|
16
86
|
};
|
|
17
87
|
/** Resolve and fetch a release without running tests or changing the worktree. */
|
|
18
88
|
export declare function breakagePrelude({ out, tagPattern, baseDirname }: BreakagePreludeOptions): Promise<BreakageBaseline>;
|
|
19
|
-
|
|
20
|
-
//#region src/npm/types.d.ts
|
|
21
|
-
type ReleaseIntent = {
|
|
22
|
-
status: `none`;
|
|
23
|
-
} | {
|
|
24
|
-
status: `release`;
|
|
25
|
-
version: string;
|
|
26
|
-
};
|
|
27
|
-
type ReleaseContext = {
|
|
28
|
-
packageName: string;
|
|
29
|
-
packageDirectory: string;
|
|
30
|
-
currentVersion: string;
|
|
31
|
-
};
|
|
32
|
-
type SupportChange = {
|
|
33
|
-
peer: string;
|
|
34
|
-
reason: `narrowed-range` | `required-peer`;
|
|
35
|
-
previous: string | null;
|
|
36
|
-
current: string | null;
|
|
37
|
-
};
|
|
38
|
-
type ReleaseEvidence = {
|
|
39
|
-
version: string;
|
|
40
|
-
delta: string;
|
|
41
|
-
};
|
|
42
|
-
type NpmSuite = {
|
|
43
|
-
/** Package-relative globs; preserve relative paths inside the stage. */
|
|
89
|
+
declare const npmSuiteSchema: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
44
90
|
files: string[];
|
|
45
|
-
/** Run once; 1 means assertion failure, other nonzero codes mean setup failure. */
|
|
46
91
|
command: string;
|
|
47
|
-
}
|
|
48
|
-
|
|
92
|
+
}, {}>;
|
|
93
|
+
declare const npmConfigSchema: import("arktype/internal/variants/object.ts").ObjectType<{
|
|
94
|
+
release?: {
|
|
95
|
+
resolveDelta?: ReleaseDeltaResolver;
|
|
96
|
+
policy?: ReleasePolicyFunction;
|
|
97
|
+
};
|
|
49
98
|
packageDirectory?: string;
|
|
50
99
|
artifact: string;
|
|
51
100
|
representatives: string | string[];
|
|
52
101
|
lockfile: string;
|
|
53
102
|
prepareCommand: string;
|
|
54
103
|
installCommand?: string;
|
|
55
|
-
suites:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
104
|
+
suites: {
|
|
105
|
+
[x: string]: {
|
|
106
|
+
files: string[];
|
|
107
|
+
command: string;
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
localPeers?: {
|
|
111
|
+
[x: string]: {
|
|
112
|
+
directory: string;
|
|
113
|
+
artifact: string;
|
|
114
|
+
};
|
|
115
|
+
};
|
|
61
116
|
baseline: {
|
|
62
117
|
firstRelease: true;
|
|
63
118
|
} | {
|
|
64
119
|
tagPattern?: string;
|
|
65
120
|
baselineFile?: string;
|
|
66
121
|
};
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
122
|
+
}, {}>;
|
|
123
|
+
type SupportChange = {
|
|
124
|
+
peer: string;
|
|
125
|
+
reason: `narrowed-range` | `required-peer`;
|
|
126
|
+
previous: string | null;
|
|
127
|
+
current: string | null;
|
|
73
128
|
};
|
|
129
|
+
type NpmSuite = typeof npmSuiteSchema.infer;
|
|
130
|
+
type NpmConfig = typeof npmConfigSchema.infer;
|
|
74
131
|
type NpmTestSelection = {
|
|
75
132
|
peer: string;
|
|
76
133
|
range: string;
|
|
@@ -110,16 +167,14 @@ type NpmReport = {
|
|
|
110
167
|
representatives: string[];
|
|
111
168
|
}[];
|
|
112
169
|
support: {
|
|
113
|
-
status: `unchanged` | `
|
|
170
|
+
status: `unchanged` | `breaking-release` | `end-of-support` | `first-release` | `not-checked` | `setup-error`;
|
|
114
171
|
changes: SupportChange[];
|
|
115
172
|
previousVersion?: string;
|
|
116
|
-
release?:
|
|
173
|
+
release?: VersionDelta;
|
|
117
174
|
error?: string;
|
|
118
175
|
};
|
|
119
176
|
errors: string[];
|
|
120
177
|
};
|
|
121
|
-
//#endregion
|
|
122
|
-
//#region src/npm/check.d.ts
|
|
123
178
|
export declare function npmCheck(config: NpmConfig, options?: {
|
|
124
179
|
baseDirectory?: string;
|
|
125
180
|
coverageOnly?: boolean;
|
|
@@ -128,19 +183,22 @@ export declare function npmTest(config: NpmConfig, selection: NpmTestSelection,
|
|
|
128
183
|
baseDirectory?: string;
|
|
129
184
|
}): Promise<NpmReport>;
|
|
130
185
|
export declare function formatNpmReport(report: NpmReport): string;
|
|
131
|
-
//#endregion
|
|
132
|
-
//#region src/breakage.d.ts
|
|
133
186
|
export type BreakageOptions = {
|
|
134
187
|
tagPattern?: string | undefined;
|
|
135
188
|
baselineFile?: string | undefined;
|
|
136
189
|
testPattern: string;
|
|
137
|
-
testCommand
|
|
138
|
-
|
|
190
|
+
testCommand?: string;
|
|
191
|
+
/** Shell command. Do not combine with testCommand. */
|
|
192
|
+
test?: string;
|
|
193
|
+
release?: ReleaseConfig;
|
|
139
194
|
baseDirname?: string;
|
|
140
195
|
verbose?: boolean | undefined;
|
|
141
196
|
};
|
|
142
197
|
export type BreakageOutcome = {
|
|
143
198
|
gitWasClean: false;
|
|
199
|
+
} | {
|
|
200
|
+
gitWasClean: true;
|
|
201
|
+
setupError: string;
|
|
144
202
|
} | {
|
|
145
203
|
gitWasClean: true;
|
|
146
204
|
lastReleaseFound: false;
|
|
@@ -156,6 +214,7 @@ export type BreakageOutcome = {
|
|
|
156
214
|
testsWereFound: true;
|
|
157
215
|
testsFound: string[];
|
|
158
216
|
breakingChangesFound: false;
|
|
217
|
+
release?: VersionDelta;
|
|
159
218
|
} | {
|
|
160
219
|
gitWasClean: true;
|
|
161
220
|
lastReleaseFound: true;
|
|
@@ -164,13 +223,10 @@ export type BreakageOutcome = {
|
|
|
164
223
|
testsFound: string[];
|
|
165
224
|
breakingChangesFound: true;
|
|
166
225
|
testResult: string;
|
|
167
|
-
|
|
168
|
-
certificationStdout: string;
|
|
169
|
-
certificationStderr: string;
|
|
226
|
+
release?: VersionDelta;
|
|
170
227
|
};
|
|
171
|
-
export declare function breakage(
|
|
228
|
+
export declare function breakage(options: BreakageOptions): Promise<BreakageOutcome & {
|
|
172
229
|
summary: string;
|
|
173
230
|
}>;
|
|
174
|
-
|
|
175
|
-
export type { BreakageBaseline, BreakagePreludeOptions, NpmConfig, NpmPeerEvidence, NpmReport, NpmRepresentativeResult, NpmSuite, NpmSuiteResult, NpmTestSelection, ReleaseContext, ReleaseEvidence, ReleaseIntent, SupportChange };
|
|
231
|
+
export { type BreakageBaseline, type BreakageConfig, type BreakagePreludeOptions, type CommandResult, type NpmConfig, type NpmPeerEvidence, type NpmReport, type NpmRepresentativeResult, type NpmSuite, type NpmSuiteResult, type NpmTestSelection, type ReleaseConfig, type ReleaseDeltaContext, type ReleaseDeltaResolver, type ReleasePolicy, type ReleasePolicyFunction, type SemverPolicyOptions, type SupportChange, type VersionDelta, type VersionTransition, resolveReleaseDelta, semverPolicy, versionDelta, versionTransition };
|
|
176
232
|
//# sourceMappingURL=breakage.d.ts.map
|
package/dist/breakage.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"breakage.d.ts","names":[],"sources":["../src/baseline.ts","../src/npm/types.ts","../src/npm/check.ts","../src/breakage.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"breakage.d.ts","names":["_$__release_ts0.ReleaseDeltaResolver","_$__release_ts0.ReleasePolicyFunction","_$___release_ts0.ReleaseDeltaResolver","_$___release_ts0.ReleasePolicyFunction"],"sources":["../src/config.ts","../src/task.ts","../src/baseline.ts","../src/npm/config.ts","../src/npm/types.ts","../src/npm/check.ts","../src/breakage.ts"],"mappings":";;;;cAuCa;;;;;;;;;;;;M,eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAYD,iBAAiB,mBAAmB;;wBAGhC,aAAa,QAAQ,iBAAiB;;wBA8DhC,WAAW,mBAAmB,QAAQ;KCjHhD;EAAkB;EAAc;;KCOhC;EACX;EACA;;KAGW,yBAAyB;EAAoB;;KAE7C;EACX;EACA;EACA;EACA;EACA;;;wBAoBqB,kBACrB,KACA,YACA,eACE,yBAAyB,QAAQ;cCtCvB,8DAAc;;;;cAKd,+DAAe;;I,eAAfE;;;;;;;;;;;;;;;;;;;;;;;;;;;;KCXD;EACX;EACA;EACA;EACA;;KAGW,kBAAA,eAAuD;KACvD,mBAAA,gBAAyD;KAEzD;EACP;EAAc;;EACd;;KAEO;EACX;EACA;EACA;EACA;;KAGW;EACX;EACA;EACA;;KAGW;EACX;EACA;EAMA,OAAO,eAAe;EACtB,QAAQ;EACR;EACA;;KAGW;EACX;IAAW;IAAc;;EACzB;EACA;EACA,iBAAiB;EACjB;IAAY;IAAc;IAAa;;EACvC;IACC;IAOA,SAAS;IACT;IACA,UAAU;IACV;;EAED;;wBCwUqB,SACrB,QAAQ,WACR;EAAW;EAAwB;IACjC,QAAQ;wBAQW,QACrB,QAAQ,WACR,WAAW,kBACX;EAAW;IACT,QAAQ;wBASK,gBAAgB,QAAQ;YCvW5B;EACX;EACA;EACA;EACA;;EAEA;EACA,UAAU;EACV;EACA;;YAGW;EACP;;EACA;EAAmB;;EAErB;EACA;;EAGA;EACA;EACA;EACA;;EAGA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;;EAGV;EACA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;;wBAGS,SACrB,SAAS,kBACP,QAAQ;EAAoB"}
|
package/dist/breakage.js
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
import { d as loadConfig, i as npmTest, m as breakagePrelude, n as formatNpmReport, r as npmCheck, t as breakage, u as defineConfig } from "./breakage-DIY49fzP.js";
|
|
2
|
+
import { i as semverPolicy, o as versionDelta, r as resolveReleaseDelta, s as versionTransition } from "./release-BsdIDT4g.js";
|
|
3
|
+
export { breakage, breakagePrelude, defineConfig, formatNpmReport, loadConfig, npmCheck, npmTest, resolveReleaseDelta, semverPolicy, versionDelta, versionTransition };
|