@embroider/compat 1.9.0 → 2.0.0

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 (36) hide show
  1. package/package.json +7 -8
  2. package/src/audit/build.js +5 -1
  3. package/src/audit/build.js.map +1 -1
  4. package/src/audit/capture.d.ts +1 -0
  5. package/src/compat-adapters/ember-cli-fastboot.d.ts +1 -1
  6. package/src/compat-adapters/ember-cli-fastboot.js.map +1 -1
  7. package/src/compat-app.js +8 -24
  8. package/src/compat-app.js.map +1 -1
  9. package/src/dasherize-component-name.d.ts +1 -0
  10. package/src/dasherize-component-name.js +10 -1
  11. package/src/dasherize-component-name.js.map +1 -1
  12. package/src/default-pipeline.js +2 -2
  13. package/src/default-pipeline.js.map +1 -1
  14. package/src/dependency-rules.js +6 -1
  15. package/src/dependency-rules.js.map +1 -1
  16. package/src/{template-compiler-broccoli-plugin.d.ts → hbs-to-js-broccoli-plugin.d.ts} +2 -4
  17. package/src/hbs-to-js-broccoli-plugin.js +39 -0
  18. package/src/hbs-to-js-broccoli-plugin.js.map +1 -0
  19. package/src/moved-package-cache.js +5 -1
  20. package/src/moved-package-cache.js.map +1 -1
  21. package/src/resolver-transform.d.ts +11 -27
  22. package/src/resolver-transform.js +163 -65
  23. package/src/resolver-transform.js.map +1 -1
  24. package/src/resolver.d.ts +26 -27
  25. package/src/resolver.js +124 -169
  26. package/src/resolver.js.map +1 -1
  27. package/src/synthesize-template-only-components.js +8 -8
  28. package/src/synthesize-template-only-components.js.map +1 -1
  29. package/src/v1-addon.d.ts +2 -26
  30. package/src/v1-addon.js +29 -68
  31. package/src/v1-addon.js.map +1 -1
  32. package/src/v1-app.d.ts +3 -2
  33. package/src/v1-app.js +14 -3
  34. package/src/v1-app.js.map +1 -1
  35. package/src/template-compiler-broccoli-plugin.js +0 -28
  36. package/src/template-compiler-broccoli-plugin.js.map +0 -1
package/src/resolver.js CHANGED
@@ -15,9 +15,9 @@ const core_1 = require("@embroider/core");
15
15
  const path_1 = require("path");
16
16
  const typescript_memoize_1 = require("typescript-memoize");
17
17
  const dasherize_component_name_1 = require("./dasherize-component-name");
18
- const resolver_transform_1 = require("./resolver-transform");
19
18
  const fs_extra_1 = require("fs-extra");
20
19
  const resolve_1 = __importDefault(require("resolve"));
20
+ const semver_1 = __importDefault(require("semver"));
21
21
  // TODO: this depends on the ember version. And it's probably missing some
22
22
  // private-but-used values.
