@embroider/compat 3.8.1-unstable.fc482ba → 3.8.1

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.
Files changed (97) hide show
  1. package/package.json +17 -15
  2. package/src/audit/babel-visitor.js +1 -7
  3. package/src/audit/babel-visitor.js.map +1 -1
  4. package/src/audit/build.js.map +1 -1
  5. package/src/audit/options.d.ts +1 -2
  6. package/src/audit/options.js.map +1 -1
  7. package/src/audit-cli.d.ts +2 -0
  8. package/src/audit-cli.js +150 -0
  9. package/src/audit-cli.js.map +1 -0
  10. package/src/audit.d.ts +57 -7
  11. package/src/audit.js +301 -101
  12. package/src/audit.js.map +1 -1
  13. package/src/babel-plugin-adjust-imports.js +18 -19
  14. package/src/babel-plugin-adjust-imports.js.map +1 -1
  15. package/src/compat-adapters/@ember-data/debug.d.ts +6 -0
  16. package/src/compat-adapters/@ember-data/debug.js +22 -0
  17. package/src/compat-adapters/@ember-data/debug.js.map +1 -0
  18. package/src/compat-adapters/@ember-data/store.d.ts +5 -1
  19. package/src/compat-adapters/@ember-data/store.js +15 -3
  20. package/src/compat-adapters/@ember-data/store.js.map +1 -1
  21. package/src/compat-adapters/active-model-adapter.d.ts +1 -1
  22. package/src/compat-adapters/ember-asset-loader.d.ts +1 -1
  23. package/src/compat-adapters/ember-cli-addon-docs.d.ts +1 -1
  24. package/src/compat-adapters/ember-cli-fastboot.js +1 -0
  25. package/src/compat-adapters/ember-cli-fastboot.js.map +1 -1
  26. package/src/compat-adapters/ember-cli-mirage.js +1 -0
  27. package/src/compat-adapters/ember-cli-mirage.js.map +1 -1
  28. package/src/compat-adapters/ember-decorators.d.ts +1 -1
  29. package/src/compat-adapters/ember-macro-helpers.d.ts +4 -0
  30. package/src/compat-adapters/{ember-fetch.js → ember-macro-helpers.js} +4 -5
  31. package/src/compat-adapters/ember-macro-helpers.js.map +1 -0
  32. package/src/compat-adapters/ember-percy.d.ts +1 -1
  33. package/src/compat-adapters/ember-scroll-modifiers.d.ts +1 -1
  34. package/src/compat-adapters/ember-source.d.ts +6 -3
  35. package/src/compat-adapters/ember-source.js +41 -26
  36. package/src/compat-adapters/ember-source.js.map +1 -1
  37. package/src/compat-adapters/ember-test-selectors.d.ts +1 -1
  38. package/src/compat-addons.js +1 -1
  39. package/src/compat-addons.js.map +1 -1
  40. package/src/compat-app-builder.d.ts +64 -9
  41. package/src/compat-app-builder.js +1272 -110
  42. package/src/compat-app-builder.js.map +1 -1
  43. package/src/compat-app.d.ts +22 -4
  44. package/src/compat-app.js +218 -77
  45. package/src/compat-app.js.map +1 -1
  46. package/src/default-pipeline.d.ts +5 -4
  47. package/src/default-pipeline.js +46 -21
  48. package/src/default-pipeline.js.map +1 -1
  49. package/src/dependency-rules.d.ts +0 -1
  50. package/src/dependency-rules.js +11 -19
  51. package/src/dependency-rules.js.map +1 -1
  52. package/src/detect-babel-plugins.d.ts +0 -1
  53. package/src/detect-babel-plugins.js +0 -14
  54. package/src/detect-babel-plugins.js.map +1 -1
  55. package/src/index.d.ts +2 -2
  56. package/src/index.js +4 -3
  57. package/src/index.js.map +1 -1
  58. package/src/options.d.ts +40 -3
  59. package/src/options.js +11 -3
  60. package/src/options.js.map +1 -1
  61. package/src/rename-require-plugin.d.ts +1 -0
  62. package/src/rename-require-plugin.js +15 -0
  63. package/src/rename-require-plugin.js.map +1 -0
  64. package/src/resolver-transform.js +15 -56
  65. package/src/resolver-transform.js.map +1 -1
  66. package/src/standalone-addon-build.js +15 -6
  67. package/src/standalone-addon-build.js.map +1 -1
  68. package/src/sync-dir.d.ts +8 -0
  69. package/src/sync-dir.js +68 -0
  70. package/src/sync-dir.js.map +1 -0
  71. package/src/template-tag-codemod.d.ts +13 -0
  72. package/src/template-tag-codemod.js +302 -0
  73. package/src/template-tag-codemod.js.map +1 -0
  74. package/src/v1-appboot.d.ts +14 -0
  75. package/src/v1-appboot.js +47 -0
  76. package/src/v1-appboot.js.map +1 -0
  77. package/src/v1-config.d.ts +8 -0
  78. package/src/v1-config.js +51 -1
  79. package/src/v1-config.js.map +1 -1
  80. package/babel.js +0 -1
  81. package/src/babel.d.ts +0 -17
  82. package/src/babel.js +0 -146
  83. package/src/babel.js.map +0 -1
  84. package/src/compat-adapters/ember-fetch.d.ts +0 -5
  85. package/src/compat-adapters/ember-fetch.js.map +0 -1
  86. package/src/compat-adapters/ember-resolver.d.ts +0 -4
  87. package/src/compat-adapters/ember-resolver.js +0 -21
  88. package/src/compat-adapters/ember-resolver.js.map +0 -1
  89. package/src/content-for-config.d.ts +0 -11
  90. package/src/content-for-config.js +0 -66
  91. package/src/content-for-config.js.map +0 -1
  92. package/src/http-audit.d.ts +0 -13
  93. package/src/http-audit.js +0 -60
  94. package/src/http-audit.js.map +0 -1
  95. package/src/module-visitor.d.ts +0 -52
  96. package/src/module-visitor.js +0 -285
  97. package/src/module-visitor.js.map +0 -1
package/src/audit.js CHANGED
@@ -10,30 +10,72 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.Audit = exports.AuditResults = exports.isBuildError = exports.BuildError = void 0;
13
+ exports.isRootMarker = isRootMarker;
13
14
  const fs_extra_1 = require("fs-extra");
14
15
  const path_1 = require("path");
15
16
  const core_1 = require("@embroider/core");
16
17
  const typescript_memoize_1 = require("typescript-memoize");
17
18
  const chalk_1 = __importDefault(require("chalk"));
19
+ const jsdom_1 = __importDefault(require("jsdom"));
18
20
  const groupBy_1 = __importDefault(require("lodash/groupBy"));
21
+ const fromPairs_1 = __importDefault(require("lodash/fromPairs"));
19
22
  const babel_visitor_1 = require("./audit/babel-visitor");
20
23
  const build_1 = require("./audit/build");
21
24
  Object.defineProperty(exports, "BuildError", { enumerable: true, get: function () { return build_1.BuildError; } });
22
25
  Object.defineProperty(exports, "isBuildError", { enumerable: true, get: function () { return build_1.isBuildError; } });
