mirror of
https://github.com/pnpm/pnpm.git
synced 2026-06-28 01:45:30 -04:00
The TypeScript pnpm CLI freezes at v11; pnpm 12 will be the Rust pacquet port. To make that split legible, all TypeScript source, test, and build directories move under a new top-level pnpm11/ directory. The name states the version boundary rather than implying a behavioral fork, since the two stacks are meant to behave identically. Scope is source-only: the shared workspace root stays at the repo root. pnpm-workspace.yaml, package.json, pnpm-lock.yaml, .pnpmfile.cjs, .meta-updater, __patches__, .changeset, .husky, and the lint/spell configs remain in place, so one pnpm workspace and one Cargo workspace still span all three products. pnpr/client and pacquet/tasks/registry-mock stay as cross-product workspace members. Rewiring the move required: - pnpm-workspace.yaml globs prefixed with pnpm11/ - root package.json script paths, eslint.config.mjs, tsconfig.lint.json, .gitignore, and CODEOWNERS updated - .meta-updater/src/index.ts literals repointed (pnpm11/pnpm/package.json, pnpm11/__utils__, pnpm11/__typings__, and the main package directory) - regenerated every moved package's repository/homepage URL via meta-updater - pnpm11/pnpm/bundle-deps.ts and __utils__/scripts/src/typecheck-only.ts climb one more level to reach the repo root .meta-updater stays at the repo root because @pnpm/meta-updater resolves its config at <cwd>/.meta-updater/main.mjs. TS CI (.github/workflows/ci.yml) now only runs when pnpm11/-relevant paths change, via a dorny/paths-filter changes job plus a TS CI / Success aggregate gate; branch protection should require only that gate.
70 lines
2.4 KiB
TypeScript
70 lines
2.4 KiB
TypeScript
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
|
|
import type { PackageMeta } from '@pnpm/resolving.npm-resolver'
|
|
import { StoreIndex, storeIndexKey } from '@pnpm/store.index'
|
|
import getRegistryName from 'encode-registry'
|
|
import { glob } from 'tinyglobby'
|
|
|
|
interface CachedVersions {
|
|
cachedVersions: string[]
|
|
nonCachedVersions: string[]
|
|
cachedAt?: string
|
|
distTags: Record<string, string>
|
|
}
|
|
|
|
export async function cacheView (opts: { cacheDir: string, storeDir: string, registry?: string }, packageName: string): Promise<string> {
|
|
const prefix = opts.registry ? `${getRegistryName(opts.registry)}` : '*'
|
|
const metaFilePaths = (await glob(`${prefix}/${packageName}.jsonl`, {
|
|
cwd: opts.cacheDir,
|
|
expandDirectories: false,
|
|
})).sort()
|
|
const metaFilesByPath: Record<string, CachedVersions> = {}
|
|
const storeIndex = new StoreIndex(opts.storeDir)
|
|
try {
|
|
for (const filePath of metaFilePaths) {
|
|
let metaObject: PackageMeta | null
|
|
const fullPath = path.join(opts.cacheDir, filePath)
|
|
let mtime: Date | undefined
|
|
try {
|
|
const raw = fs.readFileSync(fullPath, 'utf8')
|
|
mtime = fs.statSync(fullPath).mtime
|
|
const newlineIdx = raw.indexOf('\n')
|
|
if (newlineIdx !== -1) {
|
|
// NDJSON format: line 1 = headers, line 2 = metadata
|
|
metaObject = JSON.parse(raw.slice(newlineIdx + 1)) as PackageMeta
|
|
} else {
|
|
metaObject = JSON.parse(raw) as PackageMeta
|
|
}
|
|
} catch {
|
|
continue
|
|
}
|
|
if (!metaObject) continue
|
|
const cachedVersions: string[] = []
|
|
const nonCachedVersions: string[] = []
|
|
for (const [version, manifest] of Object.entries(metaObject.versions)) {
|
|
if (!manifest.dist.integrity) continue
|
|
const key = storeIndexKey(manifest.dist.integrity, `${manifest.name}@${manifest.version}`)
|
|
if (storeIndex.has(key)) {
|
|
cachedVersions.push(version)
|
|
} else {
|
|
nonCachedVersions.push(version)
|
|
}
|
|
}
|
|
let registryName = filePath
|
|
while (path.dirname(registryName) !== '.') {
|
|
registryName = path.dirname(registryName)
|
|
}
|
|
metaFilesByPath[registryName.replaceAll('+', ':')] = {
|
|
cachedVersions,
|
|
nonCachedVersions,
|
|
cachedAt: mtime?.toString(),
|
|
distTags: metaObject['dist-tags'],
|
|
}
|
|
}
|
|
} finally {
|
|
storeIndex.close()
|
|
}
|
|
return JSON.stringify(metaFilesByPath, null, 2)
|
|
}
|