@atlaspack/package-manager 2.14.31 → 2.14.32
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 +12 -0
- package/dist/JSONParseStream.js +37 -0
- package/dist/MockPackageInstaller.js +54 -0
- package/dist/NodePackageManager.js +559 -0
- package/dist/Npm.js +73 -0
- package/dist/Pnpm.js +140 -0
- package/dist/Yarn.js +124 -0
- package/dist/getCurrentPackageManager.js +17 -0
- package/dist/index.js +24 -0
- package/dist/installPackage.js +197 -0
- package/dist/nodejsConditions.js +39 -0
- package/dist/promiseFromProcess.js +16 -0
- package/dist/utils.js +76 -0
- package/dist/validateModuleSpecifier.js +11 -0
- package/package.json +7 -8
- package/test/NodePackageManager.test.ts +3 -3
- package/tsconfig.json +31 -2
- package/tsconfig.tsbuildinfo +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @atlaspack/package-manager
|
|
2
2
|
|
|
3
|
+
## 2.14.32
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`1180103`](https://github.com/atlassian-labs/atlaspack/commit/118010351ed444f8178988afb3f77807154dd933)]:
|
|
8
|
+
- @atlaspack/utils@3.0.0
|
|
9
|
+
- @atlaspack/fs@2.15.27
|
|
10
|
+
- @atlaspack/node-resolver-core@3.7.3
|
|
11
|
+
- @atlaspack/logger@2.14.24
|
|
12
|
+
- @atlaspack/workers@2.14.32
|
|
13
|
+
- @atlaspack/types@2.15.22
|
|
14
|
+
|
|
3
15
|
## 2.14.31
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const logger_1 = __importDefault(require("@atlaspack/logger"));
|
|
7
|
+
const stream_1 = require("stream");
|
|
8
|
+
// Transforms chunks of json strings to parsed objects.
|
|
9
|
+
// Pair with split2 to parse stream of newline-delimited text.
|
|
10
|
+
class JSONParseStream extends stream_1.Transform {
|
|
11
|
+
constructor(options) {
|
|
12
|
+
// @ts-expect-error TS2698
|
|
13
|
+
super({ ...options, objectMode: true });
|
|
14
|
+
}
|
|
15
|
+
_transform(chunk, encoding, callback) {
|
|
16
|
+
try {
|
|
17
|
+
let parsed;
|
|
18
|
+
try {
|
|
19
|
+
parsed = JSON.parse(chunk.toString());
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
// Be permissive and ignoreJSON parse errors in case there was
|
|
23
|
+
// a non-JSON line in the package manager's stdout.
|
|
24
|
+
logger_1.default.verbose({
|
|
25
|
+
message: 'Ignored invalid JSON message: ' + chunk.toString(),
|
|
26
|
+
origin: '@atlaspack/package-manager',
|
|
27
|
+
});
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
callback(null, parsed);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
callback(err);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.default = JSONParseStream;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.MockPackageInstaller = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const build_cache_1 = require("@atlaspack/build-cache");
|
|
9
|
+
const fs_1 = require("@atlaspack/fs");
|
|
10
|
+
const package_json_1 = __importDefault(require("../package.json"));
|
|
11
|
+
const utils_1 = require("./utils");
|
|
12
|
+
// This PackageInstaller implementation simply copies files from one filesystem to another.
|
|
13
|
+
// Mostly useful for testing purposes.
|
|
14
|
+
class MockPackageInstaller {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.packages = new Map();
|
|
17
|
+
}
|
|
18
|
+
register(packageName, fs, packagePath) {
|
|
19
|
+
this.packages.set(packageName, { fs, packagePath });
|
|
20
|
+
}
|
|
21
|
+
async install({ modules, fs, cwd, packagePath, saveDev = true, }) {
|
|
22
|
+
if (packagePath == null) {
|
|
23
|
+
packagePath = path_1.default.join(cwd, 'package.json');
|
|
24
|
+
await fs.writeFile(packagePath, '{}');
|
|
25
|
+
}
|
|
26
|
+
let pkg = JSON.parse(await fs.readFile(packagePath, 'utf8'));
|
|
27
|
+
let key = saveDev ? 'devDependencies' : 'dependencies';
|
|
28
|
+
if (!pkg[key]) {
|
|
29
|
+
pkg[key] = {};
|
|
30
|
+
}
|
|
31
|
+
for (let module of modules) {
|
|
32
|
+
pkg[key][module.name] =
|
|
33
|
+
'^' + (await this.installPackage(module, fs, packagePath));
|
|
34
|
+
}
|
|
35
|
+
await fs.writeFile(packagePath, JSON.stringify(pkg));
|
|
36
|
+
}
|
|
37
|
+
async installPackage(moduleRequest, fs, packagePath) {
|
|
38
|
+
let pkg = this.packages.get(moduleRequest.name);
|
|
39
|
+
if (!pkg) {
|
|
40
|
+
throw new Error('Unknown package ' + moduleRequest.name);
|
|
41
|
+
}
|
|
42
|
+
let dest = path_1.default.join(path_1.default.dirname(packagePath), 'node_modules', moduleRequest.name);
|
|
43
|
+
await (0, fs_1.ncp)(pkg.fs, pkg.packagePath, fs, dest);
|
|
44
|
+
let packageJSON = JSON.parse(await fs.readFile(path_1.default.join(dest, 'package.json'), 'utf8'));
|
|
45
|
+
if (packageJSON.dependencies != null) {
|
|
46
|
+
for (let dep of (0, utils_1.moduleRequestsFromDependencyMap)(packageJSON.dependencies)) {
|
|
47
|
+
await this.installPackage(dep, fs, packagePath);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return packageJSON.version;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
exports.MockPackageInstaller = MockPackageInstaller;
|
|
54
|
+
(0, build_cache_1.registerSerializableClass)(`${package_json_1.default.version}:MockPackageInstaller`, MockPackageInstaller);
|
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.NodePackageManager = void 0;
|
|
40
|
+
const build_cache_1 = require("@atlaspack/build-cache");
|
|
41
|
+
const diagnostic_1 = __importStar(require("@atlaspack/diagnostic"));
|
|
42
|
+
const fs_1 = require("@atlaspack/fs");
|
|
43
|
+
const fs_2 = __importDefault(require("fs"));
|
|
44
|
+
const module_1 = __importDefault(require("module"));
|
|
45
|
+
const path_1 = __importDefault(require("path"));
|
|
46
|
+
const semver_1 = __importDefault(require("semver"));
|
|
47
|
+
const logger_1 = __importDefault(require("@atlaspack/logger"));
|
|
48
|
+
const nullthrows_1 = __importDefault(require("nullthrows"));
|
|
49
|
+
const utils_1 = require("@atlaspack/utils");
|
|
50
|
+
const utils_2 = require("./utils");
|
|
51
|
+
const installPackage_1 = require("./installPackage");
|
|
52
|
+
const package_json_1 = __importDefault(require("../package.json"));
|
|
53
|
+
const nodejsConditions_1 = require("./nodejsConditions");
|
|
54
|
+
const node_resolver_core_1 = require("@atlaspack/node-resolver-core");
|
|
55
|
+
const url_1 = require("url");
|
|
56
|
+
const core_1 = require("@swc/core");
|
|
57
|
+
// Package.json fields. Must match package_json.rs.
|
|
58
|
+
const MAIN = 1 << 0;
|
|
59
|
+
const SOURCE = 1 << 2;
|
|
60
|
+
let ENTRIES = MAIN;
|
|
61
|
+
if (process.env.ATLASPACK_REGISTER_USE_SRC === 'true') {
|
|
62
|
+
ENTRIES |= SOURCE;
|
|
63
|
+
}
|
|
64
|
+
const NODE_MODULES = `${path_1.default.sep}node_modules${path_1.default.sep}`;
|
|
65
|
+
const compileExtensions = new Set(['.ts', '.tsx', '.mts', '.cts']);
|
|
66
|
+
// There can be more than one instance of NodePackageManager, but node has only a single module cache.
|
|
67
|
+
// Therefore, the resolution cache and the map of parent to child modules should also be global.
|
|
68
|
+
const cache = new Map();
|
|
69
|
+
const children = new Map();
|
|
70
|
+
const invalidationsCache = new Map();
|
|
71
|
+
// This implements a package manager for Node by monkey patching the Node require
|
|
72
|
+
// algorithm so that it uses the specified FileSystem instead of the native one.
|
|
73
|
+
// It also handles installing packages when they are required if not already installed.
|
|
74
|
+
// See https://github.com/nodejs/node/blob/master/lib/internal/modules/cjs/loader.js
|
|
75
|
+
// for reference to Node internals.
|
|
76
|
+
class NodePackageManager {
|
|
77
|
+
constructor(fs, projectRoot, installer) {
|
|
78
|
+
this.fs = fs;
|
|
79
|
+
this.projectRoot = projectRoot;
|
|
80
|
+
this.installer = installer;
|
|
81
|
+
// If using src then assume we're linked and find the link root dir
|
|
82
|
+
this.atlaspackLinkRoot =
|
|
83
|
+
process.env.ATLASPACK_REGISTER_USE_SRC === 'true'
|
|
84
|
+
? path_1.default.resolve(__dirname, '../../../..')
|
|
85
|
+
: null;
|
|
86
|
+
// @ts-expect-error TS2339
|
|
87
|
+
this.currentExtensions = Object.keys(module_1.default._extensions).map((e) => e.substring(1));
|
|
88
|
+
}
|
|
89
|
+
// @ts-expect-error TS2749
|
|
90
|
+
_createResolver() {
|
|
91
|
+
return new node_resolver_core_1.ResolverBase(this.projectRoot, {
|
|
92
|
+
fs: this.fs instanceof fs_1.NodeFS && process.versions.pnp == null
|
|
93
|
+
? undefined
|
|
94
|
+
: {
|
|
95
|
+
canonicalize: (path) => this.fs.realpathSync(path),
|
|
96
|
+
read: (path) => this.fs.readFileSync(path),
|
|
97
|
+
isFile: (path) => this.fs.statSync(path).isFile(),
|
|
98
|
+
isDir: (path) => this.fs.statSync(path).isDirectory(),
|
|
99
|
+
},
|
|
100
|
+
mode: 2,
|
|
101
|
+
entries: ENTRIES,
|
|
102
|
+
packageExports: true,
|
|
103
|
+
moduleDirResolver: process.versions.pnp != null
|
|
104
|
+
? (module, from) => {
|
|
105
|
+
// @ts-expect-error TS2339
|
|
106
|
+
let pnp = module_1.default.findPnpApi(path_1.default.dirname(from));
|
|
107
|
+
return pnp.resolveToUnqualified(
|
|
108
|
+
// append slash to force loading builtins from npm
|
|
109
|
+
module + '/', from);
|
|
110
|
+
}
|
|
111
|
+
: undefined,
|
|
112
|
+
extensions: this.currentExtensions,
|
|
113
|
+
typescript: true,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
static deserialize(opts) {
|
|
117
|
+
return new NodePackageManager(opts.fs, opts.projectRoot, opts.installer);
|
|
118
|
+
}
|
|
119
|
+
serialize() {
|
|
120
|
+
return {
|
|
121
|
+
$$raw: false,
|
|
122
|
+
fs: this.fs,
|
|
123
|
+
projectRoot: this.projectRoot,
|
|
124
|
+
installer: this.installer,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async require(name, from, opts) {
|
|
128
|
+
let { resolved, type } = await this.resolve(name, from, opts);
|
|
129
|
+
if (type === 2) {
|
|
130
|
+
logger_1.default.warn({
|
|
131
|
+
message: 'ES module dependencies are experimental.',
|
|
132
|
+
origin: '@atlaspack/package-manager',
|
|
133
|
+
codeFrames: [
|
|
134
|
+
{
|
|
135
|
+
filePath: resolved,
|
|
136
|
+
codeHighlights: [],
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
});
|
|
140
|
+
// On Windows, Node requires absolute paths to be file URLs.
|
|
141
|
+
if (process.platform === 'win32' && path_1.default.isAbsolute(resolved)) {
|
|
142
|
+
// @ts-expect-error TS2322
|
|
143
|
+
resolved = (0, url_1.pathToFileURL)(resolved);
|
|
144
|
+
}
|
|
145
|
+
return import(resolved);
|
|
146
|
+
}
|
|
147
|
+
return this.load(resolved, from);
|
|
148
|
+
}
|
|
149
|
+
requireSync(name, from) {
|
|
150
|
+
let { resolved } = this.resolveSync(name, from);
|
|
151
|
+
return this.load(resolved, from);
|
|
152
|
+
}
|
|
153
|
+
load(filePath, from) {
|
|
154
|
+
if (!path_1.default.isAbsolute(filePath)) {
|
|
155
|
+
// Node builtin module
|
|
156
|
+
return require(filePath);
|
|
157
|
+
}
|
|
158
|
+
// @ts-expect-error TS2339
|
|
159
|
+
const cachedModule = module_1.default._cache[filePath];
|
|
160
|
+
if (cachedModule !== undefined) {
|
|
161
|
+
return cachedModule.exports;
|
|
162
|
+
}
|
|
163
|
+
// @ts-expect-error TS2339
|
|
164
|
+
let m = new module_1.default(filePath, module_1.default._cache[from] || module.parent);
|
|
165
|
+
// @ts-expect-error TS2339
|
|
166
|
+
const extensions = Object.keys(module_1.default._extensions);
|
|
167
|
+
// This handles supported extensions changing due to, for example, esbuild/register being used
|
|
168
|
+
// We assume that the extension list will change in size - as these tools usually add support for
|
|
169
|
+
// additional extensions.
|
|
170
|
+
if (extensions.length !== this.currentExtensions.length) {
|
|
171
|
+
this.currentExtensions = extensions.map((e) => e.substring(1));
|
|
172
|
+
this.resolver = this._createResolver();
|
|
173
|
+
}
|
|
174
|
+
// @ts-expect-error TS2339
|
|
175
|
+
module_1.default._cache[filePath] = m;
|
|
176
|
+
// Patch require within this module so it goes through our require
|
|
177
|
+
m.require = (id) => {
|
|
178
|
+
return this.requireSync(id, filePath);
|
|
179
|
+
};
|
|
180
|
+
// Patch `fs.readFileSync` temporarily so that it goes through our file system
|
|
181
|
+
let { readFileSync, statSync } = fs_2.default;
|
|
182
|
+
// @ts-expect-error TS2322
|
|
183
|
+
fs_2.default.readFileSync = (filename, encoding) => {
|
|
184
|
+
return this.fs.readFileSync(filename, encoding);
|
|
185
|
+
};
|
|
186
|
+
// @ts-expect-error TS2540
|
|
187
|
+
fs_2.default.statSync = (filename) => {
|
|
188
|
+
return this.fs.statSync(filename);
|
|
189
|
+
};
|
|
190
|
+
let extname = path_1.default.extname(filePath);
|
|
191
|
+
function shouldCompile(atlaspackLinkRoot) {
|
|
192
|
+
if (filePath.includes(NODE_MODULES)) {
|
|
193
|
+
// Don't compile node_modules
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
if (!compileExtensions.has(extname)) {
|
|
197
|
+
// Ignore non-TS files
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
if (atlaspackLinkRoot != null) {
|
|
201
|
+
// If we're linked, only compile files outside the linked atlaspack
|
|
202
|
+
// as those are handled by @atlaspack/babel-register
|
|
203
|
+
return !filePath.startsWith(atlaspackLinkRoot);
|
|
204
|
+
}
|
|
205
|
+
// @ts-expect-error TS2339
|
|
206
|
+
// Lastly make sure there's no existing loader for this extension
|
|
207
|
+
return !module_1.default._extensions[extname];
|
|
208
|
+
}
|
|
209
|
+
if (shouldCompile(this.atlaspackLinkRoot)) {
|
|
210
|
+
// @ts-expect-error TS2339
|
|
211
|
+
let compile = m._compile;
|
|
212
|
+
// @ts-expect-error TS2339
|
|
213
|
+
m._compile = (code, filename) => {
|
|
214
|
+
let out = (0, core_1.transformSync)(code, {
|
|
215
|
+
filename,
|
|
216
|
+
module: { type: 'commonjs' },
|
|
217
|
+
env: { targets: { node: '18' } },
|
|
218
|
+
});
|
|
219
|
+
compile.call(m, out.code, filename);
|
|
220
|
+
};
|
|
221
|
+
// @ts-expect-error TS2339
|
|
222
|
+
module_1.default._extensions[extname] = (m, filename) => {
|
|
223
|
+
// @ts-expect-error TS2339
|
|
224
|
+
delete module_1.default._extensions[extname];
|
|
225
|
+
// @ts-expect-error TS2339
|
|
226
|
+
module_1.default._extensions['.js'](m, filename);
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
// @ts-expect-error TS2339
|
|
231
|
+
m.load(filePath);
|
|
232
|
+
}
|
|
233
|
+
catch (err) {
|
|
234
|
+
// @ts-expect-error TS2339
|
|
235
|
+
delete module_1.default._cache[filePath];
|
|
236
|
+
throw err;
|
|
237
|
+
}
|
|
238
|
+
finally {
|
|
239
|
+
fs_2.default.readFileSync = readFileSync;
|
|
240
|
+
// @ts-expect-error TS2540
|
|
241
|
+
fs_2.default.statSync = statSync;
|
|
242
|
+
}
|
|
243
|
+
return m.exports;
|
|
244
|
+
}
|
|
245
|
+
async resolve(id, from, options) {
|
|
246
|
+
let basedir = path_1.default.dirname(from);
|
|
247
|
+
let key = basedir + ':' + id;
|
|
248
|
+
let resolved = cache.get(key);
|
|
249
|
+
if (!resolved) {
|
|
250
|
+
let [name] = (0, utils_1.getModuleParts)(id);
|
|
251
|
+
try {
|
|
252
|
+
resolved = this.resolveInternal(id, from);
|
|
253
|
+
}
|
|
254
|
+
catch (e) {
|
|
255
|
+
if (e.code !== 'MODULE_NOT_FOUND' ||
|
|
256
|
+
options?.shouldAutoInstall !== true ||
|
|
257
|
+
id.startsWith('.') // a local file, don't autoinstall
|
|
258
|
+
) {
|
|
259
|
+
if (e.code === 'MODULE_NOT_FOUND' &&
|
|
260
|
+
options?.shouldAutoInstall !== true) {
|
|
261
|
+
let err = new diagnostic_1.default({
|
|
262
|
+
diagnostic: {
|
|
263
|
+
message: (0, diagnostic_1.escapeMarkdown)(e.message),
|
|
264
|
+
hints: [
|
|
265
|
+
'Autoinstall is disabled, please install this package manually and restart Parcel.',
|
|
266
|
+
],
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
// @ts-expect-error TS2339
|
|
270
|
+
err.code = 'MODULE_NOT_FOUND';
|
|
271
|
+
throw err;
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
throw e;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
let conflicts = await (0, utils_2.getConflictingLocalDependencies)(this.fs, name, from, this.projectRoot);
|
|
278
|
+
if (conflicts == null) {
|
|
279
|
+
this.invalidate(id, from);
|
|
280
|
+
await this.install([{ name, range: options?.range }], from, {
|
|
281
|
+
saveDev: options?.saveDev ?? true,
|
|
282
|
+
});
|
|
283
|
+
return this.resolve(id, from, {
|
|
284
|
+
...options,
|
|
285
|
+
shouldAutoInstall: false,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
throw new diagnostic_1.default({
|
|
289
|
+
diagnostic: conflicts.fields.map((field) => ({
|
|
290
|
+
message: (0, diagnostic_1.md) `Could not find module "${name}", but it was listed in package.json. Run your package manager first.`,
|
|
291
|
+
origin: '@atlaspack/package-manager',
|
|
292
|
+
codeFrames: [
|
|
293
|
+
{
|
|
294
|
+
filePath: conflicts.filePath,
|
|
295
|
+
language: 'json',
|
|
296
|
+
code: conflicts.json,
|
|
297
|
+
codeHighlights: (0, diagnostic_1.generateJSONCodeHighlights)(conflicts.json, [
|
|
298
|
+
{
|
|
299
|
+
key: `/${field}/${(0, diagnostic_1.encodeJSONKeyComponent)(name)}`,
|
|
300
|
+
type: 'key',
|
|
301
|
+
message: 'Defined here, but not installed',
|
|
302
|
+
},
|
|
303
|
+
]),
|
|
304
|
+
},
|
|
305
|
+
],
|
|
306
|
+
})),
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
let range = options?.range;
|
|
310
|
+
if (range != null) {
|
|
311
|
+
let pkg = resolved.pkg;
|
|
312
|
+
if (pkg == null || !semver_1.default.satisfies(pkg.version, range)) {
|
|
313
|
+
let conflicts = await (0, utils_2.getConflictingLocalDependencies)(this.fs, name, from, this.projectRoot);
|
|
314
|
+
if (conflicts == null && options?.shouldAutoInstall === true) {
|
|
315
|
+
this.invalidate(id, from);
|
|
316
|
+
await this.install([{ name, range }], from);
|
|
317
|
+
return this.resolve(id, from, {
|
|
318
|
+
...options,
|
|
319
|
+
shouldAutoInstall: false,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
else if (conflicts != null) {
|
|
323
|
+
throw new diagnostic_1.default({
|
|
324
|
+
diagnostic: {
|
|
325
|
+
message: (0, diagnostic_1.md) `Could not find module "${name}" satisfying ${range}.`,
|
|
326
|
+
origin: '@atlaspack/package-manager',
|
|
327
|
+
codeFrames: [
|
|
328
|
+
{
|
|
329
|
+
filePath: conflicts.filePath,
|
|
330
|
+
language: 'json',
|
|
331
|
+
code: conflicts.json,
|
|
332
|
+
codeHighlights: (0, diagnostic_1.generateJSONCodeHighlights)(conflicts.json, conflicts.fields.map((field) => ({
|
|
333
|
+
key: `/${field}/${(0, diagnostic_1.encodeJSONKeyComponent)(name)}`,
|
|
334
|
+
type: 'key',
|
|
335
|
+
message: 'Found this conflicting local requirement.',
|
|
336
|
+
}))),
|
|
337
|
+
},
|
|
338
|
+
],
|
|
339
|
+
},
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
let version = pkg?.version;
|
|
343
|
+
let message = (0, diagnostic_1.md) `Could not resolve package "${name}" that satisfies ${range}.`;
|
|
344
|
+
if (version != null) {
|
|
345
|
+
message += (0, diagnostic_1.md) ` Found ${version}.`;
|
|
346
|
+
}
|
|
347
|
+
throw new diagnostic_1.default({
|
|
348
|
+
diagnostic: {
|
|
349
|
+
message,
|
|
350
|
+
hints: [
|
|
351
|
+
'Looks like the incompatible version was installed transitively. Add this package as a direct dependency with a compatible version range.',
|
|
352
|
+
],
|
|
353
|
+
},
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
cache.set(key, resolved);
|
|
358
|
+
invalidationsCache.clear();
|
|
359
|
+
// Add the specifier as a child to the parent module.
|
|
360
|
+
// Don't do this if the specifier was an absolute path, as this was likely a dynamically resolved path
|
|
361
|
+
// (e.g. babel uses require() to load .babelrc.js configs and we don't want them to be added as children of babel itself).
|
|
362
|
+
if (!path_1.default.isAbsolute(name)) {
|
|
363
|
+
let moduleChildren = children.get(from);
|
|
364
|
+
if (!moduleChildren) {
|
|
365
|
+
moduleChildren = new Set();
|
|
366
|
+
children.set(from, moduleChildren);
|
|
367
|
+
}
|
|
368
|
+
moduleChildren.add(name);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return resolved;
|
|
372
|
+
}
|
|
373
|
+
resolveSync(name, from) {
|
|
374
|
+
let basedir = path_1.default.dirname(from);
|
|
375
|
+
let key = basedir + ':' + name;
|
|
376
|
+
let resolved = cache.get(key);
|
|
377
|
+
if (!resolved) {
|
|
378
|
+
resolved = this.resolveInternal(name, from);
|
|
379
|
+
cache.set(key, resolved);
|
|
380
|
+
invalidationsCache.clear();
|
|
381
|
+
if (!path_1.default.isAbsolute(name)) {
|
|
382
|
+
let moduleChildren = children.get(from);
|
|
383
|
+
if (!moduleChildren) {
|
|
384
|
+
moduleChildren = new Set();
|
|
385
|
+
children.set(from, moduleChildren);
|
|
386
|
+
}
|
|
387
|
+
moduleChildren.add(name);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
return resolved;
|
|
391
|
+
}
|
|
392
|
+
async install(modules, from, opts) {
|
|
393
|
+
await (0, installPackage_1.installPackage)(this.fs, this, modules, from, this.projectRoot, {
|
|
394
|
+
packageInstaller: this.installer,
|
|
395
|
+
...opts,
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
getInvalidations(name, from) {
|
|
399
|
+
let basedir = path_1.default.dirname(from);
|
|
400
|
+
let cacheKey = basedir + ':' + name;
|
|
401
|
+
let resolved = cache.get(cacheKey);
|
|
402
|
+
if (resolved && path_1.default.isAbsolute(resolved.resolved)) {
|
|
403
|
+
let cached = invalidationsCache.get(resolved.resolved);
|
|
404
|
+
if (cached != null) {
|
|
405
|
+
return cached;
|
|
406
|
+
}
|
|
407
|
+
let res = {
|
|
408
|
+
invalidateOnFileCreate: [],
|
|
409
|
+
invalidateOnFileChange: new Set(),
|
|
410
|
+
invalidateOnStartup: false,
|
|
411
|
+
};
|
|
412
|
+
let seen = new Set();
|
|
413
|
+
let addKey = (name, from) => {
|
|
414
|
+
let basedir = path_1.default.dirname(from);
|
|
415
|
+
let key = basedir + ':' + name;
|
|
416
|
+
if (seen.has(key)) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
seen.add(key);
|
|
420
|
+
let resolved = cache.get(key);
|
|
421
|
+
if (!resolved || !path_1.default.isAbsolute(resolved.resolved)) {
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
// @ts-expect-error TS2345
|
|
425
|
+
res.invalidateOnFileCreate.push(...resolved.invalidateOnFileCreate);
|
|
426
|
+
res.invalidateOnFileChange.add(resolved.resolved);
|
|
427
|
+
for (let file of resolved.invalidateOnFileChange) {
|
|
428
|
+
res.invalidateOnFileChange.add(file);
|
|
429
|
+
}
|
|
430
|
+
let moduleChildren = children.get(resolved.resolved);
|
|
431
|
+
if (moduleChildren) {
|
|
432
|
+
for (let specifier of moduleChildren) {
|
|
433
|
+
addKey(specifier, resolved.resolved);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
addKey(name, from);
|
|
438
|
+
// If this is an ES module, we won't have any of the dependencies because import statements
|
|
439
|
+
// cannot be intercepted. Instead, ask the resolver to parse the file and recursively analyze the deps.
|
|
440
|
+
if (resolved.type === 2) {
|
|
441
|
+
let invalidations = this.resolver.getInvalidations(resolved.resolved);
|
|
442
|
+
// @ts-expect-error TS7006
|
|
443
|
+
invalidations.invalidateOnFileChange.forEach((i) => res.invalidateOnFileChange.add(i));
|
|
444
|
+
// @ts-expect-error TS7006
|
|
445
|
+
invalidations.invalidateOnFileCreate.forEach((i) =>
|
|
446
|
+
// @ts-expect-error TS2345
|
|
447
|
+
res.invalidateOnFileCreate.push(i));
|
|
448
|
+
res.invalidateOnStartup || (res.invalidateOnStartup = invalidations.invalidateOnStartup);
|
|
449
|
+
if (res.invalidateOnStartup) {
|
|
450
|
+
logger_1.default.warn({
|
|
451
|
+
message: (0, diagnostic_1.md) `${path_1.default.relative(this.projectRoot, resolved.resolved)} contains non-statically analyzable dependencies in its module graph. This causes Parcel to invalidate the cache on startup.`,
|
|
452
|
+
origin: '@atlaspack/package-manager',
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
// @ts-expect-error TS2345
|
|
457
|
+
invalidationsCache.set(resolved.resolved, res);
|
|
458
|
+
// @ts-expect-error TS2322
|
|
459
|
+
return res;
|
|
460
|
+
}
|
|
461
|
+
return {
|
|
462
|
+
invalidateOnFileCreate: [],
|
|
463
|
+
invalidateOnFileChange: new Set(),
|
|
464
|
+
invalidateOnStartup: false,
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
invalidate(name, from) {
|
|
468
|
+
let seen = new Set();
|
|
469
|
+
let invalidate = (name, from) => {
|
|
470
|
+
let basedir = path_1.default.dirname(from);
|
|
471
|
+
let key = basedir + ':' + name;
|
|
472
|
+
if (seen.has(key)) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
seen.add(key);
|
|
476
|
+
let resolved = cache.get(key);
|
|
477
|
+
if (!resolved || !path_1.default.isAbsolute(resolved.resolved)) {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
// During testing don't invalidate Atlaspack modules because
|
|
481
|
+
// this causes failures due to multiple instances of the same module
|
|
482
|
+
// existing simultaniously. This is fine when using babe;-register because
|
|
483
|
+
// it has an internal module cache that NodePacakageManager does not invalidate
|
|
484
|
+
// but fails when using compiled Atlaspack packages in integration tests
|
|
485
|
+
if (process.env.ATLASPACK_BUILD_ENV === 'test' &&
|
|
486
|
+
name.startsWith('@atlaspack/')) {
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
invalidationsCache.delete(resolved.resolved);
|
|
490
|
+
// @ts-expect-error TS2339
|
|
491
|
+
let module = module_1.default._cache[resolved.resolved];
|
|
492
|
+
if (module) {
|
|
493
|
+
// @ts-expect-error TS2339
|
|
494
|
+
delete module_1.default._cache[resolved.resolved];
|
|
495
|
+
}
|
|
496
|
+
let moduleChildren = children.get(resolved.resolved);
|
|
497
|
+
if (moduleChildren) {
|
|
498
|
+
for (let specifier of moduleChildren) {
|
|
499
|
+
invalidate(specifier, resolved.resolved);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
children.delete(resolved.resolved);
|
|
503
|
+
cache.delete(key);
|
|
504
|
+
};
|
|
505
|
+
invalidate(name, from);
|
|
506
|
+
this.resolver = this._createResolver();
|
|
507
|
+
}
|
|
508
|
+
resolveInternal(name, from) {
|
|
509
|
+
if (this.resolver == null) {
|
|
510
|
+
this.resolver = this._createResolver();
|
|
511
|
+
}
|
|
512
|
+
let res = this.resolver.resolve({
|
|
513
|
+
filename: name,
|
|
514
|
+
specifierType: 'commonjs',
|
|
515
|
+
parent: from,
|
|
516
|
+
packageConditions: (0, nodejsConditions_1.getConditionsFromEnv)(),
|
|
517
|
+
});
|
|
518
|
+
// Invalidate whenever the .pnp.js file changes.
|
|
519
|
+
// TODO: only when we actually resolve a node_modules package?
|
|
520
|
+
if (process.versions.pnp != null && res.invalidateOnFileChange) {
|
|
521
|
+
// @ts-expect-error TS2339
|
|
522
|
+
let pnp = module_1.default.findPnpApi(path_1.default.dirname(from));
|
|
523
|
+
res.invalidateOnFileChange.push(pnp.resolveToUnqualified('pnpapi', null));
|
|
524
|
+
}
|
|
525
|
+
if (res.error) {
|
|
526
|
+
let e = new Error(`Could not resolve module "${name}" from "${from}"`);
|
|
527
|
+
// @ts-expect-error TS2339
|
|
528
|
+
e.code = 'MODULE_NOT_FOUND';
|
|
529
|
+
throw e;
|
|
530
|
+
}
|
|
531
|
+
// @ts-expect-error TS7034
|
|
532
|
+
let getPkg;
|
|
533
|
+
switch (res.resolution.type) {
|
|
534
|
+
case 'Path':
|
|
535
|
+
getPkg = () => {
|
|
536
|
+
let pkgPath = this.fs.findAncestorFile(['package.json'], (0, nullthrows_1.default)(res.resolution.value), this.projectRoot);
|
|
537
|
+
return pkgPath
|
|
538
|
+
? JSON.parse(this.fs.readFileSync(pkgPath, 'utf8'))
|
|
539
|
+
: null;
|
|
540
|
+
};
|
|
541
|
+
// fallthrough
|
|
542
|
+
case 'Builtin':
|
|
543
|
+
return {
|
|
544
|
+
resolved: res.resolution.value,
|
|
545
|
+
invalidateOnFileChange: new Set(res.invalidateOnFileChange),
|
|
546
|
+
invalidateOnFileCreate: res.invalidateOnFileCreate,
|
|
547
|
+
type: res.moduleType,
|
|
548
|
+
get pkg() {
|
|
549
|
+
// @ts-expect-error TS7005
|
|
550
|
+
return getPkg();
|
|
551
|
+
},
|
|
552
|
+
};
|
|
553
|
+
default:
|
|
554
|
+
throw new Error('Unknown resolution type');
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
exports.NodePackageManager = NodePackageManager;
|
|
559
|
+
(0, build_cache_1.registerSerializableClass)(`${package_json_1.default.version}:NodePackageManager`, NodePackageManager);
|