diff --git a/.vscode/settings.json b/.vscode/settings.json index 25fa6215..95fbfac4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "typescript.tsdk": "node_modules/typescript/lib" -} + "typescript.tsdk": "node_modules/typescript/lib", + "glint.libraryPath": "./ember-async-data" +} \ No newline at end of file diff --git a/ember-async-data/.eslintrc.cjs b/ember-async-data/.eslintrc.cjs index 1e4f0c86..1df6c1bd 100644 --- a/ember-async-data/.eslintrc.cjs +++ b/ember-async-data/.eslintrc.cjs @@ -7,11 +7,7 @@ module.exports = { ecmaVersion: 'latest', }, plugins: ['ember'], - extends: [ - 'eslint:recommended', - 'plugin:ember/recommended', - 'plugin:prettier/recommended', - ], + extends: ['eslint:recommended', 'plugin:ember/recommended', 'prettier'], env: { browser: true, }, diff --git a/ember-async-data/.prettierrc.js b/ember-async-data/.prettierrc.js index df5c6e8f..3fd864db 100644 --- a/ember-async-data/.prettierrc.js +++ b/ember-async-data/.prettierrc.js @@ -9,4 +9,5 @@ module.exports = { }, }, ], + plugins: ['prettier-plugin-ember-template-tag'], }; diff --git a/ember-async-data/babel.config.json b/ember-async-data/babel.config.json index cd53605c..6561fa9a 100644 --- a/ember-async-data/babel.config.json +++ b/ember-async-data/babel.config.json @@ -1,6 +1,7 @@ { "presets": [["@babel/preset-typescript"]], "plugins": [ + "ember-template-imports/src/babel-plugin", "@embroider/addon-dev/template-colocation-plugin", ["@babel/plugin-transform-typescript", { "allowDeclareFields": true }], ["@babel/plugin-proposal-decorators", { "version": "legacy" }], diff --git a/ember-async-data/package.json b/ember-async-data/package.json index 4c0a14fd..e6bc43f8 100644 --- a/ember-async-data/package.json +++ b/ember-async-data/package.json @@ -25,8 +25,10 @@ "lint:fix": "concurrently 'npm:lint:*:fix' --names 'fix:'", "lint:hbs": "ember-template-lint . --no-error-on-unmatched-pattern", "lint:js": "eslint . --cache", + "lint:prettier": "prettier . --check", "lint:hbs:fix": "ember-template-lint . --fix --no-error-on-unmatched-pattern", "lint:js:fix": "eslint . --fix", + "lint:prettier:fix": "prettier . --write", "lint:types": "glint", "start": "concurrently 'npm:start:*'", "start:js": "rollup --config --watch --no-watch.clearScreen", @@ -47,16 +49,17 @@ "@embroider/addon-dev": "^4.1.0", "@glimmer/component": "^1.1.2", "@glimmer/tracking": "^1.1.2", - "@glint/core": "^1.0.2", - "@glint/environment-ember-loose": "^1.0.2", - "@glint/template": "^1.0.2", + "@glint/core": "^1.1.0", + "@glint/environment-ember-loose": "^1.1.0", + "@glint/environment-ember-template-imports": "^1.1.0", + "@glint/template": "^1.1.0", "@rollup/plugin-babel": "^6.0.3", "@rollup/plugin-node-resolve": "^15.1.0", "@tsconfig/ember": "^2.0.0", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", "concurrently": "^8.2.0", - "ember-source": "^4.12.3", + "ember-source": "^5.2.0", "ember-template-lint": "^5.11.2", "eslint": "^8.46.0", "eslint-config-prettier": "^8.8.0", @@ -64,7 +67,8 @@ "eslint-plugin-n": "^16.1.0", "eslint-plugin-prettier": "^4.2.1", "expect-type": "^0.16.0", - "prettier": "^2.8.8", + "prettier": "^3.0.3", + "prettier-plugin-ember-template-tag": "^1.1.0", "rollup": "^3.28.0", "typescript": "~5.2.2" }, diff --git a/ember-async-data/rollup-plugin-template-tag.mjs b/ember-async-data/rollup-plugin-template-tag.mjs new file mode 100644 index 00000000..530ec3e5 --- /dev/null +++ b/ember-async-data/rollup-plugin-template-tag.mjs @@ -0,0 +1,75 @@ +import fs from "node:fs/promises"; +import path from "node:path"; +import { preprocessEmbeddedTemplates } from "ember-template-imports/lib/preprocess-embedded-templates.js"; +import { + TEMPLATE_TAG_NAME, + TEMPLATE_TAG_PLACEHOLDER, +} from "ember-template-imports/lib/util.js"; + +export default function firstClassComponentTemplates() { + return { + name: "preprocess-fccts", + async resolveId(source, importer, options) { + if (source.endsWith(".hbs")) return; + + for (let ext of ["", ".gjs", ".gts"]) { + let result = await this.resolve(source + ext, importer, { + ...options, + skipSelf: true, + }); + + if (result?.external) { + return; + } + + if (FCCT_EXTENSION.test(result?.id)) { + return resolutionFor(result.id); + } + } + }, + + async load(id) { + let originalId = this.getModuleInfo(id)?.meta?.fccts?.originalId ?? id; + + if (originalId !== id) { + this.addWatchFile(originalId); + } + + if (FCCT_EXTENSION.test(originalId)) { + return await preprocessTemplates(originalId); + } + }, + }; +} + +const FCCT_EXTENSION = /\.g([jt]s)$/; + +function resolutionFor(originalId) { + return { + id: originalId.replace(FCCT_EXTENSION, ".$1"), + meta: { + fccts: { originalId }, + }, + }; +} + +async function preprocessTemplates(id) { + let ember = (await import("ember-source")).default; + let contents = await fs.readFile(id, "utf-8"); + + // This is basically taken directly from `ember-template-imports` + let result = preprocessEmbeddedTemplates(contents, { + relativePath: path.relative(".", id), + + getTemplateLocalsRequirePath: ember.absolutePaths.templateCompiler, + getTemplateLocalsExportPath: "_GlimmerSyntax.getTemplateLocals", + + templateTag: TEMPLATE_TAG_NAME, + templateTagReplacement: TEMPLATE_TAG_PLACEHOLDER, + + includeSourceMaps: true, + includeTemplateTokens: true, + }); + + return result.output; +} diff --git a/ember-async-data/rollup.config.mjs b/ember-async-data/rollup.config.mjs index b30b8cfd..4e0f1e16 100644 --- a/ember-async-data/rollup.config.mjs +++ b/ember-async-data/rollup.config.mjs @@ -1,14 +1,15 @@ -import { babel } from '@rollup/plugin-babel'; -import { nodeResolve } from '@rollup/plugin-node-resolve'; -import { Addon } from '@embroider/addon-dev/rollup'; +import { babel } from "@rollup/plugin-babel"; +import { nodeResolve } from "@rollup/plugin-node-resolve"; +import { Addon } from "@embroider/addon-dev/rollup"; +import templateTag from "./rollup-plugin-template-tag.mjs"; const addon = new Addon({ - srcDir: 'src', - destDir: 'dist', + srcDir: "src", + destDir: "dist", }); // Add extensions here, such as ts, gjs, etc that you may import -const extensions = ['.js', '.ts']; +const extensions = [".js", ".ts", ".gjs", ".gts"]; export default { // This provides defaults that work well alongside `publicEntrypoints` below. @@ -19,16 +20,18 @@ export default { // These are the modules that users should be able to import from your // addon. Anything not listed here may get optimized away. addon.publicEntrypoints([ - 'helpers/**/*.js', - 'index.js', - 'template-registry.js', - 'tracked-async-data.js', + "helpers/**/*.js", + "index.js", + "template-registry.js", + "tracked-async-data.js", ]), // These are the modules that should get reexported into the traditional // "app" tree. Things in here should also be in publicEntrypoints above, but // not everything in publicEntrypoints necessarily needs to go here. - addon.appReexports(['helpers/**/*.js']), + addon.appReexports(["helpers/**/*.js"]), + + templateTag(), // Follow the V2 Addon rules about dependencies. Your code can import from // `dependencies` and `peerDependencies` as well as standard Ember-provided @@ -43,7 +46,7 @@ export default { // babel.config.json. babel({ extensions, - babelHelpers: 'bundled', + babelHelpers: "bundled", }), // Allows rollup to resolve imports of files with the specified extensions @@ -54,7 +57,7 @@ export default { // addons are allowed to contain imports of .css files, which we want rollup // to leave alone and keep in the published output. - addon.keepAssets(['**/*.css']), + addon.keepAssets(["**/*.css"]), // Remove leftover build artifacts when starting a new build. addon.clean(), diff --git a/ember-async-data/src/components/async.gts b/ember-async-data/src/components/async.gts new file mode 100644 index 00000000..9ba13242 --- /dev/null +++ b/ember-async-data/src/components/async.gts @@ -0,0 +1,81 @@ +import Component from '@glimmer/component'; +import { cached } from '@glimmer/tracking'; +import TrackedAsyncData from '../tracked-async-data'; + +export interface AsyncSignature { + Args: { + /** The data to `await`. */ + data: T | Promise; + }; + Blocks: { + /** To render while waiting on the promise */ + pending: []; + /** To render once the promise has resolved, with the resolved value. */ + resolved: [value: T]; + /** To render if the promise has rejected, with the associated reason. */ + rejected: [reason: unknown]; + }; +} + +/** + Render a `TrackedAsyncData` in a template, with named blocks for each of the + states the value may be in. This is somewhat nicer than doing the same with + an `if`/`else if` chain, and composes nicely with other template primitives. + + It is also less error prone, in that you *cannot* access the value of the data + in the `pending` or `rejected` blocks: it is only yielded by the `resolved` + named block. + + ```ts + import { Async } from 'ember-async-data' + import LoadingSpinner from './loading-spinner'; + + function dumpError(error: unknown) { + return JSON.stringify(error); + } + + let example = new TrackedAsyncData("hello"); + + + ``` + */ +// IMPLEMENTATION NOTE: yes, future maintainer, this *does* have to be a class, +// not a template-only component. This is because it must be generic over the +// type passed in so that the yielded type can preserve that ("parametricity"). +// That is: if we pass in a `TrackedAsyncData`, the value yielded from +// the `resolved` named block should be a string. The only things which can +// preserve the type parameter that way are functions and classes, and we do not +// presently have a function-based way to define components, so we have to use +// a class instead to preserve the type! +export default class Async extends Component> { + @cached get data() { + return new TrackedAsyncData(this.args.data); + } + + +} diff --git a/ember-async-data/src/index.ts b/ember-async-data/src/index.ts index 4d16a81a..ef42a283 100644 --- a/ember-async-data/src/index.ts +++ b/ember-async-data/src/index.ts @@ -1,2 +1,3 @@ export { default as TrackedAsyncData } from './tracked-async-data'; export { load } from './helpers/load'; +export { default as Async } from './components/async'; diff --git a/ember-async-data/src/template-registry.ts b/ember-async-data/src/template-registry.ts index 49984c1c..8100b879 100644 --- a/ember-async-data/src/template-registry.ts +++ b/ember-async-data/src/template-registry.ts @@ -3,7 +3,9 @@ // See https://typed-ember.gitbook.io/glint/using-glint/ember/authoring-addons import type Load from './helpers/load'; +import type Async from './components/async'; export default interface Registry { load: typeof Load; + Async: typeof Async; } diff --git a/ember-async-data/src/tracked-async-data.ts b/ember-async-data/src/tracked-async-data.ts index cfeb4be9..f54588eb 100644 --- a/ember-async-data/src/tracked-async-data.ts +++ b/ember-async-data/src/tracked-async-data.ts @@ -57,7 +57,7 @@ class _TrackedAsyncData { (error) => { this.#state.data = ['REJECTED', error]; waiter.endAsync(this.#token); - } + }, ); } @@ -100,7 +100,7 @@ class _TrackedAsyncData { enabled: '1.0.0', }, until: '2.0.0', - } + }, ); return this.#state.data[0] === 'RESOLVED' ? this.#state.data[1] : null; @@ -129,7 +129,7 @@ class _TrackedAsyncData { enabled: '1.0.0', }, until: '2.0.0', - } + }, ); return this.#state.data[0] === 'REJECTED' ? this.#state.data[1] : null; @@ -182,6 +182,21 @@ class _TrackedAsyncData { toString(): string { return JSON.stringify(this.toJSON(), null, 2); } + + match(matcher: { + pending: () => V; + resolved: (value: T) => V; + rejected: (reason: unknown) => V; + }) { + switch (this.#state.data[0]) { + case 'PENDING': + return matcher.pending(); + case 'RESOLVED': + return matcher.resolved(this.#state.data[1]); + case 'REJECTED': + return matcher.rejected(this.#state.data[1]); + } + } } /** @@ -223,30 +238,38 @@ export type JSONRepr = // shared implementations (i.e. `.toJSON()` and `.toString()`) are shared // automatically. -interface Pending extends _TrackedAsyncData { +/** + A `TrackedAsyncData` whose wrapped promise is still pending, and which + therefore does not have a `value` or an `error` property. + */ +interface Pending extends Omit<_TrackedAsyncData, 'value' | 'error'> { state: 'PENDING'; isPending: true; isResolved: false; isRejected: false; - value: null; - error: null; } -interface Resolved extends _TrackedAsyncData { +/** + A `TrackedAsyncData` whose wrapped promise has resolved, and which therefore + has a `value` property with the value the promise resolved to. + */ +interface Resolved extends Omit<_TrackedAsyncData, 'error'> { state: 'RESOLVED'; isPending: false; isResolved: true; isRejected: false; value: T; - error: null; } -interface Rejected extends _TrackedAsyncData { +/** + A `TrackedAsyncData` whose wrapped promise has rejected, and which therefore + has an `error` property with the rejection value of the promise (if any). + */ +interface Rejected extends Omit<_TrackedAsyncData, 'value'> { state: 'REJECTED'; isPending: false; isResolved: false; isRejected: true; - value: null; error: unknown; } @@ -268,44 +291,51 @@ interface Rejected extends _TrackedAsyncData { import Component from '@glimmer/component'; import { cached } from '@glimmer/tracking'; import { inject as service } from '@ember/service'; - import TrackedAsyncData from 'ember-async-data/tracked-async-data'; + import type Store from '@ember-data/store'; + import { TrackedAsyncData, Match } from 'ember-async-data'; + import LoadingSpinner from './loading-spinner'; + import PresentTheData from './present-the-data'; + + interface ProfileSignature { + Args: { + id: number; + }; + } - export default class SmartProfile extends Component<{ id: number }> { - @service store; + export default class SmartProfile extends Component { + @service declare store: Store; - @cached - get someData() { + @cached get someData() { let recordPromise = this.store.findRecord('user', this.args.id); return new TrackedAsyncData(recordPromise); } - } - ``` - And a corresponding template: - - ```hbs - {{#if this.someData.isResolved}} - - {{else if this.someData.isPending}} - - {{else if this.someData.isRejected}} -

