@embroider/compat 3.5.1-unstable.e01da0a → 3.5.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 (83) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +13 -13
  3. package/src/audit/babel-visitor.js +3 -5
  4. package/src/audit/babel-visitor.js.map +1 -1
  5. package/src/audit/build.js.map +1 -1
  6. package/src/audit-cli.js.map +1 -1
  7. package/src/audit.d.ts +54 -6
  8. package/src/audit.js +275 -86
  9. package/src/audit.js.map +1 -1
  10. package/src/babel-plugin-adjust-imports.d.ts +1 -2
  11. package/src/babel-plugin-adjust-imports.js +1 -1
  12. package/src/babel-plugin-adjust-imports.js.map +1 -1
  13. package/src/build-compat-addon.js.map +1 -1
  14. package/src/compat-adapters/@ember/test-waiters.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/ember-asset-loader.js.map +1 -1
  22. package/src/compat-adapters/ember-cli-babel.js.map +1 -1
  23. package/src/compat-adapters/ember-cli-fastboot.js.map +1 -1
  24. package/src/compat-adapters/ember-cli-mirage.js.map +1 -1
  25. package/src/compat-adapters/ember-composable-helpers.js.map +1 -1
  26. package/src/compat-adapters/ember-data.js.map +1 -1
  27. package/src/compat-adapters/ember-engines.js.map +1 -1
  28. package/src/compat-adapters/ember-macro-helpers.js.map +1 -1
  29. package/src/compat-adapters/ember-scroll-modifiers.js.map +1 -1
  30. package/src/compat-adapters/ember-source.js.map +1 -1
  31. package/src/compat-adapters/ember-svg-jar.js.map +1 -1
  32. package/src/compat-addons.js.map +1 -1
  33. package/src/compat-app-builder.d.ts +19 -7
  34. package/src/compat-app-builder.js +667 -73
  35. package/src/compat-app-builder.js.map +1 -1
  36. package/src/compat-app.d.ts +4 -2
  37. package/src/compat-app.js +24 -60
  38. package/src/compat-app.js.map +1 -1
  39. package/src/compat-utils.js.map +1 -1
  40. package/src/dasherize-component-name.js.map +1 -1
  41. package/src/default-pipeline.d.ts +2 -2
  42. package/src/default-pipeline.js +1 -22
  43. package/src/default-pipeline.js.map +1 -1
  44. package/src/dependency-rules.js.map +1 -1
  45. package/src/detect-babel-plugins.js.map +1 -1
  46. package/src/detect-compact-reexports.js.map +1 -1
  47. package/src/dummy-package.js.map +1 -1
  48. package/src/empty-package-tree.js.map +1 -1
  49. package/src/get-real-addon.js.map +1 -1
  50. package/src/hbs-to-js-broccoli-plugin.js.map +1 -1
  51. package/src/index.d.ts +1 -1
  52. package/src/index.js +1 -2
  53. package/src/index.js.map +1 -1
  54. package/src/merges.js.map +1 -1
  55. package/src/options.d.ts +0 -1
  56. package/src/options.js +0 -1
  57. package/src/options.js.map +1 -1
  58. package/src/prepare-htmlbars-ast-plugins.js.map +1 -1
  59. package/src/rename-require-plugin.js.map +1 -1
  60. package/src/resolver-transform.js +0 -3
  61. package/src/resolver-transform.js.map +1 -1
  62. package/src/rewrite-addon-tree.js.map +1 -1
  63. package/src/smoosh-package-json.js.map +1 -1
  64. package/src/snitch.js.map +1 -1
  65. package/src/standalone-addon-build.js.map +1 -1
  66. package/src/sync-dir.js.map +1 -1
  67. package/src/synthesize-template-only-components.js.map +1 -1
  68. package/src/v1-addon.js.map +1 -1
  69. package/src/v1-appboot.js.map +1 -1
  70. package/src/v1-config.js.map +1 -1
  71. package/src/v1-instance-cache.js.map +1 -1
  72. package/src/compat-adapters/ember-fetch.d.ts +0 -5
  73. package/src/compat-adapters/ember-fetch.js +0 -19
  74. package/src/compat-adapters/ember-fetch.js.map +0 -1
  75. package/src/content-for-config.d.ts +0 -11
  76. package/src/content-for-config.js +0 -66
  77. package/src/content-for-config.js.map +0 -1
  78. package/src/http-audit.d.ts +0 -13
  79. package/src/http-audit.js +0 -46
  80. package/src/http-audit.js.map +0 -1
  81. package/src/module-visitor.d.ts +0 -53
  82. package/src/module-visitor.js +0 -286
  83. package/src/module-visitor.js.map +0 -1
@@ -1,21 +1,49 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
2
18
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
19
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
20
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
21
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
22
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
23
  };
24
+ var __importStar = (this && this.__importStar) || function (mod) {
25
+ if (mod && mod.__esModule) return mod;
26
+ var result = {};
27
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
28
+ __setModuleDefault(result, mod);
29
+ return result;
30
+ };
8
31
  var __importDefault = (this && this.__importDefault) || function (mod) {
9
32
  return (mod && mod.__esModule) ? mod : { "default": mod };
10
33
  };
11
34
  Object.defineProperty(exports, "__esModule", { value: true });
12
35
  exports.CompatAppBuilder = void 0;
13
36
  const core_1 = require("@embroider/core");
37
+ const walk_sync_1 = __importDefault(require("walk-sync"));
14
38
  const path_1 = require("path");
15
39
  const dependency_rules_1 = require("./dependency-rules");
16
40
  const flatMap_1 = __importDefault(require("lodash/flatMap"));
41
+ const sortBy_1 = __importDefault(require("lodash/sortBy"));
42
+ const flatten_1 = __importDefault(require("lodash/flatten"));
43
+ const partition_1 = __importDefault(require("lodash/partition"));
17
44
  const mergeWith_1 = __importDefault(require("lodash/mergeWith"));
18
45
  const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
46
+ const resolve_1 = require("resolve");
19
47
  const bind_decorator_1 = __importDefault(require("bind-decorator"));
20
48
  const fs_extra_1 = require("fs-extra");
21
49
  const ember_html_1 = require("@embroider/core/src/ember-html");
@@ -25,22 +53,22 @@ const portable_1 = require("@embroider/core/src/portable");
25
53
  const assert_never_1 = __importDefault(require("assert-never"));
26
54
  const typescript_memoize_1 = require("typescript-memoize");
27
55
  const path_2 = require("path");
28
- const resolve_1 = __importDefault(require("resolve"));
56
+ const resolve_2 = __importDefault(require("resolve"));
29
57
  const fs_extra_2 = require("fs-extra");
30
58
  const node_1 = require("@embroider/macros/src/node");
59
+ const fast_sourcemap_concat_1 = __importDefault(require("fast-sourcemap-concat"));
31
60
  const escape_string_regexp_1 = __importDefault(require("escape-string-regexp"));
32
61
  const sync_dir_1 = require("./sync-dir");
33
62
  // This exists during the actual broccoli build step. As opposed to CompatApp,
34
63
  // which also exists during pipeline-construction time.
