@teambit/pnpm 1.0.106 → 1.0.108
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/dist/get-proxy-config.d.ts +1 -1
- package/dist/lynx.d.ts +2 -2
- package/dist/lynx.js +32 -37
- package/dist/lynx.js.map +1 -1
- package/dist/pnpm-prune-modules.js +1 -1
- package/dist/pnpm-prune-modules.js.map +1 -1
- package/dist/pnpm.composition.d.ts +2 -2
- package/dist/pnpm.package-manager.d.ts +1 -1
- package/dist/pnpm.package-manager.js +5 -5
- package/dist/pnpm.package-manager.js.map +1 -1
- package/dist/pnpm.ui.runtime.js +4 -4
- package/dist/pnpm.ui.runtime.js.map +1 -1
- package/dist/{preview-1703505948637.js → preview-1703647408454.js} +2 -2
- package/get-proxy-config.ts +19 -0
- package/get-registries.ts +100 -0
- package/index.ts +4 -0
- package/log-converter.ts +12 -0
- package/lynx.ts +606 -0
- package/package.json +16 -23
- package/pnpm-error-to-bit-error.spec.ts +22 -0
- package/pnpm-error-to-bit-error.ts +44 -0
- package/pnpm-prune-modules.ts +23 -0
- package/pnpm.aspect.ts +9 -0
- package/pnpm.main.runtime.ts +26 -0
- package/pnpm.package-manager.ts +326 -0
- package/read-config.ts +16 -0
- package/tsconfig.json +16 -21
- package/types/asset.d.ts +15 -3
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PnpmError } from '@pnpm/error';
|
|
2
|
+
import { pnpmErrorToBitError } from './pnpm-error-to-bit-error';
|
|
3
|
+
|
|
4
|
+
test('the hint from the fetch error is used', () => {
|
|
5
|
+
const bitError = pnpmErrorToBitError(
|
|
6
|
+
new PnpmError('FETCH_404', 'GET https://node-registry.bit.cloud/dsffsdf: Not Found - 404', {
|
|
7
|
+
hint: `dsffsdf is not in the npm registry, or you have no permission to fetch it.
|
|
8
|
+
|
|
9
|
+
An authorization header was used: Bearer df96[hidden]`,
|
|
10
|
+
})
|
|
11
|
+
);
|
|
12
|
+
expect(bitError.report()).toEqual(`GET https://node-registry.bit.cloud/dsffsdf: Not Found - 404
|
|
13
|
+
|
|
14
|
+
dsffsdf is not in the npm registry, or you have no permission to fetch it.
|
|
15
|
+
|
|
16
|
+
An authorization header was used: Bearer df96[hidden]`);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('a regular error object is reported', () => {
|
|
20
|
+
const bitError = pnpmErrorToBitError(new Error('some error') as any);
|
|
21
|
+
expect(bitError.report()).toEqual('some error');
|
|
22
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { PnpmError } from '@pnpm/error';
|
|
2
|
+
import { BitError } from '@teambit/bit-error';
|
|
3
|
+
|
|
4
|
+
export class BitErrorWithRichMessage extends BitError {
|
|
5
|
+
private richMessage: string;
|
|
6
|
+
constructor(message: string, richMessage: string) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.richMessage = richMessage;
|
|
9
|
+
}
|
|
10
|
+
public report() {
|
|
11
|
+
return this.richMessage;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function pnpmErrorToBitError(err: PnpmError): BitError {
|
|
16
|
+
const msg = renderErrorMessage(err);
|
|
17
|
+
const newErr = new BitErrorWithRichMessage(msg, msg);
|
|
18
|
+
newErr.cause = err;
|
|
19
|
+
return newErr;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function renderErrorMessage(err: PnpmError): string {
|
|
23
|
+
let output = err.message;
|
|
24
|
+
if (err.hint) {
|
|
25
|
+
output += `\n\n${err.hint}`;
|
|
26
|
+
}
|
|
27
|
+
if (err.pkgsStack != null) {
|
|
28
|
+
if (err.pkgsStack.length > 0) {
|
|
29
|
+
output += `\n\n${formatPkgsStack(err.pkgsStack)}`;
|
|
30
|
+
} else if (err.prefix) {
|
|
31
|
+
output += `\n\nThis error happened while installing a direct dependency of ${err.prefix as string}`;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return output;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function formatPkgsStack(pkgsStack: Array<{ id: string; name: string; version: string }>) {
|
|
38
|
+
return `This error happened while installing the dependencies of \
|
|
39
|
+
${pkgsStack[0].name}@${pkgsStack[0].version}\
|
|
40
|
+
${pkgsStack
|
|
41
|
+
.slice(1)
|
|
42
|
+
.map(({ name, version }) => `\n at ${name}@${version}`)
|
|
43
|
+
.join('')}`;
|
|
44
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { difference } from 'lodash';
|
|
4
|
+
import { readCurrentLockfile } from '@pnpm/lockfile-file';
|
|
5
|
+
import { depPathToFilename } from '@pnpm/dependency-path';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Reads the private lockfile at node_modules/.pnpm/lock.yaml
|
|
9
|
+
* and removes any directories from node_modules/.pnpm that are not listed in the lockfile.
|
|
10
|
+
*/
|
|
11
|
+
export async function pnpmPruneModules(rootDir: string): Promise<void> {
|
|
12
|
+
const virtualStoreDir = path.join(rootDir, 'node_modules/.pnpm');
|
|
13
|
+
const pkgDirs = await readPackageDirsFromVirtualStore(virtualStoreDir);
|
|
14
|
+
if (pkgDirs.length === 0) return;
|
|
15
|
+
const lockfile = await readCurrentLockfile(virtualStoreDir, { ignoreIncompatible: false });
|
|
16
|
+
const dirsShouldBePresent = Object.keys(lockfile?.packages ?? {}).map(depPathToFilename);
|
|
17
|
+
await Promise.all(difference(pkgDirs, dirsShouldBePresent).map((dir) => fs.remove(path.join(virtualStoreDir, dir))));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function readPackageDirsFromVirtualStore(virtualStoreDir: string): Promise<string[]> {
|
|
21
|
+
const allDirs = await fs.readdir(virtualStoreDir);
|
|
22
|
+
return allDirs.filter((dir) => dir !== 'lock.yaml' && dir !== 'node_modules');
|
|
23
|
+
}
|
package/pnpm.aspect.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { MainRuntime } from '@teambit/cli';
|
|
2
|
+
import { DependencyResolverAspect, DependencyResolverMain } from '@teambit/dependency-resolver';
|
|
3
|
+
import { LoggerAspect, LoggerMain } from '@teambit/logger';
|
|
4
|
+
|
|
5
|
+
import { PnpmAspect } from './pnpm.aspect';
|
|
6
|
+
import { PnpmPackageManager } from './pnpm.package-manager';
|
|
7
|
+
|
|
8
|
+
export class PnpmMain {
|
|
9
|
+
static runtime = MainRuntime;
|
|
10
|
+
static dependencies = [DependencyResolverAspect, LoggerAspect];
|
|
11
|
+
|
|
12
|
+
static async provider([depResolver, loggerExt]: [DependencyResolverMain, LoggerMain]) {
|
|
13
|
+
const logger = loggerExt.createLogger(PnpmAspect.id);
|
|
14
|
+
const packageManager = new PnpmPackageManager(depResolver, logger);
|
|
15
|
+
depResolver.registerPackageManager(packageManager);
|
|
16
|
+
return new PnpmMain(packageManager);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
constructor(private packageManager: PnpmPackageManager) {}
|
|
20
|
+
|
|
21
|
+
getPackageManager(): PnpmPackageManager {
|
|
22
|
+
return this.packageManager;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
PnpmAspect.addRuntime(PnpmMain);
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DependencyResolverMain,
|
|
3
|
+
extendWithComponentsFromDir,
|
|
4
|
+
InstallationContext,
|
|
5
|
+
PackageManager,
|
|
6
|
+
PackageManagerInstallOptions,
|
|
7
|
+
PackageManagerResolveRemoteVersionOptions,
|
|
8
|
+
ResolvedPackageVersion,
|
|
9
|
+
Registries,
|
|
10
|
+
Registry,
|
|
11
|
+
BIT_CLOUD_REGISTRY,
|
|
12
|
+
PackageManagerProxyConfig,
|
|
13
|
+
PackageManagerNetworkConfig,
|
|
14
|
+
} from '@teambit/dependency-resolver';
|
|
15
|
+
import { Logger } from '@teambit/logger';
|
|
16
|
+
import fs from 'fs';
|
|
17
|
+
import { memoize, omit } from 'lodash';
|
|
18
|
+
import { PeerDependencyIssuesByProjects } from '@pnpm/core';
|
|
19
|
+
import { readModulesManifest } from '@pnpm/modules-yaml';
|
|
20
|
+
import {
|
|
21
|
+
buildDependenciesHierarchy,
|
|
22
|
+
DependenciesHierarchy,
|
|
23
|
+
createPackagesSearcher,
|
|
24
|
+
PackageNode,
|
|
25
|
+
} from '@pnpm/reviewing.dependencies-hierarchy';
|
|
26
|
+
import { renderTree } from '@pnpm/list';
|
|
27
|
+
import { readWantedLockfile } from '@pnpm/lockfile-file';
|
|
28
|
+
import { ProjectManifest } from '@pnpm/types';
|
|
29
|
+
import { join } from 'path';
|
|
30
|
+
import { readConfig } from './read-config';
|
|
31
|
+
import { pnpmPruneModules } from './pnpm-prune-modules';
|
|
32
|
+
import type { RebuildFn } from './lynx';
|
|
33
|
+
|
|
34
|
+
export class PnpmPackageManager implements PackageManager {
|
|
35
|
+
readonly name = 'pnpm';
|
|
36
|
+
|
|
37
|
+
private _readConfig = async (dir?: string) => {
|
|
38
|
+
const { config, warnings } = await readConfig(dir);
|
|
39
|
+
if (config?.fetchRetries && config?.fetchRetries < 5) {
|
|
40
|
+
config.fetchRetries = 5;
|
|
41
|
+
return { config, warnings };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return { config, warnings };
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
public readConfig = memoize(this._readConfig);
|
|
48
|
+
|
|
49
|
+
constructor(private depResolver: DependencyResolverMain, private logger: Logger) {}
|
|
50
|
+
|
|
51
|
+
async install(
|
|
52
|
+
{ rootDir, manifests }: InstallationContext,
|
|
53
|
+
installOptions: PackageManagerInstallOptions = {}
|
|
54
|
+
): Promise<{ dependenciesChanged: boolean; rebuild: RebuildFn; storeDir: string }> {
|
|
55
|
+
// require it dynamically for performance purpose. the pnpm package require many files - do not move to static import
|
|
56
|
+
// eslint-disable-next-line global-require, import/no-dynamic-require
|
|
57
|
+
const { install } = require('./lynx');
|
|
58
|
+
|
|
59
|
+
this.logger.debug(`running installation in root dir ${rootDir}`);
|
|
60
|
+
this.logger.debug('components manifests for installation', manifests);
|
|
61
|
+
if (!installOptions.hidePackageManagerOutput) {
|
|
62
|
+
// this.logger.setStatusLine('installing dependencies using pnpm');
|
|
63
|
+
// turn off the logger because it interrupts the pnpm output
|
|
64
|
+
// this.logger.console('-------------------------PNPM OUTPUT-------------------------');
|
|
65
|
+
this.logger.off();
|
|
66
|
+
}
|
|
67
|
+
const registries = await this.depResolver.getRegistries();
|
|
68
|
+
const proxyConfig = await this.depResolver.getProxyConfig();
|
|
69
|
+
const networkConfig = await this.depResolver.getNetworkConfig();
|
|
70
|
+
const { config } = await this.readConfig(installOptions.packageManagerConfigRootDir);
|
|
71
|
+
if (!installOptions.useNesting) {
|
|
72
|
+
manifests = await extendWithComponentsFromDir(rootDir, manifests);
|
|
73
|
+
}
|
|
74
|
+
if (installOptions.nmSelfReferences) {
|
|
75
|
+
Object.values(manifests).forEach((manifest) => {
|
|
76
|
+
if (manifest.name) {
|
|
77
|
+
manifest.devDependencies = {
|
|
78
|
+
[manifest.name]: 'link:.',
|
|
79
|
+
...manifest.devDependencies,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
const { dependenciesChanged, rebuild, storeDir } = await install(
|
|
85
|
+
rootDir,
|
|
86
|
+
manifests,
|
|
87
|
+
config.storeDir,
|
|
88
|
+
config.cacheDir,
|
|
89
|
+
registries,
|
|
90
|
+
proxyConfig,
|
|
91
|
+
networkConfig,
|
|
92
|
+
{
|
|
93
|
+
engineStrict: installOptions.engineStrict ?? config.engineStrict,
|
|
94
|
+
excludeLinksFromLockfile: installOptions.excludeLinksFromLockfile,
|
|
95
|
+
lockfileOnly: installOptions.lockfileOnly,
|
|
96
|
+
neverBuiltDependencies: installOptions.neverBuiltDependencies,
|
|
97
|
+
nodeLinker: installOptions.nodeLinker,
|
|
98
|
+
nodeVersion: installOptions.nodeVersion ?? config.nodeVersion,
|
|
99
|
+
includeOptionalDeps: installOptions.includeOptionalDeps,
|
|
100
|
+
ignorePackageManifest: installOptions.ignorePackageManifest,
|
|
101
|
+
dedupeInjectedDeps: installOptions.dedupeInjectedDeps,
|
|
102
|
+
dryRun: installOptions.dryRun,
|
|
103
|
+
overrides: installOptions.overrides,
|
|
104
|
+
hoistPattern: config.hoistPattern,
|
|
105
|
+
publicHoistPattern: config.shamefullyHoist
|
|
106
|
+
? ['*']
|
|
107
|
+
: ['@eslint/plugin-*', '*eslint-plugin*', '@prettier/plugin-*', '*prettier-plugin-*'],
|
|
108
|
+
packageImportMethod: installOptions.packageImportMethod ?? config.packageImportMethod,
|
|
109
|
+
preferOffline: installOptions.preferOffline,
|
|
110
|
+
rootComponents: installOptions.rootComponents,
|
|
111
|
+
rootComponentsForCapsules: installOptions.rootComponentsForCapsules,
|
|
112
|
+
peerDependencyRules: installOptions.peerDependencyRules,
|
|
113
|
+
sideEffectsCacheRead: installOptions.sideEffectsCache ?? true,
|
|
114
|
+
sideEffectsCacheWrite: installOptions.sideEffectsCache ?? true,
|
|
115
|
+
pnpmHomeDir: config.pnpmHomeDir,
|
|
116
|
+
updateAll: installOptions.updateAll,
|
|
117
|
+
hidePackageManagerOutput: installOptions.hidePackageManagerOutput,
|
|
118
|
+
reportOptions: {
|
|
119
|
+
appendOnly: installOptions.optimizeReportForNonTerminal,
|
|
120
|
+
throttleProgress: installOptions.throttleProgress,
|
|
121
|
+
hideProgressPrefix: installOptions.hideProgressPrefix,
|
|
122
|
+
hideLifecycleOutput: installOptions.hideLifecycleOutput,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
this.logger
|
|
126
|
+
);
|
|
127
|
+
if (!installOptions.hidePackageManagerOutput) {
|
|
128
|
+
this.logger.on();
|
|
129
|
+
// Make a divider row to improve output
|
|
130
|
+
// this.logger.console('-------------------------END PNPM OUTPUT-------------------------');
|
|
131
|
+
// this.logger.consoleSuccess('installing dependencies using pnpm');
|
|
132
|
+
}
|
|
133
|
+
return { dependenciesChanged, rebuild, storeDir };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async getPeerDependencyIssues(
|
|
137
|
+
rootDir: string,
|
|
138
|
+
manifests: Record<string, ProjectManifest>,
|
|
139
|
+
installOptions: PackageManagerInstallOptions = {}
|
|
140
|
+
): Promise<PeerDependencyIssuesByProjects> {
|
|
141
|
+
const proxyConfig = await this.depResolver.getProxyConfig();
|
|
142
|
+
const networkConfig = await this.depResolver.getNetworkConfig();
|
|
143
|
+
const registries = await this.depResolver.getRegistries();
|
|
144
|
+
// require it dynamically for performance purpose. the pnpm package require many files - do not move to static import
|
|
145
|
+
// eslint-disable-next-line global-require, import/no-dynamic-require
|
|
146
|
+
const lynx = require('./lynx');
|
|
147
|
+
const { config } = await this.readConfig(installOptions.packageManagerConfigRootDir);
|
|
148
|
+
return lynx.getPeerDependencyIssues(manifests, {
|
|
149
|
+
storeDir: config.storeDir,
|
|
150
|
+
cacheDir: config.cacheDir,
|
|
151
|
+
proxyConfig,
|
|
152
|
+
registries,
|
|
153
|
+
rootDir,
|
|
154
|
+
networkConfig,
|
|
155
|
+
overrides: installOptions.overrides,
|
|
156
|
+
packageImportMethod: installOptions.packageImportMethod ?? config.packageImportMethod,
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async resolveRemoteVersion(
|
|
161
|
+
packageName: string,
|
|
162
|
+
options: PackageManagerResolveRemoteVersionOptions
|
|
163
|
+
): Promise<ResolvedPackageVersion> {
|
|
164
|
+
// require it dynamically for performance purpose. the pnpm package require many files - do not move to static import
|
|
165
|
+
// eslint-disable-next-line global-require, import/no-dynamic-require
|
|
166
|
+
const { resolveRemoteVersion } = require('./lynx');
|
|
167
|
+
const registries = await this.depResolver.getRegistries();
|
|
168
|
+
const proxyConfig = await this.depResolver.getProxyConfig();
|
|
169
|
+
const networkConfig = await this.depResolver.getNetworkConfig();
|
|
170
|
+
const { config } = await this.readConfig(options.packageManagerConfigRootDir);
|
|
171
|
+
return resolveRemoteVersion(packageName, options.rootDir, config.cacheDir, registries, proxyConfig, networkConfig);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async getProxyConfig?(): Promise<PackageManagerProxyConfig> {
|
|
175
|
+
// eslint-disable-next-line global-require, import/no-dynamic-require
|
|
176
|
+
const { getProxyConfig } = require('./get-proxy-config');
|
|
177
|
+
const { config } = await this.readConfig();
|
|
178
|
+
return getProxyConfig(config);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async getNetworkConfig?(): Promise<PackageManagerNetworkConfig> {
|
|
182
|
+
const { config } = await this.readConfig();
|
|
183
|
+
// We need to use config.rawConfig as it will only contain the settings defined by the user.
|
|
184
|
+
// config contains default values of the settings when they are not defined by the user.
|
|
185
|
+
return {
|
|
186
|
+
maxSockets: config.rawConfig['max-sockets'],
|
|
187
|
+
networkConcurrency: config.rawConfig['network-concurrency'],
|
|
188
|
+
fetchRetries: config.rawConfig['fetch-retries'],
|
|
189
|
+
fetchTimeout: config.rawConfig['fetch-timeout'],
|
|
190
|
+
fetchRetryMaxtimeout: config.rawConfig['fetch-retry-maxtimeout'],
|
|
191
|
+
fetchRetryMintimeout: config.rawConfig['fetch-retry-mintimeout'],
|
|
192
|
+
strictSSL: config.rawConfig['strict-ssl'],
|
|
193
|
+
// These settings don't have default value, so it is safe to read them from config
|
|
194
|
+
// ca is automatically populated from the content of the file specified by cafile.
|
|
195
|
+
ca: config.ca,
|
|
196
|
+
cert: config.cert,
|
|
197
|
+
key: config.key,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async getRegistries(): Promise<Registries> {
|
|
202
|
+
// eslint-disable-next-line global-require, import/no-dynamic-require
|
|
203
|
+
const { getRegistries } = require('./get-registries');
|
|
204
|
+
const { config } = await this.readConfig();
|
|
205
|
+
const pnpmRegistry = await getRegistries(config);
|
|
206
|
+
const defaultRegistry = new Registry(
|
|
207
|
+
pnpmRegistry.default.uri,
|
|
208
|
+
pnpmRegistry.default.alwaysAuth,
|
|
209
|
+
pnpmRegistry.default.authHeaderValue,
|
|
210
|
+
pnpmRegistry.default.originalAuthType,
|
|
211
|
+
pnpmRegistry.default.originalAuthValue
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
const pnpmScoped = omit(pnpmRegistry, ['default']);
|
|
215
|
+
const scopesRegistries: Record<string, Registry> = Object.keys(pnpmScoped).reduce((acc, scopedRegName) => {
|
|
216
|
+
const scopedReg = pnpmScoped[scopedRegName];
|
|
217
|
+
const name = scopedRegName.replace('@', '');
|
|
218
|
+
acc[name] = new Registry(
|
|
219
|
+
scopedReg.uri,
|
|
220
|
+
scopedReg.alwaysAuth,
|
|
221
|
+
scopedReg.authHeaderValue,
|
|
222
|
+
scopedReg.originalAuthType,
|
|
223
|
+
scopedReg.originalAuthValue
|
|
224
|
+
);
|
|
225
|
+
return acc;
|
|
226
|
+
}, {});
|
|
227
|
+
|
|
228
|
+
// Add bit registry server if not exist
|
|
229
|
+
if (!scopesRegistries.bit) {
|
|
230
|
+
scopesRegistries.bit = new Registry(BIT_CLOUD_REGISTRY, true);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return new Registries(defaultRegistry, scopesRegistries);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
async getInjectedDirs(rootDir: string, componentDir: string, packageName: string): Promise<string[]> {
|
|
237
|
+
const modulesState = await this._readModulesManifest(rootDir);
|
|
238
|
+
if (modulesState?.injectedDeps == null) return [];
|
|
239
|
+
return modulesState.injectedDeps[`node_modules/${packageName}`] ?? modulesState.injectedDeps[componentDir] ?? [];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
_readModulesManifest(lockfileDir: string) {
|
|
243
|
+
return readModulesManifest(join(lockfileDir, 'node_modules'));
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
getWorkspaceDepsOfBitRoots(manifests: ProjectManifest[]): Record<string, string> {
|
|
247
|
+
return Object.fromEntries(manifests.map((manifest) => [manifest.name, 'workspace:*']));
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
async pruneModules(rootDir: string): Promise<void> {
|
|
251
|
+
return pnpmPruneModules(rootDir);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async findUsages(depName: string, opts: { lockfileDir: string; depth?: number }): Promise<string> {
|
|
255
|
+
const search = createPackagesSearcher([depName]);
|
|
256
|
+
const lockfile = await readWantedLockfile(opts.lockfileDir, { ignoreIncompatible: false });
|
|
257
|
+
const projectPaths = Object.keys(lockfile?.importers ?? {})
|
|
258
|
+
.filter((id) => !id.startsWith('node_modules/.bit_roots'))
|
|
259
|
+
.map((id) => join(opts.lockfileDir, id));
|
|
260
|
+
const cache = new Map();
|
|
261
|
+
const modulesManifest = await this._readModulesManifest(opts.lockfileDir);
|
|
262
|
+
const isHoisted = modulesManifest?.nodeLinker === 'hoisted';
|
|
263
|
+
const getPkgLocation: GetPkgLocation = isHoisted
|
|
264
|
+
? ({ name }) => join(opts.lockfileDir, 'node_modules', name)
|
|
265
|
+
: ({ path }) => path;
|
|
266
|
+
const results = Object.entries(
|
|
267
|
+
await buildDependenciesHierarchy(projectPaths, {
|
|
268
|
+
depth: opts.depth ?? Infinity,
|
|
269
|
+
include: {
|
|
270
|
+
dependencies: true,
|
|
271
|
+
devDependencies: true,
|
|
272
|
+
optionalDependencies: true,
|
|
273
|
+
},
|
|
274
|
+
lockfileDir: opts.lockfileDir,
|
|
275
|
+
registries: {
|
|
276
|
+
default: 'https://registry.npmjs.org',
|
|
277
|
+
},
|
|
278
|
+
search,
|
|
279
|
+
})
|
|
280
|
+
).map(([projectPath, builtDependenciesHierarchy]) => {
|
|
281
|
+
pkgNamesToComponentIds(builtDependenciesHierarchy, { cache, getPkgLocation });
|
|
282
|
+
return {
|
|
283
|
+
path: projectPath,
|
|
284
|
+
...builtDependenciesHierarchy,
|
|
285
|
+
};
|
|
286
|
+
});
|
|
287
|
+
return renderTree(results, {
|
|
288
|
+
alwaysPrintRootPackage: false,
|
|
289
|
+
depth: Infinity,
|
|
290
|
+
search: true,
|
|
291
|
+
long: false,
|
|
292
|
+
showExtraneous: false,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
type GetPkgLocation = (pkgNode: PackageNode) => string;
|
|
298
|
+
|
|
299
|
+
function pkgNamesToComponentIds(
|
|
300
|
+
deps: DependenciesHierarchy,
|
|
301
|
+
{ cache, getPkgLocation }: { cache: Map<string, string>; getPkgLocation: GetPkgLocation }
|
|
302
|
+
) {
|
|
303
|
+
for (const depType of ['dependencies', 'devDependencies', 'optionalDependencies']) {
|
|
304
|
+
if (deps[depType]) {
|
|
305
|
+
for (const dep of deps[depType]) {
|
|
306
|
+
if (!cache.has(dep.name)) {
|
|
307
|
+
const pkgJson = tryReadPackageJson(getPkgLocation(dep));
|
|
308
|
+
cache.set(
|
|
309
|
+
dep.name,
|
|
310
|
+
pkgJson?.componentId ? `${pkgJson.componentId.scope}/${pkgJson.componentId.name}` : dep.name
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
dep.name = cache.get(dep.name);
|
|
314
|
+
pkgNamesToComponentIds(dep, { cache, getPkgLocation });
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function tryReadPackageJson(pkgDir: string) {
|
|
321
|
+
try {
|
|
322
|
+
return JSON.parse(fs.readFileSync(join(pkgDir, 'package.json'), 'utf8'));
|
|
323
|
+
} catch (err) {
|
|
324
|
+
return undefined;
|
|
325
|
+
}
|
|
326
|
+
}
|
package/read-config.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { getConfig } from '@pnpm/config';
|
|
2
|
+
|
|
3
|
+
export async function readConfig(dir?: string) {
|
|
4
|
+
const pnpmConfig = await getConfig({
|
|
5
|
+
cliOptions: {
|
|
6
|
+
dir,
|
|
7
|
+
// 'global': true,
|
|
8
|
+
// 'link-workspace-packages': true,
|
|
9
|
+
},
|
|
10
|
+
packageManager: {
|
|
11
|
+
name: 'pnpm',
|
|
12
|
+
version: '1.0.0',
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
return pnpmConfig;
|
|
16
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -1,38 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"lib": [
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"DOM.Iterable",
|
|
8
|
-
"ScriptHost"
|
|
4
|
+
"esnext",
|
|
5
|
+
"dom",
|
|
6
|
+
"dom.Iterable"
|
|
9
7
|
],
|
|
10
|
-
"target": "
|
|
11
|
-
"module": "
|
|
12
|
-
"jsx": "react",
|
|
13
|
-
"allowJs": true,
|
|
14
|
-
"composite": true,
|
|
8
|
+
"target": "es2020",
|
|
9
|
+
"module": "es2020",
|
|
10
|
+
"jsx": "react-jsx",
|
|
15
11
|
"declaration": true,
|
|
16
12
|
"sourceMap": true,
|
|
17
|
-
"skipLibCheck": true,
|
|
18
13
|
"experimentalDecorators": true,
|
|
19
|
-
"
|
|
14
|
+
"skipLibCheck": true,
|
|
20
15
|
"moduleResolution": "node",
|
|
21
16
|
"esModuleInterop": true,
|
|
22
|
-
"rootDir": ".",
|
|
23
17
|
"resolveJsonModule": true,
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"strictPropertyInitialization": false,
|
|
28
|
-
"strict": true,
|
|
29
|
-
"noImplicitAny": false,
|
|
30
|
-
"preserveConstEnums": true
|
|
18
|
+
"allowJs": true,
|
|
19
|
+
"outDir": "dist",
|
|
20
|
+
"emitDeclarationOnly": true
|
|
31
21
|
},
|
|
32
22
|
"exclude": [
|
|
23
|
+
"artifacts",
|
|
24
|
+
"public",
|
|
33
25
|
"dist",
|
|
26
|
+
"node_modules",
|
|
27
|
+
"package.json",
|
|
34
28
|
"esm.mjs",
|
|
35
|
-
"
|
|
29
|
+
"**/*.cjs",
|
|
30
|
+
"./dist"
|
|
36
31
|
],
|
|
37
32
|
"include": [
|
|
38
33
|
"**/*",
|
package/types/asset.d.ts
CHANGED
|
@@ -5,12 +5,12 @@ declare module '*.png' {
|
|
|
5
5
|
declare module '*.svg' {
|
|
6
6
|
import type { FunctionComponent, SVGProps } from 'react';
|
|
7
7
|
|
|
8
|
-
export const ReactComponent: FunctionComponent<
|
|
8
|
+
export const ReactComponent: FunctionComponent<
|
|
9
|
+
SVGProps<SVGSVGElement> & { title?: string }
|
|
10
|
+
>;
|
|
9
11
|
const src: string;
|
|
10
12
|
export default src;
|
|
11
13
|
}
|
|
12
|
-
|
|
13
|
-
// @TODO Gilad
|
|
14
14
|
declare module '*.jpg' {
|
|
15
15
|
const value: any;
|
|
16
16
|
export = value;
|
|
@@ -27,3 +27,15 @@ declare module '*.bmp' {
|
|
|
27
27
|
const value: any;
|
|
28
28
|
export = value;
|
|
29
29
|
}
|
|
30
|
+
declare module '*.otf' {
|
|
31
|
+
const value: any;
|
|
32
|
+
export = value;
|
|
33
|
+
}
|
|
34
|
+
declare module '*.woff' {
|
|
35
|
+
const value: any;
|
|
36
|
+
export = value;
|
|
37
|
+
}
|
|
38
|
+
declare module '*.woff2' {
|
|
39
|
+
const value: any;
|
|
40
|
+
export = value;
|
|
41
|
+
}
|