diff --git a/CHANGELOG.md b/CHANGELOG.md index 5016e52bc63..b7ad848ac0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,64 @@ # Ember Changelog +## v3.28.4 (October 22, 2021) + +- [#19798](https://github.com/emberjs/ember.js/pull/19798) More fixes for errors while precompiling inline templates (introduced in 3.28.2) +- [glimmerjs/glimmer-vm@0.80.3](https://github.com/glimmerjs/glimmer-vm/releases/tag/v0.80.3) Improve template compilation speed regression + +## v3.28.3 (October 22, 2021) + +- [#19799](https://github.com/emberjs/ember.js/pull/19799) / [glimmerjs/glimmer-vm#1354](https://github.com/glimmerjs/glimmer-vm/pull/1354) Fixes for errors while precompiling inline templates (introduced in 3.28.2) + +## v3.28.2 (October 21, 2021) + +- [glimmerjs/glimmer-vm#1351](https://github.com/glimmerjs/glimmer-vm/pull/1351) Support lexical scope in loose mode + +## v3.28.1 (August 30, 2021) + +- [#19733](https://github.com/emberjs/ember.js/pull/19733) [BUGFIX] Ensure that using `routerService.urlFor(...)` and `routerService.recognize(...)` does not error if the router is not fully initialized + +## v3.28.0 (August 9, 2021) + +- [#19697](https://github.com/emberjs/ember.js/pull/19697) [BUGFIX] Ensure `deserializeQueryParam` is called for lazy routes +- [#19681](https://github.com/emberjs/ember.js/pull/19681) [BUGFIX] Restore previous hash behavior +- [#19685](https://github.com/emberjs/ember.js/pull/19685) [BUGFIX] Fix memory leak in RouterService +- [#19690](https://github.com/emberjs/ember.js/pull/19690) [BUGFIX] Deprecates String.prototype.htmlSafe targeting Ember 4.0, as intended by the original deprecation. +- [#19584](https://github.com/emberjs/ember.js/pull/19584) [BUGFIX] Ensure hash objects correctly entangle as dependencies +- [#19491](https://github.com/emberjs/ember.js/pull/19491) [BUGFIX] Fix `owner.lookup` `owner.register` behavior with `singleton: true` option +- [#19472](https://github.com/emberjs/ember.js/pull/19472) [BUGFIX] Prevent transformation of block params called `attrs` + +## v3.27.5 (June 10, 2021) + +- [#19597](https://github.com/emberjs/ember.js/pull/19597) [BIGFIX] Fix `` with nested children + +## v3.27.4 (June 9, 2021) + +- [#19594](https://github.com/emberjs/ember.js/pull/19594) [BUGFIX] Revert lazy hash changes +- [#19596](https://github.com/emberjs/ember.js/pull/19596) [DOC] Fix "Dormant" addon warning typo + +## v3.27.3 (June 3, 2021) + +- [#19565](https://github.com/emberjs/ember.js/pull/19565) [BUGFIX] Ensures that `computed` can depend on dynamic `(hash` keys +- [#19571](https://github.com/emberjs/ember.js/pull/19571) [BUGFIX] Extend `Route.prototype.transitionTo` deprecation until 5.0.0 +- [#19586](https://github.com/emberjs/ember.js/pull/19586) [BUGFIX] Fix Embroider compatibility + +### v3.27.2 (May 27, 2021) + +- [#19511](https://github.com/emberjs/ember.js/pull/19511) / [#19548](https://github.com/emberjs/ember.js/pull/19548) [BUGFIX] Makes the (hash) helper lazy +- [#19530](https://github.com/emberjs/ember.js/pull/19530) [DOC] fix passing params to named blocks examples +- [#19536](https://github.com/emberjs/ember.js/pull/19536) [BUGFIX] Fix `computed.*` deprecation message to include the correct import path +- [#19544](https://github.com/emberjs/ember.js/pull/19544) [BUGFIX] Use explicit this in helper test blueprints +- [#19555](https://github.com/emberjs/ember.js/pull/19555) [BUGFIX] Improve class based tranform deprecation message +- [#19557](https://github.com/emberjs/ember.js/pull/19557) [BUGFIX] Refine Ember Global deprecation message +- [#19564](https://github.com/emberjs/ember.js/pull/19564) [BUGFIX] Improve computed.* and run.* deprecation message (IE11) + +### v3.27.1 (May 13, 2021) + +- [#19540](https://github.com/emberjs/ember.js/pull/19540) [BUGFIX] Ensure ember-testing is loaded lazily +- [#19541](https://github.com/emberjs/ember.js/pull/19541) [BUGFIX] Add missing metadata for some deprecations enabled in 3.27.0 +- [#19541](https://github.com/emberjs/ember.js/pull/19541) [BUGFIX] Ensure passing `@href` to `` throws an error +- [#19541](https://github.com/emberjs/ember.js/pull/19541) [CLEANUP] Consistently use https://deprecations.emberjs.com/ in deprecation URLs + ### v3.27.0 (May 3, 2021) - [#19309](https://github.com/emberjs/ember.js/pull/19309) / [#19487](https://github.com/emberjs/ember.js/pull/19487) / [#19474](https://github.com/emberjs/ember.js/pull/19474) [FEATURE] Enable `(helper` and `(modifier` helpers per [RFC #432](https://github.com/emberjs/rfcs/blob/master/text/0432-contextual-helpers.md). @@ -10,7 +69,7 @@ - [#19442](https://github.com/emberjs/ember.js/pull/19442) [DEPRECATION] Add deprecation for `Route#render` method per [RFC #418](https://github.com/emberjs/rfcs/blob/master/text/0418-deprecate-route-render-methods.md). - [#19429](https://github.com/emberjs/ember.js/pull/19429) [DEPRECATION] `registerPlugin` / `unregisterPlugin` and legacy class based AST plugins (private APIs) - [#19499](https://github.com/emberjs/ember.js/pull/19499) [DEPRECATION] Deprecate `@foo={{helper}}` per [RFC #496](https://github.com/emberjs/rfcs/blob/master/text/0496-handlebars-strict-mode.md#3-no-implicit-invocation-of-argument-less-helpers). -- [#19499](https://github.com/emberjs/ember.js/pull/19499) [BUGFIX] Update rendering engine to `@glimmer/*` 0.78.2 for fixes including: +- [#19499](https://github.com/emberjs/ember.js/pull/19499) [BUGFIX] Update rendering engine to `@glimmer/*` 0.78.2 for fixes including: - `<:else>` and `<:inverse>` should be aliases (see https://github.com/glimmerjs/glimmer-vm/pull/1296) - Fix nested calls to helpers in dynamic helpers (see https://github.com/glimmerjs/glimmer-vm/pull/1293) - [#19477](https://github.com/emberjs/ember.js/pull/19477) [BUGFIX] Allow `` to override internal assertion @@ -102,7 +161,7 @@ ### v3.24.0 (December 28, 2020) -- [#19224](https://github.com/emberjs/ember.js/pull/19224) [FEATURE] Add `{{page-title}}` helper to route template blueprints to implement [RFC #0654](https://github.com/emberjs/rfcs/blob/master/text/0645-add-ember-page-title-addon.md). +- [#19224](https://github.com/emberjs/ember.js/pull/19224) [FEATURE] Add `{{page-title}}` helper to route template blueprints to implement [RFC #0654](https://github.com/emberjs/rfcs/blob/master/text/0645-add-ember-page-title-addon.md). - [#19133](https://github.com/emberjs/ember.js/pull/19133) [FEATURE / DEPRECATION] Add new options to `deprecate()` for `for` and `since` and deprecate using `deprecate()` without those options per the [Deprecation Staging RFC](https://github.com/emberjs/rfcs/blob/master/text/0649-deprecation-staging.md). - [#19211](https://github.com/emberjs/ember.js/pull/19211) [DEPRECATION] Deprecate `Ember.String.loc` and `{{loc}}` per the [Deprecate Ember String RFC](https://github.com/emberjs/rfcs/blob/master/text/0236-deprecation-ember-string.md). - [#19234](https://github.com/emberjs/ember.js/pull/19234) [DEPRECATION] Deprecate String Prototype extensions per the [Deprecate Ember String RFC](https://github.com/emberjs/rfcs/blob/master/text/0236-deprecation-ember-string.md). @@ -126,7 +185,7 @@ - [#19160](https://github.com/emberjs/ember.js/pull/19160) / [#19182](https://github.com/emberjs/ember.js/pull/19182) [FEATURE] Implements the helper manager feature specified in the [Helper Managers RFC](https://github.com/emberjs/rfcs/blob/master/text/0625-helper-managers.md). - [#19171](https://github.com/emberjs/ember.js/pull/19171) / [#19182](https://github.com/emberjs/ember.js/pull/19182) [FEATURE] Implements `invokeHelper` from the [JavaScript Helper Invocation API RFC](https://github.com/emberjs/rfcs/blob/master/text/0626-invoke-helper.md). -- [#19148](https://github.com/emberjs/ember.js/pull/19148) / [#19119](https://github.com/emberjs/ember.js/pull/19119) Update rendering engine to `@glimmer/*` 0.62.1 +- [#19148](https://github.com/emberjs/ember.js/pull/19148) / [#19119](https://github.com/emberjs/ember.js/pull/19119) Update rendering engine to `@glimmer/*` 0.62.1 - [#19122](https://github.com/emberjs/ember.js/pull/19122) [BUGFIX] Prevents dynamic invocations of string values when referenced directly in angle brackets - [#19136](https://github.com/emberjs/ember.js/pull/19136) [BUGFIX] Update router microlib to improve Transition related debugging - [#19173](https://github.com/emberjs/ember.js/pull/19173) [BUGFIX] Enforce usage of `capabilities` generation. @@ -155,7 +214,7 @@ - [#19062](https://github.com/emberjs/ember.js/pull/19062) / [#19068](https://github.com/emberjs/ember.js/pull/19068) [FEATURE] Add @ember/destroyable feature from the [Destroyables RFC](https://github.com/emberjs/rfcs/blob/master/text/0580-destroyables.md). - [#18984](https://github.com/emberjs/ember.js/pull/18984) / [#19067](https://github.com/emberjs/ember.js/pull/19067) [FEATURE] Add low-level Cache API per [Autotracking Memoization RFC](https://github.com/emberjs/rfcs/blob/master/text/0615-autotracking-memoization.md) - [#19086](https://github.com/emberjs/ember.js/pull/19086) [FEATURE] Pass transition object to activate/deactivate hooks and events -- [#19094](https://github.com/emberjs/ember.js/pull/19094) [BUGFIX] Fix RouterService#isActive() to work with tracking +- [#19094](https://github.com/emberjs/ember.js/pull/19094) [BUGFIX] Fix RouterService#isActive() to work with tracking - [#19163](https://github.com/emberjs/ember.js/pull/19163) [BUGFIX] Use args proxy for modifier managers. - [#19170](https://github.com/emberjs/ember.js/pull/19170) [BUGFIX] Make modifier manager 3.22 accept the resolved value directly. - [#19124](https://github.com/emberjs/ember.js/pull/19124) [BUGFIX] Fix rendering engine usage within a `fastboot` sandbox @@ -178,7 +237,7 @@ - [#18993](https://github.com/emberjs/ember.js/pull/18993) [DEPRECATION] Deprecate `getWithDefault` per [RFC #554](https://github.com/emberjs/rfcs/blob/master/text/0554-deprecate-getwithdefault.md). - [#19087](https://github.com/emberjs/ember.js/pull/19087) [BUGFIX] Generated initializer tests no longer causes a deprecation warning -- [#17571](https://github.com/emberjs/ember.js/pull/17571) [BUGFIX] Avoid tampering `queryParam` argument in RouterService#isActive +- [#17571](https://github.com/emberjs/ember.js/pull/17571) [BUGFIX] Avoid tampering `queryParam` argument in RouterService#isActive ### v3.20.6 (November 11, 2020) @@ -236,7 +295,7 @@ - Fix: Rerender an `{{#each`s block only when the specific item has changed - [#18958](https://github.com/emberjs/ember.js/pull/18958) [BUGFIX] Ensure AST transforms using `in-element` work properly. - [#18960](https://github.com/emberjs/ember.js/pull/18960) [BUGFIX] More assertions for Application lifecycle methods -- [#18919](https://github.com/emberjs/ember.js/pull/18919) [BUGFIX] Add error for modifier manager without capabilities. +- [#18919](https://github.com/emberjs/ember.js/pull/18919) [BUGFIX] Add error for modifier manager without capabilities. - [#18828](https://github.com/emberjs/ember.js/pull/18828) [BUGFIX] Prepend 'TODO: ' to 'Replace this with your real tests' comments in generated tests - [#18353](https://github.com/emberjs/ember.js/pull/18353) [BUGFIX] Improve `fn` & `on` undefined callback message - [#18824](https://github.com/emberjs/ember.js/pull/18824) [CLEANUP] Remove deprecated private `window.ENV` diff --git a/blueprints/helper-test/mocha-0.12-files/__root__/__testType__/__collection__/__name__-test.js b/blueprints/helper-test/mocha-0.12-files/__root__/__testType__/__collection__/__name__-test.js index 5e27688598d..051de3a18f5 100644 --- a/blueprints/helper-test/mocha-0.12-files/__root__/__testType__/__collection__/__name__-test.js +++ b/blueprints/helper-test/mocha-0.12-files/__root__/__testType__/__collection__/__name__-test.js @@ -19,7 +19,7 @@ describe('<%= friendlyTestName %>', function() { // `); this.set('inputValue', '1234'); - this.render(hbs`{{<%= dasherizedModuleName %> inputValue}}`); + this.render(hbs`{{<%= dasherizedModuleName %> this.inputValue}}`); expect(this.$().text().trim()).to.equal('1234'); }); diff --git a/blueprints/helper-test/mocha-files/__root__/__testType__/__collection__/__name__-test.js b/blueprints/helper-test/mocha-files/__root__/__testType__/__collection__/__name__-test.js index 0e9276ae197..89d55cf614c 100644 --- a/blueprints/helper-test/mocha-files/__root__/__testType__/__collection__/__name__-test.js +++ b/blueprints/helper-test/mocha-files/__root__/__testType__/__collection__/__name__-test.js @@ -19,7 +19,7 @@ describeComponent('<%= dasherizedModuleName %>', 'helper:<%= dasherizedModuleNam // `); this.set('inputValue', '1234'); - this.render(hbs`{{<%= dasherizedModuleName %> inputValue}}`); + this.render(hbs`{{<%= dasherizedModuleName %> this.inputValue}}`); expect(this.$().text().trim()).to.equal('1234'); }); diff --git a/blueprints/helper-test/mocha-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js b/blueprints/helper-test/mocha-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js index 62a21879351..9b6702f1fd8 100644 --- a/blueprints/helper-test/mocha-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js +++ b/blueprints/helper-test/mocha-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js @@ -11,7 +11,7 @@ describe('<%= friendlyTestName %>', function() { it('renders', async function() { this.set('inputValue', '1234'); - await render(hbs`{{<%= dasherizedModuleName %> inputValue}}`); + await render(hbs`{{<%= dasherizedModuleName %> this.inputValue}}`); expect(this.element.textContent.trim()).to.equal('1234'); }); diff --git a/blueprints/helper-test/qunit-files/__root__/__testType__/__collection__/__name__-test.js b/blueprints/helper-test/qunit-files/__root__/__testType__/__collection__/__name__-test.js index 2182592ebcd..6bef509e111 100644 --- a/blueprints/helper-test/qunit-files/__root__/__testType__/__collection__/__name__-test.js +++ b/blueprints/helper-test/qunit-files/__root__/__testType__/__collection__/__name__-test.js @@ -9,7 +9,7 @@ moduleForComponent('<%= dasherizedModuleName %>', 'helper:<%= dasherizedModuleNa test('it renders', function(assert) { this.set('inputValue', '1234'); - this.render(hbs`{{<%= dasherizedModuleName %> inputValue}}`); + this.render(hbs`{{<%= dasherizedModuleName %> this.inputValue}}`); assert.equal(this.$().text().trim(), '1234'); });<% } else if (testType == 'unit') { %> diff --git a/blueprints/helper-test/qunit-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js b/blueprints/helper-test/qunit-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js index 4ba1b477266..baf3d449ad1 100644 --- a/blueprints/helper-test/qunit-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js +++ b/blueprints/helper-test/qunit-rfc-232-files/__root__/__testType__/__collection__/__name__-test.js @@ -10,7 +10,7 @@ module('<%= friendlyTestName %>', function(hooks) { test('it renders', async function(assert) { this.set('inputValue', '1234'); - await render(hbs`{{<%= dasherizedModuleName %> inputValue}}`); + await render(hbs`{{<%= dasherizedModuleName %> this.inputValue}}`); assert.dom(this.element).hasText('1234'); }); diff --git a/blueprints/initializer-test/qunit-rfc-232-files/__root__/__testType__/__path__/__name__-test.js b/blueprints/initializer-test/qunit-rfc-232-files/__root__/__testType__/__path__/__name__-test.js index b5bd4650aee..4fe80c2b1d9 100644 --- a/blueprints/initializer-test/qunit-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +++ b/blueprints/initializer-test/qunit-rfc-232-files/__root__/__testType__/__path__/__name__-test.js @@ -1,27 +1,32 @@ import Application from '@ember/application'; +import config from '<%= modulePrefix %>/config/environment'; import { initialize } from '<%= modulePrefix %>/initializers/<%= dasherizedModuleName %>'; import { module, test } from 'qunit'; import Resolver from 'ember-resolver'; <% if (destroyAppExists) { %>import destroyApp from '../../helpers/destroy-app';<% } else { %>import { run } from '@ember/runloop';<% } %> -module('<%= friendlyTestName %>', function(hooks) { - hooks.beforeEach(function() { - this.TestApplication = class TestApplication extends Application {} +module('<%= friendlyTestName %>', function (hooks) { + hooks.beforeEach(function () { + this.TestApplication = class TestApplication extends Application { + modulePrefix = config.modulePrefix; + podModulePrefix = config.podModulePrefix; + Resolver = Resolver; + }; this.TestApplication.initializer({ name: 'initializer under test', - initialize + initialize, }); - this.application = this.TestApplication.create({ autoboot: false, Resolver }); + this.application = this.TestApplication.create({ autoboot: false }); }); - hooks.afterEach(function() { + hooks.afterEach(function () { <% if (destroyAppExists) { %>destroyApp(this.application);<% } else { %>run(this.application, 'destroy');<% } %> }); // TODO: Replace this with your real tests. - test('it works', async function(assert) { + test('it works', async function (assert) { await this.application.boot(); assert.ok(true); diff --git a/blueprints/instance-initializer-test/qunit-rfc-232-files/__root__/__testType__/__path__/__name__-test.js b/blueprints/instance-initializer-test/qunit-rfc-232-files/__root__/__testType__/__path__/__name__-test.js index 9e09050e437..e200288b65b 100644 --- a/blueprints/instance-initializer-test/qunit-rfc-232-files/__root__/__testType__/__path__/__name__-test.js +++ b/blueprints/instance-initializer-test/qunit-rfc-232-files/__root__/__testType__/__path__/__name__-test.js @@ -1,27 +1,32 @@ import Application from '@ember/application'; +import config from '<%= modulePrefix %>/config/environment'; import { initialize } from '<%= modulePrefix %>/instance-initializers/<%= dasherizedModuleName %>'; import { module, test } from 'qunit'; import Resolver from 'ember-resolver'; <% if (destroyAppExists) { %>import destroyApp from '../../helpers/destroy-app';<% } else { %>import { run } from '@ember/runloop';<% } %> -module('<%= friendlyTestName %>', function(hooks) { - hooks.beforeEach(function() { - this.TestApplication = class TestApplication extends Application {} +module('<%= friendlyTestName %>', function (hooks) { + hooks.beforeEach(function () { + this.TestApplication = class TestApplication extends Application { + modulePrefix = config.modulePrefix; + podModulePrefix = config.podModulePrefix; + Resolver = Resolver; + }; this.TestApplication.instanceInitializer({ name: 'initializer under test', - initialize + initialize, }); - this.application = this.TestApplication.create({ autoboot: false, Resolver }); + this.application = this.TestApplication.create({ autoboot: false }); this.instance = this.application.buildInstance(); }); - hooks.afterEach(function() { + hooks.afterEach(function () { <% if (destroyAppExists) { %>destroyApp(this.instance);<% } else { %>run(this.instance, 'destroy');<% } %> <% if (destroyAppExists) { %>destroyApp(this.application);<% } else { %>run(this.application, 'destroy');<% } %> }); // TODO: Replace this with your real tests. - test('it works', async function(assert) { + test('it works', async function (assert) { await this.instance.boot(); assert.ok(true); diff --git a/lib/index.js b/lib/index.js index 6be64ec350e..ce887fbeb22 100644 --- a/lib/index.js +++ b/lib/index.js @@ -10,6 +10,7 @@ const buildStripClassCallcheckPlugin = require('./build-strip-class-callcheck-pl const injectBabelHelpers = require('./transforms/inject-babel-helpers').injectBabelHelpers; const debugTree = require('broccoli-debug').buildDebugCallback('ember-source:addon'); const vmBabelPlugins = require('@glimmer/vm-babel-plugins'); +const Overrides = require('./overrides'); const PRE_BUILT_TARGETS = [ 'last 1 Chrome versions', @@ -65,10 +66,21 @@ module.exports = { paths, absolutePaths, _jqueryIntegrationEnabled: true, + _overrideTree: undefined, included() { this._super.included.apply(this, arguments); + let overrides = Overrides.for(this.project); + + if (overrides.hasOverrides) { + this._overrideTree = overrides.toTree(); + } + + if (overrides.hasBuildTimeWarning) { + this.ui.writeWarnLine('[DEPRECATION] ' + overrides.buildTimeWarning); + } + const { has } = require('@ember/edition-utils'); let optionalFeatures = this.project.addons.find((a) => a.name === '@ember/optional-features'); @@ -209,6 +221,10 @@ module.exports = { }, buildEmberBundles(tree, isProduction) { + if (this._overrideTree) { + tree = new MergeTrees([tree, this._overrideTree], { overwrite: true }); + } + let packages = this.transpileTree(new Funnel(tree, { srcDir: 'packages' }), isProduction); let dependencies = this.transpileTree( @@ -244,7 +260,7 @@ module.exports = { return new MergeTrees([ concatBundle(emberFiles, { outputFile: 'ember.js', - footer: "require('@ember/-internals/bootstrap');", + footer: `require('@ember/-internals/bootstrap')`, }), concatBundle(emberTestingFiles, { @@ -281,7 +297,7 @@ module.exports = { if (targets.includes('ie 11')) { this.ui.writeWarnLine( - 'Internet Explorer 11 is listed in your compilation targets, but it will no longer be supported in the next major version of Ember. Please update your targets to remove IE 11 and include new targets that are within the updated support policy. For details on the new browser support policy, see:\n\n - The official documentation: http://emberjs.com/browser-support\n - the deprecation guide: https://emberjs.com/deprecations/v3.x#toc_3-0-browser-support-policy\n' + 'Internet Explorer 11 is listed in your compilation targets, but it will no longer be supported in the next major version of Ember. Please update your targets to remove IE 11 and include new targets that are within the updated support policy. For details on the new browser support policy, see:\n\n - The official documentation: http://emberjs.com/browser-support\n - the deprecation guide: https://deprecations.emberjs.com/v3.x#toc_3-0-browser-support-policy\n' ); } @@ -289,10 +305,13 @@ module.exports = { if ( !isProduction && + // do the running applications targets match our prebuilt assets targets? PRE_BUILT_TARGETS.every((target) => targets.includes(target)) && targets.length === PRE_BUILT_TARGETS.length && // if node is defined in targets we can't reliably use the prebuilt bundles - !targetNode + !targetNode && + // if we have a custom override (e.g. for globals deprecations) we can't use the prebuilt bundles + !this._overrideTree ) { ember = new Funnel(tree, { destDir: 'ember', diff --git a/lib/overrides.js b/lib/overrides.js new file mode 100644 index 00000000000..4eaed77a0c8 --- /dev/null +++ b/lib/overrides.js @@ -0,0 +1,411 @@ +const createFile = require('broccoli-file-creator'); +const semver = require('semver'); +const validSemverRange = require('semver/ranges/valid'); + +const DEFAULT_OPTIONS = Object.freeze({ + showAllEmberGlobalDeprecations: false, + showAllDotAccessDeprecations: false, +}); + +function* walkAddonTree(project, pathToAddon = []) { + for (let addon of project.addons) { + yield [addon, pathToAddon]; + yield* walkAddonTree(addon, [...pathToAddon, `${addon.name}@${addon.pkg.version}`]); + } +} + +function requirementFor(pkg, deps = {}) { + return deps[pkg]; +} + +const KNWON_DORMANT_ADDONS = Object.freeze([ + 'ember-angle-bracket-invocation-polyfill', + 'ember-fn-helper-polyfill', + 'ember-in-element-polyfill', + 'ember-named-blocks-polyfill', + 'ember-on-modifier', +]); +module.exports = class Overrides { + static for(project, env = process.env) { + if (env.EMBER_ENV === 'production') { + return new Overrides([]); + } else { + return new Overrides(Overrides.addonsInfoFor(project), { + showAllEmberGlobalDeprecations: env.EMBER_GLOBAL_DEPRECATIONS === 'all', + showAllDotAccessDeprecations: + env.EMBER_RUNLOOP_AND_COMPUTED_DOT_ACCESS_DEPRECATIONS === 'all', + }); + } + } + + static *addonsInfoFor(project) { + for (let [addon, pathToAddon] of walkAddonTree(project)) { + let version = addon.pkg.version; + + if (addon.name === 'ember-cli-babel' && semver.lt(version, '7.26.6')) { + if (addon.parent === project) { + let requirement = + requirementFor('ember-cli-babel', project.pkg.dependencies) || + requirementFor('ember-cli-babel', project.pkg.devDependencies); + + let validRange = validSemverRange(requirement); + let compatible = validRange ? semver.satisfies('7.26.6', requirement) : true; + + yield { + parent: `${project.name()} (your app)`, + topLevel: null, + version, + requirement, + compatible, + dormant: false, + path: [], + }; + } else { + let requirement = requirementFor('ember-cli-babel', addon.parent.pkg.dependencies); + let validRange = validSemverRange(requirement); + let compatible = validRange ? semver.satisfies('7.26.6', requirement) : true; + let dormant = + KNWON_DORMANT_ADDONS.includes(addon.parent.name) || + (addon.parent._fileSystemInfo + ? addon.parent._fileSystemInfo().hasJSFiles === false + : false); + + let topLevelAddon = addon.parent; + + while (topLevelAddon.parent !== project) { + topLevelAddon = topLevelAddon.parent; + } + + yield { + parent: `${addon.parent.name}@${addon.parent.pkg.version}`, + topLevel: topLevelAddon.name, + version, + requirement, + compatible, + dormant, + path: pathToAddon, + }; + } + } + } + } + + static printList(list, indent = '') { + let output = ''; + + for (let item of list) { + if (Array.isArray(item)) { + output += `${indent}* ${item[0]}\n`; + output += Overrides.printList(item[1], indent + ' '); + } else { + output += `${indent}* ${item}\n`; + } + } + + return output; + } + + constructor(addonsInfo, options = {}) { + let _addonsInfo = []; + let projectInfo; + let groupedByTopLevel = Object.create(null); + let groupedByVersion = Object.create(null); + + for (let info of addonsInfo) { + _addonsInfo.push(info); + + if (info.topLevel === null) { + projectInfo = info; + } else { + let topLevel = info.topLevel; + let addons = groupedByTopLevel[topLevel] || []; + groupedByTopLevel[topLevel] = [...addons, info]; + } + + let version = info.version; + + let group = groupedByVersion[version] || Object.create(null); + groupedByVersion[version] = group; + + let addons = group[info.parent] || []; + group[info.parent] = [...addons, info]; + } + + let dormantTopLevelAddons = []; + let compatibleTopLevelAddons = []; + let incompatibleTopLevelAddons = []; + + let suggestions = []; + let hasActionableSuggestions = false; + + if (_addonsInfo.length > 0) { + for (let addon of Object.keys(groupedByTopLevel)) { + let group = groupedByTopLevel[addon]; + + if (group.every((info) => info.dormant)) { + dormantTopLevelAddons.push(addon); + } else if (group.every((info) => info.compatible)) { + compatibleTopLevelAddons.push(addon); + } else { + incompatibleTopLevelAddons.push(addon); + } + } + + if (projectInfo) { + suggestions.push('Upgrade your `devDependencies` on `ember-cli-babel` to `^7.26.6`.'); + hasActionableSuggestions = true; + } else if (compatibleTopLevelAddons.length > 0) { + // Only show the compatible addons if the project itself is up-to-date, because updating the + // project's own dependency on ember-cli-babel to latest may also get these addons to use it + // as well. Otherwise, there is an unnecessary copy in the tree and it needs to be deduped. + suggestions.push( + 'If using yarn, run `npx yarn-deduplicate --packages ember-cli-babel` followed by `yarn install`.' + ); + + suggestions.push('If using npm, run `npm dedupe`.'); + + hasActionableSuggestions = true; + } + + if (incompatibleTopLevelAddons.length > 0) { + suggestions.push([ + 'Upgrade the following addons to the latest version:', + incompatibleTopLevelAddons, + ]); + + hasActionableSuggestions = true; + } + + if (!hasActionableSuggestions) { + suggestions.push([ + 'Upgrade the following addons to the latest version, if available:', + dormantTopLevelAddons, + ]); + } + } + + this.addonsInfo = _addonsInfo; + this.projectInfo = projectInfo; + this.groupedByTopLevel = groupedByTopLevel; + this.groupedByVersion = groupedByVersion; + this.dormantTopLevelAddons = dormantTopLevelAddons; + this.compatibleTopLevelAddons = compatibleTopLevelAddons; + this.incompatibleTopLevelAddons = incompatibleTopLevelAddons; + this.suggestions = suggestions; + this.hasActionableSuggestions = hasActionableSuggestions; + this.options = { ...DEFAULT_OPTIONS, ...options }; + } + + get hasOverrides() { + return this.addonsInfo.length > 0; + } + + get hasBuildTimeWarning() { + return this.hasActionableSuggestions; + } + + get hasCompatibleAddons() { + return this.addonsInfo.some((info) => info.compatible); + } + + get hasDormantAddons() { + return this.addonsInfo.some((info) => info.dormant); + } + + get showAllEmberGlobalDeprecations() { + return !this.hasActionableSuggestions || this.options.showAllEmberGlobalDeprecations; + } + + get showAllDotAccessDeprecations() { + return !this.hasActionableSuggestions || this.options.showAllDotAccessDeprecations; + } + + get details() { + let details = + '\n### Details ###\n\n' + + 'Prior to v7.26.6, ember-cli-babel sometimes transpiled imports into the equivalent Ember Global API, ' + + 'potentially triggering this deprecation message indirectly, ' + + 'even when you did not observe these deprecated usages in your code.\n\n' + + 'The following outdated versions are found in your project:\n\n' + + Overrides.printList(this.outdated); + + if (this.hasDormantAddons) { + details += + '\nNote: Addons marked as "Dormant" does not appear to have any JavaScript files. ' + + 'Therefore, even if they are using an old version ember-cli-babel, they are ' + + 'unlikely to be the culprit of this deprecation and can likely be ignored.\n'; + } + + if (this.hasCompatibleAddons) { + details += `\nNote: Addons marked as "Compatible" are already compatible with ember-cli-babel@7.26.6. `; + + if (this.projectInfo) { + details += 'Try upgrading your `devDependencies` on `ember-cli-babel` to `^7.26.6`.\n'; + } else { + details += + 'If using yarn, try running `npx yarn-deduplicate --packages ember-cli-babel` followed by `yarn install`.' + + 'If using npm, try running `npm dedupe`.\n'; + } + } + + return details; + } + + get outdated() { + let list = []; + + let groupedByVersion = this.groupedByVersion; + + for (let version of Object.keys(groupedByVersion).sort(semver.compare)) { + let addons = []; + + for (let parent of Object.keys(groupedByVersion[version]).sort()) { + let info = groupedByVersion[version][parent][0]; + let addon; + let details = []; + + if (info.dormant) { + addon = `${parent} (Dormant)`; + } else if (info.compatible) { + addon = `${parent} (Compatible)`; + } else { + addon = parent; + } + + details.push(`Depends on ember-cli-babel@${info.requirement}`); + + for (let info of groupedByVersion[version][parent]) { + let adddedBy = info.path.slice(0, -1); + + if (adddedBy.length) { + details.push(`Added by ${adddedBy.join(' > ')}`); + } + } + + addons.push([addon, details]); + } + + list.push([`ember-cli-babel@${version}, currently used by:`, addons]); + } + + return list; + } + + get globalMessage() { + let message = + 'Usage of the Ember Global is deprecated. ' + + 'You should import the Ember module or the specific API instead.\n\n' + + 'See https://deprecations.emberjs.com/v3.x/#toc_ember-global for details.\n\n' + + 'Usages of the Ember Global may be caused by an outdated ember-cli-babel dependency. ' + + 'The following steps may help:\n\n' + + Overrides.printList(this.suggestions); + + if (!this.showAllEmberGlobalDeprecations) { + message += + '\n### Important ###\n\n' + + 'In order to avoid repeatedly showing the same deprecation messages, ' + + 'no further deprecation messages will be shown for usages of the Ember Global ' + + 'until ember-cli-babel is upgraded to v7.26.6 or above.\n\n' + + 'To see all instances of this deprecation message, ' + + 'set the `EMBER_GLOBAL_DEPRECATIONS` environment variable to "all", ' + + 'e.g. `EMBER_GLOBAL_DEPRECATIONS=all ember test`.\n'; + } + + message += this.details; + + return message; + } + + get buildTimeWarning() { + if (this.hasBuildTimeWarning) { + return `[DEPRECATION] ${this.globalMessage}`; + } else { + return ''; + } + } + + toTree() { + if (this.hasOverrides) { + return createFile('packages/@ember/-internals/overrides/index.js', this.toModule()); + } + } + + toModule() { + return ` + export let onEmberGlobalAccess; + export let onComputedDotAccess; + export let onRunloopDotAccess; + + ${this.toJS()}; + `; + } + + toJS() { + return ` + function once(callback) { + let called = false; + + return (...args) => { + if (called) { + return null; + } else { + called = true; + return callback(...args); + } + }; + } + + ${this.onDotAcces} + + onEmberGlobalAccess = ${this.onEmberGlobalAccess}; + onComputedDotAccess = onDotAccess; + onRunloopDotAccess = onDotAccess; + + if (!${this.showAllEmberGlobalDeprecations}) { + onEmberGlobalAccess = once(onEmberGlobalAccess); + } + + if (!${this.showAllDotAccessDeprecations}) { + onComputedDotAccess = once(onComputedDotAccess); + onRunloopDotAccess = once(onRunloopDotAccess); + } + `; + } + + get onEmberGlobalAccess() { + return ` + function onEmberGlobalAccess() { + return ${JSON.stringify(this.globalMessage)}; + } + `; + } + + get onDotAcces() { + return ` + function onDotAccess(dotKey, importKey, module) { + let message = + 'Using \`' + dotKey + '\` has been deprecated. Instead, import the value directly from ' + module + ':\\n\\n' + + ' import { ' + importKey + ' } from \\'' + module + '\\';\\n\\n' + + 'These usages may be caused by an outdated ember-cli-babel dependency. ' + + 'Usages of the Ember Global may be caused by an outdated ember-cli-babel dependency. ' + + 'The following steps may help:\\n\\n' + + ${JSON.stringify(Overrides.printList(this.suggestions))}; + + if (!${this.showAllDotAccessDeprecations}) { + message += + '\\n### Important ###\\n\\n' + + 'In order to avoid repeatedly showing the same deprecation messages, ' + + 'no further deprecation messages will be shown for theses deprecated usages ' + + 'until ember-cli-babel is upgraded to v7.26.6 or above.\\n\\n' + + 'To see all instances of this deprecation message, ' + + 'set the \`EMBER_RUNLOOP_AND_COMPUTED_DOT_ACCESS_DEPRECATIONS\` environment variable to "all", ' + + 'e.g. \`EMBER_RUNLOOP_AND_COMPUTED_DOT_ACCESS_DEPRECATIONS=all ember test\`.\\n'; + } + + message += ${JSON.stringify(this.details)}; + + return message; + } + `; + } +}; diff --git a/node-tests/fixtures/helper-test/integration.js b/node-tests/fixtures/helper-test/integration.js index ad4f7e3782b..9abe683c279 100644 --- a/node-tests/fixtures/helper-test/integration.js +++ b/node-tests/fixtures/helper-test/integration.js @@ -9,7 +9,7 @@ moduleForComponent('foo/bar-baz', 'helper:foo/bar-baz', { test('it renders', function(assert) { this.set('inputValue', '1234'); - this.render(hbs`{{foo/bar-baz inputValue}}`); + this.render(hbs`{{foo/bar-baz this.inputValue}}`); assert.equal(this.$().text().trim(), '1234'); }); diff --git a/node-tests/fixtures/helper-test/mocha-0.12.js b/node-tests/fixtures/helper-test/mocha-0.12.js index d2eb4578af0..b78ee50dc92 100644 --- a/node-tests/fixtures/helper-test/mocha-0.12.js +++ b/node-tests/fixtures/helper-test/mocha-0.12.js @@ -19,7 +19,7 @@ describe('Integration | Helper | foo/bar-baz', function() { // `); this.set('inputValue', '1234'); - this.render(hbs`{{foo/bar-baz inputValue}}`); + this.render(hbs`{{foo/bar-baz this.inputValue}}`); expect(this.$().text().trim()).to.equal('1234'); }); diff --git a/node-tests/fixtures/helper-test/mocha-rfc232.js b/node-tests/fixtures/helper-test/mocha-rfc232.js index 9944e574437..2337d5c74f2 100644 --- a/node-tests/fixtures/helper-test/mocha-rfc232.js +++ b/node-tests/fixtures/helper-test/mocha-rfc232.js @@ -11,7 +11,7 @@ describe('Integration | Helper | foo/bar-baz', function() { it('renders', async function() { this.set('inputValue', '1234'); - await render(hbs`{{foo/bar-baz inputValue}}`); + await render(hbs`{{foo/bar-baz this.inputValue}}`); expect(this.element.textContent.trim()).to.equal('1234'); }); diff --git a/node-tests/fixtures/helper-test/mocha.js b/node-tests/fixtures/helper-test/mocha.js index bece512a42d..9e3c985f0e6 100644 --- a/node-tests/fixtures/helper-test/mocha.js +++ b/node-tests/fixtures/helper-test/mocha.js @@ -19,7 +19,7 @@ describeComponent('foo/bar-baz', 'helper:foo/bar-baz', // `); this.set('inputValue', '1234'); - this.render(hbs`{{foo/bar-baz inputValue}}`); + this.render(hbs`{{foo/bar-baz this.inputValue}}`); expect(this.$().text().trim()).to.equal('1234'); }); diff --git a/node-tests/fixtures/helper-test/rfc232.js b/node-tests/fixtures/helper-test/rfc232.js index e1b7290a2f3..c39592e478c 100644 --- a/node-tests/fixtures/helper-test/rfc232.js +++ b/node-tests/fixtures/helper-test/rfc232.js @@ -10,7 +10,7 @@ module('Integration | Helper | foo/bar-baz', function(hooks) { test('it renders', async function(assert) { this.set('inputValue', '1234'); - await render(hbs`{{foo/bar-baz inputValue}}`); + await render(hbs`{{foo/bar-baz this.inputValue}}`); assert.dom(this.element).hasText('1234'); }); diff --git a/node-tests/fixtures/initializer-test/rfc232.js b/node-tests/fixtures/initializer-test/rfc232.js index 709ea9aaf46..78ef00434d4 100644 --- a/node-tests/fixtures/initializer-test/rfc232.js +++ b/node-tests/fixtures/initializer-test/rfc232.js @@ -1,27 +1,32 @@ import Application from '@ember/application'; +import config from 'my-app/config/environment'; import { initialize } from 'my-app/initializers/foo'; import { module, test } from 'qunit'; import Resolver from 'ember-resolver'; import { run } from '@ember/runloop'; -module('Unit | Initializer | foo', function(hooks) { - hooks.beforeEach(function() { - this.TestApplication = class TestApplication extends Application {} +module('Unit | Initializer | foo', function (hooks) { + hooks.beforeEach(function () { + this.TestApplication = class TestApplication extends Application { + modulePrefix = config.modulePrefix; + podModulePrefix = config.podModulePrefix; + Resolver = Resolver; + }; this.TestApplication.initializer({ name: 'initializer under test', - initialize + initialize, }); - this.application = this.TestApplication.create({ autoboot: false, Resolver }); + this.application = this.TestApplication.create({ autoboot: false }); }); - hooks.afterEach(function() { + hooks.afterEach(function () { run(this.application, 'destroy'); }); // TODO: Replace this with your real tests. - test('it works', async function(assert) { + test('it works', async function (assert) { await this.application.boot(); assert.ok(true); diff --git a/node-tests/fixtures/instance-initializer-test/rfc232.js b/node-tests/fixtures/instance-initializer-test/rfc232.js index 64814eda522..03654f52dcf 100644 --- a/node-tests/fixtures/instance-initializer-test/rfc232.js +++ b/node-tests/fixtures/instance-initializer-test/rfc232.js @@ -1,27 +1,32 @@ import Application from '@ember/application'; +import config from 'my-app/config/environment'; import { initialize } from 'my-app/instance-initializers/foo'; import { module, test } from 'qunit'; import Resolver from 'ember-resolver'; import { run } from '@ember/runloop'; -module('Unit | Instance Initializer | foo', function(hooks) { - hooks.beforeEach(function() { - this.TestApplication = class TestApplication extends Application {} +module('Unit | Instance Initializer | foo', function (hooks) { + hooks.beforeEach(function () { + this.TestApplication = class TestApplication extends Application { + modulePrefix = config.modulePrefix; + podModulePrefix = config.podModulePrefix; + Resolver = Resolver; + }; this.TestApplication.instanceInitializer({ name: 'initializer under test', - initialize + initialize, }); - this.application = this.TestApplication.create({ autoboot: false, Resolver }); + this.application = this.TestApplication.create({ autoboot: false }); this.instance = this.application.buildInstance(); }); - hooks.afterEach(function() { + hooks.afterEach(function () { run(this.instance, 'destroy'); run(this.application, 'destroy'); }); // TODO: Replace this with your real tests. - test('it works', async function(assert) { + test('it works', async function (assert) { await this.instance.boot(); assert.ok(true); diff --git a/package.json b/package.json index ea3fd977765..fd59c04bd57 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ember-source", - "version": "3.28.0-alpha.1", + "version": "3.28.4", "description": "A JavaScript framework for creating ambitious web applications", "keywords": [ "ember-addon" @@ -51,11 +51,12 @@ "@babel/plugin-transform-block-scoping": "^7.8.3", "@babel/plugin-transform-object-assign": "^7.8.3", "@ember/edition-utils": "^1.2.0", - "@glimmer/vm-babel-plugins": "0.78.2", - "babel-plugin-debug-macros": "^0.3.3", + "@glimmer/vm-babel-plugins": "0.80.3", + "babel-plugin-debug-macros": "^0.3.4", "babel-plugin-filter-imports": "^4.0.0", "broccoli-concat": "^4.2.4", "broccoli-debug": "^0.6.4", + "broccoli-file-creator": "^2.1.1", "broccoli-funnel": "^2.0.2", "broccoli-merge-trees": "^4.2.0", "chalk": "^4.0.0", @@ -75,19 +76,19 @@ }, "devDependencies": { "@babel/preset-env": "^7.9.5", - "@glimmer/compiler": "0.78.2", - "@glimmer/destroyable": "0.78.2", + "@glimmer/compiler": "0.80.3", + "@glimmer/destroyable": "0.80.3", "@glimmer/env": "^0.1.7", - "@glimmer/global-context": "0.78.2", - "@glimmer/interfaces": "0.78.2", - "@glimmer/manager": "0.78.2", - "@glimmer/node": "0.78.2", - "@glimmer/opcode-compiler": "0.78.2", - "@glimmer/owner": "0.78.2", - "@glimmer/program": "0.78.2", - "@glimmer/reference": "0.78.2", - "@glimmer/runtime": "0.78.2", - "@glimmer/validator": "0.78.2", + "@glimmer/global-context": "0.80.3", + "@glimmer/interfaces": "0.80.3", + "@glimmer/manager": "0.80.3", + "@glimmer/node": "0.80.3", + "@glimmer/opcode-compiler": "0.80.3", + "@glimmer/owner": "0.80.3", + "@glimmer/program": "0.80.3", + "@glimmer/reference": "0.80.3", + "@glimmer/runtime": "0.80.3", + "@glimmer/validator": "0.80.3", "@simple-dom/document": "^1.4.0", "@types/qunit": "^2.11.1", "@types/rsvp": "^4.0.3", @@ -98,7 +99,6 @@ "babel-template": "^6.26.0", "backburner.js": "^2.7.0", "broccoli-babel-transpiler": "^7.8.0", - "broccoli-file-creator": "^2.1.1", "broccoli-persistent-filter": "^2.3.1", "broccoli-plugin": "^4.0.3", "broccoli-rollup": "^2.1.1", diff --git a/packages/@ember/-internals/bootstrap/index.js b/packages/@ember/-internals/bootstrap/index.js deleted file mode 100644 index 431992b2e55..00000000000 --- a/packages/@ember/-internals/bootstrap/index.js +++ /dev/null @@ -1,46 +0,0 @@ -import require from 'require'; -import { context } from '@ember/-internals/environment'; -import { deprecate } from '@ember/debug'; - -(function () { - let Ember; - - function defineEmber(key) { - Object.defineProperty(context.exports, key, { - enumerable: true, - configurable: true, - get() { - if (!Ember) { - Ember = require('ember').default; - } - - deprecate( - 'Usage of the Ember Global is deprecated. You should import the Ember module or the specific API instead.', - false, - { - id: 'ember-global', - until: '4.0.0', - url: 'https://deprecations.emberjs.com/v3.x/#toc_ember-global', - for: 'ember-source', - since: { - enabled: '3.27.0', - }, - } - ); - - return Ember; - }, - }); - } - - // Bootstrap the global - defineEmber('Ember'); - defineEmber('Em'); - - // Bootstrap Node module - // eslint-disable-next-line no-undef - if (typeof module === 'object' && typeof module.require === 'function') { - // eslint-disable-next-line no-undef - module.exports = Ember = require('ember').default; - } -})(); diff --git a/packages/@ember/-internals/bootstrap/index.ts b/packages/@ember/-internals/bootstrap/index.ts new file mode 100644 index 00000000000..022ef158407 --- /dev/null +++ b/packages/@ember/-internals/bootstrap/index.ts @@ -0,0 +1,64 @@ +import { context } from '@ember/-internals/environment'; +import { onEmberGlobalAccess } from '@ember/-internals/overrides'; +import { deprecate } from '@ember/debug'; +import { DEBUG } from '@glimmer/env'; +import require from 'require'; + +(function bootstrap() { + let Ember: unknown; + + let get = () => { + if (!Ember) { + // tslint:disable-next-line: no-require-imports + Ember = require('ember').default; + } + + return Ember; + }; + + if (DEBUG) { + let defaultHandler = () => { + return 'Usage of the Ember Global is deprecated. You should import the Ember module or the specific API instead.'; + }; + + let handler = onEmberGlobalAccess || defaultHandler; + let _get = get; + + get = () => { + let message = handler(); + + if (message !== null) { + deprecate(message, false, { + id: 'ember-global', + until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x/#toc_ember-global', + for: 'ember-source', + since: { + enabled: '3.27.0', + }, + }); + } + + return _get(); + }; + } + + function defineEmber(key: string) { + Object.defineProperty(context.exports, key, { + enumerable: true, + configurable: true, + get, + }); + } + + // Bootstrap the global + defineEmber('Ember'); + defineEmber('Em'); + + // Bootstrap Node module + // eslint-disable-next-line no-undef + if (typeof module === 'object' && typeof module.require === 'function') { + // tslint:disable-next-line: no-require-imports + module.exports = Ember = require('ember').default; + } +})(); diff --git a/packages/@ember/-internals/console/index.js b/packages/@ember/-internals/console/index.js index 41b97ec62c5..38bda85f0aa 100644 --- a/packages/@ember/-internals/console/index.js +++ b/packages/@ember/-internals/console/index.js @@ -6,7 +6,7 @@ import { LOGGER } from '@ember/deprecated-features'; const DEPRECATION_MESSAGE = 'Use of Ember.Logger is deprecated. Please use `console` for logging.'; const DEPRECATION_ID = 'ember-console.deprecate-logger'; const DEPRECATION_URL = - 'https://emberjs.com/deprecations/v3.x#toc_use-console-rather-than-ember-logger'; + 'https://deprecations.emberjs.com/v3.x#toc_use-console-rather-than-ember-logger'; /** @module ember */ diff --git a/packages/@ember/-internals/container/lib/container.ts b/packages/@ember/-internals/container/lib/container.ts index 464cee719f6..091203bec0b 100644 --- a/packages/@ember/-internals/container/lib/container.ts +++ b/packages/@ember/-internals/container/lib/container.ts @@ -272,7 +272,10 @@ function isInstantiatable(container: Container, fullName: string) { function lookup(container: Container, fullName: string, options: LookupOptions = {}) { let normalizedName = fullName; - if (options.singleton !== false) { + if ( + options.singleton === true || + (options.singleton === undefined && isSingleton(container, fullName)) + ) { let cached = container.cache[normalizedName]; if (cached !== undefined) { return cached; @@ -335,7 +338,7 @@ function isSingletonInstance( return ( singleton !== false && instantiate !== false && - isSingleton(container, fullName) && + (singleton === true || isSingleton(container, fullName)) && isInstantiatable(container, fullName) ); } @@ -359,7 +362,7 @@ function isFactoryInstance( ) { return ( instantiate !== false && - (singleton !== false || isSingleton(container, fullName)) && + (singleton === false || !isSingleton(container, fullName)) && isInstantiatable(container, fullName) ); } diff --git a/packages/@ember/-internals/container/tests/container_test.js b/packages/@ember/-internals/container/tests/container_test.js index f97ebbb6204..4fc52d28452 100644 --- a/packages/@ember/-internals/container/tests/container_test.js +++ b/packages/@ember/-internals/container/tests/container_test.js @@ -6,48 +6,9 @@ import { Registry } from '..'; import { factory, moduleFor, AbstractTestCase, runTask } from 'internal-test-helpers'; moduleFor( - 'Container', + 'Container.lookup', class extends AbstractTestCase { - ['@test A registered factory returns the same instance each time'](assert) { - let registry = new Registry(); - let container = registry.container(); - let PostController = factory(); - - registry.register('controller:post', PostController); - - let postController = container.lookup('controller:post'); - - assert.ok( - postController instanceof PostController, - 'The lookup is an instance of the factory' - ); - - assert.equal(postController, container.lookup('controller:post')); - } - - ['@test uses create time injections if factory has no extend'](assert) { - let registry = new Registry(); - let container = registry.container(); - let AppleController = factory(); - let PostController = factory(); - - PostController.extend = undefined; // remove extend - - registry.register('controller:apple', AppleController); - registry.register('controller:post', PostController); - registry.injection('controller:post', 'apple', 'controller:apple'); - - let postController = container.lookup('controller:post'); - - assert.ok( - postController.apple instanceof AppleController, - 'instance receives an apple of instance AppleController' - ); - } - - ['@test A registered factory returns a fresh instance if singleton: false is passed as an option']( - assert - ) { + ['@test lookup returns a fresh instance if singleton: false is passed as an option'](assert) { let registry = new Registry(); let container = registry.container(); let PostController = factory(); @@ -102,6 +63,187 @@ moduleFor( ); } + ['@test lookup returns a fresh instance if singleton: false is passed as an option to lookup']( + assert + ) { + class TestFactory { + constructor(opts) { + Object.assign(this, opts); + } + static create(opts) { + return new this(opts); + } + } + + let registry = new Registry(); + let container = registry.container(); + registry.register('thing:test/obj', TestFactory); + + let instance1 = container.lookup('thing:test/obj'); + let instance2 = container.lookup('thing:test/obj', { + singleton: false, + }); + let instance3 = container.lookup('thing:test/obj', { + singleton: false, + }); + let instance4 = container.lookup('thing:test/obj'); + + assert.ok( + instance1 === instance4, + 'factories looked up up without singleton: false are the same instance' + ); + assert.ok( + instance1 !== instance2, + 'factories looked up with singleton: false are a different instance' + ); + assert.ok( + instance2 !== instance3, + 'factories looked up with singleton: false are a different instance' + ); + assert.ok( + instance3 !== instance4, + 'factories looked up after a call to singleton: false is a different instance' + ); + assert.ok( + instance1 instanceof TestFactory, + 'All instances are instances of the registered factory' + ); + assert.ok( + instance2 instanceof TestFactory, + 'All instances are instances of the registered factory' + ); + assert.ok( + instance3 instanceof TestFactory, + 'All instances are instances of the registered factory' + ); + assert.ok( + instance4 instanceof TestFactory, + 'All instances are instances of the registered factory' + ); + } + + ['@test lookup returns a fresh instance if singleton: false is passed as an option to register']( + assert + ) { + class TestFactory { + constructor(opts) { + Object.assign(this, opts); + } + static create(opts) { + return new this(opts); + } + } + + let registry = new Registry(); + let container = registry.container(); + registry.register('thing:test/obj', TestFactory, { singleton: false }); + + let instance1 = container.lookup('thing:test/obj'); + let instance2 = container.lookup('thing:test/obj'); + let instance3 = container.lookup('thing:test/obj'); + + assert.ok(instance1 !== instance2, 'each lookup is a different instance'); + assert.ok(instance2 !== instance3, 'each lookup is a different instance'); + assert.ok(instance1 !== instance3, 'each lookup is a different instance'); + assert.ok( + instance1 instanceof TestFactory, + 'All instances are instances of the registered factory' + ); + assert.ok( + instance2 instanceof TestFactory, + 'All instances are instances of the registered factory' + ); + assert.ok( + instance3 instanceof TestFactory, + 'All instances are instances of the registered factory' + ); + } + + ['@test lookup returns a singleton instance if singleton: true is passed as an option even if registered as singleton: false']( + assert + ) { + class TestFactory { + constructor(opts) { + Object.assign(this, opts); + } + static create(opts) { + return new this(opts); + } + } + + let registry = new Registry(); + let container = registry.container(); + registry.register('thing:test/obj', TestFactory, { singleton: false }); + + let instance1 = container.lookup('thing:test/obj'); + let instance2 = container.lookup('thing:test/obj', { singleton: true }); + let instance3 = container.lookup('thing:test/obj', { singleton: true }); + let instance4 = container.lookup('thing:test/obj'); + + assert.ok(instance1 !== instance2, 'each lookup is a different instance'); + assert.ok(instance2 === instance3, 'each singleton: true lookup is the same instance'); + assert.ok(instance3 !== instance4, 'each lookup is a different instance'); + assert.ok(instance1 !== instance4, 'each lookup is a different instance'); + assert.ok( + instance1 instanceof TestFactory, + 'All instances are instances of the registered factory' + ); + assert.ok( + instance2 instanceof TestFactory, + 'All instances are instances of the registered factory' + ); + assert.ok( + instance3 instanceof TestFactory, + 'All instances are instances of the registered factory' + ); + assert.ok( + instance4 instanceof TestFactory, + 'All instances are instances of the registered factory' + ); + } + } +); + +moduleFor( + 'Container', + class extends AbstractTestCase { + ['@test A registered factory returns the same instance each time'](assert) { + let registry = new Registry(); + let container = registry.container(); + let PostController = factory(); + + registry.register('controller:post', PostController); + + let postController = container.lookup('controller:post'); + + assert.ok( + postController instanceof PostController, + 'The lookup is an instance of the factory' + ); + + assert.equal(postController, container.lookup('controller:post')); + } + + ['@test uses create time injections if factory has no extend'](assert) { + let registry = new Registry(); + let container = registry.container(); + let AppleController = factory(); + let PostController = factory(); + + PostController.extend = undefined; // remove extend + + registry.register('controller:apple', AppleController); + registry.register('controller:post', PostController); + registry.injection('controller:post', 'apple', 'controller:apple'); + + let postController = container.lookup('controller:post'); + + assert.ok( + postController.apple instanceof AppleController, + 'instance receives an apple of instance AppleController' + ); + } + ["@test A factory type with a registered injection's instances receive that injection"]( assert ) { diff --git a/packages/@ember/-internals/glimmer/lib/component.ts b/packages/@ember/-internals/glimmer/lib/component.ts index 369b69a94ab..c5ffd019de8 100644 --- a/packages/@ember/-internals/glimmer/lib/component.ts +++ b/packages/@ember/-internals/glimmer/lib/component.ts @@ -687,7 +687,7 @@ const Component = CoreView.extend( { id: 'ember-views.event-dispatcher.mouseenter-leave-move', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_component-mouseenter-leave-move', + url: 'https://deprecations.emberjs.com/v3.x#toc_component-mouseenter-leave-move', for: 'ember-source', since: { enabled: '3.13.0-beta.1', @@ -700,7 +700,7 @@ const Component = CoreView.extend( { id: 'ember-views.event-dispatcher.mouseenter-leave-move', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_component-mouseenter-leave-move', + url: 'https://deprecations.emberjs.com/v3.x#toc_component-mouseenter-leave-move', for: 'ember-source', since: { enabled: '3.13.0-beta.1', @@ -713,7 +713,7 @@ const Component = CoreView.extend( { id: 'ember-views.event-dispatcher.mouseenter-leave-move', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_component-mouseenter-leave-move', + url: 'https://deprecations.emberjs.com/v3.x#toc_component-mouseenter-leave-move', for: 'ember-source', since: { enabled: '3.13.0-beta.1', diff --git a/packages/@ember/-internals/glimmer/lib/components/-link-to.ts b/packages/@ember/-internals/glimmer/lib/components/-link-to.ts index 2ae57b6e124..642eeb64605 100644 --- a/packages/@ember/-internals/glimmer/lib/components/-link-to.ts +++ b/packages/@ember/-internals/glimmer/lib/components/-link-to.ts @@ -1035,8 +1035,11 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.reopen', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-reopen', } ); @@ -1060,8 +1063,11 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.reopen', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-reopen', } ); diff --git a/packages/@ember/-internals/glimmer/lib/components/-textarea.ts b/packages/@ember/-internals/glimmer/lib/components/-textarea.ts index 00473ea09b7..95aa097bc1c 100644 --- a/packages/@ember/-internals/glimmer/lib/components/-textarea.ts +++ b/packages/@ember/-internals/glimmer/lib/components/-textarea.ts @@ -62,8 +62,11 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.reopen', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-reopen', } ); @@ -87,8 +90,11 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.reopen', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-reopen', } ); diff --git a/packages/@ember/-internals/glimmer/lib/components/abstract-input.ts b/packages/@ember/-internals/glimmer/lib/components/abstract-input.ts index 13096945949..f459d5fb704 100644 --- a/packages/@ember/-internals/glimmer/lib/components/abstract-input.ts +++ b/packages/@ember/-internals/glimmer/lib/components/abstract-input.ts @@ -239,7 +239,7 @@ export function handleDeprecatedFeatures( for: 'ember-source', since: {}, until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_ember-component-send-action', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-component-send-action', } ); @@ -270,7 +270,7 @@ export function handleDeprecatedFeatures( for: 'ember-source', since: {}, until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_ember-component-send-action', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-component-send-action', } ); diff --git a/packages/@ember/-internals/glimmer/lib/components/checkbox.ts b/packages/@ember/-internals/glimmer/lib/components/checkbox.ts index 31d42f17da2..d9a39d50e49 100644 --- a/packages/@ember/-internals/glimmer/lib/components/checkbox.ts +++ b/packages/@ember/-internals/glimmer/lib/components/checkbox.ts @@ -181,8 +181,11 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.reopen', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-reopen', } ); @@ -206,8 +209,11 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.reopen', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-reopen', } ); diff --git a/packages/@ember/-internals/glimmer/lib/components/internal.ts b/packages/@ember/-internals/glimmer/lib/components/internal.ts index 1942dbe344f..393b4380aa8 100644 --- a/packages/@ember/-internals/glimmer/lib/components/internal.ts +++ b/packages/@ember/-internals/glimmer/lib/components/internal.ts @@ -274,8 +274,12 @@ export function handleDeprecatedArguments(target: DeprecatingInternalComponentCo deprecate(`Passing the \`@${name}\` argument to <${angle}> is deprecated.`, false, { id: 'ember.built-in-components.legacy-arguments', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: + 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-legacy-arguments', }); this.modernized = false; @@ -356,8 +360,12 @@ export function handleDeprecatedAttributeArguments( { id: 'ember.built-in-components.legacy-attribute-arguments', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: + 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-legacy-attribute-arguments', } ); @@ -517,8 +525,12 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.legacy-attribute-arguments', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: + 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-legacy-attribute-arguments', } ); @@ -530,8 +542,12 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.legacy-attribute-arguments', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: + 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-legacy-attribute-arguments', } ); diff --git a/packages/@ember/-internals/glimmer/lib/components/link-to.ts b/packages/@ember/-internals/glimmer/lib/components/link-to.ts index 32b69ea997b..a139ba18c80 100644 --- a/packages/@ember/-internals/glimmer/lib/components/link-to.ts +++ b/packages/@ember/-internals/glimmer/lib/components/link-to.ts @@ -138,7 +138,7 @@ class LinkTo extends InternalComponent implements DeprecatingInternalComponent { return; } - let element = event.target; + let element = event.currentTarget; assert('[BUG] must be an element', element instanceof HTMLAnchorElement); let isSelf = element.target === '' || element.target === '_self'; @@ -393,7 +393,6 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { ['role', 'ariaRole'], // LinkTo - 'href', 'title', 'rel', 'tabindex', @@ -402,6 +401,23 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { handleDeprecatedEventArguments(LinkTo); + // @href + { + let superOnUnsupportedArgument = prototype['onUnsupportedArgument']; + + Object.defineProperty(prototype, 'onUnsupportedArgument', { + configurable: true, + enumerable: false, + value: function onUnsupportedArgument(this: LinkTo, name: string): void { + if (name === 'href') { + assert(`Passing the \`@href\` argument to is not supported.`); + } else { + superOnUnsupportedArgument.call(this, name); + } + }, + }); + } + // @tagName { let superOnUnsupportedArgument = prototype['onUnsupportedArgument']; @@ -454,8 +470,12 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.legacy-arguments', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: + 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-legacy-arguments', } ); @@ -472,8 +492,12 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.legacy-arguments', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: + 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-legacy-arguments', } ); @@ -505,8 +529,12 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.legacy-arguments', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: + 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-legacy-arguments', } ); } else { @@ -519,8 +547,12 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.legacy-arguments', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: + 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-legacy-arguments', } ); @@ -540,8 +572,12 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.legacy-arguments', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: + 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-legacy-arguments', } ); @@ -556,8 +592,12 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.legacy-arguments', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: + 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-legacy-arguments', } ); } diff --git a/packages/@ember/-internals/glimmer/lib/components/text-field.ts b/packages/@ember/-internals/glimmer/lib/components/text-field.ts index 1db0db7bf3f..a83a0f1c4b5 100644 --- a/packages/@ember/-internals/glimmer/lib/components/text-field.ts +++ b/packages/@ember/-internals/glimmer/lib/components/text-field.ts @@ -225,8 +225,11 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.reopen', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-reopen', } ); @@ -250,8 +253,11 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { { id: 'ember.built-in-components.reopen', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-reopen', } ); diff --git a/packages/@ember/-internals/glimmer/lib/environment.ts b/packages/@ember/-internals/glimmer/lib/environment.ts index 847642050f0..12a91fcb41d 100644 --- a/packages/@ember/-internals/glimmer/lib/environment.ts +++ b/packages/@ember/-internals/glimmer/lib/environment.ts @@ -118,12 +118,21 @@ const VM_DEPRECATION_OVERRIDES: (DeprecationOptions & { }, { id: 'argument-less-helper-paren-less-invocation', + url: 'https://deprecations.emberjs.com/v3.x#toc_argument-less-helper-paren-less-invocation', until: '4.0.0', for: 'ember-source', since: { enabled: '3.27.0', }, }, + { + id: 'setting-on-hash', + until: '4.4.0', + for: 'ember-source', + since: { + enabled: '3.28.0', + }, + }, ]; const VM_ASSERTION_OVERRIDES: { id: string; message: string }[] = []; diff --git a/packages/@ember/-internals/glimmer/lib/glimmer-component-docs.ts b/packages/@ember/-internals/glimmer/lib/glimmer-component-docs.ts index ec4399d774b..5be0786f4ea 100644 --- a/packages/@ember/-internals/glimmer/lib/glimmer-component-docs.ts +++ b/packages/@ember/-internals/glimmer/lib/glimmer-component-docs.ts @@ -163,7 +163,7 @@ You can also pass parameters to named blocks: ```app/templates/components/person-profile.hbs -

