@pnpm/lockfile.fs 1100.1.13 → 1100.1.14
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/CHANGELOG.md +17 -0
- package/lib/envLockfile.d.ts +4 -0
- package/lib/envLockfile.js +61 -0
- package/lib/errors/LockfileBreakingChangeError.d.ts +5 -0
- package/lib/errors/LockfileBreakingChangeError.js +9 -0
- package/lib/errors/index.d.ts +1 -0
- package/lib/errors/index.js +2 -0
- package/lib/existsWantedLockfile.d.ts +6 -0
- package/lib/existsWantedLockfile.js +23 -0
- package/lib/getLockfileImporterId.d.ts +2 -0
- package/lib/getLockfileImporterId.js +6 -0
- package/lib/gitBranchLockfile.d.ts +3 -0
- package/lib/gitBranchLockfile.js +22 -0
- package/lib/gitMergeFile.d.ts +3 -0
- package/lib/gitMergeFile.js +47 -0
- package/lib/index.d.ts +10 -0
- package/lib/lockfileFormatConverters.d.ts +3 -0
- package/lib/lockfileFormatConverters.js +227 -0
- package/lib/lockfileName.d.ts +6 -0
- package/lib/lockfileName.js +19 -0
- package/lib/logger.d.ts +1 -0
- package/lib/logger.js +3 -0
- package/lib/read.d.ts +42 -0
- package/lib/read.js +203 -0
- package/lib/sortLockfileKeys.d.ts +3 -0
- package/lib/sortLockfileKeys.js +78 -0
- package/lib/write.d.ts +39 -0
- package/lib/write.js +203 -0
- package/lib/yamlDocuments.d.ts +27 -0
- package/lib/yamlDocuments.js +165 -0
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @pnpm/lockfile-file
|
|
2
2
|
|
|
3
|
+
## 1100.1.14
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Republished every package: the tarballs published by the v11.13.1 through v11.16.0 releases were missing most of their compiled files due to a packing bug [#13164](https://github.com/pnpm/pnpm/issues/13164).
|
|
8
|
+
|
|
9
|
+
- Updated dependencies:
|
|
10
|
+
- @pnpm/constants@1100.0.1
|
|
11
|
+
- @pnpm/deps.path@1100.0.11
|
|
12
|
+
- @pnpm/error@1100.1.0
|
|
13
|
+
- @pnpm/lockfile.merger@1100.0.16
|
|
14
|
+
- @pnpm/lockfile.types@1100.0.16
|
|
15
|
+
- @pnpm/lockfile.utils@1100.1.5
|
|
16
|
+
- @pnpm/network.git-utils@1100.0.3
|
|
17
|
+
- @pnpm/object.key-sorting@1100.0.2
|
|
18
|
+
- @pnpm/types@1101.6.0
|
|
19
|
+
|
|
3
20
|
## 1100.1.13
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { EnvLockfile } from '@pnpm/lockfile.types';
|
|
2
|
+
export declare function createEnvLockfile(): EnvLockfile;
|
|
3
|
+
export declare function readEnvLockfile(rootDir: string): Promise<EnvLockfile | null>;
|
|
4
|
+
export declare function writeEnvLockfile(rootDir: string, lockfile: EnvLockfile): Promise<void>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { LOCKFILE_VERSION, WANTED_LOCKFILE } from '@pnpm/constants';
|
|
3
|
+
import yaml from 'js-yaml';
|
|
4
|
+
import writeFileAtomic from 'write-file-atomic';
|
|
5
|
+
import { sortLockfileKeys } from './sortLockfileKeys.js';
|
|
6
|
+
import { lockfileYamlDump } from './write.js';
|
|
7
|
+
import { extractMainDocument, readLockfileToStringNoFollow, streamReadFirstYamlDocument } from './yamlDocuments.js';
|
|
8
|
+
export function createEnvLockfile() {
|
|
9
|
+
return {
|
|
10
|
+
lockfileVersion: LOCKFILE_VERSION,
|
|
11
|
+
importers: {
|
|
12
|
+
'.': {
|
|
13
|
+
configDependencies: {},
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
packages: {},
|
|
17
|
+
snapshots: {},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export async function readEnvLockfile(rootDir) {
|
|
21
|
+
const lockfilePath = path.join(rootDir, WANTED_LOCKFILE);
|
|
22
|
+
const rawContent = await streamReadFirstYamlDocument(lockfilePath);
|
|
23
|
+
if (rawContent == null) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const parsed = yaml.load(rawContent);
|
|
27
|
+
if (parsed == null || typeof parsed !== 'object') {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const lockfile = parsed;
|
|
31
|
+
if (typeof lockfile.lockfileVersion !== 'string') {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
if (lockfile.importers == null || typeof lockfile.importers !== 'object') {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
if (lockfile.packages == null || typeof lockfile.packages !== 'object') {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
if (lockfile.snapshots == null || typeof lockfile.snapshots !== 'object') {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const envLockfile = parsed;
|
|
44
|
+
if (!envLockfile.importers['.']) {
|
|
45
|
+
envLockfile.importers['.'] = { configDependencies: {} };
|
|
46
|
+
}
|
|
47
|
+
else if (!envLockfile.importers['.'].configDependencies) {
|
|
48
|
+
envLockfile.importers['.'].configDependencies = {};
|
|
49
|
+
}
|
|
50
|
+
return envLockfile;
|
|
51
|
+
}
|
|
52
|
+
export async function writeEnvLockfile(rootDir, lockfile) {
|
|
53
|
+
const lockfilePath = path.join(rootDir, WANTED_LOCKFILE);
|
|
54
|
+
const sorted = sortLockfileKeys(lockfile);
|
|
55
|
+
const envYaml = lockfileYamlDump(sorted);
|
|
56
|
+
const existing = await readLockfileToStringNoFollow(lockfilePath);
|
|
57
|
+
const mainDoc = existing == null ? '' : extractMainDocument(existing);
|
|
58
|
+
const combined = `---\n${envYaml}\n---\n${mainDoc}`;
|
|
59
|
+
return writeFileAtomic(lockfilePath, combined);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=envLockfile.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { PnpmError } from '@pnpm/error';
|
|
2
|
+
export class LockfileBreakingChangeError extends PnpmError {
|
|
3
|
+
filename;
|
|
4
|
+
constructor(filename) {
|
|
5
|
+
super('LOCKFILE_BREAKING_CHANGE', `Lockfile ${filename} not compatible with current pnpm`);
|
|
6
|
+
this.filename = filename;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=LockfileBreakingChangeError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { LockfileBreakingChangeError } from './LockfileBreakingChangeError.js';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
interface ExistsNonEmptyWantedLockfileOptions {
|
|
2
|
+
useGitBranchLockfile?: boolean;
|
|
3
|
+
mergeGitBranchLockfiles?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare function existsNonEmptyWantedLockfile(pkgPath: string, opts?: ExistsNonEmptyWantedLockfileOptions): Promise<boolean>;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { getWantedLockfileName } from './lockfileName.js';
|
|
4
|
+
export async function existsNonEmptyWantedLockfile(pkgPath, opts = {
|
|
5
|
+
useGitBranchLockfile: false,
|
|
6
|
+
mergeGitBranchLockfiles: false,
|
|
7
|
+
}) {
|
|
8
|
+
const wantedLockfile = await getWantedLockfileName(opts);
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
fs.access(path.join(pkgPath, wantedLockfile), (err) => {
|
|
11
|
+
if (err == null) {
|
|
12
|
+
resolve(true);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (err.code === 'ENOENT') {
|
|
16
|
+
resolve(false);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
reject(err);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=existsWantedLockfile.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import fs, { promises as fsp } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
// Branch lockfiles are written as `pnpm-lock.<branch>.yaml` with literal
|
|
4
|
+
// dots and a non-empty branch segment. Escaping the dots keeps unrelated
|
|
5
|
+
// files out of the matches that feed scanning and `cleanGitBranchLockfiles`.
|
|
6
|
+
const GIT_BRANCH_LOCKFILE_NAME = /^pnpm-lock\..+\.yaml$/;
|
|
7
|
+
export async function getGitBranchLockfileNames(lockfileDir) {
|
|
8
|
+
const files = await fsp.readdir(lockfileDir);
|
|
9
|
+
return files.filter(file => GIT_BRANCH_LOCKFILE_NAME.test(file));
|
|
10
|
+
}
|
|
11
|
+
export function getGitBranchLockfileNamesSync(lockfileDir) {
|
|
12
|
+
const files = fs.readdirSync(lockfileDir);
|
|
13
|
+
return files.filter(file => GIT_BRANCH_LOCKFILE_NAME.test(file));
|
|
14
|
+
}
|
|
15
|
+
export async function cleanGitBranchLockfiles(lockfileDir) {
|
|
16
|
+
const gitBranchLockfiles = await getGitBranchLockfileNames(lockfileDir);
|
|
17
|
+
await Promise.all(gitBranchLockfiles.map(async (file) => {
|
|
18
|
+
const filepath = path.join(lockfileDir, file);
|
|
19
|
+
await fsp.unlink(filepath);
|
|
20
|
+
}));
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=gitBranchLockfile.js.map
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { mergeLockfileChanges } from '@pnpm/lockfile.merger';
|
|
2
|
+
import yaml from 'js-yaml';
|
|
3
|
+
import { convertToLockfileObject } from './lockfileFormatConverters.js';
|
|
4
|
+
const MERGE_CONFLICT_PARENT = '|||||||';
|
|
5
|
+
const MERGE_CONFLICT_END = '>>>>>>>';
|
|
6
|
+
const MERGE_CONFLICT_THEIRS = '=======';
|
|
7
|
+
const MERGE_CONFLICT_OURS = '<<<<<<<';
|
|
8
|
+
export function autofixMergeConflicts(fileContent) {
|
|
9
|
+
const { ours, theirs } = parseMergeFile(fileContent);
|
|
10
|
+
return mergeLockfileChanges(convertToLockfileObject(yaml.load(ours)), convertToLockfileObject(yaml.load(theirs)));
|
|
11
|
+
}
|
|
12
|
+
function parseMergeFile(fileContent) {
|
|
13
|
+
const lines = fileContent.split(/[\n\r]+/);
|
|
14
|
+
let state = 'top';
|
|
15
|
+
const ours = [];
|
|
16
|
+
const theirs = [];
|
|
17
|
+
while (lines.length > 0) {
|
|
18
|
+
const line = lines.shift();
|
|
19
|
+
if (line.startsWith(MERGE_CONFLICT_PARENT)) {
|
|
20
|
+
state = 'parent';
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (line.startsWith(MERGE_CONFLICT_OURS)) {
|
|
24
|
+
state = 'ours';
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (line === MERGE_CONFLICT_THEIRS) {
|
|
28
|
+
state = 'theirs';
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (line.startsWith(MERGE_CONFLICT_END)) {
|
|
32
|
+
state = 'top';
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (state === 'top' || state === 'ours')
|
|
36
|
+
ours.push(line);
|
|
37
|
+
if (state === 'top' || state === 'theirs')
|
|
38
|
+
theirs.push(line);
|
|
39
|
+
}
|
|
40
|
+
return { ours: ours.join('\n'), theirs: theirs.join('\n') };
|
|
41
|
+
}
|
|
42
|
+
export function isDiff(fileContent) {
|
|
43
|
+
return fileContent.includes(MERGE_CONFLICT_OURS) &&
|
|
44
|
+
fileContent.includes(MERGE_CONFLICT_THEIRS) &&
|
|
45
|
+
fileContent.includes(MERGE_CONFLICT_END);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=gitMergeFile.js.map
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { createEnvLockfile, readEnvLockfile, writeEnvLockfile } from './envLockfile.js';
|
|
2
|
+
export { existsNonEmptyWantedLockfile } from './existsWantedLockfile.js';
|
|
3
|
+
export { getLockfileImporterId } from './getLockfileImporterId.js';
|
|
4
|
+
export { cleanGitBranchLockfiles, getGitBranchLockfileNamesSync } from './gitBranchLockfile.js';
|
|
5
|
+
export { convertToLockfileFile, convertToLockfileObject } from './lockfileFormatConverters.js';
|
|
6
|
+
export { getWantedLockfileName } from './lockfileName.js';
|
|
7
|
+
export * from './read.js';
|
|
8
|
+
export { isEmptyLockfile, writeCurrentLockfile, writeLockfileFile, writeLockfiles, type WriteLockfilesResult, writeWantedLockfile, } from './write.js';
|
|
9
|
+
export { extractMainDocument } from './yamlDocuments.js';
|
|
10
|
+
export * from '@pnpm/lockfile.types';
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { LOCKFILE_VERSION } from '@pnpm/constants';
|
|
2
|
+
import { parse, refToRelative, removeSuffix } from '@pnpm/deps.path';
|
|
3
|
+
import { isGitHostedTarballUrl } from '@pnpm/lockfile.utils';
|
|
4
|
+
import { DEPENDENCIES_FIELDS } from '@pnpm/types';
|
|
5
|
+
import { isEmpty, map as _mapValues, omit, pick, pickBy } from 'ramda';
|
|
6
|
+
export function convertToLockfileFile(lockfile) {
|
|
7
|
+
const packages = {};
|
|
8
|
+
const snapshots = {};
|
|
9
|
+
for (const [depPath, pkg] of Object.entries(lockfile.packages ?? {})) {
|
|
10
|
+
snapshots[depPath] = pick([
|
|
11
|
+
'dependencies',
|
|
12
|
+
'optionalDependencies',
|
|
13
|
+
'transitivePeerDependencies',
|
|
14
|
+
'optional',
|
|
15
|
+
'id',
|
|
16
|
+
], pkg);
|
|
17
|
+
const pkgId = removeSuffix(depPath);
|
|
18
|
+
if (!packages[pkgId]) {
|
|
19
|
+
packages[pkgId] = pick([
|
|
20
|
+
'bundledDependencies',
|
|
21
|
+
'cpu',
|
|
22
|
+
'deprecated',
|
|
23
|
+
'engines',
|
|
24
|
+
'hasBin',
|
|
25
|
+
'libc',
|
|
26
|
+
'name',
|
|
27
|
+
'os',
|
|
28
|
+
'peerDependencies',
|
|
29
|
+
'peerDependenciesMeta',
|
|
30
|
+
'resolution',
|
|
31
|
+
'version',
|
|
32
|
+
], pkg);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const newLockfile = {
|
|
36
|
+
...lockfile,
|
|
37
|
+
snapshots,
|
|
38
|
+
packages,
|
|
39
|
+
lockfileVersion: LOCKFILE_VERSION,
|
|
40
|
+
importers: mapValues(lockfile.importers, convertProjectSnapshotToInlineSpecifiersFormat),
|
|
41
|
+
};
|
|
42
|
+
if (newLockfile.settings?.peersSuffixMaxLength === 1000) {
|
|
43
|
+
newLockfile.settings = omit(['peersSuffixMaxLength'], newLockfile.settings);
|
|
44
|
+
}
|
|
45
|
+
if (newLockfile.settings?.injectWorkspacePackages === false) {
|
|
46
|
+
delete newLockfile.settings.injectWorkspacePackages;
|
|
47
|
+
}
|
|
48
|
+
return normalizeLockfile(newLockfile);
|
|
49
|
+
}
|
|
50
|
+
function normalizeLockfile(lockfile) {
|
|
51
|
+
const lockfileToSave = {
|
|
52
|
+
...lockfile,
|
|
53
|
+
importers: _mapValues((importer) => {
|
|
54
|
+
const normalizedImporter = {};
|
|
55
|
+
if (importer.dependenciesMeta != null && !isEmpty(importer.dependenciesMeta)) {
|
|
56
|
+
normalizedImporter.dependenciesMeta = importer.dependenciesMeta;
|
|
57
|
+
}
|
|
58
|
+
for (const depType of DEPENDENCIES_FIELDS) {
|
|
59
|
+
if (!isEmpty(importer[depType] ?? {})) {
|
|
60
|
+
normalizedImporter[depType] = importer[depType];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (importer.publishDirectory) {
|
|
64
|
+
normalizedImporter.publishDirectory = importer.publishDirectory;
|
|
65
|
+
}
|
|
66
|
+
return normalizedImporter;
|
|
67
|
+
}, lockfile.importers ?? {}),
|
|
68
|
+
};
|
|
69
|
+
if (isEmpty(lockfileToSave.packages) || (lockfileToSave.packages == null)) {
|
|
70
|
+
delete lockfileToSave.packages;
|
|
71
|
+
}
|
|
72
|
+
if (isEmpty(lockfileToSave.snapshots) || (lockfileToSave.snapshots == null)) {
|
|
73
|
+
delete lockfileToSave.snapshots;
|
|
74
|
+
}
|
|
75
|
+
if (lockfileToSave.time) {
|
|
76
|
+
lockfileToSave.time = pruneTimeInLockfile(lockfileToSave.time, lockfile.importers ?? {});
|
|
77
|
+
}
|
|
78
|
+
if ((lockfileToSave.catalogs != null) && isEmpty(lockfileToSave.catalogs)) {
|
|
79
|
+
delete lockfileToSave.catalogs;
|
|
80
|
+
}
|
|
81
|
+
if ((lockfileToSave.overrides != null) && isEmpty(lockfileToSave.overrides)) {
|
|
82
|
+
delete lockfileToSave.overrides;
|
|
83
|
+
}
|
|
84
|
+
if ((lockfileToSave.patchedDependencies != null) && isEmpty(lockfileToSave.patchedDependencies)) {
|
|
85
|
+
delete lockfileToSave.patchedDependencies;
|
|
86
|
+
}
|
|
87
|
+
if (!lockfileToSave.packageExtensionsChecksum) {
|
|
88
|
+
delete lockfileToSave.packageExtensionsChecksum;
|
|
89
|
+
}
|
|
90
|
+
if (!lockfileToSave.ignoredOptionalDependencies?.length) {
|
|
91
|
+
delete lockfileToSave.ignoredOptionalDependencies;
|
|
92
|
+
}
|
|
93
|
+
if (!lockfileToSave.pnpmfileChecksum) {
|
|
94
|
+
delete lockfileToSave.pnpmfileChecksum;
|
|
95
|
+
}
|
|
96
|
+
return lockfileToSave;
|
|
97
|
+
}
|
|
98
|
+
function pruneTimeInLockfile(time, importers) {
|
|
99
|
+
const rootDepPaths = new Set();
|
|
100
|
+
for (const importer of Object.values(importers)) {
|
|
101
|
+
for (const depType of DEPENDENCIES_FIELDS) {
|
|
102
|
+
for (const [depName, ref] of Object.entries(importer[depType] ?? {})) {
|
|
103
|
+
const suffixStart = ref.version.indexOf('(');
|
|
104
|
+
const refWithoutPeerDepGraphHash = suffixStart === -1 ? ref.version : ref.version.slice(0, suffixStart);
|
|
105
|
+
const depPath = refToRelative(refWithoutPeerDepGraphHash, depName);
|
|
106
|
+
if (!depPath)
|
|
107
|
+
continue;
|
|
108
|
+
rootDepPaths.add(depPath);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return pickBy((_, depPath) => rootDepPaths.has(depPath), time);
|
|
113
|
+
}
|
|
114
|
+
// Mirrors `isFilename` in `resolving/local-resolver/src/parseBareSpecifier.ts`
|
|
115
|
+
// so the directory-vs-tarball boundary applied at lockfile load time
|
|
116
|
+
// matches the resolver's at resolve time.
|
|
117
|
+
const LOCAL_TARBALL_RE = /\.(?:tgz|tar\.gz|tar)$/i;
|
|
118
|
+
export function convertToLockfileObject(lockfile) {
|
|
119
|
+
const { importers, ...rest } = lockfile;
|
|
120
|
+
const packages = {};
|
|
121
|
+
for (const [depPath, pkg] of Object.entries(lockfile.snapshots ?? {})) {
|
|
122
|
+
const pkgId = removeSuffix(depPath);
|
|
123
|
+
const snapshot = Object.assign(pkg, lockfile.packages?.[pkgId]);
|
|
124
|
+
// Defense-in-depth for pruned lockfiles (older `turbo prune --docker`,
|
|
125
|
+
// pre vercel/turborepo#12825): a peer-variant injected workspace
|
|
126
|
+
// snapshot whose base `packages:` entry was dropped now has a null
|
|
127
|
+
// `resolution`. Reconstruct it from the `file:` depPath — same value
|
|
128
|
+
// pnpm's writer emits — so every downstream reader sees a complete
|
|
129
|
+
// snapshot without per-reader guards.
|
|
130
|
+
if (snapshot.resolution == null) {
|
|
131
|
+
const ref = parse(depPath).nonSemverVersion;
|
|
132
|
+
if (ref != null && ref.startsWith('file:') && !LOCAL_TARBALL_RE.test(ref)) {
|
|
133
|
+
snapshot.resolution = { directory: ref.slice('file:'.length), type: 'directory' };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
packages[depPath] = snapshot;
|
|
137
|
+
enrichGitHostedFlag(packages[depPath]?.resolution);
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
...omit(['snapshots'], rest),
|
|
141
|
+
patchedDependencies: migratePatchedDependencies(rest.patchedDependencies),
|
|
142
|
+
packages,
|
|
143
|
+
importers: mapValues(importers ?? {}, revertProjectSnapshot),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
// Backfill the `gitHosted` flag for tarball resolutions written by older
|
|
147
|
+
// pnpm versions. Doing it once at load time lets every downstream reader
|
|
148
|
+
// rely on the typed field instead of repeating URL prefix matches.
|
|
149
|
+
function enrichGitHostedFlag(resolution) {
|
|
150
|
+
if (resolution == null)
|
|
151
|
+
return;
|
|
152
|
+
if (resolution.type !== undefined)
|
|
153
|
+
return;
|
|
154
|
+
if (resolution.gitHosted != null)
|
|
155
|
+
return;
|
|
156
|
+
if (resolution.tarball != null && isGitHostedTarballUrl(resolution.tarball)) {
|
|
157
|
+
resolution.gitHosted = true;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function migratePatchedDependencies(patchedDependencies) {
|
|
161
|
+
if (!patchedDependencies)
|
|
162
|
+
return undefined;
|
|
163
|
+
const result = {};
|
|
164
|
+
for (const [key, value] of Object.entries(patchedDependencies)) {
|
|
165
|
+
result[key] = typeof value === 'string' ? value : value.hash;
|
|
166
|
+
}
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
function convertProjectSnapshotToInlineSpecifiersFormat(projectSnapshot) {
|
|
170
|
+
const { specifiers, ...rest } = projectSnapshot;
|
|
171
|
+
if (specifiers == null)
|
|
172
|
+
return projectSnapshot;
|
|
173
|
+
const convertBlock = (block) => block != null
|
|
174
|
+
? convertResolvedDependenciesToInlineSpecifiersFormat(block, { specifiers })
|
|
175
|
+
: block;
|
|
176
|
+
return {
|
|
177
|
+
...rest,
|
|
178
|
+
dependencies: convertBlock(projectSnapshot.dependencies ?? {}),
|
|
179
|
+
optionalDependencies: convertBlock(projectSnapshot.optionalDependencies ?? {}),
|
|
180
|
+
devDependencies: convertBlock(projectSnapshot.devDependencies ?? {}),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function convertResolvedDependenciesToInlineSpecifiersFormat(resolvedDependencies, { specifiers }) {
|
|
184
|
+
return mapValues(resolvedDependencies, (version, depName) => ({
|
|
185
|
+
specifier: specifiers[depName],
|
|
186
|
+
version,
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
189
|
+
function revertProjectSnapshot(from) {
|
|
190
|
+
const specifiers = {};
|
|
191
|
+
function moveSpecifiers(from) {
|
|
192
|
+
const resolvedDependencies = {};
|
|
193
|
+
for (const [depName, { specifier, version }] of Object.entries(from)) {
|
|
194
|
+
const existingValue = specifiers[depName];
|
|
195
|
+
if (existingValue != null && existingValue !== specifier) {
|
|
196
|
+
throw new Error(`Project snapshot lists the same dependency more than once with conflicting versions: ${depName}`);
|
|
197
|
+
}
|
|
198
|
+
specifiers[depName] = specifier;
|
|
199
|
+
resolvedDependencies[depName] = version;
|
|
200
|
+
}
|
|
201
|
+
return resolvedDependencies;
|
|
202
|
+
}
|
|
203
|
+
const dependencies = from.dependencies == null
|
|
204
|
+
? from.dependencies
|
|
205
|
+
: moveSpecifiers(from.dependencies);
|
|
206
|
+
const devDependencies = from.devDependencies == null
|
|
207
|
+
? from.devDependencies
|
|
208
|
+
: moveSpecifiers(from.devDependencies);
|
|
209
|
+
const optionalDependencies = from.optionalDependencies == null
|
|
210
|
+
? from.optionalDependencies
|
|
211
|
+
: moveSpecifiers(from.optionalDependencies);
|
|
212
|
+
return {
|
|
213
|
+
...from,
|
|
214
|
+
specifiers,
|
|
215
|
+
dependencies,
|
|
216
|
+
devDependencies,
|
|
217
|
+
optionalDependencies,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function mapValues(obj, mapper) {
|
|
221
|
+
const result = {};
|
|
222
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
223
|
+
result[key] = mapper(value, key);
|
|
224
|
+
}
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=lockfileFormatConverters.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { WANTED_LOCKFILE } from '@pnpm/constants';
|
|
2
|
+
import { getCurrentBranch } from '@pnpm/network.git-utils';
|
|
3
|
+
export async function getWantedLockfileName(opts = {}) {
|
|
4
|
+
if (opts.useGitBranchLockfile && !opts.mergeGitBranchLockfiles) {
|
|
5
|
+
const currentBranchName = await getCurrentBranch({ cwd: opts.cwd });
|
|
6
|
+
if (currentBranchName) {
|
|
7
|
+
return WANTED_LOCKFILE.replace('.yaml', `.${stringifyBranchName(currentBranchName)}.yaml`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return WANTED_LOCKFILE;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 1. Git branch name may contains slashes, which is not allowed in filenames
|
|
14
|
+
* 2. Filesystem may be case-insensitive, so we need to convert branch name to lowercase
|
|
15
|
+
*/
|
|
16
|
+
function stringifyBranchName(branchName = '') {
|
|
17
|
+
return branchName.replace(/[^\w.-]/g, '!').toLowerCase();
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=lockfileName.js.map
|
package/lib/logger.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const lockfileLogger: import("@pnpm/logger").Logger<unknown>;
|
package/lib/logger.js
ADDED
package/lib/read.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { LockfileFile, LockfileObject } from '@pnpm/lockfile.types';
|
|
2
|
+
import type { ProjectId } from '@pnpm/types';
|
|
3
|
+
export declare function readCurrentLockfile(pnpmInternalDir: string, opts: {
|
|
4
|
+
wantedVersions?: string[];
|
|
5
|
+
ignoreIncompatible: boolean;
|
|
6
|
+
}): Promise<LockfileObject | null>;
|
|
7
|
+
export declare function readWantedLockfileAndAutofixConflicts(pkgPath: string, opts: {
|
|
8
|
+
wantedVersions?: string[];
|
|
9
|
+
ignoreIncompatible: boolean;
|
|
10
|
+
useGitBranchLockfile?: boolean;
|
|
11
|
+
mergeGitBranchLockfiles?: boolean;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
lockfile: LockfileObject | null;
|
|
14
|
+
hadConflicts: boolean;
|
|
15
|
+
}>;
|
|
16
|
+
export declare function readWantedLockfile(pkgPath: string, opts: {
|
|
17
|
+
wantedVersions?: string[];
|
|
18
|
+
ignoreIncompatible: boolean;
|
|
19
|
+
useGitBranchLockfile?: boolean;
|
|
20
|
+
mergeGitBranchLockfiles?: boolean;
|
|
21
|
+
}): Promise<LockfileObject | null>;
|
|
22
|
+
/**
|
|
23
|
+
* Read the wanted lockfile in its on-disk shape ({@link LockfileFile}),
|
|
24
|
+
* skipping the conversion to the in-memory {@link LockfileObject}.
|
|
25
|
+
*
|
|
26
|
+
* Use this when the caller needs the exact serialized form — e.g. to
|
|
27
|
+
* forward the lockfile to a server that speaks the on-disk format —
|
|
28
|
+
* rather than the in-process representation.
|
|
29
|
+
*/
|
|
30
|
+
export declare function readWantedLockfileFile(pkgPath: string, opts: {
|
|
31
|
+
wantedVersions?: string[];
|
|
32
|
+
ignoreIncompatible: boolean;
|
|
33
|
+
useGitBranchLockfile?: boolean;
|
|
34
|
+
mergeGitBranchLockfiles?: boolean;
|
|
35
|
+
}): Promise<LockfileFile | null>;
|
|
36
|
+
export declare function wantedLockfileHasMergeConflictsSync(pkgPath: string, lockfileName?: string): boolean;
|
|
37
|
+
export declare function createLockfileObject(importerIds: ProjectId[], opts: {
|
|
38
|
+
lockfileVersion: string;
|
|
39
|
+
autoInstallPeers: boolean;
|
|
40
|
+
excludeLinksFromLockfile: boolean;
|
|
41
|
+
peersSuffixMaxLength: number;
|
|
42
|
+
}): LockfileObject;
|