diff --git a/changelog/25272.txt b/changelog/25272.txt new file mode 100644 index 0000000000..77006057bf --- /dev/null +++ b/changelog/25272.txt @@ -0,0 +1,3 @@ +```release-note:change +ui: Upgrade Ember data from 4.11.3 to 4.12.4 +``` \ No newline at end of file diff --git a/ui/app/serializers/secret.js b/ui/app/serializers/secret.js index dd31bfab93..821bafe685 100644 --- a/ui/app/serializers/secret.js +++ b/ui/app/serializers/secret.js @@ -37,9 +37,8 @@ export default ApplicationSerializer.extend({ // to `secret_data` so it will be `secretData` in the model payload.secret_data = get(payload, path); delete payload[path]; - // return the payload if it's expecting a single object or wrap - // it as an array if not - return requestType === 'queryRecord' ? payload : [payload]; + + return payload; }, serialize(snapshot) { diff --git a/ui/app/services/store.js b/ui/app/services/store.js index c2bc4fd713..3662614e21 100644 --- a/ui/app/services/store.js +++ b/ui/app/services/store.js @@ -3,7 +3,9 @@ * SPDX-License-Identifier: BUSL-1.1 */ -import Store from '@ember-data/store'; +import Store, { CacheHandler } from '@ember-data/store'; +import RequestManager from '@ember-data/request'; +import { LegacyNetworkHandler } from '@ember-data/legacy-compat'; import { run, schedule } from '@ember/runloop'; import { resolve, Promise } from 'rsvp'; import { dasherize } from '@ember/string'; @@ -33,6 +35,16 @@ export function keyForCache(query) { } export default class StoreService extends Store { + requestManager = new RequestManager(); + + constructor(args) { + super(args); + // If at some point we no longer need an extended store, we can remove the @ember-data/legacy-compat dep + // See: https://api.emberjs.com/ember-data/4.12/modules/@ember-data%2Frequest + this.requestManager.use([LegacyNetworkHandler]); + this.requestManager.useCache(CacheHandler); + } + lazyCaches = new Map(); setLazyCacheForModel(modelName, key, value) { diff --git a/ui/mirage/handlers/sync.js b/ui/mirage/handlers/sync.js index cc1d29469f..eba258f42a 100644 --- a/ui/mirage/handlers/sync.js +++ b/ui/mirage/handlers/sync.js @@ -75,8 +75,15 @@ const createOrUpdateDestination = (schema, req) => { } } const data = { ...apiResponse, type, name }; - schema.db.syncDestinations.firstOrCreate({ type, name }, data); - return schema.db.syncDestinations.update({ type, name }, data); + // issue with mirages' update method not returning an id on the payload which causes ember data to error after 4.12.x upgrade. + // to work around this, determine if we're creating or updating a record first + const records = schema.db.syncDestinations.where({ type, name }); + + if (!records.length) { + return schema.db.syncDestinations.firstOrCreate({ type, name }, data); + } else { + return schema.db.syncDestinations.update({ type, name }, data); + } }; export default function (server) { diff --git a/ui/package.json b/ui/package.json index 7acfd205b3..c3a68ebcab 100644 --- a/ui/package.json +++ b/ui/package.json @@ -59,6 +59,7 @@ "@babel/plugin-proposal-decorators": "^7.21.0", "@babel/plugin-proposal-object-rest-spread": "^7.12.1", "@babel/plugin-transform-block-scoping": "^7.12.1", + "@ember-data/legacy-compat": "~4.12.4", "@ember/legacy-built-in-components": "^0.4.1", "@ember/optional-features": "^2.0.0", "@ember/render-modifiers": "^1.0.2", @@ -145,7 +146,7 @@ "ember-concurrency": "2.3.4", "ember-copy": "2.0.1", "ember-d3": "^0.5.1", - "ember-data": "~4.11.3", + "ember-data": "~4.12.4", "ember-engines": "0.8.23", "ember-exam": "^9.0.0", "ember-fetch": "^8.1.2", diff --git a/ui/tests/acceptance/auth-test.js b/ui/tests/acceptance/auth-test.js index 30bdc6528b..ab48fe5d33 100644 --- a/ui/tests/acceptance/auth-test.js +++ b/ui/tests/acceptance/auth-test.js @@ -75,7 +75,7 @@ module('Acceptance | auth', function (hooks) { let included; if (backend.type === 'token') { keys = lastRequest.requestHeaders; - included = 'X-Vault-Token'; + included = 'x-vault-token'; } else if (backend.type === 'github') { keys = body; included = 'token'; diff --git a/ui/tests/acceptance/mfa-login-enforcement-test.js b/ui/tests/acceptance/mfa-login-enforcement-test.js index f3f59abff2..1c4751d374 100644 --- a/ui/tests/acceptance/mfa-login-enforcement-test.js +++ b/ui/tests/acceptance/mfa-login-enforcement-test.js @@ -5,7 +5,7 @@ import { module, test } from 'qunit'; import { setupApplicationTest } from 'ember-qunit'; -import { click, currentRouteName, fillIn, visit } from '@ember/test-helpers'; +import { click, currentRouteName, fillIn, visit, waitFor } from '@ember/test-helpers'; import authPage from 'vault/tests/pages/auth'; import { setupMirage } from 'ember-cli-mirage/test-support'; import mfaConfigHandlers from 'vault/mirage/handlers/mfa-config'; @@ -134,6 +134,7 @@ module('Acceptance | mfa-login-enforcement', function (hooks) { assert.dom('h1').includesText(enforcement.name, 'Name renders in title'); assert.dom('h1 svg').hasClass('flight-icon-lock', 'Lock icon renders in title'); assert.dom('[data-test-tab="targets"]').hasClass('active', 'Targets tab is active by default'); + await waitFor('[data-test-target]', { timeout: 5000 }); assert.dom('[data-test-target]').exists({ count: 4 }, 'Targets render in list'); // targets tab const targets = { @@ -231,6 +232,7 @@ module('Acceptance | mfa-login-enforcement', function (hooks) { await click('[data-test-mlef-remove-target="Authentication method"]'); await click('[data-test-mlef-save]'); + await waitFor('[data-test-target]', { timeout: 5000 }); assert.strictEqual( currentRouteName(), 'vault.cluster.access.mfa.enforcements.enforcement.index', diff --git a/ui/tests/acceptance/mfa-login-test.js b/ui/tests/acceptance/mfa-login-test.js index d6115d2d8d..5154a6647b 100644 --- a/ui/tests/acceptance/mfa-login-test.js +++ b/ui/tests/acceptance/mfa-login-test.js @@ -5,7 +5,7 @@ import { module, test } from 'qunit'; import { setupApplicationTest } from 'ember-qunit'; -import { click, currentRouteName, fillIn, visit, waitUntil, find } from '@ember/test-helpers'; +import { click, currentRouteName, fillIn, visit, waitUntil, find, waitFor } from '@ember/test-helpers'; import { setupMirage } from 'ember-cli-mirage/test-support'; import mfaLoginHandler, { validationHandler } from '../../mirage/handlers/mfa-login'; @@ -35,7 +35,11 @@ module('Acceptance | mfa-login', function (hooks) { await fillIn('[data-test-password]', 'test'); await click('[data-test-auth-submit]'); }; - const didLogin = (assert) => { + const didLogin = async (assert) => { + await waitFor('[data-test-dashboard-card-header]', { + timeout: 5000, + timeoutMessage: 'timed out waiting for dashboard title to render', + }); assert.strictEqual(currentRouteName(), 'vault.cluster.dashboard', 'Route transitions after login'); }; const validate = async (multi) => { @@ -58,7 +62,7 @@ module('Acceptance | mfa-login', function (hooks) { assert.dom('[data-test-mfa-select]').doesNotExist('Select is hidden for single method'); assert.dom('[data-test-mfa-passcode]').exists({ count: 1 }, 'Single passcode input renders'); await validate(); - didLogin(assert); + await didLogin(assert); }); test('it should handle single mfa constraint with push method', async function (assert) { @@ -84,7 +88,7 @@ module('Acceptance | mfa-login', function (hooks) { }); await login('mfa-b'); - didLogin(assert); + await didLogin(assert); }); test('it should handle single mfa constraint with 2 passcode methods', async function (assert) { @@ -99,7 +103,7 @@ module('Acceptance | mfa-login', function (hooks) { assert.dom('[data-test-mfa-passcode]').doesNotExist('Passcode input hidden until selection is made'); await this.select(); await validate(); - didLogin(assert); + await didLogin(assert); }); test('it should handle single mfa constraint with 2 push methods', async function (assert) { @@ -107,7 +111,7 @@ module('Acceptance | mfa-login', function (hooks) { await login('mfa-d'); await this.select(); await click('[data-test-mfa-validate]'); - didLogin(assert); + await didLogin(assert); }); test('it should handle single mfa constraint with 1 passcode and 1 push method', async function (assert) { @@ -118,7 +122,7 @@ module('Acceptance | mfa-login', function (hooks) { await this.select(); assert.dom('[data-test-mfa-passcode]').doesNotExist('Passcode input is hidden for push method'); await click('[data-test-mfa-validate]'); - didLogin(assert); + await didLogin(assert); }); test('it should handle multiple mfa constraints with 1 passcode method each', async function (assert) { @@ -132,13 +136,13 @@ module('Acceptance | mfa-login', function (hooks) { ); assert.dom('[data-test-mfa-select]').doesNotExist('Selects do not render for single methods'); await validate(true); - didLogin(assert); + await didLogin(assert); }); test('it should handle multi mfa constraint with 1 push method each', async function (assert) { assert.expect(1); await login('mfa-g'); - didLogin(assert); + await didLogin(assert); }); test('it should handle multiple mfa constraints with 1 passcode and 1 push method', async function (assert) { @@ -153,7 +157,7 @@ module('Acceptance | mfa-login', function (hooks) { assert.dom('[data-test-mfa-select]').doesNotExist('Select is hidden for single method'); assert.dom('[data-test-mfa-passcode]').exists({ count: 1 }, 'Passcode input renders'); await validate(); - didLogin(assert); + await didLogin(assert); }); test('it should handle multiple mfa constraints with multiple mixed methods', async function (assert) { @@ -168,11 +172,12 @@ module('Acceptance | mfa-login', function (hooks) { await this.select(); await fillIn('[data-test-mfa-passcode="1"]', 'test'); await click('[data-test-mfa-validate]'); - didLogin(assert); + await didLogin(assert); }); test('it should render unauthorized message for push failure', async function (assert) { await login('mfa-j'); + await waitFor('[data-test-empty-state-title]'); assert.dom('[data-test-auth-form]').doesNotExist('Auth form hidden when mfa fails'); assert.dom('[data-test-empty-state-title]').hasText('Unauthorized', 'Error title renders'); assert diff --git a/ui/tests/acceptance/mfa-setup-test.js b/ui/tests/acceptance/mfa-setup-test.js index abfcf7e80a..1750356253 100644 --- a/ui/tests/acceptance/mfa-setup-test.js +++ b/ui/tests/acceptance/mfa-setup-test.js @@ -7,7 +7,7 @@ import { module, test } from 'qunit'; import { create } from 'ember-cli-page-object'; import { v4 as uuidv4 } from 'uuid'; import { setupApplicationTest } from 'ember-qunit'; -import { click, fillIn } from '@ember/test-helpers'; +import { click, fillIn, waitFor } from '@ember/test-helpers'; import authPage from 'vault/tests/pages/auth'; import enablePage from 'vault/tests/pages/settings/auth/enable'; import consoleClass from 'vault/tests/pages/components/console/ui-panel'; @@ -77,9 +77,11 @@ module('Acceptance | mfa-setup', function (hooks) { }); await fillIn('[data-test-input="uuid"]', 123); await click('[data-test-verify]'); + await waitFor('[data-test-qrcode]', { timeout: 5000 }); assert.dom('[data-test-qrcode]').exists('the qrCode is shown.'); assert.dom('[data-test-mfa-enabled-warning]').doesNotExist('warning does not show.'); await click('[data-test-restart]'); + await waitFor('[data-test-step-one]', { timeout: 5000 }); assert.dom('[data-test-step-one]').exists('back to step one.'); }); @@ -95,6 +97,7 @@ module('Acceptance | mfa-setup', function (hooks) { await fillIn('[data-test-input="uuid"]', 123); await click('[data-test-verify]'); + await waitFor('[data-test-mfa-enabled-warning]', { timeout: 5000 }); assert.dom('[data-test-qrcode]').doesNotExist('the qrCode is not shown.'); assert.dom('[data-test-mfa-enabled-warning]').exists('the mfa-enabled warning shows.'); }); diff --git a/ui/tests/acceptance/pki/pki-configuration-test.js b/ui/tests/acceptance/pki/pki-configuration-test.js index 7e1176a495..3e9fae9507 100644 --- a/ui/tests/acceptance/pki/pki-configuration-test.js +++ b/ui/tests/acceptance/pki/pki-configuration-test.js @@ -3,10 +3,11 @@ * SPDX-License-Identifier: BUSL-1.1 */ +/* eslint-disable ember/no-settled-after-test-helper */ import { module, test } from 'qunit'; import { setupApplicationTest } from 'ember-qunit'; import { setupMirage } from 'ember-cli-mirage/test-support'; -import { click, currentURL, fillIn, visit, isSettled, waitUntil, find } from '@ember/test-helpers'; +import { click, currentURL, fillIn, visit, settled, find, waitFor, waitUntil } from '@ember/test-helpers'; import { v4 as uuidv4 } from 'uuid'; import authPage from 'vault/tests/pages/auth'; @@ -44,7 +45,7 @@ module('Acceptance | pki configuration test', function (hooks) { await visit(`/vault/secrets/${this.mountPath}/pki/configuration`); await click(SELECTORS.configuration.configureButton); assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/configuration/create`); - await isSettled(); + await settled(); await click(SELECTORS.configuration.generateRootOption); await fillIn(SELECTORS.configuration.typeField, 'exported'); await fillIn(SELECTORS.configuration.generateRootCommonNameField, 'issuer-common-0'); @@ -52,15 +53,19 @@ module('Acceptance | pki configuration test', function (hooks) { await click(SELECTORS.configuration.generateRootSave); await click(SELECTORS.configuration.doneButton); assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/overview`); - await isSettled(); + await settled(); await click(SELECTORS.configTab); - await isSettled(); + await settled(); assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/configuration`); await click(SELECTORS.configuration.issuerLink); - await isSettled(); + await settled(); + await waitFor(SELECTORS.configuration.deleteAllIssuerModal, { timeout: 5000 }); assert.dom(SELECTORS.configuration.deleteAllIssuerModal).exists(); await fillIn(SELECTORS.configuration.deleteAllIssuerInput, 'delete-all'); await click(SELECTORS.configuration.deleteAllIssuerButton); + await settled(); + await waitUntil(() => !find(SELECTORS.configuration.deleteAllIssuerModal)); + assert.dom(SELECTORS.configuration.deleteAllIssuerModal).doesNotExist(); assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/configuration`); }); @@ -92,10 +97,11 @@ module('Acceptance | pki configuration test', function (hooks) { 'goes to configuration page' ); await click(SELECTORS.configuration.issuerLink); + await waitFor(SELECTORS.configuration.deleteAllIssuerModal); assert.dom(SELECTORS.configuration.deleteAllIssuerModal).exists(); await fillIn(SELECTORS.configuration.deleteAllIssuerInput, 'delete-all'); await click(SELECTORS.configuration.deleteAllIssuerButton); - await isSettled(); + await waitUntil(() => !find(SELECTORS.configuration.deleteAllIssuerModal)); assert .dom(SELECTORS.configuration.deleteAllIssuerModal) .doesNotExist('delete all issuers modal closes'); @@ -104,10 +110,9 @@ module('Acceptance | pki configuration test', function (hooks) { `/vault/secrets/${this.mountPath}/pki/configuration`, 'is still on configuration page' ); - await isSettled(); + await settled(); await visit(`/vault/secrets/${this.mountPath}/pki/overview`); - await waitUntil(() => currentURL() === `/vault/secrets/${this.mountPath}/pki/overview`); - await isSettled(); + await settled(); assert.strictEqual( currentURL(), `/vault/secrets/${this.mountPath}/pki/overview`, @@ -120,25 +125,25 @@ module('Acceptance | pki configuration test', function (hooks) { ); await visit(`/vault/secrets/${this.mountPath}/pki/roles`); - await isSettled(); + await settled(); assert .dom(SELECTORS.emptyStateMessage) .hasText("This PKI mount hasn't yet been configured with a certificate issuer."); await visit(`/vault/secrets/${this.mountPath}/pki/issuers`); - await isSettled(); + await settled(); assert .dom(SELECTORS.emptyStateMessage) .hasText("This PKI mount hasn't yet been configured with a certificate issuer."); await visit(`/vault/secrets/${this.mountPath}/pki/keys`); - await isSettled(); + await settled(); assert .dom(SELECTORS.emptyStateMessage) .hasText("This PKI mount hasn't yet been configured with a certificate issuer."); await visit(`/vault/secrets/${this.mountPath}/pki/certificates`); - await isSettled(); + await settled(); assert .dom(SELECTORS.emptyStateMessage) .hasText( @@ -148,6 +153,7 @@ module('Acceptance | pki configuration test', function (hooks) { test('it shows the correct empty state message if roles and certificates exists after delete all issuers', async function (assert) { await authPage.login(this.pkiAdminToken); + // Configure PKI await visit(`/vault/secrets/${this.mountPath}/pki/configuration`); await click(SELECTORS.configuration.configureButton); assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/configuration/create`); @@ -157,6 +163,7 @@ module('Acceptance | pki configuration test', function (hooks) { await fillIn(SELECTORS.configuration.generateRootIssuerNameField, 'issuer-0'); await click(SELECTORS.configuration.generateRootSave); await click(SELECTORS.configuration.doneButton); + // Create role and root CA" await runCmd([ `write ${this.mountPath}/roles/some-role \ issuer_ref="default" \ @@ -169,16 +176,17 @@ module('Acceptance | pki configuration test', function (hooks) { await click(SELECTORS.configTab); assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/configuration`); await click(SELECTORS.configuration.issuerLink); + await waitFor(SELECTORS.configuration.deleteAllIssuerModal); assert.dom(SELECTORS.configuration.deleteAllIssuerModal).exists(); await fillIn(SELECTORS.configuration.deleteAllIssuerInput, 'delete-all'); await click(SELECTORS.configuration.deleteAllIssuerButton); - await isSettled(); + await settled(); + await waitUntil(() => !find(SELECTORS.configuration.deleteAllIssuerModal)); assert.dom(SELECTORS.configuration.deleteAllIssuerModal).doesNotExist(); assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/configuration`); - await isSettled(); + await settled(); await visit(`/vault/secrets/${this.mountPath}/pki/overview`); - await waitUntil(() => currentURL() === `/vault/secrets/${this.mountPath}/pki/overview`); - await isSettled(); + await settled(); assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/overview`); assert .dom(SELECTORS.emptyStateMessage) @@ -187,7 +195,7 @@ module('Acceptance | pki configuration test', function (hooks) { ); await visit(`/vault/secrets/${this.mountPath}/pki/roles`); - await isSettled(); + await settled(); assert .dom(SELECTORS.emptyStateMessage) .hasText( @@ -195,19 +203,19 @@ module('Acceptance | pki configuration test', function (hooks) { ); await visit(`/vault/secrets/${this.mountPath}/pki/issuers`); - await isSettled(); + await settled(); assert .dom(SELECTORS.emptyStateMessage) .hasText("This PKI mount hasn't yet been configured with a certificate issuer."); await visit(`/vault/secrets/${this.mountPath}/pki/keys`); - await isSettled(); + await settled(); assert .dom(SELECTORS.emptyStateMessage) .hasText("This PKI mount hasn't yet been configured with a certificate issuer."); await visit(`/vault/secrets/${this.mountPath}/pki/certificates`); - await isSettled(); + await settled(); assert .dom(SELECTORS.emptyStateMessage) .hasText( diff --git a/ui/tests/acceptance/sync/secrets/destination-test.js b/ui/tests/acceptance/sync/secrets/destination-test.js index 0ace5f28f5..b5182b90c6 100644 --- a/ui/tests/acceptance/sync/secrets/destination-test.js +++ b/ui/tests/acceptance/sync/secrets/destination-test.js @@ -3,13 +3,14 @@ * SPDX-License-Identifier: BUSL-1.1 */ +/* eslint-disable ember/no-settled-after-test-helper */ import { module, test } from 'qunit'; import { setupApplicationTest } from 'ember-qunit'; import { setupMirage } from 'ember-cli-mirage/test-support'; import syncScenario from 'vault/mirage/scenarios/sync'; import syncHandlers from 'vault/mirage/handlers/sync'; import authPage from 'vault/tests/pages/auth'; -import { click, visit, currentURL, fillIn, currentRouteName } from '@ember/test-helpers'; +import { settled, click, visit, currentURL, fillIn, currentRouteName } from '@ember/test-helpers'; import { PAGE as ts } from 'vault/tests/helpers/sync/sync-selectors'; // sync is an enterprise feature but since mirage is used the enterprise label has been intentionally omitted from the module name @@ -101,6 +102,7 @@ module('Acceptance | sync | destination', function (hooks) { this.server.db.syncDestinations.update({ purge_initiated_at: '2024-02-08T11:49:04.123251-07:00' }); await visit('vault/sync/secrets/overview'); + await settled(); await click(ts.overview.table.actionToggle(0)); await click(ts.overview.table.action('sync')); assert.strictEqual( diff --git a/ui/tests/acceptance/sync/secrets/overview-test.js b/ui/tests/acceptance/sync/secrets/overview-test.js index eb79c58b8a..ea24d262f7 100644 --- a/ui/tests/acceptance/sync/secrets/overview-test.js +++ b/ui/tests/acceptance/sync/secrets/overview-test.js @@ -9,7 +9,7 @@ import { setupMirage } from 'ember-cli-mirage/test-support'; import syncScenario from 'vault/mirage/scenarios/sync'; import syncHandlers from 'vault/mirage/handlers/sync'; import authPage from 'vault/tests/pages/auth'; -import { click } from '@ember/test-helpers'; +import { click, waitFor } from '@ember/test-helpers'; import { PAGE as ts } from 'vault/tests/helpers/sync/sync-selectors'; // sync is an enterprise feature but since mirage is used the enterprise label has been intentionally omitted from the module name @@ -29,10 +29,12 @@ module('Acceptance | sync | destination', function (hooks) { await click(ts.createCancel); await click(ts.overviewCard.actionLink('Create new')); await click(ts.createCancel); + await waitFor(ts.overview.table.actionToggle(0)); await click(ts.overview.table.actionToggle(0)); await click(ts.overview.table.action('sync')); await click(ts.destinations.sync.cancel); await click(ts.breadcrumbLink('Secrets Sync')); + await waitFor(ts.overview.table.actionToggle(0)); await click(ts.overview.table.actionToggle(0)); await click(ts.overview.table.action('details')); assert.dom(ts.tab('Secrets')).hasClass('active', 'Navigates to secrets view for destination'); diff --git a/ui/tests/integration/components/auth-form-test.js b/ui/tests/integration/components/auth-form-test.js index 1f589229c6..8e1dd06f3a 100644 --- a/ui/tests/integration/components/auth-form-test.js +++ b/ui/tests/integration/components/auth-form-test.js @@ -244,7 +244,7 @@ module('Integration | Component | auth form', function (hooks) { 'makes call to unwrap the token' ); assert.strictEqual( - server.handledRequests[0].requestHeaders['X-Vault-Token'], + server.handledRequests[0].requestHeaders['x-vault-token'], wrappedToken, 'uses passed wrapped token for the unwrap' ); diff --git a/ui/tests/integration/components/page/userpass-reset-password-test.js b/ui/tests/integration/components/page/userpass-reset-password-test.js index d16b24a2cd..c995e10f7f 100644 --- a/ui/tests/integration/components/page/userpass-reset-password-test.js +++ b/ui/tests/integration/components/page/userpass-reset-password-test.js @@ -7,7 +7,7 @@ import { module, test } from 'qunit'; import { setupRenderingTest } from 'vault/tests/helpers'; import { setupMirage } from 'ember-cli-mirage/test-support'; import { Response } from 'miragejs'; -import { click, fillIn, render } from '@ember/test-helpers'; +import { click, fillIn, render, settled } from '@ember/test-helpers'; import { hbs } from 'ember-cli-htmlbars'; const S = { @@ -44,6 +44,8 @@ module('Integration | Component | page/userpass-reset-password', function (hooks await fillIn(S.input, 'new'); await click(S.save); + // eslint-disable-next-line ember/no-settled-after-test-helper + await settled(); assert.dom(S.input).hasValue('', 'After successful save shows input again with empty value'); }); @@ -64,6 +66,8 @@ module('Integration | Component | page/userpass-reset-password', function (hooks await fillIn(S.input, 'invalid-pw'); await click(S.save); + // eslint-disable-next-line ember/no-settled-after-test-helper + await settled(); assert.dom(S.error).hasText('Error some error occurred', 'Shows error from API'); }); }); diff --git a/ui/tests/integration/components/shamir/dr-token-flow-test.js b/ui/tests/integration/components/shamir/dr-token-flow-test.js index 2cbb76bf25..b3a3032e83 100644 --- a/ui/tests/integration/components/shamir/dr-token-flow-test.js +++ b/ui/tests/integration/components/shamir/dr-token-flow-test.js @@ -6,7 +6,7 @@ import sinon from 'sinon'; import { module, test } from 'qunit'; import { setupRenderingTest } from 'vault/tests/helpers'; -import { click, fillIn, render } from '@ember/test-helpers'; +import { click, fillIn, find, render, waitUntil } from '@ember/test-helpers'; import { hbs } from 'ember-cli-htmlbars'; import { setupMirage } from 'ember-cli-mirage/test-support'; @@ -54,8 +54,13 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) { assert.dom('[data-test-dr-token-flow-step="begin"]').exists('First step shows'); assert.dom('[data-test-use-pgp-key-cta]').hasText('Provide PGP Key'); assert.dom('[data-test-generate-token-cta]').hasText('Generate operation token'); + await click('[data-test-generate-token-cta]'); - assert.dom('[data-test-dr-token-flow-step="shamir"]').exists('Shows shamir step after start'); + + assert.ok( + await waitUntil(() => find('[data-test-dr-token-flow-step="shamir"]')), + 'shows shamir step after start' + ); assert .dom('.shamir-progress') .hasText('0/3 keys provided', 'progress shows reflecting checkStatus response with defaults'); @@ -64,13 +69,15 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) { // Fill in shamir key and submit await fillIn('[data-test-shamir-key-input]', 'some-key'); await click('[data-test-shamir-submit]'); - assert.dom('.shamir-progress').hasText('1/3 keys provided', 'progress shows reflecting attempt response'); - assert - .dom('[data-test-otp-info]') - .exists('OTP info still banner shows even when attempt response does not include it'); + + assert.ok( + await waitUntil(() => find('[data-test-otp-info]')), + 'OTP info still banner shows even when attempt response does not include it' + ); assert .dom('[data-test-otp]') .hasText('otp-9876', 'Still shows OTP in copy banner when attempt response does not include it'); + assert.dom('.shamir-progress').hasText('1/3 keys provided', 'progress shows reflecting attempt response'); }); test('middle to finish flow works', async function (assert) { @@ -107,7 +114,11 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) { }; }); await render(hbs``); - assert.dom('[data-test-dr-token-flow-step="shamir"]').exists('Shows shamir step on load'); + + assert.ok( + await waitUntil(() => find('[data-test-dr-token-flow-step="shamir"]')), + 'shows shamir step after start' + ); assert .dom('.shamir-progress') .hasText('2/3 keys provided', 'progress shows reflecting checkStatus response'); @@ -115,9 +126,11 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) { assert.dom('[data-test-otp]').doesNotExist('otp-9876', 'OTP copy banner not shown'); await fillIn('[data-test-shamir-key-input]', 'some-key'); await click('[data-test-shamir-submit]'); - assert - .dom('[data-test-dr-token-flow-step="show-token"]') - .exists('updates to show encoded token on complete'); + + assert.ok( + await waitUntil(() => find('[data-test-dr-token-flow-step="show-token"]')), + 'updates to show encoded token on complete' + ); assert .dom('[data-test-shamir-encoded-token]') .hasText('encoded-token-here', 'shows encoded token from /update response'); @@ -148,7 +161,10 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) { await fillIn('[data-test-pgp-file-textarea]', 'some-key-here'); await click('[data-test-use-pgp-key-button]'); await click('[data-test-confirm-pgp-key-submit]'); - assert.dom('[data-test-dr-token-flow-step="shamir"]').exists('Renders shamir step after PGP key chosen'); + assert.ok( + await waitUntil(() => find('[data-test-dr-token-flow-step="shamir"]')), + 'Renders shamir step after PGP key chosen' + ); }); test('it cancels correctly when generation not started', async function (assert) { @@ -170,11 +186,14 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) { await click('[data-test-shamir-modal-cancel-button]'); assert.ok(cancelSpy.calledOnce, 'cancel spy called on click'); }); + test('it cancels correctly when generation has started but not finished', async function (assert) { - assert.expect(3); - const cancelSpy = sinon.spy(); + assert.expect(6); + const cancelSpy = sinon.spy(() => { + assert.ok(true, 'passed cancel method called'); + }); this.set('onCancel', cancelSpy); - this.server.get('/sys/replication/dr/secondary/generate-operation-token/attempt', function () { + this.server.get('sys/replication/dr/secondary/generate-operation-token/attempt', function () { return { started: true, progress: 1, @@ -183,17 +202,24 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) { }; }); this.server.delete('/sys/replication/dr/secondary/generate-operation-token/attempt', function () { - assert.ok('delete endpoint is queried'); + assert.ok(true, 'delete endpoint is queried'); return {}; }); await render( hbs`` ); - assert.dom('[data-test-shamir-modal-cancel-button]').hasText('Cancel', 'Close button has correct copy'); + assert.ok(await waitUntil(() => find('[data-test-shamir-key-input]')), 'shows shamir key input'); + await click('[data-test-shamir-modal-cancel-button]'); - assert.ok(cancelSpy.calledOnce, 'cancel spy called on click'); + + assert.ok( + await waitUntil(() => find('[data-test-generate-token-cta]')), + 'shows generate token button again' + ); + assert.dom('[data-test-shamir-key-input]').doesNotExist('Does not render input for shamir key'); }); + test('it closes correctly when generation is completed', async function (assert) { assert.expect(2); const cancelSpy = sinon.spy(); @@ -215,6 +241,7 @@ module('Integration | Component | shamir/dr-token-flow', function (hooks) { hbs`` ); + await waitUntil(() => find('[data-test-dr-token-flow-step="show-token"]')); assert.dom('[data-test-shamir-modal-cancel-button]').hasText('Close', 'Close button has correct copy'); await click('[data-test-shamir-modal-cancel-button]'); assert.ok(cancelSpy.calledOnce, 'cancel spy called on click'); diff --git a/ui/tests/integration/components/sync/secrets/page/overview-test.js b/ui/tests/integration/components/sync/secrets/page/overview-test.js index 5e22f3045c..2587b8df50 100644 --- a/ui/tests/integration/components/sync/secrets/page/overview-test.js +++ b/ui/tests/integration/components/sync/secrets/page/overview-test.js @@ -3,6 +3,7 @@ * SPDX-License-Identifier: BUSL-1.1 */ +/* eslint-disable ember/no-settled-after-test-helper */ import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; import { setupEngine } from 'ember-engines/test-support'; @@ -114,6 +115,7 @@ module('Integration | Component | sync | Page::Overview', function (hooks) { assert.dom(name(0)).hasText('destination-aws', 'First destination renders on page 1'); await click(pagination.next); + await settled(); assert.dom(overview.table.row).exists({ count: 3 }, 'New items are fetched and rendered on page change'); assert.dom(name(0)).hasText('destination-gcp', 'First destination renders on page 2'); }); @@ -124,6 +126,7 @@ module('Integration | Component | sync | Page::Overview', function (hooks) { }); // since the request resolved trigger a page change and return an error from the associations endpoint await click(pagination.next); + await settled(); assert.dom(emptyStateTitle).hasText('Error fetching information', 'Empty state title renders'); assert .dom(emptyStateMessage) diff --git a/ui/tests/integration/services/auth-test.js b/ui/tests/integration/services/auth-test.js index 33c2298f3d..da00e65f2a 100644 --- a/ui/tests/integration/services/auth-test.js +++ b/ui/tests/integration/services/auth-test.js @@ -134,8 +134,8 @@ module('Integration | Service | auth', function (hooks) { this.server = new Pretender(function () { this.get('/v1/auth/token/lookup-self', function (request) { const resp = copy(ROOT_TOKEN_RESPONSE, true); - resp.id = request.requestHeaders['X-Vault-Token']; - resp.data.id = request.requestHeaders['X-Vault-Token']; + resp.id = request.requestHeaders['x-vault-token']; + resp.data.id = request.requestHeaders['x-vault-token']; return [200, {}, resp]; }); this.post('/v1/auth/userpass/login/:username', function (request) { @@ -321,8 +321,8 @@ module('Integration | Service | auth', function (hooks) { this.server.map(function () { this.get('/v1/auth/token/lookup-self', function (request) { const resp = copy(tokenResp, true); - resp.id = request.requestHeaders['X-Vault-Token']; - resp.data.id = request.requestHeaders['X-Vault-Token']; + resp.id = request.requestHeaders['x-vault-token']; + resp.data.id = request.requestHeaders['x-vault-token']; return [200, {}, resp]; }); }); diff --git a/ui/tsconfig.json b/ui/tsconfig.json index cf41d7a1eb..1f163fc908 100644 --- a/ui/tsconfig.json +++ b/ui/tsconfig.json @@ -12,6 +12,7 @@ "noPropertyAccessFromIndexSignature": true, "noEmitOnError": true, "skipLibCheck": true, + "target": "es2021", // The combination of `baseUrl` with `paths` allows Ember's classic package // layout, which is not resolvable with the Node resolution algorithm, to // work with TypeScript. diff --git a/ui/yarn.lock b/ui/yarn.lock index 21365ff98c..5b0f0e4dd6 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -243,7 +243,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.20.2, @babel/core@npm:^7.21.0": +"@babel/core@npm:^7.21.0": version: 7.22.9 resolution: "@babel/core@npm:7.22.9" dependencies: @@ -266,7 +266,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.23.6": +"@babel/core@npm:^7.21.4, @babel/core@npm:^7.23.6": version: 7.23.7 resolution: "@babel/core@npm:7.23.7" dependencies: @@ -3002,7 +3002,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.20.2, @babel/plugin-transform-block-scoping@npm:^7.20.5": +"@babel/plugin-transform-block-scoping@npm:^7.20.5": version: 7.22.5 resolution: "@babel/plugin-transform-block-scoping@npm:7.22.5" dependencies: @@ -3013,7 +3013,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.23.4": +"@babel/plugin-transform-block-scoping@npm:^7.21.0, @babel/plugin-transform-block-scoping@npm:^7.23.4": version: 7.23.4 resolution: "@babel/plugin-transform-block-scoping@npm:7.23.4" dependencies: @@ -4969,15 +4969,6 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.20.1": - version: 7.22.6 - resolution: "@babel/runtime@npm:7.22.6" - dependencies: - regenerator-runtime: ^0.13.11 - checksum: e585338287c4514a713babf4fdb8fc2a67adcebab3e7723a739fc62c79cfda875b314c90fd25f827afb150d781af97bc16c85bfdbfa2889f06053879a1ddb597 - languageName: node - linkType: hard - "@babel/runtime@npm:^7.21.0": version: 7.21.5 resolution: "@babel/runtime@npm:7.21.5" @@ -5334,85 +5325,125 @@ __metadata: languageName: node linkType: hard -"@ember-data/adapter@npm:4.11.3": - version: 4.11.3 - resolution: "@ember-data/adapter@npm:4.11.3" +"@ember-data/adapter@npm:4.12.5": + version: 4.12.5 + resolution: "@ember-data/adapter@npm:4.12.5" dependencies: - "@ember-data/private-build-infra": 4.11.3 - "@ember/edition-utils": ^1.2.0 + "@ember-data/private-build-infra": 4.12.5 "@embroider/macros": ^1.10.0 - ember-auto-import: ^2.4.3 ember-cli-babel: ^7.26.11 ember-cli-test-info: ^1.0.0 peerDependencies: - "@ember-data/store": 4.11.3 + "@ember-data/store": 4.12.5 "@ember/string": ^3.0.1 ember-inflector: ^4.0.2 - checksum: 2fc2366b334eb1e0a722d97296df11dd41b31dcd3343c41a90a21d0aeecc949ccb23ee94101830b91b7c6c74127cf55e953d1d4da67c3668776c95c107cda831 + checksum: 224b66b96bd7b5e982d3c60720172b57c817153d97a1b396a36644e18571afaff2257af58ef7821bad7515f6aec37c78ceb82148c526f871cf3d11b2d1b2364b languageName: node linkType: hard -"@ember-data/canary-features@npm:4.11.3": - version: 4.11.3 - resolution: "@ember-data/canary-features@npm:4.11.3" +"@ember-data/debug@npm:4.12.5": + version: 4.12.5 + resolution: "@ember-data/debug@npm:4.12.5" dependencies: - "@embroider/macros": ^1.10.0 - ember-cli-babel: ^7.26.11 - checksum: 24983d2aa36cdd2a071abc64c3bece4c031004e5160e90ea8d65486ac6430746f0669c3fc6f1315b85ed401c58b98e910d8da92bc8e84fa11e36b8c9b3fc93c8 - languageName: node - linkType: hard - -"@ember-data/debug@npm:4.11.3": - version: 4.11.3 - resolution: "@ember-data/debug@npm:4.11.3" - dependencies: - "@ember-data/private-build-infra": 4.11.3 + "@ember-data/private-build-infra": 4.12.5 "@ember/edition-utils": ^1.2.0 "@embroider/macros": ^1.10.0 - ember-auto-import: ^2.4.3 + ember-auto-import: ^2.6.1 ember-cli-babel: ^7.26.11 peerDependencies: + "@ember-data/store": 4.12.5 "@ember/string": ^3.0.1 - checksum: 9eac1c756e54e1a397ac7bb8442b2c621c1a6f6d9c07588e9bcaac160f19449fac6cfd2ce01358d4dfa80fdc72b1868f93b56ede9993339853c88b312e70198e + checksum: 2fcca256b2f8e0a5636312df4d4f6b4ac05d95552131d64a96eeef482221ea6426ff5164d9ffcab88e2f5e651010c91f1810d777439a6ba35ae3da6f8b6ef737 languageName: node linkType: hard -"@ember-data/model@npm:4.11.3": - version: 4.11.3 - resolution: "@ember-data/model@npm:4.11.3" +"@ember-data/graph@npm:4.12.5": + version: 4.12.5 + resolution: "@ember-data/graph@npm:4.12.5" dependencies: - "@ember-data/canary-features": 4.11.3 - "@ember-data/private-build-infra": 4.11.3 + "@ember-data/private-build-infra": 4.12.5 + "@ember/edition-utils": ^1.2.0 + "@embroider/macros": ^1.10.0 + ember-cli-babel: ^7.26.11 + peerDependencies: + "@ember-data/store": 4.12.5 + checksum: ed23005e79db2bb68269a168820f69404d60ea11e0c54ac12a8b3b5f156688f4e1d089b932bc8ee4737c4aa6b5dcc00b643ac9bce1ff24847b0f1719cd9bd0d4 + languageName: node + linkType: hard + +"@ember-data/json-api@npm:4.12.5": + version: 4.12.5 + resolution: "@ember-data/json-api@npm:4.12.5" + dependencies: + "@ember-data/private-build-infra": 4.12.5 + "@ember/edition-utils": ^1.2.0 + "@embroider/macros": ^1.10.0 + ember-cli-babel: ^7.26.11 + peerDependencies: + "@ember-data/graph": 4.12.5 + "@ember-data/store": 4.12.5 + checksum: 3b8f3d80f37e706edd829376a6d8184c7169fd1816fe4b91e8a67b142354be74ca3850263f7547f4c81cc51f6bef6c4408f5efd30aa07cfdaeec85f4fa12cf96 + languageName: node + linkType: hard + +"@ember-data/legacy-compat@npm:4.12.5, @ember-data/legacy-compat@npm:~4.12.4": + version: 4.12.5 + resolution: "@ember-data/legacy-compat@npm:4.12.5" + dependencies: + "@ember-data/private-build-infra": 4.12.5 + "@embroider/macros": ^1.10.0 + ember-cli-babel: ^7.26.11 + peerDependencies: + "@ember-data/graph": 4.12.5 + "@ember-data/json-api": 4.12.5 + peerDependenciesMeta: + "@ember-data/graph": + optional: true + "@ember-data/json-api": + optional: true + checksum: e9cfa9f05534217f0eaa433f152251714937fcaead62beaf5e51a59b470bb8cbac4598abd6ba014ed39cd61ce35a033c78f0b9dfcd6c90cb62531ef098dfa8ce + languageName: node + linkType: hard + +"@ember-data/model@npm:4.12.5": + version: 4.12.5 + resolution: "@ember-data/model@npm:4.12.5" + dependencies: + "@ember-data/private-build-infra": 4.12.5 "@ember/edition-utils": ^1.2.0 "@embroider/macros": ^1.10.0 - ember-auto-import: ^2.4.3 ember-cached-decorator-polyfill: ^1.0.1 ember-cli-babel: ^7.26.11 ember-cli-string-utils: ^1.1.0 ember-cli-test-info: ^1.0.0 - ember-compatibility-helpers: ^1.2.6 - inflection: ~2.0.0 + inflection: ~2.0.1 peerDependencies: - "@ember-data/record-data": 4.11.3 - "@ember-data/store": 4.11.3 - "@ember-data/tracking": 4.11.3 + "@ember-data/debug": 4.12.5 + "@ember-data/graph": 4.12.5 + "@ember-data/json-api": 4.12.5 + "@ember-data/legacy-compat": 4.12.5 + "@ember-data/store": 4.12.5 + "@ember-data/tracking": 4.12.5 "@ember/string": ^3.0.1 ember-inflector: ^4.0.2 peerDependenciesMeta: - "@ember-data/record-data": + "@ember-data/debug": optional: true - checksum: 734fd60c6a5bf84d657a86e4aa89f965c5624caf478d0b87d517bec589e3e6db2cba45e46dfcfa5a6506733a94bcf4c2f43daecaa9ad6f06b62a408da2714d13 + "@ember-data/graph": + optional: true + "@ember-data/json-api": + optional: true + checksum: 2d17d16a665fac2c755e65ae690f6ade32d5dfd1d936ef0f1fab031b33977a659212dc384b73a4fb98df229ef254eeba9f3319592e0d4ff19150c6ba2ea67fa6 languageName: node linkType: hard -"@ember-data/private-build-infra@npm:4.11.3": - version: 4.11.3 - resolution: "@ember-data/private-build-infra@npm:4.11.3" +"@ember-data/private-build-infra@npm:4.12.5": + version: 4.12.5 + resolution: "@ember-data/private-build-infra@npm:4.12.5" dependencies: - "@babel/core": ^7.20.2 - "@babel/plugin-transform-block-scoping": ^7.20.2 - "@babel/runtime": ^7.20.1 - "@ember-data/canary-features": 4.11.3 + "@babel/core": ^7.21.4 + "@babel/plugin-transform-block-scoping": ^7.21.0 + "@babel/runtime": ^7.21.0 "@ember/edition-utils": ^1.2.0 "@embroider/macros": ^1.10.0 babel-import-util: ^1.3.0 @@ -5431,29 +5462,23 @@ __metadata: ember-cli-string-utils: ^1.1.0 ember-cli-version-checker: ^5.1.2 git-repo-info: ^2.1.1 - glob: ^8.0.3 + glob: ^9.3.4 npm-git-info: ^1.0.3 - rimraf: ^3.0.2 - rsvp: ^4.8.5 semver: ^7.3.8 silent-error: ^1.1.1 - checksum: a9a1e865de89f7b7fbf9461c511931b03309e41fe1fd32e5b2d4d4fa43fcb62bc89bada264f924fafd86373590cc4834d5052900bddecaa37f0b7fefa36a732d + checksum: 0f16a66c7086ba263af43703e163a3a0d4d4701b3dbd0fd67236ea7247f6950263b878782c137c300610a3fae041f0d037908c435464a55fd2a8462ac6bc8af6 languageName: node linkType: hard -"@ember-data/record-data@npm:4.11.3": - version: 4.11.3 - resolution: "@ember-data/record-data@npm:4.11.3" +"@ember-data/request@npm:4.12.5": + version: 4.12.5 + resolution: "@ember-data/request@npm:4.12.5" dependencies: - "@ember-data/canary-features": 4.11.3 - "@ember-data/private-build-infra": 4.11.3 - "@ember/edition-utils": ^1.2.0 + "@ember-data/private-build-infra": 4.12.5 + "@ember/test-waiters": ^3.0.2 "@embroider/macros": ^1.10.0 - ember-auto-import: ^2.4.3 ember-cli-babel: ^7.26.11 - peerDependencies: - "@ember-data/store": 4.11.3 - checksum: e49caa3e2279d119a9f3668980c8ac7ce49d7fb451d9630b395a4a5b5993ab96c5a6a8230cf08e03711b41027f174dbc0c1819f31489a738670670b2e751f25a + checksum: e812e7a7bef347dcbb7f885ee848f8f47b61ecb6c4f8fc6aee0683da1207e195a04320d34b9766fdac7b9e96b139ab71d18d9200ec07d6bd6703d7d7e11c3fb3 languageName: node linkType: hard @@ -5464,54 +5489,59 @@ __metadata: languageName: node linkType: hard -"@ember-data/serializer@npm:4.11.3": - version: 4.11.3 - resolution: "@ember-data/serializer@npm:4.11.3" +"@ember-data/serializer@npm:4.12.5": + version: 4.12.5 + resolution: "@ember-data/serializer@npm:4.12.5" dependencies: - "@ember-data/private-build-infra": 4.11.3 + "@ember-data/private-build-infra": 4.12.5 "@embroider/macros": ^1.10.0 - ember-auto-import: ^2.4.3 ember-cli-babel: ^7.26.11 ember-cli-test-info: ^1.0.0 peerDependencies: - "@ember-data/store": 4.11.3 + "@ember-data/store": 4.12.5 "@ember/string": ^3.0.1 ember-inflector: ^4.0.2 - checksum: a36dea451165e8bb3aa572366bb13b8af3377ab31239396b741b6912ee155099cb36df8349e69e585a2b12a7250c457e2973d95c43bb1578228e41afd254c0f6 + checksum: ea866f07844987c97e2982e6be9e772182c656ba305562813084618d9eba8d7fd4920b239875aeb9a7473032ccfc8ee8393f1f17de664cd60b1d110f77628d09 languageName: node linkType: hard -"@ember-data/store@npm:4.11.3": - version: 4.11.3 - resolution: "@ember-data/store@npm:4.11.3" +"@ember-data/store@npm:4.12.5": + version: 4.12.5 + resolution: "@ember-data/store@npm:4.12.5" dependencies: - "@ember-data/canary-features": 4.11.3 - "@ember-data/private-build-infra": 4.11.3 + "@ember-data/private-build-infra": 4.12.5 "@embroider/macros": ^1.10.0 - ember-auto-import: ^2.4.3 ember-cached-decorator-polyfill: ^1.0.1 ember-cli-babel: ^7.26.11 peerDependencies: - "@ember-data/model": 4.11.3 - "@ember-data/record-data": 4.11.3 - "@ember-data/tracking": 4.11.3 + "@ember-data/graph": 4.12.5 + "@ember-data/json-api": 4.12.5 + "@ember-data/legacy-compat": 4.12.5 + "@ember-data/model": 4.12.5 + "@ember-data/tracking": 4.12.5 "@ember/string": ^3.0.1 "@glimmer/tracking": ^1.1.2 peerDependenciesMeta: + "@ember-data/graph": + optional: true + "@ember-data/json-api": + optional: true + "@ember-data/legacy-compat": + optional: true "@ember-data/model": optional: true - "@ember-data/record-data": - optional: true - checksum: 132384d5a3c02697f1e1c1599e10d5ffed6f4d73c79ab353cb89b5b533410a906bc238005cde702f57072f2a0a48f885de72d063d593ff7f3620b3bc58763092 + checksum: 3309d4c8960055915d7f8de0ae83cd9dc1d2b6db0e97d2a069a36f8ae99cd2a024a9a577bc86e63267c230b2ba1efba5aa7dfb54d6901f1b2c63dc2f08ebfb54 languageName: node linkType: hard -"@ember-data/tracking@npm:4.11.3": - version: 4.11.3 - resolution: "@ember-data/tracking@npm:4.11.3" +"@ember-data/tracking@npm:4.12.5": + version: 4.12.5 + resolution: "@ember-data/tracking@npm:4.12.5" dependencies: + "@ember-data/private-build-infra": 4.12.5 + "@embroider/macros": ^1.10.0 ember-cli-babel: ^7.26.11 - checksum: c93f00f647769da12206bd4166b85c6bfcf37118acbcecac37357804451b3e9a5ee8bad9aa63c3ec1900013ceadcf2480b06656f0e9caff276ba046fc6be512f + checksum: be07b307f9915b63369d7edb298cb1585f1eed57bb6c9fa45767f1c37ee563605240296cfeea815f87fd5c6957d6aaaa081bc3cd1c37958e0ca216b80465ba64 languageName: node linkType: hard @@ -5646,7 +5676,7 @@ __metadata: languageName: node linkType: hard -"@ember/test-waiters@npm:^2.4.3 || ^3.0.0, @ember/test-waiters@npm:^3.1.0": +"@ember/test-waiters@npm:^2.4.3 || ^3.0.0, @ember/test-waiters@npm:^3.0.2, @ember/test-waiters@npm:^3.1.0": version: 3.1.0 resolution: "@ember/test-waiters@npm:3.1.0" dependencies: @@ -13978,7 +14008,7 @@ __metadata: languageName: node linkType: hard -"ember-auto-import@npm:2.6.3, ember-auto-import@npm:^2.4.3, ember-auto-import@npm:^2.5.0, ember-auto-import@npm:^2.6.3": +"ember-auto-import@npm:2.6.3, ember-auto-import@npm:^2.5.0, ember-auto-import@npm:^2.6.3": version: 2.6.3 resolution: "ember-auto-import@npm:2.6.3" dependencies: @@ -14171,7 +14201,7 @@ __metadata: languageName: node linkType: hard -"ember-auto-import@npm:^2.7.0": +"ember-auto-import@npm:^2.6.1, ember-auto-import@npm:^2.7.0": version: 2.7.2 resolution: "ember-auto-import@npm:2.7.2" dependencies: @@ -15085,7 +15115,7 @@ __metadata: languageName: node linkType: hard -"ember-compatibility-helpers@npm:^1.2.5, ember-compatibility-helpers@npm:^1.2.6": +"ember-compatibility-helpers@npm:^1.2.5": version: 1.2.6 resolution: "ember-compatibility-helpers@npm:1.2.6" dependencies: @@ -15173,28 +15203,31 @@ __metadata: languageName: node linkType: hard -"ember-data@npm:~4.11.3": - version: 4.11.3 - resolution: "ember-data@npm:4.11.3" +"ember-data@npm:~4.12.4": + version: 4.12.5 + resolution: "ember-data@npm:4.12.5" dependencies: - "@ember-data/adapter": 4.11.3 - "@ember-data/debug": 4.11.3 - "@ember-data/model": 4.11.3 - "@ember-data/private-build-infra": 4.11.3 - "@ember-data/record-data": 4.11.3 - "@ember-data/serializer": 4.11.3 - "@ember-data/store": 4.11.3 - "@ember-data/tracking": 4.11.3 + "@ember-data/adapter": 4.12.5 + "@ember-data/debug": 4.12.5 + "@ember-data/graph": 4.12.5 + "@ember-data/json-api": 4.12.5 + "@ember-data/legacy-compat": 4.12.5 + "@ember-data/model": 4.12.5 + "@ember-data/private-build-infra": 4.12.5 + "@ember-data/request": 4.12.5 + "@ember-data/serializer": 4.12.5 + "@ember-data/store": 4.12.5 + "@ember-data/tracking": 4.12.5 "@ember/edition-utils": ^1.2.0 "@embroider/macros": ^1.10.0 "@glimmer/env": ^0.1.7 broccoli-merge-trees: ^4.2.0 - ember-auto-import: ^2.4.3 + ember-auto-import: ^2.6.1 ember-cli-babel: ^7.26.11 ember-inflector: ^4.0.2 peerDependencies: "@ember/string": ^3.0.1 - checksum: b9a9450b7567ec68a64ed4bac9878a2fc603f18a3adba657e04f476f4cef38fc9cdd71838203274f677af0c403a522a70838e9580526ff198e82229da9d7c326 + checksum: c8649d42c534b8038a43bc3fd72bbfc390e39b9fd50f2903ac5aaed2d36cff86a48d6ab418c8055591e9a170cf310fae3cba8ab4d57e7d46bddf45b14b104e67 languageName: node linkType: hard @@ -18271,6 +18304,18 @@ __metadata: languageName: node linkType: hard +"glob@npm:^9.3.4": + version: 9.3.5 + resolution: "glob@npm:9.3.5" + dependencies: + fs.realpath: ^1.0.0 + minimatch: ^8.0.2 + minipass: ^4.2.4 + path-scurry: ^1.6.1 + checksum: 94b093adbc591bc36b582f77927d1fb0dbf3ccc231828512b017601408be98d1fe798fc8c0b19c6f2d1a7660339c3502ce698de475e9d938ccbb69b47b647c84 + languageName: node + linkType: hard + "global-modules@npm:^1.0.0": version: 1.0.0 resolution: "global-modules@npm:1.0.0" @@ -19144,7 +19189,7 @@ __metadata: languageName: node linkType: hard -"inflection@npm:^2.0.1, inflection@npm:~2.0.0": +"inflection@npm:^2.0.1, inflection@npm:~2.0.1": version: 2.0.1 resolution: "inflection@npm:2.0.1" checksum: bb095b495e10a77afc043cc349ae0f7c8c53e4d1fbcd7781111c18d17bde87ce31ea08bd883774bcbb2ff50c301dd4835b5448c80eb50b5e4e080165b6030f3b @@ -21978,7 +22023,7 @@ __metadata: languageName: node linkType: hard -"minipass@npm:^4.0.0": +"minipass@npm:^4.0.0, minipass@npm:^4.2.4": version: 4.2.8 resolution: "minipass@npm:4.2.8" checksum: 7f4914d5295a9a30807cae5227a37a926e6d910c03f315930fde52332cf0575dfbc20295318f91f0baf0e6bb11a6f668e30cde8027dea7a11b9d159867a3c830 @@ -23313,7 +23358,7 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^1.10.1": +"path-scurry@npm:^1.10.1, path-scurry@npm:^1.6.1": version: 1.10.1 resolution: "path-scurry@npm:1.10.1" dependencies: @@ -27893,6 +27938,7 @@ __metadata: "@babel/plugin-proposal-decorators": ^7.21.0 "@babel/plugin-proposal-object-rest-spread": ^7.12.1 "@babel/plugin-transform-block-scoping": ^7.12.1 + "@ember-data/legacy-compat": ~4.12.4 "@ember/legacy-built-in-components": ^0.4.1 "@ember/optional-features": ^2.0.0 "@ember/render-modifiers": ^1.0.2 @@ -27981,7 +28027,7 @@ __metadata: ember-concurrency: 2.3.4 ember-copy: 2.0.1 ember-d3: ^0.5.1 - ember-data: ~4.11.3 + ember-data: ~4.12.4 ember-engines: 0.8.23 ember-exam: ^9.0.0 ember-fetch: ^8.1.2