@pnpm/releasing.exportable-manifest 1100.3.2 → 1100.3.4
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 +29 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.js +91 -16
- package/lib/overridePublishConfig.js +5 -2
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @pnpm/exportable-manifest
|
|
2
2
|
|
|
3
|
+
## 1100.3.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- `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).
|
|
8
|
+
|
|
9
|
+
- Updated dependencies:
|
|
10
|
+
- @pnpm/catalogs.resolver@1100.1.1
|
|
11
|
+
- @pnpm/error@1100.2.1
|
|
12
|
+
- @pnpm/resolving.jsr-specifier-parser@1100.0.9
|
|
13
|
+
- @pnpm/workspace.project-manifest-reader@1100.1.1
|
|
14
|
+
|
|
15
|
+
## 1100.3.3
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- The `publish` command now resolves `workspace:` dependencies from workspace manifests when `node_modules` is not installed. Previously, publishing without `node_modules` failed with `ERR_PNPM_CANNOT_RESOLVE_WORKSPACE_PROTOCOL`. pnpm/pnpm#6567
|
|
20
|
+
|
|
21
|
+
- `make-dedicated-lockfile` no longer removes fields such as `main` and `types` from the `publishConfig` of the project's `package.json`.
|
|
22
|
+
|
|
23
|
+
- `pnpm publish` and `pnpm pack` now report a missing `version` or `name` field on a workspace dependency. Previously, pnpm reported that the dependency was not installed [#4164](https://github.com/pnpm/pnpm/issues/4164).
|
|
24
|
+
|
|
25
|
+
- Updated dependencies:
|
|
26
|
+
- @pnpm/bins.resolver@1100.0.17
|
|
27
|
+
- @pnpm/error@1100.2.0
|
|
28
|
+
- @pnpm/resolving.jsr-specifier-parser@1100.0.8
|
|
29
|
+
- @pnpm/types@1102.1.1
|
|
30
|
+
- @pnpm/workspace.project-manifest-reader@1100.1.0
|
|
31
|
+
|
|
3
32
|
## 1100.3.2
|
|
4
33
|
|
|
5
34
|
### Patch Changes
|
package/lib/index.d.ts
CHANGED
|
@@ -3,12 +3,17 @@ import type { Hooks } from '@pnpm/hooks.pnpmfile';
|
|
|
3
3
|
import type { ProjectManifest } from '@pnpm/types';
|
|
4
4
|
import { type ExportedManifest } from './transform/index.js';
|
|
5
5
|
export { type ExportedManifest };
|
|
6
|
+
export type WorkspacePackageLookup = Array<{
|
|
7
|
+
manifest: ProjectManifest;
|
|
8
|
+
rootDir?: string;
|
|
9
|
+
}> | Map<string, unknown> | Record<string, unknown> | ((depName: string) => ProjectManifest | undefined);
|
|
6
10
|
export interface MakePublishManifestOptions {
|
|
7
11
|
catalogs: Catalogs;
|
|
8
12
|
hooks?: Hooks;
|
|
9
13
|
modulesDir?: string;
|
|
10
14
|
skipManifestObfuscation?: boolean;
|
|
11
15
|
embedReadme?: boolean;
|
|
16
|
+
workspacePackages?: WorkspacePackageLookup;
|
|
12
17
|
}
|
|
13
18
|
export declare function createExportableManifest(dir: string, originalManifest: ProjectManifest, opts: MakePublishManifestOptions): Promise<ExportedManifest>;
|
|
14
19
|
export declare function readReadmeFile(projectDir: string): Promise<string | undefined>;
|
|
@@ -16,8 +21,10 @@ export type PublishDependencyConverter = (depName: string, depSpec: string, cont
|
|
|
16
21
|
export interface PublishDependencyConverterContext {
|
|
17
22
|
dir: string;
|
|
18
23
|
modulesDir?: string;
|
|
24
|
+
workspacePackages?: (depName: string) => ProjectManifest | undefined;
|
|
19
25
|
}
|
|
20
26
|
export interface MakePublishDependenciesOpts {
|
|
21
27
|
readonly modulesDir?: string;
|
|
22
28
|
readonly convertDependencyForPublish: PublishDependencyConverter;
|
|
29
|
+
readonly workspacePackages?: (depName: string) => ProjectManifest | undefined;
|
|
23
30
|
}
|
package/lib/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import util from 'node:util';
|
|
4
3
|
import { resolveFromCatalog } from '@pnpm/catalogs.resolver';
|
|
5
|
-
import { PnpmError } from '@pnpm/error';
|
|
4
|
+
import { isError, PnpmError } from '@pnpm/error';
|
|
6
5
|
import { parseJsrSpecifier } from '@pnpm/resolving.jsr-specifier-parser';
|
|
7
6
|
import { tryReadProjectManifest } from '@pnpm/workspace.project-manifest-reader';
|
|
8
7
|
import { WorkspaceSpec } from '@pnpm/workspace.spec-parser';
|
|
@@ -31,11 +30,13 @@ export async function createExportableManifest(dir, originalManifest, opts) {
|
|
|
31
30
|
}
|
|
32
31
|
const catalogResolver = resolveFromCatalog.bind(null, opts.catalogs);
|
|
33
32
|
const replaceCatalogProtocol = resolveCatalogProtocol.bind(null, catalogResolver);
|
|
33
|
+
const getWorkspaceManifest = buildWorkspaceManifestGetter(opts.workspacePackages);
|
|
34
34
|
const convertDependencyForPublish = combineConverters(replaceCatalogProtocol, replaceWorkspaceProtocol, replaceJsrProtocol);
|
|
35
35
|
await Promise.all(['dependencies', 'devDependencies', 'optionalDependencies'].map(async (depsField) => {
|
|
36
36
|
const deps = await makePublishDependencies(dir, originalManifest[depsField], {
|
|
37
37
|
modulesDir: opts?.modulesDir,
|
|
38
38
|
convertDependencyForPublish,
|
|
39
|
+
workspacePackages: getWorkspaceManifest,
|
|
39
40
|
});
|
|
40
41
|
if (deps != null) {
|
|
41
42
|
publishManifest[depsField] = deps;
|
|
@@ -47,6 +48,7 @@ export async function createExportableManifest(dir, originalManifest, opts) {
|
|
|
47
48
|
publishManifest.peerDependencies = await makePublishDependencies(dir, peerDependencies, {
|
|
48
49
|
modulesDir: opts?.modulesDir,
|
|
49
50
|
convertDependencyForPublish: convertPeersForPublish,
|
|
51
|
+
workspacePackages: getWorkspaceManifest,
|
|
50
52
|
});
|
|
51
53
|
}
|
|
52
54
|
overridePublishConfig(publishManifest);
|
|
@@ -81,7 +83,7 @@ export async function readReadmeFile(projectDir) {
|
|
|
81
83
|
}
|
|
82
84
|
catch (err) {
|
|
83
85
|
// ELOOP: the entry is a symlink after all (a concurrent swap) — skip it, as the isFile() check intended.
|
|
84
|
-
if (
|
|
86
|
+
if (isError(err) && 'code' in err && err.code === 'ELOOP')
|
|
85
87
|
return undefined;
|
|
86
88
|
throw err;
|
|
87
89
|
}
|
|
@@ -99,19 +101,91 @@ function combineConverters(...converters) {
|
|
|
99
101
|
return bareSpecifier;
|
|
100
102
|
};
|
|
101
103
|
}
|
|
102
|
-
async function makePublishDependencies(dir, dependencies, { modulesDir, convertDependencyForPublish }) {
|
|
104
|
+
async function makePublishDependencies(dir, dependencies, { modulesDir, convertDependencyForPublish, workspacePackages }) {
|
|
103
105
|
if (dependencies == null)
|
|
104
106
|
return dependencies;
|
|
105
|
-
const publishDependencies = await Promise.all(Object.entries(dependencies).map(async ([depName, depSpec]) => [depName, await convertDependencyForPublish(depName, depSpec, { dir, modulesDir })]));
|
|
107
|
+
const publishDependencies = await Promise.all(Object.entries(dependencies).map(async ([depName, depSpec]) => [depName, await convertDependencyForPublish(depName, depSpec, { dir, modulesDir, workspacePackages })]));
|
|
106
108
|
return Object.fromEntries(publishDependencies);
|
|
107
109
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
function extractManifest(val) {
|
|
111
|
+
if (!val || typeof val !== 'object')
|
|
112
|
+
return undefined;
|
|
113
|
+
if ('manifest' in val && val.manifest && typeof val.manifest === 'object') {
|
|
114
|
+
return val.manifest;
|
|
115
|
+
}
|
|
116
|
+
if ('package' in val && val.package && typeof val.package === 'object' && 'manifest' in val.package && val.package.manifest && typeof val.package.manifest === 'object') {
|
|
117
|
+
return val.package.manifest;
|
|
118
|
+
}
|
|
119
|
+
if ('name' in val && typeof val.name === 'string') {
|
|
120
|
+
return val;
|
|
121
|
+
}
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
function buildWorkspaceManifestGetter(workspacePackages) {
|
|
125
|
+
if (!workspacePackages)
|
|
126
|
+
return undefined;
|
|
127
|
+
if (typeof workspacePackages === 'function') {
|
|
128
|
+
return workspacePackages;
|
|
129
|
+
}
|
|
130
|
+
const byName = new Map();
|
|
131
|
+
const addManifest = (val) => {
|
|
132
|
+
const manifest = extractManifest(val);
|
|
133
|
+
if (!manifest?.name)
|
|
134
|
+
return;
|
|
135
|
+
const existing = byName.get(manifest.name);
|
|
136
|
+
if (!existing || (!existing.version && manifest.version)) {
|
|
137
|
+
byName.set(manifest.name, manifest);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
if (Array.isArray(workspacePackages)) {
|
|
141
|
+
for (const pkg of workspacePackages) {
|
|
142
|
+
addManifest(pkg);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else if (workspacePackages instanceof Map) {
|
|
146
|
+
for (const val of workspacePackages.values()) {
|
|
147
|
+
if (val instanceof Map) {
|
|
148
|
+
for (const subVal of val.values()) {
|
|
149
|
+
addManifest(subVal);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
addManifest(val);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else if (typeof workspacePackages === 'object') {
|
|
158
|
+
for (const val of Object.values(workspacePackages)) {
|
|
159
|
+
addManifest(val);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return (depName) => byName.get(depName);
|
|
163
|
+
}
|
|
164
|
+
async function readAndCheckManifest(depName, dependencyDir, getWorkspaceManifest, targetPkgName) {
|
|
165
|
+
const { manifest: dirManifest } = await tryReadProjectManifest(dependencyDir);
|
|
166
|
+
if (dirManifest?.name && dirManifest?.version) {
|
|
167
|
+
return dirManifest;
|
|
168
|
+
}
|
|
169
|
+
const lookupName = targetPkgName ?? depName;
|
|
170
|
+
const workspaceManifest = getWorkspaceManifest?.(lookupName);
|
|
171
|
+
if (workspaceManifest?.name && workspaceManifest?.version) {
|
|
172
|
+
return workspaceManifest;
|
|
173
|
+
}
|
|
174
|
+
const found = dirManifest?.name || dirManifest?.version
|
|
175
|
+
? dirManifest
|
|
176
|
+
: workspaceManifest?.name || workspaceManifest?.version
|
|
177
|
+
? workspaceManifest
|
|
178
|
+
: dirManifest ?? workspaceManifest;
|
|
179
|
+
if (found?.name && !found.version) {
|
|
180
|
+
throw new PnpmError('CANNOT_RESOLVE_WORKSPACE_PROTOCOL', `Cannot resolve workspace protocol of dependency "${depName}" ` +
|
|
181
|
+
'because its package.json has no "version" field.', { hint: `Add a "version" field to the package.json of "${found.name}".` });
|
|
182
|
+
}
|
|
183
|
+
if (found) {
|
|
111
184
|
throw new PnpmError('CANNOT_RESOLVE_WORKSPACE_PROTOCOL', `Cannot resolve workspace protocol of dependency "${depName}" ` +
|
|
112
|
-
'because
|
|
185
|
+
'because its package.json has no "name" field.');
|
|
113
186
|
}
|
|
114
|
-
|
|
187
|
+
throw new PnpmError('CANNOT_RESOLVE_WORKSPACE_PROTOCOL', `Cannot resolve workspace protocol of dependency "${depName}" ` +
|
|
188
|
+
'because this dependency is not installed. Try running "pnpm install".');
|
|
115
189
|
}
|
|
116
190
|
function resolveCatalogProtocol(catalogResolver, alias, bareSpecifier) {
|
|
117
191
|
const result = catalogResolver({ alias, bareSpecifier });
|
|
@@ -121,7 +195,7 @@ function resolveCatalogProtocol(catalogResolver, alias, bareSpecifier) {
|
|
|
121
195
|
case 'misconfiguration': throw result.error;
|
|
122
196
|
}
|
|
123
197
|
}
|
|
124
|
-
async function replaceWorkspaceProtocol(depName, depSpec, { dir, modulesDir }) {
|
|
198
|
+
async function replaceWorkspaceProtocol(depName, depSpec, { dir, modulesDir, workspacePackages }) {
|
|
125
199
|
if (!depSpec.startsWith('workspace:')) {
|
|
126
200
|
return depSpec;
|
|
127
201
|
}
|
|
@@ -129,7 +203,8 @@ async function replaceWorkspaceProtocol(depName, depSpec, { dir, modulesDir }) {
|
|
|
129
203
|
const versionAliasSpecParts = /^workspace:(?:(.+)@)?([\^~*])?$/.exec(depSpec);
|
|
130
204
|
if (versionAliasSpecParts != null) {
|
|
131
205
|
modulesDir = modulesDir ?? path.join(dir, 'node_modules');
|
|
132
|
-
const
|
|
206
|
+
const targetPkgName = versionAliasSpecParts[1];
|
|
207
|
+
const manifest = await readAndCheckManifest(depName, path.join(modulesDir, depName), workspacePackages, targetPkgName);
|
|
133
208
|
const specifierSuffix = versionAliasSpecParts[2];
|
|
134
209
|
const semverRangeToken = specifierSuffix === '^' || specifierSuffix === '~' ? specifierSuffix : '';
|
|
135
210
|
if (depName !== manifest.name) {
|
|
@@ -138,7 +213,7 @@ async function replaceWorkspaceProtocol(depName, depSpec, { dir, modulesDir }) {
|
|
|
138
213
|
return `${semverRangeToken}${manifest.version}`;
|
|
139
214
|
}
|
|
140
215
|
if (depSpec.startsWith('workspace:./') || depSpec.startsWith('workspace:../')) {
|
|
141
|
-
const manifest = await readAndCheckManifest(depName, path.join(dir, depSpec.slice(10)));
|
|
216
|
+
const manifest = await readAndCheckManifest(depName, path.join(dir, depSpec.slice(10)), workspacePackages);
|
|
142
217
|
if (manifest.name === depName)
|
|
143
218
|
return `${manifest.version}`;
|
|
144
219
|
return `npm:${manifest.name}@${manifest.version}`;
|
|
@@ -149,7 +224,7 @@ async function replaceWorkspaceProtocol(depName, depSpec, { dir, modulesDir }) {
|
|
|
149
224
|
}
|
|
150
225
|
return depSpec;
|
|
151
226
|
}
|
|
152
|
-
async function replaceWorkspaceProtocolPeerDependency(depName, depSpec, { dir, modulesDir }) {
|
|
227
|
+
async function replaceWorkspaceProtocolPeerDependency(depName, depSpec, { dir, modulesDir, workspacePackages }) {
|
|
153
228
|
if (!depSpec.includes('workspace:')) {
|
|
154
229
|
return depSpec;
|
|
155
230
|
}
|
|
@@ -161,7 +236,7 @@ async function replaceWorkspaceProtocolPeerDependency(depName, depSpec, { dir, m
|
|
|
161
236
|
return `npm:${workspaceSpec.alias}@${version}`;
|
|
162
237
|
}
|
|
163
238
|
if (workspaceSpec?.version.startsWith('./') || workspaceSpec?.version.startsWith('../')) {
|
|
164
|
-
return replaceWorkspaceProtocol(depName, depSpec, { dir, modulesDir });
|
|
239
|
+
return replaceWorkspaceProtocol(depName, depSpec, { dir, modulesDir, workspacePackages });
|
|
165
240
|
}
|
|
166
241
|
// Dependencies with bare "*", "^", "~",">=",">","<=", "<", version
|
|
167
242
|
const workspaceSemverRegex = /workspace:([\^~*]|>=|>|<=|<)?((\d+|[xX*])(\.(\d+|[xX*])){0,2})?/;
|
|
@@ -172,7 +247,7 @@ async function replaceWorkspaceProtocolPeerDependency(depName, depSpec, { dir, m
|
|
|
172
247
|
return depSpec.replace('workspace:', '');
|
|
173
248
|
}
|
|
174
249
|
modulesDir = modulesDir ?? path.join(dir, 'node_modules');
|
|
175
|
-
const manifest = await readAndCheckManifest(depName, path.join(modulesDir, depName));
|
|
250
|
+
const manifest = await readAndCheckManifest(depName, path.join(modulesDir, depName), workspacePackages);
|
|
176
251
|
const semverRangeToken = semverRangGroup !== '*' ? semverRangGroup : '';
|
|
177
252
|
return depSpec.replace(workspaceSemverRegex, `${semverRangeToken}${manifest.version}`);
|
|
178
253
|
}
|
|
@@ -30,9 +30,9 @@ const PUBLISH_CONFIG_WHITELIST = new Set([
|
|
|
30
30
|
'typesVersions',
|
|
31
31
|
]);
|
|
32
32
|
export function overridePublishConfig(publishManifest) {
|
|
33
|
-
|
|
34
|
-
if (!publishConfig)
|
|
33
|
+
if (!publishManifest.publishConfig)
|
|
35
34
|
return;
|
|
35
|
+
const publishConfig = { ...publishManifest.publishConfig };
|
|
36
36
|
for (const key in publishConfig) {
|
|
37
37
|
if (!PUBLISH_CONFIG_WHITELIST.has(key))
|
|
38
38
|
continue;
|
|
@@ -43,5 +43,8 @@ export function overridePublishConfig(publishManifest) {
|
|
|
43
43
|
if (isEmpty(publishConfig)) {
|
|
44
44
|
delete publishManifest.publishConfig;
|
|
45
45
|
}
|
|
46
|
+
else {
|
|
47
|
+
publishManifest.publishConfig = publishConfig;
|
|
48
|
+
}
|
|
46
49
|
}
|
|
47
50
|
//# sourceMappingURL=overridePublishConfig.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/releasing.exportable-manifest",
|
|
3
|
-
"version": "1100.3.
|
|
3
|
+
"version": "1100.3.4",
|
|
4
4
|
"description": "Creates an exportable manifest",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -28,22 +28,22 @@
|
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@npm/types": "^2.1.0",
|
|
31
|
-
"@pnpm/bins.resolver": "1100.0.
|
|
32
|
-
"@pnpm/catalogs.resolver": "1100.1.
|
|
33
|
-
"@pnpm/error": "1100.1
|
|
34
|
-
"@pnpm/resolving.jsr-specifier-parser": "1100.0.
|
|
35
|
-
"@pnpm/types": "1102.1.
|
|
36
|
-
"@pnpm/workspace.project-manifest-reader": "1100.
|
|
31
|
+
"@pnpm/bins.resolver": "1100.0.17",
|
|
32
|
+
"@pnpm/catalogs.resolver": "1100.1.1",
|
|
33
|
+
"@pnpm/error": "1100.2.1",
|
|
34
|
+
"@pnpm/resolving.jsr-specifier-parser": "1100.0.9",
|
|
35
|
+
"@pnpm/types": "1102.1.1",
|
|
36
|
+
"@pnpm/workspace.project-manifest-reader": "1100.1.1",
|
|
37
37
|
"@pnpm/workspace.spec-parser": "1100.0.1",
|
|
38
38
|
"ramda": "npm:@pnpm/ramda@0.28.1"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@jest/globals": "30.4.1",
|
|
42
|
-
"@pnpm/catalogs.config": "1100.0.
|
|
42
|
+
"@pnpm/catalogs.config": "1100.0.9",
|
|
43
43
|
"@pnpm/catalogs.types": "1100.0.1",
|
|
44
|
-
"@pnpm/hooks.pnpmfile": "1100.0.
|
|
45
|
-
"@pnpm/prepare": "1100.0.
|
|
46
|
-
"@pnpm/releasing.exportable-manifest": "1100.3.
|
|
44
|
+
"@pnpm/hooks.pnpmfile": "1100.0.34",
|
|
45
|
+
"@pnpm/prepare": "1100.0.33",
|
|
46
|
+
"@pnpm/releasing.exportable-manifest": "1100.3.4",
|
|
47
47
|
"@types/cross-spawn": "^6.0.6",
|
|
48
48
|
"@types/ramda": "0.32.0",
|
|
49
49
|
"cross-spawn": "^7.0.6",
|