@pnpm/lockfile.fs 1100.1.7 → 1100.1.9
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/lib/envLockfile.js +3 -14
- package/lib/yamlDocuments.d.ts +1 -0
- package/lib/yamlDocuments.js +51 -2
- package/package.json +7 -7
package/lib/envLockfile.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { promises as fs } from 'node:fs';
|
|
2
1
|
import path from 'node:path';
|
|
3
|
-
import util from 'node:util';
|
|
4
2
|
import { LOCKFILE_VERSION, WANTED_LOCKFILE } from '@pnpm/constants';
|
|
5
3
|
import yaml from 'js-yaml';
|
|
6
4
|
import writeFileAtomic from 'write-file-atomic';
|
|
7
5
|
import { sortLockfileKeys } from './sortLockfileKeys.js';
|
|
8
6
|
import { lockfileYamlDump } from './write.js';
|
|
9
|
-
import { extractMainDocument, streamReadFirstYamlDocument } from './yamlDocuments.js';
|
|
7
|
+
import { extractMainDocument, readLockfileToStringNoFollow, streamReadFirstYamlDocument } from './yamlDocuments.js';
|
|
10
8
|
export function createEnvLockfile() {
|
|
11
9
|
return {
|
|
12
10
|
lockfileVersion: LOCKFILE_VERSION,
|
|
@@ -55,17 +53,8 @@ export async function writeEnvLockfile(rootDir, lockfile) {
|
|
|
55
53
|
const lockfilePath = path.join(rootDir, WANTED_LOCKFILE);
|
|
56
54
|
const sorted = sortLockfileKeys(lockfile);
|
|
57
55
|
const envYaml = lockfileYamlDump(sorted);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
try {
|
|
61
|
-
const existing = await fs.readFile(lockfilePath, 'utf8');
|
|
62
|
-
mainDoc = extractMainDocument(existing);
|
|
63
|
-
}
|
|
64
|
-
catch (err) {
|
|
65
|
-
if (!(util.types.isNativeError(err) && 'code' in err && err.code === 'ENOENT')) {
|
|
66
|
-
throw err;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
56
|
+
const existing = await readLockfileToStringNoFollow(lockfilePath);
|
|
57
|
+
const mainDoc = existing == null ? '' : extractMainDocument(existing);
|
|
69
58
|
const combined = `---\n${envYaml}\n---\n${mainDoc}`;
|
|
70
59
|
return writeFileAtomic(lockfilePath, combined);
|
|
71
60
|
}
|
package/lib/yamlDocuments.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export declare const YAML_DOCUMENT_START = "---\n";
|
|
|
7
7
|
* Returns null if the file doesn't exist or doesn't start with "---\n".
|
|
8
8
|
*/
|
|
9
9
|
export declare function streamReadFirstYamlDocument(filePath: string, readBufferSize?: number): Promise<string | null>;
|
|
10
|
+
export declare function readLockfileToStringNoFollow(filePath: string): Promise<string | null>;
|
|
10
11
|
/**
|
|
11
12
|
* Extracts the main lockfile content (second YAML document) from a combined string.
|
|
12
13
|
* If the file starts with "---\n", returns the content after the separator.
|
package/lib/yamlDocuments.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { constants } from 'node:fs';
|
|
2
|
+
import { lstat, open } from 'node:fs/promises';
|
|
2
3
|
import { StringDecoder } from 'node:string_decoder';
|
|
3
4
|
import util from 'node:util';
|
|
5
|
+
import { PnpmError } from '@pnpm/error';
|
|
4
6
|
import stripBom from 'strip-bom';
|
|
5
7
|
export const YAML_DOCUMENT_SEPARATOR = '\n---\n';
|
|
6
8
|
export const YAML_DOCUMENT_START = '---\n';
|
|
7
9
|
const READ_BUFFER_SIZE = 64 * 1024;
|
|
10
|
+
const LOCKFILE_READ_FLAGS = constants.O_RDONLY | (process.platform === 'win32' ? 0 : constants.O_NOFOLLOW);
|
|
8
11
|
/**
|
|
9
12
|
* Reads the first YAML document from a multi-document YAML file using streaming.
|
|
10
13
|
* The file must start with "---\n" to indicate it contains an env lockfile document.
|
|
@@ -16,7 +19,7 @@ export async function streamReadFirstYamlDocument(filePath, readBufferSize = REA
|
|
|
16
19
|
let buffer = '';
|
|
17
20
|
let firstChunk = true;
|
|
18
21
|
try {
|
|
19
|
-
fileHandle = await
|
|
22
|
+
fileHandle = await openLockfileNoFollow(filePath);
|
|
20
23
|
const decoder = new StringDecoder('utf8');
|
|
21
24
|
const readBuffer = Buffer.allocUnsafe(normalizeReadBufferSize(readBufferSize));
|
|
22
25
|
let position = 0;
|
|
@@ -60,6 +63,52 @@ export async function streamReadFirstYamlDocument(filePath, readBufferSize = REA
|
|
|
60
63
|
await fileHandle?.close().catch(() => { });
|
|
61
64
|
}
|
|
62
65
|
}
|
|
66
|
+
export async function readLockfileToStringNoFollow(filePath) {
|
|
67
|
+
let fileHandle;
|
|
68
|
+
try {
|
|
69
|
+
fileHandle = await openLockfileNoFollow(filePath);
|
|
70
|
+
return await fileHandle.readFile('utf8');
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
if (util.types.isNativeError(err) && 'code' in err && err.code === 'ENOENT') {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
throw err;
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
await fileHandle?.close().catch(() => { });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function openLockfileNoFollow(filePath) {
|
|
83
|
+
await ensureLockfileIsNotSymlink(filePath);
|
|
84
|
+
try {
|
|
85
|
+
return await open(filePath, LOCKFILE_READ_FLAGS);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
if (util.types.isNativeError(err) && 'code' in err && err.code === 'ELOOP') {
|
|
89
|
+
throw symlinkedLockfileError(filePath);
|
|
90
|
+
}
|
|
91
|
+
throw err;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async function ensureLockfileIsNotSymlink(filePath) {
|
|
95
|
+
let stat;
|
|
96
|
+
try {
|
|
97
|
+
stat = await lstat(filePath);
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
if (util.types.isNativeError(err) && 'code' in err && err.code === 'ENOENT') {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
throw err;
|
|
104
|
+
}
|
|
105
|
+
if (stat.isSymbolicLink()) {
|
|
106
|
+
throw symlinkedLockfileError(filePath);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function symlinkedLockfileError(filePath) {
|
|
110
|
+
return new PnpmError('LOCKFILE_IS_SYMLINK', `Refusing to read or write symlinked lockfile at ${filePath}`);
|
|
111
|
+
}
|
|
63
112
|
function canRejectDocumentStart(buffer) {
|
|
64
113
|
if (buffer.length < YAML_DOCUMENT_START.length)
|
|
65
114
|
return false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/lockfile.fs",
|
|
3
|
-
"version": "1100.1.
|
|
3
|
+
"version": "1100.1.9",
|
|
4
4
|
"description": "Read/write pnpm-lock.yaml files",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -37,14 +37,14 @@
|
|
|
37
37
|
"semver": "^7.8.4",
|
|
38
38
|
"strip-bom": "^5.0.0",
|
|
39
39
|
"write-file-atomic": "^7.0.1",
|
|
40
|
-
"@pnpm/constants": "1100.0.0",
|
|
41
40
|
"@pnpm/deps.path": "1100.0.8",
|
|
42
|
-
"@pnpm/
|
|
41
|
+
"@pnpm/constants": "1100.0.0",
|
|
42
|
+
"@pnpm/lockfile.merger": "1100.0.13",
|
|
43
|
+
"@pnpm/lockfile.utils": "1100.1.1",
|
|
44
|
+
"@pnpm/network.git-utils": "1100.0.2",
|
|
43
45
|
"@pnpm/error": "1100.0.1",
|
|
44
46
|
"@pnpm/object.key-sorting": "1100.0.1",
|
|
45
|
-
"@pnpm/lockfile.
|
|
46
|
-
"@pnpm/lockfile.utils": "1100.1.0",
|
|
47
|
-
"@pnpm/network.git-utils": "1100.0.2",
|
|
47
|
+
"@pnpm/lockfile.types": "1100.0.13",
|
|
48
48
|
"@pnpm/types": "1101.3.2"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"tempy": "3.0.0",
|
|
61
61
|
"write-yaml-file": "^6.0.0",
|
|
62
62
|
"yaml-tag": "1.1.0",
|
|
63
|
-
"@pnpm/lockfile.fs": "1100.1.
|
|
63
|
+
"@pnpm/lockfile.fs": "1100.1.9",
|
|
64
64
|
"@pnpm/logger": "1100.0.0"
|
|
65
65
|
},
|
|
66
66
|
"engines": {
|