From ac10d6c27f2f0561585ce68b7f617966258f6465 Mon Sep 17 00:00:00 2001 From: Chris Thoburn Date: Fri, 30 Jun 2023 17:18:34 -0700 Subject: [PATCH] DX: Nicer backtracking errors (#8660) * dx: better debugging for backtracking errors * fixes * fix prod test --- packages/model/src/-private/record-state.ts | 10 +- packages/store/src/-private/cache-handler.ts | 2 + .../record-arrays/identifier-array.ts | 14 +- packages/tracking/addon-main.js | 76 ++++- packages/tracking/babel.config.js | 13 + packages/tracking/babel.config.json | 8 - packages/tracking/package.json | 18 +- packages/tracking/rollup.config.mjs | 2 +- packages/tracking/src/-private.ts | 64 +++- pnpm-lock.yaml | 319 ++++++++++++++++-- .../meaningful-backtracking-errors-test.js | 57 ++++ 11 files changed, 531 insertions(+), 52 deletions(-) create mode 100644 packages/tracking/babel.config.js delete mode 100644 packages/tracking/babel.config.json create mode 100644 tests/main/tests/end-user-dx/meaningful-backtracking-errors-test.js diff --git a/packages/model/src/-private/record-state.ts b/packages/model/src/-private/record-state.ts index 0da1ed7234e..59f3e6f2379 100644 --- a/packages/model/src/-private/record-state.ts +++ b/packages/model/src/-private/record-state.ts @@ -37,8 +37,15 @@ class Tag { declare isDirty: boolean; declare value: any; declare t: boolean; + declare _debug_base: string; + declare _debug_prop: string; constructor() { + if (DEBUG) { + const [base, prop] = arguments as unknown as [string, string]; + this._debug_base = base; + this._debug_prop = prop; + } this.rev = 1; this.isDirty = true; this.value = undefined; @@ -67,7 +74,8 @@ function getTag(record, key) { tags = Object.create(null); Tags.set(record, tags); } - return (tags[key] = tags[key] || new Tag()); + // @ts-expect-error + return (tags[key] = tags[key] || (DEBUG ? new Tag(record.constructor.modelName, key) : new Tag())); } export function peekTag(record, key) { diff --git a/packages/store/src/-private/cache-handler.ts b/packages/store/src/-private/cache-handler.ts index 8700f5ffa08..5fa3dc3f549 100644 --- a/packages/store/src/-private/cache-handler.ts +++ b/packages/store/src/-private/cache-handler.ts @@ -79,6 +79,7 @@ function maybeUpdateUiObjects( return document as T; } const data = recordArrayManager.createArray({ + type: request.url, identifiers: document.data, doc: document as CollectionResourceDataDocument, query: request, @@ -95,6 +96,7 @@ function maybeUpdateUiObjects( if (!managed) { managed = recordArrayManager.createArray({ + type: identifier.lid, identifiers: document.data, doc: document as CollectionResourceDataDocument, }); diff --git a/packages/store/src/-private/record-arrays/identifier-array.ts b/packages/store/src/-private/record-arrays/identifier-array.ts index ef616c0a7cb..6de05b440cd 100644 --- a/packages/store/src/-private/record-arrays/identifier-array.ts +++ b/packages/store/src/-private/record-arrays/identifier-array.ts @@ -63,7 +63,7 @@ export const NOTIFY = Symbol('#notify'); const IS_COLLECTION = Symbol.for('Collection'); export function notifyArray(arr: IdentifierArray) { - arr[IDENTIFIER_ARRAY_TAG].ref = null; + addToTransaction(arr[IDENTIFIER_ARRAY_TAG]); if (DEPRECATE_COMPUTED_CHAINS) { // eslint-disable-next-line @@ -90,8 +90,16 @@ class Tag { * whether this was part of a transaction when last mutated */ declare t: boolean; + declare _debug_base: string; + declare _debug_prop: string; constructor() { + if (DEBUG) { + const [arr, prop] = arguments as unknown as [IdentifierArray, string]; + + this._debug_base = arr.constructor.name + ':' + String(arr.modelName); + this._debug_prop = prop; + } this.shouldReset = false; this.t = false; } @@ -183,7 +191,7 @@ class IdentifierArray { _updatingPromise: Promise | null = null; [IS_COLLECTION] = true; - [IDENTIFIER_ARRAY_TAG] = new Tag(); + declare [IDENTIFIER_ARRAY_TAG]: Tag; [SOURCE]: StableRecordIdentifier[]; [NOTIFY]() { notifyArray(this); @@ -235,6 +243,8 @@ class IdentifierArray { this.store = options.store; this._manager = options.manager; this[SOURCE] = options.identifiers; + // @ts-expect-error + this[IDENTIFIER_ARRAY_TAG] = DEBUG ? new Tag(this, 'length') : new Tag(); const store = options.store; const boundFns = new Map(); const _TAG = this[IDENTIFIER_ARRAY_TAG]; diff --git a/packages/tracking/addon-main.js b/packages/tracking/addon-main.js index 459ef9174ca..13f812d930a 100644 --- a/packages/tracking/addon-main.js +++ b/packages/tracking/addon-main.js @@ -1,5 +1,79 @@ +const requireModule = require('@ember-data/private-build-infra/src/utilities/require-module'); +const getEnv = require('@ember-data/private-build-infra/src/utilities/get-env'); +const detectModule = require('@ember-data/private-build-infra/src/utilities/detect-module'); + +const pkg = require('./package.json'); + module.exports = { - name: require('./package.json').name, + name: pkg.name, + + options: { + '@embroider/macros': { + setOwnConfig: {}, + }, + }, + + _emberDataConfig: null, + configureEmberData() { + if (this._emberDataConfig) { + return this._emberDataConfig; + } + const app = this._findHost(); + const isProd = /production/.test(process.env.EMBER_ENV); + const hostOptions = app.options?.emberData || {}; + const debugOptions = Object.assign( + { + LOG_PAYLOADS: false, + LOG_OPERATIONS: false, + LOG_MUTATIONS: false, + LOG_NOTIFICATIONS: false, + LOG_REQUESTS: false, + LOG_REQUEST_STATUS: false, + LOG_IDENTIFIERS: false, + LOG_GRAPH: false, + LOG_INSTANCE_CACHE: false, + }, + hostOptions.debug || {} + ); + + const HAS_DEBUG_PACKAGE = detectModule(require, '@ember-data/debug', __dirname, pkg); + const HAS_META_PACKAGE = detectModule(require, 'ember-data', __dirname, pkg); + + const includeDataAdapterInProduction = + typeof hostOptions.includeDataAdapterInProduction === 'boolean' + ? hostOptions.includeDataAdapterInProduction + : HAS_META_PACKAGE; + + const includeDataAdapter = HAS_DEBUG_PACKAGE ? (isProd ? includeDataAdapterInProduction : true) : false; + const DEPRECATIONS = require('@ember-data/private-build-infra/src/deprecations')(hostOptions.compatWith || null); + const FEATURES = require('@ember-data/private-build-infra/src/features')(isProd); + + const ALL_PACKAGES = requireModule('@ember-data/private-build-infra/virtual-packages/packages.js'); + const MACRO_PACKAGE_FLAGS = Object.assign({}, ALL_PACKAGES.default); + delete MACRO_PACKAGE_FLAGS['HAS_DEBUG_PACKAGE']; + + Object.keys(MACRO_PACKAGE_FLAGS).forEach((key) => { + MACRO_PACKAGE_FLAGS[key] = detectModule(require, MACRO_PACKAGE_FLAGS[key], __dirname, pkg); + }); + + // copy configs forward + const ownConfig = this.options['@embroider/macros'].setOwnConfig; + ownConfig.compatWith = hostOptions.compatWith || null; + ownConfig.debug = debugOptions; + ownConfig.deprecations = Object.assign(DEPRECATIONS, ownConfig.deprecations || {}, hostOptions.deprecations || {}); + ownConfig.features = Object.assign({}, FEATURES, ownConfig.features || {}, hostOptions.features || {}); + ownConfig.includeDataAdapter = includeDataAdapter; + ownConfig.packages = MACRO_PACKAGE_FLAGS; + ownConfig.env = getEnv(ownConfig); + + this._emberDataConfig = ownConfig; + return ownConfig; + }, + + included() { + this.configureEmberData(); + return this._super.included.call(this, ...arguments); + }, treeForVendor() { return; diff --git a/packages/tracking/babel.config.js b/packages/tracking/babel.config.js new file mode 100644 index 00000000000..944b6102d62 --- /dev/null +++ b/packages/tracking/babel.config.js @@ -0,0 +1,13 @@ +const macros = require('@ember-data/private-build-infra/src/v2-babel-build-pack'); + +module.exports = { + plugins: [ + ...macros, + // '@embroider/macros/src/babel/macros-babel-plugin.js', + ['@babel/plugin-transform-runtime', { loose: true }], + ['@babel/plugin-transform-typescript', { allowDeclareFields: true }], + ['@babel/plugin-proposal-decorators', { legacy: true, loose: true }], + ['@babel/plugin-proposal-private-methods', { loose: true }], + ['@babel/plugin-proposal-class-properties', { loose: true }], + ], +}; diff --git a/packages/tracking/babel.config.json b/packages/tracking/babel.config.json deleted file mode 100644 index fea1b66f091..00000000000 --- a/packages/tracking/babel.config.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "plugins": [ - "@babel/plugin-transform-runtime", - ["@babel/plugin-transform-typescript", { "allowDeclareFields": true }], - ["@babel/plugin-proposal-decorators", { "legacy": true }], - "@babel/plugin-proposal-class-properties" - ] -} diff --git a/packages/tracking/package.json b/packages/tracking/package.json index 8d2dd9bcb29..0e8c0496a1c 100644 --- a/packages/tracking/package.json +++ b/packages/tracking/package.json @@ -21,8 +21,15 @@ "volta": { "extends": "../../package.json" }, + "dependenciesMeta": { + "@ember-data/private-build-infra": { + "injected": true + } + }, "dependencies": { - "ember-cli-babel": "^7.26.11" + "ember-cli-babel": "^7.26.11", + "@ember-data/private-build-infra": "workspace:5.3.0-alpha.2", + "@embroider/macros": "^1.10.0" }, "files": [ "addon-main.js", @@ -47,12 +54,13 @@ "@babel/core": "^7.22.5", "@babel/cli": "^7.22.5", "@babel/plugin-proposal-class-properties": "^7.18.6", - "@babel/plugin-proposal-decorators": "^7.22.5", - "@babel/plugin-transform-runtime": "^7.22.5", + "@babel/plugin-proposal-private-methods": "^7.18.6", + "@babel/plugin-proposal-decorators": "^7.22.6", + "@babel/plugin-transform-runtime": "^7.22.6", "@babel/plugin-transform-typescript": "^7.22.5", - "@babel/preset-env": "^7.22.5", + "@babel/preset-env": "^7.22.6", "@babel/preset-typescript": "^7.22.5", - "@babel/runtime": "^7.22.5", + "@babel/runtime": "^7.22.6", "@embroider/addon-dev": "^3.1.1", "@rollup/plugin-babel": "^6.0.3", "@rollup/plugin-node-resolve": "^15.1.0", diff --git a/packages/tracking/rollup.config.mjs b/packages/tracking/rollup.config.mjs index 8a728409277..34fe8a317de 100644 --- a/packages/tracking/rollup.config.mjs +++ b/packages/tracking/rollup.config.mjs @@ -12,7 +12,7 @@ export default { // You can augment this if you need to. output: addon.output(), - external: [], + external: ['@embroider/macros'], plugins: [ // These are the modules that users should be able to import from your diff --git a/packages/tracking/src/-private.ts b/packages/tracking/src/-private.ts index 812b43c3c97..a1bedd43ad1 100644 --- a/packages/tracking/src/-private.ts +++ b/packages/tracking/src/-private.ts @@ -1,3 +1,5 @@ +import { DEBUG } from '@ember-data/env'; + /** * This package provides primitives that allow powerful low-level * adjustments to change tracking notification behaviors. @@ -43,6 +45,62 @@ export function subscribe(obj: Tag): void { } } +function updateRef(obj: Tag): void { + if (DEBUG) { + try { + obj.ref = null; + } catch (e: unknown) { + if (e instanceof Error) { + if (e.message.includes('You attempted to update `ref` on `Tag`')) { + e.message = e.message.replace( + 'You attempted to update `ref` on `Tag`', + // @ts-expect-error + `You attempted to update <${obj._debug_base}>.${obj._debug_prop}` // eslint-disable-line + ); + e.stack = e.stack?.replace( + 'You attempted to update `ref` on `Tag`', + // @ts-expect-error + `You attempted to update <${obj._debug_base}>.${obj._debug_prop}` // eslint-disable-line + ); + + const lines = e.stack?.split(`\n`); + const finalLines: string[] = []; + let lastFile: string | null = null; + + lines?.forEach((line) => { + if (line.trim().startsWith('at ')) { + // get the last string in the line which contains the code source location + const location = line.split(' ').at(-1)!; + // remove the line and char offset info + + if (location.includes(':')) { + const parts = location.split(':'); + parts.pop(); + parts.pop(); + const file = parts.join(':'); + if (file !== lastFile) { + lastFile = file; + finalLines.push(''); + } + } + finalLines.push(line); + } + }); + + const splitstr = '`ref` was first used:'; + const parts = e.message.split(splitstr); + parts.splice(1, 0, `Original Stack\n=============\n${finalLines.join(`\n`)}\n\n${splitstr}`); + + e.message = parts.join(''); + } + } + throw e; + } + } else { + obj.ref = null; + } +} + function flushTransaction() { let transaction = TRANSACTION!; TRANSACTION = transaction.parent; @@ -52,7 +110,7 @@ function flushTransaction() { transaction.props.forEach((obj: Tag) => { // mark this mutation as part of a transaction obj.t = true; - obj.ref = null; + updateRef(obj); }); transaction.sub.forEach((obj: Tag) => { obj.ref; @@ -70,7 +128,7 @@ async function untrack() { transaction.props.forEach((obj: Tag) => { // mark this mutation as part of a transaction obj.t = true; - obj.ref = null; + updateRef(obj); }); } @@ -78,7 +136,7 @@ export function addToTransaction(obj: Tag): void { if (TRANSACTION) { TRANSACTION.props.add(obj); } else { - obj.ref = null; + updateRef(obj); } } export function addTransactionCB(method: OpaqueFn): void { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e121f9844e1..37325e54117 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1045,6 +1045,12 @@ importers: packages/tracking: dependencies: + '@ember-data/private-build-infra': + specifier: workspace:5.3.0-alpha.2 + version: file:packages/private-build-infra + '@embroider/macros': + specifier: ^1.12.2 + version: 1.12.2 ember-cli-babel: specifier: ^7.26.11 version: 7.26.11 @@ -1059,23 +1065,26 @@ importers: specifier: ^7.18.6 version: 7.18.6(@babel/core@7.22.5) '@babel/plugin-proposal-decorators': - specifier: ^7.22.5 - version: 7.22.5(@babel/core@7.22.5) + specifier: ^7.22.6 + version: 7.22.6(@babel/core@7.22.5) + '@babel/plugin-proposal-private-methods': + specifier: ^7.18.6 + version: 7.18.6(@babel/core@7.22.5) '@babel/plugin-transform-runtime': - specifier: ^7.22.5 - version: 7.22.5(@babel/core@7.22.5) + specifier: ^7.22.6 + version: 7.22.6(@babel/core@7.22.5) '@babel/plugin-transform-typescript': specifier: ^7.22.5 version: 7.22.5(@babel/core@7.22.5) '@babel/preset-env': - specifier: ^7.22.5 - version: 7.22.5(@babel/core@7.22.5) + specifier: ^7.22.6 + version: 7.22.6(@babel/core@7.22.5) '@babel/preset-typescript': specifier: ^7.22.5 version: 7.22.5(@babel/core@7.22.5) '@babel/runtime': - specifier: ^7.22.5 - version: 7.22.5 + specifier: ^7.22.6 + version: 7.22.6 '@embroider/addon-dev': specifier: ^3.1.1 version: 3.1.1(rollup@3.26.0) @@ -1097,6 +1106,9 @@ importers: walk-sync: specifier: ^3.0.0 version: 3.0.0 + dependenciesMeta: + '@ember-data/private-build-infra': + injected: true packages/unpublished-eslint-rules: {} @@ -2871,6 +2883,10 @@ packages: resolution: {integrity: sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==} engines: {node: '>=6.9.0'} + /@babel/compat-data@7.22.6: + resolution: {integrity: sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==} + engines: {node: '>=6.9.0'} + /@babel/core@7.22.5: resolution: {integrity: sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==} engines: {node: '>=6.9.0'} @@ -2983,6 +2999,19 @@ packages: lru-cache: 5.1.1 semver: 6.3.0 + /@babel/helper-compilation-targets@7.22.6(@babel/core@7.22.5): + resolution: {integrity: sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.22.6 + '@babel/core': 7.22.5 + '@babel/helper-validator-option': 7.22.5 + '@nicolo-ribaudo/semver-v6': 6.3.3 + browserslist: 4.21.9 + lru-cache: 5.1.1 + /@babel/helper-create-class-features-plugin@7.21.0(@babel/core@7.22.5): resolution: {integrity: sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==} engines: {node: '>=6.9.0'} @@ -3020,6 +3049,25 @@ packages: transitivePeerDependencies: - supports-color + /@babel/helper-create-class-features-plugin@7.22.6(@babel/core@7.22.5): + resolution: {integrity: sha512-iwdzgtSiBxF6ni6mzVnZCF3xt5qE6cEA0J7nFt8QOAWZ0zjCFceEgpn3vtb2V7WFR6QzP2jmIFOHMTRo7eNJjQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-member-expression-to-functions': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@nicolo-ribaudo/semver-v6': 6.3.3 + transitivePeerDependencies: + - supports-color + /@babel/helper-create-regexp-features-plugin@7.22.1(@babel/core@7.22.5): resolution: {integrity: sha512-WWjdnfR3LPIe+0EY8td7WmjhytxXtjKAEpnAxun/hkNiyOaPlvGK+NZaBFIdi9ndYV3Gav7BpFvtUwnaJlwi1w==} engines: {node: '>=6.9.0'} @@ -3048,7 +3096,7 @@ packages: '@babel/core': ^7.4.0-0 dependencies: '@babel/core': 7.22.5 - '@babel/helper-compilation-targets': 7.22.5(@babel/core@7.22.5) + '@babel/helper-compilation-targets': 7.22.6(@babel/core@7.22.5) '@babel/helper-plugin-utils': 7.22.5 debug: 4.3.4 lodash.debounce: 4.0.8 @@ -3063,7 +3111,7 @@ packages: '@babel/core': ^7.4.0-0 dependencies: '@babel/core': 7.22.5 - '@babel/helper-compilation-targets': 7.22.5(@babel/core@7.22.5) + '@babel/helper-compilation-targets': 7.22.6(@babel/core@7.22.5) '@babel/helper-plugin-utils': 7.22.5 debug: 4.3.4 lodash.debounce: 4.0.8 @@ -3246,6 +3294,12 @@ packages: dependencies: '@babel/types': 7.22.5 + /@babel/helper-split-export-declaration@7.22.6: + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + /@babel/helper-string-parser@7.22.5: resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} engines: {node: '>=6.9.0'} @@ -3358,7 +3412,7 @@ packages: '@babel/core': ^7.12.0 dependencies: '@babel/core': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-create-class-features-plugin': 7.22.6(@babel/core@7.22.5) '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.5) transitivePeerDependencies: @@ -3394,6 +3448,22 @@ packages: transitivePeerDependencies: - supports-color + /@babel/plugin-proposal-decorators@7.22.6(@babel/core@7.22.5): + resolution: {integrity: sha512-cgskJ9W7kxTk/wBM16JNHhlTkeyDK6slMJg1peaI4LM3y2HtTv+6I85sW9UXSUZilndIBvDBETA1BRoOYdxWKw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.22.6(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/plugin-syntax-decorators': 7.22.5(@babel/core@7.22.5) + transitivePeerDependencies: + - supports-color + dev: true + /@babel/plugin-proposal-dynamic-import@7.18.6(@babel/core@7.22.5): resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} engines: {node: '>=6.9.0'} @@ -3460,9 +3530,9 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.22.5 + '@babel/compat-data': 7.22.6 '@babel/core': 7.22.5 - '@babel/helper-compilation-targets': 7.22.5(@babel/core@7.22.5) + '@babel/helper-compilation-targets': 7.22.6(@babel/core@7.22.5) '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.5) '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.5) @@ -3495,8 +3565,8 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.22.5) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 transitivePeerDependencies: - supports-color @@ -3772,7 +3842,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-create-class-features-plugin': 7.22.6(@babel/core@7.22.5) '@babel/helper-plugin-utils': 7.22.5 transitivePeerDependencies: - supports-color @@ -3784,7 +3854,7 @@ packages: '@babel/core': ^7.12.0 dependencies: '@babel/core': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-create-class-features-plugin': 7.22.6(@babel/core@7.22.5) '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.5) transitivePeerDependencies: @@ -3804,11 +3874,31 @@ packages: '@babel/helper-optimise-call-expression': 7.22.5 '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-replace-supers': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 globals: 11.12.0 transitivePeerDependencies: - supports-color + /@babel/plugin-transform-classes@7.22.6(@babel/core@7.22.5): + resolution: {integrity: sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-compilation-targets': 7.22.6(@babel/core@7.22.5) + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.22.5): resolution: {integrity: sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==} engines: {node: '>=6.9.0'} @@ -4083,6 +4173,18 @@ packages: '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.5) + /@babel/plugin-transform-optional-chaining@7.22.6(@babel/core@7.22.5): + resolution: {integrity: sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.5) + dev: true + /@babel/plugin-transform-parameters@7.22.5(@babel/core@7.22.5): resolution: {integrity: sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==} engines: {node: '>=6.9.0'} @@ -4099,7 +4201,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-create-class-features-plugin': 7.22.6(@babel/core@7.22.5) '@babel/helper-plugin-utils': 7.22.5 transitivePeerDependencies: - supports-color @@ -4112,7 +4214,7 @@ packages: dependencies: '@babel/core': 7.22.5 '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-create-class-features-plugin': 7.22.6(@babel/core@7.22.5) '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.5) transitivePeerDependencies: @@ -4179,6 +4281,23 @@ packages: - supports-color dev: true + /@babel/plugin-transform-runtime@7.22.6(@babel/core@7.22.5): + resolution: {integrity: sha512-+AGkst7Kqq3QUflKGkhWWMRb9vaKamoreNmYc+sjsIpOp+TsyU0exhp3RlwjQa/HdlKkPt3AMDwfg8Hpt9Vwqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-module-imports': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@nicolo-ribaudo/semver-v6': 6.3.3 + babel-plugin-polyfill-corejs2: 0.4.3(@babel/core@7.22.5) + babel-plugin-polyfill-corejs3: 0.8.1(@babel/core@7.22.5) + babel-plugin-polyfill-regenerator: 0.5.0(@babel/core@7.22.5) + transitivePeerDependencies: + - supports-color + dev: true + /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.22.5): resolution: {integrity: sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==} engines: {node: '>=6.9.0'} @@ -4268,7 +4387,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-create-class-features-plugin': 7.22.6(@babel/core@7.22.5) '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.5) transitivePeerDependencies: @@ -4496,6 +4615,97 @@ packages: transitivePeerDependencies: - supports-color + /@babel/preset-env@7.22.6(@babel/core@7.22.5): + resolution: {integrity: sha512-IHr0AXHGk8oh8HYSs45Mxuv6iySUBwDTIzJSnXN7PURqHdxJVQlCoXmKJgyvSS9bcNf9NVRVE35z+LkCvGmi6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.22.6 + '@babel/core': 7.22.5 + '@babel/helper-compilation-targets': 7.22.6(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.22.5 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.5) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.5) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.5) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.5) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.5) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.5) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.5) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.5) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.5) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.22.5) + '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-async-generator-functions': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-block-scoping': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-class-static-block': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-classes': 7.22.6(@babel/core@7.22.5) + '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-destructuring': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-dynamic-import': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-export-namespace-from': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-for-of': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-json-strings': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-logical-assignment-operators': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-modules-amd': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-modules-commonjs': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-modules-systemjs': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-nullish-coalescing-operator': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-numeric-separator': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-object-rest-spread': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-optional-catch-binding': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-optional-chaining': 7.22.6(@babel/core@7.22.5) + '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-private-property-in-object': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-regenerator': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-unicode-escapes': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.22.5) + '@babel/preset-modules': 0.1.5(@babel/core@7.22.5) + '@babel/types': 7.22.5 + '@nicolo-ribaudo/semver-v6': 6.3.3 + babel-plugin-polyfill-corejs2: 0.4.3(@babel/core@7.22.5) + babel-plugin-polyfill-corejs3: 0.8.1(@babel/core@7.22.5) + babel-plugin-polyfill-regenerator: 0.5.0(@babel/core@7.22.5) + core-js-compat: 3.31.1 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/preset-modules@0.1.5(@babel/core@7.22.5): resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} peerDependencies: @@ -4538,6 +4748,12 @@ packages: dependencies: regenerator-runtime: 0.13.11 + /@babel/runtime@7.22.6: + resolution: {integrity: sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.11 + /@babel/template@7.22.5: resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} engines: {node: '>=6.9.0'} @@ -4717,9 +4933,9 @@ packages: '@babel/code-frame': 7.22.5 '@babel/core': 7.22.5 '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.5) - '@babel/plugin-transform-runtime': 7.22.5(@babel/core@7.22.5) - '@babel/preset-env': 7.22.5(@babel/core@7.22.5) - '@babel/runtime': 7.22.5 + '@babel/plugin-transform-runtime': 7.22.6(@babel/core@7.22.5) + '@babel/preset-env': 7.22.6(@babel/core@7.22.5) + '@babel/runtime': 7.22.6 '@babel/traverse': 7.22.5 '@embroider/core': 3.1.2 '@embroider/macros': 1.12.2 @@ -5241,6 +5457,10 @@ packages: eslint-scope: 5.1.1 dev: true + /@nicolo-ribaudo/semver-v6@6.3.3: + resolution: {integrity: sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==} + hasBin: true + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -6680,7 +6900,7 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.22.5 + '@babel/compat-data': 7.22.6 '@babel/core': 7.22.5 '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.22.5) semver: 6.3.0 @@ -6706,7 +6926,7 @@ packages: dependencies: '@babel/core': 7.22.5 '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.22.5) - core-js-compat: 3.30.2 + core-js-compat: 3.31.1 transitivePeerDependencies: - supports-color @@ -7765,8 +7985,8 @@ packages: resolution: {integrity: sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==} hasBin: true dependencies: - caniuse-lite: 1.0.30001470 - electron-to-chromium: 1.4.340 + caniuse-lite: 1.0.30001512 + electron-to-chromium: 1.4.451 dev: true /browserslist@4.21.5: @@ -7779,6 +7999,16 @@ packages: node-releases: 2.0.10 update-browserslist-db: 1.0.10(browserslist@4.21.5) + /browserslist@4.21.9: + resolution: {integrity: sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001512 + electron-to-chromium: 1.4.451 + node-releases: 2.0.12 + update-browserslist-db: 1.0.11(browserslist@4.21.9) + /bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} dependencies: @@ -7897,6 +8127,9 @@ packages: /caniuse-lite@1.0.30001470: resolution: {integrity: sha512-065uNwY6QtHCBOExzbV6m236DDhYCCtPmQUCoQtwkVqzud8v5QPidoMr6CoMkC2nfp6nksjttqWQRRh75LqUmA==} + /caniuse-lite@1.0.30001512: + resolution: {integrity: sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==} + /capture-exit@2.0.0: resolution: {integrity: sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==} engines: {node: 6.* || 8.* || >= 10.*} @@ -8506,6 +8739,11 @@ packages: dependencies: browserslist: 4.21.5 + /core-js-compat@3.31.1: + resolution: {integrity: sha512-wIDWd2s5/5aJSdpOJHfSibxNODxoGoWOBHt8JSPB41NOE94M7kuTPZCYLOlTtuoXTsBPKobpJ6T+y0SSy5L9SA==} + dependencies: + browserslist: 4.21.9 + /core-js@2.6.12: resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. @@ -8919,6 +9157,9 @@ packages: /electron-to-chromium@1.4.340: resolution: {integrity: sha512-zx8hqumOqltKsv/MF50yvdAlPF9S/4PXbyfzJS6ZGhbddGkRegdwImmfSVqCkEziYzrIGZ/TlrzBND4FysfkDg==} + /electron-to-chromium@1.4.451: + resolution: {integrity: sha512-YYbXHIBxAHe3KWvGOJOuWa6f3tgow44rBW+QAuwVp2DvGqNZeE//K2MowNdWS7XE8li5cgQDrX1LdBr41LufkA==} + /ember-auto-import@2.6.3(webpack@5.88.1): resolution: {integrity: sha512-uLhrRDJYWCRvQ4JQ1e64XlSrqAKSd6PXaJ9ZsZI6Tlms9T4DtQFxNXasqji2ZRJBVrxEoLCRYX3RTldsQ0vNGQ==} engines: {node: 12.* || 14.* || >= 16} @@ -12149,7 +12390,7 @@ packages: /is-language-code@3.1.0: resolution: {integrity: sha512-zJdQ3QTeLye+iphMeK3wks+vXSRFKh68/Pnlw7aOfApFSEIOhYa8P9vwwa6QrImNNBMJTiL1PpYF0f4BxDuEgA==} dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.22.6 /is-module@1.0.0: resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} @@ -13454,6 +13695,9 @@ packages: /node-releases@2.0.10: resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} + /node-releases@2.0.12: + resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==} + /node-uuid@1.4.8: resolution: {integrity: sha512-TkCET/3rr9mUuRp+CpO7qfgT++aAxfDRaalQhwPFzI9BY/2rCDn6OfpZOVggi1AXfTPpfkTrg5f5WQx5G1uLxA==} deprecated: Use uuid module instead @@ -14314,7 +14558,7 @@ packages: /regenerator-transform@0.15.1: resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} dependencies: - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.22.6 /regex-not@1.0.2: resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} @@ -15995,6 +16239,16 @@ packages: escalade: 3.1.1 picocolors: 1.0.0 + /update-browserslist-db@1.0.11(browserslist@4.21.9): + resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.9 + escalade: 3.1.1 + picocolors: 1.0.0 + /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: @@ -17037,7 +17291,7 @@ packages: dependencies: '@babel/core': 7.22.5 '@babel/plugin-transform-block-scoping': 7.22.5(@babel/core@7.22.5) - '@babel/runtime': 7.22.5 + '@babel/runtime': 7.22.6 '@ember/edition-utils': 1.2.0 '@embroider/macros': 1.12.2 babel-import-util: 1.3.0 @@ -17375,8 +17629,11 @@ packages: name: '@ember-data/tracking' engines: {node: 16.* || >= 18} dependencies: + '@ember-data/private-build-infra': file:packages/private-build-infra + '@embroider/macros': 1.12.2 ember-cli-babel: 7.26.11 transitivePeerDependencies: + - '@glint/template' - supports-color file:packages/unpublished-test-infra: diff --git a/tests/main/tests/end-user-dx/meaningful-backtracking-errors-test.js b/tests/main/tests/end-user-dx/meaningful-backtracking-errors-test.js new file mode 100644 index 00000000000..e24968a051b --- /dev/null +++ b/tests/main/tests/end-user-dx/meaningful-backtracking-errors-test.js @@ -0,0 +1,57 @@ +import { render, setupOnerror } from '@ember/test-helpers'; + +import hbs from 'htmlbars-inline-precompile'; +import { module } from 'qunit'; + +import Store from 'ember-data/store'; +import { setupRenderingTest } from 'ember-qunit'; + +import Model, { attr } from '@ember-data/model'; +import test from '@ember-data/unpublished-test-infra/test-support/test-in-debug'; + +module('DX | Meaningful Backtracking Errors', function (hooks) { + setupRenderingTest(hooks); + + hooks.beforeEach(function () { + this.owner.register('service:store', Store); + this.owner.register( + 'model:user', + class extends Model { + @attr name; + } + ); + }); + + test('We meaningfully error for live arrays', async function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + + class PoorlyWrittenCode { + get value() { + return store.createRecord('user', { name: 'Chris' }); + } + } + + this.set('records', store.peekAll('user')); + this.set('badCode', new PoorlyWrittenCode()); + + function handler(error) { + assert.true( + error.message.includes( + 'You attempted to update .length, but it had already been used previously in the same computation' + ), + 'we have a meaningful error' + ); + return false; + } + + setupOnerror(handler); + + await render(hbs` + Count: {{this.records.length}} + Value: {{this.badCode.value}} + `); + + setupOnerror(); + }); +});