{{yield to="title" @person.name}}

+

{{yield @person.name to="title"}}

{{yield @person.signature}} ``` @@ -184,7 +184,7 @@ ```app/templates/components/person-profile.hbs

{{#if (has-block "title")}} - {{yield to="title" @person.name}} + {{yield @person.name to="title"}} {{else}} {{@person.name}} {{/if}} diff --git a/packages/@ember/-internals/glimmer/lib/modifiers/action.ts b/packages/@ember/-internals/glimmer/lib/modifiers/action.ts index f3678a76b96..99d516c26af 100644 --- a/packages/@ember/-internals/glimmer/lib/modifiers/action.ts +++ b/packages/@ember/-internals/glimmer/lib/modifiers/action.ts @@ -223,7 +223,7 @@ class ActionModifierManager implements InternalModifierManager(); - named.model = childRefFromParts(outletRef, ['render', 'model']); + + // Create a ref for the model + let modelRef = childRefFromParts(outletRef, ['render', 'model']); + + // Store the value of the model + let model = valueForRef(modelRef); + + // Create a compute ref which we pass in as the `{{@model}}` reference + // for the outlet. This ref will update and return the value of the + // model _until_ the outlet itself changes. Once the outlet changes, + // dynamic scope also changes, and so the original model ref would not + // provide the correct updated value. So we stop updating and return + // the _last_ model value for that outlet. + named.model = createComputeRef(() => { + if (lastState === state) { + model = valueForRef(modelRef); + } + + return model; + }); if (DEBUG) { named.model = createDebugAliasRef!('@model', named.model); diff --git a/packages/@ember/-internals/glimmer/lib/utils/managers.ts b/packages/@ember/-internals/glimmer/lib/utils/managers.ts index d437227f0db..c12bf49ba41 100644 --- a/packages/@ember/-internals/glimmer/lib/utils/managers.ts +++ b/packages/@ember/-internals/glimmer/lib/utils/managers.ts @@ -22,7 +22,7 @@ export function setComponentManager( { id: 'deprecate-string-based-component-manager', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x/#toc_component-manager-string-lookup', + url: 'https://deprecations.emberjs.com/v3.x/#toc_component-manager-string-lookup', for: 'ember-source', since: { enabled: '3.8.0', @@ -49,7 +49,7 @@ if (DEBUG) { version === '3.13', { id: 'manager-capabilities.components-3-4', - url: 'https://emberjs.com/deprecations/v3.x#toc_manager-capabilities-components-3-4', + url: 'https://deprecations.emberjs.com/v3.x#toc_manager-capabilities-components-3-4', until: '4.0.0', for: 'ember-source', since: { @@ -67,7 +67,7 @@ if (DEBUG) { version === '3.22', { id: 'manager-capabilities.modifiers-3-13', - url: 'https://emberjs.com/deprecations/v3.x#toc_manager-capabilities-modifiers-3-13', + url: 'https://deprecations.emberjs.com/v3.x#toc_manager-capabilities-modifiers-3-13', until: '4.0.0', for: 'ember-source', since: { diff --git a/packages/@ember/-internals/glimmer/tests/integration/application/engine-test.js b/packages/@ember/-internals/glimmer/tests/integration/application/engine-test.js index 49f3499b046..b518a074f98 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/application/engine-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/application/engine-test.js @@ -974,5 +974,64 @@ moduleFor( assert.equal(error.message, 'Whoops! Something went wrong...'); }); } + + ['@test visit() with `shouldRender: true` queryParams are properly deserialized for lazy routes']( + assert + ) { + assert.expect(2); + + let hooks = []; + + this.setupAppAndRoutableEngine(hooks); + + this.add( + 'engine:blog', + Engine.extend({ + Resolver: ModuleBasedTestResolver, + + init() { + this._super(...arguments); + this.register( + 'controller:application', + Controller.extend({ + queryParams: ['lazyQueryParam'], + }) + ); + + this.register( + 'template:application', + compile('Engine
{{this.lazyQueryParam}}
{{outlet}}') + ); + + this.register( + 'route:application', + Route.extend({ + queryParams: { + lazyQueryParam: { + defaultValue: null, + }, + }, + deserializeQueryParam() { + hooks.push('engine - deserialize query param'); + return 'foo'; + }, + model() { + hooks.push('engine - application'); + }, + }) + ); + }, + }) + ); + + return this.visit('/blog?lazyQueryParam=bar', { shouldRender: true }).then(() => { + assert.deepEqual( + hooks, + ['application - application', 'engine - deserialize query param', 'engine - application'], + 'the expected hooks were fired' + ); + assert.strictEqual(this.element.querySelector('.lazy-query-param').innerHTML, 'foo'); + }); + } } ); diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/query-params-angle-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/query-params-angle-test.js index 47ad96e478f..2729071af47 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/query-params-angle-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/query-params-angle-test.js @@ -350,6 +350,30 @@ moduleFor( assert.equal(theLink.attr('href'), '/?foo=ASL'); } + async ['@test supplied QP properties can be bound in legacy components'](assert) { + expectDeprecation(/Passing the `@tagName` argument to/); + + this.addTemplate( + 'index', + ` + + Index + + ` + ); + + await this.visit('/'); + + let indexController = this.getController('index'); + let theLink = this.$('#the-link'); + + assert.equal(theLink.attr('href'), '/?foo=OMG'); + + runTask(() => indexController.set('boundThing', 'ASL')); + + assert.equal(theLink.attr('href'), '/?foo=ASL'); + } + async ['@test supplied QP properties can be bound (booleans)'](assert) { this.addTemplate( 'index', diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-angle-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-angle-test.js index 3932e4c573a..3c555705a1c 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-angle-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-angle-test.js @@ -9,6 +9,7 @@ import { Router, Route } from '@ember/-internals/routing'; import Controller from '@ember/controller'; import { set } from '@ember/-internals/metal'; import { LinkComponent } from '@ember/-internals/glimmer'; +import { DEBUG } from '@glimmer/env'; moduleFor( ' component (rendering tests)', @@ -22,6 +23,19 @@ moduleFor( ); } + async [`@test it throws a useful error if you pass the href argument`](assert) { + this.addTemplate('application', `Index`); + + if (DEBUG) { + await assert.rejects( + this.visit('/'), + /Passing the `@href` argument to is not supported\./ + ); + } else { + assert.expect(0); + } + } + async ['@test it should be able to be inserted in DOM when the router is not present']() { this.addTemplate('application', `Go to Index`); diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-curly-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-curly-test.js index 7115e81ec21..b934154d7ba 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-curly-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/rendering-curly-test.js @@ -3,6 +3,7 @@ import { moduleFor, ApplicationTestCase, RenderingTestCase, runTask } from 'inte import Controller from '@ember/controller'; import { set } from '@ember/-internals/metal'; import { LinkComponent } from '@ember/-internals/glimmer'; +import { DEBUG } from '@glimmer/env'; moduleFor( '{{link-to}} component (rendering tests)', @@ -15,6 +16,19 @@ moduleFor( }, /You must provide one or more parameters to the `{{link-to}}` component\. \('my-app\/templates\/application\.hbs' @ L1:C0\)/); } + async [`@test it throws a useful error if you pass the href argument`](assert) { + this.addTemplate('application', `{{#link-to href="nope" route="index"}}Index{{/link-to}}`); + + if (DEBUG) { + await assert.rejects( + this.visit('/'), + /Passing the `@href` argument to is not supported\./ + ); + } else { + assert.expect(0); + } + } + async ['@test it should be able to be inserted in DOM when the router is not present']() { this.addTemplate('application', `{{#link-to route='index'}}Go to Index{{/link-to}}`); diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-angle-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-angle-test.js index 60ac6577dac..fa7e4c22561 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-angle-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-angle-test.js @@ -92,6 +92,47 @@ moduleFor( ); } + async ['@test [GH#19546] it navigates into the named route when containing other elements']( + assert + ) { + this.addTemplate( + 'about', + ` +

About

+ Home + Self + ` + ); + + await this.visit('/about'); + + assert.equal(this.$('h3.about').length, 1, 'The about template was rendered'); + assert.equal( + this.$('#self-link.active').length, + 1, + 'The self-link was rendered with active class' + ); + assert.equal( + this.$('#home-link:not(.active)').length, + 1, + 'The other link was rendered without active class' + ); + + await this.click('#inside'); + + assert.equal(this.$('h3.home').length, 1, 'The home template was rendered'); + assert.equal( + this.$('#self-link.active').length, + 1, + 'The self-link was rendered with active class' + ); + assert.equal( + this.$('#about-link:not(.active)').length, + 1, + 'The other link was rendered without active class' + ); + } + async [`@test [DEPRECATED] it doesn't add an href when the tagName isn't 'a'`](assert) { this.addTemplate( 'index', diff --git a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-curly-test.js b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-curly-test.js index 138a66f7068..2ecf5ae4cf0 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-curly-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/components/link-to/routing-curly-test.js @@ -92,6 +92,47 @@ moduleFor( ); } + async ['@test [GH#19546] it navigates into the named route when containing other elements']( + assert + ) { + this.addTemplate( + 'about', + ` +

About

+ + + ` + ); + + await this.visit('/about'); + + assert.equal(this.$('h3.about').length, 1, 'The about template was rendered'); + assert.equal( + this.$('#self-link > a.active').length, + 1, + 'The self-link was rendered with active class' + ); + assert.equal( + this.$('#home-link > a:not(.active)').length, + 1, + 'The other link was rendered without active class' + ); + + await this.click('#inside'); + + assert.equal(this.$('h3.home').length, 1, 'The home template was rendered'); + assert.equal( + this.$('#self-link > a.active').length, + 1, + 'The self-link was rendered with active class' + ); + assert.equal( + this.$('#about-link > a:not(.active)').length, + 1, + 'The other link was rendered without active class' + ); + } + async [`@test [DEPRECATED] it doesn't add an href when the tagName isn't 'a'`](assert) { this.addTemplate( 'index', diff --git a/packages/@ember/-internals/glimmer/tests/integration/helpers/hash-test.js b/packages/@ember/-internals/glimmer/tests/integration/helpers/hash-test.js index c827f9694df..9eb7d13135f 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/helpers/hash-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/helpers/hash-test.js @@ -2,7 +2,8 @@ import { RenderingTestCase, moduleFor, runTask } from 'internal-test-helpers'; import { Component } from '../../utils/helpers'; -import { set } from '@ember/-internals/metal'; +import { set, computed } from '@ember/-internals/metal'; +import { HAS_NATIVE_PROXY } from '@ember/-internals/utils'; moduleFor( 'Helpers test: {{hash}}', @@ -186,5 +187,140 @@ moduleFor( this.assertText('Chad Hietala'); } + + ['@test works with computeds']() { + let FooBarComponent = Component.extend({ + fullName: computed('hash.firstName', 'hash.lastName', function () { + return `${this.hash.firstName} ${this.hash.lastName}`; + }), + }); + + this.registerComponent('foo-bar', { + ComponentClass: FooBarComponent, + template: `{{this.fullName}}`, + }); + + this.render(`{{foo-bar hash=(hash firstName=this.firstName lastName=this.lastName)}}`, { + firstName: 'Chad', + lastName: 'Hietala', + }); + + this.assertText('Chad Hietala'); + + runTask(() => this.rerender()); + + this.assertText('Chad Hietala'); + + runTask(() => { + set(this.context, 'firstName', 'Godfrey'); + set(this.context, 'lastName', 'Chan'); + }); + + this.assertText('Godfrey Chan'); + } + + ['@test works with computeds on non-defined properties']() { + let instance; + + let FooBarComponent = Component.extend({ + init() { + this._super(...arguments); + + if (HAS_NATIVE_PROXY) { + expectDeprecation(() => { + set(this.hash, 'lastName', 'Hietala'); + }, /You set the '.*' property on a {{hash}} object/); + } else { + set(this.hash, 'lastName', 'Hietala'); + } + + instance = this; + }, + + fullName: computed('hash.firstName', 'hash.lastName', function () { + return `${this.hash.firstName} ${this.hash.lastName}`; + }), + }); + + this.registerComponent('foo-bar', { + ComponentClass: FooBarComponent, + template: `{{this.fullName}}`, + }); + + this.render(`{{foo-bar hash=(hash firstName=this.firstName)}}`, { + firstName: 'Chad', + lastName: 'Hietala', + }); + + this.assertText('Chad Hietala'); + + runTask(() => this.rerender()); + + this.assertText('Chad Hietala'); + + runTask(() => { + set(this.context, 'firstName', 'Godfrey'); + }); + + // needs to be separate task because of the way classic components update args + runTask(() => { + if (HAS_NATIVE_PROXY) { + expectDeprecation(() => { + set(instance.hash, 'lastName', 'Chan'); + }, /You set the '.*' property on a {{hash}} object/); + } else { + set(instance.hash, 'lastName', 'Chan'); + } + }); + + this.assertText('Godfrey Chan'); + } + + ['@test works when properties are set dynamically']() { + let fooBarInstance; + let FooBarComponent = Component.extend({ + init() { + this._super(); + fooBarInstance = this; + }, + }); + + this.registerComponent('foo-bar', { + ComponentClass: FooBarComponent, + template: `{{this.hash.firstName}} {{this.hash.lastName}}`, + }); + + this.render(`{{foo-bar hash=(hash firstName=this.firstName)}}`, { + firstName: 'Chad', + }); + + this.assertText('Chad '); + + runTask(() => { + if (HAS_NATIVE_PROXY) { + expectDeprecation(() => { + set(fooBarInstance.hash, 'lastName', 'Hietala'); + }, /You set the '.*' property on a {{hash}} object/); + } else { + set(fooBarInstance.hash, 'lastName', 'Hietala'); + } + }); + + this.assertText('Chad Hietala'); + + runTask(() => { + if (HAS_NATIVE_PROXY) { + expectDeprecation(() => { + set(fooBarInstance.hash, 'firstName', 'Godfrey'); + set(fooBarInstance.hash, 'lastName', 'Chan'); + }, /You set the '.*' property on a {{hash}} object/); + } else { + set(fooBarInstance.hash, 'firstName', 'Godfrey'); + set(fooBarInstance.hash, 'lastName', 'Chan'); + } + }); + + this.assertText('Godfrey Chan'); + } } ); diff --git a/packages/@ember/-internals/glimmer/tests/utils/string-test.js b/packages/@ember/-internals/glimmer/tests/utils/string-test.js index 139c6c3846d..343ea352474 100644 --- a/packages/@ember/-internals/glimmer/tests/utils/string-test.js +++ b/packages/@ember/-internals/glimmer/tests/utils/string-test.js @@ -1,4 +1,5 @@ import { moduleFor, AbstractTestCase } from 'internal-test-helpers'; +import { ENV } from '@ember/-internals/environment'; import { SafeString, htmlSafe, isHTMLSafe } from './helpers'; @@ -11,6 +12,19 @@ moduleFor( this.assert.ok(safeString instanceof SafeString, 'should be a SafeString'); } + ['@test [deprecated] htmlSafe via string prototype should return an instance of SafeString']() { + if (ENV.EXTEND_PROTOTYPES.String) { + let safeString; + expectDeprecation(() => { + safeString = 'you need to be more bold'.htmlSafe(); + }, /String prototype extensions are deprecated/); + + this.assert.ok(safeString instanceof SafeString, 'should be a SafeString'); + } else { + this.assert.expect(0); + } + } + ['@test htmlSafe should return an empty string for null']() { let safeString = htmlSafe(null); @@ -24,6 +38,32 @@ moduleFor( this.assert.equal(safeString instanceof SafeString, true, 'should be a SafeString'); this.assert.equal(safeString.toString(), '', 'should return an empty string'); } + + ['@test [deprecated] htmlSafe via string prototype should return an instance of SafeString for an empty string']() { + if (ENV.EXTEND_PROTOTYPES.String) { + let safeString; + expectDeprecation(() => { + safeString = ''.htmlSafe(); + }, /String prototype extensions are deprecated/); + + this.assert.ok(safeString instanceof SafeString, 'should be a SafeString'); + } else { + this.assert.expect(0); + } + } + + ['@test [deprecated] String.prototype.htmlSafe is not modified without EXTEND_PROTOTYPES']( + assert + ) { + if (!ENV.EXTEND_PROTOTYPES.String) { + assert.ok( + 'undefined' === typeof String.prototype.htmlSafe, + 'String.prototype helper disabled' + ); + } else { + this.assert.expect(0); + } + } } ); diff --git a/packages/@ember/-internals/metal/lib/computed.ts b/packages/@ember/-internals/metal/lib/computed.ts index 630f1eade01..9f261df8c6f 100644 --- a/packages/@ember/-internals/metal/lib/computed.ts +++ b/packages/@ember/-internals/metal/lib/computed.ts @@ -510,7 +510,7 @@ export class ComputedProperty extends ComputedDescriptor { { id: 'computed-property.override', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_computed-property-override', + url: 'https://deprecations.emberjs.com/v3.x#toc_computed-property-override', for: 'ember-source', since: { enabled: '3.9.0-beta.1', @@ -722,7 +722,7 @@ class ComputedDecoratorImpl extends Function { { id: 'computed-property.volatile', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_computed-property-volatile', + url: 'https://deprecations.emberjs.com/v3.x#toc_computed-property-volatile', for: 'ember-source', since: { enabled: '3.9.0-beta.1', @@ -797,7 +797,7 @@ class ComputedDecoratorImpl extends Function { { id: 'computed-property.property', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_computed-property-property', + url: 'https://deprecations.emberjs.com/v3.x#toc_computed-property-property', for: 'ember-source', since: { enabled: '3.9.0-beta.1', diff --git a/packages/@ember/-internals/metal/lib/mixin.ts b/packages/@ember/-internals/metal/lib/mixin.ts index 7073f79f8c6..3878765daaa 100644 --- a/packages/@ember/-internals/metal/lib/mixin.ts +++ b/packages/@ember/-internals/metal/lib/mixin.ts @@ -841,7 +841,7 @@ if (ALIAS_METHOD) { { id: 'object.alias-method', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_object-alias-method', + url: 'https://deprecations.emberjs.com/v3.x#toc_object-alias-method', for: 'ember-source', since: { enabled: '3.9.0', diff --git a/packages/@ember/-internals/overrides/index.d.ts b/packages/@ember/-internals/overrides/index.d.ts new file mode 100644 index 00000000000..e52fbb81445 --- /dev/null +++ b/packages/@ember/-internals/overrides/index.d.ts @@ -0,0 +1,12 @@ +type Callback = (...args: TArgs) => TReturn; + +/** + * Returns a deprecation message or null to skip the deprecation. + */ +type Handler = Callback; +type GlobalAccessHandler = Handler<[]>; +type DotAccessHandler = Handler<[dotKey: string, importKey: string, module: string]>; + +export let onEmberGlobalAccess: GlobalAccessHandler | undefined; +export let onComputedDotAccess: DotAccessHandler | undefined; +export let onRunloopDotAccess: DotAccessHandler | undefined; diff --git a/packages/@ember/-internals/overrides/index.js b/packages/@ember/-internals/overrides/index.js new file mode 100644 index 00000000000..35b83669272 --- /dev/null +++ b/packages/@ember/-internals/overrides/index.js @@ -0,0 +1,3 @@ +export let onEmberGlobalAccess; +export let onComputedDotAccess; +export let onRunloopDotAccess; diff --git a/packages/@ember/-internals/routing/lib/services/router.ts b/packages/@ember/-internals/routing/lib/services/router.ts index 1982ea5e32a..8abcb6ff46d 100644 --- a/packages/@ember/-internals/routing/lib/services/router.ts +++ b/packages/@ember/-internals/routing/lib/services/router.ts @@ -58,9 +58,16 @@ export default class RouterService extends Service { } const owner = getOwner(this) as Owner; router = owner.lookup('router:main') as EmberRouter; + router.setupRouter(); return (this[ROUTER] = router); } + willDestroy() { + super.willDestroy(...arguments); + + this[ROUTER] = null; + } + /** Transition the application into another route. The route may be either a single route or route path: @@ -502,7 +509,9 @@ RouterService.reopen(Evented, { @type String @public */ - currentRouteName: readOnly('_router.currentRouteName'), + get currentRouteName() { + return this._router.currentRouteName; + }, /** Current URL for the application. diff --git a/packages/@ember/-internals/routing/lib/system/route.ts b/packages/@ember/-internals/routing/lib/system/route.ts index 60b87e409ea..69dcd37e48b 100644 --- a/packages/@ember/-internals/routing/lib/system/route.ts +++ b/packages/@ember/-internals/routing/lib/system/route.ts @@ -2026,11 +2026,21 @@ export function getFullQueryParams(router: EmberRouter, state: TransitionState routeInfo.route); - router._deserializeQueryParams(state.routeInfos, state['fullQueryParams'] as QueryParam); - return state['fullQueryParams']; + assign(fullQueryParamsState, state.queryParams); + + router._deserializeQueryParams(state.routeInfos, fullQueryParamsState as QueryParam); + + // only cache query params state if all routeinfos have resolved; it's possible + // for lazy routes to not have resolved when `getFullQueryParams` is called, so + // we wait until all routes have resolved prior to caching query params state + if (haveAllRouteInfosResolved) { + state['fullQueryParams'] = fullQueryParamsState; + } + + return fullQueryParamsState; } function getQueryParamsFor(route: Route, state: TransitionState) { @@ -2725,7 +2735,7 @@ if (ROUTER_EVENTS) { { id: 'deprecate-router-events', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_deprecate-router-events', + url: 'https://deprecations.emberjs.com/v3.x#toc_deprecate-router-events', for: 'ember-source', since: { enabled: '3.11.0', @@ -2741,7 +2751,7 @@ if (ROUTER_EVENTS) { { id: 'deprecate-router-events', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_deprecate-router-events', + url: 'https://deprecations.emberjs.com/v3.x#toc_deprecate-router-events', for: 'ember-source', since: { enabled: '3.11.0', diff --git a/packages/@ember/-internals/routing/lib/system/router.ts b/packages/@ember/-internals/routing/lib/system/router.ts index b2466ece517..7c54fb58355 100644 --- a/packages/@ember/-internals/routing/lib/system/router.ts +++ b/packages/@ember/-internals/routing/lib/system/router.ts @@ -259,7 +259,7 @@ class EmberRouter extends EmberObject { { id: 'deprecate-router-events', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_deprecate-router-events', + url: 'https://deprecations.emberjs.com/v3.x#toc_deprecate-router-events', for: 'ember-source', since: { enabled: '3.11.0', @@ -284,7 +284,7 @@ class EmberRouter extends EmberObject { { id: 'deprecate-router-events', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_deprecate-router-events', + url: 'https://deprecations.emberjs.com/v3.x#toc_deprecate-router-events', for: 'ember-source', since: { enabled: '3.11.0', @@ -1552,7 +1552,7 @@ function updatePaths(router: EmberRouter) { id: 'application-controller.router-properties', until: '4.0.0', url: - 'https://emberjs.com/deprecations/v3.x#toc_application-controller-router-properties', + 'https://deprecations.emberjs.com/v3.x#toc_application-controller-router-properties', for: 'ember-source', since: { enabled: '3.10.0-beta.1', @@ -1575,7 +1575,7 @@ function updatePaths(router: EmberRouter) { id: 'application-controller.router-properties', until: '4.0.0', url: - 'https://emberjs.com/deprecations/v3.x#toc_application-controller-router-properties', + 'https://deprecations.emberjs.com/v3.x#toc_application-controller-router-properties', for: 'ember-source', since: { enabled: '3.10.0-beta.1', diff --git a/packages/@ember/-internals/routing/lib/utils.ts b/packages/@ember/-internals/routing/lib/utils.ts index a4c82de6b52..71c666d244b 100644 --- a/packages/@ember/-internals/routing/lib/utils.ts +++ b/packages/@ember/-internals/routing/lib/utils.ts @@ -254,7 +254,7 @@ export function deprecateTransitionMethods(frameworkClass: string, methodName: s since: { enabled: '3.26.0', }, - until: '4.0.0', + until: '5.0.0', url: 'https://deprecations.emberjs.com/v3.x/#toc_routing-transition-methods', } ); diff --git a/packages/@ember/-internals/runtime/lib/copy.js b/packages/@ember/-internals/runtime/lib/copy.js index ea5add693ff..b3416485569 100644 --- a/packages/@ember/-internals/runtime/lib/copy.js +++ b/packages/@ember/-internals/runtime/lib/copy.js @@ -100,7 +100,7 @@ export default function copy(obj, deep) { deprecate('Use ember-copy addon instead of copy method and Copyable mixin.', false, { id: 'ember-runtime.deprecate-copy-copyable', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x/#toc_ember-runtime-deprecate-copy-copyable', + url: 'https://deprecations.emberjs.com/v3.x/#toc_ember-runtime-deprecate-copy-copyable', for: 'ember-source', since: { enabled: '3.3.0', diff --git a/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js b/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js index 6c46433fa6c..b0d4bde399b 100644 --- a/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js +++ b/packages/@ember/-internals/runtime/lib/mixins/target_action_support.js @@ -170,8 +170,11 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { deprecate('Reopening Ember.TargetActionSupport is deprecated.', false, { id: 'ember.built-in-components.reopen', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-reopen', }); TargetActionSupport._wasReopened = true; diff --git a/packages/@ember/-internals/views/lib/mixins/action_support.js b/packages/@ember/-internals/views/lib/mixins/action_support.js index 159f6cc5b8b..db831a8aa7e 100644 --- a/packages/@ember/-internals/views/lib/mixins/action_support.js +++ b/packages/@ember/-internals/views/lib/mixins/action_support.js @@ -135,7 +135,7 @@ if (SEND_ACTION) { { id: 'ember-component.send-action', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_ember-component-send-action', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-component-send-action', for: 'ember-source', since: { enabled: '3.4.0', diff --git a/packages/@ember/-internals/views/lib/mixins/text_support.js b/packages/@ember/-internals/views/lib/mixins/text_support.js index e7e8b197a17..cd0a949302c 100644 --- a/packages/@ember/-internals/views/lib/mixins/text_support.js +++ b/packages/@ember/-internals/views/lib/mixins/text_support.js @@ -328,7 +328,7 @@ function sendAction(eventName, view, event) { deprecate(message, false, { id: 'ember-component.send-action', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_ember-component-send-action', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-component-send-action', for: 'ember-source', since: { enabled: '3.4.0', @@ -365,8 +365,11 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { deprecate('Reopening Ember.TextSupport is deprecated.', false, { id: 'ember.built-in-components.reopen', for: 'ember-source', - since: {}, + since: { + enabled: '3.27.0', + }, until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-reopen', }); TextSupport._wasReopened = true; diff --git a/packages/@ember/-internals/views/lib/mixins/view_support.js b/packages/@ember/-internals/views/lib/mixins/view_support.js index 9e8867c5c98..5eb1e617f30 100644 --- a/packages/@ember/-internals/views/lib/mixins/view_support.js +++ b/packages/@ember/-internals/views/lib/mixins/view_support.js @@ -449,7 +449,7 @@ if (JQUERY_INTEGRATION) { { id: 'ember-views.curly-components.jquery-element', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_jquery-apis', + url: 'https://deprecations.emberjs.com/v3.x#toc_jquery-apis', for: 'ember-source', since: { enabled: '3.9.0', diff --git a/packages/@ember/-internals/views/lib/system/jquery_event_deprecation.js b/packages/@ember/-internals/views/lib/system/jquery_event_deprecation.js index f86cf84ae55..fe91faa4d75 100644 --- a/packages/@ember/-internals/views/lib/system/jquery_event_deprecation.js +++ b/packages/@ember/-internals/views/lib/system/jquery_event_deprecation.js @@ -30,7 +30,7 @@ export default function addJQueryEventDeprecation(jqEvent) { { id: 'ember-views.event-dispatcher.jquery-event', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_jquery-event', + url: 'https://deprecations.emberjs.com/v3.x#toc_jquery-event', for: 'ember-source', since: { enabled: '3.9.0', diff --git a/packages/@ember/-internals/views/lib/system/utils.ts b/packages/@ember/-internals/views/lib/system/utils.ts index 81050f2b5bd..454676c0ea6 100644 --- a/packages/@ember/-internals/views/lib/system/utils.ts +++ b/packages/@ember/-internals/views/lib/system/utils.ts @@ -22,7 +22,7 @@ export function constructStyleDeprecationMessage(affectedStyle: string): string 'Binding style attributes may introduce cross-site scripting vulnerabilities; ' + 'please ensure that values being bound are properly escaped. For more information, ' + 'including how to disable this warning, see ' + - 'https://emberjs.com/deprecations/v1.x/#toc_binding-style-attributes. ' + + 'https://deprecations.emberjs.com/v1.x/#toc_binding-style-attributes. ' + 'Style affected: "' + affectedStyle + '"' diff --git a/packages/@ember/canary-features/index.ts b/packages/@ember/canary-features/index.ts index c6afc535d6f..ce88fefdfbf 100644 --- a/packages/@ember/canary-features/index.ts +++ b/packages/@ember/canary-features/index.ts @@ -13,8 +13,8 @@ import { assign } from '@ember/polyfills'; */ export const DEFAULT_FEATURES = { - EMBER_LIBRARIES_ISREGISTERED: null, - EMBER_IMPROVED_INSTRUMENTATION: null, + EMBER_LIBRARIES_ISREGISTERED: false, + EMBER_IMPROVED_INSTRUMENTATION: false, EMBER_NAMED_BLOCKS: true, EMBER_GLIMMER_HELPER_MANAGER: true, EMBER_GLIMMER_INVOKE_HELPER: true, diff --git a/packages/@ember/component/checkbox.ts b/packages/@ember/component/checkbox.ts index 374d4fb53cb..28788824d26 100644 --- a/packages/@ember/component/checkbox.ts +++ b/packages/@ember/component/checkbox.ts @@ -4,16 +4,17 @@ import { deprecate } from '@ember/debug'; if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { deprecate( `Using Ember.Checkbox or importing from 'Checkbox' has been deprecated, install the ` + - `\`ember-legacy-built-in-components\` addon and use \`import { Checkbox } from ` + - `'ember-legacy-built-in-components';\` instead`, + `\`@ember/legacy-built-in-components\` addon and use \`import { Checkbox } from ` + + `'@ember/legacy-built-in-components';\` instead`, false, { - id: 'ember.legacy-built-in-components', + id: 'ember.built-in-components.import', until: '4.0.0', for: 'ember-source', since: { - // TODO: update this when enabling the feature + enabled: '3.27.0', }, + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-import', } ); } diff --git a/packages/@ember/component/text-area.ts b/packages/@ember/component/text-area.ts index 10aaf051c0a..930a55ee198 100644 --- a/packages/@ember/component/text-area.ts +++ b/packages/@ember/component/text-area.ts @@ -4,16 +4,17 @@ import { deprecate } from '@ember/debug'; if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { deprecate( `Using Ember.TextArea or importing from 'TextArea' has been deprecated, install the ` + - `\`ember-legacy-built-in-components\` addon and use \`import { TextArea } from ` + - `'ember-legacy-built-in-components';\` instead`, + `\`@ember/legacy-built-in-components\` addon and use \`import { TextArea } from ` + + `'@ember/legacy-built-in-components';\` instead`, false, { - id: 'ember.legacy-built-in-components', + id: 'ember.built-in-components.import', until: '4.0.0', for: 'ember-source', since: { - // TODO: update this when enabling the feature + enabled: '3.27.0', }, + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-import', } ); } diff --git a/packages/@ember/component/text-field.ts b/packages/@ember/component/text-field.ts index 119f91bb2b3..77f3d6cdf3b 100644 --- a/packages/@ember/component/text-field.ts +++ b/packages/@ember/component/text-field.ts @@ -4,16 +4,17 @@ import { deprecate } from '@ember/debug'; if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { deprecate( `Using Ember.TextField or importing from 'TextField' has been deprecated, install the ` + - `\`ember-legacy-built-in-components\` addon and use \`import { TextField } from ` + - `'ember-legacy-built-in-components';\` instead`, + `\`@ember/legacy-built-in-components\` addon and use \`import { TextField } from ` + + `'@ember/legacy-built-in-components';\` instead`, false, { - id: 'ember.legacy-built-in-components', + id: 'ember.built-in-components.import', until: '4.0.0', for: 'ember-source', since: { - // TODO: update this when enabling the feature + enabled: '3.27.0', }, + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-import', } ); } diff --git a/packages/@ember/object/index.js b/packages/@ember/object/index.js index 9c6bb11faed..d6ae7fbbf84 100644 --- a/packages/@ember/object/index.js +++ b/packages/@ember/object/index.js @@ -2,6 +2,7 @@ import { DEBUG } from '@glimmer/env'; import { assert, deprecate } from '@ember/debug'; import { assign } from '@ember/polyfills'; import { isElementDescriptor, setClassicDecorator } from '@ember/-internals/metal'; +import { onComputedDotAccess } from '@ember/-internals/overrides'; export { Object as default } from '@ember/-internals/runtime'; @@ -57,21 +58,25 @@ import { // eslint-disable-next-line no-undef if (DEBUG) { + let defaultHandler = (dotKey, importKey, module) => { + return `Using \`${dotKey}\` has been deprecated. Instead, import the value directly from ${module}:\n\n import { ${importKey} } from '${module}';`; + }; + + let handler = onComputedDotAccess || defaultHandler; + let defineDeprecatedComputedFunc = (key, func) => { Object.defineProperty(computed, key, { get() { - deprecate( - `Using \`computed.${key}\` has been deprecated. Instead, import the value directly from @ember/object/computed:\n\n import { ${key} } from '@ember/runloop';`, - false, - { - id: 'deprecated-run-loop-and-computed-dot-access', - until: '4.0.0', - for: 'ember-source', - since: { - enabled: '3.27.0', - }, - } - ); + let message = handler(`computed.${key}`, key, '@ember/object/computed'); + + deprecate(message, message === null, { + id: 'deprecated-run-loop-and-computed-dot-access', + until: '4.0.0', + for: 'ember-source', + since: { + enabled: '3.27.0', + }, + }); return func; }, diff --git a/packages/@ember/polyfills/lib/merge.ts b/packages/@ember/polyfills/lib/merge.ts index 3e7bf2c08d7..dfd90473a17 100644 --- a/packages/@ember/polyfills/lib/merge.ts +++ b/packages/@ember/polyfills/lib/merge.ts @@ -31,7 +31,7 @@ function merge(original: object, updates: object) { deprecate('Use of `merge` has been deprecated. Please use `assign` instead.', false, { id: 'ember-polyfills.deprecate-merge', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x/#toc_ember-polyfills-deprecate-merge', + url: 'https://deprecations.emberjs.com/v3.x/#toc_ember-polyfills-deprecate-merge', for: 'ember-source', since: { enabled: '3.6.0-beta.1', diff --git a/packages/@ember/routing/link-component.ts b/packages/@ember/routing/link-component.ts index e419425d424..8c3e4f86a60 100644 --- a/packages/@ember/routing/link-component.ts +++ b/packages/@ember/routing/link-component.ts @@ -4,16 +4,17 @@ import { deprecate } from '@ember/debug'; if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { deprecate( `Using Ember.LinkComponent or importing from 'LinkComponent' has been deprecated, install the ` + - `\`ember-legacy-built-in-components\` addon and use \`import { LinkComponent } from ` + - `'ember-legacy-built-in-components';\` instead`, + `\`@ember/legacy-built-in-components\` addon and use \`import { LinkComponent } from ` + + `'@ember/legacy-built-in-components';\` instead`, false, { - id: 'ember.legacy-built-in-components', + id: 'ember.built-in-components.import', until: '4.0.0', for: 'ember-source', since: { - // TODO: update this when enabling the feature + enabled: '3.27.0', }, + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-import', } ); } diff --git a/packages/@ember/runloop/index.js b/packages/@ember/runloop/index.js index d3ae2d1e780..c78ceaa48a5 100644 --- a/packages/@ember/runloop/index.js +++ b/packages/@ember/runloop/index.js @@ -2,6 +2,7 @@ import { DEBUG } from '@glimmer/env'; import { assert, deprecate } from '@ember/debug'; import { onErrorTarget } from '@ember/-internals/error-handling'; import { flushAsyncObservers } from '@ember/-internals/metal'; +import { onRunloopDotAccess } from '@ember/-internals/overrides'; import Backburner from 'backburner'; let currentRunLoop = null; @@ -745,21 +746,25 @@ export let _deprecatedGlobalGetCurrentRunLoop; // eslint-disable-next-line no-undef if (DEBUG) { + let defaultHandler = (dotKey, importKey, module) => { + return `Using \`${dotKey}\` has been deprecated. Instead, import the value directly from ${module}:\n\n import { ${importKey} } from '${module}';`; + }; + + let handler = onRunloopDotAccess || defaultHandler; + let defineDeprecatedRunloopFunc = (key, func) => { Object.defineProperty(run, key, { get() { - deprecate( - `Using \`run.${key}\` has been deprecated. Instead, import the value directly from @ember/runloop:\n\n import { ${key} } from '@ember/runloop';`, - false, - { - id: 'deprecated-run-loop-and-computed-dot-access', - until: '4.0.0', - for: 'ember-source', - since: { - enabled: '3.27.0', - }, - } - ); + let message = handler(`run.${key}`, key, '@ember/runloop'); + + deprecate(message, message === null, { + id: 'deprecated-run-loop-and-computed-dot-access', + until: '4.0.0', + for: 'ember-source', + since: { + enabled: '3.27.0', + }, + }); return func; }, @@ -767,18 +772,16 @@ if (DEBUG) { }; _deprecatedGlobalGetCurrentRunLoop = () => { - deprecate( - `Using \`run.currentRunLoop\` has been deprecated. Instead, import the getCurrentRunLoop() directly from @ember/runloop:\n\n import { getCurrentRunLoop } from '@ember/runloop';`, - false, - { - id: 'deprecated-run-loop-and-computed-dot-access', - until: '4.0.0', - for: 'ember-source', - since: { - enabled: '3.27.0', - }, - } - ); + let message = handler('run.currentRunLoop', 'getCurrentRunLoop', '@ember/runloop'); + + deprecate(message, message === null, { + id: 'deprecated-run-loop-and-computed-dot-access', + until: '4.0.0', + for: 'ember-source', + since: { + enabled: '3.27.0', + }, + }); return _getCurrentRunLoop(); }; diff --git a/packages/@ember/test/index.js b/packages/@ember/test/index.js index 2c5d3ae272d..3f226dbcac6 100644 --- a/packages/@ember/test/index.js +++ b/packages/@ember/test/index.js @@ -1,11 +1,27 @@ -import { Test } from 'ember-testing'; +import require, { has } from 'require'; -const { - registerAsyncHelper, - registerHelper, - registerWaiter, - unregisterHelper, - unregisterWaiter, -} = Test; +export let registerAsyncHelper; +export let registerHelper; +export let registerWaiter; +export let unregisterHelper; +export let unregisterWaiter; -export { registerAsyncHelper, registerHelper, registerWaiter, unregisterHelper, unregisterWaiter }; +if (has('ember-testing')) { + let { Test } = require('ember-testing'); + + registerAsyncHelper = Test.registerAsyncHelper; + registerHelper = Test.registerHelper; + registerWaiter = Test.registerWaiter; + unregisterHelper = Test.unregisterHelper; + unregisterWaiter = Test.unregisterWaiter; +} else { + let testingNotAvailableMessage = () => { + throw new Error('Attempted to use test utilities, but `ember-testing` was not included'); + }; + + registerAsyncHelper = testingNotAvailableMessage; + registerHelper = testingNotAvailableMessage; + registerWaiter = testingNotAvailableMessage; + unregisterHelper = testingNotAvailableMessage; + unregisterWaiter = testingNotAvailableMessage; +} diff --git a/packages/ember-template-compiler/lib/plugins/deprecate-send-action.ts b/packages/ember-template-compiler/lib/plugins/deprecate-send-action.ts index 8a7962172ed..5d72fb778bd 100644 --- a/packages/ember-template-compiler/lib/plugins/deprecate-send-action.ts +++ b/packages/ember-template-compiler/lib/plugins/deprecate-send-action.ts @@ -48,7 +48,7 @@ export default function deprecateSendAction(env: EmberASTPluginEnvironment): AST deprecate(deprecationMessage(node, eventName, value.chars), false, { id: 'ember-component.send-action', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_ember-component-send-action', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-component-send-action', for: 'ember-source', since: { enabled: '3.4.0', @@ -61,7 +61,7 @@ export default function deprecateSendAction(env: EmberASTPluginEnvironment): AST deprecate(deprecationMessage(node, eventName, value.path.original), false, { id: 'ember-component.send-action', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_ember-component-send-action', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-component-send-action', for: 'ember-source', since: { enabled: '3.4.0', @@ -83,7 +83,7 @@ export default function deprecateSendAction(env: EmberASTPluginEnvironment): AST deprecate(deprecationMessage(node, pair.key, pair.value.original), false, { id: 'ember-component.send-action', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_ember-component-send-action', + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-component-send-action', for: 'ember-source', since: { enabled: '3.4.0', diff --git a/packages/ember-template-compiler/lib/plugins/transform-has-block-syntax.ts b/packages/ember-template-compiler/lib/plugins/transform-has-block-syntax.ts index 34ead65a659..ac45872bf34 100644 --- a/packages/ember-template-compiler/lib/plugins/transform-has-block-syntax.ts +++ b/packages/ember-template-compiler/lib/plugins/transform-has-block-syntax.ts @@ -42,7 +42,7 @@ export default function transformHasBlockSyntax(env: EmberASTPluginEnvironment): { id: 'has-block-and-has-block-params', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_has-block-and-has-block-params', + url: 'https://deprecations.emberjs.com/v3.x#toc_has-block-and-has-block-params', for: 'ember-source', since: { enabled: '3.25.0', diff --git a/packages/ember-template-compiler/lib/system/compile-options.ts b/packages/ember-template-compiler/lib/system/compile-options.ts index 1f4c3e67964..4dd7fbba8d8 100644 --- a/packages/ember-template-compiler/lib/system/compile-options.ts +++ b/packages/ember-template-compiler/lib/system/compile-options.ts @@ -37,6 +37,15 @@ export function buildCompileOptions(_options: EmberPrecompileOptions): EmberPrec options.locals = undefined; } + if ('locals' in options && !options.locals) { + // Glimmer's precompile options declare `locals` like: + // locals?: string[] + // but many in-use versions of babel-plugin-htmlbars-inline-precompile will + // set locals to `null`. This used to work but only because glimmer was + // ignoring locals for non-strict templates, and now it supports that case. + delete options.locals; + } + // move `moduleName` into `meta` property if (options.moduleName) { let meta = options.meta; @@ -82,11 +91,16 @@ interface LegacyPlugin { export type LegacyPluginClass = new (env: ASTPluginEnvironment) => LegacyPlugin; -function wrapLegacyPluginIfNeeded(_plugin: PluginFunc | LegacyPluginClass): PluginFunc { - let plugin = _plugin; - if (_plugin.prototype && _plugin.prototype.transform) { +function isLegacyPluginClass(plugin: PluginFunc | LegacyPluginClass): plugin is LegacyPluginClass { + return plugin.prototype && typeof plugin.prototype.transform === 'function'; +} + +function wrapLegacyPluginIfNeeded(plugin: PluginFunc | LegacyPluginClass): PluginFunc { + if (isLegacyPluginClass(plugin)) { + const Plugin = plugin; + deprecate( - 'Using class based template compilation plugins is deprecated, please update to the functional style', + `Using class based template compilation plugins is deprecated, please update to the functional style: ${Plugin.name}`, false, { id: 'template-compiler.registerPlugin', @@ -102,28 +116,29 @@ function wrapLegacyPluginIfNeeded(_plugin: PluginFunc | LegacyPluginClass): Plug let pluginInstantiated = false; return { - name: _plugin.constructor && _plugin.constructor.name, + name: plugin.name, visitor: { Program(node: AST.Program): AST.Node | void { if (!pluginInstantiated) { pluginInstantiated = true; - let plugin = new (_plugin as LegacyPluginClass)(env); + let instance = new Plugin(env); - plugin.syntax = env.syntax; + instance.syntax = env.syntax; - return plugin.transform(node); + return instance.transform(node); } }, }, }; }; - pluginFunc.__raw = _plugin as LegacyPluginClass; - plugin = pluginFunc; - } + pluginFunc.__raw = Plugin; - return plugin as PluginFunc; + return pluginFunc; + } else { + return plugin; + } } export function registerPlugin(type: string, _plugin: PluginFunc | LegacyPluginClass): void { diff --git a/packages/ember-template-compiler/tests/system/compile_options_test.js b/packages/ember-template-compiler/tests/system/compile_options_test.js index 921d3f2387a..2b75b69f36d 100644 --- a/packages/ember-template-compiler/tests/system/compile_options_test.js +++ b/packages/ember-template-compiler/tests/system/compile_options_test.js @@ -124,7 +124,7 @@ moduleFor( class extends CustomPluginsTests { beforeEach() { expectDeprecation( - 'Using class based template compilation plugins is deprecated, please update to the functional style' + `Using class based template compilation plugins is deprecated, please update to the functional style: ${LegacyCustomTransform.name}` ); expectDeprecation( 'registerPlugin is deprecated, please pass plugins directly via `compile` and/or `precompile`.' @@ -141,7 +141,7 @@ moduleFor( ['@test custom registered plugins are deduplicated'](assert) { expectDeprecation( - 'Using class based template compilation plugins is deprecated, please update to the functional style' + `Using class based template compilation plugins is deprecated, please update to the functional style: ${LegacyCustomTransform.name}` ); expectDeprecation( 'registerPlugin is deprecated, please pass plugins directly via `compile` and/or `precompile`.' @@ -194,7 +194,7 @@ moduleFor( // override so that we can provide custom AST plugins to compile compile(templateString) { expectDeprecation( - 'Using class based template compilation plugins is deprecated, please update to the functional style' + 'Using class based template compilation plugins is deprecated, please update to the functional style: LegacyCustomTransform' ); return compile(templateString, { plugins: { diff --git a/packages/ember/index.js b/packages/ember/index.js index 43543fdb462..76c0eb46172 100644 --- a/packages/ember/index.js +++ b/packages/ember/index.js @@ -143,7 +143,7 @@ deprecate( !isIE, { id: '3-0-browser-support-policy', - url: 'https://emberjs.com/deprecations/v3.x#toc_3-0-browser-support-policy', + url: 'https://deprecations.emberjs.com/v3.x#toc_3-0-browser-support-policy', until: '4.0.0', for: 'ember-source', since: { @@ -513,17 +513,18 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { if (availableInLegacyAddon) { message += - ` Install the \`ember-legacy-built-in-components\` addon and use ` + - `\`import { ${name} } from 'ember-legacy-built-in-components';\` instead.`; + ` Install the \`@ember/legacy-built-in-components\` addon and use ` + + `\`import { ${name} } from '@ember/legacy-built-in-components';\` instead.`; } deprecate(message, false, { - id: 'ember.built-in-components.legacy-import', + id: 'ember.built-in-components.import', until: '4.0.0', for: 'ember-source', since: { - // TODO: update this when enabling the feature + enabled: '3.27.0', }, + url: 'https://deprecations.emberjs.com/v3.x#toc_ember-built-in-components-import', }); return value; @@ -533,7 +534,7 @@ if (EMBER_MODERNIZED_BUILT_IN_COMPONENTS) { enumerable: true, }); - // Expose a non-deprecated version for tests and the ember-legacy-built-in-components addon + // Expose a non-deprecated version for tests and the @ember/legacy-built-in-components addon Ember[`_Legacy${name}`] = value; }); } else { @@ -572,6 +573,19 @@ Ember._captureRenderTree = captureRenderTree; if (ENV.EXTEND_PROTOTYPES.String) { String.prototype.htmlSafe = function () { + deprecate( + `String prototype extensions are deprecated. Please import htmlSafe from '@ember/template' instead.`, + false, + { + id: 'ember-string.prototype-extensions', + for: 'ember-source', + since: { + enabled: '3.27.6', + }, + until: '4.0.0', + url: 'https://deprecations.emberjs.com/v3.x/#toc_ember-string-htmlsafe-ishtmlsafe', + } + ); return htmlSafe(this); }; } @@ -644,7 +658,7 @@ if (JQUERY_INTEGRATION && !views.jQueryDisabled) { { id: 'ember-views.curly-components.jquery-element', until: '4.0.0', - url: 'https://emberjs.com/deprecations/v3.x#toc_jquery-apis', + url: 'https://deprecations.emberjs.com/v3.x#toc_jquery-apis', for: 'ember-source', since: { enabled: '3.9.0', diff --git a/packages/ember/tests/reexports_test.js b/packages/ember/tests/reexports_test.js index b5e131eff1d..4bccf517f6b 100644 --- a/packages/ember/tests/reexports_test.js +++ b/packages/ember/tests/reexports_test.js @@ -66,7 +66,7 @@ moduleFor( ), publicPath === null ? `Using Ember.${name} is deprecated.` - : `Using Ember.${name} or importing from '${publicPath}' is deprecated. Install the \`ember-legacy-built-in-components\` addon and use \`import { ${name} } from 'ember-legacy-built-in-components';\` instead.` + : `Using Ember.${name} or importing from '${publicPath}' is deprecated. Install the \`@ember/legacy-built-in-components\` addon and use \`import { ${name} } from '@ember/legacy-built-in-components';\` instead.` ); } catch (error) { assert.pushResult({ diff --git a/packages/ember/tests/routing/router_service_test/non_application_test_test.js b/packages/ember/tests/routing/router_service_test/non_application_test_test.js index add81994bdd..f24f24b8e00 100644 --- a/packages/ember/tests/routing/router_service_test/non_application_test_test.js +++ b/packages/ember/tests/routing/router_service_test/non_application_test_test.js @@ -66,14 +66,15 @@ moduleFor( } ['@test RouterService#urlFor returns url'](assert) { - let router = this.owner.lookup('router:main'); - router.setupRouter(); assert.equal(this.routerService.urlFor('parent.child'), '/child'); } ['@test RouterService#transitionTo with basic route'](assert) { assert.expect(2); + // Callers who want to actually execute a transition in a non-application + // test are doing something weird and therefore should do + // `owner.setupRouter()` explicitly in their tests. let componentInstance; let router = this.owner.lookup('router:main'); router.setupRouter(); @@ -107,8 +108,6 @@ moduleFor( } ['@test RouterService#recognize recognize returns routeInfo'](assert) { - let router = this.owner.lookup('router:main'); - router.setupRouter(); let routeInfo = this.routerService.recognize('/dynamic-with-child/123/1?a=b'); assert.ok(routeInfo); let { name, localName, parent, child, params, queryParams, paramNames } = routeInfo; diff --git a/tests/node/fixtures/project.js b/tests/node/fixtures/project.js new file mode 100644 index 00000000000..bcc867af91c --- /dev/null +++ b/tests/node/fixtures/project.js @@ -0,0 +1,148 @@ +module.exports = class Project { + static withDep(depOptions = {}, projectOptions = {}) { + let addons = projectOptions.addons || []; + + return new Project({ + ...projectOptions, + addons: [...addons, new Addon(depOptions)], + }); + } + + static withTransientDep(transientDepOptions = {}, depOptions = {}, projectOptions = {}) { + let addons = depOptions.addons || []; + + return Project.withDep( + { + ...depOptions, + addons: [ + ...addons, + new Addon({ + name: 'my-nested-addon', + version: '0.1.0', + ...transientDepOptions, + }), + ], + }, + projectOptions + ); + } + + constructor({ + name = 'my-app', + emberCliBabel, + dependencies = {}, + devDependencies = {}, + addons = [], + } = {}) { + this.name = () => name; + this.parent = null; + this.pkg = { + name, + dependencies: { ...dependencies }, + devDependencies: { ...devDependencies }, + }; + this.addons = [...addons]; + + if (typeof emberCliBabel === 'string') { + this.pkg.devDependencies['ember-cli-babel'] = emberCliBabel; + } + + reifyAddons(this); + addMissingAddons(this, this.pkg.devDependencies); + addMissingAddons(this, this.pkg.dependencies); + addMissingDeps(this, true); + } +}; + +class Addon { + constructor({ + parent, + name = 'my-addon', + version = '1.0.0', + emberCliBabel, + dependencies = {}, + addons = [], + hasJSFiles = name !== 'ember-cli-babel', + } = {}) { + this.parent = parent; + this.name = name; + this.pkg = { + name, + version, + dependencies: { ...dependencies }, + devDependencies: {}, + }; + this.addons = [...addons]; + this._fileSystemInfo = () => ({ hasJSFiles }); + + if (typeof emberCliBabel === 'string') { + this.pkg.dependencies['ember-cli-babel'] = emberCliBabel; + } + + reifyAddons(this); + addMissingAddons(this, this.pkg.dependencies); + addMissingDeps(this); + } +} + +// Can only handle the few hardcoded cases +function resolve(requirement) { + if (requirement.startsWith('link:')) { + // Expecting something like "link:1.2.3" + return requirement.slice(5); + } else { + // Only handles "^1.0.0" -> "1.0.0", doesn't work for the general case + return requirement.slice(1); + } +} + +function reifyAddons(parent) { + parent.addons = parent.addons.map((addon) => { + if (addon instanceof Addon) { + addon.parent = parent; + return addon; + } else { + let version = addon.version; + + if (!version) { + if (parent.pkg.devDependencies[addon.name]) { + version = resolve(parent.pkg.devDependencies[addon.name]); + } else if (parent.pkg.dependencies[addon.name]) { + version = resolve(parent.pkg.dependencies[addon.name]); + } + } + + return new Addon({ ...addon, parent, version }); + } + }); +} + +function addMissingAddons(parent, deps) { + for (let [name, requirement] of Object.entries(deps)) { + if (!parent.addons.find((addon) => addon.name === name)) { + parent.addons.push( + new Addon({ + parent, + name, + version: resolve(requirement), + }) + ); + } + } +} + +function addMissingDeps(parent, devDeps = false) { + for (let addon of parent.addons) { + let target = parent.pkg.dependencies; + let isMissing = !(addon.name in target); + + if (devDeps) { + target = parent.pkg.devDependencies; + isMissing = isMissing && !(addon.name in target); + } + + if (isMissing) { + target[addon.name] = `^${addon.pkg.version}`; + } + } +} diff --git a/tests/node/overrides-test.js b/tests/node/overrides-test.js new file mode 100644 index 00000000000..90dc4aebe4e --- /dev/null +++ b/tests/node/overrides-test.js @@ -0,0 +1,869 @@ +'use strict'; + +const Project = require('./fixtures/project'); +const Overrides = require('../../lib/overrides'); + +function cmp(a, b) { + if (a == undefined || a < b) { + return -1; + } else if (b == undefined || a > b) { + return 1; + } else { + return 0; + } +} + +function addonsInfoFor(project) { + if (!(project instanceof Project)) { + project = new Project(project); + } + + let addonsInfo = [...Overrides.addonsInfoFor(project)]; + + addonsInfo.sort((a, b) => cmp(a.topLevel, b.topLevel) || cmp(a.parent, b.parent)); + + return addonsInfo; +} + +function fullExample() { + return { + name: 'direwolf', + devDependencies: { + 'active-model-adapter': '^2.2.0', + 'ember-animated': '^0.11.0', + 'ember-cli-babel': '^7.26.3', + 'ember-fetch': '^8.0.5', + 'ember-source': 'link:3.27.3', + }, + addons: [ + { + name: 'active-model-adapter', + dependencies: { + 'ember-cli-babel': '^6.18.0', + }, + }, + { + name: 'ember-animated', + dependencies: { + 'ember-angle-bracket-invocation-polyfill': '^2.0.0', + 'ember-cli-babel': '^7.26.3', + }, + addons: [ + { + name: 'ember-angle-bracket-invocation-polyfill', + dependencies: { + 'ember-cli-babel': '^6.16.0', + }, + addons: [ + { + name: 'ember-cli-babel', + version: '6.18.0', + }, + ], + }, + { + name: 'ember-cli-babel', + version: '7.26.5', + }, + ], + }, + { + name: 'ember-cli-babel', + version: '7.26.5', + }, + { + name: 'ember-fetch', + hasJSFiles: false, + dependencies: { + 'ember-cli-babel': '^7.26.0', + }, + }, + { + name: 'ember-source', + dependencies: { + 'ember-cli-babel': '^7.26.6', + }, + }, + ], + }; +} + +function infoForApp({ + name = 'direwolf', + version = '7.26.6', + requirement = `^${version}`, + compatible = requirement.startsWith('^7'), +} = {}) { + return { + parent: `${name} (your app)`, + topLevel: null, + version, + requirement, + compatible, + dormant: false, + path: [], + }; +} + +// function info({ +// parent, +// topLevel = parent, +// version = '7.26.6', +// requirement = `^${version}`, +// compatible = requirement.startsWith('^7'), +// dormant = false, +// path = [`${parent}@${version}`], +// } = {}) { +// return { +// parent, +// topLevel, +// version, +// requirement, +// compatible, +// dormant, +// path, +// }; +// } + +function evalJS(overrides) { + return eval(` + (function () { + let onEmberGlobalAccess, onComputedDotAccess, onRunloopDotAccess; + + ${overrides.toJS()} + + return { + onEmberGlobalAccess: onEmberGlobalAccess, + onComputedDotAccess: onComputedDotAccess, + onRunloopDotAccess: onRunloopDotAccess, + }; + })() + `); +} + +QUnit.module('Overrides', function () { + QUnit.module('.addonsInfoFor', function () { + // app + + QUnit.test('it returns old babel added by app', function (assert) { + assert.deepEqual(addonsInfoFor({ emberCliBabel: '^6.0.0' }), [ + { + parent: 'my-app (your app)', + topLevel: null, + version: '6.0.0', + requirement: '^6.0.0', + compatible: false, + dormant: false, + path: [], + }, + ]); + }); + + QUnit.test('it returns old but compatible babel added by app', function (assert) { + assert.deepEqual(addonsInfoFor({ emberCliBabel: '^7.0.0' }), [ + { + parent: 'my-app (your app)', + topLevel: null, + version: '7.0.0', + requirement: '^7.0.0', + compatible: true, + dormant: false, + path: [], + }, + ]); + }); + + QUnit.test('it does not return new babel added by app', function (assert) { + assert.deepEqual(addonsInfoFor({ emberCliBabel: '^7.26.6' }), []); + }); + + // direct dependency + + QUnit.test('it returns old babel added by a dependency', function (assert) { + assert.deepEqual(addonsInfoFor(Project.withDep({ emberCliBabel: '^6.0.0' })), [ + { + parent: 'my-addon@1.0.0', + topLevel: 'my-addon', + version: '6.0.0', + requirement: '^6.0.0', + compatible: false, + dormant: false, + path: ['my-addon@1.0.0'], + }, + ]); + }); + + QUnit.test('it returns old but compatible babel added by a dependency', function (assert) { + assert.deepEqual(addonsInfoFor(Project.withDep({ emberCliBabel: '^7.0.0' })), [ + { + parent: 'my-addon@1.0.0', + topLevel: 'my-addon', + version: '7.0.0', + requirement: '^7.0.0', + compatible: true, + dormant: false, + path: ['my-addon@1.0.0'], + }, + ]); + }); + + QUnit.test('it does not return new babel added by a dependency', function (assert) { + assert.deepEqual(addonsInfoFor(Project.withDep({ emberCliBabel: '^7.26.6' })), []); + }); + + // direct dependency (dormant) + + QUnit.test('it returns old babel added by a dormant dependency', function (assert) { + assert.deepEqual( + addonsInfoFor(Project.withDep({ emberCliBabel: '^6.0.0', hasJSFiles: false })), + [ + { + parent: 'my-addon@1.0.0', + topLevel: 'my-addon', + version: '6.0.0', + requirement: '^6.0.0', + compatible: false, + dormant: true, + path: ['my-addon@1.0.0'], + }, + ] + ); + }); + + QUnit.test('it returns old but compatible babel added by a dormant dependency', function ( + assert + ) { + assert.deepEqual( + addonsInfoFor(Project.withDep({ emberCliBabel: '^7.0.0', hasJSFiles: false })), + [ + { + parent: 'my-addon@1.0.0', + topLevel: 'my-addon', + version: '7.0.0', + requirement: '^7.0.0', + compatible: true, + dormant: true, + path: ['my-addon@1.0.0'], + }, + ] + ); + }); + + QUnit.test('it does not return new babel added by a dormant dependency', function (assert) { + assert.deepEqual( + addonsInfoFor(Project.withDep({ emberCliBabel: '^7.26.6', hasJSFiles: false })), + [] + ); + }); + + // transient dep + + QUnit.test('it returns old babel added by a transient dependency', function (assert) { + assert.deepEqual(addonsInfoFor(Project.withTransientDep({ emberCliBabel: '^6.0.0' })), [ + { + parent: 'my-nested-addon@0.1.0', + topLevel: 'my-addon', + version: '6.0.0', + requirement: '^6.0.0', + compatible: false, + dormant: false, + path: ['my-addon@1.0.0', 'my-nested-addon@0.1.0'], + }, + ]); + }); + + QUnit.test('it returns old but compatible babel added by a transient dependency', function ( + assert + ) { + assert.deepEqual(addonsInfoFor(Project.withTransientDep({ emberCliBabel: '^7.0.0' })), [ + { + parent: 'my-nested-addon@0.1.0', + topLevel: 'my-addon', + version: '7.0.0', + requirement: '^7.0.0', + compatible: true, + dormant: false, + path: ['my-addon@1.0.0', 'my-nested-addon@0.1.0'], + }, + ]); + }); + + QUnit.test('it does not return new babel added by a transient dependency', function (assert) { + assert.deepEqual(addonsInfoFor(Project.withDep({ emberCliBabel: '^7.26.6' })), []); + }); + + // dormant transient dep + + QUnit.test('it returns old babel added by a dormant transient dependency', function (assert) { + assert.deepEqual( + addonsInfoFor(Project.withTransientDep({ emberCliBabel: '^6.0.0', hasJSFiles: false })), + [ + { + parent: 'my-nested-addon@0.1.0', + topLevel: 'my-addon', + version: '6.0.0', + requirement: '^6.0.0', + compatible: false, + dormant: true, + path: ['my-addon@1.0.0', 'my-nested-addon@0.1.0'], + }, + ] + ); + }); + + QUnit.test( + 'it returns old but compatible babel added by a dormant transient dependency', + function (assert) { + assert.deepEqual( + addonsInfoFor(Project.withTransientDep({ emberCliBabel: '^7.0.0', hasJSFiles: false })), + [ + { + parent: 'my-nested-addon@0.1.0', + topLevel: 'my-addon', + version: '7.0.0', + requirement: '^7.0.0', + compatible: true, + dormant: true, + path: ['my-addon@1.0.0', 'my-nested-addon@0.1.0'], + }, + ] + ); + } + ); + + QUnit.test('it does not return new babel added by a dormant transient dependency', function ( + assert + ) { + assert.deepEqual( + addonsInfoFor(Project.withDep({ emberCliBabel: '^7.26.6', hasJSFiles: false })), + [] + ); + }); + + // transient dep through a dormant dep + + QUnit.test( + 'it returns old babel added by a transient dependency through a dormant dependency', + function (assert) { + assert.deepEqual( + addonsInfoFor( + Project.withTransientDep({ emberCliBabel: '^6.0.0' }, { hasJSFiles: false }) + ), + [ + { + parent: 'my-nested-addon@0.1.0', + topLevel: 'my-addon', + version: '6.0.0', + requirement: '^6.0.0', + compatible: false, + dormant: false, + path: ['my-addon@1.0.0', 'my-nested-addon@0.1.0'], + }, + ] + ); + } + ); + + QUnit.test( + 'it returns old but compatible babel added by a transient dependency through a dormant dependency', + function (assert) { + assert.deepEqual( + addonsInfoFor( + Project.withTransientDep({ emberCliBabel: '^7.0.0' }, { hasJSFiles: false }) + ), + [ + { + parent: 'my-nested-addon@0.1.0', + topLevel: 'my-addon', + version: '7.0.0', + requirement: '^7.0.0', + compatible: true, + dormant: false, + path: ['my-addon@1.0.0', 'my-nested-addon@0.1.0'], + }, + ] + ); + } + ); + + QUnit.test( + 'it does not return new babel added by a transient dependency through a dormant dependency', + function (assert) { + assert.deepEqual( + addonsInfoFor(Project.withDep({ emberCliBabel: '^7.26.6' }, { hasJSFiles: false })), + [] + ); + } + ); + + // linked dep + + QUnit.test('it returns old babel added by a linked dependency', function (assert) { + assert.deepEqual( + addonsInfoFor( + new Project({ + devDependencies: { + 'ember-source': 'link:3.27.3', + }, + addons: [ + { + name: 'ember-source', + emberCliBabel: '^6.0.0', + }, + ], + }) + ), + [ + { + parent: 'ember-source@3.27.3', + topLevel: 'ember-source', + version: '6.0.0', + requirement: '^6.0.0', + compatible: false, + dormant: false, + path: ['ember-source@3.27.3'], + }, + ] + ); + }); + + QUnit.test('it returns old but compatible babel added by a linked dependency', function ( + assert + ) { + assert.deepEqual( + addonsInfoFor( + new Project({ + devDependencies: { + 'ember-source': 'link:3.27.3', + }, + addons: [ + { + name: 'ember-source', + emberCliBabel: '^7.0.0', + }, + ], + }) + ), + [ + { + parent: 'ember-source@3.27.3', + topLevel: 'ember-source', + version: '7.0.0', + requirement: '^7.0.0', + compatible: true, + dormant: false, + path: ['ember-source@3.27.3'], + }, + ] + ); + }); + + QUnit.test('it does not return new babel added by a linked dependency', function (assert) { + assert.deepEqual( + addonsInfoFor( + new Project({ + devDependencies: { + 'ember-source': 'link:3.27.3', + }, + addons: [ + { + name: 'ember-source', + emberCliBabel: '^7.26.6', + }, + ], + }) + ), + [] + ); + }); + + // full example + + QUnit.test('full example', function (assert) { + let project = new Project(fullExample()); + + assert.deepEqual(addonsInfoFor(project), [ + { + parent: 'direwolf (your app)', + topLevel: null, + version: '7.26.5', + requirement: '^7.26.3', + compatible: true, + dormant: false, + path: [], + }, + { + parent: 'active-model-adapter@2.2.0', + topLevel: 'active-model-adapter', + version: '6.18.0', + requirement: '^6.18.0', + compatible: false, + dormant: false, + path: ['active-model-adapter@2.2.0'], + }, + { + parent: 'ember-angle-bracket-invocation-polyfill@2.0.0', + topLevel: 'ember-animated', + version: '6.18.0', + requirement: '^6.16.0', + compatible: false, + dormant: true, + path: ['ember-animated@0.11.0', 'ember-angle-bracket-invocation-polyfill@2.0.0'], + }, + { + parent: 'ember-animated@0.11.0', + topLevel: 'ember-animated', + version: '7.26.5', + requirement: '^7.26.3', + compatible: true, + dormant: false, + path: ['ember-animated@0.11.0'], + }, + { + parent: 'ember-fetch@8.0.5', + topLevel: 'ember-fetch', + version: '7.26.0', + requirement: '^7.26.0', + compatible: true, + dormant: true, + path: ['ember-fetch@8.0.5'], + }, + ]); + }); + }); + + QUnit.module('.printList', function () { + QUnit.test('it can print a flat list', function (assert) { + assert.equal( + Overrides.printList(['first', 'second', 'third'], ' '), + `\ + * first + * second + * third +` + ); + }); + + QUnit.test('it can print a nested list', function (assert) { + assert.equal( + Overrides.printList( + [ + 'first', + [ + 'second', + ['second.1', ['second.2', ['second.2.1', 'second.2.2', 'second.2.3']], 'second.3'], + ], + 'third', + ], + ' ' + ), + `\ + * first + * second + * second.1 + * second.2 + * second.2.1 + * second.2.2 + * second.2.3 + * second.3 + * third +` + ); + }); + }); + + QUnit.test('it does nothing when in production', function (assert) { + let project = new Project(fullExample()); + let overrides = Overrides.for(project, { EMBER_ENV: 'production' }); + + assert.strictEqual(overrides.hasOverrides, false, 'hasOverrides'); + assert.strictEqual(overrides.hasBuildTimeWarning, false, 'hasBuildTimeWarning'); + }); + + QUnit.test('it does nothing when everything is on new babel', function (assert) { + let overrides = new Overrides([]); + + assert.strictEqual(overrides.hasOverrides, false, 'hasOverrides'); + assert.strictEqual(overrides.hasBuildTimeWarning, false, 'hasBuildTimeWarning'); + }); + + QUnit.test('when app is on old babel', function (assert) { + let overrides = new Overrides([infoForApp({ version: '6.0.0' })]); + + assert.strictEqual(overrides.hasOverrides, true, 'hasOverrides'); + assert.strictEqual(overrides.hasBuildTimeWarning, true, 'hasBuildTimeWarning'); + assert.strictEqual(overrides.hasActionableSuggestions, true, 'hasActionableSuggestions'); + assert.strictEqual(overrides.hasCompatibleAddons, false, 'hasCompatibleAddons'); + assert.strictEqual(overrides.hasDormantAddons, false, 'hasDormantAddons'); + assert.strictEqual( + overrides.showAllEmberGlobalDeprecations, + false, + 'showAllEmberGlobalDeprecations' + ); + assert.strictEqual( + overrides.showAllDotAccessDeprecations, + false, + 'showAllDotAccessDeprecations' + ); + assert.deepEqual(overrides.suggestions, [ + 'Upgrade your `devDependencies` on `ember-cli-babel` to `^7.26.6`.', + ]); + assert.equal( + overrides.outdated.length, + 1 /* number of different old babel versions */, + 'outdated.length' + ); + assert.ok( + overrides.buildTimeWarning.startsWith( + '[DEPRECATION] Usage of the Ember Global is deprecated.' + ), + 'overrides.buildTimeWarning' + ); + assert.ok( + overrides.globalMessage.startsWith('Usage of the Ember Global is deprecated.'), + 'overrides.globalMessage' + ); + + let { onEmberGlobalAccess, onComputedDotAccess, onRunloopDotAccess } = evalJS(overrides); + + assert.equal( + onEmberGlobalAccess(), + overrides.globalMessage, + 'onEmberGlobalAccess() (first call)' + ); + + assert.strictEqual(onEmberGlobalAccess(), null, 'onEmberGlobalAccess() (second call)'); + + assert.ok( + onComputedDotAccess('computed.reads', 'reads', '@ember/object/computed').startsWith( + 'Using `computed.reads` has been deprecated. ' + + 'Instead, import the value directly from @ember/object/computed:\n\n' + + " import { reads } from '@ember/object/computed';\n\n" + ), + 'onComputedDotAccess() (first call)' + ); + + assert.strictEqual( + onComputedDotAccess('computed.reads', 'reads', '@ember/object/computed'), + null, + 'onComputedDotAccess() (second call)' + ); + + assert.ok( + onRunloopDotAccess('run.next', 'next', '@ember/runloop').startsWith( + 'Using `run.next` has been deprecated. ' + + 'Instead, import the value directly from @ember/runloop:\n\n' + + " import { next } from '@ember/runloop';\n\n" + ), + 'onRunloopDotAccess() (first call)' + ); + + assert.strictEqual( + onRunloopDotAccess('run.next', 'next', '@ember/runloop'), + null, + 'onRunloopDotAccess() (second call)' + ); + }); + + // let project, env; + + // function buildBabel(parent, version) { + // return { + // name: 'ember-cli-babel', + // parent, + // pkg: { + // version, + // }, + // addons: [], + // }; + // } + + // hooks.beforeEach(function () { + // project = { + // name() { + // return 'fake-project'; + // }, + // pkg: { + // dependencies: {}, + // devDependencies: {}, + // }, + // addons: [], + // }; + // env = Object.create(null); + // }); + + // hooks.afterEach(function () {}); + + // QUnit.test('when in production, does nothing', function (assert) { + // env.EMBER_ENV = 'production'; + + // let result = globalDeprecationInfo(project, env); + + // assert.deepEqual(result, { + // globalMessage: '', + // hasActionableSuggestions: false, + // shouldIssueSingleDeprecation: false, + // bootstrap: `require('@ember/-internals/bootstrap').default()`, + // }); + // }); + + // QUnit.test('without addons, does nothing', function (assert) { + // project.addons = []; + // let result = globalDeprecationInfo(project, env); + + // assert.deepEqual(result, { + // globalMessage: '', + // hasActionableSuggestions: false, + // shouldIssueSingleDeprecation: false, + // bootstrap: `require('@ember/-internals/bootstrap').default()`, + // }); + // }); + + // QUnit.test('projects own ember-cli-babel is too old', function (assert) { + // project.pkg.devDependencies = { + // 'ember-cli-babel': '^7.26.0', + // }; + + // project.addons.push({ + // name: 'ember-cli-babel', + // parent: project, + // pkg: { + // version: '7.26.5', + // }, + // addons: [], + // }); + + // let result = globalDeprecationInfo(project, env); + // assert.strictEqual(result.shouldIssueSingleDeprecation, true); + // assert.strictEqual(result.hasActionableSuggestions, true); + // assert.ok( + // result.globalMessage.includes( + // '* Upgrade your `devDependencies` on `ember-cli-babel` to `^7.26.6`' + // ) + // ); + // }); + + // QUnit.test('projects has ember-cli-babel in dependencies', function (assert) { + // project.pkg.dependencies = { + // 'ember-cli-babel': '^7.25.0', + // }; + + // project.addons.push({ + // name: 'ember-cli-babel', + // parent: project, + // pkg: { + // version: '7.26.5', + // }, + // addons: [], + // }); + + // let result = globalDeprecationInfo(project, env); + // assert.strictEqual(result.shouldIssueSingleDeprecation, true); + // assert.strictEqual(result.hasActionableSuggestions, true); + // assert.ok( + // result.globalMessage.includes( + // '* Upgrade your `devDependencies` on `ember-cli-babel` to `^7.26.6`' + // ) + // ); + // }); + // QUnit.test( + // 'projects has no devDependencies, but old ember-cli-babel found in addons array', + // function (assert) { + // project.pkg.devDependencies = {}; + + // project.addons.push({ + // name: 'ember-cli-babel', + // parent: project, + // pkg: { + // version: '7.26.5', + // }, + // addons: [], + // }); + + // let result = globalDeprecationInfo(project, env); + // assert.strictEqual(result.shouldIssueSingleDeprecation, true); + // assert.strictEqual(result.hasActionableSuggestions, true); + // assert.ok( + // result.globalMessage.includes( + // '* Upgrade your `devDependencies` on `ember-cli-babel` to `^7.26.6`' + // ) + // ); + // } + // ); + + // QUnit.test('projects uses linked ember-cli-babel', function (assert) { + // project.pkg.devDependencies = { + // 'ember-cli-babel': 'link:./some/path/here', + // }; + + // let otherAddon = { + // name: 'other-thing-here', + // parent: project, + // pkg: {}, + // addons: [], + // }; + + // otherAddon.addons.push(buildBabel(otherAddon, '7.26.5')); + // project.addons.push(buildBabel(project, '7.26.6'), otherAddon); + + // let result = globalDeprecationInfo(project, env); + // assert.strictEqual(result.shouldIssueSingleDeprecation, true); + // assert.strictEqual(result.hasActionableSuggestions, true); + + // assert.ok( + // result.globalMessage.includes( + // '* If using yarn, run `npx yarn-deduplicate --packages ember-cli-babel`' + // ) + // ); + // assert.ok(result.globalMessage.includes('* If using npm, run `npm dedupe`')); + // }); + + // QUnit.test('projects own ember-cli-babel is up to date', function (assert) { + // project.pkg.devDependencies = { + // 'ember-cli-babel': '^7.26.0', + // }; + + // project.addons.push({ + // name: 'ember-cli-babel', + // parent: project, + // pkg: { + // version: '7.26.6', + // }, + // addons: [], + // }); + + // let result = globalDeprecationInfo(project, env); + // assert.strictEqual(result.shouldIssueSingleDeprecation, false); + // assert.strictEqual(result.hasActionableSuggestions, false); + // assert.notOk( + // result.globalMessage.includes( + // '* Upgrade your `devDependencies` on `ember-cli-babel` to `^7.26.6`' + // ) + // ); + // }); + + // QUnit.test('transient babel that is out of date', function (assert) { + // project.pkg.devDependencies = { + // 'ember-cli-babel': '^7.26.0', + // }; + + // let otherAddon = { + // name: 'other-thing-here', + // parent: project, + // pkg: { + // dependencies: { + // 'ember-cli-babel': '^7.25.0', + // }, + // }, + // addons: [], + // }; + + // otherAddon.addons.push(buildBabel(otherAddon, '7.26.5')); + // project.addons.push(buildBabel(project, '7.26.6'), otherAddon); + + // let result = globalDeprecationInfo(project, env); + // assert.strictEqual(result.shouldIssueSingleDeprecation, true); + // assert.strictEqual(result.hasActionableSuggestions, true); + // assert.ok(result.globalMessage.includes('* other-thing-here@7.26.5 (Compatible)')); + // }); +}); diff --git a/yarn.lock b/yarn.lock index 7eb6a9d5555..64e49a632a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1588,52 +1588,52 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@glimmer/compiler@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/compiler/-/compiler-0.78.2.tgz#b02d4f1027770446637ffcce41bb5dfc71076c82" - integrity sha512-tI0vkwz4qxsTsOOrbJpXZiOQvDwl5dOyPbeq5Z0Fca1byaAPhxPgq+lvuSny0bDYz+T+NGS0B+9MB4yLMnCl7Q== - dependencies: - "@glimmer/interfaces" "0.78.2" - "@glimmer/syntax" "0.78.2" - "@glimmer/util" "0.78.2" - "@glimmer/wire-format" "0.78.2" +"@glimmer/compiler@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/compiler/-/compiler-0.80.3.tgz#a347192ede2e25e01f72079bfc4310a20bab1e87" + integrity sha512-eMsp5iOHZAWKJNmWFwfGxJ3Cs0gySELDRTqW/fm0RC0MLXoViaPYSQJ/yb2/VozkHeDijoQkPWPCY6TW8zRCjg== + dependencies: + "@glimmer/interfaces" "0.80.3" + "@glimmer/syntax" "0.80.3" + "@glimmer/util" "0.80.3" + "@glimmer/wire-format" "0.80.3" "@simple-dom/interface" "^1.4.0" -"@glimmer/destroyable@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/destroyable/-/destroyable-0.78.2.tgz#13a3eab3397f25b1a52e7dc3f9f81cf7ceec621c" - integrity sha512-cZ+fXp4PPf9CkDV8GY8A8sd5IJ367uEDk99n0DNBLcypeZU0REb8rCIV/GzJoCUcCnT9FzDXuFGgelp23x2tFw== +"@glimmer/destroyable@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/destroyable/-/destroyable-0.80.3.tgz#bdbce5253429c4ee46116582e2bfde2fd9fd1638" + integrity sha512-fi0lO1QzWdkq/Izgef9l57dvFX+HS0ecd1N6Y6aWV/YKz8wjSgq/PNVBJMeFF+eV+HGIOzWnwu1oaIFfk9qKUw== dependencies: "@glimmer/env" "0.1.7" - "@glimmer/global-context" "0.78.2" - "@glimmer/interfaces" "0.78.2" - "@glimmer/util" "0.78.2" + "@glimmer/global-context" "0.80.3" + "@glimmer/interfaces" "0.80.3" + "@glimmer/util" "0.80.3" -"@glimmer/encoder@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/encoder/-/encoder-0.78.2.tgz#39a4f8223cd7819417909d4a7c86c9e31bb1eef5" - integrity sha512-3V+DYqLf5sY8ehV4qaeACqpy8i1pjP0zGlsxiaFb3LdfIbfuzrNxE1JQGvN/60urqhKqGeeIk+e/Y2879voVbw== +"@glimmer/encoder@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/encoder/-/encoder-0.80.3.tgz#854be4d7673568ade867078676f2b8c8f6e3a89d" + integrity sha512-lhF4z9M5tWURapA4uoGUGHwCinpzWrKEhdX3L0V1WmXsWxZviWin8f9WcvmK4O990uFBfe/GVSF0anYDU+fFAw== dependencies: "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.78.2" - "@glimmer/vm" "0.78.2" + "@glimmer/interfaces" "0.80.3" + "@glimmer/vm" "0.80.3" "@glimmer/env@0.1.7", "@glimmer/env@^0.1.7": version "0.1.7" resolved "https://registry.yarnpkg.com/@glimmer/env/-/env-0.1.7.tgz#fd2d2b55a9029c6b37a6c935e8c8871ae70dfa07" integrity sha1-/S0rVakCnGs3psk16MiHGucN+gc= -"@glimmer/global-context@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.78.2.tgz#3443b000e8617da39202d5319db881ff59a2f248" - integrity sha512-om0ryTEqER1ZZKD9TLBJlPm/M3z9EwHMR22luufPKZ1la8RrDQpGPMh32a8QzWnOyigiv2NXIfuUiSh5OGR/BA== +"@glimmer/global-context@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.80.3.tgz#bfac6f048a8c3884e7d2c56509d57b4f63101d9a" + integrity sha512-GQLx1CznQeAELq4lg1VKo4zZ12wXX5wNdyFc0p+BdUP07vYUR47p/FJNst1RfUg1gU2/NxuUjdBh26QIHb+QTw== dependencies: "@glimmer/env" "^0.1.7" -"@glimmer/interfaces@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.78.2.tgz#4dafd7f7abaf03f5a9b5d2192205ad007550ca36" - integrity sha512-OM1zJHNioKwd+7PM+mt28Ine9QfZLI7bwDOgB1Y+lHEZ0OdAGu6m351RBrXfQEgDCoVSFPQpOtUpWLP/FU3Utw== +"@glimmer/interfaces@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.80.3.tgz#c7c866376d73b9c4e4282e9056c6798e84ce7331" + integrity sha512-38PVcR7uFdFdJnqDNhLMbaluZhJezdwRAJCTkwk/AxlC2bGa6iCv2GDQhErXp1qr26gyO7dt37gbtwLojBDauA== dependencies: "@simple-dom/interface" "^1.4.0" @@ -1642,140 +1642,140 @@ resolved "https://registry.yarnpkg.com/@glimmer/low-level/-/low-level-0.78.2.tgz#bca5f666760ce98345e87c5b3e37096e772cb2de" integrity sha512-0S6TWOOd0fzLLysw1pWZN0TgasaHmYs1Sjz9Til1mTByIXU1S+1rhdyr2veSQPO/aRjPuEQyKXZQHvx23Zax6w== -"@glimmer/manager@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/manager/-/manager-0.78.2.tgz#5c1d0fc24225f9546b182cab6d8ea800135bf86b" - integrity sha512-mHTtPJXf7uYVOsHSrLQEcv0nxGj9M2Rmks60hWKxk/pdNwt12FzRElMqyyj1j9lSbUj+LOpt9g+IZYu03w4O8g== +"@glimmer/manager@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/manager/-/manager-0.80.3.tgz#6d509ad6760e5aa484608201b146dce0d8cc4197" + integrity sha512-K2TEqp5VU61D/ytHzf1DmcsCV/MTLJZw8yuxp1/azDYEYJTKThM8U09yIcbsfTaEXDPkWNJ8A11LzcvYjow2iQ== dependencies: - "@glimmer/destroyable" "0.78.2" + "@glimmer/destroyable" "0.80.3" "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.78.2" - "@glimmer/reference" "0.78.2" - "@glimmer/util" "0.78.2" - "@glimmer/validator" "0.78.2" - -"@glimmer/node@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/node/-/node-0.78.2.tgz#a27bd6d5ef188ea4892bc6953a62fc165a173893" - integrity sha512-e5mc63xbvix6qRwGLWrc5zYi0PSN5bUUlx6SWCxItObht7i7TpkylYo3y4bDZc2LqfkTN8e8dIyPqfF2dZsLsQ== - dependencies: - "@glimmer/interfaces" "0.78.2" - "@glimmer/runtime" "0.78.2" - "@glimmer/util" "0.78.2" + "@glimmer/interfaces" "0.80.3" + "@glimmer/reference" "0.80.3" + "@glimmer/util" "0.80.3" + "@glimmer/validator" "0.80.3" + +"@glimmer/node@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/node/-/node-0.80.3.tgz#c1fde8e3095e99764589f6d6730a14b05d2cfce8" + integrity sha512-WzYsJ3V8aDrQRlu6So8p/Fe0N3TdEUJJ/tbFIwpKDviVEhLxuJOnW/Qv6CjHaE1mzaVK8/HOxCtM96myg80GxQ== + dependencies: + "@glimmer/interfaces" "0.80.3" + "@glimmer/runtime" "0.80.3" + "@glimmer/util" "0.80.3" "@simple-dom/document" "^1.4.0" "@simple-dom/interface" "^1.4.0" -"@glimmer/opcode-compiler@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/opcode-compiler/-/opcode-compiler-0.78.2.tgz#c5199fa02a7e36dbe62e4387bf37d54b1f2c33c7" - integrity sha512-WEmeMZMt3nD8jcUlAYLuW6xVB0uOBkyGAUHU7SHcldnfdP3GTilyPO3OzRC9ksEHK/bwtFelrbwu5tpPH1RgvQ== +"@glimmer/opcode-compiler@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/opcode-compiler/-/opcode-compiler-0.80.3.tgz#3c92ed8f3ed278743f57813089efe52339cb438b" + integrity sha512-qxKemQkjEeaznBQJHjhYy6LYSxi3XtBuMXLau/iouKI+tIq6MWIrmcET9Pg6ODS7O46JP/xMbDpGgf9IrKQvPQ== dependencies: - "@glimmer/encoder" "0.78.2" + "@glimmer/encoder" "0.80.3" "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.78.2" - "@glimmer/reference" "0.78.2" - "@glimmer/util" "0.78.2" - "@glimmer/vm" "0.78.2" - "@glimmer/wire-format" "0.78.2" + "@glimmer/interfaces" "0.80.3" + "@glimmer/reference" "0.80.3" + "@glimmer/util" "0.80.3" + "@glimmer/vm" "0.80.3" + "@glimmer/wire-format" "0.80.3" -"@glimmer/owner@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/owner/-/owner-0.78.2.tgz#15e0adf8e2fef7045674e67627fa48d4b8df877e" - integrity sha512-02I4O5kgmQasE5vbmRY/3F6ZshPURAWtZgvCR5+YHgGo+Jt1UBMaLLDtbg8ldPDc5muUmonA3ZXIYmm1F4wTSw== +"@glimmer/owner@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/owner/-/owner-0.80.3.tgz#24574d75ada5ecd4b1caa96310cf956420d936df" + integrity sha512-kf8NunzhzFzZ+/ySHNu66w6DS9OW1EY7UmKypMESE4Suy3FShGnWmm8aoqxpjoOwczzOaODScRX9ZIPIpV3xNg== dependencies: - "@glimmer/util" "0.78.2" + "@glimmer/util" "0.80.3" -"@glimmer/program@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/program/-/program-0.78.2.tgz#c38f2f55005b3c2e8f1a4825aacc2ffd6891d9a1" - integrity sha512-6ZeCSwqnC0mMzfHwbToTX/LC6HeUm2UMAaMri7WIh9ncNetCfKqBXRdFIKepG7fnWEADuCwE/+r6e2Qq2x3dNQ== +"@glimmer/program@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/program/-/program-0.80.3.tgz#42408a451681edf503104827d268079bd00abcc1" + integrity sha512-Y058DF2pb7ulUf2ytU8cK/b1VSyRIbBRQyorgRXaR4dpLO7RXm6AHSrn2miiy2EtoOodBk7JX50Ei3kr0+eVZw== dependencies: - "@glimmer/encoder" "0.78.2" + "@glimmer/encoder" "0.80.3" "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.78.2" - "@glimmer/manager" "0.78.2" - "@glimmer/opcode-compiler" "0.78.2" - "@glimmer/util" "0.78.2" + "@glimmer/interfaces" "0.80.3" + "@glimmer/manager" "0.80.3" + "@glimmer/opcode-compiler" "0.80.3" + "@glimmer/util" "0.80.3" -"@glimmer/reference@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.78.2.tgz#dbffbeb4bc42f64f57104eebab0eb4ef7778d989" - integrity sha512-vUk20mKknDqtQEWfGbDwU9eh+XVztUUuww6V6/UKm8JokBDjGkdt4w74R2wvPIrDZYkfXErZjXwY8Ltu1lBV0A== +"@glimmer/reference@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.80.3.tgz#e60aaf3eb73b9ca3803942b49e29d104a06c948b" + integrity sha512-ghvMnkHBRc5xwAxL/r5ZVbBH1bGxLk2LmgQwpgeSzv5EhZvRQCRW8W19IDmMCv9pAEmgsxgdjAQcP0gudMvyrQ== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/global-context" "0.78.2" - "@glimmer/interfaces" "0.78.2" - "@glimmer/util" "0.78.2" - "@glimmer/validator" "0.78.2" + "@glimmer/global-context" "0.80.3" + "@glimmer/interfaces" "0.80.3" + "@glimmer/util" "0.80.3" + "@glimmer/validator" "0.80.3" -"@glimmer/runtime@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/runtime/-/runtime-0.78.2.tgz#e8d8de5b1c74f2aeaa129b43d264ff36de4de5a1" - integrity sha512-pzndIFJl2ycVAAnaFNm2MLwDTKymn03a+xAtHpsFwEZQ3EE2wQNnEKyBDI5SkNRShD8nkbwodd0N+YwZdGDKHw== +"@glimmer/runtime@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/runtime/-/runtime-0.80.3.tgz#faec66e717b57035332bab22f8d377c6aaeda4d9" + integrity sha512-my+myLcOeYjdcrUbjjOfguPAtgOzSDBMjLql58aiColsEntvv1NsKAYLRaxf+MwSYK/PzxAUM+tN+pRdm43vSA== dependencies: - "@glimmer/destroyable" "0.78.2" + "@glimmer/destroyable" "0.80.3" "@glimmer/env" "0.1.7" - "@glimmer/global-context" "0.78.2" - "@glimmer/interfaces" "0.78.2" + "@glimmer/global-context" "0.80.3" + "@glimmer/interfaces" "0.80.3" "@glimmer/low-level" "0.78.2" - "@glimmer/owner" "0.78.2" - "@glimmer/program" "0.78.2" - "@glimmer/reference" "0.78.2" - "@glimmer/util" "0.78.2" - "@glimmer/validator" "0.78.2" - "@glimmer/vm" "0.78.2" - "@glimmer/wire-format" "0.78.2" + "@glimmer/owner" "0.80.3" + "@glimmer/program" "0.80.3" + "@glimmer/reference" "0.80.3" + "@glimmer/util" "0.80.3" + "@glimmer/validator" "0.80.3" + "@glimmer/vm" "0.80.3" + "@glimmer/wire-format" "0.80.3" "@simple-dom/interface" "^1.4.0" -"@glimmer/syntax@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.78.2.tgz#3be25df8c7b7564d94d204ac0ab0c9717abe9043" - integrity sha512-B6OgBtUFo+K0sA+72sNQOs//TKJIZdAPUAIQGjZWsfGZGpzlFx3kuouKeK1DCtXxRIktqSDpmXFcPNKd1OqbOw== +"@glimmer/syntax@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.80.3.tgz#9018469f03c9ad5ee9e14446280f5f6312bdf130" + integrity sha512-hACbTpXgNO2l7USDVDUPvXh4Xo9e06sQEyv1QvGn/MK8FKfMkThxOmLrWy/pcEdeePmCMNGMLGgfjG6bO5FCUQ== dependencies: - "@glimmer/interfaces" "0.78.2" - "@glimmer/util" "0.78.2" + "@glimmer/interfaces" "0.80.3" + "@glimmer/util" "0.80.3" "@handlebars/parser" "~2.0.0" simple-html-tokenizer "^0.5.10" -"@glimmer/util@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.78.2.tgz#d6e7e363d198ef426858a3958170774b4548cce1" - integrity sha512-SqmlzdtXJwAhf5fhflFsoYuM3zk1M/8bamqGXQpCB5I40NpcshpFybY/ZMwIGsYOWEwIo/LDDC1UBZ3gyMPZzA== +"@glimmer/util@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.80.3.tgz#573e562e20c7c1a869d84095a987d641ea9885d1" + integrity sha512-H6u9gPpBrZWfdHAXQyVTsttSJzBfpQ2NWc2Jnh35b7HxPpg0npcLsjIAuba4gHlcsKLwlN42s3O+J8x9weL4gQ== dependencies: "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.78.2" + "@glimmer/interfaces" "0.80.3" "@simple-dom/interface" "^1.4.0" -"@glimmer/validator@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.78.2.tgz#bc7f3cf376789d1090add73bed599e840697fdc8" - integrity sha512-pzdC9uPaQerOoPEeSV9U/oRbZtgTkL+BryGR8R534mhAFfVlzenAa4aavKZEcnIns73MNN/G1l2iYDmjSH/6Hg== +"@glimmer/validator@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.80.3.tgz#32814cb9d4c504e2ffc828cd6def0e6e27dd9e67" + integrity sha512-73Kk6v4q8zz4brbsM6stMrQKyyRU9uBYqpyfhQNAIjsJAtVchazt/v/h6JcXTDAJZ+YvhIoFrM//8GJWAqPh3w== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/global-context" "0.78.2" + "@glimmer/global-context" "0.80.3" -"@glimmer/vm-babel-plugins@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/vm-babel-plugins/-/vm-babel-plugins-0.78.2.tgz#b530a19f54da385c7099a22cf348e9062d186838" - integrity sha512-GSEf16h6OCtKx7PsSvD21cLXZuVc6swW2rSOAvfLeZco1DEWMRgYTwkCkColydKZcQ3gvwbPBeYwTC2K6tlnjg== +"@glimmer/vm-babel-plugins@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/vm-babel-plugins/-/vm-babel-plugins-0.80.3.tgz#434b62172318cac43830d3ac29818cf2c5f111c1" + integrity sha512-9ej6xlm5MzHBJ5am2l0dbbn8Z0wJoYoMpM8FcrGMlUP6SPMLWxvxpMsApgQo8u6dvZRCjR3/bw3fdf7GOy0AFw== dependencies: babel-plugin-debug-macros "^0.3.4" -"@glimmer/vm@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/vm/-/vm-0.78.2.tgz#525589b4d3556eafea84a2b9c6e7aa72698bf5d6" - integrity sha512-x+0qn1B00i8Gcw3ptqEaGsIECG4M1IdmxtLSIr+Kfga/Da/PPLXJYQx+jk924rVCnad2FzxizhyKRxCqPbU+EA== +"@glimmer/vm@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/vm/-/vm-0.80.3.tgz#3073cfa40b4cf16468a62862fd608b20f4880dc6" + integrity sha512-W3auYwgJPGgAINsF/8aU8Vsdw1w/k0LjIq6KAmuMlj09ol1jVQKjFNp990Te9L18OPHp2BcFvFd4x3kHZa0Z0Q== dependencies: - "@glimmer/interfaces" "0.78.2" - "@glimmer/util" "0.78.2" + "@glimmer/interfaces" "0.80.3" + "@glimmer/util" "0.80.3" -"@glimmer/wire-format@0.78.2": - version "0.78.2" - resolved "https://registry.yarnpkg.com/@glimmer/wire-format/-/wire-format-0.78.2.tgz#32686633e66fe674ea39910d48e3db9ba524eadb" - integrity sha512-kd8xP9P7oo+F0EijG3/2YwzUXq/AESxPS2hadjmhu2uMZ+QOzgYbeo1xC2Ig7EkXhf1tdxlmVpCS4rwhCsxzXA== +"@glimmer/wire-format@0.80.3": + version "0.80.3" + resolved "https://registry.yarnpkg.com/@glimmer/wire-format/-/wire-format-0.80.3.tgz#e8acb095244e982c328cceba8438b19eb5226358" + integrity sha512-mcF3iyIukja3RlMbFFMFY80dZ9FtCooMdX/R1py1TfzPc9dYPmLadayC0mrRNPmf/PV9NQVihFHFHNuWitNSrw== dependencies: - "@glimmer/interfaces" "0.78.2" - "@glimmer/util" "0.78.2" + "@glimmer/interfaces" "0.80.3" + "@glimmer/util" "0.80.3" "@handlebars/parser@~2.0.0": version "2.0.0"