@embroider/core 3.4.8-unstable.fad2387 → 3.4.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -15,59 +15,63 @@ const path_1 = require("path");
15
15
  const shared_internals_2 = require("@embroider/shared-internals");
16
16
  const debug_1 = __importDefault(require("debug"));
17
17
  const assert_never_1 = __importDefault(require("assert-never"));
18
- const reverse_exports_1 = __importDefault(require("@embroider/reverse-exports"));
19
- const resolve_exports_1 = require("resolve.exports");
18
+ const resolve_1 = __importDefault(require("resolve"));
20
19
  const virtual_content_1 = require("./virtual-content");
21
20
  const typescript_memoize_1 = require("typescript-memoize");
22
21
  const describe_exports_1 = require("./describe-exports");
23
22
  const fs_1 = require("fs");
24
- const node_resolve_1 = require("./node-resolve");
25
23
  const debug = (0, debug_1.default)('embroider:resolver');
26
- // Using a formatter makes this work lazy so nothing happens when we aren't
27
- // logging. It is unfortunate that formatters are a globally mutable config and
28
- // you can only use single character names, but oh well.
29
- debug_1.default.formatters.p = (s) => {
30
- let cwd = process.cwd();
31
- if (s.startsWith(cwd)) {
32
- return s.slice(cwd.length + 1);
33
- }
34
- return s;
35
- };
36
24
  function logTransition(reason, before, after = before) {
37
25
  if (after.isVirtual) {
38
- debug(`[%s:virtualized] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile);
39
- }
40
- else if (after.resolvedTo) {
41
- debug(`[%s:resolvedTo] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile);
26
+ debug(`virtualized %s in %s because %s`, before.specifier, before.fromFile, reason);
42
27
  }
43
28
  else if (before.specifier !== after.specifier) {
44
29
  if (before.fromFile !== after.fromFile) {
45
- debug(`[%s:aliased and rehomed] %s to %s\n because %s\n from %p\n to %p`, before.debugType, before.specifier, after.specifier, reason, before.fromFile, after.fromFile);
30
+ debug(`aliased and rehomed: %s to %s, from %s to %s because %s`, before.specifier, after.specifier, before.fromFile, after.fromFile, reason);
46
31
  }
47
32
  else {
48
- debug(`[%s:aliased] %s to %s\n because %s`, before.debugType, before.specifier, after.specifier, reason);
33
+ debug(`aliased: %s to %s in %s because`, before.specifier, after.specifier, before.fromFile, reason);
49
34
  }
50
35
  }
51
36
  else if (before.fromFile !== after.fromFile) {
52
- debug(`[%s:rehomed] %s, because %s\n from %p\n to %p`, before.debugType, before.specifier, reason, before.fromFile, after.fromFile);
53
- }
54
- else if (after.isNotFound) {
55
- debug(`[%s:not-found] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile);
37
+ debug(`rehomed: %s from %s to %s because`, before.specifier, before.fromFile, after.fromFile, reason);
56
38
  }
57
39
  else {
58
- debug(`[%s:unchanged] %s because %s\n in %p`, before.debugType, before.specifier, reason, before.fromFile);
40
+ debug(`unchanged: %s in %s because %s`, before.specifier, before.fromFile, reason);
59
41
  }
60
42
  return after;
61
43
  }
62
- function isTerminal(request) {
63
- return request.isVirtual || request.isNotFound || Boolean(request.resolvedTo);
64
- }
65
44
  const compatPattern = /#embroider_compat\/(?<type>[^\/]+)\/(?<rest>.*)/;
45
+ class NodeModuleRequest {
46
+ constructor(specifier, fromFile, isVirtual, meta) {
47
+ this.specifier = specifier;
48
+ this.fromFile = fromFile;
49
+ this.isVirtual = isVirtual;
50
+ this.meta = meta;
51
+ }
52
+ alias(specifier) {
53
+ return new NodeModuleRequest(specifier, this.fromFile, false, this.meta);
54
+ }
55
+ rehome(fromFile) {
56
+ if (this.fromFile === fromFile) {
57
+ return this;
58
+ }
59
+ else {
60
+ return new NodeModuleRequest(this.specifier, fromFile, false, this.meta);
61
+ }
62
+ }
63
+ virtualize(filename) {
64
+ return new NodeModuleRequest(filename, this.fromFile, true, this.meta);
65
+ }
66
+ withMeta(meta) {
67
+ return new NodeModuleRequest(this.specifier, this.fromFile, this.isVirtual, meta);
68
+ }
69
+ }
66
70
  class Resolver {
67
71
  constructor(options) {
68
72
  this.options = options;
69
73
  }
70
- async beforeResolve(request) {
74
+ beforeResolve(request) {
71
75
  if (request.specifier === '@embroider/macros') {
72
76
  // the macros package is always handled directly within babel (not
73
77
  // necessarily as a real resolvable package), so we should not mess with it.
@@ -75,15 +79,9 @@ class Resolver {
75
79
  // why we need to know about it.
76
80
  return logTransition('early exit', request);
77
81
  }
78
- if (request.specifier === 'require') {
79
- return this.external('early require', request, request.specifier);
80
- }
81
82
  request = this.handleFastbootSwitch(request);
82
- request = await this.handleGlobalsCompat(request);
83
+ request = this.handleGlobalsCompat(request);
83
84
  request = this.handleImplicitModules(request);
84
- request = this.handleImplicitTestScripts(request);
85
- request = this.handleVendorStyles(request);
86
- request = this.handleTestSupportStyles(request);
87
85
  request = this.handleRenaming(request);
88
86
  // we expect the specifier to be app relative at this point - must be after handleRenaming
89
87
  request = this.generateFastbootSwitch(request);
@@ -98,45 +96,95 @@ class Resolver {
98
96
  // that calls your build system's normal module resolver, this does both pre-
99
97
  // and post-resolution adjustments as needed to implement our compatibility
100
98
  // rules.
101
- async resolve(request) {
102
- request = await this.beforeResolve(request);
103
- if (request.resolvedTo) {
104
- return request.resolvedTo;
105
- }
106
- let resolution = await request.defaultResolve();
99
+ //
100
+ // Depending on the plugin architecture you're working in, it may be easier to
101
+ // call beforeResolve and fallbackResolve directly, in which case matching the
102
+ // details of the recursion to what this method does are your responsibility.
103
+ async resolve(request, defaultResolve) {
104
+ let gen = this.internalResolve(request, defaultResolve);
105
+ let out = gen.next();
106
+ while (!out.done) {
107
+ out = gen.next(await out.value);
108
+ }
109
+ return out.value;
110
+ }
111
+ // synchronous alternative to resolve() above. Because our own internals are
112
+ // all synchronous, you can use this if your defaultResolve function is
113
+ // synchronous.
114
+ resolveSync(request, defaultResolve) {
115
+ let gen = this.internalResolve(request, defaultResolve);
116
+ let out = gen.next();
117
+ while (!out.done) {
118
+ out = gen.next(out.value);
119
+ }
120
+ return out.value;
121
+ }
122
+ // Our core implementation is a generator so it can power both resolve() and
123
+ // resolveSync()
124
+ *internalResolve(request, defaultResolve) {
125
+ request = this.beforeResolve(request);
126
+ let resolution = yield defaultResolve(request);
107
127
  switch (resolution.type) {
108
128
  case 'found':
109
- case 'ignored':
110
129
  return resolution;
111
130
  case 'not_found':
112
131
  break;
113
132
  default:
114
133
  throw (0, assert_never_1.default)(resolution);
115
134
  }
116
- let nextRequest = await this.fallbackResolve(request);
135
+ let nextRequest = this.fallbackResolve(request);
117
136
  if (nextRequest === request) {
118
137
  // no additional fallback is available.
119
138
  return resolution;
120
139
  }
121
- if (nextRequest.resolvedTo) {
122
- return nextRequest.resolvedTo;
123
- }
124
140
  if (nextRequest.fromFile === request.fromFile && nextRequest.specifier === request.specifier) {
125
141
  throw new Error('Bug Discovered! New request is not === original request but has the same fromFile and specifier. This will likely create a loop.');
126
142
  }
127
- if (nextRequest.isVirtual || nextRequest.isNotFound) {
128
- // virtual and NotFound requests are terminal, there is no more
129
- // beforeResolve or fallbackResolve around them. The defaultResolve is
130
- // expected to know how to implement them.
131
- return nextRequest.defaultResolve();
143
+ if (nextRequest.isVirtual) {
144
+ // virtual requests are terminal, there is no more beforeResolve or
145
+ // fallbackResolve around them. The defaultResolve is expected to know how
146
+ // to implement them.
147
+ return yield defaultResolve(nextRequest);
132
148
  }
133
- return this.resolve(nextRequest);
149
+ return yield* this.internalResolve(nextRequest, defaultResolve);
134
150
  }
135
151
  // Use standard NodeJS resolving, with our required compatibility rules on
136
152
  // top. This is a convenience method for calling resolveSync with the
137
153
  // defaultResolve already configured to be "do the normal node thing".
138
- async nodeResolve(specifier, fromFile) {
139
- return (0, node_resolve_1.nodeResolve)(this, specifier, fromFile);
154
+ nodeResolve(specifier, fromFile) {
155
+ let resolution = this.resolveSync(new NodeModuleRequest(specifier, fromFile, false, undefined), request => {
156
+ if (request.isVirtual) {
157
+ return {
158
+ type: 'found',
159
+ result: {
160
+ type: 'virtual',
161
+ content: (0, virtual_content_1.virtualContent)(request.specifier, this),
162
+ filename: request.specifier,
163
+ },
164
+ };
165
+ }
166
+ try {
167
+ let filename = resolve_1.default.sync(request.specifier, {
168
+ basedir: (0, path_1.dirname)(request.fromFile),
169
+ extensions: this.options.resolvableExtensions,
170
+ });
171
+ return { type: 'found', result: { type: 'real', filename } };
172
+ }
173
+ catch (err) {
174
+ if (err.code !== 'MODULE_NOT_FOUND') {
175
+ throw err;
176
+ }
177
+ return { type: 'not_found', err };
178
+ }
179
+ });
180
+ switch (resolution.type) {
181
+ case 'not_found':
182
+ return resolution;
183
+ case 'found':
184
+ return resolution.result;
185
+ default:
186
+ throw (0, assert_never_1.default)(resolution);
187
+ }
140
188
  }
141
189
  get packageCache() {
142
190
  return shared_internals_2.RewrittenPackageCache.shared('embroider', this.options.appRoot);
@@ -153,9 +201,6 @@ class Resolver {
153
201
  return owningPackage;
154
202
  }
155
203
  generateFastbootSwitch(request) {
156
- if (isTerminal(request)) {
157
- return request;
158
- }
159
204
  let pkg = this.packageCache.ownerOfFile(request.fromFile);
160
205
  if (!pkg) {
161
206
  return request;
@@ -173,9 +218,7 @@ class Resolver {
173
218
  let fastbootFile = engineConfig.fastbootFiles[candidate];
174
219
  if (fastbootFile) {
175
220
  if (fastbootFile.shadowedFilename) {
176
- let { names } = (0, describe_exports_1.describeExports)((0, fs_1.readFileSync)((0, path_1.resolve)(pkg.root, fastbootFile.shadowedFilename), 'utf8'), {
177
- configFile: false,
178
- });
221
+ let { names } = (0, describe_exports_1.describeExports)((0, fs_1.readFileSync)((0, path_1.resolve)(pkg.root, fastbootFile.shadowedFilename), 'utf8'), {});
179
222
  let switchFile = (0, virtual_content_1.fastbootSwitch)(candidate, (0, path_1.resolve)(pkg.root, 'package.json'), names);
180
223
  if (switchFile === request.fromFile) {
181
224
  return logTransition('internal lookup from fastbootSwitch', request);
@@ -194,9 +237,6 @@ class Resolver {
194
237
  }
195
238
  handleFastbootSwitch(request) {
196
239
  var _a;
197
- if (isTerminal(request)) {
198
- return request;
199
- }
200
240
  let match = (0, virtual_content_1.decodeFastbootSwitch)(request.fromFile);
201
241
  if (!match) {
202
242
  return request;
@@ -235,15 +275,12 @@ class Resolver {
235
275
  }
236
276
  let entry = (_a = this.getEntryFromMergeMap(rel, pkg.root)) === null || _a === void 0 ? void 0 : _a.entry;
237
277
  if ((entry === null || entry === void 0 ? void 0 : entry.type) === 'both') {
238
- return logTransition('matched addon entry', request, request.alias(entry[section].specifier).rehome(entry[section].fromFile));
278
+ return logTransition('matched addon entry', request, request.alias(entry[section].localPath).rehome((0, path_1.resolve)(entry[section].packageRoot, 'package.json')));
239
279
  }
240
280
  }
241
281
  return logTransition('failed to match in fastboot switch', request);
242
282
  }
243
283
  handleImplicitModules(request) {
244
- if (isTerminal(request)) {
245
- return request;
246
- }
247
284
  let im = (0, virtual_content_1.decodeImplicitModules)(request.specifier);
248
285
  if (!im) {
249
286
  return request;
@@ -261,42 +298,7 @@ class Resolver {
261
298
  return logTransition(`own implicit modules`, request, request.virtualize((0, path_1.resolve)(pkg.root, `-embroider-${im.type}.js`)));
262
299
  }
263
300
  }
264
- handleImplicitTestScripts(request) {
265
- //TODO move the extra forwardslash handling out into the vite plugin
266
- const candidates = [
267
- '@embroider/core/test-support.js',
268
- '/@embroider/core/test-support.js',
269
- './@embroider/core/test-support.js',
270
- ];
271
- if (!candidates.includes(request.specifier)) {
272
- return request;
273
- }
274
- let pkg = this.packageCache.ownerOfFile(request.fromFile);
275
- if ((pkg === null || pkg === void 0 ? void 0 : pkg.root) !== this.options.engines[0].root) {
276
- throw new Error(`bug: found an import of ${request.specifier} in ${request.fromFile}, but this is not the top-level Ember app. The top-level Ember app is the only one that has support for @embroider/core/test-support.js. If you think something should be fixed in Embroider, please open an issue on https://github.com/embroider-build/embroider/issues.`);
277
- }
278
- return logTransition('test-support', request, request.virtualize((0, path_1.resolve)(pkg.root, '-embroider-test-support.js')));
279
- }
280
- handleTestSupportStyles(request) {
281
- //TODO move the extra forwardslash handling out into the vite plugin
282
- const candidates = [
283
- '@embroider/core/test-support.css',
284
- '/@embroider/core/test-support.css',
285
- './@embroider/core/test-support.css',
286
- ];
287
- if (!candidates.includes(request.specifier)) {
288
- return request;
289
- }
290
- let pkg = this.packageCache.ownerOfFile(request.fromFile);
291
- if ((pkg === null || pkg === void 0 ? void 0 : pkg.root) !== this.options.engines[0].root) {
292
- throw new Error(`bug: found an import of ${request.specifier} in ${request.fromFile}, but this is not the top-level Ember app. The top-level Ember app is the only one that has support for @embroider/core/test-support.css. If you think something should be fixed in Embroider, please open an issue on https://github.com/embroider-build/embroider/issues.`);
293
- }
294
- return logTransition('test-support-styles', request, request.virtualize((0, path_1.resolve)(pkg.root, '-embroider-test-support-styles.css')));
295
- }
296
- async handleGlobalsCompat(request) {
297
- if (isTerminal(request)) {
298
- return request;
299
- }
301
+ handleGlobalsCompat(request) {
300
302
  let match = compatPattern.exec(request.specifier);
301
303
  if (!match) {
302
304
  return request;
@@ -320,76 +322,56 @@ class Resolver {
320
322
  throw new Error(`bug: unexepected #embroider_compat specifier: ${request.specifier}`);
321
323
  }
322
324
  }
323
- handleVendorStyles(request) {
324
- //TODO move the extra forwardslash handling out into the vite plugin
325
- const candidates = ['@embroider/core/vendor.css', '/@embroider/core/vendor.css', './@embroider/core/vendor.css'];
326
- if (!candidates.includes(request.specifier)) {
327
- return request;
328
- }
329
- let pkg = this.packageCache.ownerOfFile(request.fromFile);
330
- if ((pkg === null || pkg === void 0 ? void 0 : pkg.root) !== this.options.engines[0].root) {
331
- throw new Error(`bug: found an import of ${request.specifier} in ${request.fromFile}, but this is not the top-level Ember app. The top-level Ember app is the only one that has support for @embroider/core/vendor.css. If you think something should be fixed in Embroider, please open an issue on https://github.com/embroider-build/embroider/issues.`);
332
- }
333
- return logTransition('vendor-styles', request, request.virtualize((0, path_1.resolve)(pkg.root, '-embroider-vendor-styles.css')));
334
- }
335
325
  resolveHelper(path, inEngine, request) {
336
326
  let target = this.parseGlobalPath(path, inEngine);
337
327
  return logTransition('resolveHelper', request, request.alias(`${target.packageName}/helpers/${target.memberName}`).rehome((0, path_1.resolve)(inEngine.root, 'package.json')));
338
328
  }
339
- async resolveComponent(path, inEngine, request) {
329
+ resolveComponent(path, inEngine, request) {
340
330
  let target = this.parseGlobalPath(path, inEngine);
341
331
  let hbsModule = null;
342
332
  let jsModule = null;
343
333
  // first, the various places our template might be.
344
334
  for (let candidate of this.componentTemplateCandidates(target.packageName)) {
345
- let candidateSpecifier = `${target.packageName}${candidate.prefix}${target.memberName}${candidate.suffix}`;
346
- let resolution = await this.resolve(request.alias(candidateSpecifier).rehome(target.from).withMeta({
347
- runtimeFallback: false,
348
- }));
349
- if (resolution.type === 'found') {
350
- hbsModule = resolution;
335
+ let resolution = this.nodeResolve(`${target.packageName}${candidate.prefix}${target.memberName}${candidate.suffix}`, target.from);
336
+ if (resolution.type === 'real') {
337
+ hbsModule = resolution.filename;
351
338
  break;
352
339
  }
353
340
  }
354
341
  // then the various places our javascript might be.
355
342
  for (let candidate of this.componentJSCandidates(target.packageName)) {
356
- let candidateSpecifier = `${target.packageName}${candidate.prefix}${target.memberName}${candidate.suffix}`;
357
- let resolution = await this.resolve(request.alias(candidateSpecifier).rehome(target.from).withMeta({
358
- runtimeFallback: false,
359
- }));
343
+ let resolution = this.nodeResolve(`${target.packageName}${candidate.prefix}${target.memberName}${candidate.suffix}`, target.from);
360
344
  // .hbs is a resolvable extension for us, so we need to exclude it here.
361
345
  // It matches as a priority lower than .js, so finding an .hbs means
362
346
  // there's definitely not a .js.
363
- if (resolution.type === 'found' && !resolution.filename.endsWith('.hbs')) {
364
- jsModule = resolution;
347
+ if (resolution.type === 'real' && !resolution.filename.endsWith('.hbs')) {
348
+ jsModule = resolution.filename;
365
349
  break;
366
350
  }
367
351
  }
368
352
  if (hbsModule) {
369
- return logTransition(`resolveComponent found legacy HBS`, request, request.virtualize((0, virtual_content_1.virtualPairComponent)(hbsModule.filename, jsModule === null || jsModule === void 0 ? void 0 : jsModule.filename)));
353
+ return logTransition(`resolveComponent found legacy HBS`, request, request.virtualize((0, virtual_content_1.virtualPairComponent)(hbsModule, jsModule)));
370
354
  }
371
355
  else if (jsModule) {
372
- return logTransition(`resolving to resolveComponent found only JS`, request, request.resolveTo(jsModule));
356
+ return logTransition(`resolveComponent found only JS`, request, request.alias(jsModule).rehome(target.from));
373
357
  }
374
358
  else {
375
359
  return logTransition(`resolveComponent failed`, request);
376
360
  }
377
361
  }
378
- async resolveHelperOrComponent(path, inEngine, request) {
362
+ resolveHelperOrComponent(path, inEngine, request) {
379
363
  // resolveHelper just rewrites our request to one that should target the
380
364
  // component, so here to resolve the ambiguity we need to actually resolve
381
365
  // that candidate to see if it works.
382
366
  let helperCandidate = this.resolveHelper(path, inEngine, request);
383
- let helperMatch = await this.resolve(request.alias(helperCandidate.specifier).rehome(helperCandidate.fromFile).withMeta({
384
- runtimeFallback: false,
385
- }));
386
- if (helperMatch.type === 'found') {
387
- return logTransition('resolve to ambiguous case matched a helper', request, request.resolveTo(helperMatch));
367
+ let helperMatch = this.nodeResolve(helperCandidate.specifier, helperCandidate.fromFile);
368
+ if (helperMatch.type === 'real') {
369
+ return logTransition('ambiguous case matched a helper', request, helperCandidate);
388
370
  }
389
371
  // unlike resolveHelper, resolveComponent already does pre-resolution in
390
372
  // order to deal with its own internal ambiguity around JS vs HBS vs
391
373
  // colocation.≥
392
- let componentMatch = await this.resolveComponent(path, inEngine, request);
374
+ let componentMatch = this.resolveComponent(path, inEngine, request);
393
375
  if (componentMatch !== request) {
394
376
  return logTransition('ambiguous case matched a cmoponent', request, componentMatch);
395
377
  }
@@ -414,7 +396,6 @@ class Resolver {
414
396
  }
415
397
  *componentJSCandidates(inPackageName) {
416
398
  yield { prefix: '/components/', suffix: '' };
417
- yield { prefix: '/components/', suffix: '/index' };
418
399
  yield { prefix: '/components/', suffix: '/component' };
419
400
  let pods = this.podPrefix(inPackageName);
420
401
  if (pods) {
@@ -433,10 +414,10 @@ class Resolver {
433
414
  parseGlobalPath(path, inEngine) {
434
415
  let parts = path.split('@');
435
416
  if (parts.length > 1 && parts[0].length > 0) {
436
- return { packageName: parts[0], memberName: parts[1], from: (0, path_1.resolve)(inEngine.root, 'package.json') };
417
+ return { packageName: parts[0], memberName: parts[1], from: (0, path_1.resolve)(inEngine.root, 'pacakge.json') };
437
418
  }
438
419
  else {
439
- return { packageName: inEngine.packageName, memberName: path, from: (0, path_1.resolve)(inEngine.root, 'package.json') };
420
+ return { packageName: inEngine.packageName, memberName: path, from: (0, path_1.resolve)(inEngine.root, 'pacakge.json') };
440
421
  }
441
422
  }
442
423
  engineConfig(packageName) {
@@ -468,8 +449,8 @@ class Resolver {
468
449
  engineModules.set(inEngineName, {
469
450
  type: 'app-only',
470
451
  'app-js': {
471
- specifier: (0, reverse_exports_1.default)(addon.packageJSON, inAddonName),
472
- fromFile: addonConfig.canResolveFromFile,
452
+ localPath: inAddonName,
453
+ packageRoot: addon.root,
473
454
  fromPackageName: addon.name,
474
455
  },
475
456
  });
@@ -482,8 +463,8 @@ class Resolver {
482
463
  engineModules.set(inEngineName, {
483
464
  type: 'both',
484
465
  'app-js': {
485
- specifier: (0, reverse_exports_1.default)(addon.packageJSON, inAddonName),
486
- fromFile: addonConfig.canResolveFromFile,
466
+ localPath: inAddonName,
467
+ packageRoot: addon.root,
487
468
  fromPackageName: addon.name,
488
469
  },
489
470
  'fastboot-js': prevEntry['fastboot-js'],
@@ -507,8 +488,8 @@ class Resolver {
507
488
  engineModules.set(inEngineName, {
508
489
  type: 'fastboot-only',
509
490
  'fastboot-js': {
510
- specifier: (0, reverse_exports_1.default)(addon.packageJSON, inAddonName),
511
- fromFile: addonConfig.canResolveFromFile,
491
+ localPath: inAddonName,
492
+ packageRoot: addon.root,
512
493
  fromPackageName: addon.name,
513
494
  },
514
495
  });
@@ -521,8 +502,8 @@ class Resolver {
521
502
  engineModules.set(inEngineName, {
522
503
  type: 'both',
523
504
  'fastboot-js': {
524
- specifier: (0, reverse_exports_1.default)(addon.packageJSON, inAddonName),
525
- fromFile: addonConfig.canResolveFromFile,
505
+ localPath: inAddonName,
506
+ packageRoot: addon.root,
526
507
  fromPackageName: addon.name,
527
508
  },
528
509
  'app-js': prevEntry['app-js'],
@@ -544,7 +525,7 @@ class Resolver {
544
525
  return owningEngine;
545
526
  }
546
527
  handleRewrittenPackages(request) {
547
- if (isTerminal(request)) {
528
+ if (request.isVirtual) {
548
529
  return request;
549
530
  }
550
531
  let requestingPkg = this.packageCache.ownerOfFile(request.fromFile);
@@ -563,6 +544,10 @@ class Resolver {
563
544
  targetPkg = this.packageCache.resolve(packageName, requestingPkg);
564
545
  }
565
546
  catch (err) {
547
+ // this is not the place to report resolution failures. If the thing
548
+ // doesn't resolve, we're just not interested in redirecting it for
549
+ // backward-compat, that's all. The rest of the system will take care of
550
+ // reporting a failure to resolve (or handling it a different way)
566
551
  if (err.code !== 'MODULE_NOT_FOUND') {
567
552
  throw err;
568
553
  }
@@ -578,26 +563,14 @@ class Resolver {
578
563
  return logTransition('request targets a moved package', request, this.resolveWithinMovedPackage(request, targetPkg));
579
564
  }
580
565
  else if (originalRequestingPkg !== requestingPkg) {
581
- if (targetPkg) {
582
- // in this case, the requesting package is moved but its destination is
583
- // not, so we need to rehome the request back to the original location.
584
- return logTransition('outbound request from moved package', request, request
585
- // setting meta here because if this fails, we want the fallback
586
- // logic to revert our rehome and continue from the *moved* package.
587
- .withMeta({ originalFromFile: request.fromFile })
588
- .rehome((0, path_1.resolve)(originalRequestingPkg.root, 'package.json')));
589
- }
590
- else {
591
- // requesting package was moved and we failed to find its target. We
592
- // can't let that accidentally succeed in the defaultResolve because we
593
- // could escape the moved package system.
594
- return logTransition('missing outbound request from moved package', request, request.notFound());
595
- }
566
+ // in this case, the requesting package is moved but its destination is
567
+ // not, so we need to rehome the request back to the original location.
568
+ return logTransition('outbound request from moved package', request, request.withMeta({ wasMovedTo: request.fromFile }).rehome((0, path_1.resolve)(originalRequestingPkg.root, 'package.json')));
596
569
  }
597
570
  return request;
598
571
  }
599
572
  handleRenaming(request) {
600
- if (isTerminal(request)) {
573
+ if (request.isVirtual) {
601
574
  return request;
602
575
  }
603
576
  let packageName = (0, shared_internals_1.packageName)(request.specifier);
@@ -630,34 +603,12 @@ class Resolver {
630
603
  return logTransition(`renamePackages`, request, request.alias(request.specifier.replace(packageName, this.options.renamePackages[packageName])));
631
604
  }
632
605
  }
633
- if (pkg.name === packageName) {
634
- // we found a self-import
635
- if (pkg.meta['auto-upgraded']) {
636
- // auto-upgraded packages always get automatically adjusted. They never
637
- // supported fancy package.json exports features so this direct mapping
638
- // to the root is always right.
639
- // "my-package/foo" -> "./foo"
640
- // "my-package" -> "./" (this can't be just "." because node's require.resolve doesn't reliable support that)
641
- let selfImportPath = request.specifier === pkg.name ? './' : request.specifier.replace(pkg.name, '.');
642
- return logTransition(`v1 self-import`, request, request.alias(selfImportPath).rehome((0, path_1.resolve)(pkg.root, 'package.json')));
643
- }
644
- else {
645
- // v2 packages are supposed to use package.json `exports` to enable
646
- // self-imports, but not all build tools actually follow the spec. This
647
- // is a workaround for badly behaved packagers.
648
- //
649
- // Known upstream bugs this works around:
650
- // - https://github.com/vitejs/vite/issues/9731
651
- if (pkg.packageJSON.exports) {
652
- let found = (0, resolve_exports_1.exports)(pkg.packageJSON, request.specifier, {
653
- browser: true,
654
- conditions: ['default', 'imports'],
655
- });
656
- if (found === null || found === void 0 ? void 0 : found[0]) {
657
- return logTransition(`v2 self-import with package.json exports`, request, request.alias(found === null || found === void 0 ? void 0 : found[0]).rehome((0, path_1.resolve)(pkg.root, 'package.json')));
658
- }
659
- }
660
- }
606
+ if (pkg.meta['auto-upgraded'] && pkg.name === packageName) {
607
+ // we found a self-import, resolve it for them. Only auto-upgraded
608
+ // packages get this help, v2 packages are natively supposed to make their
609
+ // own modules resolvable, and we want to push them all to do that
610
+ // correctly.
611
+ return logTransition(`v1 self-import`, request, request.alias(request.specifier.replace(pkg.name, '.')).rehome((0, path_1.resolve)(pkg.root, 'package.json')));
661
612
  }
662
613
  return request;
663
614
  }
@@ -666,17 +617,16 @@ class Resolver {
666
617
  if (pkg.name.startsWith('@')) {
667
618
  levels.push('..');
668
619
  }
669
- let originalFromFile = request.fromFile;
670
620
  let newRequest = request.rehome((0, path_1.resolve)(pkg.root, ...levels, 'moved-package-target.js'));
671
621
  if (newRequest === request) {
672
622
  return request;
673
623
  }
674
- // setting meta because if this fails, we want the fallback to pick up back
675
- // in the original requesting package.
676
- return newRequest.withMeta({ originalFromFile });
624
+ return newRequest.withMeta({
625
+ resolvedWithinPackage: pkg.root,
626
+ });
677
627
  }
678
628
  preHandleExternal(request) {
679
- if (isTerminal(request)) {
629
+ if (request.isVirtual) {
680
630
  return request;
681
631
  }
682
632
  let { specifier, fromFile } = request;
@@ -709,15 +659,7 @@ class Resolver {
709
659
  // engine
710
660
  let logicalLocation = this.reverseSearchAppTree(pkg, request.fromFile);
711
661
  if (logicalLocation) {
712
- return logTransition('beforeResolve: relative import in app-js', request, request
713
- .alias('./' + path_1.posix.join((0, path_1.dirname)(logicalLocation.inAppName), request.specifier))
714
- // it's important that we're rehoming this to the root of the engine
715
- // (which we know really exists), and not to a subdir like
716
- // logicalLocation.inAppName (which might not physically exist),
717
- // because some environments (including node's require.resolve) will
718
- // refuse to do resolution from a notional path that doesn't
719
- // physically exist.
720
- .rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, 'package.json')));
662
+ return logTransition('beforeResolve: relative import in app-js', request, request.rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, logicalLocation.inAppName)));
721
663
  }
722
664
  return request;
723
665
  }
@@ -732,11 +674,11 @@ class Resolver {
732
674
  if (shared_internals_1.emberVirtualPeerDeps.has(packageName) && !pkg.hasDependency(packageName)) {
733
675
  // addons (whether auto-upgraded or not) may use the app's
734
676
  // emberVirtualPeerDeps, like "@glimmer/component" etc.
735
- let addon = this.locateActiveAddon(packageName);
736
- if (!addon) {
737
- throw new Error(`${pkg.name} is trying to import the emberVirtualPeerDep "${packageName}", but it seems to be missing`);
677
+ if (!this.options.activeAddons[packageName]) {
678
+ throw new Error(`${pkg.name} is trying to import the app's ${packageName} package, but it seems to be missing`);
738
679
  }
739
- return logTransition(`emberVirtualPeerDeps`, request, request.rehome(addon.canResolveFromFile));
680
+ let newHome = (0, path_1.resolve)(this.packageCache.maybeMoved(this.packageCache.get(this.options.appRoot)).root, 'package.json');
681
+ return logTransition(`emberVirtualPeerDeps in v2 addon`, request, request.rehome(newHome));
740
682
  }
741
683
  // if this file is part of an addon's app-js, it's really the logical
742
684
  // package to which it belongs (normally the app) that affects some policy
@@ -767,22 +709,6 @@ class Resolver {
767
709
  }
768
710
  return request;
769
711
  }
770
- locateActiveAddon(packageName) {
771
- if (packageName === this.options.modulePrefix) {
772
- // the app itself is something that addon's can classically resolve if they know it's name.
773
- return {
774
- root: this.options.appRoot,
775
- canResolveFromFile: (0, path_1.resolve)(this.packageCache.maybeMoved(this.packageCache.get(this.options.appRoot)).root, 'package.json'),
776
- };
777
- }
778
- for (let engine of this.options.engines) {
779
- for (let addon of engine.activeAddons) {
780
- if (addon.name === packageName) {
781
- return addon;
782
- }
783
- }
784
- }
785
- }
786
712
  external(label, request, specifier) {
787
713
  if (this.options.amdCompatibility === 'cjs') {
788
714
  let filename = (0, virtual_content_1.virtualExternalCJSModule)(specifier);
@@ -815,11 +741,8 @@ class Resolver {
815
741
  throw new Error(`Embroider's amdCompatibility option is disabled, but something tried to use it to access "${request.specifier}"`);
816
742
  }
817
743
  }
818
- async fallbackResolve(request) {
744
+ fallbackResolve(request) {
819
745
  var _a, _b, _c;
820
- if (request.isVirtual) {
821
- throw new Error('Build tool bug detected! Fallback resolve should never see a virtual request. It is expected that the defaultResolve for your bundler has already resolved this request');
822
- }
823
746
  if (request.specifier === '@embroider/macros') {
824
747
  // the macros package is always handled directly within babel (not
825
748
  // necessarily as a real resolvable package), so we should not mess with it.
@@ -827,7 +750,8 @@ class Resolver {
827
750
  // why we need to know about it.
828
751
  return logTransition('fallback early exit', request);
829
752
  }
830
- if (compatPattern.test(request.specifier)) {
753
+ let { specifier, fromFile } = request;
754
+ if (compatPattern.test(specifier)) {
831
755
  // Some kinds of compat requests get rewritten into other things
832
756
  // deterministically. For example, "#embroider_compat/helpers/whatever"
833
757
  // means only "the-current-engine/helpers/whatever", and if that doesn't
@@ -843,33 +767,39 @@ class Resolver {
843
767
  // here.
844
768
  return request;
845
769
  }
846
- let pkg = this.packageCache.ownerOfFile(request.fromFile);
770
+ if (fromFile.endsWith('moved-package-target.js')) {
771
+ if (!((_a = request.meta) === null || _a === void 0 ? void 0 : _a.resolvedWithinPackage)) {
772
+ throw new Error(`bug: embroider resolver's meta is not propagating`);
773
+ }
774
+ fromFile = (0, path_1.resolve)((_b = request.meta) === null || _b === void 0 ? void 0 : _b.resolvedWithinPackage, 'package.json');
775
+ }
776
+ let pkg = this.packageCache.ownerOfFile(fromFile);
847
777
  if (!pkg) {
848
778
  return logTransition('no identifiable owningPackage', request);
849
779
  }
850
- // meta.originalFromFile gets set when we want to try to rehome a request
851
- // but then come back to the original location here in the fallback when the
852
- // rehomed request fails
780
+ // if we rehomed this request to its un-rewritten location in order to try
781
+ // to do the defaultResolve from there, now we refer back to the rewritten
782
+ // location because that's what we want to use when asking things like
783
+ // isV2Ember()
853
784
  let movedPkg = this.packageCache.maybeMoved(pkg);
854
785
  if (movedPkg !== pkg) {
855
- let originalFromFile = (_a = request.meta) === null || _a === void 0 ? void 0 : _a.originalFromFile;
856
- if (typeof originalFromFile !== 'string') {
786
+ if (!((_c = request.meta) === null || _c === void 0 ? void 0 : _c.wasMovedTo)) {
857
787
  throw new Error(`bug: embroider resolver's meta is not propagating`);
858
788
  }
859
- request = request.rehome(originalFromFile);
789
+ fromFile = request.meta.wasMovedTo;
860
790
  pkg = movedPkg;
861
791
  }
862
792
  if (!pkg.isV2Ember()) {
863
793
  return logTransition('fallbackResolve: not in an ember package', request);
864
794
  }
865
- let packageName = (0, shared_internals_1.packageName)(request.specifier);
795
+ let packageName = (0, shared_internals_1.packageName)(specifier);
866
796
  if (!packageName) {
867
797
  // this is a relative import
868
798
  let withinEngine = this.engineConfig(pkg.name);
869
799
  if (withinEngine) {
870
800
  // it's a relative import inside an engine (which also means app), which
871
801
  // means we may need to satisfy the request via app tree merging.
872
- let appJSMatch = await this.searchAppTree(request, withinEngine, (0, shared_internals_2.explicitRelative)(pkg.root, (0, path_1.resolve)((0, path_1.dirname)(request.fromFile), request.specifier)));
802
+ let appJSMatch = this.searchAppTree(request, withinEngine, (0, shared_internals_2.explicitRelative)(pkg.root, (0, path_1.resolve)((0, path_1.dirname)(fromFile), specifier)));
873
803
  if (appJSMatch) {
874
804
  return logTransition('fallbackResolve: relative appJsMatch', request, appJSMatch);
875
805
  }
@@ -883,49 +813,40 @@ class Resolver {
883
813
  }
884
814
  }
885
815
  // auto-upgraded packages can fall back to the set of known active addons
886
- if (pkg.meta['auto-upgraded']) {
887
- let addon = this.locateActiveAddon(packageName);
888
- if (addon) {
889
- const rehomed = request.rehome(addon.canResolveFromFile);
890
- if (rehomed !== request) {
891
- return logTransition(`activeAddons`, request, rehomed);
892
- }
816
+ if (pkg.meta['auto-upgraded'] && this.options.activeAddons[packageName]) {
817
+ const rehomed = this.resolveWithinMovedPackage(request, this.packageCache.get(this.options.activeAddons[packageName]));
818
+ if (rehomed !== request) {
819
+ return logTransition(`activeAddons`, request, rehomed);
893
820
  }
894
821
  }
895
- let logicalLocation = this.reverseSearchAppTree(pkg, request.fromFile);
822
+ let logicalLocation = this.reverseSearchAppTree(pkg, fromFile);
896
823
  if (logicalLocation) {
897
824
  // the requesting file is in an addon's appTree. We didn't succeed in
898
825
  // resolving this (non-relative) request from inside the actual addon, so
899
826
  // next try to resolve it from the corresponding logical location in the
900
827
  // app.
901
- return logTransition('fallbackResolve: retry from logical home of app-js file', request,
902
- // it might look more precise to rehome into logicalLocation.inAppName
903
- // rather than package.json. But that logical location may not actually
904
- // exist, and some systems (including node's require.resolve) will be
905
- // mad about trying to resolve from notional paths that don't really
906
- // exist.
907
- request.rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, 'package.json')));
828
+ return logTransition('fallbackResolve: retry from logical home of app-js file', request, request.rehome((0, path_1.resolve)(logicalLocation.owningEngine.root, logicalLocation.inAppName)));
908
829
  }
909
830
  let targetingEngine = this.engineConfig(packageName);
910
831
  if (targetingEngine) {
911
- let appJSMatch = await this.searchAppTree(request, targetingEngine, request.specifier.replace(packageName, '.'));
832
+ let appJSMatch = this.searchAppTree(request, targetingEngine, specifier.replace(packageName, '.'));
912
833
  if (appJSMatch) {
913
834
  return logTransition('fallbackResolve: non-relative appJsMatch', request, appJSMatch);
914
835
  }
915
836
  }
916
- if (pkg.meta['auto-upgraded'] && ((_c = (_b = request.meta) === null || _b === void 0 ? void 0 : _b.runtimeFallback) !== null && _c !== void 0 ? _c : true)) {
837
+ if (pkg.meta['auto-upgraded']) {
917
838
  // auto-upgraded packages can fall back to attempting to find dependencies at
918
839
  // runtime. Native v2 packages can only get this behavior in the
919
840
  // isExplicitlyExternal case above because they need to explicitly ask for
920
841
  // externals.
921
- return this.external('v1 catch-all fallback', request, request.specifier);
842
+ return this.external('v1 catch-all fallback', request, specifier);
922
843
  }
923
844
  else {
924
845
  // native v2 packages don't automatically externalize *everything* the way
925
846
  // auto-upgraded packages do, but they still externalize known and approved
926
847
  // ember virtual packages (like @ember/component)
927
848
  if (shared_internals_1.emberVirtualPackages.has(packageName)) {
928
- return this.external('emberVirtualPackages', request, request.specifier);
849
+ return this.external('emberVirtualPackages', request, specifier);
929
850
  }
930
851
  }
931
852
  // this is falling through with the original specifier which was
@@ -952,23 +873,25 @@ class Resolver {
952
873
  }
953
874
  }
954
875
  }
955
- async searchAppTree(request, engine, inEngineSpecifier) {
876
+ searchAppTree(request, engine, inEngineSpecifier) {
956
877
  let matched = this.getEntryFromMergeMap(inEngineSpecifier, engine.root);
957
878
  switch (matched === null || matched === void 0 ? void 0 : matched.entry.type) {
958
879
  case undefined:
959
880
  return undefined;
960
881
  case 'app-only':
961
- return request.alias(matched.entry['app-js'].specifier).rehome(matched.entry['app-js'].fromFile);
882
+ return request
883
+ .alias(matched.entry['app-js'].localPath)
884
+ .rehome((0, path_1.resolve)(matched.entry['app-js'].packageRoot, 'package.json'));
962
885
  case 'fastboot-only':
963
- return request.alias(matched.entry['fastboot-js'].specifier).rehome(matched.entry['fastboot-js'].fromFile);
886
+ return request
887
+ .alias(matched.entry['fastboot-js'].localPath)
888
+ .rehome((0, path_1.resolve)(matched.entry['fastboot-js'].packageRoot, 'package.json'));
964
889
  case 'both':
965
- let foundAppJS = await this.resolve(request.alias(matched.entry['app-js'].specifier).rehome(matched.entry['app-js'].fromFile).withMeta({
966
- runtimeFallback: false,
967
- }));
968
- if (foundAppJS.type !== 'found') {
890
+ let foundAppJS = this.nodeResolve(matched.entry['app-js'].localPath, (0, path_1.resolve)(matched.entry['app-js'].packageRoot, 'package.json'));
891
+ if (foundAppJS.type !== 'real') {
969
892
  throw new Error(`${matched.entry['app-js'].fromPackageName} declared ${inEngineSpecifier} in packageJSON.ember-addon.app-js, but that module does not exist`);
970
893
  }
971
- let { names } = (0, describe_exports_1.describeExports)((0, fs_1.readFileSync)(foundAppJS.filename, 'utf8'), { configFile: false });
894
+ let { names } = (0, describe_exports_1.describeExports)((0, fs_1.readFileSync)(foundAppJS.filename, 'utf8'), {});
972
895
  return request.virtualize((0, virtual_content_1.fastbootSwitch)(matched.matched, (0, path_1.resolve)(engine.root, 'package.json'), names));
973
896
  }
974
897
  }