23
- const module_visitor_1 = require("./module-visitor");
26
+ const { JSDOM } = jsdom_1.default;
27
+ function isResolutionFailure(result) {
28
+ return typeof result === 'object' && 'isResolutionFailure' in result;
29
+ }
30
+ function isResolved(module) {
31
+ return Boolean((module === null || module === void 0 ? void 0 : module.parsed) && module.resolved);
32
+ }
33
+ function isLinked(module) {
34
+ return Boolean((module === null || module === void 0 ? void 0 : module.parsed) && module.resolved && module.linked);
35
+ }
24
36
  class AuditResults {
25
37
  constructor() {
26
38
  this.modules = {};
27
39
  this.findings = [];
28
40
  }
29
41
  static create(baseDir, findings, modules) {
42
+ var _a, _b, _c, _d;
30
43
  let results = new this();
31
- results.modules = modules;
44
+ for (let [filename, module] of modules) {
45
+ let publicModule = {
46
+ appRelativePath: (0, core_1.explicitRelative)(baseDir, filename),
47
+ consumedFrom: module.consumedFrom.map(entry => {
48
+ if (isRootMarker(entry)) {
49
+ return entry;
50
+ }
51
+ else {
52
+ return (0, core_1.explicitRelative)(baseDir, entry);
53
+ }
54
+ }),
55
+ resolutions: module.resolved
56
+ ? (0, fromPairs_1.default)([...module.resolved].map(([source, target]) => [
57
+ source,
58
+ isResolutionFailure(target) ? null : (0, core_1.explicitRelative)(baseDir, target),
59
+ ]))
60
+ : {},
61
+ imports: ((_a = module.parsed) === null || _a === void 0 ? void 0 : _a.imports)
62
+ ? module.parsed.imports.map(i => ({
63
+ source: i.source,
64
+ specifiers: i.specifiers.map(s => ({
65
+ name: s.name,
66
+ local: s.local,
67
+ })),
68
+ }))
69
+ : [],
70
+ exports: ((_b = module.linked) === null || _b === void 0 ? void 0 : _b.exports) ? [...module.linked.exports] : [],
71
+ content: ((_c = module.parsed) === null || _c === void 0 ? void 0 : _c.transpiledContent)
72
+ ? (_d = module.parsed) === null || _d === void 0 ? void 0 : _d.transpiledContent.toString()
73
+ : 'module failed to transpile',
74
+ };
75
+ results.modules[(0, core_1.explicitRelative)(baseDir, filename)] = publicModule;
76
+ }
32
77
  for (let finding of findings) {
33
- const filename = finding.filename.startsWith('./')
34
- ? finding.filename
35
- : (0, core_1.explicitRelative)(baseDir, finding.filename);
36
- let relFinding = Object.assign({}, finding, { filename });
78
+ let relFinding = Object.assign({}, finding, { filename: (0, core_1.explicitRelative)(baseDir, finding.filename) });
37
79
  results.findings.push(relFinding);
38
80
  }
39
81
  return results;
@@ -53,7 +95,7 @@ class AuditResults {
53
95
  }
54
96
  output.push(indent(chalk_1.default.blueBright(`file was included because:`), 1));
55
97
  let pointer = filename;
56
- while (!(0, module_visitor_1.isRootMarker)(pointer)) {
98
+ while (!isRootMarker(pointer)) {
57
99
  // the zero here means we only display the first path we found. I think
58
100
  // that's a fine tradeoff to keep the output smaller.
59
101
  let nextPointer = (_a = this.modules[pointer]) === null || _a === void 0 ? void 0 : _a.consumedFrom[0];
@@ -61,7 +103,7 @@ class AuditResults {
61
103
  output.push(indent(chalk_1.default.red(`couldn't figure out why this was included. Please file a bug against @embroider/compat.`), 2));
62
104
  break;
63
105
  }
64
- if ((0, module_visitor_1.isRootMarker)(nextPointer)) {
106
+ if (isRootMarker(nextPointer)) {
65
107
  output.push(indent('packageJSON.ember-addon.assets', 2));
66
108
  }
67
109
  else {
@@ -93,97 +135,107 @@ class Audit {
93
135
  await (0, build_1.buildApp)(options);
94
136
  }
95
137
  let audit = new this(options.app, options);
138
+ if (options['reuse-build']) {
139
+ if (!audit.meta.babel.isParallelSafe) {
140
+ throw new build_1.BuildError(`You can't use the ${chalk_1.default.red('--reuse-build')} option because some of your babel or HBS plugins are non-serializable`);
141
+ }
142
+ }
96
143
  return audit.run();
97
144
  }
98
- constructor(originAppRoot, options) {
145
+ constructor(originAppRoot, options = {}) {
99
146
  this.originAppRoot = originAppRoot;
100
147
  this.options = options;
148
+ this.modules = new Map();
101
149
  this.virtualModules = new Map();
150
+ this.moduleQueue = new Set();
102
151
  this.findings = [];
103
152
  this.frames = new babel_visitor_1.CodeFrameStorage();
104
153
  this.resolver = new core_1.Resolver(this.resolverParams);
105
- this.resolveId = async (specifier, fromFile) => {
106
- if (['@embroider/macros'].includes(specifier)) {
107
- // the audit process deliberately removes the @embroider/macros babel
108
- // plugins, so the imports are still present and should be left alone.
109
- return undefined;
110
- }
111
- if (fromFile.endsWith('.html') && specifier.startsWith(this.options.rootURL)) {
112
- // root-relative URLs in HTML are actually relative to the appDir
113
- specifier = (0, core_1.explicitRelative)((0, path_1.dirname)(fromFile), (0, path_1.resolve)(this.movedAppRoot, specifier.replace(this.options.rootURL, '')));
114
- }
115
- let resolution = await this.resolver.nodeResolve(specifier, fromFile);
116
- switch (resolution.type) {
117
- case 'virtual':
118
- this.virtualModules.set(resolution.filename, resolution.content);
119
- return resolution.filename;
120
- case 'not_found':
121
- return undefined;
122
- case 'real':
123
- return resolution.filename;
124
- }
125
- };
126
- this.load = async (id) => {
127
- let content;
128
- if (this.virtualModules.has(id)) {
129
- content = this.virtualModules.get(id);
130
- }
131
- else {
132
- content = (0, fs_extra_1.readFileSync)(id);
133
- }
134
- if (id.endsWith('.html')) {
135
- return { content, type: 'html' };
136
- }
137
- else if (id.endsWith('.hbs')) {
138
- return { content: (0, core_1.hbsToJS)(content.toString('utf8')), type: 'javascript' };
139
- }
140
- else if (id.endsWith('.json')) {
141
- return this.handleJSON(id, content);
142
- }
143
- else {
144
- return { content, type: 'javascript' };
145
- }
146
- };
154
+ }
155
+ get pkg() {
156
+ return (0, fs_extra_1.readJSONSync)((0, path_1.join)(this.movedAppRoot, 'package.json'));
147
157
  }
148
158
  get movedAppRoot() {
149
159
  let cache = core_1.RewrittenPackageCache.shared('embroider', this.originAppRoot);
150
160
  return cache.maybeMoved(cache.get(this.originAppRoot)).root;
151
161
  }
162
+ get meta() {
163
+ return this.pkg['ember-addon'];
164
+ }
152
165
  get babelConfig() {
153
- let origCwd = process.cwd();
154
- process.chdir(this.originAppRoot);
155
- try {
156
- // eslint-disable-next-line @typescript-eslint/no-require-imports
157
- let config = require((0, path_1.join)(this.originAppRoot, 'babel.config.cjs'));
158
- config = Object.assign({}, config);
159
- config.plugins = config.plugins.filter((p) => !isMacrosPlugin(p));
160
- config.ast = true;
161
- return config;
162
- }
163
- finally {
164
- process.chdir(origCwd);
165
- }
166
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
167
+ let config = require((0, path_1.join)(this.movedAppRoot, this.meta.babel.filename));
168
+ config = Object.assign({}, config);
169
+ config.plugins = config.plugins.filter((p) => !isMacrosPlugin(p));
170
+ config.ast = true;
171
+ return config;
166
172
  }
167
173
  get resolverParams() {
168
174
  return (0, fs_extra_1.readJSONSync)((0, path_1.join)((0, core_1.locateEmbroiderWorkingDir)(this.originAppRoot), 'resolver.json'));
169
175
  }
176
+ debug(message, ...args) {
177
+ if (this.options.debug) {
178
+ console.log(message, ...args);
179
+ }
180
+ }
181
+ visitorFor(filename) {
182
+ if (filename.endsWith('.html')) {
183
+ return this.visitHTML;
184
+ }
185
+ else if (filename.endsWith('.hbs')) {
186
+ return this.visitHBS;
187
+ }
188
+ else if (filename.endsWith('.json')) {
189
+ return this.visitJSON;
190
+ }
191
+ else {
192
+ return this.visitJS;
193
+ }
194
+ }
195
+ async drainQueue() {
196
+ while (this.moduleQueue.size > 0) {
197
+ let filename = this.moduleQueue.values().next().value;
198
+ this.moduleQueue.delete(filename);
199
+ this.debug('visit', filename);
200
+ let visitor = this.visitorFor(filename);
201
+ let content;
202
+ if (this.virtualModules.has(filename)) {
203
+ content = this.virtualModules.get(filename);
204
+ }
205
+ else {
206
+ content = (0, fs_extra_1.readFileSync)(filename);
207
+ }
208
+ // cast is safe because the only way to get into the queue is to go
209
+ // through scheduleVisit, and scheduleVisit creates the entry in
210
+ // this.modules.
211
+ let module = this.modules.get(filename);
212
+ let visitResult = await visitor.call(this, filename, content);
213
+ if (Array.isArray(visitResult)) {
214
+ // the visitor was unable to figure out the ParseFields and returned
215
+ // some number of Findings to us to explain why.
216
+ for (let finding of visitResult) {
217
+ this.pushFinding(finding);
218
+ }
219
+ }
220
+ else {
221
+ module.parsed = visitResult;
222
+ module.resolved = await this.resolveDeps(visitResult.dependencies, filename);
223
+ }
224
+ }
225
+ }
170
226
  async run() {
171
227
  globalThis.embroider_audit = this.handleResolverError.bind(this);
172
228
  try {
173
- let entrypoints = this.options.entrypoints
174
- .filter(a => a.endsWith('html'))
175
- .map(a => (0, path_1.resolve)(this.movedAppRoot, a));
176
- let modules = await (0, module_visitor_1.visitModules)({
177
- base: this.originAppRoot,
178
- entrypoints,
179
- resolveId: this.resolveId,
180
- load: this.load,
181
- findings: this.findings,
182
- frames: this.frames,
183
- babelConfig: this.babelConfig,
184
- });
185
- this.inspectModules(modules);
186
- return AuditResults.create(this.originAppRoot, this.findings, modules);
229
+ this.debug(`meta`, this.meta);
230
+ for (let asset of this.meta.assets) {
231
+ if (asset.endsWith('.html')) {
232
+ this.scheduleVisit((0, path_1.resolve)(this.movedAppRoot, asset), { isRoot: true });
233
+ }
234
+ }
235
+ await this.drainQueue();
236
+ this.linkModules();
237
+ this.inspectModules();
238
+ return AuditResults.create(this.originAppRoot, this.findings, this.modules);
187
239
  }
188
240
  finally {
189
241
  delete globalThis.embroider_audit;
@@ -197,22 +249,54 @@ class Audit {
197
249
  codeFrame: this.frames.render(this.frames.forSource(msg.source)(msg)),
198
250
  });
199
251
  }
200
- inspectModules(modules) {
201
- for (let [filename, module] of Object.entries(modules)) {
202
- if (module.type === 'complete') {
203
- this.inspectImports(filename, module, modules);
252
+ linkModules() {
253
+ for (let module of this.modules.values()) {
254
+ if (isResolved(module)) {
255
+ this.linkModule(module);
204
256
  }
205
257
  }
206
258
  }
207
- inspectImports(filename, module, modules) {
208
- for (let imp of module.imports) {
209
- // our Audit should always ignore any imports of @embroider/macros because we already ignored them
210
- // in resolveId above
211
- if (imp.source === '@embroider/macros') {
212
- continue;
259
+ linkModule(module) {
260
+ let exports = new Set();
261
+ for (let exp of module.parsed.exports) {
262
+ if (typeof exp === 'string') {
263
+ exports.add(exp);
213
264
  }
214
- let resolved = module.resolutions[imp.source];
215
- if (!resolved) {
265
+ else {
266
+ let moduleName = module.resolved.get(exp.all);
267
+ if (!isResolutionFailure(moduleName)) {
268
+ let target = this.modules.get(moduleName);
269
+ if (!isLinked(target) && isResolved(target)) {
270
+ this.linkModule(target);
271
+ }
272
+ if (isLinked(target)) {
273
+ for (let innerExp of target.linked.exports) {
274
+ exports.add(innerExp);
275
+ }
276
+ }
277
+ else {
278
+ // our module doesn't successfully enter linked state because it
279
+ // depends on stuff that also couldn't
280
+ return;
281
+ }
282
+ }
283
+ }
284
+ }
285
+ module.linked = {
286
+ exports,
287
+ };
288
+ }
289
+ inspectModules() {
290
+ for (let [filename, module] of this.modules) {
291
+ if (isLinked(module)) {
292
+ this.inspectImports(filename, module);
293
+ }
294
+ }
295
+ }
296
+ inspectImports(filename, module) {
297
+ for (let imp of module.parsed.imports) {
298
+ let resolved = module.resolved.get(imp.source);
299
+ if (isResolutionFailure(resolved)) {
216
300
  this.findings.push({
217
301
  filename,
218
302
  message: 'unable to resolve dependency',
@@ -221,9 +305,9 @@ class Audit {
221
305
  });
222
306
  }
223
307
  else if (resolved) {
224
- let target = modules[resolved];
308
+ let target = this.modules.get(resolved);
225
309
  for (let specifier of imp.specifiers) {
226
- if (target.type === 'complete' && !this.moduleProvidesName(target, specifier.name)) {
310
+ if (isLinked(target) && !this.moduleProvidesName(target, specifier.name)) {
227
311
  if (specifier.name === 'default') {
228
312
  let backtick = '`';
229
313
  this.findings.push({
@@ -250,29 +334,142 @@ class Audit {
250
334
  // any module can provide a namespace.
251
335
  // CJS and AMD are too dynamic to be sure exactly what names are available,
252
336
  // so they always get a pass
253
- return (0, babel_visitor_1.isNamespaceMarker)(name) || target.isCJS || target.isAMD || target.exports.includes(name);
337
+ return (0, babel_visitor_1.isNamespaceMarker)(name) || target.parsed.isCJS || target.parsed.isAMD || target.linked.exports.has(name);
254
338
  }
255
- handleJSON(filename, content) {
339
+ async visitHTML(filename, content) {
340
+ let dom = new JSDOM(content);
341
+ let scripts = dom.window.document.querySelectorAll('script[type="module"]');
342
+ let dependencies = [];
343
+ for (let script of scripts) {
344
+ let src = script.src;
345
+ if (!src) {
346
+ continue;
347
+ }
348
+ if (new URL(src, 'http://example.com:4321').origin !== 'http://example.com:4321') {
349
+ // src was absolute, we don't handle it
350
+ continue;
351
+ }
352
+ if (src.startsWith(this.meta['root-url'])) {
353
+ // root-relative URLs are actually relative to the appDir
354
+ src = (0, core_1.explicitRelative)((0, path_1.dirname)(filename), (0, path_1.resolve)(this.movedAppRoot, src.replace(this.meta['root-url'], '')));
355
+ }
356
+ dependencies.push(src);
357
+ }
358
+ return {
359
+ imports: [],
360
+ exports: new Set(),
361
+ isCJS: false,
362
+ isAMD: false,
363
+ dependencies,
364
+ transpiledContent: content,
365
+ };
366
+ }
367
+ async visitJS(filename, content) {
368
+ let rawSource = content.toString('utf8');
369
+ try {
370
+ let result = (0, babel_visitor_1.auditJS)(rawSource, filename, this.babelConfig, this.frames);
371
+ for (let problem of result.problems) {
372
+ this.pushFinding({
373
+ filename,
374
+ message: problem.message,
375
+ detail: problem.detail,
376
+ codeFrame: this.frames.render(problem.codeFrameIndex),
377
+ });
378
+ }
379
+ return {
380
+ exports: result.exports,
381
+ imports: result.imports,
382
+ isCJS: result.isCJS,
383
+ isAMD: result.isAMD,
384
+ dependencies: result.imports.map(i => i.source),
385
+ transpiledContent: result.transpiledContent,
386
+ };
387
+ }
388
+ catch (err) {
389
+ if (['BABEL_PARSE_ERROR', 'BABEL_TRANSFORM_ERROR'].includes(err.code)) {
390
+ return [
391
+ {
392
+ filename,
393
+ message: `failed to parse`,
394
+ detail: err.toString().replace(filename, (0, core_1.explicitRelative)(this.originAppRoot, filename)),
395
+ },
396
+ ];
397
+ }
398
+ else {
399
+ throw err;
400
+ }
401
+ }
402
+ }
403
+ async visitHBS(filename, content) {
404
+ let rawSource = content.toString('utf8');
405
+ let js = (0, core_1.hbsToJS)(rawSource);
406
+ return this.visitJS(filename, js);
407
+ }
408
+ async visitJSON(filename, content) {
256
409
  let js;
257
410
  try {
258
411
  let structure = JSON.parse(content.toString('utf8'));
259
412
  js = `export default ${JSON.stringify(structure)}`;
260
413
  }
261
414
  catch (err) {
262
- this.findings.push({
263
- filename,
264
- message: `failed to parse JSON`,
265
- detail: err.toString().replace(filename, (0, core_1.explicitRelative)(this.originAppRoot, filename)),
266
- });
267
- return;
415
+ return [
416
+ {
417
+ filename,
418
+ message: `failed to parse JSON`,
419
+ detail: err.toString().replace(filename, (0, core_1.explicitRelative)(this.originAppRoot, filename)),
420
+ },
421
+ ];
422
+ }
423
+ return this.visitJS(filename, js);
424
+ }
425
+ async resolveDeps(deps, fromFile) {
426
+ let resolved = new Map();
427
+ for (let dep of deps) {
428
+ let resolution = await this.resolver.nodeResolve(dep, fromFile);
429
+ switch (resolution.type) {
430
+ case 'virtual':
431
+ this.virtualModules.set(resolution.filename, resolution.content);
432
+ resolved.set(dep, resolution.filename);
433
+ this.scheduleVisit(resolution.filename, fromFile);
434
+ break;
435
+ case 'not_found':
436
+ if (['@embroider/macros', '@ember/template-factory'].includes(dep)) {
437
+ // the audit process deliberately removes the @embroider/macros babel
438
+ // plugins, so the imports are still present and should be left alone.
439
+ continue;
440
+ }
441
+ resolved.set(dep, { isResolutionFailure: true });
442
+ break;
443
+ case 'real':
444
+ resolved.set(dep, resolution.filename);
445
+ this.scheduleVisit(resolution.filename, fromFile);
446
+ break;
447
+ }
268
448
  }
269
- return { content: js, type: 'javascript' };
449
+ return resolved;
270
450
  }
271
451
  pushFinding(finding) {
272
452
  this.findings.push(finding);
273
453
  }
454
+ scheduleVisit(filename, parent) {
455
+ let record = this.modules.get(filename);
456
+ if (!record) {
457
+ this.debug(`discovered`, filename);
458
+ record = {
459
+ consumedFrom: [parent],
460
+ };
461
+ this.modules.set(filename, record);
462
+ this.moduleQueue.add(filename);
463
+ }
464
+ else {
465
+ record.consumedFrom.push(parent);
466
+ }
467
+ }
274
468
  }
275
469
  exports.Audit = Audit;
470
+ __decorate([
471
+ (0, typescript_memoize_1.Memoize)()
472
+ ], Audit.prototype, "pkg", null);
276
473
  __decorate([
277
474
  (0, typescript_memoize_1.Memoize)()
278
475
  ], Audit.prototype, "movedAppRoot", null);
@@ -293,4 +490,7 @@ function indent(str, level) {
293
490
  .map(line => spaces + line)
294
491
  .join('\n');
295
492
  }
493
+ function isRootMarker(value) {
494
+ return Boolean(value && typeof value !== 'string' && value.isRoot);
495
+ }
296
496
  //# sourceMappingURL=audit.js.map
package/src/audit.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"audit.js","sourceRoot":"","sources":["audit.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, readJSONSync } from 'fs-extra';\nimport { join, resolve as resolvePath, dirname } from 'path';\nimport type { ResolverOptions } from '@embroider/core';\nimport { explicitRelative, hbsToJS, locateEmbroiderWorkingDir, Resolver, RewrittenPackageCache } from '@embroider/core';\nimport { Memoize } from 'typescript-memoize';\nimport chalk from 'chalk';\nimport groupBy from 'lodash/groupBy';\nimport type { NamespaceMarker } from './audit/babel-visitor';\nimport { CodeFrameStorage, isNamespaceMarker } from './audit/babel-visitor';\nimport { AuditBuildOptions, AuditOptions } from './audit/options';\nimport { buildApp, BuildError, isBuildError } from './audit/build';\nimport {\n type ContentType,\n type Module,\n visitModules,\n type RootMarker,\n isRootMarker,\n type CompleteModule,\n} from './module-visitor';\n\nexport interface AuditMessage {\n message: string;\n detail: string;\n loc: Loc;\n source: string;\n filename: string;\n}\n\nexport interface Loc {\n start: { line: number; column: number };\n end: { line: number; column: number };\n}\n\nexport { AuditOptions, AuditBuildOptions, BuildError, isBuildError };\n\nexport interface Finding {\n message: string;\n filename: string;\n detail: string;\n codeFrame?: string;\n}\n\nexport class AuditResults {\n modules: { [file: string]: Module } = {};\n findings: Finding[] = [];\n\n static create(baseDir: string, findings: Finding[], modules: Record<string, Module>) {\n let results = new this();\n results.modules = modules;\n for (let finding of findings) {\n const filename = finding.filename.startsWith('./')\n ? finding.filename\n : explicitRelative(baseDir, finding.filename);\n\n let relFinding = Object.assign({}, finding, { filename });\n results.findings.push(relFinding);\n }\n return results;\n }\n\n humanReadable(): string {\n let output = [] as string[];\n let findingsByFile = groupBy(this.findings, f => f.filename);\n output.push(`=== Audit Results ===`);\n for (let [filename, findings] of Object.entries(findingsByFile)) {\n output.push(`${chalk.yellow(filename)}`);\n for (let finding of findings) {\n output.push(indent(chalk.red(finding.message) + ': ' + finding.detail, 1));\n if (finding.codeFrame) {\n output.push(indent(finding.codeFrame, 2));\n }\n }\n output.push(indent(chalk.blueBright(`file was included because:`), 1));\n let pointer: string | RootMarker = filename;\n while (!isRootMarker(pointer)) {\n // the zero here means we only display the first path we found. I think\n // that's a fine tradeoff to keep the output smaller.\n let nextPointer: string | RootMarker | undefined = this.modules[pointer]?.consumedFrom[0];\n if (!nextPointer) {\n output.push(\n indent(\n chalk.red(`couldn't figure out why this was included. Please file a bug against @embroider/compat.`),\n 2\n )\n );\n break;\n }\n if (isRootMarker(nextPointer)) {\n output.push(indent('packageJSON.ember-addon.assets', 2));\n } else {\n output.push(indent(nextPointer, 2));\n }\n pointer = nextPointer;\n }\n }\n let summaryColor;\n if (this.perfect) {\n summaryColor = chalk.green;\n } else {\n summaryColor = chalk.yellow;\n }\n output.push(summaryColor(`${this.findings.length} issues found`));\n output.push(`=== End Audit Results ===`);\n output.push(''); // always end with a newline because `yarn run` can overwrite our last line otherwise\n return output.join('\\n');\n }\n\n get perfect() {\n return this.findings.length === 0;\n }\n}\n\nexport class Audit {\n private virtualModules: Map<string, string> = new Map();\n private findings = [] as Finding[];\n\n private frames = new CodeFrameStorage();\n\n static async run(options: AuditBuildOptions): Promise<AuditResults> {\n if (!options['reuse-build']) {\n await buildApp(options);\n }\n\n let audit = new this(options.app, options);\n return audit.run();\n }\n\n constructor(private originAppRoot: string, private options: AuditOptions) {}\n\n @Memoize()\n private get movedAppRoot() {\n let cache = RewrittenPackageCache.shared('embroider', this.originAppRoot);\n return cache.maybeMoved(cache.get(this.originAppRoot)).root;\n }\n\n @Memoize()\n private get babelConfig() {\n let origCwd = process.cwd();\n process.chdir(this.originAppRoot);\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n let config = require(join(this.originAppRoot, 'babel.config.cjs'));\n\n config = Object.assign({}, config);\n config.plugins = config.plugins.filter((p: any) => !isMacrosPlugin(p));\n\n config.ast = true;\n return config;\n } finally {\n process.chdir(origCwd);\n }\n }\n\n private get resolverParams(): ResolverOptions {\n return readJSONSync(join(locateEmbroiderWorkingDir(this.originAppRoot), 'resolver.json'));\n }\n\n private resolver = new Resolver(this.resolverParams);\n\n async run(): Promise<AuditResults> {\n (globalThis as any).embroider_audit = this.handleResolverError.bind(this);\n\n try {\n let entrypoints = this.options.entrypoints\n .filter(a => a.endsWith('html'))\n .map(a => resolvePath(this.movedAppRoot, a));\n\n let modules = await visitModules({\n base: this.originAppRoot,\n entrypoints,\n resolveId: this.resolveId,\n load: this.load,\n findings: this.findings,\n frames: this.frames,\n babelConfig: this.babelConfig,\n });\n\n this.inspectModules(modules);\n\n return AuditResults.create(this.originAppRoot, this.findings, modules);\n } finally {\n delete (globalThis as any).embroider_audit;\n }\n }\n\n private resolveId = async (specifier: string, fromFile: string): Promise<string | undefined> => {\n if (['@embroider/macros'].includes(specifier)) {\n // the audit process deliberately removes the @embroider/macros babel\n // plugins, so the imports are still present and should be left alone.\n return undefined;\n }\n\n if (fromFile.endsWith('.html') && specifier.startsWith(this.options.rootURL)) {\n // root-relative URLs in HTML are actually relative to the appDir\n specifier = explicitRelative(\n dirname(fromFile),\n resolvePath(this.movedAppRoot, specifier.replace(this.options.rootURL, ''))\n );\n }\n\n let resolution = await this.resolver.nodeResolve(specifier, fromFile);\n switch (resolution.type) {\n case 'virtual':\n this.virtualModules.set(resolution.filename, resolution.content);\n return resolution.filename;\n case 'not_found':\n return undefined;\n case 'real':\n return resolution.filename;\n }\n };\n\n private load = async (id: string): Promise<{ content: string | Buffer; type: ContentType } | undefined> => {\n let content: string | Buffer;\n if (this.virtualModules.has(id)) {\n content = this.virtualModules.get(id)!;\n } else {\n content = readFileSync(id);\n }\n\n if (id.endsWith('.html')) {\n return { content, type: 'html' };\n } else if (id.endsWith('.hbs')) {\n return { content: hbsToJS(content.toString('utf8')), type: 'javascript' };\n } else if (id.endsWith('.json')) {\n return this.handleJSON(id, content);\n } else {\n return { content, type: 'javascript' };\n }\n };\n\n private handleResolverError(msg: AuditMessage) {\n this.pushFinding({\n message: msg.message,\n filename: msg.filename,\n detail: msg.detail,\n codeFrame: this.frames.render(this.frames.forSource(msg.source)(msg)),\n });\n }\n\n private inspectModules(modules: Record<string, Module>) {\n for (let [filename, module] of Object.entries(modules)) {\n if (module.type === 'complete') {\n this.inspectImports(filename, module, modules);\n }\n }\n }\n\n private inspectImports(filename: string, module: CompleteModule, modules: Record<string, Module>) {\n for (let imp of module.imports) {\n // our Audit should always ignore any imports of @embroider/macros because we already ignored them\n // in resolveId above\n if (imp.source === '@embroider/macros') {\n continue;\n }\n let resolved = module.resolutions[imp.source];\n if (!resolved) {\n this.findings.push({\n filename,\n message: 'unable to resolve dependency',\n detail: imp.source,\n codeFrame: this.frames.render(imp.codeFrameIndex),\n });\n } else if (resolved) {\n let target = modules[resolved]!;\n for (let specifier of imp.specifiers) {\n if (target.type === 'complete' && !this.moduleProvidesName(target, specifier.name)) {\n if (specifier.name === 'default') {\n let backtick = '`';\n this.findings.push({\n filename,\n message: 'importing a non-existent default export',\n detail: `\"${imp.source}\" has no default export. Did you mean ${backtick}import * as ${specifier.local} from \"${imp.source}\"${backtick}?`,\n codeFrame: this.frames.render(specifier.codeFrameIndex),\n });\n } else {\n this.findings.push({\n filename,\n message: 'importing a non-existent named export',\n detail: `\"${imp.source}\" has no export named \"${specifier.name}\".`,\n codeFrame: this.frames.render(specifier.codeFrameIndex),\n });\n }\n }\n }\n }\n }\n }\n\n private moduleProvidesName(target: CompleteModule, name: string | NamespaceMarker) {\n // any module can provide a namespace.\n // CJS and AMD are too dynamic to be sure exactly what names are available,\n // so they always get a pass\n return isNamespaceMarker(name) || target.isCJS || target.isAMD || target.exports.includes(name);\n }\n\n private handleJSON(filename: string, content: Buffer | string): { content: string; type: ContentType } | undefined {\n let js;\n try {\n let structure = JSON.parse(content.toString('utf8'));\n js = `export default ${JSON.stringify(structure)}`;\n } catch (err) {\n this.findings.push({\n filename,\n message: `failed to parse JSON`,\n detail: err.toString().replace(filename, explicitRelative(this.originAppRoot, filename)),\n });\n return;\n }\n return { content: js, type: 'javascript' };\n }\n\n private pushFinding(finding: Finding) {\n this.findings.push(finding);\n }\n}\n\nfunction isMacrosPlugin(p: any) {\n return Array.isArray(p) && p[1] && p[1].embroiderMacrosConfigMarker;\n}\n\nfunction indent(str: string, level: number) {\n const spacesPerLevel = 2;\n let spaces = '';\n for (let i = 0; i < level * spacesPerLevel; i++) {\n spaces += ' ';\n }\n\n return str\n .split('\\n')\n .map(line => spaces + line)\n .join('\\n');\n}\n\nexport { Module };\n"]}
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["audit.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, readJSONSync } from 'fs-extra';\nimport { dirname, join, resolve as resolvePath } from 'path';\nimport type { AppMeta, ResolverOptions } from '@embroider/core';\nimport { explicitRelative, hbsToJS, locateEmbroiderWorkingDir, Resolver, RewrittenPackageCache } from '@embroider/core';\nimport { Memoize } from 'typescript-memoize';\nimport chalk from 'chalk';\nimport jsdom from 'jsdom';\nimport groupBy from 'lodash/groupBy';\nimport fromPairs from 'lodash/fromPairs';\nimport type { ExportAll, InternalImport, NamespaceMarker } from './audit/babel-visitor';\nimport { auditJS, CodeFrameStorage, isNamespaceMarker } from './audit/babel-visitor';\nimport { AuditBuildOptions, AuditOptions } from './audit/options';\nimport { buildApp, BuildError, isBuildError } from './audit/build';\n\nconst { JSDOM } = jsdom;\n\nexport interface AuditMessage {\n message: string;\n detail: string;\n loc: Loc;\n source: string;\n filename: string;\n}\n\nexport interface Loc {\n start: { line: number; column: number };\n end: { line: number; column: number };\n}\n\nexport { AuditOptions, AuditBuildOptions, BuildError, isBuildError };\n\nexport interface Finding {\n message: string;\n filename: string;\n detail: string;\n codeFrame?: string;\n}\n\nexport interface Module {\n appRelativePath: string;\n consumedFrom: (string | RootMarker)[];\n imports: Import[];\n exports: string[];\n resolutions: { [source: string]: string | null };\n content: string;\n}\n\ninterface ResolutionFailure {\n isResolutionFailure: true;\n}\n\nfunction isResolutionFailure(result: string | ResolutionFailure | undefined): result is ResolutionFailure {\n return typeof result === 'object' && 'isResolutionFailure' in result;\n}\n\ninterface InternalModule {\n consumedFrom: (string | RootMarker)[];\n\n parsed?: {\n imports: InternalImport[];\n exports: Set<string | ExportAll>;\n isCJS: boolean;\n isAMD: boolean;\n dependencies: string[];\n transpiledContent: string | Buffer;\n };\n\n resolved?: Map<string, string | ResolutionFailure>;\n\n linked?: {\n exports: Set<string>;\n };\n}\n\ntype ParsedInternalModule = Omit<InternalModule, 'parsed'> & {\n parsed: NonNullable<InternalModule['parsed']>;\n};\n\ntype ResolvedInternalModule = Omit<ParsedInternalModule, 'resolved'> & {\n resolved: NonNullable<ParsedInternalModule['resolved']>;\n};\n\nfunction isResolved(module: InternalModule | undefined): module is ResolvedInternalModule {\n return Boolean(module?.parsed && module.resolved);\n}\n\ntype LinkedInternalModule = Omit<ResolvedInternalModule, 'linked'> & {\n linked: NonNullable<ResolvedInternalModule['linked']>;\n};\n\nfunction isLinked(module: InternalModule | undefined): module is LinkedInternalModule {\n return Boolean(module?.parsed && module.resolved && module.linked);\n}\n\nexport interface Import {\n source: string;\n specifiers: {\n name: string | NamespaceMarker;\n local: string | null; // can be null when re-exporting, because in that case we import `name` from `source` but don't create any local binding for it\n }[];\n}\n\nexport class AuditResults {\n modules: { [file: string]: Module } = {};\n findings: Finding[] = [];\n\n static create(baseDir: string, findings: Finding[], modules: Map<string, InternalModule>) {\n let results = new this();\n for (let [filename, module] of modules) {\n let publicModule: Module = {\n appRelativePath: explicitRelative(baseDir, filename),\n consumedFrom: module.consumedFrom.map(entry => {\n if (isRootMarker(entry)) {\n return entry;\n } else {\n return explicitRelative(baseDir, entry);\n }\n }),\n resolutions: module.resolved\n ? fromPairs(\n [...module.resolved].map(([source, target]) => [\n source,\n isResolutionFailure(target) ? null : explicitRelative(baseDir, target),\n ])\n )\n : {},\n imports: module.parsed?.imports\n ? module.parsed.imports.map(i => ({\n source: i.source,\n specifiers: i.specifiers.map(s => ({\n name: s.name,\n local: s.local,\n })),\n }))\n : [],\n exports: module.linked?.exports ? [...module.linked.exports] : [],\n content: module.parsed?.transpiledContent\n ? module.parsed?.transpiledContent.toString()\n : 'module failed to transpile',\n };\n results.modules[explicitRelative(baseDir, filename)] = publicModule;\n }\n for (let finding of findings) {\n let relFinding = Object.assign({}, finding, { filename: explicitRelative(baseDir, finding.filename) });\n results.findings.push(relFinding);\n }\n return results;\n }\n\n humanReadable(): string {\n let output = [] as string[];\n let findingsByFile = groupBy(this.findings, f => f.filename);\n output.push(`=== Audit Results ===`);\n for (let [filename, findings] of Object.entries(findingsByFile)) {\n output.push(`${chalk.yellow(filename)}`);\n for (let finding of findings) {\n output.push(indent(chalk.red(finding.message) + ': ' + finding.detail, 1));\n if (finding.codeFrame) {\n output.push(indent(finding.codeFrame, 2));\n }\n }\n output.push(indent(chalk.blueBright(`file was included because:`), 1));\n let pointer: string | RootMarker = filename;\n while (!isRootMarker(pointer)) {\n // the zero here means we only display the first path we found. I think\n // that's a fine tradeoff to keep the output smaller.\n let nextPointer: string | RootMarker | undefined = this.modules[pointer]?.consumedFrom[0];\n if (!nextPointer) {\n output.push(\n indent(\n chalk.red(`couldn't figure out why this was included. Please file a bug against @embroider/compat.`),\n 2\n )\n );\n break;\n }\n if (isRootMarker(nextPointer)) {\n output.push(indent('packageJSON.ember-addon.assets', 2));\n } else {\n output.push(indent(nextPointer, 2));\n }\n pointer = nextPointer;\n }\n }\n let summaryColor;\n if (this.perfect) {\n summaryColor = chalk.green;\n } else {\n summaryColor = chalk.yellow;\n }\n output.push(summaryColor(`${this.findings.length} issues found`));\n output.push(`=== End Audit Results ===`);\n output.push(''); // always end with a newline because `yarn run` can overwrite our last line otherwise\n return output.join('\\n');\n }\n\n get perfect() {\n return this.findings.length === 0;\n }\n}\n\nexport class Audit {\n private modules: Map<string, InternalModule> = new Map();\n private virtualModules: Map<string, string> = new Map();\n private moduleQueue = new Set<string>();\n private findings = [] as Finding[];\n\n private frames = new CodeFrameStorage();\n\n static async run(options: AuditBuildOptions): Promise<AuditResults> {\n if (!options['reuse-build']) {\n await buildApp(options);\n }\n\n let audit = new this(options.app, options);\n if (options['reuse-build']) {\n if (!audit.meta.babel.isParallelSafe) {\n throw new BuildError(\n `You can't use the ${chalk.red(\n '--reuse-build'\n )} option because some of your babel or HBS plugins are non-serializable`\n );\n }\n }\n return audit.run();\n }\n\n constructor(private originAppRoot: string, private options: AuditOptions = {}) {}\n\n @Memoize()\n private get pkg() {\n return readJSONSync(join(this.movedAppRoot, 'package.json'));\n }\n\n @Memoize()\n private get movedAppRoot() {\n let cache = RewrittenPackageCache.shared('embroider', this.originAppRoot);\n return cache.maybeMoved(cache.get(this.originAppRoot)).root;\n }\n\n private get meta() {\n return this.pkg['ember-addon'] as AppMeta;\n }\n\n @Memoize()\n private get babelConfig() {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n let config = require(join(this.movedAppRoot, this.meta.babel.filename));\n config = Object.assign({}, config);\n config.plugins = config.plugins.filter((p: any) => !isMacrosPlugin(p));\n\n config.ast = true;\n return config;\n }\n\n private get resolverParams(): ResolverOptions {\n return readJSONSync(join(locateEmbroiderWorkingDir(this.originAppRoot), 'resolver.json'));\n }\n\n private resolver = new Resolver(this.resolverParams);\n\n private debug(message: string, ...args: any[]) {\n if (this.options.debug) {\n console.log(message, ...args);\n }\n }\n\n private visitorFor(\n filename: string\n ): (\n this: Audit,\n filename: string,\n content: Buffer | string\n ) => Promise<NonNullable<InternalModule['parsed']> | Finding[]> {\n if (filename.endsWith('.html')) {\n return this.visitHTML;\n } else if (filename.endsWith('.hbs')) {\n return this.visitHBS;\n } else if (filename.endsWith('.json')) {\n return this.visitJSON;\n } else {\n return this.visitJS;\n }\n }\n\n private async drainQueue() {\n while (this.moduleQueue.size > 0) {\n let filename = this.moduleQueue.values().next().value as string;\n this.moduleQueue.delete(filename);\n this.debug('visit', filename);\n let visitor = this.visitorFor(filename);\n let content: string | Buffer;\n if (this.virtualModules.has(filename)) {\n content = this.virtualModules.get(filename)!;\n } else {\n content = readFileSync(filename);\n }\n // cast is safe because the only way to get into the queue is to go\n // through scheduleVisit, and scheduleVisit creates the entry in\n // this.modules.\n let module: InternalModule = this.modules.get(filename)!;\n let visitResult = await visitor.call(this, filename, content);\n if (Array.isArray(visitResult)) {\n // the visitor was unable to figure out the ParseFields and returned\n // some number of Findings to us to explain why.\n for (let finding of visitResult) {\n this.pushFinding(finding);\n }\n } else {\n module.parsed = visitResult;\n module.resolved = await this.resolveDeps(visitResult.dependencies, filename);\n }\n }\n }\n\n async run(): Promise<AuditResults> {\n (globalThis as any).embroider_audit = this.handleResolverError.bind(this);\n\n try {\n this.debug(`meta`, this.meta);\n for (let asset of this.meta.assets) {\n if (asset.endsWith('.html')) {\n this.scheduleVisit(resolvePath(this.movedAppRoot, asset), { isRoot: true });\n }\n }\n await this.drainQueue();\n this.linkModules();\n this.inspectModules();\n\n return AuditResults.create(this.originAppRoot, this.findings, this.modules);\n } finally {\n delete (globalThis as any).embroider_audit;\n }\n }\n\n private handleResolverError(msg: AuditMessage) {\n this.pushFinding({\n message: msg.message,\n filename: msg.filename,\n detail: msg.detail,\n codeFrame: this.frames.render(this.frames.forSource(msg.source)(msg)),\n });\n }\n\n private linkModules() {\n for (let module of this.modules.values()) {\n if (isResolved(module)) {\n this.linkModule(module);\n }\n }\n }\n\n private linkModule(module: ResolvedInternalModule) {\n let exports = new Set<string>();\n for (let exp of module.parsed.exports) {\n if (typeof exp === 'string') {\n exports.add(exp);\n } else {\n let moduleName = module.resolved.get(exp.all)!;\n if (!isResolutionFailure(moduleName)) {\n let target = this.modules.get(moduleName)!;\n if (!isLinked(target) && isResolved(target)) {\n this.linkModule(target);\n }\n if (isLinked(target)) {\n for (let innerExp of target.linked.exports) {\n exports.add(innerExp);\n }\n } else {\n // our module doesn't successfully enter linked state because it\n // depends on stuff that also couldn't\n return;\n }\n }\n }\n }\n module.linked = {\n exports,\n };\n }\n\n private inspectModules() {\n for (let [filename, module] of this.modules) {\n if (isLinked(module)) {\n this.inspectImports(filename, module);\n }\n }\n }\n\n private inspectImports(filename: string, module: LinkedInternalModule) {\n for (let imp of module.parsed.imports) {\n let resolved = module.resolved.get(imp.source);\n if (isResolutionFailure(resolved)) {\n this.findings.push({\n filename,\n message: 'unable to resolve dependency',\n detail: imp.source,\n codeFrame: this.frames.render(imp.codeFrameIndex),\n });\n } else if (resolved) {\n let target = this.modules.get(resolved)!;\n for (let specifier of imp.specifiers) {\n if (isLinked(target) && !this.moduleProvidesName(target, specifier.name)) {\n if (specifier.name === 'default') {\n let backtick = '`';\n this.findings.push({\n filename,\n message: 'importing a non-existent default export',\n detail: `\"${imp.source}\" has no default export. Did you mean ${backtick}import * as ${specifier.local} from \"${imp.source}\"${backtick}?`,\n codeFrame: this.frames.render(specifier.codeFrameIndex),\n });\n } else {\n this.findings.push({\n filename,\n message: 'importing a non-existent named export',\n detail: `\"${imp.source}\" has no export named \"${specifier.name}\".`,\n codeFrame: this.frames.render(specifier.codeFrameIndex),\n });\n }\n }\n }\n }\n }\n }\n\n private moduleProvidesName(target: LinkedInternalModule, name: string | NamespaceMarker) {\n // any module can provide a namespace.\n // CJS and AMD are too dynamic to be sure exactly what names are available,\n // so they always get a pass\n return isNamespaceMarker(name) || target.parsed.isCJS || target.parsed.isAMD || target.linked.exports.has(name);\n }\n\n private async visitHTML(filename: string, content: Buffer | string): Promise<ParsedInternalModule['parsed']> {\n let dom = new JSDOM(content);\n let scripts = dom.window.document.querySelectorAll('script[type=\"module\"]') as NodeListOf<HTMLScriptElement>;\n let dependencies = [] as string[];\n for (let script of scripts) {\n let src = script.src;\n if (!src) {\n continue;\n }\n if (new URL(src, 'http://example.com:4321').origin !== 'http://example.com:4321') {\n // src was absolute, we don't handle it\n continue;\n }\n if (src.startsWith(this.meta['root-url'])) {\n // root-relative URLs are actually relative to the appDir\n src = explicitRelative(\n dirname(filename),\n resolvePath(this.movedAppRoot, src.replace(this.meta['root-url'], ''))\n );\n }\n dependencies.push(src);\n }\n\n return {\n imports: [],\n exports: new Set(),\n isCJS: false,\n isAMD: false,\n dependencies,\n transpiledContent: content,\n };\n }\n\n private async visitJS(\n filename: string,\n content: Buffer | string\n ): Promise<ParsedInternalModule['parsed'] | Finding[]> {\n let rawSource = content.toString('utf8');\n try {\n let result = auditJS(rawSource, filename, this.babelConfig, this.frames);\n\n for (let problem of result.problems) {\n this.pushFinding({\n filename,\n message: problem.message,\n detail: problem.detail,\n codeFrame: this.frames.render(problem.codeFrameIndex),\n });\n }\n return {\n exports: result.exports,\n imports: result.imports,\n isCJS: result.isCJS,\n isAMD: result.isAMD,\n dependencies: result.imports.map(i => i.source),\n transpiledContent: result.transpiledContent,\n };\n } catch (err) {\n if (['BABEL_PARSE_ERROR', 'BABEL_TRANSFORM_ERROR'].includes(err.code)) {\n return [\n {\n filename,\n message: `failed to parse`,\n detail: err.toString().replace(filename, explicitRelative(this.originAppRoot, filename)),\n },\n ];\n } else {\n throw err;\n }\n }\n }\n\n private async visitHBS(\n filename: string,\n content: Buffer | string\n ): Promise<ParsedInternalModule['parsed'] | Finding[]> {\n let rawSource = content.toString('utf8');\n let js = hbsToJS(rawSource);\n return this.visitJS(filename, js);\n }\n\n private async visitJSON(\n filename: string,\n content: Buffer | string\n ): Promise<ParsedInternalModule['parsed'] | Finding[]> {\n let js;\n try {\n let structure = JSON.parse(content.toString('utf8'));\n js = `export default ${JSON.stringify(structure)}`;\n } catch (err) {\n return [\n {\n filename,\n message: `failed to parse JSON`,\n detail: err.toString().replace(filename, explicitRelative(this.originAppRoot, filename)),\n },\n ];\n }\n return this.visitJS(filename, js);\n }\n\n private async resolveDeps(deps: string[], fromFile: string): Promise<InternalModule['resolved']> {\n let resolved = new Map() as NonNullable<InternalModule['resolved']>;\n for (let dep of deps) {\n let resolution = await this.resolver.nodeResolve(dep, fromFile);\n switch (resolution.type) {\n case 'virtual':\n this.virtualModules.set(resolution.filename, resolution.content);\n resolved.set(dep, resolution.filename);\n this.scheduleVisit(resolution.filename, fromFile);\n break;\n case 'not_found':\n if (['@embroider/macros', '@ember/template-factory'].includes(dep)) {\n // the audit process deliberately removes the @embroider/macros babel\n // plugins, so the imports are still present and should be left alone.\n continue;\n }\n resolved.set(dep, { isResolutionFailure: true as true });\n break;\n case 'real':\n resolved.set(dep, resolution.filename);\n this.scheduleVisit(resolution.filename, fromFile);\n break;\n }\n }\n return resolved;\n }\n\n private pushFinding(finding: Finding) {\n this.findings.push(finding);\n }\n\n private scheduleVisit(filename: string, parent: string | RootMarker) {\n let record = this.modules.get(filename);\n if (!record) {\n this.debug(`discovered`, filename);\n record = {\n consumedFrom: [parent],\n };\n this.modules.set(filename, record);\n this.moduleQueue.add(filename);\n } else {\n record.consumedFrom.push(parent);\n }\n }\n}\n\nfunction isMacrosPlugin(p: any) {\n return Array.isArray(p) && p[1] && p[1].embroiderMacrosConfigMarker;\n}\n\nfunction indent(str: string, level: number) {\n const spacesPerLevel = 2;\n let spaces = '';\n for (let i = 0; i < level * spacesPerLevel; i++) {\n spaces += ' ';\n }\n\n return str\n .split('\\n')\n .map(line => spaces + line)\n .join('\\n');\n}\n\nexport interface RootMarker {\n isRoot: true;\n}\n\nexport function isRootMarker(value: string | RootMarker | undefined): value is RootMarker {\n return Boolean(value && typeof value !== 'string' && value.isRoot);\n}\n"]}