diff --git a/addons/core/addon/components/form/authenticate/details/index.js b/addons/core/addon/components/form/authenticate/details/index.js index 7a3ab5398..e1d13d887 100644 --- a/addons/core/addon/components/form/authenticate/details/index.js +++ b/addons/core/addon/components/form/authenticate/details/index.js @@ -6,7 +6,6 @@ import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; -import { run } from '@ember/runloop'; export default class FormAuthenticateDetailsComponent extends Component { // =properties @@ -36,7 +35,7 @@ export default class FormAuthenticateDetailsComponent extends Component { */ @action submit(fn, creds) { - run(() => this.resetPassword()); - run(() => fn(creds)); + this.resetPassword(); + fn(creds); } } diff --git a/addons/core/addon/components/loading-button/index.hbs b/addons/core/addon/components/loading-button/index.hbs index 48f2ecda8..2d3c5cb96 100644 --- a/addons/core/addon/components/loading-button/index.hbs +++ b/addons/core/addon/components/loading-button/index.hbs @@ -6,7 +6,7 @@ \ No newline at end of file diff --git a/addons/core/addon/components/loading-button/index.js b/addons/core/addon/components/loading-button/index.js index 2828c5120..d1e45227b 100644 --- a/addons/core/addon/components/loading-button/index.js +++ b/addons/core/addon/components/loading-button/index.js @@ -4,22 +4,13 @@ */ import Component from '@glimmer/component'; -import { tracked } from '@glimmer/tracking'; -import { action } from '@ember/object'; -import { later } from '@ember/runloop'; +import { dropTask, timeout } from 'ember-concurrency'; export default class LoadingButton extends Component { - // =actions - @tracked isLoading = false; + // =attributes - @action - async toggleRefresh() { - this.isLoading = true; - try { - await this.args.onClick(); - } catch (e) { - console.error('Error while loading data', e); - } - later(() => (this.isLoading = false), 1000); - } + toggleRefresh = dropTask(async () => { + await this.args.onClick(); + await timeout(1000); + }); } diff --git a/addons/core/addon/helpers/time-remaining.js b/addons/core/addon/helpers/time-remaining.js index ebd98fb87..72e5b5610 100644 --- a/addons/core/addon/helpers/time-remaining.js +++ b/addons/core/addon/helpers/time-remaining.js @@ -19,10 +19,10 @@ export default class extends Helper { // Parse the expiration time const expirationTime = new Date(expiration_time); - // Get the curent time + // Get the current time const currentTime = this.clockTick.now; - // Calculate the difference in milleseconds + // Calculate the difference in milliseconds const difference = expirationTime - currentTime; // Calculate the difference in seconds if the difference is positive diff --git a/addons/core/addon/services/clock-tick.js b/addons/core/addon/services/clock-tick.js index a2b16d217..04410d65b 100644 --- a/addons/core/addon/services/clock-tick.js +++ b/addons/core/addon/services/clock-tick.js @@ -6,7 +6,7 @@ import Service from '@ember/service'; import { tracked } from '@glimmer/tracking'; import { getOwner } from '@ember/application'; -import { next } from '@ember/runloop'; +import { task, timeout } from 'ember-concurrency'; export default class ClockTickService extends Service { // =attributes @@ -25,9 +25,15 @@ export default class ClockTickService extends Service { frequency = 1000; /** - * The timer interval ID + * Updates the value of `now` every `frequency` milliseconds. */ - #timer; + _tick = task(async () => { + // eslint-disable-next-line no-constant-condition + while (true) { + await timeout(this.frequency); + this.now = Date.now(); + } + }); /** * This service is enabled only in non-test environments. @@ -45,7 +51,7 @@ export default class ClockTickService extends Service { */ constructor() { super(...arguments); - if (this.enabled) this._start(); + if (this.enabled) this._tick.perform(); } /** @@ -53,31 +59,6 @@ export default class ClockTickService extends Service { */ willDestroy() { super.willDestroy(...arguments); - this._stop(); - } - - /** - * Sets up the timer interval, calling `_tick()` every - * `frequency` milliseconds. - */ - _start() { - const self = this; - this.#timer = setInterval(function () { - self._tick(); - }, this.frequency); - } - - /** - * Clears the timer interval. - */ - _stop() { - clearInterval(this.#timer); - } - - /** - * Updates the value of `now` within the next runloop. - */ - _tick() { - next(() => (this.now = Date.now())); + this._tick.cancelAll(); } } diff --git a/addons/core/ember-cli-build.js b/addons/core/ember-cli-build.js index bd89a3103..33e53c525 100644 --- a/addons/core/ember-cli-build.js +++ b/addons/core/ember-cli-build.js @@ -14,6 +14,11 @@ module.exports = function (defaults) { 'ember-simple-auth': { useSessionSetupMethod: true, }, + babel: { + plugins: [ + require.resolve('ember-concurrency/async-arrow-task-transform'), + ], + }, }); /* diff --git a/addons/core/index.js b/addons/core/index.js index 1760d1a66..684173c84 100644 --- a/addons/core/index.js +++ b/addons/core/index.js @@ -10,6 +10,14 @@ var path = require('path'); module.exports = { name: require('./package').name, + options: { + babel: { + plugins: [ + require.resolve('ember-concurrency/async-arrow-task-transform'), + ], + }, + }, + included(app) { this._super.included.apply(this, arguments); this.includePublic(app); diff --git a/addons/core/package.json b/addons/core/package.json index 8f75a7dea..fb77460c6 100644 --- a/addons/core/package.json +++ b/addons/core/package.json @@ -39,6 +39,7 @@ "ember-cli-babel": "^8.2.0", "ember-cli-htmlbars": "^6.2.0", "ember-cli-sass": "^11.0.1", + "ember-concurrency": "^4.0.3", "ember-feature-flags": "^6.0.0", "ember-intl": "^7.0.7", "ember-loading": "^2.0.0", diff --git a/ui/admin/app/components/form/account/password/change-password/index.js b/ui/admin/app/components/form/account/password/change-password/index.js index 2f8f7063f..63ce014ff 100644 --- a/ui/admin/app/components/form/account/password/change-password/index.js +++ b/ui/admin/app/components/form/account/password/change-password/index.js @@ -5,9 +5,7 @@ import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; -import { computed } from '@ember/object'; import { action } from '@ember/object'; -import { run } from '@ember/runloop'; export default class FormAccountPasswordChangePasswordIndexComponent extends Component { // =properties @@ -25,7 +23,6 @@ export default class FormAccountPasswordChangePasswordIndexComponent extends Com /** * @type {boolean} */ - @computed('currentPassword', 'newPassword') get canSave() { return this.currentPassword && this.newPassword; } @@ -33,7 +30,6 @@ export default class FormAccountPasswordChangePasswordIndexComponent extends Com /** * @type {boolean} */ - @computed('canSave') get cannotSave() { return !this.canSave; } @@ -41,7 +37,7 @@ export default class FormAccountPasswordChangePasswordIndexComponent extends Com // =methods /** - * Unsets the password fields. + * Un-sets the password fields. */ resetPasswords() { this.currentPassword = null; @@ -52,15 +48,15 @@ export default class FormAccountPasswordChangePasswordIndexComponent extends Com /** * Call passed submit function with passwords. - * Unset passwords before callack. + * Unset passwords before callback. * @param {function} fn * @param {string} currentPassword * @param {string} newPassword */ @action submit(fn, currentPassword, newPassword) { - run(() => this.resetPasswords()); - run(() => fn(currentPassword, newPassword)); + this.resetPasswords(); + fn(currentPassword, newPassword); } /** diff --git a/ui/admin/app/components/form/account/password/index.js b/ui/admin/app/components/form/account/password/index.js index e764e8b74..1dc6d12be 100644 --- a/ui/admin/app/components/form/account/password/index.js +++ b/ui/admin/app/components/form/account/password/index.js @@ -6,7 +6,6 @@ import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; -import { next } from '@ember/runloop'; export default class FormAccountPasswordIndexComponent extends Component { // =properties @@ -36,7 +35,7 @@ export default class FormAccountPasswordIndexComponent extends Component { @action submit(fn) { const password = this.password; - next(() => this.resetPassword()); + this.resetPassword(); return this.args.model.isNew ? fn(password) : fn(); } } diff --git a/ui/admin/app/components/form/account/password/set-password/index.js b/ui/admin/app/components/form/account/password/set-password/index.js index 295f03c0d..f64704d0d 100644 --- a/ui/admin/app/components/form/account/password/set-password/index.js +++ b/ui/admin/app/components/form/account/password/set-password/index.js @@ -5,9 +5,7 @@ import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; -import { computed } from '@ember/object'; import { action } from '@ember/object'; -import { run } from '@ember/runloop'; export default class FormAccountPasswordSetPasswordIndexComponent extends Component { // =properties @@ -21,7 +19,6 @@ export default class FormAccountPasswordSetPasswordIndexComponent extends Compon /** * @type {boolean} */ - @computed('password') get cannotSave() { return !this.password; } @@ -45,7 +42,7 @@ export default class FormAccountPasswordSetPasswordIndexComponent extends Compon */ @action submit(fn, password) { - run(() => this.resetPassword()); - run(() => fn(password)); + this.resetPassword(); + fn(password); } } diff --git a/ui/admin/app/routes/scopes/scope/authenticate/method/oidc.js b/ui/admin/app/routes/scopes/scope/authenticate/method/oidc.js index a2a729bc6..ff7f9ad6e 100644 --- a/ui/admin/app/routes/scopes/scope/authenticate/method/oidc.js +++ b/ui/admin/app/routes/scopes/scope/authenticate/method/oidc.js @@ -7,7 +7,7 @@ import Route from '@ember/routing/route'; import { getOwner } from '@ember/application'; import { inject as service } from '@ember/service'; import { action } from '@ember/object'; -import runEvery from 'ember-pollster/decorators/route/run-every'; +import { task, timeout } from 'ember-concurrency'; import { notifyError } from 'core/decorators/notify'; import config from '../../../../../config/environment'; @@ -20,6 +20,15 @@ export default class ScopesScopeAuthenticateMethodOidcRoute extends Route { @service windowManager; @service router; + // =attributes + + poller = task(async () => { + while (!this.session.isAuthenticated) { + await timeout(POLL_TIMEOUT_SECONDS * 1000); + this.refresh(); + } + }); + // =methods beforeModel; @@ -43,9 +52,11 @@ export default class ScopesScopeAuthenticateMethodOidcRoute extends Route { controller.authMethod = authMethod; } - @runEvery(POLL_TIMEOUT_SECONDS * 1000) - poller() { - this.refresh(); + /** + * When this route is activated (entered), start polling for authentication. + */ + activate() { + this.poller.perform(); } /** @@ -53,6 +64,7 @@ export default class ScopesScopeAuthenticateMethodOidcRoute extends Route { * any windows opened via the window manager service. */ deactivate() { + this.poller.cancelAll(); this.windowManager.closeAll(); } diff --git a/ui/admin/config/environment.js b/ui/admin/config/environment.js index 2d675b3e7..256371f15 100644 --- a/ui/admin/config/environment.js +++ b/ui/admin/config/environment.js @@ -52,7 +52,6 @@ module.exports = function (environment) { appName: APP_NAME, companyName: 'HashiCorp', - sessionPollingTimeoutSeconds: 300, oidcPollingTimeoutSeconds: 1, documentation: { @@ -195,6 +194,8 @@ module.exports = function (environment) { // Notification timeout should be 0 for fast tests ENV.flashMessageDefaults.timeout = 0; + // OIDC Authentication timeout should be 0 for fast tests + ENV.oidcPollingTimeoutSeconds = 0; ENV.enableConfirmService = false; } diff --git a/ui/admin/ember-cli-build.js b/ui/admin/ember-cli-build.js index 91d853043..e4cfcebc3 100644 --- a/ui/admin/ember-cli-build.js +++ b/ui/admin/ember-cli-build.js @@ -18,6 +18,9 @@ module.exports = function (defaults) { }, babel: { sourceMaps: 'inline', + plugins: [ + require.resolve('ember-concurrency/async-arrow-task-transform'), + ], }, sourcemaps: { enabled: true, @@ -34,7 +37,7 @@ module.exports = function (defaults) { }, }, // TODO: Update to 4.12 when deprecations are resolved - // as multiple things break when forcing compatability on > 4.6 + // as multiple things break when forcing compatibility on > 4.6 emberData: { compatWith: '4.6', }, diff --git a/ui/admin/package.json b/ui/admin/package.json index de72f3653..24f583d73 100644 --- a/ui/admin/package.json +++ b/ui/admin/package.json @@ -71,12 +71,12 @@ "ember-cli-sass": "^11.0.1", "ember-cli-sri": "^2.1.1", "ember-cli-terser": "^4.0.2", + "ember-concurrency": "^4.0.3", "ember-exam": "^8.0.0", "ember-inline-svg": "^1.0.1", "ember-load-initializers": "^2.1.2", "ember-modifier": "^4.1.0", "ember-page-title": "^7.0.0", - "ember-pollster": "https://github.com/hashicorp/ember-pollster.git#605d82e986d829b098667e4a5e221877a4ee4ac8", "ember-qunit": "^8.1.0", "ember-resolver": "^10.0.0", "ember-source": "~4.12.0", diff --git a/ui/admin/tests/acceptance/authentication-test.js b/ui/admin/tests/acceptance/authentication-test.js index 949f9e415..dd52710a2 100644 --- a/ui/admin/tests/acceptance/authentication-test.js +++ b/ui/admin/tests/acceptance/authentication-test.js @@ -16,7 +16,6 @@ import { setupApplicationTest } from 'admin/tests/helpers'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import { setupIndexedDb } from 'api/test-support/helpers/indexed-db'; import { Response } from 'miragejs'; -import { runAllJobs } from 'ember-pollster/test-support'; import a11yAudit from 'ember-a11y-testing/test-support/audit'; import { currentSession, @@ -86,7 +85,7 @@ module('Acceptance | authentication', function (hooks) { }, 'withChildren', ); - // create an emtpy org with no auth methods + // create an empty org with no auth methods this.server.create( 'scope', { @@ -391,9 +390,6 @@ module('Acceptance | authentication', function (hooks) { ); await visit(authMethodOIDCAuthenticateURL); await click('form [type="submit"]'); - // explicitly poll multiple times to trigger mock OIDC auth - await runAllJobs(); - await runAllJobs(); }); // TODO: test OIDC retry and cancel diff --git a/ui/desktop/app/components/settings-card/client-agent/index.js b/ui/desktop/app/components/settings-card/client-agent/index.js index f75d5ff08..5cf787388 100644 --- a/ui/desktop/app/components/settings-card/client-agent/index.js +++ b/ui/desktop/app/components/settings-card/client-agent/index.js @@ -63,6 +63,8 @@ export default class SettingsCardClientAgentComponent extends Component { } else { await this.ipc.invoke('resumeClientAgent'); } - await this.router.refresh('scopes.scope.projects.settings'); + // Refresh projects page in order to stop or start + // polling when client agent status changes. + await this.router.refresh('scopes.scope.projects'); } } diff --git a/ui/desktop/app/routes/scopes/scope/authenticate/method/oidc.js b/ui/desktop/app/routes/scopes/scope/authenticate/method/oidc.js index 1ca7eccc3..d55a08409 100644 --- a/ui/desktop/app/routes/scopes/scope/authenticate/method/oidc.js +++ b/ui/desktop/app/routes/scopes/scope/authenticate/method/oidc.js @@ -7,7 +7,7 @@ import Route from '@ember/routing/route'; import { getOwner } from '@ember/application'; import { inject as service } from '@ember/service'; import { action } from '@ember/object'; -import runEvery from 'ember-pollster/decorators/route/run-every'; +import { task, timeout } from 'ember-concurrency'; import { notifyError } from 'core/decorators/notify'; import config from '../../../../../config/environment'; @@ -19,6 +19,15 @@ export default class ScopesScopeAuthenticateMethodOidcRoute extends Route { @service session; @service router; + // =attributes + + poller = task(async () => { + while (!this.session.isAuthenticated) { + await timeout(POLL_TIMEOUT_SECONDS * 1000); + this.refresh(); + } + }); + // =methods model() { @@ -41,9 +50,19 @@ export default class ScopesScopeAuthenticateMethodOidcRoute extends Route { controller.authMethod = authMethod; } - @runEvery(POLL_TIMEOUT_SECONDS * 1000) - poller() { - this.refresh(); + /** + * When this route is activated (entered), start polling for authentication. + */ + activate() { + this.poller.perform(); + } + + /** + * When this route is deactivated (exited), stop polling for changes and close + * any windows opened via the window manager service. + */ + deactivate() { + this.poller.cancelAll(); } /** diff --git a/ui/desktop/app/routes/scopes/scope/projects.js b/ui/desktop/app/routes/scopes/scope/projects.js index bbbe26d42..60805045e 100644 --- a/ui/desktop/app/routes/scopes/scope/projects.js +++ b/ui/desktop/app/routes/scopes/scope/projects.js @@ -5,7 +5,10 @@ import Route from '@ember/routing/route'; import { inject as service } from '@ember/service'; +import { restartableTask, timeout } from 'ember-concurrency'; +import config from '../../../config/environment'; +const POLL_TIMEOUT_SECONDS = config.sessionPollingTimeoutSeconds; const { __electronLog } = globalThis; /** @@ -23,10 +26,6 @@ const { __electronLog } = globalThis; * It no longer makes sense as a dedicated route. */ export default class ScopesScopeProjectsRoute extends Route { - // =attributes - - job; - // =services @service session; @@ -36,7 +35,6 @@ export default class ScopesScopeProjectsRoute extends Route { @service intl; @service ipc; @service clientAgentSessions; - @service pollster; @service flashMessages; // =methods @@ -53,17 +51,13 @@ export default class ScopesScopeProjectsRoute extends Route { * @return {Promise} */ async model() { - // Setup the poller job - if (!this.job) { - this.boundPoller = this.poller.bind(this); - this.job = this.pollster.findOrCreateJob(this.boundPoller, 2000); - } - const isClientAgentRunning = await this.ipc.invoke('isClientAgentRunning'); if (isClientAgentRunning) { - this.job.start(); + this.poller.perform(); + // start polling task } else { - this.job.stop(); + this.poller.cancelAll(); + // cancel polling job } const { id: scope_id } = this.modelFor('scopes.scope'); @@ -75,42 +69,48 @@ export default class ScopesScopeProjectsRoute extends Route { return projects; } - willDestroy() { - this.job?.stop(); - super.willDestroy(); + /** + * Cancel poller task instances when exiting this route. + */ + deactivate() { + this.poller.cancelAll(); } /** * Poll for new sessions with credentials. Sends a notification for each new session that has a credential. */ - async poller() { + poller = restartableTask(async () => { let sessions; - try { - sessions = await this.clientAgentSessions.getNewSessionsWithCredentials(); - } catch (e) { - // If we're unauthenticated, try and re-authenticate - if (e.statusCode === 401 || e.statusCode === 403) { - const sessionData = this.session.data?.authenticated; - const auth_token_id = sessionData?.id; - const token = sessionData?.token; + // We use a while loop to poll for new sessions from the client agent. + // eslint-disable-next-line no-constant-condition + while (true) { + try { + sessions = + await this.clientAgentSessions.getNewSessionsWithCredentials(); + } catch (e) { + // If we're unauthenticated, try and re-authenticate + if (e.statusCode === 401 || e.statusCode === 403) { + const sessionData = this.session.data?.authenticated; + const auth_token_id = sessionData?.id; + const token = sessionData?.token; - try { - await this.ipc.invoke('addTokenToDaemons', { - tokenId: auth_token_id, - token, - }); - this.job.start(); - __electronLog?.info('Starting polling of new sessions again'); - return; - } catch (e) { - __electronLog?.error('Failed to add token to daemons', e.message); - // If it fails again, just let the poller be killed + try { + await this.ipc.invoke('addTokenToDaemons', { + tokenId: auth_token_id, + token, + }); + + __electronLog?.info('Starting polling of new sessions again'); + this.poller.perform(); + return; + } catch (e) { + __electronLog?.error('Failed to add token to daemons', e.message); + // If it fails again, just let the poller be killed + } } - } - __electronLog?.error('Failed to get new Sessions', e.message); - if (this.job) { + __electronLog?.error('Failed to get new Sessions', e.message); this.flashMessages.danger( this.intl.t('errors.client-agent-failed.sessions'), { @@ -120,46 +120,46 @@ export default class ScopesScopeProjectsRoute extends Route { }, ); - // Kill the poller if we get an error - this.job.stop(); __electronLog?.info('Stopping polling of new sessions'); + return; } - return; + sessions.forEach((session) => { + new window.Notification( + this.intl.t('notifications.connected-to-target.title', { + target: session.alias, + }), + { + body: this.intl.t('notifications.connected-to-target.description'), + // This only has an effect on windows + requireInteraction: true, + }, + ).onclick = async () => { + let orgScope = 'global'; + + try { + const aliases = await this.store.query('alias', { + scope_id: 'global', + force_refresh: true, + }); + const alias = aliases.find( + (alias) => alias.value === session.alias, + ); + + const target = await this.store.findRecord( + 'target', + alias.destination_id, + ); + orgScope = target.scope.parent_scope_id; + } catch (e) { + // Do nothing and default scope to global if an error occurs + } + + window.location.href = `serve://boundary/#/scopes/${orgScope}/projects/sessions/${session.session_authorization.session_id}`; + await this.ipc.invoke('focusWindow'); + }; + }); + await timeout(POLL_TIMEOUT_SECONDS * 1000); } - - sessions.forEach((session) => { - new window.Notification( - this.intl.t('notifications.connected-to-target.title', { - target: session.alias, - }), - { - body: this.intl.t('notifications.connected-to-target.description'), - // This only has an effect on windows - requireInteraction: true, - }, - ).onclick = async () => { - let orgScope = 'global'; - - try { - const aliases = await this.store.query('alias', { - scope_id: 'global', - force_refresh: true, - }); - const alias = aliases.find((alias) => alias.value === session.alias); - - const target = await this.store.findRecord( - 'target', - alias.destination_id, - ); - orgScope = target.scope.parent_scope_id; - } catch (e) { - // Do nothing and default scope to global if an error occurs - } - - window.location.href = `serve://boundary/#/scopes/${orgScope}/projects/sessions/${session.session_authorization.session_id}`; - await this.ipc.invoke('focusWindow'); - }; - }); - } + }); } diff --git a/ui/desktop/config/environment.js b/ui/desktop/config/environment.js index 7a4641079..f240a6ca8 100644 --- a/ui/desktop/config/environment.js +++ b/ui/desktop/config/environment.js @@ -43,8 +43,8 @@ module.exports = function (environment) { appName: APP_NAME, - sessionPollingTimeoutSeconds: 300, oidcPollingTimeoutSeconds: 1, + sessionPollingTimeoutSeconds: 2, documentation: { baseURL: 'https://developer.hashicorp.com/boundary', @@ -94,6 +94,10 @@ module.exports = function (environment) { // Notification timeout should be 0 for fast tests ENV.flashMessageDefaults.timeout = 0; + // OIDC Authentication timeout should be 0 for fast tests + ENV.oidcPollingTimeoutSeconds = 0; + // Sessions polling timeout should be 0 for fast tests + ENV.sessionPollingTimeoutSeconds = 0; ENV.enableConfirmService = false; diff --git a/ui/desktop/ember-cli-build.js b/ui/desktop/ember-cli-build.js index d06785927..badd6fc75 100644 --- a/ui/desktop/ember-cli-build.js +++ b/ui/desktop/ember-cli-build.js @@ -18,6 +18,9 @@ module.exports = function (defaults) { }, babel: { sourceMaps: 'inline', + plugins: [ + require.resolve('ember-concurrency/async-arrow-task-transform'), + ], }, sourcemaps: { enabled: true, diff --git a/ui/desktop/package.json b/ui/desktop/package.json index 60eb3f665..ab4f79940 100644 --- a/ui/desktop/package.json +++ b/ui/desktop/package.json @@ -76,13 +76,13 @@ "ember-cli-sass": "^11.0.1", "ember-cli-sri": "^2.1.1", "ember-cli-terser": "^4.0.2", + "ember-concurrency": "^4.0.3", "ember-electron": "^4.2.2", "ember-exam": "^8.0.0", "ember-inline-svg": "^1.0.1", "ember-load-initializers": "^2.1.2", "ember-modifier": "^4.1.0", "ember-page-title": "^7.0.0", - "ember-pollster": "https://github.com/hashicorp/ember-pollster.git#605d82e986d829b098667e4a5e221877a4ee4ac8", "ember-qunit": "^8.1.0", "ember-resolver": "^10.0.0", "ember-source": "~4.12.0", diff --git a/yarn.lock b/yarn.lock index 0dfa50a9a..020535b9b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -812,6 +812,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-imports@npm:^7.22.15, @babel/helper-module-imports@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-module-imports@npm:7.25.9" + dependencies: + "@babel/traverse": "npm:^7.25.9" + "@babel/types": "npm:^7.25.9" + checksum: 10c0/078d3c2b45d1f97ffe6bb47f61961be4785d2342a4156d8b42c92ee4e1b7b9e365655dd6cb25329e8fe1a675c91eeac7e3d04f0c518b67e417e29d6e27b6aa70 + languageName: node + linkType: hard + "@babel/helper-module-imports@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-module-imports@npm:7.22.5" @@ -831,16 +841,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.25.9": - version: 7.25.9 - resolution: "@babel/helper-module-imports@npm:7.25.9" - dependencies: - "@babel/traverse": "npm:^7.25.9" - "@babel/types": "npm:^7.25.9" - checksum: 10c0/078d3c2b45d1f97ffe6bb47f61961be4785d2342a4156d8b42c92ee4e1b7b9e365655dd6cb25329e8fe1a675c91eeac7e3d04f0c518b67e417e29d6e27b6aa70 - languageName: node - linkType: hard - "@babel/helper-module-transforms@npm:^7.14.5": version: 7.15.0 resolution: "@babel/helper-module-transforms@npm:7.15.0" @@ -4409,6 +4409,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.12.13, @babel/types@npm:^7.8.3": + version: 7.26.9 + resolution: "@babel/types@npm:7.26.9" + dependencies: + "@babel/helper-string-parser": "npm:^7.25.9" + "@babel/helper-validator-identifier": "npm:^7.25.9" + checksum: 10c0/999c56269ba00e5c57aa711fbe7ff071cd6990bafd1b978341ea7572cc78919986e2aa6ee51dacf4b6a7a6fa63ba4eb3f1a03cf55eee31b896a56d068b895964 + languageName: node + linkType: hard + "@babel/types@npm:^7.14.5, @babel/types@npm:^7.14.8, @babel/types@npm:^7.15.0, @babel/types@npm:^7.4.4, @babel/types@npm:^7.7.2": version: 7.15.0 resolution: "@babel/types@npm:7.15.0" @@ -4472,16 +4482,6 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.8.3": - version: 7.26.9 - resolution: "@babel/types@npm:7.26.9" - dependencies: - "@babel/helper-string-parser": "npm:^7.25.9" - "@babel/helper-validator-identifier": "npm:^7.25.9" - checksum: 10c0/999c56269ba00e5c57aa711fbe7ff071cd6990bafd1b978341ea7572cc78919986e2aa6ee51dacf4b6a7a6fa63ba4eb3f1a03cf55eee31b896a56d068b895964 - languageName: node - linkType: hard - "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -7187,13 +7187,13 @@ __metadata: ember-cli-sass: "npm:^11.0.1" ember-cli-sri: "npm:^2.1.1" ember-cli-terser: "npm:^4.0.2" + ember-concurrency: "npm:^4.0.3" ember-exam: "npm:^8.0.0" ember-inline-svg: "npm:^1.0.1" ember-load-initializers: "npm:^2.1.2" ember-modifier: "npm:^4.1.0" ember-named-blocks-polyfill: "npm:^0.2.5" ember-page-title: "npm:^7.0.0" - ember-pollster: "https://github.com/hashicorp/ember-pollster.git#605d82e986d829b098667e4a5e221877a4ee4ac8" ember-qunit: "npm:^8.1.0" ember-resolver: "npm:^10.0.0" ember-source: "npm:~4.12.0" @@ -10090,6 +10090,7 @@ __metadata: ember-cli-sass: "npm:^11.0.1" ember-cli-sri: "npm:^2.1.1" ember-cli-terser: "npm:^4.0.2" + ember-concurrency: "npm:^4.0.3" ember-feature-flags: "npm:^6.0.0" ember-inline-svg: "npm:^1.0.1" ember-intl: "npm:^7.0.7" @@ -10488,7 +10489,7 @@ __metadata: languageName: node linkType: hard -"decorator-transforms@npm:^1.1.0": +"decorator-transforms@npm:^1.0.1, decorator-transforms@npm:^1.1.0": version: 1.2.1 resolution: "decorator-transforms@npm:1.2.1" dependencies: @@ -10649,6 +10650,7 @@ __metadata: ember-cli-sass: "npm:^11.0.1" ember-cli-sri: "npm:^2.1.1" ember-cli-terser: "npm:^4.0.2" + ember-concurrency: "npm:^4.0.3" ember-electron: "npm:^4.2.2" ember-exam: "npm:^8.0.0" ember-inline-svg: "npm:^1.0.1" @@ -10656,7 +10658,6 @@ __metadata: ember-modifier: "npm:^4.1.0" ember-named-blocks-polyfill: "npm:^0.2.5" ember-page-title: "npm:^7.0.0" - ember-pollster: "https://github.com/hashicorp/ember-pollster.git#605d82e986d829b098667e4a5e221877a4ee4ac8" ember-qunit: "npm:^8.1.0" ember-resolver: "npm:^10.0.0" ember-source: "npm:~4.12.0" @@ -11167,7 +11168,7 @@ __metadata: languageName: node linkType: hard -"ember-cli-babel@npm:^7.10.0, ember-cli-babel@npm:^7.11.1, ember-cli-babel@npm:^7.13.0, ember-cli-babel@npm:^7.19.0, ember-cli-babel@npm:^7.21.0, ember-cli-babel@npm:^7.22.1, ember-cli-babel@npm:^7.23.0, ember-cli-babel@npm:^7.26.11, ember-cli-babel@npm:^7.26.3, ember-cli-babel@npm:^7.26.5, ember-cli-babel@npm:^7.26.6, ember-cli-babel@npm:^7.26.8, ember-cli-babel@npm:^7.7.3": +"ember-cli-babel@npm:^7.10.0, ember-cli-babel@npm:^7.11.1, ember-cli-babel@npm:^7.13.0, ember-cli-babel@npm:^7.19.0, ember-cli-babel@npm:^7.21.0, ember-cli-babel@npm:^7.22.1, ember-cli-babel@npm:^7.23.0, ember-cli-babel@npm:^7.26.11, ember-cli-babel@npm:^7.26.3, ember-cli-babel@npm:^7.26.5, ember-cli-babel@npm:^7.26.6, ember-cli-babel@npm:^7.7.3": version: 7.26.11 resolution: "ember-cli-babel@npm:7.26.11" dependencies: @@ -11933,6 +11934,26 @@ __metadata: languageName: node linkType: hard +"ember-concurrency@npm:^4.0.3": + version: 4.0.3 + resolution: "ember-concurrency@npm:4.0.3" + dependencies: + "@babel/helper-module-imports": "npm:^7.22.15" + "@babel/helper-plugin-utils": "npm:^7.12.13" + "@babel/types": "npm:^7.12.13" + "@embroider/addon-shim": "npm:^1.8.7" + decorator-transforms: "npm:^1.0.1" + peerDependencies: + "@glimmer/tracking": ^1.1.2 + "@glint/template": ">= 1.0.0" + ember-source: ^3.28.0 || ^4.0.0 || >=5.0.0 + peerDependenciesMeta: + "@glint/template": + optional: true + checksum: 10c0/01fd3b6b3358f185ee8df7667803044d9a0c13f5e8500c2c8c8b478632a070e03fd7372a2e557ec5fcd605bb34b1f2edea9d3e0968a222a1b1c2d0bce9a9bff3 + languageName: node + linkType: hard + "ember-cookies@npm:^1.0.0, ember-cookies@npm:^1.2.0": version: 1.2.0 resolution: "ember-cookies@npm:1.2.0" @@ -12304,16 +12325,6 @@ __metadata: languageName: node linkType: hard -"ember-pollster@https://github.com/hashicorp/ember-pollster.git#605d82e986d829b098667e4a5e221877a4ee4ac8": - version: 0.0.1-beta.2 - resolution: "ember-pollster@https://github.com/hashicorp/ember-pollster.git#commit=605d82e986d829b098667e4a5e221877a4ee4ac8" - dependencies: - ember-cli-babel: "npm:^7.26.8" - ember-cli-htmlbars: "npm:^6.0.1" - checksum: 10c0/0e1b6e8b9ef466d864d01e63a5c58b9ccd81ea5d1e71402a5bd74d010f52a40bd9d257c2c9adf3ccd7f383327e8ffaa1b4ec73980afb6ddd4b1e18676ab099c4 - languageName: node - linkType: hard - "ember-power-select@npm:^8.2.0": version: 8.2.0 resolution: "ember-power-select@npm:8.2.0"