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