diff --git a/CHANGELOG.md b/CHANGELOG.md index 00fcb41871b..13997c8d744 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Ember Changelog +### v3.28.0-beta.6 (June 21, 2021) + +- [#19584](https://github.com/emberjs/ember.js/pull/19584) [BUGFIX] Ensure hash objects correctly entangle as dependencies + +### v3.28.0-beta.5 (June 14, 2021) + +- [#19597](https://github.com/emberjs/ember.js/pull/19597) [BUGFIX] Fix `` with nested children + +### v3.28.0-beta.4 (June 7, 2021) + +- [#19586](https://github.com/emberjs/ember.js/pull/19586) [BUGFIX] Fix Embroider compatibility + +### v3.28.0-beta.3 (June 1, 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] Delay until: 5.0.0 the removal of the deprecated transition methods of controller and route from [RFC #674](https://github.com/emberjs/rfcs/blob/master/text/0674-deprecate-transition-methods-of-controller-and-route.md). + ### v3.28.0-beta.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 @@ -15,6 +32,21 @@ - [#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 diff --git a/ember-cli-build.js b/ember-cli-build.js index 77b3aa5c9e3..d7587989b7c 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -120,6 +120,9 @@ module.exports = function ({ project }) { '@ember/-internals/*/tests/**' /* internal packages */, '*/*/tests/**' /* scoped packages */, '*/tests/**' /* packages */, + '@ember/-internals/*/type-tests/**' /* internal packages */, + '*/*/type-tests/**' /* scoped packages */, + '*/type-tests/**' /* packages */, 'ember-template-compiler/**', 'internal-test-helpers/**', ], diff --git a/lib/index.js b/lib/index.js index 95b509eba80..406ac88e808 100644 --- a/lib/index.js +++ b/lib/index.js @@ -10,7 +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 semver = require('semver'); +const Overrides = require('./overrides'); const PRE_BUILT_TARGETS = [ 'last 1 Chrome versions', @@ -41,17 +41,6 @@ add( path.join(__dirname, '..', 'dist', 'ember-template-compiler.js') ); -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]; -} - module.exports = { init() { this._super.init && this._super.init.apply(this, arguments); @@ -76,13 +65,21 @@ module.exports = { name: 'ember-source', paths, absolutePaths, - _bootstrapEmber: "require('@ember/-internals/bootstrap').default();", _jqueryIntegrationEnabled: true, + _overrideTree: undefined, included() { this._super.included.apply(this, arguments); - this._issueGlobalsDeprecation(); + 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'); @@ -145,7 +142,7 @@ module.exports = { } } else { this.ui.writeWarnLine( - 'The Ember Classic edition has been deprecated. Speciying "classic" in your package.json, or not specifying a value at all, will no longer be supported. You must explicitly set the "ember.edition" property to "octane". This warning will become an error in Ember 4.0.0.\n\nFor more information, see the deprecation guide: https://deprecations.emberjs.com/v3.x/#toc_editions-classic' + 'The Ember Classic edition has been deprecated. Specifying "classic" in your package.json, or not specifying a value at all, will no longer be supported. You must explicitly set the "ember.edition" property to "octane". This warning will become an error in Ember 4.0.0.\n\nFor more information, see the deprecation guide: https://deprecations.emberjs.com/v3.x/#toc_editions-classic' ); if ( @@ -223,6 +220,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( @@ -258,7 +259,7 @@ module.exports = { return new MergeTrees([ concatBundle(emberFiles, { outputFile: 'ember.js', - footer: this._bootstrapEmber, + footer: `require('@ember/-internals/bootstrap')`, }), concatBundle(emberTestingFiles, { @@ -297,10 +298,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', @@ -317,289 +321,4 @@ module.exports = { return debugTree(new MergeTrees([ember, templateCompiler, jquery]), 'vendor:final'); }, - - _issueGlobalsDeprecation() { - if (process.env.EMBER_ENV === 'production') { - return; - } - - let isYarnProject = ((root) => { - try { - // eslint-disable-next-line node/no-unpublished-require - return require('ember-cli/lib/utilities/is-yarn-project')(root); - } catch { - return undefined; - } - })(this.project.root); - - let groupedByTopLevelAddon = Object.create(null); - let groupedByVersion = Object.create(null); - let projectInfo; - - for (let [addon, pathToAddon] of walkAddonTree(this.project)) { - let version = addon.pkg.version; - - if (addon.name === 'ember-cli-babel' && semver.lt(version, '7.26.6')) { - let info; - - if (addon.parent === this.project) { - let requirement = requirementFor('ember-cli-babel', this.project.pkg.devDependencies); - let compatible = semver.satisfies('7.26.6', requirement); - - info = projectInfo = { - parent: `${this.project.name()} (your app)`, - version, - requirement, - compatible, - dormant: false, - path: pathToAddon, - }; - } else { - let requirement = requirementFor('ember-cli-babel', addon.parent.pkg.dependencies); - let compatible = semver.satisfies('7.26.6', requirement); - let dormant = addon.parent._fileSystemInfo - ? addon.parent._fileSystemInfo().hasJSFiles === false - : false; - - let topLevelAddon = addon.parent; - - while (topLevelAddon.parent !== this.project) { - topLevelAddon = topLevelAddon.parent; - } - - info = { - parent: `${addon.parent.name}@${addon.pkg.version}`, - version, - requirement, - compatible, - dormant, - path: pathToAddon, - }; - - let addons = groupedByTopLevelAddon[topLevelAddon.name] || []; - groupedByTopLevelAddon[topLevelAddon.name] = [...addons, info]; - } - - let group = groupedByVersion[version] || Object.create(null); - groupedByVersion[version] = group; - - let addons = group[info.parent] || []; - group[info.parent] = [...addons, info]; - } - } - - if (Object.keys(groupedByVersion).length === 0) { - return; - } - - let dormantTopLevelAddons = []; - let compatibleTopLevelAddons = []; - let incompatibleTopLevelAddons = []; - - for (let addon of Object.keys(groupedByTopLevelAddon)) { - let group = groupedByTopLevelAddon[addon]; - - if (group.every((info) => info.dormant)) { - dormantTopLevelAddons.push(addon); - } else if (group.every((info) => info.compatible)) { - compatibleTopLevelAddons.push(addon); - } else { - incompatibleTopLevelAddons.push(addon); - } - } - - let suggestions = 'The following steps may help:\n\n'; - - let hasActionableSuggestions = false; - - if (projectInfo) { - suggestions += '* Upgrade your `devDependencies` on `ember-cli-babel` to `^7.26.6`.\n'; - 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. - if (isYarnProject === true) { - suggestions += - '* Run `npx yarn-deduplicate --packages ember-cli-babel` followed by `yarn install`.\n'; - } else if (isYarnProject === false) { - suggestions += '* Run `npm dedupe`.\n'; - } else { - suggestions += - '* If using yarn, run `npx yarn-deduplicate --packages ember-cli-babel` followed by `yarn install`.\n' + - '* If using npm, run `npm dedupe`.\n'; - } - - hasActionableSuggestions = true; - } - - if (incompatibleTopLevelAddons.length > 0) { - suggestions += '* Upgrade the following addons to the latest version:\n'; - - for (let addon of incompatibleTopLevelAddons) { - suggestions += ` * ${addon}\n`; - } - - hasActionableSuggestions = true; - } - - if (!hasActionableSuggestions) { - // Only show the dormant addons if there are nothing else to do because they are unlikely to - // be the problem. - suggestions += '* Upgrade the following addons to the latest version, if available:\n'; - - for (let addon of dormantTopLevelAddons) { - suggestions += ` * ${addon}\n`; - } - } - - 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'; - - let hasDormantAddons = false; - let hasCompatibleAddons = false; - - for (let version of Object.keys(groupedByVersion).sort(semver.compare)) { - details += `\n* ember-cli-babel@${version}, currently used by:\n`; - - for (let parent of Object.keys(groupedByVersion[version]).sort()) { - let info = groupedByVersion[version][parent][0]; - - details += ` * ${parent}`; - - if (info.dormant) { - details += ' (Dormant)\n'; - hasDormantAddons = true; - } else if (info.compatible) { - details += ' (Compatible)\n'; - hasCompatibleAddons = true; - } else { - details += '\n'; - } - - details += ` * Depends on ember-cli-babel@${groupedByVersion[version][parent][0].requirement}\n`; - - for (let info of groupedByVersion[version][parent]) { - let adddedBy = info.path.slice(0, -1); - - if (adddedBy.length) { - details += ` * Added by ${adddedBy.join(' > ')}\n`; - } - - if (info.compatible) { - hasCompatibleAddons = true; - } - } - } - } - - if (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 cuplrit of this deprecation and can likely be ignored.\n'; - } - - if (hasCompatibleAddons) { - details += `\nNote: Addons marked as "Compatible" are already compatible with ember-cli-babel@7.26.6. `; - - if (projectInfo) { - details += 'Try upgrading your `devDependencies` on `ember-cli-babel` to `^7.26.6`.\n'; - } else { - if (isYarnProject === true) { - details += - 'Try running `npx yarn-deduplicate --packages ember-cli-babel` followed by `yarn install`.\n'; - } else if (isYarnProject === false) { - details += 'Try running `npm dedupe`.\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'; - } - } - } - - let globalMessage = - '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. ' + - suggestions; - - if (hasActionableSuggestions && process.env.EMBER_GLOBAL_DEPRECATIONS !== 'all') { - globalMessage += - '\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'; - } - - globalMessage += details; - - if (hasActionableSuggestions) { - this.ui.writeWarnLine('[DEPRECATION] ' + globalMessage); - } - - let onDotAccess = `function (dotKey, importKey, module) { - var 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. ' + - ${JSON.stringify(suggestions)}; - - if (${ - hasActionableSuggestions && - process.env.EMBER_RUNLOOP_AND_COMPUTED_DOT_ACCESS_DEPRECATIONS !== 'all' - }) { - 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(details)}; - - return message; - }`; - - this._bootstrapEmber = ` - require('@ember/-internals/bootstrap').default( - ${JSON.stringify(globalMessage)}, - ${hasActionableSuggestions && process.env.EMBER_GLOBAL_DEPRECATIONS !== 'all'} - ); - - (function(disabled, once, _onDotAccess) { - var onDotAccess = function () { - if (disabled) { - return null; - } else { - disabled = once; - return _onDotAccess.apply(undefined, arguments); - } - }; - - require('@ember/object')._onDotAccess(onDotAccess); - - require('@ember/runloop')._onDotAccess(onDotAccess); - })( - false, - ${ - hasActionableSuggestions && - process.env.EMBER_RUNLOOP_AND_COMPUTED_DOT_ACCESS_DEPRECATIONS !== 'all' - }, - ${onDotAccess} - ); - `; - }, }; 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/package.json b/package.json index 68d9f640578..d3a51855060 100644 --- a/package.json +++ b/package.json @@ -50,11 +50,12 @@ "@babel/helper-module-imports": "^7.8.3", "@babel/plugin-transform-block-scoping": "^7.8.3", "@ember/edition-utils": "^1.2.0", - "@glimmer/vm-babel-plugins": "0.79.2", + "@glimmer/vm-babel-plugins": "0.79.4", "babel-plugin-debug-macros": "^0.3.3", "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", @@ -74,19 +75,19 @@ }, "devDependencies": { "@babel/preset-env": "^7.9.5", - "@glimmer/compiler": "0.79.2", - "@glimmer/destroyable": "0.79.2", + "@glimmer/compiler": "0.79.4", + "@glimmer/destroyable": "0.79.4", "@glimmer/env": "^0.1.7", - "@glimmer/global-context": "0.79.2", - "@glimmer/interfaces": "0.79.2", - "@glimmer/manager": "0.79.2", - "@glimmer/node": "0.79.2", - "@glimmer/opcode-compiler": "0.79.2", - "@glimmer/owner": "0.79.2", - "@glimmer/program": "0.79.2", - "@glimmer/reference": "0.79.2", - "@glimmer/runtime": "0.79.2", - "@glimmer/validator": "0.79.2", + "@glimmer/global-context": "0.79.4", + "@glimmer/interfaces": "0.79.4", + "@glimmer/manager": "0.79.4", + "@glimmer/node": "0.79.4", + "@glimmer/opcode-compiler": "0.79.4", + "@glimmer/owner": "0.80.0", + "@glimmer/program": "0.79.4", + "@glimmer/reference": "0.79.4", + "@glimmer/runtime": "0.79.4", + "@glimmer/validator": "0.79.4", "@simple-dom/document": "^1.4.0", "@types/qunit": "^2.11.1", "@types/rsvp": "^4.0.3", @@ -97,7 +98,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", @@ -123,14 +123,14 @@ "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "^3.3.1", "eslint-plugin-qunit": "^4.0.0", - "execa": "^2.0.4", + "execa": "^5.1.1", "expect-type": "^0.11.0", "express": "^4.17.1", "finalhandler": "^1.1.2", "fs-extra": "^9.1.0", "git-repo-info": "^2.1.1", "github": "^0.2.3", - "glob": "^7.1.4", + "glob": "^7.1.7", "html-differ": "^1.4.0", "lodash.uniq": "^4.5.0", "mkdirp": "^1.0.4", diff --git a/packages/@ember/-internals/bootstrap/index.js b/packages/@ember/-internals/bootstrap/index.js deleted file mode 100644 index 05e70d3a721..00000000000 --- a/packages/@ember/-internals/bootstrap/index.js +++ /dev/null @@ -1,50 +0,0 @@ -import require from 'require'; -import { context } from '@ember/-internals/environment'; -import { deprecate } from '@ember/debug'; - -const DEFAULT_MESSAGE = - 'Usage of the Ember Global is deprecated. You should import the Ember module or the specific API instead.'; - -export default function bootstrap(message = DEFAULT_MESSAGE, once = false) { - let Ember; - let disabled = false; - - function defineEmber(key) { - Object.defineProperty(context.exports, key, { - enumerable: true, - configurable: true, - get() { - if (!Ember) { - Ember = require('ember').default; - } - - deprecate(message, disabled, { - 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', - }, - }); - - if (once) { - disabled = true; - } - - 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/glimmer/lib/components/link-to.ts b/packages/@ember/-internals/glimmer/lib/components/link-to.ts index 40ee661d959..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'; diff --git a/packages/@ember/-internals/glimmer/lib/helper.ts b/packages/@ember/-internals/glimmer/lib/helper.ts index b1888d6dac1..d14b9eb9cf1 100644 --- a/packages/@ember/-internals/glimmer/lib/helper.ts +++ b/packages/@ember/-internals/glimmer/lib/helper.ts @@ -78,6 +78,7 @@ export interface SimpleHelper { Additionally, class helpers can call `recompute` to force a new computation. @class Helper + @extends CoreObject @public @since 1.13.0 */ 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/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 3cd67140fd5..9b3cd24b1a1 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/helpers/hash-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/helpers/hash-test.js @@ -219,6 +219,60 @@ moduleFor( 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'); + + 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({ diff --git a/packages/@ember/-internals/metal/lib/chain-tags.ts b/packages/@ember/-internals/metal/lib/chain-tags.ts index 816f9420620..f918196155c 100644 --- a/packages/@ember/-internals/metal/lib/chain-tags.ts +++ b/packages/@ember/-internals/metal/lib/chain-tags.ts @@ -1,6 +1,7 @@ import { Meta, meta as metaFor, peekMeta } from '@ember/-internals/meta'; import { isObject } from '@ember/-internals/utils'; import { assert, deprecate } from '@ember/debug'; +import { isHashProxy } from '@glimmer/runtime'; import { _WeakSet } from '@glimmer/util'; import { combine, @@ -16,7 +17,7 @@ import { tagForProperty } from './tags'; export const CHAIN_PASS_THROUGH = new _WeakSet(); -export function finishLazyChains(meta: Meta, key: string, value: any) { +export function finishLazyChains(meta: Meta, key: string, value: unknown): void { let lazyTags = meta.readableLazyChainsFor(key); if (lazyTags === undefined) { @@ -173,20 +174,6 @@ function getChainTags( chainTags.push(propertyTag); - // If we're at the end of the path, processing the last segment, and it's - // not an alias, we should _not_ get the last value, since we already have - // its tag. There's no reason to access it and do more work. - if (segmentEnd === pathLength) { - // If the key was an alias, we should always get the next value in order to - // bootstrap the alias. This is because aliases, unlike other CPs, should - // always be in sync with the aliased value. - if (CHAIN_PASS_THROUGH.has(descriptor)) { - // tslint:disable-next-line: no-unused-expression - current[segment]; - } - break; - } - if (descriptor === undefined) { // If the descriptor is undefined, then its a normal property, so we should // lookup the value to chain off of like normal. @@ -223,8 +210,16 @@ function getChainTags( } } - if (!isObject(current)) { + if (segmentEnd === pathLength || !isObject(current)) { // we've hit the end of the chain for now, break out + + // If the last value is a HashProxy, then entangle all of its tags + if (isHashProxy(current)) { + for (let key in current) { + chainTags.push(tagForProperty(current, key)); + } + } + break; } 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/utils.ts b/packages/@ember/-internals/routing/lib/utils.ts index 3828653351a..2e35a299543 100644 --- a/packages/@ember/-internals/routing/lib/utils.ts +++ b/packages/@ember/-internals/routing/lib/utils.ts @@ -253,7 +253,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/component/template-only.ts b/packages/@ember/component/template-only.ts index 4fda1e66fe8..509390074fb 100644 --- a/packages/@ember/component/template-only.ts +++ b/packages/@ember/component/template-only.ts @@ -23,8 +23,10 @@ ``` @public + @static @method templateOnly @param {String} moduleName the module name that the template only component represents, this will be used for debugging purposes + @for @ember/component/template-only @category EMBER_GLIMMER_SET_COMPONENT_TEMPLATE */ export { templateOnlyComponent as default } from '@glimmer/runtime'; diff --git a/packages/@ember/helper/index.ts b/packages/@ember/helper/index.ts index 8f224c2c32e..f3d84cc6e21 100644 --- a/packages/@ember/helper/index.ts +++ b/packages/@ember/helper/index.ts @@ -264,8 +264,8 @@ } } - export default class PlusOne extends Component { - plusOne = invokeHelper(this, RemoteData, () => { + export default class PlusOneComponent extends Component { + plusOne = invokeHelper(this, PlusOne, () => { return { positional: [this.args.number], }; diff --git a/packages/@ember/object/index.js b/packages/@ember/object/index.js index 6b07d4d3190..cf1f7dccc1c 100644 --- a/packages/@ember/object/index.js +++ b/packages/@ember/object/index.js @@ -1,6 +1,7 @@ import { DEBUG } from '@glimmer/env'; import { assert, deprecate } from '@ember/debug'; import { isElementDescriptor, setClassicDecorator } from '@ember/-internals/metal'; +import { onComputedDotAccess } from '@ember/-internals/overrides'; export { Object as default } from '@ember/-internals/runtime'; @@ -54,22 +55,18 @@ import { uniq, } from '@ember/object/computed'; -export let _onDotAccess; - // eslint-disable-next-line no-undef if (DEBUG) { - let _callback = (dotKey, importKey, module) => { + let defaultHandler = (dotKey, importKey, module) => { return `Using \`${dotKey}\` has been deprecated. Instead, import the value directly from ${module}:\n\n import { ${importKey} } from '${module}';`; }; - _onDotAccess = (callback) => { - _callback = callback; - }; + let handler = onComputedDotAccess || defaultHandler; let defineDeprecatedComputedFunc = (key, func) => { Object.defineProperty(computed, key, { get() { - let message = _callback(`computed.${key}`, key, '@ember/object/computed'); + let message = handler(`computed.${key}`, key, '@ember/object/computed'); deprecate(message, message === null, { id: 'deprecated-run-loop-and-computed-dot-access', diff --git a/packages/@ember/runloop/index.js b/packages/@ember/runloop/index.js index 6ce847c96db..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; @@ -743,22 +744,18 @@ export function throttle() { export let _deprecatedGlobalGetCurrentRunLoop; -export let _onDotAccess; - // eslint-disable-next-line no-undef if (DEBUG) { - let _callback = (dotKey, importKey, module) => { + let defaultHandler = (dotKey, importKey, module) => { return `Using \`${dotKey}\` has been deprecated. Instead, import the value directly from ${module}:\n\n import { ${importKey} } from '${module}';`; }; - _onDotAccess = (callback) => { - _callback = callback; - }; + let handler = onRunloopDotAccess || defaultHandler; let defineDeprecatedRunloopFunc = (key, func) => { Object.defineProperty(run, key, { get() { - let message = _callback(`run.${key}`, key, '@ember/runloop'); + let message = handler(`run.${key}`, key, '@ember/runloop'); deprecate(message, message === null, { id: 'deprecated-run-loop-and-computed-dot-access', @@ -775,7 +772,7 @@ if (DEBUG) { }; _deprecatedGlobalGetCurrentRunLoop = () => { - let message = _callback('run.currentRunLoop', 'getCurrentRunLoop', '@ember/runloop'); + let message = handler('run.currentRunLoop', 'getCurrentRunLoop', '@ember/runloop'); deprecate(message, message === null, { id: 'deprecated-run-loop-and-computed-dot-access', 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 67db5c5e819..0097dbd8538 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1579,52 +1579,59 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@glimmer/compiler@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/compiler/-/compiler-0.79.2.tgz#b874e59de7ad3317c6c28dd781dbc8c08a5942b4" - integrity sha512-FbN9/lJyRHOmy4bBPqU/TdiPhN/dSIEJA6Y0dyAu03zuHJqBMd5rtHLm1CRdII9dDwU6T6B09aDlsBBAt8FQcA== - dependencies: - "@glimmer/interfaces" "0.79.2" - "@glimmer/syntax" "0.79.2" - "@glimmer/util" "0.79.2" - "@glimmer/wire-format" "0.79.2" +"@glimmer/compiler@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/compiler/-/compiler-0.79.4.tgz#746909c5f01ad57efec15da79567b515d1e3a6b0" + integrity sha512-aXTows4Kjbutp6BV18oQTFaJjIkX5+hQ25KVETK/5zla/rC9O0DQHGb2r8DDfx4DiJLXGdl4g2VLy/BfkYmcwA== + dependencies: + "@glimmer/interfaces" "0.79.4" + "@glimmer/syntax" "0.79.4" + "@glimmer/util" "0.79.4" + "@glimmer/wire-format" "0.79.4" "@simple-dom/interface" "^1.4.0" -"@glimmer/destroyable@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/destroyable/-/destroyable-0.79.2.tgz#50b473483d2d45fb3fa12a28719495af683dd695" - integrity sha512-owBXBWHQuLN5lzbG+3yzupnTGQj6ttPAx0KTCiUBfH0BpE7tKx+w52MA87bt5GJRX+RS0g57Z1DLQy2yLavfFQ== +"@glimmer/destroyable@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/destroyable/-/destroyable-0.79.4.tgz#23a3a13a50063aefb2fa169feae79a373c9132bf" + integrity sha512-qpaglWv+GKlcm28MZvYemWTZV3kSlOKPc7kluRqXvoo7oqQdBEagm60XivMpxJUEf+A5YXsJ/Atty+r58eVvQg== dependencies: "@glimmer/env" "0.1.7" - "@glimmer/global-context" "0.79.2" - "@glimmer/interfaces" "0.79.2" - "@glimmer/util" "0.79.2" + "@glimmer/global-context" "0.79.4" + "@glimmer/interfaces" "0.79.4" + "@glimmer/util" "0.79.4" -"@glimmer/encoder@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/encoder/-/encoder-0.79.2.tgz#e3e3ebc85ba210cffdb4c66dd4bdd2e07d864dad" - integrity sha512-MqFWJ4rGcikk27iUOkHc2vtnC+cVO2XBQHk6m+T5LEkLHFEC0JEDSj+POxHoHnkjXi8BxbxUxxOptz85p0LGWg== +"@glimmer/encoder@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/encoder/-/encoder-0.79.4.tgz#2e2e7da3f80f21732f7ed0003c391caf4b42acfe" + integrity sha512-qqyW/TWVK1RP/zEVq0NU2EvOViftVyB43BB7y2yVyb+qD3gK0weP1InwPp1tyNUF7B6LHAcd64d4pN29Qj3vHw== dependencies: "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.79.2" - "@glimmer/vm" "0.79.2" + "@glimmer/interfaces" "0.79.4" + "@glimmer/vm" "0.79.4" "@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.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.79.2.tgz#970276f1c7c44d34b4bd619709de78b1f46fabaf" - integrity sha512-Cwna7I28+6amQd+n4/6sc8PccI3cyk/fIWoxzOKBTA0AqJp/HetiE2IvLQI97VCx/Rv338IINzIu4JlfymWnXA== +"@glimmer/global-context@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.79.4.tgz#2d683a457aba7c340a3e850fdcf8a35fbcd8308e" + integrity sha512-Hn6KS7QUV63oMbop1LVOfPZ3KISzq4xMASjP+xrMzLIugvjBYYB+WoarUJcG7eB+TioOo0OMyVFibSP8ZTO2TQ== dependencies: "@glimmer/env" "^0.1.7" -"@glimmer/interfaces@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.79.2.tgz#387d11f69ced699e2a227ab9095bd9970829cbf5" - integrity sha512-2+CulmZ5XV3Mq2xG4qYPCcA8LVZq76OixdyLHvkGLEvwFx1J2gixcKK0+KNc0dr+Iia6Ebmu9sntulFCRguMgw== +"@glimmer/interfaces@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.79.4.tgz#3213e7fe73f35340762bef7f4e8c8df593a4a8c8" + integrity sha512-cyNZlRa7aXAfXY9kk7hhnWgL1R7Zw8wwi2UVEWq2nBanmpNmL1lSMJ6nY8oRIWCtWrYA9CeH7RZ6mVP5cQ/v2w== + dependencies: + "@simple-dom/interface" "^1.4.0" + +"@glimmer/interfaces@0.80.0": + version "0.80.0" + resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.80.0.tgz#eabc7551ffe7ad27c44ba96d39e2af6ebf01c942" + integrity sha512-evD9aVhYacFe/lD/FzaPs0CuuIgkr17+KbOCWDeEMXW0q2FnrLiQET40eP5nyhGLELhKE62mlIzdGmleUR6XYg== dependencies: "@simple-dom/interface" "^1.4.0" @@ -1633,140 +1640,156 @@ resolved "https://registry.yarnpkg.com/@glimmer/low-level/-/low-level-0.78.2.tgz#bca5f666760ce98345e87c5b3e37096e772cb2de" integrity sha512-0S6TWOOd0fzLLysw1pWZN0TgasaHmYs1Sjz9Til1mTByIXU1S+1rhdyr2veSQPO/aRjPuEQyKXZQHvx23Zax6w== -"@glimmer/manager@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/manager/-/manager-0.79.2.tgz#6b5a5d393483522636bc4c4b34604246950b7b08" - integrity sha512-1lzO8Ud7cJWmBaM7lru8dJvtgivzE5mEhkd7LwfLc/UPNNCOHY/fkfypPr0/C2nQLksVLnMB28pDsQThqoGmZQ== +"@glimmer/manager@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/manager/-/manager-0.79.4.tgz#82cefd85d503c5a3c40389f3c869a8abbf273648" + integrity sha512-SCSrBEdu/JvTEFPvgkDu3kaRgJrJHrhAdB2WAoevNb8bMMhADxRPTVSfYDFL/6+eQtx6krcycVeeaCLjhZ2LNA== dependencies: - "@glimmer/destroyable" "0.79.2" + "@glimmer/destroyable" "0.79.4" "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.79.2" - "@glimmer/reference" "0.79.2" - "@glimmer/util" "0.79.2" - "@glimmer/validator" "0.79.2" - -"@glimmer/node@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/node/-/node-0.79.2.tgz#7ead836a2ff17273ddd37351c9f6470f17a60f1e" - integrity sha512-2NcWC1PzF/Ru8Xr3h8cuGUumauZMLbyTo24wzJDFCruoMIpizbxcBWGVHuFnH1Cdg8e+fu6eICsCaItVvoJNIw== - dependencies: - "@glimmer/interfaces" "0.79.2" - "@glimmer/runtime" "0.79.2" - "@glimmer/util" "0.79.2" + "@glimmer/interfaces" "0.79.4" + "@glimmer/reference" "0.79.4" + "@glimmer/util" "0.79.4" + "@glimmer/validator" "0.79.4" + +"@glimmer/node@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/node/-/node-0.79.4.tgz#734ed99979fe8c396af3c356c0a5d5eee835d552" + integrity sha512-EDv/PkLGf92aFc7J8qKtBUd6ewxC5udntN6Syj0VHJ2MQeikVJWyZHwJbZP5+VUw8AbjuSKPc0Nt8G37Y2xtug== + dependencies: + "@glimmer/interfaces" "0.79.4" + "@glimmer/runtime" "0.79.4" + "@glimmer/util" "0.79.4" "@simple-dom/document" "^1.4.0" "@simple-dom/interface" "^1.4.0" -"@glimmer/opcode-compiler@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/opcode-compiler/-/opcode-compiler-0.79.2.tgz#997fc9cb559512afc7eb059d80e27ca58009a715" - integrity sha512-sXqzgYfK06ZSHzvVq0ChTx8C/2+A33E3se53wfODXZ88XAGyalTX9U2tHbfKIk3tgOUuMncNfT02NFRDZ/KnmA== +"@glimmer/opcode-compiler@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/opcode-compiler/-/opcode-compiler-0.79.4.tgz#c5dffda71216909a8b17d9ff3223a82ef018dde9" + integrity sha512-K/29Wvy5nzo3deLGVZhoziznLsd8+psKhA8SO2zpS7a1a7HCSAL8SvXUZFsdsUZSU0gBmCPmw+sXSkyZTpu5CA== dependencies: - "@glimmer/encoder" "0.79.2" + "@glimmer/encoder" "0.79.4" "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.79.2" - "@glimmer/reference" "0.79.2" - "@glimmer/util" "0.79.2" - "@glimmer/vm" "0.79.2" - "@glimmer/wire-format" "0.79.2" + "@glimmer/interfaces" "0.79.4" + "@glimmer/reference" "0.79.4" + "@glimmer/util" "0.79.4" + "@glimmer/vm" "0.79.4" + "@glimmer/wire-format" "0.79.4" -"@glimmer/owner@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/owner/-/owner-0.79.2.tgz#562805781e235388a17f15c69ae72e834d680325" - integrity sha512-W5ZejPXyKWeCJF+6+Rv3+mkCJ56eLv+gtesggaVosbXwgL6QnUySjOdvTOwZ++HUYm6WCLognnO+XNzV25oHcQ== +"@glimmer/owner@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/owner/-/owner-0.79.4.tgz#ebb300eaf23986c94705cbff8c4415ed1eaad9e9" + integrity sha512-6w24OglbMeib1xJVxOnTBoiCQbeLtDLDSzisn9z3o6+Iv3NCMzylyjv25JU9TqJydEPftDG/An/h/Aswb8iEFw== dependencies: - "@glimmer/util" "0.79.2" + "@glimmer/util" "0.79.4" -"@glimmer/program@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/program/-/program-0.79.2.tgz#755c50144ddc9b8aacf47082347552ec86207217" - integrity sha512-w2xI7Wz7CHx1HS49c6yZToa7XX29vhO+ydWJabMWqoaktvOTBFKZPfwVLIS7mjIe3rwQVose+VIUmbQ1IzwCQg== +"@glimmer/owner@0.80.0": + version "0.80.0" + resolved "https://registry.yarnpkg.com/@glimmer/owner/-/owner-0.80.0.tgz#ae5da1e4bf8121592afc920a88f3f6dda603606a" + integrity sha512-6VkPqa1fn8Y+9K0nevtMukdVlSaGzrrpYn+QReaXGFjN97YFDQWqQUrmEjcAXeOF/zcyKTpDNrQH0ev0s4JicQ== dependencies: - "@glimmer/encoder" "0.79.2" + "@glimmer/util" "0.80.0" + +"@glimmer/program@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/program/-/program-0.79.4.tgz#80cfda3261388caeeb66ccc46fac469d2e788b71" + integrity sha512-8wvhs7xUTdbAtG+oV19PKSFsyFujnRjl4gPs76Pr7GLHX25XOBhGxL8TptPm0JShxuvB2TMZrBwMGc3rhe402g== + dependencies: + "@glimmer/encoder" "0.79.4" "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.79.2" - "@glimmer/manager" "0.79.2" - "@glimmer/opcode-compiler" "0.79.2" - "@glimmer/util" "0.79.2" + "@glimmer/interfaces" "0.79.4" + "@glimmer/manager" "0.79.4" + "@glimmer/opcode-compiler" "0.79.4" + "@glimmer/util" "0.79.4" -"@glimmer/reference@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.79.2.tgz#070c16268dc22341aa6ffd30b6dee88cd9cf63d4" - integrity sha512-OobgRrcegj88E8peRHnb1KilCemEK2hF89diUkpnQAO7rOTQknnbyzxO3UgVgm/arEcW4+Ga6T+sirumJ5bKIA== +"@glimmer/reference@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.79.4.tgz#3d9fcf5e57c63583da14f243128a3195f650e568" + integrity sha512-neCaUe9vqc/zGj1kNdm1ssHQ/9icC0BJd8xjYf6vAjiJ/TKEL+u+PfL8H8zqdWAK2al5zekNlhHFY55NxzX8bQ== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/global-context" "0.79.2" - "@glimmer/interfaces" "0.79.2" - "@glimmer/util" "0.79.2" - "@glimmer/validator" "0.79.2" + "@glimmer/global-context" "0.79.4" + "@glimmer/interfaces" "0.79.4" + "@glimmer/util" "0.79.4" + "@glimmer/validator" "0.79.4" -"@glimmer/runtime@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/runtime/-/runtime-0.79.2.tgz#93d0285db9d19313a0d477548e4d4af880701bcc" - integrity sha512-FFjDVR1JQaczO+wIRudhCwAeRKUjXB+ZqhOskSEboGbVjSq4v9nxooYVf+np5SEpwPNvlqX6lEW6H7/nfusv0Q== +"@glimmer/runtime@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/runtime/-/runtime-0.79.4.tgz#188044848721f710859c35eecec15293b8c98bba" + integrity sha512-jacyHy7zQ39kR6c4BvPUXpnNDSybnFpFplnhsa0Fr8IqnXRTKqNv1KdfBwdbbPQNaojuV6vyWoh0jPErkcgh0w== dependencies: - "@glimmer/destroyable" "0.79.2" + "@glimmer/destroyable" "0.79.4" "@glimmer/env" "0.1.7" - "@glimmer/global-context" "0.79.2" - "@glimmer/interfaces" "0.79.2" + "@glimmer/global-context" "0.79.4" + "@glimmer/interfaces" "0.79.4" "@glimmer/low-level" "0.78.2" - "@glimmer/owner" "0.79.2" - "@glimmer/program" "0.79.2" - "@glimmer/reference" "0.79.2" - "@glimmer/util" "0.79.2" - "@glimmer/validator" "0.79.2" - "@glimmer/vm" "0.79.2" - "@glimmer/wire-format" "0.79.2" + "@glimmer/owner" "0.79.4" + "@glimmer/program" "0.79.4" + "@glimmer/reference" "0.79.4" + "@glimmer/util" "0.79.4" + "@glimmer/validator" "0.79.4" + "@glimmer/vm" "0.79.4" + "@glimmer/wire-format" "0.79.4" "@simple-dom/interface" "^1.4.0" -"@glimmer/syntax@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.79.2.tgz#fcd6e742860ca39230043969fb04644d5cc6a5c9" - integrity sha512-65ZXxIM38EMKESWgvTU31ouZiQAELRO/LmOfzTJZlYH5LhSAZWSQ7tatYXDrcjPoiDojLO0a16WccZggM1etmg== +"@glimmer/syntax@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.79.4.tgz#5aa21d4b3918238c24da3d640abc3b66150fc0c6" + integrity sha512-NiMIoW2G0+sBfLYnvDaZ8o8Ul/3P/ezOT8U7ZvsHDGU5hXM2buFozyoSKLILTvAQ56izdfK9fKCsn0oi4ISx3w== dependencies: - "@glimmer/interfaces" "0.79.2" - "@glimmer/util" "0.79.2" + "@glimmer/interfaces" "0.79.4" + "@glimmer/util" "0.79.4" "@handlebars/parser" "~2.0.0" simple-html-tokenizer "^0.5.10" -"@glimmer/util@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.79.2.tgz#7c8e1684f1ad48430b7ed64a2319051b5975ccf9" - integrity sha512-jELDUEoNx0CCHboHFdinQu8W5ye5a7kW6fyR4Pb0zN4PPHKybOjieE6jf5l60R0pBGyqU8W8/S+CeiNgM/AU8g== +"@glimmer/util@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.79.4.tgz#4762ed9b231482470cb9763332097d50042f9bde" + integrity sha512-n2lEGzM9khM43HmKlig2lG5L5cHoL4tFzW21CZzmhMfc1IDCqHuP7s7924OsXSbLT1WB7B9sm/ZhnEj2nd+GiQ== + dependencies: + "@glimmer/env" "0.1.7" + "@glimmer/interfaces" "0.79.4" + "@simple-dom/interface" "^1.4.0" + +"@glimmer/util@0.80.0": + version "0.80.0" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.80.0.tgz#286ec9e2c8c9e2f364e49272a3baf9d0fe3dc40c" + integrity sha512-fvr4zyGVp58vzVajwTwbGwp0LmPxm2SVWkfIGFcCr9r2BmYD+9bd52I0u00LsZvNJQqFNyI8RB+qXThRMi+TiA== dependencies: "@glimmer/env" "0.1.7" - "@glimmer/interfaces" "0.79.2" + "@glimmer/interfaces" "0.80.0" "@simple-dom/interface" "^1.4.0" -"@glimmer/validator@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.79.2.tgz#b132673925ce79842b4c4ef1ecbf170aa3c0daa7" - integrity sha512-BtSp/izgnhZHPC2onEKa4H+v6ovaq6snwLQcWHPtoenVpn5Y7KbwSy6qSuW5+NaW+XaO3ryvJbZYlDB3dDGuTw== +"@glimmer/validator@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.79.4.tgz#35bc9c6b88d0681b372f1fba3969e6385465b8d7" + integrity sha512-VLT9TozD3n3qwX9hOECn/d2Ig8PTn0Gl1FdiEpb04tldXWY0YL6oSoLEjH97R4KNqvati2jFQOOzyinzu9Ffkw== dependencies: "@glimmer/env" "^0.1.7" - "@glimmer/global-context" "0.79.2" + "@glimmer/global-context" "0.79.4" -"@glimmer/vm-babel-plugins@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/vm-babel-plugins/-/vm-babel-plugins-0.79.2.tgz#8fa4af60c5089977690ee501c7b358c90b8d6bc5" - integrity sha512-c5XQQwM8iogT1mdE/U2+UuGsiFmhP4d53lgXOAq1DQ2/AMFlAXa5djMVETDUlncvLLlo6S3Iaj/FvpqTxwqn2g== +"@glimmer/vm-babel-plugins@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/vm-babel-plugins/-/vm-babel-plugins-0.79.4.tgz#317b9b85752abab903674b959ed9e00e1942ae23" + integrity sha512-LEdgx6QXOAm+88TxgrvWvkUc6J6jPKmnMzW3IAiD7aIHasSl+/aKfZF0x3ICHyCXGaJGWI00mVKxd2n61aAY9g== dependencies: babel-plugin-debug-macros "^0.3.4" -"@glimmer/vm@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/vm/-/vm-0.79.2.tgz#cbebf74fae0cd413486f7a4ca31715eb8ab9a39d" - integrity sha512-4Bbg7eDLymuV7wiM0GVbIYnQMZxo/Dn+PF1+w5mWUjHqH+ajNKNARJVt3+w+M1tg5Q/nblBVHshNzYwFaugagA== +"@glimmer/vm@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/vm/-/vm-0.79.4.tgz#1d0f00909c6b97b99d7c8bb11d1e7b958822dbd3" + integrity sha512-enCXJlypgMTxWUupQWCPUvE41Gh4vsCIWVhqdh6ol+QGzRZBGvfXTz5xu5lTKPJQhFQsTn2ecVTKKVhqMOtzpA== dependencies: - "@glimmer/interfaces" "0.79.2" - "@glimmer/util" "0.79.2" + "@glimmer/interfaces" "0.79.4" + "@glimmer/util" "0.79.4" -"@glimmer/wire-format@0.79.2": - version "0.79.2" - resolved "https://registry.yarnpkg.com/@glimmer/wire-format/-/wire-format-0.79.2.tgz#adb88d25752e00f0f9d3f609c1ab458ca2cac932" - integrity sha512-jYiEbRtHGs2auQWOmEEDbT3p9zTqAVUzKkpWzoc9u6fEC8/QfcT3FuLW7S3YjLzauPiIlOQyDVeC5IvhyZag9w== +"@glimmer/wire-format@0.79.4": + version "0.79.4" + resolved "https://registry.yarnpkg.com/@glimmer/wire-format/-/wire-format-0.79.4.tgz#4074b1194650909e295c349e75d2cebb8a03c8bd" + integrity sha512-QuGfVIX1ziyFDPzJaKZnbgyhzzz5a8s/B+xYg5ZEhMo5BHuyL1a3Gw+0qUMCPlVUIX0Uv+VWvI7NF9tH/ykiZA== dependencies: - "@glimmer/interfaces" "0.79.2" - "@glimmer/util" "0.79.2" + "@glimmer/interfaces" "0.79.4" + "@glimmer/util" "0.79.4" "@handlebars/parser@~2.0.0": version "2.0.0" @@ -3849,7 +3872,7 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cross-spawn@^6.0.0, cross-spawn@^6.0.5: +cross-spawn@^6.0.0: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity "sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q= sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==" @@ -3860,7 +3883,7 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.2: +cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity "sha1-9zqFudXUHQRVUcF34ogtSshXKKY= sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==" @@ -4953,19 +4976,19 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/execa/-/execa-2.0.4.tgz#2f5cc589c81db316628627004ea4e37b93391d8e" - integrity "sha1-L1zFicgdsxZihicATqTje5M5HY4= sha512-VcQfhuGD51vQUQtKIq2fjGDLDbL6N1DTQVpYzxZ7LPIXw3HqTuIz6uxRmpV1qf8i31LHf2kjiaGI+GdHwRgbnQ==" +execa@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: - cross-spawn "^6.0.5" - get-stream "^5.0.0" + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" is-stream "^2.0.0" merge-stream "^2.0.0" - npm-run-path "^3.0.0" - onetime "^5.1.0" - p-finally "^2.0.0" - signal-exit "^3.0.2" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" strip-final-newline "^2.0.0" exists-sync@0.0.3: @@ -5599,13 +5622,18 @@ get-stream@^4.0.0: dependencies: pump "^3.0.0" -get-stream@^5.0.0, get-stream@^5.1.0: +get-stream@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" integrity "sha1-ASA83JJZf5uQkGfD5lbMH008Tck= sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==" dependencies: pump "^3.0.0" +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -5636,9 +5664,9 @@ github@^0.2.3: mime "^1.2.11" glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity "sha1-tsHvQXxOVmPqSY8cRa+saRa7wik= sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==" + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" @@ -5665,10 +5693,10 @@ glob@^5.0.10: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.4, glob@^7.0.5, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== +glob@^7.0.4, glob@^7.0.5, glob@^7.1.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.7: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -6050,6 +6078,11 @@ https-proxy-agent@^4.0.0: agent-base "5" debug "4" +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + iconv-lite@0.4.24, iconv-lite@^0.4.13, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -6225,7 +6258,7 @@ is-binary-path@~2.1.0: is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity "sha1-76ouqdqg16suoTqXsritUf776L4= sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== is-buffer@~2.0.3: version "2.0.3" @@ -6306,7 +6339,7 @@ is-extendable@^1.0.1: is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= is-fullwidth-code-point@^1.0.0: version "1.0.0" @@ -6335,7 +6368,7 @@ is-glob@^3.1.0: is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity "sha1-dWfb6fL14kZ7x3q4PEopSCQHpdw= sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== dependencies: is-extglob "^2.1.1" @@ -6665,7 +6698,7 @@ keyv@3.0.0: kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= dependencies: is-buffer "^1.1.5" @@ -7782,10 +7815,10 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npm-run-path@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-3.1.0.tgz#7f91be317f6a466efed3c9f2980ad8a4ee8b0fa5" - integrity "sha1-f5G+MX9qRm7+08nymArYpO6LD6U= sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==" +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" @@ -7911,10 +7944,10 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -onetime@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" - integrity "sha1-//DzyRYX/mK7UBiWNumayKbfe+U= sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==" +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" @@ -7983,11 +8016,6 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==" -p-finally@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" - integrity "sha1-vW/KqcVZoJa2gIBvTWV7Pw8kBWE= sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" - p-is-promise@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" @@ -9060,9 +9088,9 @@ set-blocking@^2.0.0, set-blocking@~2.0.0: integrity "sha1-BF+XgtARrppoA93TgrJDkrPYkPc= sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" set-getter@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.0.tgz#d769c182c9d5a51f409145f2fba82e5e86e80376" - integrity "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y= sha512-lIj6AWViymAQLQyq1qehP44w4iGbSv6pYOKRQCDzqlmxctLyCrecuge0bxRPrNSnV8EeMHKR2fVTRl3LniQLNg==" + version "0.1.1" + resolved "https://registry.yarnpkg.com/set-getter/-/set-getter-0.1.1.tgz#a3110e1b461d31a9cfc8c5c9ee2e9737ad447102" + integrity sha512-9sVWOy+gthr+0G9DzqqLaYNA7+5OKkSmcqjL9cBpDEaZrr3ShQlyX2cZ/O/ozE41oxn/Tt0LGEM/w4Rub3A3gw== dependencies: to-object-path "^0.3.0" @@ -9125,10 +9153,10 @@ shellwords@^0.1.0: resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" integrity "sha1-1rkYHBpI05cyTISHHvvPxz/AZUs= sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= sha512-meQNNykwecVxdu1RlYMKpQx4+wefIYpmxi6gexo/KAbwquJrBUrBmKYJrE8KFkVQAAVWEnwNdu21PgrD77J3xA==" +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== silent-error@^1.0.0, silent-error@^1.0.1, silent-error@^1.1.0, silent-error@^1.1.1: version "1.1.1" @@ -9888,7 +9916,7 @@ to-fast-properties@^2.0.0: to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= dependencies: kind-of "^3.0.2"