35
64
  class CompatAppBuilder {
36
- constructor(root, origAppPackage, appPackageWithMovedDeps, options, compatApp, configTree, contentForTree, synthVendor, synthStyles) {
65
+ constructor(root, origAppPackage, appPackageWithMovedDeps, options, compatApp, configTree, synthVendor, synthStyles) {
37
66
  this.root = root;
38
67
  this.origAppPackage = origAppPackage;
39
68
  this.appPackageWithMovedDeps = appPackageWithMovedDeps;
40
69
  this.options = options;
41
70
  this.compatApp = compatApp;
42
71
  this.configTree = configTree;
43
- this.contentForTree = contentForTree;
44
72
  this.synthVendor = synthVendor;
45
73
  this.synthStyles = synthStyles;
46
74
  // for each relativePath, an Asset we have already emitted
@@ -55,11 +83,52 @@ class CompatAppBuilder {
55
83
  }
56
84
  extractAssets(treePaths) {
57
85
  let assets = [];
86
+ // Everything in our traditional public tree is an on-disk asset
87
+ if (treePaths.publicTree) {
88
+ walk_sync_1.default
89
+ .entries(treePaths.publicTree, {
90
+ directories: false,
91
+ })
92
+ .forEach(entry => {
93
+ assets.push({
94
+ kind: 'on-disk',
95
+ relativePath: entry.relativePath,
96
+ sourcePath: entry.fullPath,
97
+ mtime: entry.mtime,
98
+ size: entry.size,
99
+ });
100
+ });
101
+ }
102
+ // ember-cli traditionally outputs a dummy testem.js file to prevent
103
+ // spurious errors when running tests under "ember s".
104
+ if (this.compatApp.shouldBuildTests) {
105
+ let testemAsset = this.findTestemAsset();
106
+ if (testemAsset) {
107
+ assets.push(testemAsset);
108
+ }
109
+ }
58
110
  for (let asset of this.emberEntrypoints(treePaths.htmlTree)) {
59
111
  assets.push(asset);
60
112
  }
61
113
  return assets;
62
114
  }
115
+ findTestemAsset() {
116
+ let sourcePath;
117
+ try {
118
+ sourcePath = (0, resolve_1.sync)('ember-cli/lib/broccoli/testem.js', { basedir: this.root });
119
+ }
120
+ catch (err) { }
121
+ if (sourcePath) {
122
+ let stat = (0, fs_extra_1.statSync)(sourcePath);
123
+ return {
124
+ kind: 'on-disk',
125
+ relativePath: 'testem.js',
126
+ sourcePath,
127
+ mtime: stat.mtime.getTime(),
128
+ size: stat.size,
129
+ };
130
+ }
131
+ }
63
132
  activeAddonChildren(pkg) {
64
133
  let result = pkg.dependencies.filter(this.isActiveAddon).filter(
65
134
  // When looking for child addons, we want to ignore 'peerDependencies' of
@@ -108,7 +177,7 @@ class CompatAppBuilder {
108
177
  // For TS, we defer to ember-cli-babel, and the setting for
109
178
  // "enableTypescriptTransform" can be set with and without
110
179
  // ember-cli-typescript
111
- return ['.wasm', '.mjs', '.js', '.json', '.ts', '.hbs', '.hbs.js', '.gjs', '.gts'];
180
+ return ['.wasm', '.mjs', '.js', '.json', '.ts', '.hbs', '.hbs.js'];
112
181
  }
113
182
  *emberEntrypoints(htmlTreePath) {
114
183
  let classicEntrypoints = [
@@ -131,10 +200,15 @@ class CompatAppBuilder {
131
200
  rootURL: this.rootURL(),
132
201
  prepare: (dom) => {
133
202
  let scripts = [...dom.window.document.querySelectorAll('script')];
203
+ let styles = [...dom.window.document.querySelectorAll('link[rel*="stylesheet"]')];
134
204
  return {
135
205
  javascript: this.compatApp.findAppScript(scripts, entrypoint),
206
+ styles: this.compatApp.findAppStyles(styles, entrypoint),
136
207
  implicitScripts: this.compatApp.findVendorScript(scripts, entrypoint),
208
+ implicitStyles: this.compatApp.findVendorStyles(styles, entrypoint),
137
209
  testJavascript: this.compatApp.findTestScript(scripts),
210
+ implicitTestScripts: this.compatApp.findTestSupportScript(scripts),
211
+ implicitTestStyles: this.compatApp.findTestSupportStyles(styles),
138
212
  };
139
213
  },
140
214
  };
@@ -159,6 +233,10 @@ class CompatAppBuilder {
159
233
  resolverConfig(engines) {
160
234
  let renamePackages = Object.assign({}, ...this.allActiveAddons.map(dep => dep.meta['renamed-packages']));
161
235
  let renameModules = Object.assign({}, ...this.allActiveAddons.map(dep => dep.meta['renamed-modules']));
236
+ let activeAddons = {};
237
+ for (let addon of this.allActiveAddons) {
238
+ activeAddons[addon.name] = addon.root;
239
+ }
162
240
  let options = {
163
241
  staticHelpers: this.options.staticHelpers,
164
242
  staticModifiers: this.options.staticModifiers,
@@ -167,6 +245,7 @@ class CompatAppBuilder {
167
245
  };
168
246
  let config = {
169
247
  // this part is the base ModuleResolverOptions as required by @embroider/core
248
+ activeAddons,
170
249
  renameModules,
171
250
  renamePackages,
172
251
  resolvableExtensions: this.resolvableExtensions(),
@@ -178,34 +257,118 @@ class CompatAppBuilder {
178
257
  root: (0, fs_extra_1.realpathSync)(index === 0 ? this.root : appFiles.engine.package.root),
179
258
  fastbootFiles: appFiles.fastbootFiles,
180
259
  activeAddons: [...appFiles.engine.addons]
181
- .map(([addon, canResolveFromFile]) => ({
182
- name: addon.name,
183
- root: addon.root,
184
- canResolveFromFile,
260
+ .map(a => ({
261
+ name: a.name,
262
+ root: a.root,
185
263
  }))
186
264
  // the traditional order is the order in which addons will run, such
187
265
  // that the last one wins. Our resolver's order is the order to
188
266
  // search, so first one wins.
189
267
  .reverse(),
190
- isLazy: appFiles.engine.package.isLazyEngine(),
191
268
  })),
192
269
  amdCompatibility: this.options.amdCompatibility,
193
270
  // this is the additional stufff that @embroider/compat adds on top to do
194
271
  // global template resolving
195
272
  modulePrefix: this.modulePrefix(),
196
- splitAtRoutes: this.options.splitAtRoutes,
197
273
  podModulePrefix: this.podModulePrefix(),
198
274
  activePackageRules: this.activeRules(),
199
275
  options,
200
- autoRun: this.compatApp.autoRun,
201
- staticAppPaths: this.options.staticAppPaths,
202
276
  };
203
277
  return config;
204
278
  }
279
+ scriptPriority(pkg) {
280
+ switch (pkg.name) {
281
+ case 'loader.js':
282
+ return 0;
283
+ case 'ember-source':
284
+ return 10;
285
+ default:
286
+ return 1000;
287
+ }
288
+ }
205
289
  get resolvableExtensionsPattern() {
206
290
  return (0, core_1.extensionsPattern)(this.resolvableExtensions());
207
291
  }
208
- async babelConfig(resolverConfig) {
292
+ impliedAssets(type, engine, emberENV) {
293
+ let result = this.impliedAddonAssets(type, engine).map((sourcePath) => {
294
+ let stats = (0, fs_extra_1.statSync)(sourcePath);
295
+ return {
296
+ kind: 'on-disk',
297
+ relativePath: (0, core_1.explicitRelative)(this.root, sourcePath),
298
+ sourcePath,
299
+ mtime: stats.mtimeMs,
300
+ size: stats.size,
301
+ };
302
+ });
303
+ if (type === 'implicit-scripts') {
304
+ result.unshift({
305
+ kind: 'in-memory',
306
+ relativePath: '_testing_prefix_.js',
307
+ source: `var runningTests=false;`,
308
+ });
309
+ result.unshift({
310
+ kind: 'in-memory',
311
+ relativePath: '_ember_env_.js',
312
+ source: `window.EmberENV={ ...(window.EmberENV || {}), ...${JSON.stringify(emberENV, null, 2)} };`,
313
+ });
314
+ result.push({
315
+ kind: 'in-memory',
316
+ relativePath: '_loader_.js',
317
+ source: `loader.makeDefaultExport=false;`,
318
+ });
319
+ }
320
+ if (type === 'implicit-test-scripts') {
321
+ // this is the traditional test-support-suffix.js
322
+ result.push({
323
+ kind: 'in-memory',
324
+ relativePath: '_testing_suffix_.js',
325
+ source: `
326
+ var runningTests=true;
327
+ if (typeof Testem !== 'undefined' && (typeof QUnit !== 'undefined' || typeof Mocha !== 'undefined')) {
328
+ Testem.hookIntoTestFramework();
329
+ }`,
330
+ });
331
+ // whether or not anybody was actually using @embroider/macros
332
+ // explicitly as an addon, we ensure its test-support file is always
333
+ // present.
334
+ if (!result.find(s => s.kind === 'on-disk' && s.sourcePath.endsWith('embroider-macros-test-support.js'))) {
335
+ result.unshift({
336
+ kind: 'on-disk',
337
+ sourcePath: require.resolve('@embroider/macros/src/vendor/embroider-macros-test-support'),
338
+ mtime: 0,
339
+ size: 0,
340
+ relativePath: 'embroider-macros-test-support.js',
341
+ });
342
+ }
343
+ }
344
+ return result;
345
+ }
346
+ impliedAddonAssets(type, { engine }) {
347
+ let result = [];
348
+ for (let addon of (0, sortBy_1.default)(Array.from(engine.addons), this.scriptPriority.bind(this))) {
349
+ let implicitScripts = addon.meta[type];
350
+ if (implicitScripts) {
351
+ let styles = [];
352
+ let options = { basedir: addon.root };
353
+ for (let mod of implicitScripts) {
354
+ if (type === 'implicit-styles') {
355
+ // exclude engines because they will handle their own css importation
356
+ if (!addon.isLazyEngine()) {
357
+ styles.push(resolve_2.default.sync(mod, options));
358
+ }
359
+ }
360
+ else {
361
+ result.push(resolve_2.default.sync(mod, options));
362
+ }
363
+ }
364
+ if (styles.length) {
365
+ result = [...styles, ...result];
366
+ }
367
+ }
368
+ }
369
+ return result;
370
+ }
371
+ babelConfig(resolverConfig) {
209
372
  let babel = (0, cloneDeep_1.default)(this.compatApp.babelConfig());
210
373
  if (!babel.plugins) {
211
374
  babel.plugins = [];
@@ -215,10 +378,7 @@ class CompatAppBuilder {
215
378
  babel.plugins.push(require.resolve('@babel/plugin-syntax-dynamic-import'));
216
379
  // https://github.com/webpack/webpack/issues/12154
217
380
  babel.plugins.push(require.resolve('./rename-require-plugin'));
218
- babel.plugins.push([
219
- require.resolve('babel-plugin-ember-template-compilation'),
220
- await this.etcOptions(resolverConfig),
221
- ]);
381
+ babel.plugins.push([require.resolve('babel-plugin-ember-template-compilation'), this.etcOptions(resolverConfig)]);
222
382
  // this is @embroider/macros configured for full stage3 resolution
223
383
  babel.plugins.push(...this.compatApp.macrosConfig.babelPluginConfig());
224
384
  let colocationOptions = {
@@ -270,7 +430,7 @@ class CompatAppBuilder {
270
430
  addCachablePlugin(portable.config);
271
431
  return portable;
272
432
  }
273
- insertEmberApp(asset) {
433
+ insertEmberApp(asset, appFiles, prepared, emberENV) {
274
434
  let html = asset.html;
275
435
  if (this.fastbootConfig) {
276
436
  // ignore scripts like ember-cli-livereload.js which are not really associated with
@@ -280,6 +440,12 @@ class CompatAppBuilder {
280
440
  script.setAttribute('data-fastboot-ignore', '');
281
441
  });
282
442
  }
443
+ // our tests entrypoint already includes a correct module dependency on the
444
+ // app, so we only insert the app when we're not inserting tests
445
+ if (!asset.fileAsset.includeTests) {
446
+ let appJS = this.topAppJSAsset(appFiles, prepared);
447
+ html.insertScriptTag(html.javascript, appJS.relativePath, { type: 'module' });
448
+ }
283
449
  if (this.fastbootConfig) {
284
450
  // any extra fastboot app files get inserted into our html.javascript
285
451
  // section, after the app has been inserted.
@@ -287,6 +453,12 @@ class CompatAppBuilder {
287
453
  html.insertScriptTag(html.javascript, script, { tag: 'fastboot-script' });
288
454
  }
289
455
  }
456
+ html.insertStyleLink(html.styles, `assets/${this.origAppPackage.name}.css`);
457
+ const parentEngine = appFiles.find(e => !e.engine.parent);
458
+ let vendorJS = this.implicitScriptsAsset(prepared, parentEngine, emberENV);
459
+ if (vendorJS) {
460
+ html.insertScriptTag(html.implicitScripts, vendorJS.relativePath);
461
+ }
290
462
  if (this.fastbootConfig) {
291
463
  // any extra fastboot vendor files get inserted into our
292
464
  // html.implicitScripts section, after the regular implicit script
@@ -295,11 +467,69 @@ class CompatAppBuilder {
295
467
  html.insertScriptTag(html.implicitScripts, script, { tag: 'fastboot-script' });
296
468
  }
297
469
  }
470
+ let implicitStyles = this.implicitStylesAsset(prepared, parentEngine);
471
+ if (implicitStyles) {
472
+ html.insertStyleLink(html.implicitStyles, implicitStyles.relativePath);
473
+ }
298
474
  if (!asset.fileAsset.includeTests) {
299
475
  return;
300
476
  }
301
477
  // Test-related assets happen below this point
302
- html.insertScriptTag(html.javascript, '@embroider/core/test-entrypoint', { type: 'module' });
478
+ let testJS = this.testJSEntrypoint(appFiles, prepared);
479
+ html.insertScriptTag(html.testJavascript, testJS.relativePath, { type: 'module' });
480
+ let implicitTestScriptsAsset = this.implicitTestScriptsAsset(prepared, parentEngine);
481
+ if (implicitTestScriptsAsset) {
482
+ html.insertScriptTag(html.implicitTestScripts, implicitTestScriptsAsset.relativePath);
483
+ }
484
+ let implicitTestStylesAsset = this.implicitTestStylesAsset(prepared, parentEngine);
485
+ if (implicitTestStylesAsset) {
486
+ html.insertStyleLink(html.implicitTestStyles, implicitTestStylesAsset.relativePath);
487
+ }
488
+ }
489
+ implicitScriptsAsset(prepared, application, emberENV) {
490
+ let asset = prepared.get('assets/vendor.js');
491
+ if (!asset) {
492
+ let implicitScripts = this.impliedAssets('implicit-scripts', application, emberENV);
493
+ if (implicitScripts.length > 0) {
494
+ asset = new ConcatenatedAsset('assets/vendor.js', implicitScripts, this.resolvableExtensionsPattern);
495
+ prepared.set(asset.relativePath, asset);
496
+ }
497
+ }
498
+ return asset;
499
+ }
500
+ implicitStylesAsset(prepared, application) {
501
+ let asset = prepared.get('assets/vendor.css');
502
+ if (!asset) {
503
+ let implicitStyles = this.impliedAssets('implicit-styles', application);
504
+ if (implicitStyles.length > 0) {
505
+ // we reverse because we want the synthetic vendor style at the top
506
+ asset = new ConcatenatedAsset('assets/vendor.css', implicitStyles.reverse(), this.resolvableExtensionsPattern);
507
+ prepared.set(asset.relativePath, asset);
508
+ }
509
+ }
510
+ return asset;
511
+ }
512
+ implicitTestScriptsAsset(prepared, application) {
513
+ let testSupportJS = prepared.get('assets/test-support.js');
514
+ if (!testSupportJS) {
515
+ let implicitTestScripts = this.impliedAssets('implicit-test-scripts', application);
516
+ if (implicitTestScripts.length > 0) {
517
+ testSupportJS = new ConcatenatedAsset('assets/test-support.js', implicitTestScripts, this.resolvableExtensionsPattern);
518
+ prepared.set(testSupportJS.relativePath, testSupportJS);
519
+ }
520
+ }
521
+ return testSupportJS;
522
+ }
523
+ implicitTestStylesAsset(prepared, application) {
524
+ let asset = prepared.get('assets/test-support.css');
525
+ if (!asset) {
526
+ let implicitTestStyles = this.impliedAssets('implicit-test-styles', application);
527
+ if (implicitTestStyles.length > 0) {
528
+ asset = new ConcatenatedAsset('assets/test-support.css', implicitTestStyles, this.resolvableExtensionsPattern);
529
+ prepared.set(asset.relativePath, asset);
530
+ }
531
+ }
532
+ return asset;
303
533
  }
304
534
  // recurse to find all active addons that don't cross an engine boundary.
305
535
  // Inner engines themselves will be returned, but not those engines' children.
@@ -310,31 +540,22 @@ class CompatAppBuilder {
310
540
  if (!child.isEngine()) {
311
541
  this.findActiveAddons(child, engine, true);
312
542
  }
313
- let canResolveFrom;
314
- if (pkg === this.appPackageWithMovedDeps) {
315
- // we want canResolveFrom to always be a rewritten package path, and our
316
- // app's package is not rewritten yet here.
317
- canResolveFrom = (0, path_1.resolve)(this.root, 'package.json');
318
- }
319
- else {
320
- // whereas our addons are already moved
321
- canResolveFrom = (0, path_1.resolve)(pkg.root, 'package.json');
322
- }
323
- engine.addons.set(child, canResolveFrom);
543
+ engine.addons.add(child);
324
544
  }
325
545
  // ensure addons are applied in the correct order, if set (via @embroider/compat/v1-addon)
326
546
  if (!isChild) {
327
- engine.addons = new Map([...engine.addons].sort(([a], [b]) => {
547
+ engine.addons = new Set([...engine.addons].sort((a, b) => {
328
548
  return (a.meta['order-index'] || 0) - (b.meta['order-index'] || 0);
329
549
  }));
330
550
  }
331
551
  }
332
- partitionEngines() {
552
+ partitionEngines(appJSPath) {
333
553
  let queue = [
334
554
  {
335
555
  package: this.appPackageWithMovedDeps,
336
- addons: new Map(),
337
- isApp: true,
556
+ addons: new Set(),
557
+ parent: undefined,
558
+ sourcePath: appJSPath,
338
559
  modulePrefix: this.modulePrefix(),
339
560
  appRelativePath: '.',
340
561
  },
@@ -347,13 +568,14 @@ class CompatAppBuilder {
347
568
  break;
348
569
  }
349
570
  this.findActiveAddons(current.package, current);
350
- for (let addon of current.addons.keys()) {
571
+ for (let addon of current.addons) {
351
572
  if (addon.isEngine() && !seenEngines.has(addon)) {
352
573
  seenEngines.add(addon);
353
574
  queue.push({
354
575
  package: addon,
355
- addons: new Map(),
356
- isApp: !current,
576
+ addons: new Set(),
577
+ parent: current,
578
+ sourcePath: addon.root,
357
579
  modulePrefix: addon.name,
358
580
  appRelativePath: (0, core_1.explicitRelative)(this.root, addon.root),
359
581
  });
@@ -379,8 +601,8 @@ class CompatAppBuilder {
379
601
  updateAppJS(appJSPath) {
380
602
  var _a;
381
603
  if (!this.engines) {
382
- this.engines = this.partitionEngines().map(engine => {
383
- if (engine.isApp) {
604
+ this.engines = this.partitionEngines(appJSPath).map(engine => {
605
+ if (engine.sourcePath === appJSPath) {
384
606
  // this is the app. We have more to do for the app than for other
385
607
  // engines.
386
608
  let fastbootSync;
@@ -402,7 +624,7 @@ class CompatAppBuilder {
402
624
  // their files, not doing any actual copying or building.
403
625
  return {
404
626
  engine,
405
- appSync: new sync_dir_1.SyncDir(engine.package.root, undefined),
627
+ appSync: new sync_dir_1.SyncDir(engine.sourcePath, undefined),
406
628
  // AFAIK, we've never supported a fastboot overlay directory in an
407
629
  // engine. But if we do need that, it would go here.
408
630
  fastbootSync: undefined,
@@ -416,15 +638,10 @@ class CompatAppBuilder {
416
638
  }
417
639
  return this.engines.map(({ engine, appSync, fastbootSync }) => {
418
640
  var _a;
419
- return new app_files_1.AppFiles(engine, appSync.files, (_a = fastbootSync === null || fastbootSync === void 0 ? void 0 : fastbootSync.files) !== null && _a !== void 0 ? _a : new Set(), this.resolvableExtensionsPattern, this.staticAppPathsPattern, this.podModulePrefix());
641
+ return new app_files_1.AppFiles(engine, appSync.files, (_a = fastbootSync === null || fastbootSync === void 0 ? void 0 : fastbootSync.files) !== null && _a !== void 0 ? _a : new Set(), this.resolvableExtensionsPattern, this.podModulePrefix());
420
642
  });
421
643
  }
422
- get staticAppPathsPattern() {
423
- if (this.options.staticAppPaths.length > 0) {
424
- return new RegExp('^(?:' + this.options.staticAppPaths.map(staticAppPath => (0, escape_string_regexp_1.default)(staticAppPath)).join('|') + ')(?:$|/)');
425
- }
426
- }
427
- prepareAsset(asset, prepared) {
644
+ prepareAsset(asset, appFiles, prepared, emberENV) {
428
645
  if (asset.kind === 'ember') {
429
646
  let prior = this.assets.get(asset.relativePath);
430
647
  let parsed;
@@ -436,17 +653,17 @@ class CompatAppBuilder {
436
653
  else {
437
654
  parsed = new ParsedEmberAsset(asset);
438
655
  }
439
- this.insertEmberApp(parsed);
656
+ this.insertEmberApp(parsed, appFiles, prepared, emberENV);
440
657
  prepared.set(asset.relativePath, new BuiltEmberAsset(parsed));
441
658
  }
442
659
  else {
443
660
  prepared.set(asset.relativePath, asset);
444
661
  }
445
662
  }
446
- prepareAssets(requestedAssets) {
663
+ prepareAssets(requestedAssets, appFiles, emberENV) {
447
664
  let prepared = new Map();
448
665
  for (let asset of requestedAssets) {
449
- this.prepareAsset(asset, prepared);
666
+ this.prepareAsset(asset, appFiles, prepared, emberENV);
450
667
  }
451
668
  return prepared;
452
669
  }
@@ -461,6 +678,13 @@ class CompatAppBuilder {
461
678
  return prior.kind === 'in-memory' && stringOrBufferEqual(prior.source, asset.source);
462
679
  case 'built-ember':
463
680
  return prior.kind === 'built-ember' && prior.source === asset.source;
681
+ case 'concatenated-asset':
682
+ return (prior.kind === 'concatenated-asset' &&
683
+ prior.sources.length === asset.sources.length &&
684
+ prior.sources.every((priorFile, index) => {
685
+ let newFile = asset.sources[index];
686
+ return this.assetIsValid(newFile, priorFile);
687
+ }));
464
688
  }
465
689
  }
466
690
  updateOnDiskAsset(asset) {
@@ -478,8 +702,35 @@ class CompatAppBuilder {
478
702
  (0, fs_extra_2.ensureDirSync)((0, path_2.dirname)(destination));
479
703
  (0, fs_extra_1.writeFileSync)(destination, asset.source, 'utf8');
480
704
  }
481
- async updateAssets(requestedAssets) {
482
- let assets = this.prepareAssets(requestedAssets);
705
+ async updateConcatenatedAsset(asset) {
706
+ let concat = new fast_sourcemap_concat_1.default({
707
+ outputFile: (0, path_2.join)(this.root, asset.relativePath),
708
+ mapCommentType: asset.relativePath.endsWith('.js') ? 'line' : 'block',
709
+ baseDir: this.root,
710
+ });
711
+ if (process.env.EMBROIDER_CONCAT_STATS) {
712
+ let MeasureConcat = (await Promise.resolve().then(() => __importStar(require('@embroider/core/src/measure-concat')))).default;
713
+ concat = new MeasureConcat(asset.relativePath, concat, this.root);
714
+ }
715
+ for (let source of asset.sources) {
716
+ switch (source.kind) {
717
+ case 'on-disk':
718
+ concat.addFile((0, core_1.explicitRelative)(this.root, source.sourcePath));
719
+ break;
720
+ case 'in-memory':
721
+ if (typeof source.source !== 'string') {
722
+ throw new Error(`attempted to concatenated a Buffer-backed in-memory asset`);
723
+ }
724
+ concat.addSpace(source.source);
725
+ break;
726
+ default:
727
+ (0, assert_never_1.default)(source);
728
+ }
729
+ }
730
+ await concat.end();
731
+ }
732
+ async updateAssets(requestedAssets, appFiles, emberENV) {
733
+ let assets = this.prepareAssets(requestedAssets, appFiles, emberENV);
483
734
  for (let asset of assets.values()) {
484
735
  if (this.assetIsValid(asset, this.assets.get(asset.relativePath))) {
485
736
  continue;
@@ -495,6 +746,9 @@ class CompatAppBuilder {
495
746
  case 'built-ember':
496
747
  this.updateBuiltEmberAsset(asset);
497
748
  break;
749
+ case 'concatenated-asset':
750
+ await this.updateConcatenatedAsset(asset);
751
+ break;
498
752
  default:
499
753
  (0, assert_never_1.default)(asset);
500
754
  }
@@ -505,10 +759,26 @@ class CompatAppBuilder {
505
759
  }
506
760
  }
507
761
  this.assets = assets;
762
+ return [...assets.values()];
508
763
  }
509
764
  gatherAssets(inputPaths) {
510
765
  // first gather all the assets out of addons
511
766
  let assets = [];
767
+ for (let pkg of this.allActiveAddons) {
768
+ if (pkg.meta['public-assets']) {
769
+ for (let [filename, appRelativeURL] of Object.entries(pkg.meta['public-assets'] || {})) {
770
+ let sourcePath = (0, path_1.resolve)(pkg.root, filename);
771
+ let stats = (0, fs_extra_1.statSync)(sourcePath);
772
+ assets.push({
773
+ kind: 'on-disk',
774
+ sourcePath,
775
+ relativePath: appRelativeURL,
776
+ mtime: stats.mtimeMs,
777
+ size: stats.size,
778
+ });
779
+ }
780
+ }
781
+ }
512
782
  if (this.activeFastboot) {
513
783
  const source = `
514
784
  (function(){
@@ -537,20 +807,29 @@ class CompatAppBuilder {
537
807
  this.firstBuild = false;
538
808
  }
539
809
  let appFiles = this.updateAppJS(inputPaths.appJS);
810
+ let emberENV = this.configTree.readConfig().EmberENV;
540
811
  let assets = this.gatherAssets(inputPaths);
541
- await this.updateAssets(assets);
812
+ let finalAssets = await this.updateAssets(assets, appFiles, emberENV);
542
813
  let assetPaths = assets.map(asset => asset.relativePath);
543
814
  if (this.activeFastboot) {
544
815
  // when using fastboot, our own package.json needs to be in the output so fastboot can read it.
545
816
  assetPaths.push('package.json');
546
817
  }
818
+ for (let asset of finalAssets) {
819
+ // our concatenated assets all have map files that ride along. Here we're
820
+ // telling the final stage packager to be sure and serve the map files
821
+ // too.
822
+ if (asset.kind === 'concatenated-asset') {
823
+ assetPaths.push(asset.sourcemapPath);
824
+ }
825
+ }
547
826
  let meta = {
548
827
  type: 'app',
549
828
  version: 2,
550
829
  assets: assetPaths,
551
830
  babel: {
552
831
  filename: '_babel_config_.js',
553
- isParallelSafe: true, // TODO
832
+ isParallelSafe: true,
554
833
  majorVersion: this.compatApp.babelMajorVersion(),
555
834
  fileFilter: '_babel_filter_.js',
556
835
  },
@@ -562,12 +841,8 @@ class CompatAppBuilder {
562
841
  (0, fs_extra_1.writeFileSync)((0, path_2.join)(this.root, 'package.json'), JSON.stringify(pkg, null, 2), 'utf8');
563
842
  let resolverConfig = this.resolverConfig(appFiles);
564
843
  this.addResolverConfig(resolverConfig);
565
- this.addContentForConfig(this.contentForTree.readContents());
566
- this.addEmberEnvConfig(this.configTree.readConfig().EmberENV);
567
- this.addAppBoot(this.compatApp.appBoot.readAppBoot());
568
- let babelConfig = await this.babelConfig(resolverConfig);
844
+ let babelConfig = this.babelConfig(resolverConfig);
569
845
  this.addBabelConfig(babelConfig);
570
- (0, fs_extra_1.writeFileSync)((0, path_2.join)(this.root, 'macros-config.json'), JSON.stringify(this.compatApp.macrosConfig.babelPluginConfig()[0], null, 2));
571
846
  }
572
847
  combinePackageJSON(meta) {
573
848
  let pkgLayers = [this.origAppPackage.packageJSON];
@@ -580,7 +855,7 @@ class CompatAppBuilder {
580
855
  pkgLayers.push({ keywords: ['ember-addon'], 'ember-addon': meta });
581
856
  return combinePackageJSON(...pkgLayers);
582
857
  }
583
- async etcOptions(resolverConfig) {
858
+ etcOptions(resolverConfig) {
584
859
  let transforms = this.compatApp.htmlbarsPlugins;
585
860
  let { plugins: macroPlugins, setConfig } = node_1.MacrosConfig.transforms();
586
861
  setConfig(this.compatApp.macrosConfig);
@@ -597,7 +872,7 @@ class CompatAppBuilder {
597
872
  transforms.push([require.resolve('./resolver-transform'), opts]);
598
873
  }
599
874
  let resolver = new core_1.Resolver(resolverConfig);
600
- let resolution = await resolver.nodeResolve('ember-source/vendor/ember/ember-template-compiler', (0, path_1.resolve)(this.root, 'package.json'));
875
+ let resolution = resolver.nodeResolve('ember-source/vendor/ember/ember-template-compiler', (0, path_1.resolve)(this.root, 'package.json'));
601
876
  if (resolution.type !== 'real') {
602
877
  throw new Error(`bug: unable to resolve ember-template-compiler from ${this.root}`);
603
878
  }
@@ -615,7 +890,7 @@ class CompatAppBuilder {
615
890
  if (i < hint.resolve.length - 1) {
616
891
  target = (0, path_2.join)(target, 'package.json');
617
892
  }
618
- cursor = resolve_1.default.sync(target, { basedir: (0, path_2.dirname)(cursor) });
893
+ cursor = resolve_2.default.sync(target, { basedir: (0, path_2.dirname)(cursor) });
619
894
  }
620
895
  return {
621
896
  requireFile: cursor,
@@ -634,24 +909,240 @@ class CompatAppBuilder {
634
909
  addResolverConfig(config) {
635
910
  (0, fs_extra_1.outputJSONSync)((0, path_2.join)((0, core_1.locateEmbroiderWorkingDir)(this.compatApp.root), 'resolver.json'), config, { spaces: 2 });
636
911
  }
637
- addContentForConfig(contentForConfig) {
638
- (0, fs_extra_1.outputJSONSync)((0, path_2.join)((0, core_1.locateEmbroiderWorkingDir)(this.compatApp.root), 'content-for.json'), contentForConfig, {
639
- spaces: 2,
640
- });
912
+ shouldSplitRoute(routeName) {
913
+ return (!this.options.splitAtRoutes ||
914
+ this.options.splitAtRoutes.find(pattern => {
915
+ if (typeof pattern === 'string') {
916
+ return pattern === routeName;
917
+ }
918
+ else {
919
+ return pattern.test(routeName);
920
+ }
921
+ }));
922
+ }
923
+ splitRoute(routeName, files, addToParent, addLazyBundle) {
924
+ let shouldSplit = routeName && this.shouldSplitRoute(routeName);
925
+ let ownFiles = [];
926
+ let ownNames = new Set();
927
+ if (files.template) {
928
+ if (shouldSplit) {
929
+ ownFiles.push(files.template);
930
+ ownNames.add(routeName);
931
+ }
932
+ else {
933
+ addToParent(routeName, files.template);
934
+ }
935
+ }
936
+ if (files.controller) {
937
+ if (shouldSplit) {
938
+ ownFiles.push(files.controller);
939
+ ownNames.add(routeName);
940
+ }
941
+ else {
942
+ addToParent(routeName, files.controller);
943
+ }
944
+ }
945
+ if (files.route) {
946
+ if (shouldSplit) {
947
+ ownFiles.push(files.route);
948
+ ownNames.add(routeName);
949
+ }
950
+ else {
951
+ addToParent(routeName, files.route);
952
+ }
953
+ }
954
+ for (let [childName, childFiles] of files.children) {
955
+ this.splitRoute(`${routeName}.${childName}`, childFiles, (childRouteName, childFile) => {
956
+ // this is our child calling "addToParent"
957
+ if (shouldSplit) {
958
+ ownFiles.push(childFile);
959
+ ownNames.add(childRouteName);
960
+ }
961
+ else {
962
+ addToParent(childRouteName, childFile);
963
+ }
964
+ }, (routeNames, files) => {
965
+ addLazyBundle(routeNames, files);
966
+ });
967
+ }
968
+ if (ownFiles.length > 0) {
969
+ addLazyBundle([...ownNames], ownFiles);
970
+ }
641
971
  }
642
- addEmberEnvConfig(emberEnvConfig) {
643
- (0, fs_extra_1.outputJSONSync)((0, path_2.join)((0, core_1.locateEmbroiderWorkingDir)(this.compatApp.root), 'ember-env.json'), emberEnvConfig, {
644
- spaces: 2,
972
+ topAppJSAsset(engines, prepared) {
973
+ let [app, ...childEngines] = engines;
974
+ let relativePath = `assets/${this.origAppPackage.name}.js`;
975
+ return this.appJSAsset(relativePath, app, childEngines, prepared, {
976
+ autoRun: this.compatApp.autoRun,
977
+ appBoot: !this.compatApp.autoRun ? this.compatApp.appBoot.readAppBoot() : '',
978
+ mainModule: (0, core_1.explicitRelative)((0, path_2.dirname)(relativePath), 'app'),
979
+ appConfig: this.configTree.readConfig().APP,
645
980
  });
646
981
  }
647
- addAppBoot(appBoot) {
648
- (0, fs_extra_1.writeFileSync)((0, path_2.join)((0, core_1.locateEmbroiderWorkingDir)(this.compatApp.root), 'ember-app-boot.js'), appBoot !== null && appBoot !== void 0 ? appBoot : '');
982
+ get staticAppPathsPattern() {
983
+ if (this.options.staticAppPaths.length > 0) {
984
+ return new RegExp('^(?:' + this.options.staticAppPaths.map(staticAppPath => (0, escape_string_regexp_1.default)(staticAppPath)).join('|') + ')(?:$|/)');
985
+ }
986
+ }
987
+ requiredOtherFiles(appFiles) {
988
+ let pattern = this.staticAppPathsPattern;
989
+ if (pattern) {
990
+ return appFiles.otherAppFiles.filter(f => {
991
+ return !pattern.test(f);
992
+ });
993
+ }
994
+ else {
995
+ return appFiles.otherAppFiles;
996
+ }
997
+ }
998
+ appJSAsset(relativePath, appFiles, childEngines, prepared, entryParams) {
999
+ let cached = prepared.get(relativePath);
1000
+ if (cached) {
1001
+ return cached;
1002
+ }
1003
+ let eagerModules = [];
1004
+ let requiredAppFiles = [this.requiredOtherFiles(appFiles)];
1005
+ if (!this.options.staticComponents) {
1006
+ requiredAppFiles.push(appFiles.components);
1007
+ }
1008
+ if (!this.options.staticHelpers) {
1009
+ requiredAppFiles.push(appFiles.helpers);
1010
+ }
1011
+ if (!this.options.staticModifiers) {
1012
+ requiredAppFiles.push(appFiles.modifiers);
1013
+ }
1014
+ let styles = [];
1015
+ // only import styles from engines with a parent (this excludeds the parent application) as their styles
1016
+ // will be inserted via a direct <link> tag.
1017
+ if (appFiles.engine.parent && appFiles.engine.package.isLazyEngine()) {
1018
+ let implicitStyles = this.impliedAssets('implicit-styles', appFiles);
1019
+ for (let style of implicitStyles) {
1020
+ styles.push({
1021
+ path: (0, core_1.explicitRelative)('assets/_engine_', style.relativePath),
1022
+ });
1023
+ }
1024
+ let engineMeta = appFiles.engine.package.meta;
1025
+ if (engineMeta && engineMeta['implicit-styles']) {
1026
+ for (let style of engineMeta['implicit-styles']) {
1027
+ styles.push({
1028
+ path: (0, core_1.explicitRelative)((0, path_2.dirname)(relativePath), (0, path_2.join)(appFiles.engine.appRelativePath, style)),
1029
+ });
1030
+ }
1031
+ }
1032
+ }
1033
+ let lazyEngines = [];
1034
+ for (let childEngine of childEngines) {
1035
+ let asset = this.appJSAsset(`assets/_engine_/${encodeURIComponent(childEngine.engine.package.name)}.js`, childEngine, [], prepared);
1036
+ if (childEngine.engine.package.isLazyEngine()) {
1037
+ lazyEngines.push({
1038
+ names: [childEngine.engine.package.name],
1039
+ path: (0, core_1.explicitRelative)((0, path_2.dirname)(relativePath), asset.relativePath),
1040
+ });
1041
+ }
1042
+ else {
1043
+ eagerModules.push((0, core_1.explicitRelative)((0, path_2.dirname)(relativePath), asset.relativePath));
1044
+ }
1045
+ }
1046
+ let lazyRoutes = [];
1047
+ for (let [routeName, routeFiles] of appFiles.routeFiles.children) {
1048
+ this.splitRoute(routeName, routeFiles, (_, filename) => {
1049
+ requiredAppFiles.push([filename]);
1050
+ }, (routeNames, files) => {
1051
+ let routeEntrypoint = `assets/_route_/${encodeURIComponent(routeNames[0])}.js`;
1052
+ if (!prepared.has(routeEntrypoint)) {
1053
+ prepared.set(routeEntrypoint, this.routeEntrypoint(appFiles, routeEntrypoint, files));
1054
+ }
1055
+ lazyRoutes.push({
1056
+ names: routeNames,
1057
+ path: this.importPaths(appFiles, routeEntrypoint).buildtime,
1058
+ });
1059
+ });
1060
+ }
1061
+ let [fastboot, nonFastboot] = (0, partition_1.default)(excludeDotFiles((0, flatten_1.default)(requiredAppFiles)), file => appFiles.isFastbootOnly.get(file));
1062
+ let amdModules = nonFastboot.map(file => this.importPaths(appFiles, file));
1063
+ let fastbootOnlyAmdModules = fastboot.map(file => this.importPaths(appFiles, file));
1064
+ // this is a backward-compatibility feature: addons can force inclusion of
1065
+ // modules.
1066
+ eagerModules.push('./-embroider-implicit-modules.js');
1067
+ let params = { amdModules, fastbootOnlyAmdModules, lazyRoutes, lazyEngines, eagerModules, styles };
1068
+ if (entryParams) {
1069
+ Object.assign(params, entryParams);
1070
+ }
1071
+ let source = entryTemplate(params);
1072
+ let asset = {
1073
+ kind: 'in-memory',
1074
+ source,
1075
+ relativePath,
1076
+ };
1077
+ prepared.set(relativePath, asset);
1078
+ return asset;
1079
+ }
1080
+ importPaths({ engine }, engineRelativePath) {
1081
+ let noHBS = engineRelativePath.replace(this.resolvableExtensionsPattern, '').replace(/\.hbs$/, '');
1082
+ return {
1083
+ runtime: `${engine.modulePrefix}/${noHBS}`,
1084
+ buildtime: path_1.posix.join(engine.package.name, engineRelativePath),
1085
+ };
1086
+ }
1087
+ routeEntrypoint(appFiles, relativePath, files) {
1088
+ let [fastboot, nonFastboot] = (0, partition_1.default)(files, file => appFiles.isFastbootOnly.get(file));
1089
+ let asset = {
1090
+ kind: 'in-memory',
1091
+ source: routeEntryTemplate({
1092
+ files: nonFastboot.map(f => this.importPaths(appFiles, f)),
1093
+ fastbootOnlyFiles: fastboot.map(f => this.importPaths(appFiles, f)),
1094
+ }),
1095
+ relativePath,
1096
+ };
1097
+ return asset;
1098
+ }
1099
+ testJSEntrypoint(appFiles, prepared) {
1100
+ let asset = prepared.get(`assets/test.js`);
1101
+ if (asset) {
1102
+ return asset;
1103
+ }
1104
+ // We're only building tests from the first engine (the app). This is the
1105
+ // normal thing to do -- tests from engines don't automatically roll up into
1106
+ // the app.
1107
+ let engine = appFiles[0];
1108
+ const myName = 'assets/test.js';
1109
+ // tests necessarily also include the app. This is where we account for
1110
+ // that. The classic solution was to always include the app's separate
1111
+ // script tag in the tests HTML, but that isn't as easy for final stage
1112
+ // packagers to understand. It's better to express it here as a direct
1113
+ // module dependency.
1114
+ let eagerModules = [
1115
+ 'ember-testing',
1116
+ (0, core_1.explicitRelative)((0, path_2.dirname)(myName), this.topAppJSAsset(appFiles, prepared).relativePath),
1117
+ ];
1118
+ let amdModules = [];
1119
+ // this is a backward-compatibility feature: addons can force inclusion of
1120
+ // test support modules.
1121
+ eagerModules.push('./-embroider-implicit-test-modules.js');
1122
+ for (let relativePath of engine.tests) {
1123
+ amdModules.push(this.importPaths(engine, relativePath));
1124
+ }
1125
+ let source = entryTemplate({
1126
+ amdModules,
1127
+ eagerModules,
1128
+ testSuffix: true,
1129
+ });
1130
+ asset = {
1131
+ kind: 'in-memory',
1132
+ source,
1133
+ relativePath: myName,
1134
+ };
1135
+ prepared.set(asset.relativePath, asset);
1136
+ return asset;
649
1137
  }
650
1138
  }
651
1139
  exports.CompatAppBuilder = CompatAppBuilder;
652
1140
  __decorate([
653
1141
  (0, typescript_memoize_1.Memoize)()
654
1142
  ], CompatAppBuilder.prototype, "fastbootJSSrcDir", null);
1143
+ __decorate([
1144
+ (0, typescript_memoize_1.Memoize)()
1145
+ ], CompatAppBuilder.prototype, "findTestemAsset", null);
655
1146
  __decorate([
656
1147
  (0, typescript_memoize_1.Memoize)()
657
1148
  ], CompatAppBuilder.prototype, "allActiveAddons", null);
@@ -678,10 +1169,10 @@ __decorate([
678
1169
  ], CompatAppBuilder.prototype, "fastbootConfig", null);
679
1170
  __decorate([
680
1171
  (0, typescript_memoize_1.Memoize)()
681
- ], CompatAppBuilder.prototype, "staticAppPathsPattern", null);
1172
+ ], CompatAppBuilder.prototype, "portableHints", null);
682
1173
  __decorate([
683
1174
  (0, typescript_memoize_1.Memoize)()
684
- ], CompatAppBuilder.prototype, "portableHints", null);
1175
+ ], CompatAppBuilder.prototype, "staticAppPathsPattern", null);
685
1176
  function defaultAddonPackageRules() {
686
1177
  return (0, fs_extra_2.readdirSync)((0, path_2.join)(__dirname, 'addon-dependency-rules'))
687
1178
  .map(filename => {
@@ -693,6 +1184,95 @@ function defaultAddonPackageRules() {
693
1184
  .filter(Boolean)
694
1185
  .reduce((a, b) => a.concat(b), []);
695
1186
  }
1187
+ const entryTemplate = (0, core_1.jsHandlebarsCompile)(`
1188
+ import { importSync as i, macroCondition, getGlobalConfig } from '@embroider/macros';
1189
+ let w = window;
1190
+ let d = w.define;
1191
+
1192
+ {{#if styles}}
1193
+ if (macroCondition(!getGlobalConfig().fastboot?.isRunning)) {
1194
+ {{#each styles as |stylePath| ~}}
1195
+ i("{{js-string-escape stylePath.path}}");
1196
+ {{/each}}
1197
+ }
1198
+ {{/if}}
1199
+
1200
+ {{#each eagerModules as |eagerModule| ~}}
1201
+ i("{{js-string-escape eagerModule}}");
1202
+ {{/each}}
1203
+
1204
+ {{#each amdModules as |amdModule| ~}}
1205
+ d("{{js-string-escape amdModule.runtime}}", function(){ return i("{{js-string-escape amdModule.buildtime}}");});
1206
+ {{/each}}
1207
+
1208
+ {{#if fastbootOnlyAmdModules}}
1209
+ if (macroCondition(getGlobalConfig().fastboot?.isRunning)) {
1210
+ {{#each fastbootOnlyAmdModules as |amdModule| ~}}
1211
+ d("{{js-string-escape amdModule.runtime}}", function(){ return i("{{js-string-escape amdModule.buildtime}}");});
1212
+ {{/each}}
1213
+ }
1214
+ {{/if}}
1215
+
1216
+
1217
+ {{#if lazyRoutes}}
1218
+ w._embroiderRouteBundles_ = [
1219
+ {{#each lazyRoutes as |route|}}
1220
+ {
1221
+ names: {{json-stringify route.names}},
1222
+ load: function() {
1223
+ return import("{{js-string-escape route.path}}");
1224
+ }
1225
+ },
1226
+ {{/each}}
1227
+ ]
1228
+ {{/if}}
1229
+
1230
+ {{#if lazyEngines}}
1231
+ w._embroiderEngineBundles_ = [
1232
+ {{#each lazyEngines as |engine|}}
1233
+ {
1234
+ names: {{json-stringify engine.names}},
1235
+ load: function() {
1236
+ return import("{{js-string-escape engine.path}}");
1237
+ }
1238
+ },
1239
+ {{/each}}
1240
+ ]
1241
+ {{/if}}
1242
+
1243
+ {{#if autoRun ~}}
1244
+ if (!runningTests) {
1245
+ i("{{js-string-escape mainModule}}").default.create({{json-stringify appConfig}});
1246
+ }
1247
+ {{else if appBoot ~}}
1248
+ {{ appBoot }}
1249
+ {{/if}}
1250
+
1251
+ {{#if testSuffix ~}}
1252
+ {{!- TODO: both of these suffixes should get dynamically generated so they incorporate
1253
+ any content-for added by addons. -}}
1254
+
1255
+
1256
+ {{!- this is the traditional tests-suffix.js -}}
1257
+ i('../tests/test-helper');
1258
+ EmberENV.TESTS_FILE_LOADED = true;
1259
+ {{/if}}
1260
+ `);
1261
+ const routeEntryTemplate = (0, core_1.jsHandlebarsCompile)(`
1262
+ import { importSync as i } from '@embroider/macros';
1263
+ let d = window.define;
1264
+ {{#each files as |amdModule| ~}}
1265
+ d("{{js-string-escape amdModule.runtime}}", function(){ return i("{{js-string-escape amdModule.buildtime}}");});
1266
+ {{/each}}
1267
+ {{#if fastbootOnlyFiles}}
1268
+ import { macroCondition, getGlobalConfig } from '@embroider/macros';
1269
+ if (macroCondition(getGlobalConfig().fastboot?.isRunning)) {
1270
+ {{#each fastbootOnlyFiles as |amdModule| ~}}
1271
+ d("{{js-string-escape amdModule.runtime}}", function(){ return i("{{js-string-escape amdModule.buildtime}}");});
1272
+ {{/each}}
1273
+ }
1274
+ {{/if}}
1275
+ `);
696
1276
  function stringOrBufferEqual(a, b) {
697
1277
  if (typeof a === 'string' && typeof b === 'string') {
698
1278
  return a === b;
@@ -741,6 +1321,9 @@ function addCachablePlugin(babelConfig) {
741
1321
  ]);
742
1322
  }
743
1323
  }
1324
+ function excludeDotFiles(files) {
1325
+ return files.filter(file => !file.startsWith('.') && !file.includes('/.'));
1326
+ }
744
1327
  class ParsedEmberAsset {
745
1328
  constructor(asset) {
746
1329
  this.kind = 'parsed-ember';
@@ -760,4 +1343,15 @@ class BuiltEmberAsset {
760
1343
  this.relativePath = asset.relativePath;
761
1344
  }
762
1345
  }
1346
+ class ConcatenatedAsset {
1347
+ constructor(relativePath, sources, resolvableExtensions) {
1348
+ this.relativePath = relativePath;
1349
+ this.sources = sources;
1350
+ this.resolvableExtensions = resolvableExtensions;
1351
+ this.kind = 'concatenated-asset';
1352
+ }
1353
+ get sourcemapPath() {
1354
+ return this.relativePath.replace(this.resolvableExtensions, '') + '.map';
1355
+ }
1356
+ }
763
1357
  //# sourceMappingURL=compat-app-builder.js.map