23
23
  const builtInHelpers = [
@@ -78,7 +78,6 @@ exports.rehydrate = rehydrate;
78
78
  class CompatResolver {
79
79
  constructor(params) {
80
80
  this.params = params;
81
- this.dependencies = new Map();
82
81
  this.params.options = extractOptions(this.params.options);
83
82
  this._parallelBabel = {
84
83
  requireFile: __filename,
@@ -89,23 +88,6 @@ class CompatResolver {
89
88
  this.auditHandler = globalThis.embroider_audit;
90
89
  }
91
90
  }
92
- enter(moduleName, contents) {
93
- let rules = this.findComponentRules(moduleName);
94
- let deps;
95
- if (rules === null || rules === void 0 ? void 0 : rules.dependsOnComponents) {
96
- deps = rules.dependsOnComponents.map(snippet => this.resolveComponentSnippet(snippet, rules, moduleName));
97
- }
98
- else {
99
- deps = [];
100
- }
101
- this.dependencies.set(moduleName, deps);
102
- this.currentContents = contents;
103
- }
104
- add(resolution, from) {
105
- // this "!" is safe because we always `enter()` a module before hitting this
106
- this.dependencies.get(from).push(resolution);
107
- return resolution;
108
- }
109
91
  findComponentRules(absPath) {
110
92
  let rules = this.rules.components.get(absPath);
111
93
  if (rules) {
@@ -140,9 +122,7 @@ class CompatResolver {
140
122
  : params.adjustImportsOptions;
141
123
  }
142
124
  get rules() {
143
- if (!this.templateCompiler) {
144
- throw new Error(`Bug: Resolver needs to get linked into a TemplateCompiler before it can understand packageRules`);
145
- }
125
+ var _a;
146
126
  // keyed by their first resolved dependency's runtimeName.
147
127
  let components = new Map();
148
128
  // keyed by our own dasherized interpretation of the component's name.
@@ -157,7 +137,9 @@ class CompatResolver {
157
137
  ignoredComponents.push(this.standardDasherize(snippet, rule));
158
138
  continue;
159
139
  }
160
- let resolvedDep = this.resolveComponentSnippet(snippet, rule).modules[0];
140
+ let resolvedSnippet = this.resolveComponentSnippet(snippet, rule);
141
+ // cast is OK here because a component must have one or the other
142
+ let resolvedDep = ((_a = resolvedSnippet.hbsModule) !== null && _a !== void 0 ? _a : resolvedSnippet.jsModule);
161
143
  let processedRules = (0, dependency_rules_1.preprocessComponentRule)(componentRules);
162
144
  // we always register our rules on the component's own first resolved
163
145
  // module, which must be a module in the app's module namespace.
@@ -197,9 +179,6 @@ class CompatResolver {
197
179
  return { components, ignoredComponents };
198
180
  }
199
181
  resolveComponentSnippet(snippet, rule, from = 'rule-snippet.hbs') {
200
- if (!this.templateCompiler) {
201
- throw new Error(`bug: tried to use resolveComponentSnippet without a templateCompiler`);
202
- }
203
182
  let name = this.standardDasherize(snippet, rule);
204
183
  let found = this.tryComponent(name, from, false);
205
184
  if (found && found.type === 'component') {
@@ -208,73 +187,50 @@ class CompatResolver {
208
187
  throw new Error(`unable to locate component ${snippet} referred to in rule ${JSON.stringify(rule, null, 2)}`);
209
188
  }
210
189
  standardDasherize(snippet, rule) {
211
- if (!this.templateCompiler) {
212
- throw new Error(`bug: tried to use resolveComponentSnippet without a templateCompiler`);
213
- }
214
- let ast;
215
- try {
216
- ast = this.templateCompiler.parse('snippet.hbs', snippet);
217
- }
218
- catch (err) {
190
+ let name = (0, dasherize_component_name_1.snippetToDasherizedName)(snippet);
191
+ if (name == null) {
219
192
  throw new Error(`unable to parse component snippet "${snippet}" from rule ${JSON.stringify(rule, null, 2)}`);
220
193
  }
221
- if ((ast.type === 'Program' || ast.type === 'Template') && ast.body.length > 0) {
222
- let first = ast.body[0];
223
- const isMustachePath = first.type === 'MustacheStatement' && first.path.type === 'PathExpression';
224
- const isComponent = isMustachePath && first.path.original === 'component';
225
- const hasStringParam = isComponent &&
226
- Array.isArray(first.params) &&
227
- first.params[0].type === 'StringLiteral';
228
- if (isMustachePath && isComponent && hasStringParam) {
229
- return first.params[0].value;
230
- }
231
- if (isMustachePath) {
232
- return first.path.original;
233
- }
234
- if (first.type === 'ElementNode') {
235
- return (0, dasherize_component_name_1.dasherize)(first.tag);
236
- }
237
- }
238
- throw new Error(`cannot identify a component in rule snippet: "${snippet}"`);
194
+ return name;
239
195
  }
240
- astTransformer(templateCompiler) {
241
- this.templateCompiler = templateCompiler;
196
+ astTransformer() {
242
197
  if (this.staticComponentsEnabled || this.staticHelpersEnabled || this.staticModifiersEnabled) {
243
- return (0, resolver_transform_1.makeResolverTransform)(this);
198
+ let opts = {
199
+ resolver: this,
200
+ // lexical invocation of helpers was not reliable before Ember 4.2 due to https://github.com/emberjs/ember.js/pull/19878
201
+ patchHelpersBug: semver_1.default.satisfies(this.params.emberVersion, '<4.2.0-beta.0', {
202
+ includePrerelease: true,
203
+ }),
204
+ };
205
+ return [require.resolve('./resolver-transform'), opts];
244
206
  }
245
207
  }
246
- dependenciesOf(moduleName) {
247
- let flatDeps = new Map();
248
- let deps = this.dependencies.get(moduleName);
249
- if (deps) {
250
- for (let dep of deps) {
251
- if (dep.type === 'error') {
252
- if (!this.auditHandler && !this.params.options.allowUnsafeDynamicComponents) {
253
- let e = new Error(`${dep.message}: ${dep.detail} in ${humanReadableFile(this.params.root, moduleName)}`);
254
- e.isTemplateResolverError = true;
255
- e.loc = dep.loc;
256
- e.moduleName = moduleName;
257
- throw e;
258
- }
259
- if (this.auditHandler) {
260
- this.auditHandler({
261
- message: dep.message,
262
- filename: moduleName,
263
- detail: dep.detail,
264
- loc: dep.loc,
265
- source: this.currentContents,
266
- });
267
- }
268
- }
269
- else {
270
- for (let entry of dep.modules) {
271
- let { runtimeName } = entry;
272
- flatDeps.set(runtimeName, entry);
273
- }
274
- }
275
- }
208
+ humanReadableFile(file) {
209
+ if (!this.params.root.endsWith('/')) {
210
+ this.params.root += '/';
211
+ }
212
+ if (file.startsWith(this.params.root)) {
213
+ return file.slice(this.params.root.length);
214
+ }
215
+ return file;
216
+ }
217
+ reportError(dep, filename, source) {
218
+ if (!this.auditHandler && !this.params.options.allowUnsafeDynamicComponents) {
219
+ let e = new Error(`${dep.message}: ${dep.detail} in ${this.humanReadableFile(filename)}`);
220
+ e.isTemplateResolverError = true;
221
+ e.loc = dep.loc;
222
+ e.moduleName = filename;
223
+ throw e;
224
+ }
225
+ if (this.auditHandler) {
226
+ this.auditHandler({
227
+ message: dep.message,
228
+ filename,
229
+ detail: dep.detail,
230
+ loc: dep.loc,
231
+ source,
232
+ });
276
233
  }
277
- return [...flatDeps.values()];
278
234
  }
279
235
  resolveImport(path, from) {
280
236
  let absPath;
@@ -353,13 +309,12 @@ class CompatResolver {
353
309
  if ((0, fs_extra_1.pathExistsSync)(absPath)) {
354
310
  return {
355
311
  type: 'helper',
356
- modules: [
357
- {
358
- runtimeName: this.absPathToRuntimeName(absPath, targetPackage),
359
- path: (0, core_1.explicitRelative)((0, path_1.dirname)(from), absPath),
360
- absPath,
361
- },
362
- ],
312
+ module: {
313
+ runtimeName: this.absPathToRuntimeName(absPath, targetPackage),
314
+ path: (0, core_1.explicitRelative)((0, path_1.dirname)(from), absPath),
315
+ absPath,
316
+ },
317
+ nameHint: path,
363
318
  };
364
319
  }
365
320
  }
@@ -388,13 +343,12 @@ class CompatResolver {
388
343
  if ((0, fs_extra_1.pathExistsSync)(absPath)) {
389
344
  return {
390
345
  type: 'modifier',
391
- modules: [
392
- {
393
- runtimeName: this.absPathToRuntimeName(absPath, targetPackage),
394
- path: (0, core_1.explicitRelative)((0, path_1.dirname)(from), absPath),
395
- absPath,
396
- },
397
- ],
346
+ module: {
347
+ runtimeName: this.absPathToRuntimeName(absPath, targetPackage),
348
+ path: (0, core_1.explicitRelative)((0, path_1.dirname)(from), absPath),
349
+ absPath,
350
+ },
351
+ nameHint: path,
398
352
  };
399
353
  }
400
354
  }
@@ -421,23 +375,19 @@ class CompatResolver {
421
375
  }
422
376
  }
423
377
  _tryComponent(path, from, withRuleLookup, targetPackage) {
424
- // The order here is important! We always put our .hbs paths first here, so
425
- // that if we have an hbs file of our own, that will be the first resolved
426
- // dependency. The first resolved dependency is special because we use that
427
- // as a key into the rules, and we want to be able to find our rules when
428
- // checking from our own template (among other times).
429
378
  let extensions = ['.hbs', ...this.adjustImportsOptions.resolvableExtensions.filter((e) => e !== '.hbs')];
430
- let componentModules = [];
379
+ let hbsModule;
380
+ let jsModule;
431
381
  // first, the various places our template might be
432
382
  for (let extension of extensions) {
433
383
  let absPath = (0, path_1.join)(targetPackage.root, 'templates', 'components', path) + extension;
434
384
  if ((0, fs_extra_1.pathExistsSync)(absPath)) {
435
- componentModules.push(absPath);
385
+ hbsModule = absPath;
436
386
  break;
437
387
  }
438
388
  absPath = (0, path_1.join)(targetPackage.root, 'components', path, 'template') + extension;
439
389
  if ((0, fs_extra_1.pathExistsSync)(absPath)) {
440
- componentModules.push(absPath);
390
+ hbsModule = absPath;
441
391
  break;
442
392
  }
443
393
  if (typeof this.params.podModulePrefix !== 'undefined' &&
@@ -446,7 +396,7 @@ class CompatResolver {
446
396
  let podPrefix = this.params.podModulePrefix.replace(this.params.modulePrefix, '');
447
397
  absPath = (0, path_1.join)(targetPackage.root, podPrefix, 'components', path, 'template') + extension;
448
398
  if ((0, fs_extra_1.pathExistsSync)(absPath)) {
449
- componentModules.push(absPath);
399
+ hbsModule = absPath;
450
400
  break;
451
401
  }
452
402
  }
@@ -458,17 +408,17 @@ class CompatResolver {
458
408
  }
459
409
  let absPath = (0, path_1.join)(targetPackage.root, 'components', path, 'index') + extension;
460
410
  if ((0, fs_extra_1.pathExistsSync)(absPath)) {
461
- componentModules.push(absPath);
411
+ jsModule = absPath;
462
412
  break;
463
413
  }
464
414
  absPath = (0, path_1.join)(targetPackage.root, 'components', path) + extension;
465
415
  if ((0, fs_extra_1.pathExistsSync)(absPath)) {
466
- componentModules.push(absPath);
416
+ jsModule = absPath;
467
417
  break;
468
418
  }
469
419
  absPath = (0, path_1.join)(targetPackage.root, 'components', path, 'component') + extension;
470
420
  if ((0, fs_extra_1.pathExistsSync)(absPath)) {
471
- componentModules.push(absPath);
421
+ jsModule = absPath;
472
422
  break;
473
423
  }
474
424
  if (typeof this.params.podModulePrefix !== 'undefined' &&
@@ -477,29 +427,42 @@ class CompatResolver {
477
427
  let podPrefix = this.params.podModulePrefix.replace(this.params.modulePrefix, '');
478
428
  absPath = (0, path_1.join)(targetPackage.root, podPrefix, 'components', path, 'component') + extension;
479
429
  if ((0, fs_extra_1.pathExistsSync)(absPath)) {
480
- componentModules.push(absPath);
430
+ jsModule = absPath;
481
431
  break;
482
432
  }
483
433
  }
484
434
  }
485
- if (componentModules.length > 0) {
486
- let componentRules;
487
- if (withRuleLookup) {
488
- componentRules = this.findComponentRules(componentModules[0]);
489
- }
490
- return {
491
- type: 'component',
492
- modules: componentModules.map(absPath => ({
493
- path: (0, core_1.explicitRelative)((0, path_1.dirname)(from), absPath),
494
- absPath,
495
- runtimeName: this.absPathToRuntimeName(absPath, targetPackage),
496
- })),
497
- yieldsComponents: componentRules ? componentRules.yieldsSafeComponents : [],
498
- yieldsArguments: componentRules ? componentRules.yieldsArguments : [],
499
- argumentsAreComponents: componentRules ? componentRules.argumentsAreComponents : [],
500
- };
435
+ if (jsModule == null && hbsModule == null) {
436
+ return null;
501
437
  }
502
- return null;
438
+ let componentRules;
439
+ if (withRuleLookup) {
440
+ // the order here is important. We follow the convention that any rules
441
+ // get attached to the hbsModule if it exists, and only get attached to
442
+ // the jsModule otherwise
443
+ componentRules = this.findComponentRules((hbsModule !== null && hbsModule !== void 0 ? hbsModule : jsModule));
444
+ }
445
+ return {
446
+ type: 'component',
447
+ jsModule: jsModule
448
+ ? {
449
+ path: (0, core_1.explicitRelative)((0, path_1.dirname)(from), jsModule),
450
+ absPath: jsModule,
451
+ runtimeName: this.absPathToRuntimeName(jsModule, targetPackage),
452
+ }
453
+ : null,
454
+ hbsModule: hbsModule
455
+ ? {
456
+ path: (0, core_1.explicitRelative)((0, path_1.dirname)(from), hbsModule),
457
+ absPath: hbsModule,
458
+ runtimeName: this.absPathToRuntimeName(hbsModule, targetPackage),
459
+ }
460
+ : null,
461
+ yieldsComponents: componentRules ? componentRules.yieldsSafeComponents : [],
462
+ yieldsArguments: componentRules ? componentRules.yieldsArguments : [],
463
+ argumentsAreComponents: componentRules ? componentRules.argumentsAreComponents : [],
464
+ nameHint: path,
465
+ };
503
466
  }
504
467
  resolveSubExpression(path, from, loc) {
505
468
  if (!this.staticHelpersEnabled) {
@@ -507,29 +470,29 @@ class CompatResolver {
507
470
  }
508
471
  let found = this.tryHelper(path, from);
509
472
  if (found) {
510
- return this.add(found, from);
473
+ return found;
511
474
  }
512
475
  if (builtInHelpers.includes(path)) {
513
476
  return null;
514
477
  }
515
- return this.add({
478
+ return {
516
479
  type: 'error',
517
480
  message: `Missing helper`,
518
481
  detail: path,
519
482
  loc,
520
- }, from);
483
+ };
521
484
  }
522
485
  resolveMustache(path, hasArgs, from, loc) {
523
486
  if (this.staticHelpersEnabled) {
524
487
  let found = this.tryHelper(path, from);
525
488
  if (found) {
526
- return this.add(found, from);
489
+ return found;
527
490
  }
528
491
  }
529
492
  if (this.staticComponentsEnabled) {
530
493
  let found = this.tryComponent(path, from);
531
494
  if (found) {
532
- return this.add(found, from);
495
+ return found;
533
496
  }
534
497
  }
535
498
  if (hasArgs &&
@@ -537,12 +500,12 @@ class CompatResolver {
537
500
  this.staticHelpersEnabled &&
538
501
  !builtInHelpers.includes(path) &&
539
502
  !this.isIgnoredComponent(path)) {
540
- return this.add({
503
+ return {
541
504
  type: 'error',
542
505
  message: `Missing component or helper`,
543
506
  detail: path,
544
507
  loc,
545
- }, from);
508
+ };
546
509
  }
547
510
  else {
548
511
  return null;
@@ -554,17 +517,17 @@ class CompatResolver {
554
517
  }
555
518
  let found = this.tryModifier(path, from);
556
519
  if (found) {
557
- return this.add(found, from);
520
+ return found;
558
521
  }
559
522
  if (builtInModifiers.includes(path)) {
560
523
  return null;
561
524
  }
562
- return this.add({
525
+ return {
563
526
  type: 'error',
564
527
  message: `Missing modifier`,
565
528
  detail: path,
566
529
  loc,
567
- }, from);
530
+ };
568
531
  }
569
532
  resolveElement(tagName, from, loc) {
570
533
  if (!this.staticComponentsEnabled) {
@@ -581,17 +544,18 @@ class CompatResolver {
581
544
  }
582
545
  let found = this.tryComponent(dName, from);
583
546
  if (found) {
584
- return this.add(found, from);
547
+ found.nameHint = tagName;
548
+ return found;
585
549
  }
586
550
  if (this.isIgnoredComponent(dName)) {
587
551
  return null;
588
552
  }
589
- return this.add({
553
+ return {
590
554
  type: 'error',
591
555
  message: `Missing component`,
592
556
  detail: tagName,
593
557
  loc,
594
- }, from);
558
+ };
595
559
  }
596
560
  resolveComponentHelper(component, from, loc, impliedBecause) {
597
561
  if (!this.staticComponentsEnabled) {
@@ -605,38 +569,38 @@ class CompatResolver {
605
569
  message = `Unsafe dynamic component`;
606
570
  }
607
571
  if (component.type === 'other') {
608
- return this.add({
572
+ return {
609
573
  type: 'error',
610
574
  message,
611
575
  detail: `cannot statically analyze this expression`,
612
576
  loc,
613
- }, from);
577
+ };
614
578
  }
615
579
  if (component.type === 'path') {
616
580
  let ownComponentRules = this.findComponentRules(from);
617
581
  if (ownComponentRules && ownComponentRules.safeInteriorPaths.includes(component.path)) {
618
582
  return null;
619
583
  }
620
- return this.add({
584
+ return {
621
585
  type: 'error',
622
586
  message,
623
587
  detail: component.path,
624
588
  loc,
625
- }, from);
589
+ };
626
590
  }
627
591
  if (builtInComponents.includes(component.path)) {
628
592
  return null;
629
593
  }
630
594
  let found = this.tryComponent(component.path, from);
631
595
  if (found) {
632
- return this.add(found, from);
596
+ return found;
633
597
  }
634
- return this.add({
598
+ return {
635
599
  type: 'error',
636
600
  message: `Missing component`,
637
601
  detail: component.path,
638
602
  loc,
639
- }, from);
603
+ };
640
604
  }
641
605
  resolveDynamicHelper(helper, from, loc) {
642
606
  if (!this.staticHelpersEnabled) {
@@ -649,22 +613,22 @@ class CompatResolver {
649
613
  }
650
614
  let found = this.tryHelper(helperName, from);
651
615
  if (found) {
652
- return this.add(found, from);
616
+ return found;
653
617
  }
654
- return this.add({
618
+ return {
655
619
  type: 'error',
656
620
  message: `Missing helper`,
657
621
  detail: helperName,
658
622
  loc,
659
- }, from);
623
+ };
660
624
  }
661
625
  else {
662
- return this.add({
626
+ return {
663
627
  type: 'error',
664
628
  message: 'Unsafe dynamic helper',
665
629
  detail: `cannot statically analyze this expression`,
666
630
  loc,
667
- }, from);
631
+ };
668
632
  }
669
633
  }
670
634
  resolveDynamicModifier(modifier, from, loc) {
@@ -678,22 +642,22 @@ class CompatResolver {
678
642
  }
679
643
  let found = this.tryModifier(modifierName, from);
680
644
  if (found) {
681
- return this.add(found, from);
645
+ return found;
682
646
  }
683
- return this.add({
647
+ return {
684
648
  type: 'error',
685
649
  message: `Missing modifier`,
686
650
  detail: modifierName,
687
651
  loc,
688
- }, from);
652
+ };
689
653
  }
690
654
  else {
691
- return this.add({
655
+ return {
692
656
  type: 'error',
693
657
  message: 'Unsafe dynamic modifier',
694
658
  detail: `cannot statically analyze this expression`,
695
659
  loc,
696
- }, from);
660
+ };
697
661
  }
698
662
  }
699
663
  }
@@ -710,13 +674,4 @@ __decorate([
710
674
  (0, typescript_memoize_1.Memoize)()
711
675
  ], CompatResolver.prototype, "appPackage", null);
712
676
  exports.default = CompatResolver;
713
- function humanReadableFile(root, file) {
714
- if (!root.endsWith('/')) {
715
- root += '/';
716
- }
717
- if (file.startsWith(root)) {
718
- return file.slice(root.length);
719
- }
720
- return file;
721
- }
722
677
  //# sourceMappingURL=resolver.js.map