- Whoops! Looks like something went wrong! - {{this.someData.error.message}} -

- {{/if}} + + } ``` */ type TrackedAsyncData = Pending | Resolved | Rejected; const TrackedAsyncData = _TrackedAsyncData as new ( - data: T | Promise + data: T | Promise, ) => TrackedAsyncData; export default TrackedAsyncData; /** Utility type to check whether the string `key` is a property on an object */ function has( key: K, - t: T + t: T, ): t is T & Record { return key in t; } diff --git a/ember-async-data/tsconfig.json b/ember-async-data/tsconfig.json index 2198eb8f..48a2d84c 100644 --- a/ember-async-data/tsconfig.json +++ b/ember-async-data/tsconfig.json @@ -1,11 +1,8 @@ { - "extends": "@tsconfig/ember/tsconfig.json", - "include": [ - "src/**/*", - "unpublished-development-types/**/*" - ], + "extends": "../tsconfig.json", + "include": ["src/**/*", "unpublished-development-types/**/*"], "glint": { - "environment": "ember-loose" + "environment": ["ember-loose", "ember-template-imports"] }, "compilerOptions": { "declarationDir": "declarations" diff --git a/package.json b/package.json index 572c5c33..424d933c 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "prepare": "yarn build", "release": "release-it", "start": "concurrently 'npm:start:*' --restart-after 5000 --prefix-colors cyan,white,yellow", - "start:addon": "yarn workspace ember-async-data1 run start", + "start:addon": "yarn workspace ember-async-data run start", "start:test-app": "yarn workspace test-app run start", "test": "yarn workspaces run test" }, diff --git a/test-app/.eslintrc.js b/test-app/.eslintrc.js index 99e56414..b402c348 100644 --- a/test-app/.eslintrc.js +++ b/test-app/.eslintrc.js @@ -7,11 +7,7 @@ module.exports = { ecmaVersion: 'latest', }, plugins: ['ember', '@typescript-eslint'], - extends: [ - 'eslint:recommended', - 'plugin:ember/recommended', - 'plugin:prettier/recommended', - ], + extends: ['eslint:recommended', 'plugin:ember/recommended'], env: { browser: true, }, diff --git a/test-app/.prettierrc.js b/test-app/.prettierrc.js index e5f7b6d1..a84e4dbc 100644 --- a/test-app/.prettierrc.js +++ b/test-app/.prettierrc.js @@ -3,7 +3,7 @@ module.exports = { overrides: [ { - files: '*.{js,ts}', + files: '*.{js,ts,gjs,gts}', options: { singleQuote: true, }, diff --git a/test-app/.stylelintrc.js b/test-app/.stylelintrc.js index 021c539a..56a013c9 100644 --- a/test-app/.stylelintrc.js +++ b/test-app/.stylelintrc.js @@ -1,5 +1,5 @@ 'use strict'; module.exports = { - extends: ['stylelint-config-standard', 'stylelint-prettier/recommended'], + extends: ['stylelint-config-standard'], }; diff --git a/test-app/app/index.html b/test-app/app/index.html index 90cb9a37..b03d4fb6 100644 --- a/test-app/app/index.html +++ b/test-app/app/index.html @@ -1,15 +1,15 @@ - + - + TestApp - - + + {{content-for "head"}} - - + + {{content-for "head-footer"}} diff --git a/test-app/package.json b/test-app/package.json index c3066fa0..ce907b3c 100644 --- a/test-app/package.json +++ b/test-app/package.json @@ -19,7 +19,9 @@ "lint:hbs": "ember-template-lint .", "lint:hbs:fix": "ember-template-lint . --fix", "lint:js": "eslint . --cache", + "lint:prettier": "prettier . --check", "lint:js:fix": "eslint . --fix", + "lint:prettier:fix": "prettier . --write", "lint:types": "tsc --noEmit", "start": "ember serve", "test": "concurrently \"npm:lint\" \"npm:test:*\" --names \"lint,test:\"", @@ -33,8 +35,10 @@ "@embroider/test-setup": "^3.0.1", "@glimmer/component": "^1.1.2", "@glimmer/tracking": "^1.1.2", - "@glint/environment-ember-loose": "^1.0.2", - "@glint/template": "^1.0.2", + "@glint/core": "^1.1.0", + "@glint/environment-ember-loose": "^1.1.0", + "@glint/environment-ember-template-imports": "^1.1.0", + "@glint/template": "^1.1.0", "@tsconfig/ember": "^2.0.0", "@types/qunit": "^2.19.6", "@types/rsvp": "^4.0.4", @@ -58,8 +62,9 @@ "ember-page-title": "^7.0.0", "ember-qunit": "^7.0.0", "ember-resolver": "^11.0.1", - "ember-source": "^4.12.3", + "ember-source": "^5.2.0", "ember-source-channel-url": "^3.0.0", + "ember-template-imports": "^3.4.2", "ember-template-lint": "^5.11.2", "ember-try": "^3.0.0", "eslint": "^8.46.0", @@ -69,7 +74,7 @@ "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-qunit": "^8.0.0", "loader.js": "^4.7.0", - "prettier": "^2.8.8", + "prettier": "^3.0.3", "qunit": "^2.19.4", "qunit-dom": "^2.0.0", "stylelint": "^15.10.2", diff --git a/test-app/tests/defer.ts b/test-app/tests/defer.ts index 2680e830..1ea319fa 100644 --- a/test-app/tests/defer.ts +++ b/test-app/tests/defer.ts @@ -1,20 +1,20 @@ -interface Deferred { - resolve: (value?: unknown) => void; +interface Deferred { + resolve: (value: T) => void; reject: (value?: unknown) => void; - promise: Promise; + promise: Promise; } -export function defer(): Deferred { +export function defer(): Deferred { const deferred = { resolve: undefined, reject: undefined, promise: undefined, - } as Partial; + } as Partial>; deferred.promise = new Promise((resolve, reject) => { deferred.resolve = resolve; deferred.reject = reject; }); - return deferred as Deferred; + return deferred as Deferred; } diff --git a/test-app/tests/index.html b/test-app/tests/index.html index e4b2e696..5ad864df 100644 --- a/test-app/tests/index.html +++ b/test-app/tests/index.html @@ -1,24 +1,21 @@ - + - + TestApp Tests - - + + - {{content-for "head"}} - {{content-for "test-head"}} + {{content-for "head"}} {{content-for "test-head"}} - - - + + + - {{content-for "head-footer"}} - {{content-for "test-head-footer"}} + {{content-for "head-footer"}} {{content-for "test-head-footer"}} - {{content-for "body"}} - {{content-for "test-body"}} + {{content-for "body"}} {{content-for "test-body"}}
@@ -33,7 +30,6 @@ - {{content-for "body-footer"}} - {{content-for "test-body-footer"}} + {{content-for "body-footer"}} {{content-for "test-body-footer"}} diff --git a/test-app/tests/integration/components/async-test.gts b/test-app/tests/integration/components/async-test.gts new file mode 100644 index 00000000..cb276329 --- /dev/null +++ b/test-app/tests/integration/components/async-test.gts @@ -0,0 +1,300 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'ember-qunit'; +import { render, waitFor } from '@ember/test-helpers'; +import { defer } from '../../defer'; +import { Async } from 'ember-async-data'; +import { tracked } from '@glimmer/tracking'; + +class State { + @tracked promise: Promise; + constructor(promise: Promise) { + this.promise = promise; + } +} + +module('Integration | Component | Async', function (hooks) { + setupRenderingTest(hooks); + + test('it renders loading state', async function (assert) { + assert.expect(1); + + const { promise, resolve } = defer(); + + const renderPromise = render(); + + await waitFor('[data-test-async-component]'); + + assert.dom('[data-test-async-component]').hasText('PENDING'); + + resolve('hello'); + await renderPromise; + }); + + test('it renders loaded state', async function (assert) { + assert.expect(2); + + const deferred = defer(); + deferred.resolve('foobar'); + await deferred.promise; + + const renderPromise = render(); + + await waitFor('[data-test-async-component]'); + assert.dom('[data-test-async-component]').containsText('RESOLVED'); + assert.dom('[data-test-async-component]').containsText('foobar'); + + await renderPromise; + }); + + test('it renders error state', async function (assert) { + assert.expect(3); + + const { promise, reject } = defer(); + + // This handles the error throw from rendering a rejected promise + promise.catch((error: Error) => { + assert.ok(error instanceof Error); + assert.strictEqual(error.message, 'foobar'); + }); + + reject(new Error('foobar')); + + const renderPromise = render(); + + await waitFor('[data-test-async-component]'); + assert.dom('[data-test-async-component]').hasText('REJECTED'); + + await renderPromise; + }); + + test('it renders loading state and then loaded state', async function (assert) { + assert.expect(2); + + const { promise, resolve } = defer(); + + const renderPromise = render(); + + await waitFor('[data-test-async-component]'); + assert.dom('[data-test-async-component]').hasText('PENDING'); + + resolve('goodbye'); + + await waitFor('[data-test-state="RESOLVED"]'); + assert.dom('[data-test-async-component]').hasText('RESOLVED goodbye'); + + await renderPromise; + }); + + test('it renders loading state and then error state', async function (assert) { + assert.expect(3); + + const { promise, reject } = defer(); + + const renderPromise = render(); + + await waitFor('[data-test-async-component]'); + assert.dom('[data-test-async-component]').hasText('PENDING'); + + reject(new Error('foobar')); + + // This handles the error thrown at the top level + await promise.catch(() => { + assert.ok(true, 'things are neat!'); + }); + + await waitFor('[data-test-state="REJECTED"]'); + assert.dom('[data-test-async-component]').hasText('REJECTED', 'rejected'); + + await renderPromise; + }); + + test('it renders the state for the new promise if a new promise is sent and resolves before the old promise is done loading', async function (assert) { + assert.expect(4); + + const { promise: oldPromise, reject: rejectOld } = defer(); + const state = new State(oldPromise); + + // This handles the error throw from rendering a rejected promise + oldPromise.catch((error) => { + assert.ok(error instanceof Error); + assert.strictEqual(error.message, 'foobar'); + }); + + const renderPromise = render(); + + await waitFor('[data-test-async-component]'); + assert.dom('[data-test-async-component]').hasText('PENDING'); + + const { promise: newPromise, resolve: resolveNew } = defer(); + state.promise = newPromise; + + resolveNew('ahoy'); + await newPromise; + rejectOld(new Error('foobar')); + + await waitFor('[data-test-state="RESOLVED"]'); + assert.dom('[data-test-async-component]').hasText('RESOLVED ahoy'); + + await renderPromise; + }); + + test('it renders the state and value for the new promise if a new promise with a different value is sent before the old promise is done loading', async function (assert) { + assert.expect(3); + + const { promise: oldPromise, resolve: resolveOld } = defer(); + const state = new State(oldPromise); + + const renderPromise = render(); + + await waitFor('[data-test-async-component]'); + assert.dom('[data-test-async-component]').hasText('PENDING'); + + const { promise: newPromise, resolve: resolveNew } = defer(); + state.promise = newPromise; + + resolveNew('New'); + await newPromise; + resolveOld('Old'); + await oldPromise; + + await waitFor('[data-test-state="RESOLVED"]'); + assert.dom('[data-test-async-component]').containsText('RESOLVED'); + assert.dom('[data-test-async-component]').containsText('New'); + + await renderPromise; + }); + + test('it renders error state and then loading state for a retried promise', async function (assert) { + assert.expect(4); + + const deferred = defer(); + const state = new State(deferred.promise); + + // This handles the error throw from rendering a rejected promise + deferred.promise.catch((error: Error) => { + assert.ok(error instanceof Error); + assert.strictEqual(error.message, 'foobar'); + }); + + // eslint-disable-next-line ember/no-array-prototype-extensions + deferred.reject(new Error('foobar')); + + const renderPromise = render(); + + await waitFor('[data-test-async-component]'); + assert.dom('[data-test-async-component]').hasText('REJECTED'); + + const retryDeferred = defer(); + state.promise = retryDeferred.promise; + + await waitFor('[data-test-state="PENDING"]'); + assert.dom('[data-test-async-component]').hasText('PENDING'); + + retryDeferred.resolve('hello'); + await retryDeferred.promise; + await renderPromise; + }); +}); diff --git a/test-app/tests/integration/helpers/load-test.ts b/test-app/tests/integration/helpers/load-test.gts similarity index 56% rename from test-app/tests/integration/helpers/load-test.ts rename to test-app/tests/integration/helpers/load-test.gts index 4f6d08d8..1efd00e1 100644 --- a/test-app/tests/integration/helpers/load-test.ts +++ b/test-app/tests/integration/helpers/load-test.gts @@ -1,25 +1,29 @@ import { module, test } from 'qunit'; import { setupRenderingTest } from 'ember-qunit'; -import { render, waitFor, type TestContext } from '@ember/test-helpers'; -import { hbs } from 'ember-cli-htmlbars'; +import { render, waitFor } from '@ember/test-helpers'; import { defer } from '../../defer'; - -interface LocalTestContext extends TestContext { - promise: Promise; +import { load } from 'ember-async-data'; +import { tracked } from '@glimmer/tracking'; + +class State { + @tracked promise: Promise; + constructor(promise: Promise) { + this.promise = promise; + } } module('Integration | Helper | load', function (hooks) { setupRenderingTest(hooks); - test('it renders loading state', async function (this: LocalTestContext, assert) { - const { promise, resolve } = defer(); - this.set('promise', promise); + test('it renders loading state', async function (assert) { + const { promise, resolve } = defer(); - const renderPromise = render(hbs` + const renderPromise = render(); await waitFor('[data-test-load-helper]'); assert.dom('[data-test-load-helper]').hasText('PENDING'); - resolve(); + resolve('hello'); await renderPromise; }); - test('it renders loaded state', async function (this: LocalTestContext, assert) { - const deferred = defer(); + test('it renders loaded state', async function (assert) { + const deferred = defer(); deferred.resolve('foobar'); await deferred.promise; - this.set('promise', deferred.promise); - const renderPromise = render(hbs` + const renderPromise = render(); await waitFor('[data-test-load-helper]'); assert.dom('[data-test-load-helper]').containsText('RESOLVED'); @@ -64,10 +68,10 @@ module('Integration | Helper | load', function (hooks) { await renderPromise; }); - test('it renders error state', async function (this: LocalTestContext, assert) { + test('it renders error state', async function (assert) { assert.expect(3); - const { promise, reject } = defer(); + const { promise, reject } = defer(); // This handles the error throw from rendering a rejected promise promise.catch((error: Error) => { @@ -76,13 +80,13 @@ module('Integration | Helper | load', function (hooks) { }); reject(new Error('foobar')); - this.set('promise', promise); - const renderPromise = render(hbs` + const renderPromise = render(); await waitFor('[data-test-load-helper]'); assert.dom('[data-test-load-helper]').hasText('REJECTED'); @@ -98,13 +102,12 @@ module('Integration | Helper | load', function (hooks) { await renderPromise; }); - test('it renders loading state and then loaded state', async function (this: LocalTestContext, assert) { - const { promise, resolve } = defer(); - this.set('promise', promise); + test('it renders loading state and then loaded state', async function (assert) { + const { promise, resolve } = defer(); - const renderPromise = render(hbs` + const renderPromise = render(); await waitFor('[data-test-load-helper]'); assert.dom('[data-test-load-helper]').hasText('PENDING'); - resolve(); + resolve('goodbye'); await waitFor('[data-test-state="RESOLVED"]'); - assert.dom('[data-test-load-helper]').hasText('RESOLVED'); + assert.dom('[data-test-load-helper]').hasText('RESOLVED goodbye'); await renderPromise; }); - test('it renders loading state and then error state', async function (this: LocalTestContext, assert) { + test('it renders loading state and then error state', async function (assert) { assert.expect(3); - const { promise, reject } = defer(); - this.set('promise', promise); + const { promise, reject } = defer(); - const renderPromise = render(hbs` + const renderPromise = render(); await waitFor('[data-test-load-helper]'); assert.dom('[data-test-load-helper]').hasText('PENDING'); @@ -163,11 +165,11 @@ module('Integration | Helper | load', function (hooks) { await renderPromise; }); - test('it renders the state for the new promise if a new promise is sent and resolves before the old promise is done loading', async function (this: LocalTestContext, assert) { - assert.expect(4); + test('it renders the state for the new promise if a new promise is sent and resolves before the old promise is done loading', async function (assert) { + assert.expect(5); - const { promise: oldPromise, reject: rejectOld } = defer(); - this.set('promise', oldPromise); + const { promise: oldPromise, reject: rejectOld } = defer(); + const state = new State(oldPromise); // This handles the error throw from rendering a rejected promise oldPromise.catch((error) => { @@ -175,59 +177,60 @@ module('Integration | Helper | load', function (hooks) { assert.strictEqual(error.message, 'foobar'); }); - const renderPromise = render(hbs` + const renderPromise = render(); await waitFor('[data-test-load-helper]'); assert.dom('[data-test-load-helper]').hasText('PENDING'); - const { promise: newPromise, resolve: resolveNew } = defer(); - this.set('promise', newPromise); + const { promise: newPromise, resolve: resolveNew } = defer(); + state.promise = newPromise; - resolveNew(); + resolveNew('ahoy'); await newPromise; rejectOld(new Error('foobar')); await waitFor('[data-test-state="RESOLVED"]'); - assert.dom('[data-test-load-helper]').hasText('RESOLVED'); + assert.dom('[data-test-load-helper]').containsText('RESOLVED'); + assert.dom('[data-test-load-helper]').containsText('ahoy'); await renderPromise; }); - test('it renders the state and value for the new promise if a new promise with a different value is sent before the old promise is done loading', async function (this: LocalTestContext, assert) { - const { promise: oldPromise, resolve: resolveOld } = defer(); - this.set('promise', oldPromise); - - const renderPromise = render(hbs` -
- {{#let (load this.promise) as |result|}} - {{#if result.isResolved}} -
RESOLVED {{result.value}}
- {{else if result.isPending}} -
PENDING
- {{else if result.isRejected}} -
REJECTED
- {{/if}} - {{/let}} -
- `); + test('it renders the state and value for the new promise if a new promise with a different value is sent before the old promise is done loading', async function (assert) { + const { promise: oldPromise, resolve: resolveOld } = defer(); + let state = new State(oldPromise); + + const renderPromise = render(); await waitFor('[data-test-load-helper]'); assert.dom('[data-test-load-helper]').hasText('PENDING'); - const { promise: newPromise, resolve: resolveNew } = defer(); - this.set('promise', newPromise); + const { promise: newPromise, resolve: resolveNew } = defer(); + state.promise = newPromise; resolveNew('New'); await newPromise; @@ -241,11 +244,11 @@ module('Integration | Helper | load', function (hooks) { await renderPromise; }); - test('it renders error state and then loading state for a retried promise', async function (this: LocalTestContext, assert) { + test('it renders error state and then loading state for a retried promise', async function (assert) { assert.expect(4); - const deferred = defer(); - this.set('promise', deferred.promise); + const deferred = defer(); + const state = new State(deferred.promise); // This handles the error throw from rendering a rejected promise deferred.promise.catch((error: Error) => { @@ -256,30 +259,30 @@ module('Integration | Helper | load', function (hooks) { // eslint-disable-next-line ember/no-array-prototype-extensions deferred.reject(new Error('foobar')); - const renderPromise = render(hbs` -
- {{#let (load this.promise) as |result|}} - {{#if result.isResolved}} -
RESOLVED {{result.value}}
- {{else if result.isPending}} -
PENDING
- {{else if result.isRejected}} -
REJECTED
- {{/if}} - {{/let}} -
- `); + const renderPromise = render(); await waitFor('[data-test-load-helper]'); assert.dom('[data-test-load-helper]').hasText('REJECTED'); - const retryDeferred = defer(); - this.set('promise', retryDeferred.promise); + const retryDeferred = defer(); + state.promise = retryDeferred.promise; await waitFor('[data-test-state="PENDING"]'); assert.dom('[data-test-load-helper]').hasText('PENDING'); - retryDeferred.resolve(); + retryDeferred.resolve('hello'); await retryDeferred.promise; await renderPromise; }); diff --git a/test-app/tests/unit/helpers/load-test.ts b/test-app/tests/unit/helpers/load-test.ts index 2d507840..25ab46c6 100644 --- a/test-app/tests/unit/helpers/load-test.ts +++ b/test-app/tests/unit/helpers/load-test.ts @@ -21,7 +21,7 @@ module.skip('Unit | load', function (hooks) { const result = load(promise); assert.ok( result instanceof TrackedAsyncData, - 'it returns a TrackedAsyncData instance' + 'it returns a TrackedAsyncData instance', ); resolve(); await promise; @@ -31,7 +31,7 @@ module.skip('Unit | load', function (hooks) { const result = load(12); assert.ok( result instanceof TrackedAsyncData, - 'it returns a TrackedAsyncData instance' + 'it returns a TrackedAsyncData instance', ); }); }); diff --git a/test-app/tests/unit/tracked-async-data-test.ts b/test-app/tests/unit/tracked-async-data-test.ts index 9f301e28..6602fc32 100644 --- a/test-app/tests/unit/tracked-async-data-test.ts +++ b/test-app/tests/unit/tracked-async-data-test.ts @@ -20,8 +20,6 @@ module('Unit | TrackedAsyncData', function () { assert.true(result.isPending); assert.false(result.isResolved); assert.false(result.isRejected); - assert.strictEqual(result.value, null); - assert.strictEqual(result.error, null); deferred.resolve(); await deferred.promise; diff --git a/test-app/tsconfig.json b/test-app/tsconfig.json index 6e6f1f71..948bc9ea 100644 --- a/test-app/tsconfig.json +++ b/test-app/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@tsconfig/ember/tsconfig.json", + "extends": "../tsconfig.json", "compilerOptions": { // The combination of `baseUrl` with `paths` allows Ember's classic package // layout, which is not resolvable with the Node resolution algorithm, to @@ -10,5 +10,8 @@ "test-app/*": ["app/*"], "*": ["types/*"] } + }, + "glint": { + "environment": ["ember-loose", "ember-template-imports"] } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..7c32de90 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@tsconfig/ember/tsconfig.json", + "glint": { + "environment": [ + "ember-loose", + "ember-template-imports" + ] + } +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 0169049f..2a319cd0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,6 +23,14 @@ "@babel/highlight" "^7.22.10" chalk "^2.4.2" +"@babel/code-frame@^7.22.13": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== + dependencies: + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" + "@babel/compat-data@^7.17.7", "@babel/compat-data@^7.19.4": version "7.20.1" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.1.tgz#f2e6ef7790d8c8dbf03d379502dcc246dcce0b30" @@ -54,6 +62,27 @@ json5 "^2.2.2" semver "^6.3.1" +"@babel/core@^7.22.11": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.0.tgz#f8259ae0e52a123eb40f552551e647b506a94d83" + integrity sha512-97z/ju/Jy1rZmDxybphrBuI+jtJjFVoz7Mr9yUQVVVi+DNZE333uFQeMOqcCIy1x3WYBIbWftUSLmbNXNT7qFQ== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-module-transforms" "^7.23.0" + "@babel/helpers" "^7.23.0" + "@babel/parser" "^7.23.0" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.0" + "@babel/types" "^7.23.0" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + "@babel/generator@^7.22.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.10.tgz#c92254361f398e160645ac58831069707382b722" @@ -64,6 +93,16 @@ "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" +"@babel/generator@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" + integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== + dependencies: + "@babel/types" "^7.23.0" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" @@ -97,6 +136,17 @@ lru-cache "^5.1.1" semver "^6.3.1" +"@babel/helper-compilation-targets@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" + integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.15" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + "@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.22.10", "@babel/helper-create-class-features-plugin@^7.22.9", "@babel/helper-create-class-features-plugin@^7.5.5": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.10.tgz#dd2612d59eac45588021ac3d6fa976d08f4e95a3" @@ -137,6 +187,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + "@babel/helper-environment-visitor@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" @@ -165,6 +220,14 @@ "@babel/template" "^7.22.5" "@babel/types" "^7.22.5" +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + "@babel/helper-hoist-variables@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" @@ -193,6 +256,13 @@ dependencies: "@babel/types" "^7.18.6" +"@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + "@babel/helper-module-imports@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" @@ -211,6 +281,17 @@ "@babel/helper-split-export-declaration" "^7.22.6" "@babel/helper-validator-identifier" "^7.22.5" +"@babel/helper-module-transforms@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e" + integrity sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + "@babel/helper-optimise-call-expression@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" @@ -294,6 +375,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + "@babel/helper-validator-identifier@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" @@ -304,6 +390,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== +"@babel/helper-validator-option@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" + integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== + "@babel/helper-validator-option@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" @@ -328,6 +419,15 @@ "@babel/traverse" "^7.22.10" "@babel/types" "^7.22.10" +"@babel/helpers@^7.23.0": + version "7.23.1" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.1.tgz#44e981e8ce2b9e99f8f0b703f3326a4636c16d15" + integrity sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.0" + "@babel/types" "^7.23.0" + "@babel/highlight@^7.22.10": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.10.tgz#02a3f6d8c1cb4521b2fd0ab0da8f4739936137d7" @@ -337,11 +437,25 @@ chalk "^2.4.2" js-tokens "^4.0.0" +"@babel/highlight@^7.22.13": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + "@babel/parser@^7.14.5", "@babel/parser@^7.22.10", "@babel/parser@^7.22.5", "@babel/parser@^7.4.5": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.10.tgz#e37634f9a12a1716136c44624ef54283cabd3f55" integrity sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ== +"@babel/parser@^7.22.15", "@babel/parser@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" + integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" @@ -654,13 +768,20 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-block-scoping@^7.19.4", "@babel/plugin-transform-block-scoping@^7.20.5": +"@babel/plugin-transform-block-scoping@^7.19.4": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz#e737b91037e5186ee16b76e7ae093358a5634f02" integrity sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ== dependencies: "@babel/helper-plugin-utils" "^7.20.2" +"@babel/plugin-transform-block-scoping@^7.21.0": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.22.15.tgz#494eb82b87b5f8b1d8f6f28ea74078ec0a10a841" + integrity sha512-G1czpdJBZCtngoK1sJgloLiOHUnkb/bLZwqVZD8kXmq0ZnVfTTWUcs9OWtp0mBtYJ+4LQY1fllqBkOIPhXmFmw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-transform-classes@^7.19.0": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz#0e61ec257fba409c41372175e7c1e606dc79bb20" @@ -1073,6 +1194,15 @@ "@babel/parser" "^7.22.5" "@babel/types" "^7.22.5" +"@babel/template@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + "@babel/traverse@^7.14.5", "@babel/traverse@^7.19.0", "@babel/traverse@^7.22.10", "@babel/traverse@^7.4.5": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.10.tgz#20252acb240e746d27c2e82b4484f199cf8141aa" @@ -1089,6 +1219,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.0.tgz#18196ddfbcf4ccea324b7f6d3ada00d8c5a99c53" + integrity sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.0" + "@babel/types" "^7.23.0" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.19.4", "@babel/types@^7.20.0", "@babel/types@^7.21.5", "@babel/types@^7.22.10", "@babel/types@^7.22.5", "@babel/types@^7.4.4", "@babel/types@^7.7.2": version "7.22.10" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.10.tgz#4a9e76446048f2c66982d1a989dd12b8a2d2dc03" @@ -1098,6 +1244,15 @@ "@babel/helper-validator-identifier" "^7.22.5" to-fast-properties "^2.0.0" +"@babel/types@^7.22.15", "@babel/types@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" + integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -1340,6 +1495,17 @@ resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== +"@glimmer/compiler@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/compiler/-/compiler-0.84.2.tgz#ff4ef4fb244afa254189a579fa4453b2783ae7ab" + integrity sha512-rU8qpqbqxIPwrEQH82yDDFi1hgv6ud1agYexmnmCXlaLS5uCVATJAqKsVozc7aHOgmmF4Ukd/LoF4NYfGr8X3w== + dependencies: + "@glimmer/interfaces" "0.84.2" + "@glimmer/syntax" "0.84.2" + "@glimmer/util" "0.84.2" + "@glimmer/wire-format" "0.84.2" + "@simple-dom/interface" "^1.4.0" + "@glimmer/component@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@glimmer/component/-/component-1.1.2.tgz#892ec0c9f0b6b3e41c112be502fde073cf24d17c" @@ -1360,16 +1526,42 @@ ember-cli-version-checker "^3.1.3" ember-compatibility-helpers "^1.1.2" +"@glimmer/destroyable@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/destroyable/-/destroyable-0.84.2.tgz#67009d931346f4988a6dd329cd8b95141726a453" + integrity sha512-74L4+jlGUhzhUe87lTxjFdYEEfcDWcza+jqLXoyIb/p4cS0hWsTGlyF+OcuUbHO4yqJd4bXchGOVocoajmSp6w== + dependencies: + "@glimmer/env" "0.1.7" + "@glimmer/global-context" "0.84.2" + "@glimmer/interfaces" "0.84.2" + "@glimmer/util" "0.84.2" + "@glimmer/di@^0.1.9": version "0.1.11" resolved "https://registry.yarnpkg.com/@glimmer/di/-/di-0.1.11.tgz#a6878c07a13a2c2c76fcde598a5c97637bfc4280" integrity sha512-moRwafNDwHTnTHzyyZC9D+mUSvYrs1Ak0tRPjjmCghdoHHIvMshVbEnwKb/1WmW5CUlKc2eL9rlAV32n3GiItg== +"@glimmer/encoder@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/encoder/-/encoder-0.84.2.tgz#3e6038f4115cde40a1252f13ae33774341325d40" + integrity sha512-599TMDNDHiw+PhNXy5/AnMjh83NBKy+tl2YmwSRY9qktx4DDOZenzgwZ5haLlzPaceejJ6ZNAoGyV5bBrDY5+w== + dependencies: + "@glimmer/env" "0.1.7" + "@glimmer/interfaces" "0.84.2" + "@glimmer/vm" "0.84.2" + "@glimmer/env@0.1.7", "@glimmer/env@^0.1.7": version "0.1.7" resolved "https://registry.yarnpkg.com/@glimmer/env/-/env-0.1.7.tgz#fd2d2b55a9029c6b37a6c935e8c8871ae70dfa07" integrity sha512-JKF/a9I9jw6fGoz8kA7LEQslrwJ5jms5CXhu/aqkBWk+PmZ6pTl8mlb/eJ/5ujBGTiQzBhy5AIWF712iA+4/mw== +"@glimmer/global-context@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.84.2.tgz#cd4612925dbd68787b9270e91b213691150c307f" + integrity sha512-6FycLh/Eq0P3LA94bJL6WHPJyOTKeQD4KBWhowZ9TbeO3p4/WUr+POKPVEyfIx6YHybhpL9MGj45Y2r0hqVigw== + dependencies: + "@glimmer/env" "^0.1.7" + "@glimmer/global-context@0.84.3": version "0.84.3" resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.84.3.tgz#f8bf2cda9562716f2ddf3f96837e7559600635c4" @@ -1377,6 +1569,13 @@ dependencies: "@glimmer/env" "^0.1.7" +"@glimmer/interfaces@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.84.2.tgz#764cf92c954adcd1a851e5dc68ec1f6b654dc3bd" + integrity sha512-tMZxQpOddUVmHEOuripkNqVR7ba0K4doiYnFd4WyswqoHPlxqpBujbIamQ+bWCWEF0U4yxsXKa31ekS/JHkiBQ== + dependencies: + "@simple-dom/interface" "^1.4.0" + "@glimmer/interfaces@0.84.3": version "0.84.3" resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.84.3.tgz#629777a4abe373b0785656f6c8d08989f5784805" @@ -1384,6 +1583,78 @@ dependencies: "@simple-dom/interface" "^1.4.0" +"@glimmer/low-level@0.78.2": + version "0.78.2" + resolved "https://registry.yarnpkg.com/@glimmer/low-level/-/low-level-0.78.2.tgz#bca5f666760ce98345e87c5b3e37096e772cb2de" + integrity sha512-0S6TWOOd0fzLLysw1pWZN0TgasaHmYs1Sjz9Til1mTByIXU1S+1rhdyr2veSQPO/aRjPuEQyKXZQHvx23Zax6w== + +"@glimmer/manager@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/manager/-/manager-0.84.2.tgz#a96730388994a57517c45cbacf6ac481bdf1cd47" + integrity sha512-cXOnRTH9nwAe/un8hK0x6z1m67Cv5ywAuK7KRxAFTWHgGX/i6BvoZCStr6zJD/U6Frna2c7RJK8JpleP94opEA== + dependencies: + "@glimmer/destroyable" "0.84.2" + "@glimmer/env" "0.1.7" + "@glimmer/global-context" "0.84.2" + "@glimmer/interfaces" "0.84.2" + "@glimmer/reference" "0.84.2" + "@glimmer/util" "0.84.2" + "@glimmer/validator" "0.84.2" + +"@glimmer/node@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/node/-/node-0.84.2.tgz#74d4eb8fc58dbf5ed2b57af39a1f350548cf0469" + integrity sha512-kefGxH+0N0xNyb6QovdPzmIBefZwu8TID45qsASgVbFx7mfFiXjQiyaxbRUyam4MAEb8Nzzx1Byxn1FQCYyLdA== + dependencies: + "@glimmer/interfaces" "0.84.2" + "@glimmer/runtime" "0.84.2" + "@glimmer/util" "0.84.2" + "@simple-dom/document" "^1.4.0" + "@simple-dom/interface" "^1.4.0" + +"@glimmer/opcode-compiler@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/opcode-compiler/-/opcode-compiler-0.84.2.tgz#df0fb70e2fdacb7c6f6ec3edd1c66a5639f2e2c9" + integrity sha512-KwTH9cWEW4Neu3jmD9ANMIQYBiEqPsLx+h55G+wYp5djyjiYwSJ7KhgMAB+wEHuvB6izp3XdSO6jDMgp3pp49A== + dependencies: + "@glimmer/encoder" "0.84.2" + "@glimmer/env" "0.1.7" + "@glimmer/interfaces" "0.84.2" + "@glimmer/reference" "0.84.2" + "@glimmer/util" "0.84.2" + "@glimmer/vm" "0.84.2" + "@glimmer/wire-format" "0.84.2" + +"@glimmer/owner@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/owner/-/owner-0.84.2.tgz#423fd5b43fa49e95558456999be3ec0150742474" + integrity sha512-maZn642eXRImp/hOSa4nQmzMLEIywXwgahS/ZMuzD4HTTsA2SlEdjXSrVbRQYarYF8LkiJ7fpcKHkyNCe8SHrQ== + dependencies: + "@glimmer/util" "0.84.2" + +"@glimmer/program@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/program/-/program-0.84.2.tgz#4cfb5bb3a31a221671f35817f31ad175ebf4fad7" + integrity sha512-Ohx+7H3+CSVHbC08trUK7fXC6ti9x0SQDC2Lwd7BMXmMyoOZHxdaKNrTJ+CsQ8nV1JkLfXhnvRDG08TqD5VHJw== + dependencies: + "@glimmer/encoder" "0.84.2" + "@glimmer/env" "0.1.7" + "@glimmer/interfaces" "0.84.2" + "@glimmer/manager" "0.84.2" + "@glimmer/opcode-compiler" "0.84.2" + "@glimmer/util" "0.84.2" + +"@glimmer/reference@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.84.2.tgz#c8d91a3ba0b92a9430b6023d7b6f39dd56c79af1" + integrity sha512-hH0VD76OXMsGSHbqaqD64u1aBEqy//jhZtIaHGwAHNpTEX+zDtW3ka298KbAn2CZyDDrNAnuc2U1Vy4COR3zlA== + dependencies: + "@glimmer/env" "^0.1.7" + "@glimmer/global-context" "0.84.2" + "@glimmer/interfaces" "0.84.2" + "@glimmer/util" "0.84.2" + "@glimmer/validator" "0.84.2" + "@glimmer/reference@^0.84.3": version "0.84.3" resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.84.3.tgz#6420ad9c102633ac83939fd1b2457269d21fb632" @@ -1395,6 +1666,35 @@ "@glimmer/util" "0.84.3" "@glimmer/validator" "0.84.3" +"@glimmer/runtime@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/runtime/-/runtime-0.84.2.tgz#3d4a565cf72762b0aab06982e5151f7e3c1ccdd8" + integrity sha512-mUefYwq8l4df61iWYsRKVYQUqAeCgeZ3fuYNRNbvKDudnT9bQXayJLqr6ZxwTVaDoeKjg+7lMjkDSDSvqoxfsA== + dependencies: + "@glimmer/destroyable" "0.84.2" + "@glimmer/env" "0.1.7" + "@glimmer/global-context" "0.84.2" + "@glimmer/interfaces" "0.84.2" + "@glimmer/low-level" "0.78.2" + "@glimmer/owner" "0.84.2" + "@glimmer/program" "0.84.2" + "@glimmer/reference" "0.84.2" + "@glimmer/util" "0.84.2" + "@glimmer/validator" "0.84.2" + "@glimmer/vm" "0.84.2" + "@glimmer/wire-format" "0.84.2" + "@simple-dom/interface" "^1.4.0" + +"@glimmer/syntax@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.84.2.tgz#a3f65e51eec20f6adb79c6159d1ad1166fa5bccd" + integrity sha512-SPBd1tpIR9XeaXsXsMRCnKz63eLnIZ0d5G9QC4zIBFBC3pQdtG0F5kWeuRVCdfTIFuR+5WBMfk5jvg+3gbQhjg== + dependencies: + "@glimmer/interfaces" "0.84.2" + "@glimmer/util" "0.84.2" + "@handlebars/parser" "~2.0.0" + simple-html-tokenizer "^0.5.11" + "@glimmer/syntax@^0.84.2", "@glimmer/syntax@^0.84.3": version "0.84.3" resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.84.3.tgz#4045a1708cef7fd810cff42fe6deeba40c7286d0" @@ -1413,6 +1713,15 @@ "@glimmer/env" "^0.1.7" "@glimmer/validator" "^0.44.0" +"@glimmer/util@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.84.2.tgz#2711ba40f25f44b2ea309cad49f5c2622c6211bc" + integrity sha512-VbhzE2s4rmU+qJF3gGBTL1IDjq+/G2Th51XErS8MQVMCmE4CU2pdwSzec8PyOowqCGUOrVIWuMzEI6VoPM4L4w== + dependencies: + "@glimmer/env" "0.1.7" + "@glimmer/interfaces" "0.84.2" + "@simple-dom/interface" "^1.4.0" + "@glimmer/util@0.84.3": version "0.84.3" resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.84.3.tgz#9ae0166982c0b48aa94b02d6ba8c2c81976ade4b" @@ -1427,6 +1736,14 @@ resolved "https://registry.yarnpkg.com/@glimmer/util/-/util-0.44.0.tgz#45df98d73812440206ae7bda87cfe04aaae21ed9" integrity sha512-duAsm30uVK9jSysElCbLyU6QQYO2X9iLDLBIBUcCqck9qN1o3tK2qWiHbGK5d6g8E2AJ4H88UrfElkyaJlGrwg== +"@glimmer/validator@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.84.2.tgz#29394d262cf8373fe20f4e225c1adc9857a4164b" + integrity sha512-9tpSmwiktsJDqriNEiFfyP+9prMSdk08THA6Ik71xS/sudBKxoDpul678uvyEYST/+Z23F8MxwKccC+QxCMXNA== + dependencies: + "@glimmer/env" "^0.1.7" + "@glimmer/global-context" "0.84.2" + "@glimmer/validator@0.84.3", "@glimmer/validator@^0.84.3": version "0.84.3" resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.84.3.tgz#cd83b7f9ab78953f23cc11a32d83d7f729c54df2" @@ -1447,14 +1764,30 @@ dependencies: babel-plugin-debug-macros "^0.3.4" -"@glint/core@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@glint/core/-/core-1.0.2.tgz#eb684b6b7c830b8e0a8e3ddda550bc269d1cbb5e" - integrity sha512-0bVt/lT/NurpD8nBG9RTPKYlcpg51UDGCKgLoBEFOiTXv3aCSxAVKPud1IYaitGBKE0C+s5pl2PHkgptotVS+w== +"@glimmer/vm@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/vm/-/vm-0.84.2.tgz#ade992d1e4baea3e88d320ec06f3d3e173c236e9" + integrity sha512-IuQeDlh+AUOOX8QXc+ehPv5uFnqstQVZGplqqvPQRcKvsEalog88RC34dAEwFdB756SKjgRSw+N+nT3ZDNVlvA== + dependencies: + "@glimmer/interfaces" "0.84.2" + "@glimmer/util" "0.84.2" + +"@glimmer/wire-format@0.84.2": + version "0.84.2" + resolved "https://registry.yarnpkg.com/@glimmer/wire-format/-/wire-format-0.84.2.tgz#fa90d93b2f7c5baa1ef24d82d649892e6a1d8671" + integrity sha512-/FmbXSPFJAoIZ6qu28xVXpAdy2Ln++Ewe6mRHFpnudV1lUrBN+Q09A4j/RN/hpAkyz/8ai5W+5rHKuaWxoi4Dg== + dependencies: + "@glimmer/interfaces" "0.84.2" + "@glimmer/util" "0.84.2" + +"@glint/core@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@glint/core/-/core-1.1.0.tgz#b89600b59fcfac7a112615510ea05c08f985d3d9" + integrity sha512-SeAdKrQF65NRDzzmkwUC0VRZjBDysQXeIKXhyCUtXaatFDeyC0zdESJRcUykMdQoI5R6MKcts2X3gthLRuEGKA== dependencies: "@glimmer/syntax" "^0.84.2" escape-string-regexp "^4.0.0" - semver "^7.3.8" + semver "^7.5.2" silent-error "^1.1.1" uuid "^8.3.2" vscode-languageserver "^8.0.1" @@ -1462,15 +1795,20 @@ vscode-uri "^3.0.2" yargs "^17.5.1" -"@glint/environment-ember-loose@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@glint/environment-ember-loose/-/environment-ember-loose-1.0.2.tgz#701d084625707e9ba9ca2cf5269bbea443b15d62" - integrity sha512-tVLYzAx6c/4vcSaijiAubwR27/+K2tujuozArxeNud58MTwncGxhUkCHSM9xl+wn4VJjsjkzI6+nmzjEdkszSg== +"@glint/environment-ember-loose@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@glint/environment-ember-loose/-/environment-ember-loose-1.1.0.tgz#b0e3a321376924cd74c9bb741fdfd99a04d9f363" + integrity sha512-Qwr3OAptRZ8zqxaPvpVBdbSiiImYMRNu+0IPQGaDutqOV80GzWYeiMuEyPC0Nwy4mQ3991YxE24Q+a5/FTfTNw== -"@glint/template@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@glint/template/-/template-1.0.2.tgz#dcb96f048df52e7d0e78cf194fa07b3c42f15278" - integrity sha512-kFWfJrS7XM0NjC5YSN0CWA9FiN0mhUvWVlQ2O7YRz/uhrO8+TVYNLst0WKELRbfCXbdI7wyYQkazNgz6FoL9CA== +"@glint/environment-ember-template-imports@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@glint/environment-ember-template-imports/-/environment-ember-template-imports-1.1.0.tgz#908ec8b38a5837f4c28b12e4a3fe6c547366d37a" + integrity sha512-duNk2NzDilNctzz+XHecICfMMt8LjLEhaWPiBvFfFeLW35gqZo2XQpeBQI/pq2gH0ZbWOP7rr9Kde12v7ossZg== + +"@glint/template@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@glint/template/-/template-1.1.0.tgz#5734f8f4d9f425676c97bb701c9af03dd2e783ab" + integrity sha512-gK4tifrw7mIMYECzGeG5jrez2lY0TlwE584cnoYOFhzxXKrsuungdiebd7LDwjvfQpImQd1JUSQr3u/uF/XYJg== "@handlebars/parser@~2.0.0": version "2.0.0" @@ -1819,6 +2157,13 @@ estree-walker "^2.0.2" picomatch "^2.3.1" +"@simple-dom/document@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@simple-dom/document/-/document-1.4.0.tgz#af60855f957f284d436983798ef1006cca1a1678" + integrity sha512-/RUeVH4kuD3rzo5/91+h4Z1meLSLP66eXqpVAw/4aZmYozkeqUkMprq0znL4psX/adEed5cBgiNJcfMz/eKZLg== + dependencies: + "@simple-dom/interface" "^1.4.0" + "@simple-dom/interface@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@simple-dom/interface/-/interface-1.4.0.tgz#e8feea579232017f89b0138e2726facda6fbb71f" @@ -2907,6 +3252,11 @@ backbone@^1.1.2: dependencies: underscore ">=1.8.3" +backburner.js@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/backburner.js/-/backburner.js-2.7.0.tgz#36a5b8a8bfceb7efc8ad56e006a238924acfd67e" + integrity sha512-eBZC6r7wT+YYAOKeru8IqgzOimz3VgyspXiZ1k6MI8i10zUdU8cnNII56rlnItQ89cHgQO3C/nPuFW3V9di+zg== + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -4245,6 +4595,11 @@ convert-source-map@^1.7.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -4748,7 +5103,7 @@ electron-to-chromium@^1.4.431: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.470.tgz#0e932816be8d5f2b491ad2aa449ea47db4785398" integrity sha512-zZM48Lmy2FKWgqyvsX9XK+J6FfP7aCDUFLmgooLJzA7v1agCs/sxSoBpTIwDLhmbhpx9yJIxj2INig/ncjJRqg== -ember-auto-import@^2.5.0, ember-auto-import@^2.6.0: +ember-auto-import@^2.6.0: version "2.6.2" resolved "https://registry.yarnpkg.com/ember-auto-import/-/ember-auto-import-2.6.2.tgz#ea0bfccb79c0601d2857764ebe04a67559a57b48" integrity sha512-h0bdE1atVqEXkE+9OTkEi2wRHBpJilKn6iXlbrOS2nI4HGpWlqmUjWmQk/iMFad+1XEDBvNJnikxgtKb/GFL5A== @@ -4937,6 +5292,26 @@ ember-cli-htmlbars@^6.2.0: silent-error "^1.1.1" walk-sync "^2.2.0" +ember-cli-htmlbars@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-6.3.0.tgz#ac85f2bbd09788992ab7f9ca832cd044fb8e5798" + integrity sha512-N9Y80oZfcfWLsqickMfRd9YByVcTGyhYRnYQ2XVPVrp6jyUyOeRWmEAPh7ERSXpp8Ws4hr/JB9QVQrn/yZa+Ag== + dependencies: + "@ember/edition-utils" "^1.2.0" + babel-plugin-ember-template-compilation "^2.0.0" + babel-plugin-htmlbars-inline-precompile "^5.3.0" + broccoli-debug "^0.6.5" + broccoli-persistent-filter "^3.1.2" + broccoli-plugin "^4.0.3" + ember-cli-version-checker "^5.1.2" + fs-tree-diff "^2.0.1" + hash-for-dep "^1.5.1" + heimdalljs-logger "^0.1.10" + js-string-escape "^1.0.1" + semver "^7.3.4" + silent-error "^1.1.1" + walk-sync "^2.2.0" + ember-cli-inject-live-reload@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ember-cli-inject-live-reload/-/ember-cli-inject-live-reload-2.1.0.tgz#ef63c733c133024d5726405a3c247fa12e88a385" @@ -5265,25 +5640,41 @@ ember-source-channel-url@^3.0.0: dependencies: node-fetch "^2.6.0" -ember-source@^4.12.3: - version "4.12.3" - resolved "https://registry.yarnpkg.com/ember-source/-/ember-source-4.12.3.tgz#6c401f6a856bb2f7f2871f56d46e7496f97e936a" - integrity sha512-UuFpMWf931pEWBPuujkaMYhsoPvFyZc+tMYjlUn7um20uL+hWs+k2n/TxMVuxydSzJLnxrXz81nTwbYIlgRWdw== +ember-source@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ember-source/-/ember-source-5.2.0.tgz#9cfa89b8b32b658fa70dc59c11264daf77e765f5" + integrity sha512-rr8qLnyW6QV5N4ItwFluTH/SZ5W7uGsYL5GP0tYA2z9zFqD0g2TTJRBsaUPYFlHqcuUhWHiGg+xOyLcHZJOrig== dependencies: "@babel/helper-module-imports" "^7.16.7" - "@babel/plugin-transform-block-scoping" "^7.20.5" + "@babel/plugin-transform-block-scoping" "^7.21.0" "@ember/edition-utils" "^1.2.0" + "@glimmer/compiler" "0.84.2" + "@glimmer/component" "^1.1.2" + "@glimmer/destroyable" "0.84.2" + "@glimmer/env" "^0.1.7" + "@glimmer/global-context" "0.84.3" + "@glimmer/interfaces" "0.84.2" + "@glimmer/manager" "0.84.2" + "@glimmer/node" "0.84.2" + "@glimmer/opcode-compiler" "0.84.2" + "@glimmer/owner" "0.84.2" + "@glimmer/program" "0.84.2" + "@glimmer/reference" "0.84.2" + "@glimmer/runtime" "0.84.2" + "@glimmer/syntax" "0.84.2" + "@glimmer/validator" "0.84.2" "@glimmer/vm-babel-plugins" "0.84.2" "@simple-dom/interface" "^1.4.0" babel-plugin-debug-macros "^0.3.4" babel-plugin-filter-imports "^4.0.0" + backburner.js "^2.7.0" broccoli-concat "^4.2.5" broccoli-debug "^0.6.4" broccoli-file-creator "^2.1.1" broccoli-funnel "^3.0.8" broccoli-merge-trees "^4.2.0" chalk "^4.0.0" - ember-auto-import "^2.5.0" + ember-auto-import "^2.6.3" ember-cli-babel "^7.26.11" ember-cli-get-component-path-option "^1.0.0" ember-cli-is-package-missing "^1.0.0" @@ -5295,6 +5686,8 @@ ember-source@^4.12.3: ember-router-generator "^2.0.0" inflection "^1.13.2" resolve "^1.22.0" + route-recognizer "^0.3.4" + router_js "^8.0.3" semver "^7.3.8" silent-error "^1.1.1" @@ -8085,7 +8478,7 @@ json5@^0.5.1: resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" integrity sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw== -json5@^2.1.2, json5@^2.2.2: +json5@^2.1.2, json5@^2.2.2, json5@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== @@ -10181,11 +10574,27 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^2.5.1, prettier@^2.8.8: +prettier-plugin-ember-template-tag@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/prettier-plugin-ember-template-tag/-/prettier-plugin-ember-template-tag-1.1.0.tgz#b144c36736cad6c03db6612d740ad59427e616c7" + integrity sha512-zJTC+NhEU0kHNnVh7OtcvMmkJmYTgFTist76FP9q07m9+WCvcaunR1sTFIOlGE9TH/5UGm6rlF86Umt9ouorAg== + dependencies: + "@babel/core" "^7.22.11" + "@glimmer/syntax" "^0.84.3" + ember-cli-htmlbars "^6.3.0" + ember-template-imports "^3.4.2" + prettier "^3.0.3" + +prettier@^2.5.1: version "2.8.8" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +prettier@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643" + integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg== + printf@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/printf/-/printf-0.6.1.tgz#b9afa3d3b55b7f2e8b1715272479fc756ed88650" @@ -10863,6 +11272,18 @@ rollup@^3.28.0: optionalDependencies: fsevents "~2.3.2" +route-recognizer@^0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/route-recognizer/-/route-recognizer-0.3.4.tgz#39ab1ffbce1c59e6d2bdca416f0932611e4f3ca3" + integrity sha512-2+MhsfPhvauN1O8KaXpXAOfR/fwe8dnUXVM+xw7yt40lJRfPVQxV6yryZm0cgRvAj5fMF/mdRZbL2ptwbs5i2g== + +router_js@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/router_js/-/router_js-8.0.3.tgz#c00912925839bd2a427c8e12b6cec6bc0f496947" + integrity sha512-lSgNMksk/wp8nspLX3Pn6QD499FUjwYMkgP99RxqKEScil4DKC/59YezpEZ318zGtkq8WR01VBhH+/u3InlLgg== + dependencies: + "@glimmer/env" "^0.1.7" + rsvp@^3.0.14, rsvp@^3.0.17, rsvp@^3.0.18, rsvp@^3.0.21, rsvp@^3.0.6, rsvp@^3.1.0: version "3.6.2" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" @@ -11052,7 +11473,7 @@ semver-diff@^4.0.0: dependencies: semver "^7.3.5" -semver@7.5.4, semver@^7.0.0, semver@^7.1.3, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: +semver@7.5.4, semver@^7.0.0, semver@^7.1.3, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==