@pnpm/fetching.directory-fetcher 1100.0.35 → 1100.0.36
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 +19 -0
- package/lib/index.d.ts +3 -2
- package/lib/index.js +50 -13
- package/package.json +9 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @pnpm/directory-fetcher
|
|
2
2
|
|
|
3
|
+
## 1100.0.36
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- `pnpm deploy` with a shared lockfile now copies workspace dependencies into the deploy directory, even when `packageImportMethod` is set to `hardlink`. Previously, their files were hard-linked to the workspace sources, so editing a source file also changed the deployed copy [pnpm/pnpm#12176](https://github.com/pnpm/pnpm/issues/12176).
|
|
8
|
+
|
|
9
|
+
- `pnpm install` no longer fails for an injected workspace dependency whose package publishes from a `publishConfig.directory` that its own `prepare` script builds. The injected copy now picks up that directory once `prepare` finishes building it. `pnpm install --frozen-lockfile` no longer reports the dependency as outdated while the directory has not been built yet. [pnpm/pnpm#7811](https://github.com/pnpm/pnpm/issues/7811)
|
|
10
|
+
|
|
11
|
+
- `pnpm install` now works in StackBlitz WebContainers on projects without a lockfile. It used to fail there with `ENOENT ... pnpm-lock.yaml`, because pnpm did not recognize the errors that WebContainers return from asynchronous file system calls [#15649](https://github.com/pnpm/pnpm/issues/15649).
|
|
12
|
+
|
|
13
|
+
- Updated dependencies:
|
|
14
|
+
- @pnpm/building.pkg-requires-build@1100.0.19
|
|
15
|
+
- @pnpm/error@1100.2.1
|
|
16
|
+
- @pnpm/fetching.fetcher-base@1100.2.12
|
|
17
|
+
- @pnpm/fs.packlist@1100.0.6
|
|
18
|
+
- @pnpm/resolving.resolver-base@1101.3.2
|
|
19
|
+
- @pnpm/store.cafs-types@1100.1.1
|
|
20
|
+
- @pnpm/workspace.project-manifest-reader@1100.1.1
|
|
21
|
+
|
|
3
22
|
## 1100.0.35
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/lib/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { type Stats } from 'node:fs';
|
|
2
|
-
import type { DirectoryFetcher, DirectoryFetcherOptions } from '@pnpm/fetching.fetcher-base';
|
|
2
|
+
import type { DirectoryFetcher, DirectoryFetcherOptions, LocalDirPackageImportMethod } from '@pnpm/fetching.fetcher-base';
|
|
3
3
|
import type { FilesMap } from '@pnpm/store.cafs-types';
|
|
4
4
|
import type { DependencyManifest } from '@pnpm/types';
|
|
5
5
|
export interface CreateDirectoryFetcherOptions {
|
|
6
6
|
includeOnlyPackageFiles?: boolean;
|
|
7
|
+
localDirPackageImportMethod?: LocalDirPackageImportMethod;
|
|
7
8
|
resolveSymlinks?: boolean;
|
|
8
9
|
}
|
|
9
10
|
export declare function createDirectoryFetcher(opts?: CreateDirectoryFetcherOptions): {
|
|
@@ -14,7 +15,7 @@ export interface FetchResult {
|
|
|
14
15
|
local: true;
|
|
15
16
|
filesMap: FilesMap;
|
|
16
17
|
filesStats?: Record<string, Stats | null>;
|
|
17
|
-
packageImportMethod:
|
|
18
|
+
packageImportMethod: LocalDirPackageImportMethod;
|
|
18
19
|
manifest: DependencyManifest;
|
|
19
20
|
requiresBuild: boolean;
|
|
20
21
|
}
|
package/lib/index.js
CHANGED
|
@@ -1,33 +1,70 @@
|
|
|
1
1
|
import { promises as fs } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import util from 'node:util';
|
|
4
3
|
import { pkgRequiresBuild } from '@pnpm/building.pkg-requires-build';
|
|
4
|
+
import { isError } from '@pnpm/error';
|
|
5
5
|
import { packlist } from '@pnpm/fs.packlist';
|
|
6
6
|
import { logger } from '@pnpm/logger';
|
|
7
|
-
import { safeReadProjectManifestOnly } from '@pnpm/workspace.project-manifest-reader';
|
|
7
|
+
import { safeReadParentPublishManifest, safeReadProjectManifestOnly } from '@pnpm/workspace.project-manifest-reader';
|
|
8
8
|
const directoryFetcherLogger = logger('directory-fetcher');
|
|
9
9
|
export function createDirectoryFetcher(opts) {
|
|
10
10
|
const readFileStat = opts?.resolveSymlinks === true ? realFileStat : fileStat;
|
|
11
|
-
const
|
|
12
|
-
const
|
|
11
|
+
const packageImportMethod = opts?.localDirPackageImportMethod ?? 'hardlink';
|
|
12
|
+
const fetchFromDir = opts?.includeOnlyPackageFiles
|
|
13
|
+
? fetchPackageFilesFromDir.bind(null, packageImportMethod)
|
|
14
|
+
: fetchAllFilesFromDir.bind(null, readFileStat, packageImportMethod);
|
|
15
|
+
const directoryFetcher = async (cafs, resolution, opts) => {
|
|
13
16
|
// Use path.resolve so absolute directories (e.g. cross-drive Windows paths
|
|
14
17
|
// stored by `file:` deps) are respected instead of being concatenated
|
|
15
18
|
// onto lockfileDir.
|
|
16
19
|
const dir = path.resolve(opts.lockfileDir, resolution.directory);
|
|
17
|
-
|
|
20
|
+
// An injected dependency whose packed content is the output of its own
|
|
21
|
+
// lifecycle scripts (a project with `publishConfig.directory` built by
|
|
22
|
+
// `prepare`) has no source directory on a fresh install: the scripts run
|
|
23
|
+
// after linking, and the built output is imported afterwards. Inject an
|
|
24
|
+
// empty copy so the install can proceed instead of failing on the
|
|
25
|
+
// not-yet-built directory. Any other missing directory still fails.
|
|
26
|
+
if (!await dirExists(dir)) {
|
|
27
|
+
const manifest = await safeReadParentPublishManifest(dir);
|
|
28
|
+
if (manifest != null) {
|
|
29
|
+
return {
|
|
30
|
+
local: true,
|
|
31
|
+
filesMap: new Map(),
|
|
32
|
+
packageImportMethod,
|
|
33
|
+
manifest,
|
|
34
|
+
requiresBuild: false,
|
|
35
|
+
sourceExists: false,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
...await fetchFromDir(dir),
|
|
41
|
+
sourceExists: true,
|
|
42
|
+
};
|
|
18
43
|
};
|
|
19
44
|
return {
|
|
20
45
|
directory: directoryFetcher,
|
|
21
46
|
};
|
|
22
47
|
}
|
|
48
|
+
async function dirExists(dir) {
|
|
49
|
+
try {
|
|
50
|
+
await fs.stat(dir);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
if (isError(err) && 'code' in err && err.code === 'ENOENT')
|
|
55
|
+
return false;
|
|
56
|
+
throw err;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
23
59
|
export async function fetchFromDir(dir, opts) {
|
|
60
|
+
const packageImportMethod = opts.localDirPackageImportMethod ?? 'hardlink';
|
|
24
61
|
if (opts.includeOnlyPackageFiles) {
|
|
25
|
-
return fetchPackageFilesFromDir(dir);
|
|
62
|
+
return fetchPackageFilesFromDir(packageImportMethod, dir);
|
|
26
63
|
}
|
|
27
64
|
const readFileStat = opts?.resolveSymlinks === true ? realFileStat : fileStat;
|
|
28
|
-
return fetchAllFilesFromDir(readFileStat, dir);
|
|
65
|
+
return fetchAllFilesFromDir(readFileStat, packageImportMethod, dir);
|
|
29
66
|
}
|
|
30
|
-
async function fetchAllFilesFromDir(readFileStat, dir) {
|
|
67
|
+
async function fetchAllFilesFromDir(readFileStat, packageImportMethod, dir) {
|
|
31
68
|
const { filesMap, filesStats } = await _fetchAllFilesFromDir(readFileStat, dir);
|
|
32
69
|
// In a regular pnpm workspace it will probably never happen that a dependency has no package.json file.
|
|
33
70
|
// Safe read was added to support the Bit workspace in which the components have no package.json files.
|
|
@@ -38,7 +75,7 @@ async function fetchAllFilesFromDir(readFileStat, dir) {
|
|
|
38
75
|
local: true,
|
|
39
76
|
filesMap,
|
|
40
77
|
filesStats,
|
|
41
|
-
packageImportMethod
|
|
78
|
+
packageImportMethod,
|
|
42
79
|
manifest,
|
|
43
80
|
requiresBuild,
|
|
44
81
|
};
|
|
@@ -81,7 +118,7 @@ async function realFileStat(filePath) {
|
|
|
81
118
|
}
|
|
82
119
|
catch (err) {
|
|
83
120
|
// Broken symlinks are skipped
|
|
84
|
-
if (
|
|
121
|
+
if (isError(err) && 'code' in err && err.code === 'ENOENT') {
|
|
85
122
|
directoryFetcherLogger.debug({ brokenSymlink: filePath });
|
|
86
123
|
return null;
|
|
87
124
|
}
|
|
@@ -97,14 +134,14 @@ async function fileStat(filePath) {
|
|
|
97
134
|
}
|
|
98
135
|
catch (err) {
|
|
99
136
|
// Broken symlinks are skipped
|
|
100
|
-
if (
|
|
137
|
+
if (isError(err) && 'code' in err && err.code === 'ENOENT') {
|
|
101
138
|
directoryFetcherLogger.debug({ brokenSymlink: filePath });
|
|
102
139
|
return null;
|
|
103
140
|
}
|
|
104
141
|
throw err;
|
|
105
142
|
}
|
|
106
143
|
}
|
|
107
|
-
async function fetchPackageFilesFromDir(dir) {
|
|
144
|
+
async function fetchPackageFilesFromDir(packageImportMethod, dir) {
|
|
108
145
|
const files = await packlist(dir);
|
|
109
146
|
const filesMap = new Map(files.map((file) => [file, path.join(dir, file)]));
|
|
110
147
|
// In a regular pnpm workspace it will probably never happen that a dependency has no package.json file.
|
|
@@ -115,7 +152,7 @@ async function fetchPackageFilesFromDir(dir) {
|
|
|
115
152
|
return {
|
|
116
153
|
local: true,
|
|
117
154
|
filesMap,
|
|
118
|
-
packageImportMethod
|
|
155
|
+
packageImportMethod,
|
|
119
156
|
manifest,
|
|
120
157
|
requiresBuild,
|
|
121
158
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/fetching.directory-fetcher",
|
|
3
|
-
"version": "1100.0.
|
|
3
|
+
"version": "1100.0.36",
|
|
4
4
|
"description": "A fetcher for local directory packages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -28,20 +28,21 @@
|
|
|
28
28
|
"!*.map"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@pnpm/building.pkg-requires-build": "1100.0.
|
|
32
|
-
"@pnpm/
|
|
33
|
-
"@pnpm/
|
|
34
|
-
"@pnpm/
|
|
35
|
-
"@pnpm/
|
|
31
|
+
"@pnpm/building.pkg-requires-build": "1100.0.19",
|
|
32
|
+
"@pnpm/error": "1100.2.1",
|
|
33
|
+
"@pnpm/fetching.fetcher-base": "1100.2.12",
|
|
34
|
+
"@pnpm/fs.packlist": "1100.0.6",
|
|
35
|
+
"@pnpm/resolving.resolver-base": "1101.3.2",
|
|
36
|
+
"@pnpm/store.cafs-types": "1100.1.1",
|
|
36
37
|
"@pnpm/types": "1102.1.1",
|
|
37
|
-
"@pnpm/workspace.project-manifest-reader": "1100.1.
|
|
38
|
+
"@pnpm/workspace.project-manifest-reader": "1100.1.1"
|
|
38
39
|
},
|
|
39
40
|
"peerDependencies": {
|
|
40
41
|
"@pnpm/logger": "^1100.0.0"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
44
|
"@jest/globals": "30.4.1",
|
|
44
|
-
"@pnpm/fetching.directory-fetcher": "1100.0.
|
|
45
|
+
"@pnpm/fetching.directory-fetcher": "1100.0.36",
|
|
45
46
|
"@pnpm/logger": "1100.0.0",
|
|
46
47
|
"@pnpm/test-fixtures": "1100.0.1",
|
|
47
48
|
"@pnpm/text.ordinal-comparator": "1100.0.0",
|