diff --git a/ember-data-types/q/params.ts b/ember-data-types/q/params.ts new file mode 100644 index 00000000000..a2053f79e9c --- /dev/null +++ b/ember-data-types/q/params.ts @@ -0,0 +1,6 @@ +export type SerializablePrimitive = string | number | boolean | null; +export type Serializable = SerializablePrimitive | SerializablePrimitive[]; +export type QueryParamsSerializationOptions = { + arrayFormat?: 'bracket' | 'indices' | 'repeat' | 'comma'; +}; +export type QueryParamsSource = Record | URLSearchParams; diff --git a/ember-data-types/q/request.ts b/ember-data-types/q/request.ts new file mode 100644 index 00000000000..0c66448387f --- /dev/null +++ b/ember-data-types/q/request.ts @@ -0,0 +1,230 @@ +// FIXME: Seems weird that this import specifies ember-data +import { ResourceIdentifierObject } from './ember-data-json-api'; +import { StableRecordIdentifier } from './identifier'; +import { QueryParamsSerializationOptions } from './params'; + +type Store = unknown; + +export const SkipCache = Symbol.for('wd:skip-cache'); +export const EnableHydration = Symbol.for('wd:enable-hydration'); +export const IS_FUTURE = Symbol('IS_FUTURE'); +export const STRUCTURED = Symbol('DOC'); + +export type HTTPMethod = 'GET' | 'OPTIONS' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD'; + +export type CacheOptions = { + key?: string; + reload?: boolean; + backgroundReload?: boolean; +}; +export type FindRecordRequestOptions = { + url: string; + method: 'GET'; + headers: Headers; + cacheOptions: CacheOptions; + op: 'findRecord'; + records: [ResourceIdentifierObject]; +}; + +export type QueryRequestOptions = { + url: string; + method: 'GET'; + headers: Headers; + cacheOptions: CacheOptions; + op: 'query'; +}; + +export type PostQueryRequestOptions = { + url: string; + method: 'POST' | 'QUERY'; + headers: Headers; + body: string; + cacheOptions: CacheOptions & { key: string }; + op: 'query'; +}; + +export type DeleteRequestOptions = { + url: string; + method: 'DELETE'; + headers: Headers; + op: 'deleteRecord'; + data: { + record: StableRecordIdentifier; + }; +}; + +export type UpdateRequestOptions = { + url: string; + method: 'PATCH' | 'PUT'; + headers: Headers; + op: 'updateRecord'; + data: { + record: StableRecordIdentifier; + }; +}; + +export type CreateRequestOptions = { + url: string; + method: 'POST'; + headers: Headers; + op: 'createRecord'; + data: { + record: StableRecordIdentifier; + }; +}; + +export type RemotelyAccessibleIdentifier = { + id: string; + type: string; + lid?: string; +}; + +export type ConstrainedRequestOptions = { + reload?: boolean; + backgroundReload?: boolean; + host?: string; + namespace?: string; + resourcePath?: string; + urlParamsSettings?: QueryParamsSerializationOptions; +}; + +export type FindRecordOptions = ConstrainedRequestOptions & { + include?: string | string[]; +}; + +export interface StructuredDataDocument { + [STRUCTURED]?: true; + request: ImmutableRequestInfo; + response: Response | ResponseInfo | null; + content: T; +} +export interface StructuredErrorDocument extends Error { + [STRUCTURED]?: true; + request: ImmutableRequestInfo; + response: Response | ResponseInfo | null; + error: string | object; + content?: T; +} +export type StructuredDocument = StructuredDataDocument | StructuredErrorDocument; + +interface Request { + controller?: AbortController; + /* Returns the cache mode associated with request, which is a string indicating how the request will interact with the browser's cache when fetching. */ + cache?: RequestCache; + /* Returns the credentials mode associated with request, which is a string indicating whether credentials will be sent with the request always, never, or only when sent to a same-origin URL. */ + credentials?: RequestCredentials; + /* Returns the kind of resource requested by request, e.g., "document" or "script". */ + destination?: RequestDestination; + /* Returns a Headers object consisting of the headers associated with request. Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the "Host" header. */ + headers?: Headers; + /* Returns request's subresource integrity metadata, which is a cryptographic hash of the resource being fetched. Its value consists of multiple hashes separated by whitespace. [SRI] */ + integrity?: string; + /* Returns a boolean indicating whether or not request can outlive the global in which it was created. */ + keepalive?: boolean; + /* Returns request's HTTP method, which is "GET" by default. */ + method?: HTTPMethod; + /* Returns the mode associated with request, which is a string indicating whether the request will use CORS, or will be restricted to same-origin URLs. */ + mode?: RequestMode; + /* Returns the redirect mode associated with request, which is a string indicating how redirects for the request will be handled during fetching. A request will follow redirects by default. */ + redirect?: RequestRedirect; + /* Returns the referrer of request. Its value can be a same-origin URL if explicitly set in init, the empty string to indicate no referrer, and "about:client" when defaulting to the global's default. This is used during fetching to determine the value of the `Referer` header of the request being made. */ + referrer?: string; + /* Returns the referrer policy associated with request. This is used during fetching to compute the value of the request's referrer. */ + referrerPolicy?: ReferrerPolicy; + /* Returns the signal associated with request, which is an AbortSignal object indicating whether or not request has been aborted, and its abort event handler. */ + signal?: AbortSignal; + /* Returns the URL of request as a string. */ + url?: string; + body?: BodyInit | null; +} + +export type ImmutableHeaders = Headers & { clone?(): Headers; toJSON(): [string, string][] }; + +export interface RequestInfo extends Request { + cacheOptions?: { key?: string; reload?: boolean; backgroundReload?: boolean; [SkipCache]?: true }; + store?: Store; + + op?: string; + records?: StableRecordIdentifier[]; + + disableTestWaiter?: boolean; + /* + * data that a handler should convert into + * the query (GET) or body (POST) + */ + data?: Record; + /* + * options specifically intended for handlers + * to utilize to process the request + */ + options?: Record; +} + +export interface ImmutableRequestInfo { + readonly cacheOptions?: { + key?: string; + reload?: boolean; + backgroundReload?: boolean; + [SkipCache]?: true; + }; + readonly store?: Store; + + readonly op?: string; + readonly records?: StableRecordIdentifier[]; + + readonly disableTestWaiter?: boolean; + /* Returns the cache mode associated with request, which is a string indicating how the request will interact with the browser's cache when fetching. */ + readonly cache?: RequestCache; + /* Returns the credentials mode associated with request, which is a string indicating whether credentials will be sent with the request always, never, or only when sent to a same-origin URL. */ + readonly credentials?: RequestCredentials; + /* Returns the kind of resource requested by request, e.g., "document" or "script". */ + readonly destination?: RequestDestination; + /* Returns a Headers object consisting of the headers associated with request. Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the "Host" header. */ + readonly headers?: Headers & { clone?(): Headers }; + /* Returns request's subresource integrity metadata, which is a cryptographic hash of the resource being fetched. Its value consists of multiple hashes separated by whitespace. [SRI] */ + readonly integrity?: string; + /* Returns a boolean indicating whether or not request can outlive the global in which it was created. */ + readonly keepalive?: boolean; + /* Returns request's HTTP method, which is "GET" by default. */ + readonly method?: HTTPMethod; + /* Returns the mode associated with request, which is a string indicating whether the request will use CORS, or will be restricted to same-origin URLs. */ + readonly mode?: RequestMode; + /* Returns the redirect mode associated with request, which is a string indicating how redirects for the request will be handled during fetching. A request will follow redirects by default. */ + readonly redirect?: RequestRedirect; + /* Returns the referrer of request. Its value can be a same-origin URL if explicitly set in init, the empty string to indicate no referrer, and "about:client" when defaulting to the global's default. This is used during fetching to determine the value of the `Referer` header of the request being made. */ + readonly referrer?: string; + /* Returns the referrer policy associated with request. This is used during fetching to compute the value of the request's referrer. */ + readonly referrerPolicy?: ReferrerPolicy; + /* Returns the signal associated with request, which is an AbortSignal object indicating whether or not request has been aborted, and its abort event handler. */ + readonly signal?: AbortSignal; + /* Returns the URL of request as a string. */ + readonly url?: string; + /* + * data that a handler should convert into + * the query (GET) or body (POST) + */ + readonly data?: Record; + /* + * options specifically intended for handlers + * to utilize to process the request + */ + readonly options?: Record; +} + +export interface ResponseInfo { + readonly headers: ImmutableHeaders; // to do, maybe not this? + readonly ok: boolean; + readonly redirected: boolean; + readonly status: number; + readonly statusText: string; + readonly type: string; + readonly url: string; +} + +export interface RequestContext { + request: ImmutableRequestInfo; + id: number; + + setStream(stream: ReadableStream): void; + setResponse(response: Response | ResponseInfo): void; +} diff --git a/package.json b/package.json index 0bbc431142c..2aea044b883 100644 --- a/package.json +++ b/package.json @@ -136,4 +136,4 @@ "ember-cli-htmlbars": "^6.2.0" } } -} \ No newline at end of file +} diff --git a/packages/active-record/LICENSE.md b/packages/active-record/LICENSE.md new file mode 100644 index 00000000000..97a483b5d8f --- /dev/null +++ b/packages/active-record/LICENSE.md @@ -0,0 +1,11 @@ +The MIT License (MIT) + +Copyright (C) 2017-2023 Ember.js contributors +Portions Copyright (C) 2011-2017 Tilde, Inc. and contributors. +Portions Copyright (C) 2011 LivingSocial Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/active-record/README.md b/packages/active-record/README.md new file mode 100644 index 00000000000..09e14ecd1eb --- /dev/null +++ b/packages/active-record/README.md @@ -0,0 +1,69 @@ +

+ + +

+ +

Elegantly composable. Made for ActiveRecord

+ +This package provides utilities for working with **Active**Record APIs with [*Ember***Data**](https://github.com/emberjs/data/). + +## Installation + +Install using your javascript package manager of choice. For instance with [pnpm](https://pnpm.io/) + +```no-highlight +pnpm add @ember-data/active-record +``` + +## Getting Started + +If this package is how you are first learning about EmberData, we recommend starting with learning about the [Store](https://github.com/emberjs/data/blob/main/packages/store/README.md) and [Requests](https://github.com/emberjs/data/blob/main/packages/request/README.md) + +## Request Builders + +Request builders are functions that produce [Fetch Options](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). They take a few contextual inputs about the request you want to make, abstracting away the gnarlier details. + +For instance, to fetch a resource from your API + +```ts +import { findRecord } from '@ember-data/active-record/request'; + +const options = findRecord('ember-developer', '1', { include: ['pets', 'friends'] }); + +/* + => { + url: 'https://api.example.com/v1/ember_developers/1?include=friends,pets', + method: 'GET', + headers: , // 'Content-Type': 'application/json;charset=utf-8' + op: 'findRecord'; + records: [{ type: 'ember-developer', id: '1' }] + } +*/ +``` + +Request builder output may be used with either `requestManager.request` or `store.request`. + +URLs are stable. The same query will produce the same URL every time, even if the order of keys in +the query or values in an array changes. + +URLs follow the most common ActiveRecord format (underscored pluralized resource types). + +### Available Builders + +- [createRecord]() +- [deleteRecord]() +- [findRecord]() +- [query]() +- [updateRecord]() diff --git a/packages/active-record/addon-main.js b/packages/active-record/addon-main.js new file mode 100644 index 00000000000..459ef9174ca --- /dev/null +++ b/packages/active-record/addon-main.js @@ -0,0 +1,19 @@ +module.exports = { + name: require('./package.json').name, + + treeForVendor() { + return; + }, + treeForPublic() { + return; + }, + treeForStyles() { + return; + }, + treeForAddonStyles() { + return; + }, + treeForApp() { + return; + }, +}; diff --git a/packages/active-record/babel.config.json b/packages/active-record/babel.config.json new file mode 100644 index 00000000000..0e04314a08c --- /dev/null +++ b/packages/active-record/babel.config.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + "@babel/plugin-transform-runtime", + ["@babel/plugin-transform-typescript", { "allowDeclareFields": true }], + ["@babel/plugin-proposal-decorators", { "legacy": true }], + "@babel/plugin-transform-class-properties" + ] +} diff --git a/packages/active-record/ember-data-logo-dark.svg b/packages/active-record/ember-data-logo-dark.svg new file mode 100644 index 00000000000..737a4aa4321 --- /dev/null +++ b/packages/active-record/ember-data-logo-dark.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/packages/active-record/ember-data-logo-light.svg b/packages/active-record/ember-data-logo-light.svg new file mode 100644 index 00000000000..58ac3d4e544 --- /dev/null +++ b/packages/active-record/ember-data-logo-light.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/packages/active-record/package.json b/packages/active-record/package.json new file mode 100644 index 00000000000..16ce3d5ebfd --- /dev/null +++ b/packages/active-record/package.json @@ -0,0 +1,110 @@ +{ + "name": "@ember-data/active-record", + "description": "ActiveRecord Format Support for EmberData", + "version": "4.12.5", + "private": false, + "license": "MIT", + "author": "Chris Thoburn ", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com:emberjs/data.git", + "directory": "packages/active-record" + }, + "homepage": "https://github.com/emberjs/data", + "bugs": "https://github.com/emberjs/data/issues", + "engines": { + "node": "16.* || >= 18.*" + }, + "keywords": [ + "ember-addon" + ], + "volta": { + "extends": "../../package.json" + }, + "dependencies": { + "ember-cli-babel": "^8.2.0", + "pnpm-sync-dependencies-meta-injected": "0.0.10" + }, + "peerDependencies": { + "@ember-data/request-utils": "workspace:4.12.5", + "@ember-data/store": "^4.12.0 || ^5.0.0", + "@ember/string": "^3.1.1", + "ember-inflector": "^4.0.2" + }, + "dependenciesMeta": { + "ember-inflector": { + "injected": true + }, + "@ember/string": { + "injected": true + }, + "@ember-data/store": { + "injected": true + }, + "@ember-data/request-utils": { + "injected": true + }, + "@ember-data/request": { + "injected": true + }, + "@ember-data/tracking": { + "injected": true + } + }, + "files": [ + "addon-main.js", + "addon", + "README.md", + "LICENSE.md", + "ember-data-logo-dark.svg", + "ember-data-logo-light.svg", + "unstable-preview-types" + ], + "exports": { + "./*": { + "types": "./unstable-preview-types/*.d.ts", + "default": "./addon/*.js" + } + }, + "scripts": { + "build:types": "tsc --build", + "build:client": "rollup --config && babel ./addon --out-dir addon --plugins=../private-build-infra/src/transforms/babel-plugin-transform-ext.js", + "_build": "bun run build:client && bun run build:types", + "prepack": "pnpm build", + "_syncPnpm": "bun run sync-dependencies-meta-injected" + }, + "ember-addon": { + "main": "addon-main.js", + "type": "addon", + "version": 1 + }, + "devDependencies": { + "@babel/cli": "^7.23.4", + "@babel/core": "^7.23.3", + "@babel/plugin-proposal-decorators": "^7.23.3", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-runtime": "^7.23.4", + "@babel/plugin-transform-typescript": "^7.23.4", + "@babel/preset-env": "^7.23.3", + "@babel/preset-typescript": "^7.23.3", + "@babel/runtime": "^7.23.4", + "@ember-data/request": "workspace:4.12.5", + "@ember-data/request-utils": "workspace:4.12.5", + "@ember-data/store": "workspace:4.12.5", + "@ember-data/tracking": "workspace:4.12.5", + "@ember/string": "^3.1.1", + "@embroider/addon-dev": "^4.1.2", + "@glimmer/component": "^1.1.2", + "@rollup/plugin-babel": "^6.0.4", + "@rollup/plugin-node-resolve": "^15.2.3", + "@warp-drive/internal-config": "workspace:4.12.5", + "ember-inflector": "^4.0.2", + "ember-source": "~5.4.0", + "rollup": "^4.5.0", + "typescript": "^5.3.2", + "walk-sync": "^3.0.0" + }, + "ember": { + "edition": "octane" + } +} diff --git a/packages/active-record/rollup.config.mjs b/packages/active-record/rollup.config.mjs new file mode 100644 index 00000000000..683b7c9b8b0 --- /dev/null +++ b/packages/active-record/rollup.config.mjs @@ -0,0 +1,33 @@ +import { Addon } from '@embroider/addon-dev/rollup'; +import babel from '@rollup/plugin-babel'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; + +import { external } from '@warp-drive/internal-config/rollup/external.js'; + +const addon = new Addon({ + srcDir: 'src', + destDir: 'addon', +}); + +export default { + // This provides defaults that work well alongside `publicEntrypoints` below. + // You can augment this if you need to. + output: addon.output(), + + external: external(['@ember/debug']), + + plugins: [ + // These are the modules that users should be able to import from your + // addon. Anything not listed here may get optimized away. + addon.publicEntrypoints(['request.js']), + + nodeResolve({ extensions: ['.ts'] }), + babel({ + extensions: ['.ts'], + babelHelpers: 'runtime', // we should consider "external", + }), + + // Remove leftover build artifacts when starting a new build. + addon.clean(), + ], +}; diff --git a/packages/active-record/src/-private/builders/-utils.ts b/packages/active-record/src/-private/builders/-utils.ts new file mode 100644 index 00000000000..7ab3d21796d --- /dev/null +++ b/packages/active-record/src/-private/builders/-utils.ts @@ -0,0 +1,25 @@ +import type { UrlOptions } from '@ember-data/request-utils'; +import type { CacheOptions, ConstrainedRequestOptions } from '@ember-data/types/q/request'; + +export function copyForwardUrlOptions(urlOptions: UrlOptions, options: ConstrainedRequestOptions): void { + if ('host' in options) { + urlOptions.host = options.host; + } + if ('namespace' in options) { + urlOptions.namespace = options.namespace; + } + if ('resourcePath' in options) { + urlOptions.resourcePath = options.resourcePath; + } +} + +export function extractCacheOptions(options: ConstrainedRequestOptions) { + const cacheOptions: CacheOptions = {}; + if ('reload' in options) { + cacheOptions.reload = options.reload; + } + if ('backgroundReload' in options) { + cacheOptions.backgroundReload = options.backgroundReload; + } + return cacheOptions; +} diff --git a/packages/active-record/src/-private/builders/find-record.ts b/packages/active-record/src/-private/builders/find-record.ts new file mode 100644 index 00000000000..d21b6e68fed --- /dev/null +++ b/packages/active-record/src/-private/builders/find-record.ts @@ -0,0 +1,114 @@ +/** + * @module @ember-data/active-record/request + */ +import { underscore } from '@ember/string'; + +import { pluralize } from 'ember-inflector'; + +import { buildBaseURL, buildQueryParams, type FindRecordUrlOptions } from '@ember-data/request-utils'; +import type { + ConstrainedRequestOptions, + FindRecordRequestOptions, + RemotelyAccessibleIdentifier, +} from '@ember-data/types/q/request'; + +import { copyForwardUrlOptions, extractCacheOptions } from './-utils'; + +type FindRecordOptions = ConstrainedRequestOptions & { + include?: string | string[]; +}; + +/** + * Builds request options to fetch a single resource by a known id or identifier + * configured for the url and header expectations of most ActiveRecord APIs. + * + * **Basic Usage** + * + * ```ts + * import { findRecord } from '@ember-data/active-record/request'; + * + * const data = await store.request(findRecord('person', '1')); + * ``` + * + * **With Options** + * + * ```ts + * import { findRecord } from '@ember-data/active-record/request'; + * + * const options = findRecord('person', '1', { include: ['pets', 'friends'] }); + * const data = await store.request(options); + * ``` + * + * **With an Identifier** + * + * ```ts + * import { findRecord } from '@ember-data/active-record/request'; + * + * const options = findRecord({ type: 'person', id: '1' }, { include: ['pets', 'friends'] }); + * const data = await store.request(options); + * ``` + * + * **Supplying Options to Modify the Request Behavior** + * + * The following options are supported: + * + * - `host` - The host to use for the request, defaults to the `host` configured with `setBuildURLConfig`. + * - `namespace` - The namespace to use for the request, defaults to the `namespace` configured with `setBuildURLConfig`. + * - `resourcePath` - The resource path to use for the request, defaults to pluralizing and underscoring the supplied type + * - `reload` - Whether to forcibly reload the request if it is already in the store, not supplying this + * option will delegate to the store's lifetimes service, defaulting to `false` if none is configured. + * - `backgroundReload` - Whether to reload the request if it is already in the store, but to also resolve the + * promise with the cached value, not supplying this option will delegate to the store's lifetimes service, + * defaulting to `false` if none is configured. + * - `urlParamsSetting` - an object containing options for how to serialize the query params (see `buildQueryParams`) + * + * ```ts + * import { findRecord } from '@ember-data/active-record/request'; + * + * const options = findRecord('person', '1', { include: ['pets', 'friends'] }, { namespace: 'api/v2' }); + * const data = await store.request(options); + * ``` + * + * @method findRecord + * @public + * @static + * @for @ember-data/active-record/request + * @param identifier + * @param options + */ +export function findRecord( + identifier: RemotelyAccessibleIdentifier, + options?: FindRecordOptions +): FindRecordRequestOptions; +export function findRecord(type: string, id: string, options?: FindRecordOptions): FindRecordRequestOptions; +export function findRecord( + arg1: string | RemotelyAccessibleIdentifier, + arg2: string | FindRecordOptions | undefined, + arg3?: FindRecordOptions +): FindRecordRequestOptions { + const identifier: RemotelyAccessibleIdentifier = typeof arg1 === 'string' ? { type: arg1, id: arg2 as string } : arg1; + const options = ((typeof arg1 === 'string' ? arg3 : arg2) || {}) as FindRecordOptions; + const cacheOptions = extractCacheOptions(options); + const urlOptions: FindRecordUrlOptions = { + identifier, + op: 'findRecord', + resourcePath: pluralize(underscore(identifier.type)), + }; + + copyForwardUrlOptions(urlOptions, options); + + const url = buildBaseURL(urlOptions); + const headers = new Headers(); + headers.append('Accept', 'application/json;charset=utf-8'); + + return { + url: options.include?.length + ? `${url}?${buildQueryParams({ include: options.include }, options.urlParamsSettings)}` + : url, + method: 'GET', + headers, + cacheOptions, + op: 'findRecord', + records: [identifier], + }; +} diff --git a/packages/active-record/src/-private/builders/query.ts b/packages/active-record/src/-private/builders/query.ts new file mode 100644 index 00000000000..919827c691d --- /dev/null +++ b/packages/active-record/src/-private/builders/query.ts @@ -0,0 +1,90 @@ +/** + * @module @ember-data/active-record/request + */ +import { underscore } from '@ember/string'; + +import { pluralize } from 'ember-inflector'; + +import { buildBaseURL, buildQueryParams, type QueryUrlOptions } from '@ember-data/request-utils'; +import type { QueryParamsSource } from '@ember-data/types/q/params'; +import type { ConstrainedRequestOptions, QueryRequestOptions } from '@ember-data/types/q/request'; + +import { copyForwardUrlOptions, extractCacheOptions } from './-utils'; + +/** + * Builds request options to query for resources, usually by a primary + * type, configured for the url and header expectations of most ActiveRecord APIs. + * + * **Basic Usage** + * + * ```ts + * import { query } from '@ember-data/active-record/request'; + * + * const data = await store.request(query('person')); + * ``` + * + * **With Query Params** + * + * ```ts + * import { query } from '@ember-data/active-record/request'; + * + * const options = query('person', { include: ['pets', 'friends'] }); + * const data = await store.request(options); + * ``` + * + * **Supplying Options to Modify the Request Behavior** + * + * The following options are supported: + * + * - `host` - The host to use for the request, defaults to the `host` configured with `setBuildURLConfig`. + * - `namespace` - The namespace to use for the request, defaults to the `namespace` configured with `setBuildURLConfig`. + * - `resourcePath` - The resource path to use for the request, defaults to pluralizing and underscoring the supplied type + * - `reload` - Whether to forcibly reload the request if it is already in the store, not supplying this + * option will delegate to the store's lifetimes service, defaulting to `false` if none is configured. + * - `backgroundReload` - Whether to reload the request if it is already in the store, but to also resolve the + * promise with the cached value, not supplying this option will delegate to the store's lifetimes service, + * defaulting to `false` if none is configured. + * - `urlParamsSetting` - an object containing options for how to serialize the query params (see `buildQueryParams`) + * + * ```ts + * import { query } from '@ember-data/active-record/request'; + * + * const options = query('person', { include: ['pets', 'friends'] }, { reload: true }); + * const data = await store.request(options); + * ``` + * + * @method query + * @public + * @static + * @for @ember-data/active-record/request + * @param identifier + * @param query + * @param options + */ +export function query( + type: string, + // eslint-disable-next-line @typescript-eslint/no-shadow + query: QueryParamsSource = {}, + options: ConstrainedRequestOptions = {} +): QueryRequestOptions { + const cacheOptions = extractCacheOptions(options); + const urlOptions: QueryUrlOptions = { + identifier: { type }, + op: 'query', + resourcePath: pluralize(underscore(type)), + }; + + copyForwardUrlOptions(urlOptions, options); + + const url = buildBaseURL(urlOptions); + const headers = new Headers(); + headers.append('Accept', 'application/json;charset=utf-8'); + + return { + url: `${url}?${buildQueryParams(query, options.urlParamsSettings)}`, + method: 'GET', + headers, + cacheOptions, + op: 'query', + }; +} diff --git a/packages/active-record/src/-private/builders/save-record.ts b/packages/active-record/src/-private/builders/save-record.ts new file mode 100644 index 00000000000..52026d2a927 --- /dev/null +++ b/packages/active-record/src/-private/builders/save-record.ts @@ -0,0 +1,251 @@ +import { assert } from '@ember/debug'; +import { underscore } from '@ember/string'; + +import { pluralize } from 'ember-inflector'; + +import { + buildBaseURL, + type CreateRecordUrlOptions, + type DeleteRecordUrlOptions, + type UpdateRecordUrlOptions, +} from '@ember-data/request-utils'; +import { recordIdentifierFor } from '@ember-data/store'; +import type { StableExistingRecordIdentifier, StableRecordIdentifier } from '@ember-data/types/q/identifier'; +import { RecordInstance } from '@ember-data/types/q/record-instance'; +import type { + ConstrainedRequestOptions, + CreateRequestOptions, + DeleteRequestOptions, + UpdateRequestOptions, +} from '@ember-data/types/q/request'; + +import { copyForwardUrlOptions } from './-utils'; + +function isExisting(identifier: StableRecordIdentifier): identifier is StableExistingRecordIdentifier { + return 'id' in identifier && identifier.id !== null && 'type' in identifier && identifier.type !== null; +} + +/** + * Builds request options to delete record for resources, + * configured for the url, method and header expectations of ActiveRecord APIs. + * + * **Basic Usage** + * + * ```ts + * import { deleteRecord } from '@ember-data/active-record/request'; + * + * const person = this.store.peekRecord('person', '1'); + * + * // mark record as deleted + * store.deleteRecord(person); + * + * // persist deletion + * const data = await store.request(deleteRecord(person)); + * ``` + * + * **Supplying Options to Modify the Request Behavior** + * + * The following options are supported: + * + * - `host` - The host to use for the request, defaults to the `host` configured with `setBuildURLConfig`. + * - `namespace` - The namespace to use for the request, defaults to the `namespace` configured with `setBuildURLConfig`. + * - `resourcePath` - The resource path to use for the request, defaults to pluralizing the supplied type + * - `reload` - Whether to forcibly reload the request if it is already in the store, not supplying this + * option will delegate to the store's lifetimes service, defaulting to `false` if none is configured. + * - `backgroundReload` - Whether to reload the request if it is already in the store, but to also resolve the + * promise with the cached value, not supplying this option will delegate to the store's lifetimes service, + * defaulting to `false` if none is configured. + * - `urlParamsSetting` - an object containing options for how to serialize the query params (see `buildQueryParams`) + * + * ```ts + * import { deleteRecord } from '@ember-data/active-record/request'; + * + * const person = this.store.peekRecord('person', '1'); + * + * // mark record as deleted + * store.deleteRecord(person); + * + * // persist deletion + * const options = deleteRecord(person, { namespace: 'api/v1' }); + * const data = await store.request(options); + * ``` + * + * @method deleteRecord + * @public + * @static + * @for @ember-data/active-record/request + * @param record + * @param options + */ +export function deleteRecord(record: RecordInstance, options: ConstrainedRequestOptions = {}): DeleteRequestOptions { + const identifier = recordIdentifierFor(record); + assert(`Expected to be given a record instance`, identifier); + assert(`Cannot delete a record that does not have an associated type and id.`, isExisting(identifier)); + + const urlOptions: DeleteRecordUrlOptions = { + identifier: identifier, + op: 'deleteRecord', + resourcePath: pluralize(underscore(identifier.type)), + }; + + copyForwardUrlOptions(urlOptions, options); + + const url = buildBaseURL(urlOptions); + const headers = new Headers(); + headers.append('Accept', 'application/json;charset=utf-8'); + + return { + url, + method: 'DELETE', + headers, + op: 'deleteRecord', + data: { + record: identifier, + }, + }; +} + +/** + * Builds request options to create new record for resources, + * configured for the url, method and header expectations of most ActiveRecord APIs. + * + * **Basic Usage** + * + * ```ts + * import { createRecord } from '@ember-data/active-record/request'; + * + * const person = this.store.createRecord('person', { name: 'Ted' }); + * const data = await store.request(createRecord(person)); + * ``` + * + * **Supplying Options to Modify the Request Behavior** + * + * The following options are supported: + * + * - `host` - The host to use for the request, defaults to the `host` configured with `setBuildURLConfig`. + * - `namespace` - The namespace to use for the request, defaults to the `namespace` configured with `setBuildURLConfig`. + * - `resourcePath` - The resource path to use for the request, defaults to pluralizing the supplied type + * - `reload` - Whether to forcibly reload the request if it is already in the store, not supplying this + * option will delegate to the store's lifetimes service, defaulting to `false` if none is configured. + * - `backgroundReload` - Whether to reload the request if it is already in the store, but to also resolve the + * promise with the cached value, not supplying this option will delegate to the store's lifetimes service, + * defaulting to `false` if none is configured. + * - `urlParamsSetting` - an object containing options for how to serialize the query params (see `buildQueryParams`) + * + * ```ts + * import { createRecord } from '@ember-data/active-record/request'; + * + * const person = this.store.createRecord('person', { name: 'Ted' }); + * const options = createRecord(person, { namespace: 'api/v1' }); + * const data = await store.request(options); + * ``` + * + * @method createRecord + * @public + * @static + * @for @ember-data/active-record/request + * @param record + * @param options + */ +export function createRecord(record: RecordInstance, options: ConstrainedRequestOptions = {}): CreateRequestOptions { + const identifier = recordIdentifierFor(record); + assert(`Expected to be given a record instance`, identifier); + + const urlOptions: CreateRecordUrlOptions = { + identifier: identifier, + op: 'createRecord', + resourcePath: pluralize(underscore(identifier.type)), + }; + + copyForwardUrlOptions(urlOptions, options); + + const url = buildBaseURL(urlOptions); + const headers = new Headers(); + headers.append('Accept', 'application/json;charset=utf-8'); + + return { + url, + method: 'POST', + headers, + op: 'createRecord', + data: { + record: identifier, + }, + }; +} + +/** + * Builds request options to update existing record for resources, + * configured for the url, method and header expectations of most ActiveRecord APIs. + * + * **Basic Usage** + * + * ```ts + * import { updateRecord } from '@ember-data/active-record/request'; + * + * const person = this.store.peekRecord('person', '1'); + * person.name = 'Chris'; + * const data = await store.request(updateRecord(person)); + * ``` + * + * **Supplying Options to Modify the Request Behavior** + * + * The following options are supported: + * + * - `patch` - Allows caller to specify whether to use a PATCH request instead of a PUT request, defaults to `false`. + * - `host` - The host to use for the request, defaults to the `host` configured with `setBuildURLConfig`. + * - `namespace` - The namespace to use for the request, defaults to the `namespace` configured with `setBuildURLConfig`. + * - `resourcePath` - The resource path to use for the request, defaults to pluralizing the supplied type + * - `reload` - Whether to forcibly reload the request if it is already in the store, not supplying this + * option will delegate to the store's lifetimes service, defaulting to `false` if none is configured. + * - `backgroundReload` - Whether to reload the request if it is already in the store, but to also resolve the + * promise with the cached value, not supplying this option will delegate to the store's lifetimes service, + * defaulting to `false` if none is configured. + * - `urlParamsSetting` - an object containing options for how to serialize the query params (see `buildQueryParams`) + * + * ```ts + * import { updateRecord } from '@ember-data/active-record/request'; + * + * const person = this.store.peekRecord('person', '1'); + * person.name = 'Chris'; + * const options = updateRecord(person, { patch: true }); + * const data = await store.request(options); + * ``` + * + * @method updateRecord + * @public + * @static + * @for @ember-data/active-record/request + * @param record + * @param options + */ +export function updateRecord( + record: RecordInstance, + options: ConstrainedRequestOptions & { patch?: boolean } = {} +): UpdateRequestOptions { + const identifier = recordIdentifierFor(record); + assert(`Expected to be given a record instance`, identifier); + assert(`Cannot update a record that does not have an associated type and id.`, isExisting(identifier)); + + const urlOptions: UpdateRecordUrlOptions = { + identifier: identifier, + op: 'updateRecord', + resourcePath: pluralize(underscore(identifier.type)), + }; + + copyForwardUrlOptions(urlOptions, options); + + const url = buildBaseURL(urlOptions); + const headers = new Headers(); + headers.append('Accept', 'application/json;charset=utf-8'); + + return { + url, + method: options.patch ? 'PATCH' : 'PUT', + headers, + op: 'updateRecord', + data: { + record: identifier, + }, + }; +} diff --git a/packages/active-record/src/.gitkeep b/packages/active-record/src/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/active-record/src/request.ts b/packages/active-record/src/request.ts new file mode 100644 index 00000000000..1f6c37c6b51 --- /dev/null +++ b/packages/active-record/src/request.ts @@ -0,0 +1,66 @@ +/** + *

+ +

+ +This package provides utilities for working with [ActiveRecord](https://guides.rubyonrails.org/active_record_basics.html#convention-over-configuration-in-active-record) APIs with [*Ember***Data**](https://github.com/emberjs/data/). + +## Installation + +Install using your javascript package manager of choice. For instance with [pnpm](https://pnpm.io/) + +```no-highlight +pnpm add @ember-data/active-record +``` + +## Usage + +Request builders are functions that produce [Fetch Options](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). +They take a few contextual inputs about the request you want to make, abstracting away the gnarlier details. + +For instance, to fetch a resource from your API + +```ts +import { findRecord } from '@ember-data/active-record/request'; + +const options = findRecord('ember-developer', '1', { include: ['pets', 'friends'] }); + +/\* + => { + url: 'https://api.example.com/v1/ember_developers/1?include=friends,pets', + method: 'GET', + headers: , // 'Content-Type': 'application/json;charset=utf-8' + op: 'findRecord'; + records: [{ type: 'ember-developer', id: '1' }] + } +*\/ +``` + +Request builder output may be used with either `requestManager.request` or `store.request`. + +URLs are stable. The same query will produce the same URL every time, even if the order of keys in +the query or values in an array changes. + +URLs follow the most common ActiveRecord format (underscored pluralized resource types). + +### Available Builders + +- [createRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Factive-record/createRecord) +- [deleteRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Factive-record/deleteRecord) +- [findRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Factive-record/findRecord) +- [query](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Factive-record/query) +- [updateRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Factive-record/updateRecord) + + * + * @module @ember-data/active-record/request + * @main @ember-data/active-record/request + */ +export { findRecord } from './-private/builders/find-record'; +export { query } from './-private/builders/query'; +export { deleteRecord, createRecord, updateRecord } from './-private/builders/save-record'; diff --git a/packages/config/package.json b/packages/config/package.json new file mode 100644 index 00000000000..004a586ede2 --- /dev/null +++ b/packages/config/package.json @@ -0,0 +1,27 @@ +{ + "name": "@warp-drive/internal-config", + "private": true, + "version": "4.12.5", + "dependencies": { + "@babel/core": "^7.23.3", + "@babel/eslint-parser": "^7.23.3", + "@babel/plugin-proposal-decorators": "^7.23.3", + "@typescript-eslint/eslint-plugin": "^6.13.1", + "@typescript-eslint/parser": "^6.13.1", + "eslint": "^8.54.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-mocha": "^10.2.0", + "eslint-plugin-n": "^16.3.1", + "eslint-plugin-qunit": "^8.0.1", + "eslint-plugin-simple-import-sort": "^10.0.0", + "typescript": "~5.3.2" + }, + "engines": { + "node": "16.* || >= 18.*" + }, + "volta": { + "extends": "../package.json" + }, + "packageManager": "pnpm@8.11.0" +} diff --git a/packages/config/rollup/external.js b/packages/config/rollup/external.js new file mode 100644 index 00000000000..a8f1e8ea947 --- /dev/null +++ b/packages/config/rollup/external.js @@ -0,0 +1,37 @@ +const path = require('path'); + +function external(manual = []) { + const pkg = require(path.join(process.cwd(), './package.json')); + const deps = Object.keys(pkg.dependencies || {}); + const peers = Object.keys(pkg.peerDependencies || {}); + const all = new Set([...deps, ...peers, ...manual]); + + // console.log({ externals: result }); + return function (id) { + if (all.has(id)) { + return true; + } + + for (const dep of deps) { + if (id.startsWith(dep + '/')) { + return true; + } + } + + for (const dep of peers) { + if (id.startsWith(dep + '/')) { + return true; + } + } + + if (id.startsWith('@ember/') || id.startsWith('@ember-data/') || id.startsWith('@warp-drive/')) { + throw new Error(`Unexpected import: ${id}`); + } + + return false; + }; +} + +module.exports = { + external, +}; diff --git a/packages/diagnostic/.npmignore b/packages/diagnostic/.npmignore new file mode 100644 index 00000000000..07e6e472cc7 --- /dev/null +++ b/packages/diagnostic/.npmignore @@ -0,0 +1 @@ +/node_modules diff --git a/packages/diagnostic/LICENSE.md b/packages/diagnostic/LICENSE.md new file mode 100644 index 00000000000..b0ca693ab2d --- /dev/null +++ b/packages/diagnostic/LICENSE.md @@ -0,0 +1,12 @@ +The MIT License (MIT) + +Copyright (C) 2023 EmberData and WarpDrive contributors +Copyright (C) 2017-2022 Ember.js contributors +Portions Copyright (C) 2011-2017 Tilde, Inc. and contributors. +Portions Copyright (C) 2011 LivingSocial Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/diagnostic/NCC-1701-a-blue.svg b/packages/diagnostic/NCC-1701-a-blue.svg new file mode 100644 index 00000000000..3b46f232c1a --- /dev/null +++ b/packages/diagnostic/NCC-1701-a-blue.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/diagnostic/NCC-1701-a.svg b/packages/diagnostic/NCC-1701-a.svg new file mode 100644 index 00000000000..8ee688dcf30 --- /dev/null +++ b/packages/diagnostic/NCC-1701-a.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/diagnostic/README.md b/packages/diagnostic/README.md new file mode 100644 index 00000000000..ffa9fbcd6ff --- /dev/null +++ b/packages/diagnostic/README.md @@ -0,0 +1,529 @@ +

+ + +

+ +

⚡️ A Lightweight Modern Test Runner

+

QUnit Compatible (mostly! 🙈)

+ +> ⚠️ Private + +This package may currently only be used within EmberData. A public version is coming soon 💜 + +```cli +pnpm install @warp-drive/diagnostic +``` + +**@warp-drive/** *diagnostic* is a ground-up revisiting of the APIs [QUnit](https://qunitjs.com/) popularized and [Ember](https://github.com/emberjs/ember-qunit) polished. + +- 💜 Fully Typed +- :electron: Universal +- ⚡️ Fast +- ✅ Easy to use + +**@warp-drive/** *diagnostic* is ***also*** a test launcher/runner inspired by the likes of [Testem](https://github.com/testem/testem), [ember exam](https://github.com/ember-cli/ember-exam) and the [ember test](https://cli.emberjs.com/release/basic-use/cli-commands/#testingyourapp) command. It is similarly flexible, but faster and more lightweight while somehow bringing a more robust feature set to the table. + +- 🚀 Easy Browser Setup Included +- :octocat: Runs without fuss on Github Actions +- 📦 Out of the box randomization, parallelization, load balancing, and more. + +But don't worry, if you're not ready to leave your existing stack the launcher/runner portion is optional. Out of the box, it comes ready with a [Testem](https://github.com/testem/testem) integration, +or you can add your own. + +## Quickstart + +- [Writing Tests](#writing-tests) +- [Running Tests](#running-tests) +- [Using the DOM Reporter](#using-the-domreporter) +- [Concurrency](#concurrency) +- [Using The Launcher](#using-the-launcher) +- [Adding A Sidecar](#adding-a-sidecar) +- [🔜 Parallelism](#parallelism) +- [🔜 Randomization](#randomization) +- [Why Is It Fast?](#why-is-it-fast) +- [Migration From QUnit](#migration-from-qunit) +- [Using with Ember](#using-with-ember) + +--- + +### Writing Tests + +```ts +import { module, test } from '@warp-drive/diagnostic'; + +module('My Module', function(hooks) { + hooks.beforeEach(async function() { + // do setup + }); + + test('It Works!', async function(assert) { + assert.ok('We are up and running'); + }); +}); +``` + +Tests and hooks may be async or sync. + +The `this` context and `assert` instance passed to a `beforeEach` or `afterEach` hook is the same as will be used for the given test but is not shared across tests. + +This makes `this` a convenient pattern for accessing or stashing state during setup/teardown in a manner that is safe for *test concurrency*. + +Global and module level state that is not safely shared between multiple tests potentially running simultaneously should be avoided. + +When augmenting `this`, import `TestContext`. + +```ts +import { type TestContext } from '@warp-drive/diagnostic'; + +interface ModuleContext extends TestContext { + some: 'state'; +} + +module('My Module', function(hooks) { + hooks.beforeEach(async function(this: ModuleContext) { + this.some = 'state'; + }); + + test('It Works!', async function(this: ModuleContext, assert) { + assert.equal(this.some, 'state', 'We are up and running'); + }); +}); +``` + +Alternatively, key some state to a WeakMap and avoid the +type gymnastics. + +```ts +interface ModuleState { + some: 'state'; +} +const STATES = new WeakMap(); + +export function setState(key: object, state: ModuleState) { + STATES.set(key, state); +} + +export function getState(key: object) { + const state = STATES.get(key); + if (!state) { + throw new Error(`Failed to setup state`); + } + return state; +} +``` + +Now all we need to do is use the `this` we already have! + +```ts +import { setState, getState } from './helpers'; + +module('My Module', function(hooks) { + hooks.beforeEach(async function() { + setState(this, { some: 'state' }); + }); + + test('It Works!', async function(assert) { + const state = getState(this); + assert.equal(state.some, 'state', 'We are up and running'); + }); +}); +``` + +--- + +### Running Tests + +> **Note** +> This section is about how to setup your tests to run once launched. To learn about launching tests, read [Using The Launcher](#using-the-launcher) + +> **Warning** +> This section is nuanced, read carefully! + + +To run your tests, import and run `start`. + +```ts +import { start } from '@warp-drive/diagnostic'; + +start(); +``` + +Start will immediately begin running any tests it knows about, +so when you call start matters. + +For instance, if your tests require DOM to be setup, making sure `start` is called only once DOM exists is important. + +If there are global hooks that need configured, that configuration needs to happen *before* you call `start`. Similar with any reporters, `registerReporter` must be called first. + +```ts +import { registerReporter, setupGlobalHooks, start } from '@warp-drive/diagnostic'; +import CustomReporter from './my-custom-reporter'; + +setupGlobalHooks((hooks) => { + hooks.beforeEach(() => { + // .. some setup + }); + hooks.afterEach(() => { + // .. some teardown + }); +}); + +registerReporter(new CustomReporter()); + +start(); +``` + +--- + +### Using the DOMReporter + +For convenience, a `DOMReporter` is provided. When using the `DOMReporter` it expects to be given an element to render the report into. + +```ts +import { registerReporter, start } from '@warp-drive/diagnostic'; +import { DOMReporter } from '@warp-drive/diagnostic/reporters/dom'; + +const container = document.getElementById('warp-drive__diagnostic'); +registerReporter(new DOMReporter(container)); + +start(); +``` + +When using this reporter you will likely want to include the `css` for it, which can be imported from `@warp-drive/diagnostic/dist/styles/dom-reporter.css` + +The specific container element `id` of `warp-drive__diagnostic` only matters if using the provided dom-reporter CSS, custom CSS may be used. + +For convenience, the above code can be condensed by using the DOM `runner`. + +```ts +import { start } from '@warp-drive/diagnostic/runners/dom'; + +start(); +``` + +--- + +### Concurrency + +By default, diagnostic will only run tests one at a time, waiting for all `beforeEach` +and `afterEach` hooks to be called for a test before moving on to the next. + +This is exactly as QUnit would have run the tests. For most this linear mode is +likely a requirement due to state having been stored in module scope or global scope. + +But if you are starting fresh, or have a test suite and program that is very well encapsulated, you may benefit from using test concurrency. + +Emphasis on *may* because concurrency will only help if there is significany empty time +during each test due to things such as `requestAnimationFrame`, `setTimeout` or a +`fetch` request. + +Concurrency is activated by providing a concurrency option in your test suite config. The option should be a positive integer +greater than `1` for it to have any effect. + +```ts +import { configure, start } from '@warp-drive/diagnostic'; + +configure({ + concurrency: 10 +}); + +start(); +``` + +--- + +## Using The Launcher + +#### Quick Setup + +> Skip to [Advanced](#advanced-setup) + +First, we need to add a configuration file for the launcher to our project. + +If our build assets are located in `/dist-test/*` and the entry point for tests is `dist-test/tests/index.html`, then the default configuration will get us setup with no further effort. + +*\/diagnostic.js* +```ts +import launch from '@warp-drive/diagnostic/server/default-setup.js'; + +await launch(); +``` + +Next, adjust the configuration for `start` to tell the runner to emit test information to the diagnostic server. + +```diff +start({ + groupLogs: false, + instrument: true, + hideReport: false, ++ useDiagnostic: true, +}); +``` + +Next, we will want to install `bun`. (We intend to pre-bundle the runner as an executable in the near future, but until then this is required). + +For github-actions, [use the official bun action](https://github.com/oven-sh/setup-bun#readme) + +```yml +- uses: oven-sh/setup-bun@v1 + with: + bun-version: latest +``` + +Finally, give your tests a run to make sure they still work as expected. + +```cli +bun ./diagnostic.js +``` + +And update any necessary scripts in `package.json` + +```diff +{ + "scripts": { + "build" "ember build", +- "test": "ember test" ++ "test": "bun run build && bun ./diagnostic.js" + } +} +``` + +✅ That's all! You're ready to test! 💜 + +--- + +#### Advanced Setup + +--- + +### Adding A Sidecar + +Diagnostic's launcher supports running additional services alongside your test suite +when they are necessary for your tests to run correctly. For instance, you may want +to start a local API instance, http mock service, or a build process. + +#### Use with @warp-drive/holodeck + +@warp-drive/holodeck is an http mock service for test suites. We can start and stop +the holodeck server along side our test server with an easy integration. + +```ts + +``` + +--- + +### Parallelism + +[Coming Soon] + +--- + +### Randomization + +[Coming Soon] + +--- + +### Why Is It Fast? + +There's a number of micro-optimizations, but the primary difference is in "yielding". + +`QUnit` and `ember-qunit` both schedule async checks using `setTimeout`. Even if no work needs to happen and the thread is free, `setTimeout` will delay `~4.5ms` before executing its callback. + +When you delay in this manner multiple times per test, and have lots of tests, things add up. + +In our experience working on EmberData, most of our tests, even our more complicated ones, had +completion times in the `4-30ms` range, the duration of which was dominated by free-time spent +waiting for `setTimeout` callbacks. We did some math and realized that most of our tests run in +less than `0.5ms`, and even our average was `<4ms`, smaller than the time for even a single `setTimeout` +callback. + +`@warp-drive/diagnostic` runs tests as microtasks. Yielding out of the microtask queue only occurs if +the test itself needs to do so. + +> **Note** +> soon we will elect to periodically yield just to allow the DOMReporter to show results, currently its so fast though that the tests are done before you'd care. + +Next, diagnostic, uses several singleton patterns internally to keep allocations to a minimum while +running tests. + +By not waiting for DOMComplete and by being more intelligent about yielding, we start running tests +sooner. In most situations this means test runs start 100-200ms quicker. + +We further noticed that the qunit DOM Reporter was its own bottleneck for both memory and compute time. For our version we made a few tweaks to reduce this cost, which should especially help test suites with thousands or tens of thousands of tests. + +Lastly, we noticed that the serialization and storage of objects being reported had a high cost. +This was a problem shared between the launcher (Testem) and what QUnit was providing to it. For this, +we opted to reduce the amount of information shared to Testem by default to the bare minimum, but with a fast `debug` toggle to switch into the more verbose mode. + +--- + +### Migration from QUnit + +1. Replace `qunit` with `@warp-drive/diagnostic` + +```diff +index 2fbga6a55..c9537dd37 100644 +--- a/package.json ++++ b/package.json +@@ -23,5 +23,5 @@ +- "qunit": "2.20.0", ++ "@warp-drive/diagnostic": "latest", +``` + +2. Update imports from `qunit` to `@warp-drive/diagnostic` + +```diff +--- a/tests/example.ts ++++ b/tests/example.ts +@@ -1,0 +1,0 @@ +- import { module, test } from 'qunit'; ++ import { module, test } from '@warp-drive/diagnostic'; +``` + + +3. Use `equal` and `notEqual` + +Diagnostic has no loose comparison mode. So instead of `strictEqual` and `notStrictEqual` we can just use `equal` and `notEqual` which are already strict. + +4. Update module hooks + +`beforeEach` and `afterEach` are unchanged. +`before` and `after` become `beforeModule` and `afterModule`. + +```diff +module('My Module', function(hooks) { +- hooks.before(function(assert) { ++ hooks.beforeModule(function(assert) { + // ... + }); + +- hooks.after(function(assert) { ++ hooks.afterModule(function(assert) { + // ... + }); +}); +``` + +5. Update global hooks + +`QUnit.begin` and `QUnit.done` become `onSuiteStart` and `onSuiteFinish` respectively. + +`QUnit.hooks` becomes `setupGlobalHooks`. + +```diff ++ import { setupGlobalHooks } from '@warp-drive/diagnostic'; + +- QUnit.begin(function() {}); +- QUnit.done(function() {}); +- QUnit.hooks.beforeEach(function() {}); ++ setupGlobalHooks(function(hooks) { ++ hooks.onSuiteStart(function() {}); ++ hooks.onSuiteFinish(function() {}); ++ hooks.beforeEach(function() {}); ++ }); +``` + +--- + +### Using With Ember + +1. Add the following peer-deps to your app: + +```diff ++ "@ember/test-helpers": ">= 3.2.0", ++ "ember-cli-test-loader": ">= 3.1.0", ++ "@embroider/addon-shim": ">= 1.8.6" +``` + +2. Configure for ember in `test-helper.js` + +```ts +import { configure } from '@warp-drive/diagnostic/ember'; + +configure(); +``` + +3. Use setup helpers + +```ts +import { module, test } from '@warp-drive/diagnostic'; +import { setupTest } from '@warp-drive/diagnostic/ember'; + +module('My Module', function (hooks) { + setupTest(hooks); +}); +``` + +--- + +### ♥️ Credits + +
+ Brought to you with ♥️ love by 🐹 Ember + + +
diff --git a/packages/diagnostic/addon-main.cjs b/packages/diagnostic/addon-main.cjs new file mode 100644 index 00000000000..d36b0c86dac --- /dev/null +++ b/packages/diagnostic/addon-main.cjs @@ -0,0 +1,5 @@ +'use strict'; + +const { addonV1Shim } = require('@embroider/addon-shim'); + +module.exports = addonV1Shim(__dirname); diff --git a/packages/diagnostic/babel.config.json b/packages/diagnostic/babel.config.json new file mode 100644 index 00000000000..278b4a0eb62 --- /dev/null +++ b/packages/diagnostic/babel.config.json @@ -0,0 +1,3 @@ +{ + "plugins": [["@babel/plugin-transform-typescript", { "allowDeclareFields": true }]] +} diff --git a/packages/diagnostic/bin/.gitkeep b/packages/diagnostic/bin/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/diagnostic/package.json b/packages/diagnostic/package.json new file mode 100644 index 00000000000..a5fcb968f14 --- /dev/null +++ b/packages/diagnostic/package.json @@ -0,0 +1,134 @@ +{ + "name": "@warp-drive/diagnostic", + "version": "4.12.5", + "private": true, + "description": "⚡️ A Lightweight Modern Test Runner", + "keywords": [ + "test", + "assert", + "testrunner", + "tap", + "reporter", + "junit", + "qunit", + "vitest", + "jest", + "mocha", + "chai", + "ember-addon" + ], + "repository": { + "type": "git", + "url": "git+ssh://git@github.com:emberjs/data.git", + "directory": "packages/diagnostic" + }, + "license": "MIT", + "author": "Chris Thoburn ", + "files": [ + "addon-main.cjs", + "dist/", + "server/", + "README.md", + "LICENSE.md", + "NCC-1701-a.svg", + "NCC-1701-a-blue.svg" + ], + "type": "module", + "exports": { + ".": { + "node": "./server/index.js", + "bun": "./server/index.js", + "deno": "./server/index.js", + "browser": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "import": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "default": "./server/index.js" + }, + "./server/*": { + "node": "./server/*.js", + "bun": "./server/*.js", + "deno": "./server/*.js" + }, + "./ember": { + "types": "./dist/ember.d.ts", + "default": "./dist/ember.js" + }, + "./*": { + "types": "./dist/*.d.ts", + "default": "./dist/*.js" + } + }, + "scripts": { + "build:tests": "rm -rf dist-test && cp -R test dist-test && mkdir -p dist-test/@warp-drive && cp -R dist dist-test/@warp-drive/diagnostic", + "build:types": "tsc --build --force", + "build:runtime": "rollup --config", + "build": "bun run build:runtime && bun run build:types", + "start": "rollup --config --watch", + "prepack": "pnpm build", + "_syncPnpm": "bun run sync-dependencies-meta-injected" + }, + "peerDependencies": { + "@ember/test-helpers": ">= 3.2.0", + "@embroider/addon-shim": ">= 1.8.7", + "ember-cli-test-loader": ">= 3.1.0" + }, + "peerDependenciesMeta": { + "@ember/test-helpers": { + "optional": true + }, + "ember-cli-test-loader": { + "optional": true + }, + "@embroider/addon-shim": { + "optional": true + } + }, + "dependencies": { + "chalk": "^5.3.0", + "debug": "^4.3.4", + "pnpm-sync-dependencies-meta-injected": "0.0.10", + "tmp": "^0.2.1" + }, + "devDependencies": { + "@babel/cli": "^7.23.4", + "@babel/core": "^7.23.3", + "@babel/plugin-transform-typescript": "^7.23.4", + "@babel/preset-env": "^7.23.3", + "@babel/preset-typescript": "^7.23.3", + "@babel/runtime": "^7.23.4", + "@embroider/addon-dev": "^4.1.2", + "@embroider/addon-shim": "^1.8.7", + "@rollup/plugin-babel": "^6.0.4", + "@rollup/plugin-node-resolve": "^15.2.3", + "@warp-drive/internal-config": "workspace:4.12.5", + "bun-types": "^1.0.14", + "@ember/test-helpers": "^3.2.0", + "ember-source": "~5.4.0", + "@glimmer/component": "^1.1.2", + "ember-cli-test-loader": "^3.1.0", + "rollup": "^4.5.0", + "typescript": "^5.3.2", + "walk-sync": "^3.0.0" + }, + "engines": { + "node": "16.* || >= 18.*" + }, + "volta": { + "extends": "../../package.json" + }, + "packageManager": "pnpm@8.11.0", + "ember-addon": { + "main": "addon-main.cjs", + "type": "addon", + "version": 2 + }, + "ember": { + "edition": "octane" + }, + "dependenciesMeta": {} +} diff --git a/packages/diagnostic/rollup.config.mjs b/packages/diagnostic/rollup.config.mjs new file mode 100644 index 00000000000..955ecdc8558 --- /dev/null +++ b/packages/diagnostic/rollup.config.mjs @@ -0,0 +1,35 @@ +import { Addon } from '@embroider/addon-dev/rollup'; +import babel from '@rollup/plugin-babel'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; + +import { external } from '@warp-drive/internal-config/rollup/external.js'; + +const addon = new Addon({ + srcDir: 'src', + destDir: 'dist', +}); + +export default { + // This provides defaults that work well alongside `publicEntrypoints` below. + // You can augment this if you need to. + output: addon.output(), + + external: external(['@ember/test-helpers', 'ember-cli-test-loader/test-support/index']), + + plugins: [ + // These are the modules that users should be able to import from your + // addon. Anything not listed here may get optimized away. + addon.publicEntrypoints(['index.js', 'reporters/dom.js', 'reporters/tap.js', 'runners/dom.js', 'ember.js']), + + nodeResolve({ extensions: ['.ts'] }), + babel({ + extensions: ['.ts'], + babelHelpers: 'bundled', + }), + + addon.keepAssets(['**/*.css']), + + // Remove leftover build artifacts when starting a new build. + addon.clean(), + ], +}; diff --git a/packages/diagnostic/server/browsers/index.js b/packages/diagnostic/server/browsers/index.js new file mode 100644 index 00000000000..8fc72d6c3df --- /dev/null +++ b/packages/diagnostic/server/browsers/index.js @@ -0,0 +1,308 @@ +import os from 'os'; +import path from 'path'; +import tmp from 'tmp'; + +import { debug } from '../utils/debug.js'; +import { isWin, platformName } from '../utils/platform.js'; + +export function getHomeDir() { + return process.env.HOME || process.env.USERPROFILE; +} + +function chromeWinPaths(name) { + const homeDir = getHomeDir(); + return [ + homeDir + '\\Local Settings\\Application Data\\Google\\' + name + '\\Application\\chrome.exe', + homeDir + '\\AppData\\Local\\Google\\' + name + '\\Application\\chrome.exe', + 'C:\\Program Files\\Google\\' + name + '\\Application\\Chrome.exe', + 'C:\\Program Files (x86)\\Google\\' + name + '\\Application\\Chrome.exe', + ]; +} + +function chromeDarwinPaths(name) { + const homeDir = getHomeDir(); + return [ + homeDir + '/Applications/' + name + '.app/Contents/MacOS/' + name, + '/Applications/' + name + '.app/Contents/MacOS/' + name, + ]; +} + +const ChromePaths = { + win: chromeWinPaths, + darwin: chromeDarwinPaths, +}; + +const ChromeTags = { + win: { + stable: 'Chrome', + beta: 'Chrome Beta', + canary: 'Chrome SxS', + }, + darwin: { + stable: 'Google Chrome', + beta: 'Google Chrome Beta', + canary: 'Google Chrome Canary', + }, +}; + +const ChromeExeNames = { + stable: ['google-chrome-stable', 'google-chrome', 'chrome'], + beta: ['google-chrome-beta'], + canary: ['google-chrome-unstable'], +}; + +async function executableExists(exe) { + const cmd = isWin() ? 'where' : 'which'; + const result = Bun.spawnSync([cmd, exe], { + stdout: 'inherit', + }); + + return result.success; +} + +async function isInstalled(browser) { + const result = await checkBrowser(browser.possiblePath, fileExists); + if (result) { + return result; + } + + return checkBrowser(browser.possibleExe, function (exe) { + return executableExists(exe); + }); +} + +async function fileExists(file) { + const pointer = Bun.file(file); + return pointer.exists(); +} + +async function checkBrowser(lookups, method) { + if (!lookups) { + return false; + } + + if (Array.isArray(lookups)) { + for (const option of lookups) { + const result = await method(option); + if (result) { + return option; + } + } + return false; + } + + if (await method(lookups)) { + return lookups; + } +} + +async function getChrome(browser, tag) { + const platform = platformName(); + const pathName = ChromeTags[platform]?.[tag]; + const paths = ChromePaths[platform]?.(pathName) ?? []; + + const lookupInfo = { + name: browser.toLowerCase(), + possiblePath: paths, + possibleExe: ChromeExeNames[tag], + }; + + const result = await isInstalled(lookupInfo); + if (!result) { + throw new Error( + `Could not find ${ + lookupInfo.name + } on your system (${platform}).\n\n\tChecked Paths:\n\t\t${lookupInfo.possiblePath.join( + '\n\t\t' + )}\n\tChecked Executable Names:\n\t\t${lookupInfo.possibleExe.join('\n\t\t')}` + ); + } + + debug(`Found ${lookupInfo.name} executable ${result}`); + + return result; +} + +export async function getBrowser(browser) { + const name = browser.toLowerCase(); + if (name === 'chrome') { + return getChrome(name, 'stable'); + } + if (name === 'chrome-beta') { + return getChrome(name, 'beta'); + } + if (name === 'chrome-canary') { + return getChrome(name, 'canary'); + } + + throw new Error(`@warp-drive/diagnostic has no launch information for ${browser}`); +} + +const TMP_DIRS = new Map(); + +export function getTmpDir(browser) { + if (TMP_DIRS.has(browser)) { + return TMP_DIRS.get(browser).name; + } + + const userDataDir = os.tmpdir(); + const tmpPath = path.join(userDataDir, 'testem-' + browser.replace(' ', '_')); + + const tmpDir = tmp.dirSync({ + template: `${tmpPath}-XXXXXX`, + unsafeCleanup: true, + }); + + TMP_DIRS.set(browser, tmpDir); + return tmpDir.name; +} + +export function recommendedArgs(browser, options = {}) { + if (!browser || browser.toLowerCase() !== 'chrome') { + return []; + } + const DEBUG = options.debug || debug.enabled; + const DEBUG_MEMORY = options.memory || process.env.DEBUG_MEMORY; + const SERVE = 'serve' in options ? options.serve : false; + const HEADLESS = 'headless' in options ? options.headless : !SERVE; + const useExisting = 'useExisting' in options ? options.useExisting : false; + const noLaunch = 'noLaunch' in options ? options.noLaunch : false; + + if (noLaunch) { + return []; + } + + if (useExisting) { + return ['--incognito']; + } + + // See https://github.com/GoogleChrome/chrome-launcher/blob/main/docs/chrome-flags-for-tools.md + // For more details on these flags + return [ + '--user-data-dir=' + getTmpDir(browser), + HEADLESS ? '--headless=new' : false, + '--no-sandbox', + // these prevent user account + // and extensions from mucking with things + '--incognito', + '--bwsi', + '--enable-automation', + + // potentially needed to enable multi-tab + '--allow-http-background-page', + // '--silent-debugger-extension-api', + '--disable-throttle-non-visible-cross-origin-iframes', + // '--memory-saver-multi-state-mode=discarded', + // '--disable-battery-saver-mode', + // '--disable-memory-saver-mode', + // '--enable-background-thread-pool', + // '--disable-background-media-suspend', + // '--disable-tab-discarding', + // '--disable-aggressive-tab-discard', + // disabled because already enabled elsewhere + // '--disable-backgrounding-occluded-windows', + + // Enable Debugging Output + DEBUG ? '--enable-logging=stderr' : '--disable-logging', + DEBUG ? '--v=2' : false, + + // when debugging memory usage this gives us better data + DEBUG_MEMORY ? '--enable-precise-memory-info' : false, + DEBUG_MEMORY ? '--js-flags="--allow-natives-syntax --expose-gc"' : false, + + // Disable Browser Features we don't want + // ===================================== + '--ash-no-nudges', + '--autoplay-policy=user-gesture-required', + '--disable-add-to-shelf', + '--disable-client-side-phishing-detection', + '--disable-component-extensions-with-background-pages', + '--disable-default-apps', + '--disable-desktop-notifications', + '--disable-popup-blocking', + '--disable-domain-reliability', + '--disable-extensions', + '--disable-infobars', + '--disable-notifications', + '--disable-search-engine-choice-screen', + '--disable-setuid-sandbox', + '--disable-site-isolation-trials', + '--disable-sync', + '--force-color-profile=srgb', + '--force-device-scale-factor=1', + // This can cause a test to flake + // '--hide-scrollbars', + '--ignore-certificate-errors', + '--mute-audio', + '--no-default-browser-check', + '--no-first-run', + '--test-type', + + // disable specific features + // ===================================== + `--disable-features=${[ + 'ChromeEOLPowerSaveMode', + 'AutofillServerCommunication', + 'AvoidUnnecessaryBeforeUnloadCheckSync', + 'BackForwardCache', + 'BlinkGenPropertyTrees', + 'CalculateNativeWinOcclusion', + 'CertificateTransparencyComponentUpdater', + 'DialMediaRouteProvider', + // 'HeavyAdPrivacyMitigation', + 'InterestFeedContentSuggestions', + 'IsolateOrigins', + 'LazyFrameLoading', + 'MediaRouter', + 'OptimizationHints', + // 'ScriptStreaming', + 'Translate', + ] + .filter(Boolean) + .join(',')}`, + + // Adjust Task Throttling + // ===================================== + '--disable-background-timer-throttling', + '--disable-backgrounding-occluded-windows', + '--disable-hang-monitor', + '--disable-ipc-flooding-protection', + '--disable-renderer-backgrounding', + + // Disable Background Networking + // ===================================== + '--disable-background-networking', + DEBUG ? false : '--disable-breakpad', + '--disable-component-update', + '--disable-domain-reliability', + '--no-pings', + + // On Ubuntu this dev-shm-usage speeds you up on bigger machines + // and slows you down on smaller. If you are on a larger CI box + // you should consider re-enabling this. + // off because ubuntu vms currently seem to crash without this + // due to missing drivers + // '--disable-dev-shm-usage', + + // Potentially no longer needed settings + // ===================================== + '--disable-gpu', + '--disable-3d-apis', + '--disable-software-rasterizer', + '--disable-webgl', + // disable-web-security seems to cause browser not able to connect issues + // '--disable-web-security', + '--disable-remote-fonts', + '--blink-settings=imagesEnabled=false', + + // ubuntu-16-core seems to be unhappy with this being set to a non-zero port + // throws: ERROR:socket_posix.cc(147)] bind() failed: Address already in use (98) + options.useEventSimulation ? '--remote-debugging-port=0' : false, + options.useEventSimulation ? '--remote-debugging-address=0.0.0.0' : false, + '--window-size=1440,900', + // no-proxy seems to cause browser not able to connect issues + // '--no-proxy-server', + // '--proxy-bypass-list=*', + // "--proxy-server='direct://'", + ].filter(Boolean); +} diff --git a/packages/diagnostic/server/bun/fetch.js b/packages/diagnostic/server/bun/fetch.js new file mode 100644 index 00000000000..6f797dc531d --- /dev/null +++ b/packages/diagnostic/server/bun/fetch.js @@ -0,0 +1,65 @@ +import chalk from 'chalk'; +import path from 'path'; + +import { INDEX_PATHS } from '../utils/const.js'; +import { debug, info } from '../utils/debug.js'; + +/** @type {import('bun-types')} */ + +export function handleBunFetch(config, state, req, server) { + const url = new URL(req.url); + const protocol = url.protocol; + + if (protocol === 'ws:' || protocol === 'wss:') { + debug(`Upgrading websocket connection`); + server.upgrade(req); + return; + } + + const bId = url.searchParams.get('b') ?? null; + const wId = url.searchParams.get('w') ?? null; + info(`[${chalk.cyan(req.method)}] ${url.pathname}`); + + if (config.parallel > 1 && url.pathname === '/parallel-launcher') { + debug(`Serving parallel launcher`); + const dir = import.meta.dir; + const launcher = path.join(dir, 'launcher.html'); + return new Response(Bun.file(launcher)); + } + + if (INDEX_PATHS.includes(url.pathname)) { + if (bId && wId) { + // serve test index.html + if (config.entry.indexOf('?')) { + config._realEntry = config.entry.substr(0, config.entry.indexOf('?')); + } + debug(`Serving entry ${config._realEntry} for browser ${bId} window ${wId}`); + return new Response(Bun.file(config._realEntry)); + } + const _bId = bId ?? state.lastBowserId ?? state.browserId; + const _wId = wId ?? state.lastWindowId ?? state.windowId; + debug(`Redirecting to ${config.entry} for browser ${_bId} window ${_wId}`); + // redirect to index.html + return Response.redirect(`${protocol}://${state.hostname}:${state.port}?b=${_bId}&w=${_wId}`, { status: 302 }); + } else { + const pathParts = url.pathname.split('/'); + + if (pathParts.at(-1) === '') pathParts.pop(); + if (pathParts[0] === '') pathParts.shift(); + + if (pathParts[0] === 'ws') { + debug(`Upgrading websocket connection`); + server.upgrade(req); + return; + } + + const route = pathParts.join('/'); + if (route === 'favicon.ico') { + return new Response('Not Found', { status: 404 }); + } + + // serve test assets + debug(`Serving asset ${route} for browser ${bId} window ${wId}`); + return new Response(Bun.file(path.join(process.cwd(), config.assets, route))); + } +} diff --git a/packages/diagnostic/server/bun/launch-browser.js b/packages/diagnostic/server/bun/launch-browser.js new file mode 100644 index 00000000000..c3088411f3d --- /dev/null +++ b/packages/diagnostic/server/bun/launch-browser.js @@ -0,0 +1,51 @@ +import chalk from 'chalk'; + +import { info, print } from '../utils/debug.js'; + +/** @type {import('bun-types')} */ + +export async function launchBrowsers(config, state) { + const launchers = Object.keys(config.launchers ?? {}); + if (launchers.length === 0) { + throw new Error(`No launchers configured`); + } + + const parallel = config.parallel ?? 1; + for (const launcher of launchers) { + if (!config.launchers[launcher].command) { + throw new Error(`Missing command for launcher ${launcher}`); + } + + const args = config.launchers.chrome.args ?? []; + args.unshift(config.launchers.chrome.command); + const bId = state.browserId++; + + if (parallel > 1) { + const pages = []; + for (let i = 0; i < parallel; i++) { + pages.push(`?b=${bId}&w=${state.windowId++}`); + } + + const launcherUrl = `${state.protocol}://${state.hostname}:${state.port}/parallel-launcher?p[]=${pages.join( + '&p[]=' + )}`; + args.push(launcherUrl); + } else { + args.push(`${state.protocol}://${state.hostname}:${state.port}?b=${bId}&w=${state.windowId++}`); + } + + info(`Spawning:\n\t${args.join('\n\t\t')}`); + const browser = Bun.spawn(args, { + env: process.env, + cwd: process.cwd(), + stdout: 'inherit', + stderr: 'inherit', + }); + state.browsers.set(String(bId), { + launcher, + proc: browser, + }); + info(`${launcher} spawned with pid ${browser.pid}`); + print(chalk.magenta(`⚛️ Launched ${launcher}`)); + } +} diff --git a/packages/diagnostic/server/bun/port.js b/packages/diagnostic/server/bun/port.js new file mode 100644 index 00000000000..95a27402636 --- /dev/null +++ b/packages/diagnostic/server/bun/port.js @@ -0,0 +1,28 @@ +import { debug } from '../utils/debug.js'; + +/** @type {import('bun-types')} */ + +export async function checkPort(port) { + debug(`Checking if port ${port} is available`); + try { + const server = await Bun.listen({ + port, + hostname: '0.0.0.0', + exclusive: true, + socket: { + data() { + debug(`Port ${port} received data 🙈`); + }, + }, + }); + debug(`Port ${port} is available, releasing it for server`); + server.stop(true); + return true; + } catch (e) { + debug(`Port ${port} is not available: ${e.message}`); + if (e.code === 'EADDRINUSE') { + return false; + } + throw e; + } +} diff --git a/packages/diagnostic/server/bun/socket-handler.js b/packages/diagnostic/server/bun/socket-handler.js new file mode 100644 index 00000000000..cd50946707a --- /dev/null +++ b/packages/diagnostic/server/bun/socket-handler.js @@ -0,0 +1,73 @@ +import chalk from 'chalk'; + +import { debug, info } from '../utils/debug.js'; +import { sinceStart } from '../utils/time.js'; + +export function buildHandler(config, state) { + return { + perMessageDeflate: true, + async message(ws, message) { + const msg = JSON.parse(message); + msg.launcher = state.browsers.get(msg.browserId).launcher; + info(`${chalk.green('➡')} [${chalk.cyan(msg.browserId)}/${chalk.cyan(msg.windowId)}] ${chalk.green(msg.name)}`); + + switch (msg.name) { + case 'suite-start': + if (!state.started) { + state.started = true; + config.reporter.onRunStart(msg); + } + config.reporter.onSuiteStart(msg); + break; + case 'test-start': + config.reporter.onTestStart(msg); + break; + case 'test-finish': + config.reporter.onTestFinish(msg); + break; + case 'suite-finish': + config.reporter.onSuiteFinish(msg); + + if (!config.serve) { + ws.send(JSON.stringify({ name: 'close' })); + ws.close(); + } + state.completed++; + debug( + `${chalk.green('✅ [Complete]')} ${chalk.cyan(msg.browserId)}/${chalk.cyan(msg.windowId)} ${chalk.yellow( + '@' + sinceStart() + )}` + ); + if (state.completed === state.expected) { + const exitCode = config.reporter.onRunFinish(msg); + debug(`${chalk.green('✅ [All Complete]')} ${chalk.yellow('@' + sinceStart())}`); + + if (!config.serve) { + state.browsers.forEach((browser) => { + browser.proc.kill(); + browser.proc.unref(); + }); + state.server.stop(); + if (config.cleanup) { + debug(`Running configured cleanup hook`); + await config.cleanup(); + debug(`Configured cleanup hook completed`); + } + // 1. We expect all cleanup to have happened after + // config.cleanup(), so exiting here should be safe. + // 2. We also want to forcibly exit with a success code in this + // case. + // eslint-disable-next-line n/no-process-exit + process.exit(exitCode); + } + } + + break; + } + // console.log(JSON.parse(message)); + }, // a message is received + open(ws) {}, // a socket is opened + close(ws, code, message) {}, // a socket is closed + drain(ws) {}, // the socket is ready to receive more data + }; +} diff --git a/packages/diagnostic/server/default-setup.js b/packages/diagnostic/server/default-setup.js new file mode 100644 index 00000000000..87dc0311065 --- /dev/null +++ b/packages/diagnostic/server/default-setup.js @@ -0,0 +1,110 @@ +/* eslint-disable no-console */ +import chalk from 'chalk'; +import fs from 'fs'; +import path from 'path'; + +import { getBrowser, recommendedArgs } from './browsers/index.js'; +import launch from './index.js'; +import DefaultReporter from './reporters/default.js'; +import { getFlags } from './utils/get-flags.js'; + +const CI_BROWSER = process.env.CI_BROWSER || 'Chrome'; +const BROWSER_TAG = CI_BROWSER.toLowerCase(); + +const browser = await getBrowser(BROWSER_TAG); + +let TEST_FAILURES; +try { + const filePath = path.join(process.cwd(), './diagnostic-failed-test-log.txt'); + TEST_FAILURES = fs.readFileSync(filePath, { encoding: 'utf-8' }); +} catch { + TEST_FAILURES = false; +} +const FAILURES = TEST_FAILURES ? TEST_FAILURES.trim().split(',') : false; + +// default 13min per-browser test suite run timeout in seconds +const DEFAULT_SUITE_TIMEOUT = 780; +// when using a configured timeout we adjust it down a bit to account for +// to make sure we cleanup before external things cleanup +const SUITE_TIMEOUT_BUFFER = 30; +const SUITE_TIMEOUT = process.env.SUITE_TIMEOUT + ? Number(process.env.SUITE_TIMEOUT) - SUITE_TIMEOUT_BUFFER + : DEFAULT_SUITE_TIMEOUT; + +export default async function launchDefault(overrides = {}) { + const flags = getFlags().filtered; + Object.assign(overrides, flags); + + const RETRY_TESTS = + ('retry' in overrides ? overrides.retry : process.env.CI ?? process.env.RETRY_TESTS) && FAILURES.length; + const _parallel = + process.env.DIAGNOSTIC_PARALLEL && !isNaN(Number(process.env.DIAGNOSTIC_PARALLEL)) + ? Number(process.env.DIAGNOSTIC_PARALLEL) + : 1; + const parallel = _parallel > 1 && RETRY_TESTS && FAILURES.length < _parallel * 4 ? 1 : _parallel; + + if (RETRY_TESTS) { + console.log( + chalk.grey( + `⚠️ Retrying ${chalk.bold(chalk.yellow(FAILURES.length))} failed tests: ${chalk.bold( + chalk.white(FAILURES.join(',')) + )}` + ) + ); + } else if (FAILURES.length) { + console.log( + `⚠️ Found ${chalk.bold(chalk.yellow(FAILURES.length))} previously failed tests: ${chalk.bold( + chalk.white(FAILURES.join(',')) + )}. Use RETRY_TESTS=1 or --retry/-r to retry them.` + ); + } + const DEBUG = Boolean(process.env.DEBUG ?? overrides.debug ?? false); + + const TEST_PAGE_FLAGS = [ + process.env.DEBUG_MEMORY ? 'memory=1' : false, + process.env.CI || process.env.DEBUG_MEMORY ? 'hideReport=1' : false, + process.env.DEBUG_PERFORMANCE ? 'performance=1' : false, + DEBUG ? 'debug=1' : false, + RETRY_TESTS ? `testId=${FAILURES.join('&testId=')}` : false, + ].filter(Boolean); + + console.log( + `\n\nLaunching with ${chalk.bold(chalk.cyan(CI_BROWSER))} (worker count ${chalk.bold(chalk.yellow(parallel))})\n\n` + ); + + await launch({ + // flag config + serve: overrides.serve ?? false, + noLaunch: overrides.noLaunch ?? false, + filter: overrides.filter ?? false, + debug: overrides.debug ?? false, + headless: overrides.headless ?? false, + useExisting: overrides.useExisting ?? false, + + entry: overrides.entry ?? `./dist-test/tests/index.html?${TEST_PAGE_FLAGS.join('&')}`, + assets: overrides.assets ?? './dist-test', + parallel: overrides.parallel ?? parallel, + parallelMode: overrides.parallelMode ?? 'window', // 'tab' | 'browser' | 'window' + + reporter: + overrides.reporter ?? + new DefaultReporter({ + mode: process.env.DIAGNOSTIC_REPORTER_MODE || 'dot', // 'dot' | 'compact' | 'verbose' + }), + + suiteTimeout: overrides.suiteTimeout ?? SUITE_TIMEOUT, + browserDisconnectTimeout: overrides.browserDisconnectTimeout ?? 15, + browserStartTimeout: overrides.browserStartTimeout ?? 15, + socketHeartbeatTimeout: overrides.socketHeartbeatTimeout ?? 15, + + setup: overrides.setup ?? (() => {}), + cleanup: overrides.cleanup ?? (() => {}), + + launchers: overrides.launchers ?? { + [BROWSER_TAG]: { + command: browser, + args: recommendedArgs(BROWSER_TAG, overrides), + }, + }, + }); +} diff --git a/packages/diagnostic/server/index.js b/packages/diagnostic/server/index.js new file mode 100644 index 00000000000..a1a9becd155 --- /dev/null +++ b/packages/diagnostic/server/index.js @@ -0,0 +1,83 @@ +import chalk from 'chalk'; + +import { handleBunFetch } from './bun/fetch.js'; +import { launchBrowsers } from './bun/launch-browser.js'; +import { buildHandler } from './bun/socket-handler.js'; +import { debug, error, print } from './utils/debug.js'; +import { getPort } from './utils/port.js'; + +/** @type {import('bun-types')} */ +const isBun = typeof Bun !== 'undefined'; + +export default async function launch(config) { + if (isBun) { + debug(`Bun detected, using Bun.serve()`); + if (config.setup) { + debug(`Running configured setup hook`); + await config.setup(); + debug(`Configured setup hook completed`); + } + const { checkPort } = await import('./bun/port.js'); + const hostname = config.hostname ?? 'localhost'; + const protocol = config.protocol ?? 'http'; + const port = await getPort(config, checkPort); + + const serveOptions = { + port, + hostname, + }; + + const state = { + browserId: 42, + lastBowserId: null, + windowId: 0, + lastWindowId: null, + port, + hostname, + protocol, + browsers: new Map(), + completed: 0, + expected: config.parallel ?? 1, + }; + + if (protocol === 'https') { + if (!config.key) throw new Error(`Missing key for https protocol`); + if (!config.cert) throw new Error(`Missing cert for https protocol`); + + serveOptions.tls = { + key: Bun.file(config.key), + cert: Bun.file(config.cert), + }; + } + + try { + state.server = Bun.serve({ + ...serveOptions, + development: false, + exclusive: true, + fetch(req, server) { + return handleBunFetch(config, state, req, server); + }, + websocket: buildHandler(config, state), + }); + print(chalk.magenta(`🚀 Serving on ${chalk.white(protocol + '://' + hostname + ':')}${chalk.magenta(port)}`)); + config.reporter.serverConfig = { + port, + hostname, + protocol, + url: `${protocol}://${hostname}:${port}`, + }; + await launchBrowsers(config, state); + } catch (e) { + error(`Error: ${e?.message ?? e}`); + if (config.cleanup) { + debug(`Running configured cleanup hook`); + await config.cleanup(); + debug(`Configured cleanup hook completed`); + } + throw e; + } + } else { + throw new Error(`Diagnostic is not supported in this environment.`); + } +} diff --git a/packages/diagnostic/server/launcher.html b/packages/diagnostic/server/launcher.html new file mode 100644 index 00000000000..cea14159dba --- /dev/null +++ b/packages/diagnostic/server/launcher.html @@ -0,0 +1,39 @@ + + + + @warp-drive/diagnostic Parallel Test Launcher + + + + diff --git a/packages/diagnostic/server/reporters/default.js b/packages/diagnostic/server/reporters/default.js new file mode 100644 index 00000000000..4df85f0f58b --- /dev/null +++ b/packages/diagnostic/server/reporters/default.js @@ -0,0 +1,533 @@ +import chalk from 'chalk'; +import fs from 'fs'; +import path from 'path'; + +const SLOW_TEST_COUNT = 50; +const DEFAULT_TIMEOUT = 8_000; +const TIMEOUT_BUFFER = 0; +const DEFAULT_TEST_TIMEOUT = 21_000; +const failedTestsFile = path.join(process.cwd(), './diagnostic-failed-test-log.txt'); + +function indent(text, width = 2) { + return text + .split('\n') + .map((line) => { + return new Array(width).join('\t') + line; + }) + .join('\n'); +} + +const HEADER_STR = '==================================================================='; + +export default class CustomDotReporter { + // serverConfig will be injected by the server + constructor(config) { + this.config = config; + + // what format to print + this.isDotFormat = config.mode === 'dot'; + this.isCompactFormat = config.mode === 'compact'; + this.isVerboseFormat = config.mode === 'verbose'; + + this.out = process.stdout; + + // launcher tracking + this.launchers = {}; + this.tabs = new Map(); + this.idsToStartNumber = new Map(); + + // run infos + this.startNumber = 1; + this.startTime = null; + this.realStartTime = null; + this.timeZero = 0; + this.dateTimeZero = Date.now() - performance.now(); + + // results + this.results = []; + this.failedTests = []; + this.globalFailures = []; + this.failedTestIds = new Set(); + this.total = 0; + this.pass = 0; + this.skip = 0; + this.todo = 0; + this.fail = 0; + + // display info + this.shouldPrintHungTests = false; + + // dot display info + this.lineFailures = []; + this.currentLineChars = 0; + this.maxLineChars = 60; + this.totalLines = 0; + } + + write(str) { + this.out.write(str); + } + + // Hooks + // ============== + onRunStart(runInfo) { + this.startTime = performance.now(); + this.realStartTime = runInfo.timestamp; + + const runDelta = this.startTime - this.timeZero; + const elapsed = this.realStartTime - this.dateTimeZero; + + this.write( + `\n\n${HEADER_STR}\n Test Run Initiated\n\tSuite Start: ${chalk.cyan( + new Date(this.realStartTime).toLocaleString('en-US') + )} (elapsed ${chalk.cyan(elapsed.toLocaleString('en-US'))} ms)\n\tReporter Start: ${chalk.cyan( + new Date().toLocaleString('en-US') + )} (elapsed ${chalk.cyan(runDelta.toLocaleString('en-US'))} ms)\n${HEADER_STR}\n\n` + ); + } + + onSuiteStart(suiteInfo) { + this.addLauncher(suiteInfo); + } + + onTestStart(report) { + this.getTab(report).running.set(report.data.testId, report); + report.testNo = this.startNumber++; + report._testStarted = this.now(); + this.idsToStartNumber.set(`${report.browserId}:${report.windowId}:${report.data.testId}`, report.testNo); + this.ensureTimeoutCheck(); + report.launcherDescription = `${report.launcher}:${report.browserId}:${report.windowId}`; + + report.name = `${report.launcherDescription} #${report.testNo} ${chalk.magenta( + '@ ' + (Math.round(report._testStarted / 10) / 100).toLocaleString('en-US') + 's' + )} ${report.data.name}`; + + if (process.env.DISPLAY_TEST_NAMES) { + this.write(`\t\t⏱️ ${chalk.magenta(' Started')}: ${report.name}\n`); + } + } + + onTestFinish(report) { + const tab = this.getTab(report); + const startNoKey = `${report.browserId}:${report.windowId}:${report.data.testId}`; + const startNo = this.idsToStartNumber.get(startNoKey); + + report.testNo = startNo ?? ''; + report.data.runDuration = report.data.runDuration ?? 0; + report.launcherDescription = `${report.launcher}:${report.browserId}:${report.windowId}`; + + if (tab.running.has(report.data.testId)) tab.running.delete(report.data.testId); + + if (this.isCompactFormat) { + this.displayFullResult(report, false); + } else if (this.isDotFormat) { + if (this.results.length === 0) this.displayDotLegend(); + this.displayDotResult(report); + } else if (this.isVerboseFormat) { + this.displayFullResult(report, true); + } else { + throw new Error(`Unknown Reporter Mode ${this.config.mode}. Please use one of 'dot', 'compact', or 'verbose'`); + } + + const { data } = report; + + this.results.push(report); + this.total++; + if (data.skipped) { + this.skip++; + } else if (data.passed && !data.todo) { + this.pass++; + } else if (!data.passed && data.todo) { + this.todo++; + } else { + this.fail++; + } + + if (data.failed && !data.skipped && !data.todo) { + this.lineFailures.push(report); + this.failedTests.push(report); + this.failedTestIds.add(data.testId); + } + } + + onGlobalFailure(report) { + this.globalFailures.push(report); + this.fail++; + } + + onSuiteFinish() {} + + onRunFinish(runReport) { + if (this.failedTests.length) { + this.write( + chalk.red( + `\n\n${this.failedTests.length} Tests Failed. Complete stack traces for failures will print at the end.` + ) + ); + } + this.write(`\n\n`); + + this.reportPendingTests(); + this.reportSlowTests(); + this.reportFailedTests(); + + this.summarizeResults(); + + // Print run duration stats + const { startTime, realStartTime } = this; + const endTime = performance.now(); + const endDate = new Date(); + const fullElapsed = endTime - this.timeZero; + const runElapsed = endTime - startTime; + const realEndTime = runReport.timestamp; + const suiteElapsed = realEndTime - realStartTime; + const realEndDate = new Date(realEndTime); + + this.write( + `\n\n${HEADER_STR}\n Test Run Complete\n\tSuite End: ${chalk.cyan( + realEndDate.toLocaleString('en-US') + )} (elapsed ${chalk.cyan(suiteElapsed.toLocaleString('en-US'))} ms)\n\tReporter End: ${chalk.cyan( + endDate.toLocaleString('en-US') + )} (elapsed ${chalk.cyan(runElapsed.toLocaleString('en-US'))} ms)\n\tRun Duration ${chalk.cyan( + fullElapsed.toLocaleString('en-US') + )} ms\n${HEADER_STR}\n\n` + ); + + return this.failedTests.length ? 1 : 0; + } + + addLauncher(data) { + this.launchers = this.launchers || {}; + this.tabs = this.tabs || new Map(); + + const { launcher, browserId, windowId } = data; + this.launchers[launcher] = this.launchers[launcher] || {}; + const browser = (this.launchers[launcher][browserId] = this.launchers[launcher][browserId] || { + launcher, + id: browserId, + tabs: new Set(), + }); + + const tabId = `${browserId}:${windowId}`; + if (browser.tabs.has(tabId)) { + return; + } + + browser.tabs.add(tabId); + this.tabs.set(tabId, { + running: new Map(), + }); + } + + getTab(test) { + const { windowId, browserId } = test; + const tabId = `${browserId}:${windowId}`; + + return this.tabs.get(tabId); + } + + now() { + return performance.now() - this.startTime; + } + + displayDotLegend() { + this.write('\n\tLegend\n\t========='); + this.write(chalk.green('\n\tPass:\t.')); + this.write(chalk.cyan('\n\tTodo:\tT')); + this.write(chalk.yellow('\n\tSkip:\t*')); + this.write(chalk.bold(chalk.red('\n\tFail:\tF'))); + this.write('\n\n\t'); + } + + displayDotResult(report) { + // complete line + if (this.currentLineChars > this.maxLineChars) { + if (this.shouldPrintHungTests) { + this.shouldPrintHungTests = false; + this.reportHungTests(); + } + + this.totalLines++; + this.currentLineChars = 0; + const lineFailures = this.lineFailures; + this.lineFailures = []; + + if (lineFailures.length) { + this.write('\n\n'); + lineFailures.forEach((failure) => { + this.displayFullResult(failure, false); + }); + } + + if (this.totalLines % 5 === 0) { + this.write(`\n${chalk.magenta((this.totalLines * this.maxLineChars).toLocaleString('en-US'))}⎡\t`); + } else { + this.write('\n\t'); + } + } + + const result = report.data; + if (result.passed && !result.todo) { + this.write(chalk.grey('.')); + } else if (!result.passed && result.todo) { + this.write(chalk.cyan('T')); + } else if (result.skipped) { + this.write(chalk.yellow('*')); + } else { + this.write(chalk.bold(chalk.red('F'))); + } + this.currentLineChars += 1; + } + + displayFullResult(report, verbose) { + const result = report.data; + const name = `${chalk.grey(result.runDuration.toLocaleString('en-US') + 'ms')} ${chalk.white( + '#' + report.testNo + )} ${result.name} ${chalk.grey(report.launcherDescription)}`; + if (result.passed && !result.todo) { + this.write(`\t✅ ${chalk.green('Passed')}: ${name}\n`); + } else if (!result.passed && result.todo) { + this.write(chalk.cyan(`\t🛠️ TODO: ${name}\n`)); + } else if (result.skipped) { + this.write(chalk.yellow(`\t⚠️ Skipped: ${name}\n`)); + } else { + this.write(chalk.red(`\t💥 Failed: ${name}\n`)); + this.write(`\t\topen test locally: ${this.serverConfig.url}?testId=${result.testId}\n`); + + // TODO - print individual failures in verbose mode + } + } + + summarizeResults() { + const lines = [ + 'Result', + '=========', + 'Total ' + this.total, + chalk.green('# pass ' + this.pass), + chalk.yellow('# skip ' + this.skip), + chalk.cyan('# todo ' + this.todo), + chalk.red('# fail ' + this.fail), + ]; + + if (this.pass + this.skipped + this.todo === this.total) { + lines.push(''); + lines.push('# ok'); + } + this.write('\n\n\t'); + this.write(lines.join('\n\t')); + this.write('\n\n'); + } + + // special reporting functionality + // =============================== + + /** + * Periodically checks for hung tests and reports them + */ + ensureTimeoutCheck() { + if (this._timeoutId) { + return; + } + this._timeoutId = setTimeout(() => { + this.shouldPrintHungTests = true; + }, DEFAULT_TEST_TIMEOUT / 3); + } + + reportHungTests() { + let hasRunningTests = false; + this.tabs.forEach((tab) => { + const running = tab.running; + + running.forEach((report) => { + hasRunningTests = true; + const duration = this.now() - report._testStarted; + if (duration > DEFAULT_TEST_TIMEOUT) { + this.write( + chalk.grey( + `\n\n⚠️ ${chalk.yellow('Pending:')} ${chalk.white(report.name)} has been running for ${chalk.yellow( + duration.toLocaleString('en-US') + 'ms' + )}, this is likely a bug.\n` + ) + ); + } + }); + }); + + this._timeoutId = null; + if (hasRunningTests) { + this.ensureTimeoutCheck(); + } + } + + /** + * Same as `reportHungTests` but is for use to report everything + * that is currently running when the test suite completes. + */ + reportPendingTests() { + if (this._timeoutId) { + clearTimeout(this._timeoutId); + this._timeoutId = null; + } + + this.tabs.forEach((tab) => { + const running = tab.running; + let hasFoundPending = false; + + running.forEach((report) => { + if (!hasFoundPending) { + this.write(chalk.red(`\n\nStill Pending Tests:\n\n`)); + hasFoundPending = true; + } + + const duration = this.now() - report._testStarted; + + this.write( + chalk.yellow( + `\t⛔️ Stuck (${chalk.red(duration.toLocaleString('en-US') + ' ms')}): (${ + report.data.testId + }) ${chalk.white(report.name)} ${chalk.grey(report.launcherDescription)}\n` + ) + ); + }); + }); + } + + reportSlowTests() { + const results = this.results; + let totalDuration = 0; + let testsToPrint = SLOW_TEST_COUNT; + results.sort((a, b) => { + return a.runDuration > b.runDuration ? -1 : 1; + }); + + this.write( + `\n\n\t${chalk.yellow( + `${results.length < SLOW_TEST_COUNT ? results.length : SLOW_TEST_COUNT} Longest Running Tests` + )}\n${HEADER_STR}\n` + ); + for (let i = 0; i < results.length; i++) { + const { name, runDuration } = results[i].data; + + if (i < testsToPrint) { + // this test is a known offender + if (runDuration > DEFAULT_TIMEOUT + TIMEOUT_BUFFER) { + this.write(`\n\t${i + 1}.\t[S] ${chalk.yellow(runDuration.toLocaleString('en-US') + 'ms')}\t${name}`); + testsToPrint++; + } else { + this.write(`\n\t${i + 1}.\t${chalk.yellow(runDuration.toLocaleString('en-US') + 'ms')}\t${name}`); + } + } + totalDuration += runDuration; + } + this.write( + chalk.yellow( + `\n\n\tAvg Duration of all ${results.length} tests: ${Math.round(totalDuration / results.length)}ms\n\n` + ) + ); + } + + reportFailedTests() { + this.failedTests.forEach((failure) => { + const result = failure.data; + this.write(chalk.red(`\n\t💥 Failed: ${result.runDuration.toLocaleString('en-US')}ms ${result.name}\n`)); + + result.items.forEach((diagnostic) => { + this.write(`\t\t${diagnostic.passed ? chalk.green('✅ Pass') : chalk.red('💥 Fail')} ${diagnostic.message}\n`); + + if (!diagnostic.passed && 'expected' in diagnostic && 'actual' in diagnostic) { + this.write( + `\n\t\texpected: ${printValue(diagnostic.expected, 3)}\n\t\tactual: ${printValue(diagnostic.actual, 3)}\n` + ); + } + + if (!diagnostic.passed && diagnostic.stack) { + this.write(`\n${indent(diagnostic.stack)}\n`); + } + }); + + this.write('\n\n'); + }); + + if (this.globalFailures.length) { + this.write(chalk.red(`\n\n${this.globalFailures.length} Global Failures\n\n`)); + } + + this.globalFailures.forEach((failure) => { + const result = failure.error; + const label = + result.name && result.message + ? `[${result.name}] ${result.message}` + : result.name || result.message || 'Unknown Error'; + this.write(chalk.red(`\n\t💥 Failed: ${label}\n`)); + + if (result.stack) { + this.write(`\n${indent(result.stack)}\n`); + } + + this.write('\n\n'); + }); + } + + updateFailedTestCache() { + const failedTestIds = [...this.failedTestIds.entries()]; + const allFailuresAccounted = this.globalFailures.length === 0; + const cacheFile = failedTestsFile; + + if (allFailuresAccounted) { + if (failedTestIds.length) { + fs.writeFileSync(cacheFile, failedTestIds.join(','), { encoding: 'utf-8' }); + + this.write( + chalk.yellow( + `\n\nSaved ${chalk.white(failedTestIds.length)} Failed Tests for Retry with IDS ${chalk.white( + failedTestIds.join(',') + )} in ${chalk.grey(cacheFile)}` + ) + ); + + this.write( + `\n\nTo run failed tests locally, ${chalk.cyan('visit')} ${chalk.white( + `${this.serverConfig.url}?${failedTestIds.map((id) => `testId=${id}`).join('&')}` + )}` + ); + } else { + remove(cacheFile); + } + } else { + if (failedTestIds.length) { + this.write( + `\n\nTo run failed tests locally, ${chalk.cyan('visit')} ${chalk.white( + `${this.serverConfig.url}?${failedTestIds.map((id) => `testId=${id}`).join('&')}` + )}` + ); + } + this.write(chalk.red(`\n\n⚠️ Unable to save failed tests for retry, not all failures had test IDs, cleaning up`)); + remove(cacheFile); + } + } +} + +// Instead of completely removing, we replace the contents with an empty string so that CI will still cache it. +// While this shouldn't ever really be necessary it's a bit more correct to make sure that the log gets cleared +// in the cache as well. +function remove(filePath) { + fs.writeFileSync(filePath, '', { encoding: 'utf-8' }); +} + +function printValue(value, tabs = 0) { + if (typeof value === 'string') { + return value; + } else if (typeof value === 'number') { + return value; + } else if (typeof value === 'boolean') { + return String(value); + } else if (value === null) { + return 'null'; + } else if (value === undefined) { + return 'undefined'; + } else if (Array.isArray(value)) { + return indent(`[\n ${value.map((v) => printValue(v, tabs + 1)).join(',\n ')}\n]`, tabs); + } else if (typeof value === 'object') { + return JSON.stringify(value, null, tabs * 4); + } +} diff --git a/packages/diagnostic/server/utils/const.js b/packages/diagnostic/server/utils/const.js new file mode 100644 index 00000000000..591dafed205 --- /dev/null +++ b/packages/diagnostic/server/utils/const.js @@ -0,0 +1,6 @@ +export const DEFAULT_PORT = 7357; +export const DEFAULT_HOST = 'localhost'; +export const DEFAULT_PROTOCOL = 'http'; +export const MAX_PORT_TRIES = 100; + +export const INDEX_PATHS = ['', '/', 'index.html']; diff --git a/packages/diagnostic/server/utils/debug.js b/packages/diagnostic/server/utils/debug.js new file mode 100644 index 00000000000..b56fb819541 --- /dev/null +++ b/packages/diagnostic/server/utils/debug.js @@ -0,0 +1,67 @@ +import _debug from 'debug'; +const _log = _debug('wd:diagnostic'); + +export const DEBUG_LEVEL = parseDebugLevel(process.env.DEBUG_LEVEL); + +function parseDebugLevel(v) { + if (typeof v === 'string' && v && isNaN(Number(v))) { + return getDebugLevel(v); + } else if (typeof v === 'number') { + return v; + } else if (v && !isNaN(Number(v))) { + return Number(v); + } + return 1; +} + +function getDebugLevel(str) { + switch (str.toLowerCase()) { + case 'debug': + return 0; + case 'info': + case 'log': + return 1; + case 'warn': + return 2; + case 'error': + return 3; + default: + return 1; + } +} + +export function print(message) { + if (_log.enabled) { + _log(message); + } else { + console.log(message); + } +} + +export function debug(message) { + if (DEBUG_LEVEL === 0) { + _log(message); + } +} + +export function log(message) { + if (DEBUG_LEVEL <= 1) { + _log(message); + } +} + +export function info(message) { + if (DEBUG_LEVEL <= 1) { + _log(message); + } +} + +export function warn(message) { + if (DEBUG_LEVEL <= 2) { + _log(message); + } +} + +export function error(message) { + _log(message); +} diff --git a/packages/diagnostic/server/utils/get-flags.js b/packages/diagnostic/server/utils/get-flags.js new file mode 100644 index 00000000000..ef94550a966 --- /dev/null +++ b/packages/diagnostic/server/utils/get-flags.js @@ -0,0 +1,63 @@ +export function getFlags() { + const raw = process.argv.slice(2); + for (let i = 0; i < raw.length; i++) { + const rawArg = raw[i]; + if (rawArg.startsWith('--')) { + continue; + } else if (rawArg.startsWith('-')) { + const args = rawArg.slice(1); + if (args.length > 1) { + for (let j = 0; j < args.length; j++) { + raw.push(`-${args[j]}`); + } + } + } + } + const flags = new Set(raw); + const filtered = {}; + + // global flags + const debug = flags.has('--debug') || flags.has('-d'); + const serve = flags.has('--serve') || flags.has('-s'); + const noLaunch = flags.has('--no-launch') || flags.has('-n'); + const filter = flags.has('--filter') || flags.has('-f'); + const retry = flags.has('--retry') || flags.has('-r'); + const headless = flags.has('--headless') || flags.has('-h'); + const useExisting = flags.has('--use-existing') || flags.has('-e'); + + if (filter) { + filtered['filter'] = true; + } + if (debug) { + filtered['debug'] = true; + } + if (serve) { + filtered['serve'] = true; + } + if (noLaunch) { + filtered['noLaunch'] = true; + } + if (retry) { + filtered['retry'] = true; + } + if (headless) { + filtered['headless'] = true; + } + if (useExisting) { + filtered['useExisting'] = true; + } + + return { + parsed: { + debug, + serve, + noLaunch, + filter, + retry, + headless, + useExisting, + }, + filtered, + flags, + }; +} diff --git a/packages/diagnostic/server/utils/platform.js b/packages/diagnostic/server/utils/platform.js new file mode 100644 index 00000000000..8380edf1306 --- /dev/null +++ b/packages/diagnostic/server/utils/platform.js @@ -0,0 +1,35 @@ +import os from 'os'; + +function test(platform) { + return /^win/.test(platform); +} + +const currentPlatform = test(os.platform()); + +export function isWin(platform) { + if (platform) { + return test(platform); + } + + return currentPlatform; +} + +export function isMac(platform) { + if (platform) { + return /^darwin/.test(platform); + } + + return /^darwin/.test(os.platform()); +} + +export function isLinux(platform) { + if (platform) { + return /^linux/.test(platform); + } + + return /^linux/.test(os.platform()); +} + +export function platformName() { + return isWin() ? 'win' : os.platform(); +} diff --git a/packages/diagnostic/server/utils/port.js b/packages/diagnostic/server/utils/port.js new file mode 100644 index 00000000000..a5630dd0aef --- /dev/null +++ b/packages/diagnostic/server/utils/port.js @@ -0,0 +1,33 @@ +import { DEFAULT_PORT, MAX_PORT_TRIES } from './const.js'; +import { debug } from './debug.js'; + +async function discoverPort(defaultPort, checkPort) { + debug(`Discovering available port starting from default port of ${defaultPort}`); + let port = defaultPort; + + for (let i = 0; i < MAX_PORT_TRIES; i++) { + if (await checkPort(port)) { + return port; + } + port++; + } + + throw new Error(`Could not find an available port in the range ${defaultPort} to ${port}`); +} + +export async function getPort(config, checkPort) { + if (typeof config.port === 'number') { + if (config.port < 0 || config.port > 65535) { + throw new Error(`Invalid port number: ${config.port}`); + } else if (config.port === 0) { + debug('Port is set to 0, discovering available port'); + return await discoverPort(config.defaultPort || DEFAULT_PORT, checkPort); + } else { + await checkPort(config.port); + return config.port; + } + } else { + debug(`Port is not set, discovering available port`); + return await discoverPort(config.defaultPort || DEFAULT_PORT, checkPort); + } +} diff --git a/packages/diagnostic/server/utils/time.js b/packages/diagnostic/server/utils/time.js new file mode 100644 index 00000000000..cb4b06d6bf9 --- /dev/null +++ b/packages/diagnostic/server/utils/time.js @@ -0,0 +1,16 @@ +export function sinceStart() { + const time = performance.now(); + const seconds = Math.floor(time / 1000); + const minutes = Math.floor(seconds / 60); + const ms = Math.floor(time % 1000); + + if (minutes) { + return `${minutes.toLocaleString('en-US')}m ${seconds % 60}s ${ms.toLocaleString('en-US')}ms`; + } + + if (seconds) { + return `${seconds}s ${ms.toLocaleString('en-US')}ms`; + } + + return `${ms.toLocaleString('en-US')}ms`; +} diff --git a/packages/diagnostic/src/-types.ts b/packages/diagnostic/src/-types.ts new file mode 100644 index 00000000000..1a9eebf3f4b --- /dev/null +++ b/packages/diagnostic/src/-types.ts @@ -0,0 +1,127 @@ +import type { SuiteReport } from './-types/report'; + +export type CompatTestReport = { + id: number; + name: string; + items: { passed: boolean; message: string }[]; + failed: number; + passed: number; + total: number; + runDuration: number; + skipped: boolean; + todo: boolean; + testId: string; +}; + +export interface Emitter { + emit(name: 'suite-start', data: SuiteReport): void; + emit(name: 'suite-finish', data: SuiteReport): void; + emit(name: 'test-start', data: CompatTestReport): void; + emit(name: 'test-finish', data: CompatTestReport): void; +} + +export type ParamConfig = { + id: string; + label: string; + value: boolean; +}; + +export type GlobalHooksStorage = { + onSuiteStart: GlobalCallback[]; + onSuiteFinish: GlobalCallback[]; + beforeModule: GlobalCallback[]; + afterModule: GlobalCallback[]; + beforeEach: HooksCallback[]; + afterEach: HooksCallback[]; +}; + +export type GlobalConfig = { + params: { + [key in + | 'concurrency' + | 'tryCatch' + | 'instrument' + | 'hideReport' + | 'memory' + | 'groupLogs' + | 'debug' + | 'container']: ParamConfig; + }; + _current: SuiteReport | null; + useTestem: boolean; + useDiagnostic: boolean; + concurrency: number; + globalHooks: GlobalHooksStorage; + totals: { + tests: number; + primaryModules: number; + modules: number; + skipped: number; + todo: number; + }; +}; + +export interface Diagnostic { + equal(actual: T, expected: T, message?: string): void; + notEqual(actual: T, expected: T, message?: string): void; + deepEqual(actual: T, expected: T, message?: string): void; + notDeepEqual(actual: T, expected: T, message?: string): void; + throws(fn: () => Promise, expected?: string | RegExp, message?: string): Promise; + throws(fn: () => void, expected?: string | RegExp, message?: string): void; + doesNotThrow(fn: () => Promise, expected?: string | RegExp, message?: string): Promise; + doesNotThrow(fn: () => void, expected?: string | RegExp, message?: string): void; + true(actual: boolean, message?: string): void; + false(actual: boolean, message?: string): void; + ok(actual: unknown, message?: string): void; + notOk(actual: unknown, message?: string): void; + expect(count: number): void; + step(name: string): void; + verifySteps(steps: string[], message?: string): void; +} + +export interface TestContext {} + +export type GlobalCallback = () => void | Promise; + +export interface Hooks { + beforeEach: (cb: HooksCallback) => void; + afterEach: (cb: HooksCallback) => void; + beforeModule: (cb: GlobalCallback) => void; + afterModule: (cb: GlobalCallback) => void; +} +export interface GlobalHooks extends Hooks { + onSuiteStart: (cb: GlobalCallback) => void; + onSuiteFinish: (cb: GlobalCallback) => void; +} + +export type HooksCallback = (this: TC, assert: Diagnostic) => void | Promise; +export type ModuleCallback = ((hooks: Hooks) => void) | (() => void); +export type TestCallback = (this: TC, assert: Diagnostic) => void | Promise; + +export interface TestInfo { + id: string; + name: string; + cb: TestCallback; + skip: boolean; + todo: boolean; + module: ModuleInfo; +} + +export interface OrderedMap { + byName: Map; + byOrder: T[]; +} + +export interface ModuleInfo { + moduleName: string; + name: string; + cb: ModuleCallback; + config: { + beforeEach: HooksCallback[]; + afterEach: HooksCallback[]; + beforeModule: GlobalCallback[]; + afterModule: GlobalCallback[]; + }; + tests: OrderedMap>; + modules: OrderedMap>; +} diff --git a/packages/diagnostic/src/-types/report.ts b/packages/diagnostic/src/-types/report.ts new file mode 100644 index 00000000000..46e8a79f509 --- /dev/null +++ b/packages/diagnostic/src/-types/report.ts @@ -0,0 +1,57 @@ +export interface SuiteReport { + totals: { + tests: number; + primaryModules: number; + modules: number; + skipped: number; + todo: number; + }; + passed: number; + failed: number; + skipped: number; + todo: number; + start: PerformanceMark | null; + end: PerformanceMark | null; + measure: PerformanceMeasure | PerformanceMark | null; +} +export interface TestReport { + id: string; + name: string; + skipped: boolean; + todo: boolean; + start: PerformanceMark | null; + end: PerformanceMark | null; + measure: PerformanceMeasure | PerformanceMark | null; + result: { + diagnostics: DiagnosticReport[]; + passed: boolean; + failed: boolean; + }; + module: ModuleReport; +} +export interface ModuleReport { + name: string; + start: PerformanceMark | null; + end: PerformanceMark | null; + measure: PerformanceMeasure | PerformanceMark | null; + passed: boolean; + failed: boolean; +} +export interface DiagnosticReport { + testId: string; + message: string; + passed: boolean; + expected: unknown; + actual: unknown; + stack: string; +} + +export interface Reporter { + onSuiteStart: (report: SuiteReport) => void; + onSuiteFinish: (report: SuiteReport) => void; + onTestStart: (test: TestReport) => void; + onTestFinish: (test: TestReport) => void; + onModuleStart: (module: ModuleReport) => void; + onModuleFinish: (module: ModuleReport) => void; + onDiagnostic: (diagnostic: DiagnosticReport) => void; +} diff --git a/packages/diagnostic/src/-utils.ts b/packages/diagnostic/src/-utils.ts new file mode 100644 index 00000000000..31dde59ef91 --- /dev/null +++ b/packages/diagnostic/src/-utils.ts @@ -0,0 +1,71 @@ +/* global window, globalThis, global, self */ +import type { GlobalHooksStorage, HooksCallback, ModuleInfo, TestContext } from './-types'; + +export function assert(message: string, test: unknown): asserts test { + if (!test) { + throw new Error(message); + } +} + +export function getGlobal(): typeof globalThis { + // prettier-ignore + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const g: typeof globalThis | null = + typeof globalThis !== 'undefined' ? globalThis + : typeof window !== 'undefined' ? window + // @ts-expect-error global is node only + : typeof global !== 'undefined' ? global + : typeof self !== 'undefined' ? self + : null; + + assert(`Expected to find a global object`, g !== null); + return g as unknown as typeof globalThis; +} + +export function getChain( + globalHooks: GlobalHooksStorage, + module: ModuleInfo, + parents: ModuleInfo[] | null, + prop: 'beforeEach' | 'afterEach' +): HooksCallback[] { + const chain: HooksCallback[] = []; + + if (globalHooks[prop].length) { + chain.push(...globalHooks[prop]); + } + + if (parents) { + for (const parent of parents) { + if (parent.config[prop].length) { + chain.push(...parent.config[prop]); + } + } + } + if (module.config[prop].length) { + chain.push(...module.config[prop]); + } + + if (prop === 'afterEach') { + chain.reverse(); + } + + return chain; +} + +export function generateHash(str: string) { + let hash = 0; + + for (let i = 0; i < str.length; i++) { + hash = (hash << 5) - hash + str.charCodeAt(i); + hash |= 0; + } + + // Convert the possibly negative integer hash code into an 8 character hex string, which isn't + // strictly necessary but increases user understanding that the id is a SHA-like hash + let hex = (0x100000000 + hash).toString(16); + if (hex.length < 8) { + hex = '0000000' + hex; + } + + return hex.slice(-8); +} diff --git a/packages/diagnostic/src/ember.ts b/packages/diagnostic/src/ember.ts new file mode 100644 index 00000000000..5ae8277f9fb --- /dev/null +++ b/packages/diagnostic/src/ember.ts @@ -0,0 +1,73 @@ +import type { SetupContextOptions, TestContext } from '@ember/test-helpers'; +import { getTestMetadata, setupContext, teardownContext } from '@ember/test-helpers'; + +import AbstractTestLoader from 'ember-cli-test-loader/test-support/index'; + +import type { Hooks } from './-types'; +import { setupGlobalHooks } from './internals/config'; + +// fix bug with embroider/webpack/auto-import and test-loader +// prettier-ignore +// @ts-expect-error +const CLITestLoader: typeof AbstractTestLoader = AbstractTestLoader.default + // @ts-expect-error + ? AbstractTestLoader.default as typeof AbstractTestLoader + : AbstractTestLoader; + +export function setupTest(hooks: Hooks, opts?: SetupContextOptions) { + const options = { waitForSettled: false, ...opts }; + + hooks.beforeEach(async function () { + const testMetadata = getTestMetadata(this); + testMetadata.framework = 'qunit'; + + await setupContext(this, options); + }); + + hooks.afterEach(function (this: TestContext) { + return teardownContext(this, options); + }); +} + +let moduleLoadFailures: Error[] = []; + +class TestLoader extends CLITestLoader { + moduleLoadFailure(moduleName: string, error: Error) { + moduleLoadFailures.push(error); + } +} + +/** + Load tests following the default patterns: + + * The module name ends with `-test` + * The module name ends with `.jshint` + + @method loadTests + */ +function loadTests() { + TestLoader.load(); +} + +export function configure() { + setupGlobalHooks((hooks) => { + hooks.onSuiteFinish(() => { + const length = moduleLoadFailures.length; + + try { + if (length === 0) { + // do nothing + } else if (length === 1) { + throw moduleLoadFailures[0]; + } else { + throw new Error('\n' + moduleLoadFailures.join('\n')); + } + } finally { + // ensure we release previously captured errors. + moduleLoadFailures = []; + } + }); + }); + + loadTests(); +} diff --git a/packages/diagnostic/src/emitters/diagnostic.ts b/packages/diagnostic/src/emitters/diagnostic.ts new file mode 100644 index 00000000000..5d7c20cfe6d --- /dev/null +++ b/packages/diagnostic/src/emitters/diagnostic.ts @@ -0,0 +1,117 @@ +import type { CompatTestReport, Emitter } from '../-types'; +import type { SuiteReport } from '../-types/report'; +import { assert } from '../-utils'; + +type EmitEvent = { + name: 'suite-start' | 'suite-finish' | 'test-start' | 'test-finish'; + data: SuiteReport | CompatTestReport; +}; + +class DiagnosticEmitter implements Emitter { + socket: WebSocket; + connected: boolean; + buffer: EmitEvent[] = []; + browserId: string; + windowId: string; + + constructor() { + // A test url might look like + // http://localhost:7537/1984/1/tests/index.html?hidepassed&filter=foo + // where 1984 is the browserId and 1 is the windowId + const params = new URLSearchParams(window.location.search); + const host = window.location.host; + const protocol = window.location.protocol === 'https:' ? 'wss://' : 'ws://'; + const browserId = params.get('b')!; + const windowId = params.get('w')!; + const url = `${protocol}${host}/ws`; + this.browserId = browserId; + this.windowId = windowId; + this.connected = false; + this.buffer = []; + + if (!browserId || !windowId) { + console.warn( + `[Diagnostic] Expected to find a browserId and windowId in the url. Likely this page was not served by the diagnostic server. Remote reporting will not be available.` + ); + this.socket = null as unknown as WebSocket; + return; + } + + console.log(`[Diagnostic] Attempting to connect to remote reporter at ${url}`); + try { + const socket = new WebSocket(url); + socket.onopen = (_event) => { + console.log(`[Diagnostic] Remote Reporter Connection established`); + this.connected = true; + this.buffer.forEach((event) => { + this.emit(event.name as 'suite-start', event.data as SuiteReport); + }); + this.buffer = []; + }; + + socket.onclose = (event) => { + this.connected = false; + if (event.wasClean) { + console.log( + `[Diagnostic] Remote Reporter Connection closed cleanly, code=${event.code} reason=${event.reason}` + ); + } else { + console.error(`[Diagnostic] Remote Reporter Connection Died`, event); + } + }; + socket.onerror = (e) => { + this.connected = false; + console.error(e); + throw new Error(`[Diagnostic] Remote Reporter Connection Failed`); + }; + socket.onmessage = (message: MessageEvent) => { + const msg = JSON.parse(message.data) as { name: 'close' }; + if (msg.name === 'close') { + window.close(); + } else { + throw new Error(`[Diagnostic] Unexpected message from server`); + } + }; + + this.socket = socket; + } catch (e) { + console.error(`[Diagnostic] Unexpected error trying to connect`, e); + this.socket = null as unknown as WebSocket; + } + } + + emit(name: 'suite-start', data: SuiteReport): void; + emit(name: 'suite-finish', data: SuiteReport): void; + emit(name: 'test-start', data: CompatTestReport): void; + emit(name: 'test-finish', data: CompatTestReport): void; + emit(name: 'suite-start' | 'suite-finish' | 'test-start' | 'test-finish', data: SuiteReport | CompatTestReport) { + if (!this.socket) { + return; + } + if (!this.connected) { + this.buffer.push({ name, data }); + return; + } + + assert( + `Expected event.name to be one of 'suite-start', 'suite-finish', 'test-start' or 'test-finish'`, + ['suite-start', 'suite-finish', 'test-start', 'test-finish'].includes(name) + ); + assert(`Expected event.data to be defined`, typeof data !== 'undefined'); + const event = { browserId: this.browserId, windowId: this.windowId, name, data, timestamp: Date.now() }; + + this.socket.send(JSON.stringify(event)); + } +} + +// function getRelativeTimeStamp(timestamp: number) { +// const now = Date.now(); +// const perfNow = performance.now(); + +// const diff = perfNow - timestamp; +// return now - diff; +// } + +export function createDiagnosticEmitter(): Promise { + return Promise.resolve(new DiagnosticEmitter()); +} diff --git a/packages/diagnostic/src/emitters/testem.ts b/packages/diagnostic/src/emitters/testem.ts new file mode 100644 index 00000000000..33b29a628f0 --- /dev/null +++ b/packages/diagnostic/src/emitters/testem.ts @@ -0,0 +1,61 @@ +import type { CompatTestReport, Emitter } from '../-types'; +import type { SuiteReport } from '../-types/report'; +import { assert } from '../-utils'; + +type TestemSocket = { + emit(name: 'tests-start'): void; // suite-start + emit(name: 'all-test-results'): void; // suite-finish + emit(name: 'tests-start', data: CompatTestReport): void; // test-start + emit(name: 'test-result', data: CompatTestReport): void; // test-finish +}; + +interface TestemGlobal { + useCustomAdapter(callback: (socket: TestemSocket) => void): void; +} + +class TestemEmitter implements Emitter { + socket: TestemSocket; + + constructor(socket: TestemSocket) { + this.socket = socket; + } + + emit(name: 'suite-start', data: SuiteReport): void; + emit(name: 'suite-finish', data: SuiteReport): void; + emit(name: 'test-start', data: CompatTestReport): void; + emit(name: 'test-finish', data: CompatTestReport): void; + emit(name: 'suite-start' | 'suite-finish' | 'test-start' | 'test-finish', data: SuiteReport | CompatTestReport) { + assert( + `Expected event.name to be one of 'suite-start', 'suite-finish', 'test-start' or 'test-finish'`, + ['suite-start', 'suite-finish', 'test-start', 'test-finish'].includes(name) + ); + assert(`Expected event.data to be defined`, typeof data !== 'undefined'); + + if (name === 'suite-start') { + this.socket.emit('tests-start'); + } else if (name === 'suite-finish') { + this.socket.emit('all-test-results'); + } else if (name === 'test-start') { + this.socket.emit('tests-start', data as CompatTestReport); + } else if (name === 'test-finish') { + this.socket.emit('test-result', data as CompatTestReport); + } + } +} + +export function createTestemEmitter(): Promise { + return new Promise((resolve, reject) => { + // @ts-expect-error + const _Testem: TestemGlobal = window.Testem as TestemGlobal; + const hasTestem = typeof _Testem !== 'undefined'; + + if (!hasTestem) { + return reject(new Error('Testem is not present on the page.')); + } + + _Testem.useCustomAdapter((socket: TestemSocket) => { + const emitter = new TestemEmitter(socket); + resolve(emitter); + }); + }); +} diff --git a/packages/diagnostic/src/index.ts b/packages/diagnostic/src/index.ts new file mode 100644 index 00000000000..92eee74002c --- /dev/null +++ b/packages/diagnostic/src/index.ts @@ -0,0 +1,154 @@ +import type { ModuleCallback, ModuleInfo, OrderedMap, TestCallback, TestContext, TestInfo } from './-types'; +import type { SuiteReport } from './-types/report'; +import { assert, generateHash } from './-utils'; +import { Config, getCurrentModule, HooksDelegate, instrument, setCurrentModule } from './internals/config'; +import { DelegatingReporter } from './internals/delegating-reporter'; +import { runModule } from './internals/run'; + +export { registerReporter } from './internals/delegating-reporter'; +export { setupGlobalHooks, configure } from './internals/config'; + +const Modules: OrderedMap> = { + byName: new Map(), + byOrder: [], +}; + +export type { Diagnostic, Hooks as NestedHooks, GlobalHooks, TestContext } from './-types'; + +export function module(name: string, cb: ModuleCallback): void { + const parentModule = getCurrentModule() ?? null; + let moduleName = name; + if (parentModule) { + moduleName = `${parentModule.name} > ${name}`; + } else { + Config.totals.primaryModules++; + } + Config.totals.modules++; + + assert(`Cannot add the same module name twice: ${moduleName}`, !Modules.byName.has(moduleName)); + const moduleConfig: ModuleInfo['config'] = { + beforeEach: [], + afterEach: [], + beforeModule: [], + afterModule: [], + }; + const tests: OrderedMap> = { byName: new Map(), byOrder: [] }; + const modules: OrderedMap> = { byName: new Map(), byOrder: [] }; + const moduleInfo = { + moduleName, + name, + cb, + config: moduleConfig, + tests, + modules, + parent: parentModule, + }; + + setCurrentModule(moduleInfo); + + if (parentModule) { + parentModule.modules.byName.set(name, moduleInfo); + parentModule.modules.byOrder.push(moduleInfo); + } else { + // @ts-expect-error TS poorly handles subtype constraints + Modules.byName.set(name, moduleInfo); + // @ts-expect-error TS poorly handles subtype constraints + Modules.byOrder.push(moduleInfo); + } + + cb(HooksDelegate); + setCurrentModule(parentModule as unknown as ModuleInfo); +} + +export function test(name: string, cb: TestCallback): void { + const currentModule = getCurrentModule(); + assert(`Cannot add a test outside of a module`, !!currentModule); + assert(`Cannot add the same test name twice: ${name}`, !currentModule.tests.byName.has(name)); + Config.totals.tests++; + + const testInfo = { + id: generateHash(currentModule.moduleName + ' > ' + name), + name, + cb, + skip: false, + todo: false, + module: currentModule, + }; + + currentModule.tests.byName.set(name, testInfo); + currentModule.tests.byOrder.push(testInfo); +} + +export function todo(name: string, cb: TestCallback): void { + const currentModule = getCurrentModule(); + assert(`Cannot add a test outside of a module`, !!currentModule); + assert(`Cannot add the same test name twice: ${name}`, !currentModule.tests.byName.has(name)); + Config.totals.todo++; + + const testInfo = { + id: generateHash(currentModule.moduleName + ' > ' + name), + name, + cb, + skip: false, + todo: true, + module: currentModule, + }; + + currentModule.tests.byName.set(name, testInfo); + currentModule.tests.byOrder.push(testInfo); +} + +export function skip(name: string, cb: TestCallback): void { + const currentModule = getCurrentModule(); + assert(`Cannot add a test outside of a module`, !!currentModule); + assert(`Cannot add the same test name twice: ${name}`, !currentModule.tests.byName.has(name)); + Config.totals.skipped++; + + const testInfo = { + id: generateHash(currentModule.moduleName + ' > ' + name), + name, + cb, + skip: true, + todo: false, + module: currentModule, + }; + + currentModule.tests.byName.set(name, testInfo); + currentModule.tests.byOrder.push(testInfo); +} + +export async function start() { + const report: SuiteReport = { + totals: Object.assign({}, Config.totals), + passed: 0, + failed: 0, + skipped: 0, + todo: 0, + start: null, + end: null, + measure: null, + }; + Config._current = report; + report.start = instrument() && performance.mark('@warp-drive/diagnostic:start'); + + DelegatingReporter.onSuiteStart(report); + for (const hook of Config.globalHooks.onSuiteStart) { + await hook(); + } + + const promises: Promise[] = []; + for (const _module of Modules.byOrder) { + await runModule(_module, null, promises); + } + if (promises.length) { + await Promise.all(promises); + } + + for (const hook of Config.globalHooks.onSuiteFinish) { + await hook(); + } + report.end = instrument() && performance.mark('@warp-drive/diagnostic:end'); + report.measure = + instrument() && performance.measure('@warp-drive/diagnostic:run', report.start.name, report.end.name); + DelegatingReporter.onSuiteFinish(report); +} diff --git a/packages/diagnostic/src/internals/config.ts b/packages/diagnostic/src/internals/config.ts new file mode 100644 index 00000000000..c754ed17b3c --- /dev/null +++ b/packages/diagnostic/src/internals/config.ts @@ -0,0 +1,219 @@ +/* global Testem */ +import type { + GlobalCallback, + GlobalConfig, + GlobalHooks, + HooksCallback, + ModuleInfo, + ParamConfig, + TestContext, +} from '../-types'; +import { assert } from '../-utils'; + +export const Config: GlobalConfig = { + globalHooks: { + beforeEach: [], + afterEach: [], + beforeModule: [], + afterModule: [], + onSuiteStart: [], + onSuiteFinish: [], + }, + // @ts-expect-error + useTestem: typeof Testem !== 'undefined', + // @ts-expect-error + useDiagnostic: typeof Testem === 'undefined', + concurrency: 1, + params: { + hideReport: { + id: 'hideReport', + label: 'Hide Report', + value: true, + }, + concurrency: { + id: 'concurrency', + label: 'Enable Concurrency', + value: false, + }, + memory: { + id: 'memory', + label: 'Instrument Memory', + value: false, + }, + instrument: { + id: 'performance', + label: 'Instrument Performance', + value: true, + }, + groupLogs: { + id: 'groupLogs', + label: 'Group Logs', + value: true, + }, + debug: { + id: 'debug', + label: 'Debug Mode', + value: false, + }, + container: { + id: 'container', + label: 'Hide Container', + value: true, + }, + tryCatch: { + id: 'tryCatch', + label: 'No Try/Catch', + value: true, + }, + }, + totals: { + tests: 0, + primaryModules: 0, + modules: 0, + skipped: 0, + todo: 0, + }, + _current: null, +}; + +let currentModule: ModuleInfo; +let isResolvingGlobalHooks = false; +export const HooksDelegate = { + beforeEach(cb: HooksCallback): void { + if (isResolvingGlobalHooks) { + // @ts-expect-error TS poorly handles subtype constraints + Config.globalHooks.beforeEach.push(cb); + } else { + // @ts-expect-error TS poorly handles subtype constraints + currentModule.config.beforeEach.push(cb); + } + }, + afterEach(cb: HooksCallback): void { + if (isResolvingGlobalHooks) { + // @ts-expect-error TS poorly handles subtype constraints + Config.globalHooks.afterEach.push(cb); + } else { + // @ts-expect-error TS poorly handles subtype constraints + currentModule.config.afterEach.push(cb); + } + }, + beforeModule(cb: GlobalCallback): void { + if (isResolvingGlobalHooks) { + Config.globalHooks.beforeModule.push(cb); + } else { + currentModule.config.beforeModule.push(cb); + } + }, + afterModule(cb: GlobalCallback): void { + if (isResolvingGlobalHooks) { + Config.globalHooks.afterModule.push(cb); + } else { + currentModule.config.afterModule.push(cb); + } + }, + onSuiteStart(cb: GlobalCallback): void { + assert(`Cannot add a global onSuiteStart hook inside of a module`, isResolvingGlobalHooks); + Config.globalHooks.onSuiteStart.push(cb); + }, + onSuiteFinish(cb: GlobalCallback): void { + assert(`Cannot add a global onSuiteFinish hook inside of a module`, isResolvingGlobalHooks); + Config.globalHooks.onSuiteFinish.push(cb); + }, +}; + +export function getCurrentModule(): ModuleInfo { + return currentModule; +} + +export function setCurrentModule(module: ModuleInfo) { + // @ts-expect-error TS poorly handles subtype constraints + currentModule = module; +} + +export function setupGlobalHooks(cb: (hooks: GlobalHooks) => void): void { + isResolvingGlobalHooks = true; + cb(HooksDelegate); + isResolvingGlobalHooks = false; +} + +export type ConfigOptions = { + concurrency: number; + instrument: boolean; + tryCatch: boolean; + debug: boolean; + groupLogs: boolean; + memory: boolean; + container: boolean; + hideReport: boolean; + params: Record; + useTestem: boolean; + useDiagnostic: boolean; +}; +const configOptions = [ + 'concurrency', + 'tryCatch', + 'instrument', + 'hideReport', + 'memory', + 'groupLogs', + 'debug', + 'container', +] as const; +export function configure(options: ConfigOptions): void { + if (options.useTestem && options.useDiagnostic) { + throw new Error( + `Cannot use both Testem and Diagnostic at the same time. Please remove one of these options or set it to false.` + ); + } + if ('useTestem' in options && typeof options.useTestem === 'boolean') { + Config.useTestem = options.useTestem; + Config.useDiagnostic = !options.useTestem; + } + if ('useDiagnostic' in options && typeof options.useDiagnostic === 'boolean') { + Config.useDiagnostic = options.useDiagnostic; + Config.useTestem = !options.useDiagnostic; + } + + if ('concurrency' in options && typeof options.concurrency === 'number') { + Config.concurrency = options.concurrency; + // @ts-expect-error + options.concurrency = options.concurrency > 1; + } + configOptions.forEach((key) => { + if (key in options && typeof options[key] === 'boolean') { + Config.params[key].value = options[key] as boolean; + } + // don't allow setting these params via configure + if (options.params?.[key]) { + delete options.params[key]; + } + }); + + // copy over any remaining params + Object.assign(Config.params, options.params); +} + +export function getSettings() { + return { + useTestem: Config.useTestem, + useDiagnostic: Config.useDiagnostic, + concurrency: Config.concurrency, + params: Config.params, + }; +} + +export function instrument() { + return (Config.params.instrument.value || null) as unknown as PerformanceMark; +} + +export function groupLogs() { + return Config.params.groupLogs.value; +} + +// 0 - stop +// 1 - start +// 2 - back +// 3 - forward +// 4 - restart +export function updateSuiteState(value: number) {} +export function updateConfigValue(key: string, value: boolean) {} diff --git a/packages/diagnostic/src/internals/delegating-reporter.ts b/packages/diagnostic/src/internals/delegating-reporter.ts new file mode 100644 index 00000000000..8b0163c65a6 --- /dev/null +++ b/packages/diagnostic/src/internals/delegating-reporter.ts @@ -0,0 +1,59 @@ +import type { Reporter, SuiteReport } from '../-types/report'; + +const Reporters = new Set(); +export function registerReporter(reporter: Reporter) { + Reporters.add(reporter); +} + +let activeSuite: SuiteReport; +export const DelegatingReporter: Reporter = { + onSuiteStart(report) { + if (activeSuite) { + throw new Error(`Cannot start a test suite while another suite is active`); + } + activeSuite = report; + for (const reporter of Reporters) { + reporter.onSuiteStart(report); + } + }, + onSuiteFinish(report) { + activeSuite = null as unknown as SuiteReport; + for (const reporter of Reporters) { + reporter.onSuiteFinish(report); + } + }, + onTestStart(report) { + for (const reporter of Reporters) { + reporter.onTestStart(report); + } + }, + onTestFinish(report) { + activeSuite.passed += report.result.passed ? 1 : 0; + activeSuite.failed += report.result.failed ? 1 : 0; + activeSuite.skipped += report.skipped ? 1 : 0; + activeSuite.todo += report.result.passed && report.todo ? 1 : 0; + + const module = report.module; + module.failed = report.result.failed || module.failed; + module.passed = !module.failed; + + for (const reporter of Reporters) { + reporter.onTestFinish(report); + } + }, + onModuleStart(report) { + for (const reporter of Reporters) { + reporter.onModuleStart(report); + } + }, + onModuleFinish(report) { + for (const reporter of Reporters) { + reporter.onModuleFinish(report); + } + }, + onDiagnostic(report) { + for (const reporter of Reporters) { + reporter.onDiagnostic(report); + } + }, +}; diff --git a/packages/diagnostic/src/internals/diagnostic.ts b/packages/diagnostic/src/internals/diagnostic.ts new file mode 100644 index 00000000000..13cb703953e --- /dev/null +++ b/packages/diagnostic/src/internals/diagnostic.ts @@ -0,0 +1,303 @@ +import type { GlobalConfig, TestContext, TestInfo } from '../-types'; +import type { DiagnosticReport, Reporter, TestReport } from '../-types/report'; +import equiv from '../legacy/equiv'; + +class InternalCompat { + declare _diagnostic: Diagnostic; + + constructor(diagnostic: Diagnostic) { + this._diagnostic = diagnostic; + } + + get testId() { + return this._diagnostic.__currentTest.id; + } + + get expected() { + return this._diagnostic.expected; + } + set expected(value) { + this._diagnostic.expected = value; + } +} + +export class Diagnostic { + declare __currentTest: TestInfo; + declare __report: TestReport; + declare __config: GlobalConfig; + declare __reporter: Reporter; + declare expected: number | null; + declare _steps: string[]; + + // QUnit private API compat + declare test: InternalCompat; + + constructor(reporter: Reporter, config: GlobalConfig, test: TestInfo, report: TestReport) { + this.__currentTest = test; + this.__report = report; + this.__config = config; + this.__reporter = reporter; + this.expected = null; + this._steps = []; + this.test = new InternalCompat(this); + } + + pushResult( + result: Pick & { result?: boolean } + ): void { + const diagnostic = Object.assign({ passed: result.passed ?? result.result }, result, { + testId: this.__currentTest.id, + }); + this.__report.result.diagnostics.push(diagnostic); + + if (!diagnostic.passed) { + this.__report.result.passed = false; + this.__report.result.failed = true; + } + + this.__reporter.onDiagnostic(diagnostic); + } + + equal(actual: T, expected: T, message?: string): void { + if (actual !== expected) { + if (this.__config.params.tryCatch.value) { + try { + throw new Error(message || `Expected ${String(actual)} to equal ${String(expected)}`); + } catch (err) { + this.pushResult({ + message: message || 'equal', + stack: (err as Error).stack!, + passed: false, + actual, + expected, + }); + } + } else { + this.pushResult({ + message: message || 'equal', + stack: '', + passed: false, + actual, + expected, + }); + } + } else { + this.pushResult({ + message: message || 'equal', + stack: '', + passed: true, + actual: true, + expected: true, + }); + } + } + + notEqual(actual: T, expected: T, message?: string): void { + if (actual === expected) { + throw new Error(message || `Expected ${String(actual)} to not equal ${String(expected)}`); + } + } + + deepEqual(actual: T, expected: T, message?: string): void { + const isEqual = equiv(actual, expected); + if (!isEqual) { + if (this.__config.params.tryCatch.value) { + try { + throw new Error(message || `Expected items to be equivalent`); + } catch (err) { + this.pushResult({ + message: message || 'deepEqual', + stack: (err as Error).stack!, + passed: false, + actual, + expected, + }); + } + } else { + this.pushResult({ + message: message || 'deepEqual', + stack: '', + passed: false, + actual, + expected, + }); + } + } else { + this.pushResult({ + message: message || 'deepEqual', + stack: '', + passed: true, + actual: true, + expected: true, + }); + } + } + + notDeepEqual(actual: T, expected: T, message?: string): void { + const isEqual = equiv(actual, expected); + if (isEqual) { + if (this.__config.params.tryCatch.value) { + try { + throw new Error(message || `Expected items to not be equivalent`); + } catch (err) { + this.pushResult({ + message: message || 'notDeepEqual', + stack: (err as Error).stack!, + passed: false, + actual, + expected, + }); + } + } else { + this.pushResult({ + message: message || 'notDeepEqual', + stack: '', + passed: false, + actual, + expected, + }); + } + } else { + this.pushResult({ + message: message || 'notDeepEqual', + stack: '', + passed: true, + actual: true, + expected: true, + }); + } + } + + true(actual: boolean, message?: string): void { + this.equal(actual, true, message); + } + + false(actual: boolean, message?: string): void { + this.equal(actual, false, message); + } + + ok(actual: unknown, message?: string): void { + this.equal(!!actual, true, message); + } + + notOk(actual: unknown, message?: string): void { + this.equal(!!actual, false, message); + } + + expect(count: number): void { + this.expected = count; + } + + step(name: string): void { + this._steps.push(name); + } + + verifySteps(steps: string[], message?: string): void { + this.deepEqual(this._steps, steps, message); + this._steps = []; + } + + _finalize(): void { + if (this.expected !== null && this.expected !== this.__report.result.diagnostics.length) { + this.pushResult({ + message: `Expected ${this.expected} assertions, but ${this.__report.result.diagnostics.length} were run`, + stack: '', + passed: false, + actual: false, + expected: true, + }); + } + if (this.__report.result.diagnostics.length === 0) { + this.pushResult({ + message: `Expected at least one assertion, but none were run`, + stack: '', + passed: false, + actual: false, + expected: true, + }); + } + if (this._steps.length) { + this.pushResult({ + message: `Expected 0 steps remaining to verify, but ${this._steps.length} were run`, + stack: '', + passed: false, + actual: false, + expected: true, + }); + } + } + + throws(fn: () => Promise, expected?: string | RegExp, message?: string): Promise; + throws(fn: () => void, expected?: string | RegExp, message?: string): void; + throws(fn: () => void | Promise, expected?: string | RegExp, message?: string): Promise | void { + try { + const result = fn(); + const resolved = Promise.resolve(result); + const isPromise = resolved === result; + + if (!isPromise) { + throw new Error(`Expected function to throw ${expected}`); + } + + return resolved.then( + () => { + throw new Error(`Expected function to throw ${expected}`); + }, + (err: Error | string) => { + if (expected) { + if (typeof expected === 'string') { + this.equal(typeof err === 'string' ? err : err.message, expected, message); + } else { + this.equal(typeof err === 'string' ? err : expected.test(err.message), true, message); + } + } + } + ); + } catch (err) { + if (expected) { + if (typeof expected === 'string') { + this.equal(err instanceof Error ? err.message : err, expected, message); + } else { + this.equal(expected.test(err instanceof Error ? err.message : (err as string)), true, message); + } + } + } + } + + doesNotThrow(fn: () => Promise, expected?: string | RegExp, message?: string): Promise; + doesNotThrow(fn: () => void, expected?: string | RegExp, message?: string): void; + doesNotThrow(fn: () => void | Promise, expected?: string | RegExp, message?: string): Promise | void { + try { + const result = fn(); + const resolved = Promise.resolve(result); + const isPromise = resolved === result; + + if (!isPromise) { + return; + } + + return resolved.then( + () => { + return; + }, + (err: Error | string) => { + if (expected) { + if (typeof expected === 'string') { + this.equal(typeof err === 'string' ? err : err.message, expected, message); + } else { + this.equal(expected.test(typeof err === 'string' ? err : err.message), true, message); + } + } + } + ); + } catch (err) { + if (expected) { + if (typeof expected === 'string') { + this.equal(err instanceof Error ? err.message : err, expected, message); + } else { + this.equal(expected.test(err instanceof Error ? err.message : (err as string)), true, message); + } + } + } + } +} diff --git a/packages/diagnostic/src/internals/run.ts b/packages/diagnostic/src/internals/run.ts new file mode 100644 index 00000000000..f2fab1b980c --- /dev/null +++ b/packages/diagnostic/src/internals/run.ts @@ -0,0 +1,156 @@ +import type { HooksCallback, ModuleInfo, TestContext, TestInfo } from '../-types'; +import type { ModuleReport, TestReport } from '../-types/report'; +import { getChain } from '../-utils'; +import { Config, groupLogs, instrument } from './config'; +import { DelegatingReporter } from './delegating-reporter'; +import { Diagnostic } from './diagnostic'; + +export async function runTest( + moduleReport: ModuleReport, + beforeChain: HooksCallback[], + test: TestInfo, + afterChain: HooksCallback[] +) { + const testContext = {} as TC; + const testReport: TestReport = { + id: test.id, + name: test.name, + skipped: test.skip, + todo: test.todo, + start: null, + end: null, + measure: null, + result: { + diagnostics: [], + passed: true, + failed: false, + }, + module: moduleReport, + }; + testReport.start = instrument() && performance.mark(`test:${test.module.moduleName} > ${test.name}:start`); + const Assert = new Diagnostic(DelegatingReporter, Config, test, testReport); + + groupLogs() && console.groupCollapsed(test.name); + DelegatingReporter.onTestStart(testReport); + + if (test.skip) { + groupLogs() && console.groupEnd(); + testReport.end = instrument() && performance.mark(`test:${test.module.moduleName} > ${test.name}:end`); + testReport.measure = + instrument() && + performance.measure(`test:${test.module.moduleName} > ${test.name}`, testReport.start.name, testReport.end.name); + + DelegatingReporter.onTestFinish(testReport); + return; + } + + for (const hook of beforeChain) { + await hook.call(testContext, Assert); + } + + try { + await test.cb.call(testContext, Assert); + } catch (err) { + Assert.pushResult({ + message: `Unexpected Test Failure: ${(err as Error).message}`, + stack: (err as Error).stack!, + passed: false, + actual: false, + expected: true, + }); + if (!Config.params.tryCatch.value) { + throw err; + } + } + + for (const hook of afterChain) { + await hook.call(testContext, Assert); + } + Assert._finalize(); + + groupLogs() && console.groupEnd(); + testReport.end = instrument() && performance.mark(`test:${test.module.moduleName} > ${test.name}:end`); + testReport.measure = + instrument() && + performance.measure(`test:${test.module.moduleName} > ${test.name}`, testReport.start.name, testReport.end.name); + + DelegatingReporter.onTestFinish(testReport); +} + +export async function runModule( + module: ModuleInfo, + parents: ModuleInfo[] | null, + promises: Promise[] +) { + groupLogs() && console.groupCollapsed(module.name); + const moduleReport: ModuleReport = { + name: module.moduleName, + start: null, + end: null, + measure: null, + passed: true, + failed: false, + }; + moduleReport.start = instrument() && performance.mark(`module:${module.moduleName}:start`); + + DelegatingReporter.onModuleStart(moduleReport); + for (const hook of Config.globalHooks.beforeModule) { + await hook(); + } + + for (const hook of module.config.beforeModule) { + await hook(); + } + + // run tests + const beforeChain = getChain(Config.globalHooks, module, parents, 'beforeEach'); + const afterChain = getChain(Config.globalHooks, module, parents, 'afterEach'); + + if (Config.params.concurrency.value && Config.concurrency > 1) { + const tests = module.tests.byOrder; + let remainingTests = tests.length; + let currentTest = 0; + + // once remaining tests is 0, we move on + // to the next module after at least one race has completed + while (remainingTests > 0) { + const needed = Config.concurrency - promises.length; + const available = Math.min(needed, remainingTests, Config.concurrency); + for (let i = 0; i < available; i++) { + const test = tests[currentTest++]!; + remainingTests--; + const promise = runTest(moduleReport, beforeChain, test, afterChain).finally(() => { + const index = promises.indexOf(promise); + promises.splice(index, 1); + }); + promises.push(promise); + } + + if (promises.length === Config.concurrency) { + await Promise.race(promises); + } + } + } else { + for (const test of module.tests.byOrder) { + await runTest(moduleReport, beforeChain, test, afterChain); + } + } + + // run modules + for (const childModule of module.modules.byOrder) { + await runModule(childModule, [...(parents || []), module], promises); + } + + for (const hook of module.config.afterModule) { + await hook(); + } + + for (const hook of Config.globalHooks.afterModule) { + await hook(); + } + groupLogs() && console.groupEnd(); + moduleReport.end = instrument() && performance.mark(`module:${module.moduleName}:end`); + moduleReport.measure = + instrument() && performance.measure(`module:${module.moduleName}`, moduleReport.start.name, moduleReport.end.name); + DelegatingReporter.onModuleFinish(moduleReport); +} diff --git a/packages/diagnostic/src/legacy/equiv.ts b/packages/diagnostic/src/legacy/equiv.ts new file mode 100644 index 00000000000..c0aad6a076e --- /dev/null +++ b/packages/diagnostic/src/legacy/equiv.ts @@ -0,0 +1,344 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-call,@typescript-eslint/ban-types,@typescript-eslint/no-unsafe-member-access */ +/* + * The utils below are from QUnit to support deepEqual. + */ +export function objectType(obj: unknown) { + if (typeof obj === 'undefined') { + return 'undefined'; + } + + // Consider: typeof null === object + if (obj === null) { + return 'null'; + } + + const match = toString.call(obj).match(/^\[object\s(.*)\]$/); + const type = match && match[1]; + + switch (type) { + case 'Number': + if (isNaN(obj as number)) { + return 'nan'; + } + return 'number'; + case 'String': + case 'Boolean': + case 'Array': + case 'Set': + case 'Map': + case 'Date': + case 'RegExp': + case 'Function': + case 'Symbol': + return type.toLowerCase(); + default: + return typeof obj; + } +} + +type BetterObj = Record & object; +const BOXABLE_TYPES = new Set(['boolean', 'number', 'string']); + +// Memory for previously seen containers (object, array, map, set). +// Used for recursion detection, and to avoid repeated comparison. +// +// Elements are { a: val, b: val }. +let memory: { a: unknown; b: unknown }[] = []; + +function useStrictEquality(a: unknown, b: unknown) { + return a === b; +} + +function useObjectValueEquality(a: object, b: object) { + return a === b || a.valueOf() === b.valueOf(); +} + +type HasConstructor = { constructor?: unknown }; + +function compareConstructors(a: HasConstructor, b: HasConstructor) { + // Comparing constructors is more strict than using `instanceof` + return getConstructor(a) === getConstructor(b); +} + +function getConstructor(obj: HasConstructor) { + const proto = Object.getPrototypeOf(obj); + + // If the obj prototype descends from a null constructor, treat it + // as a null prototype. + // Ref https://github.com/qunitjs/qunit/issues/851 + // + // Allow objects with no prototype, from Object.create(null), to be equivalent to + // plain objects that have Object as their constructor. + return !proto || proto.constructor === null ? Object : obj.constructor; +} + +function getRegExpFlags(regexp: RegExp) { + // @ts-expect-error never narrowing is only true for modern browsers + return 'flags' in regexp ? regexp.flags : regexp.toString().match(/[gimuy]*$/)[0]; +} + +// Specialised comparisons after entryTypeCallbacks.object, based on `objectType()` +const objTypeCallbacks = { + undefined: useStrictEquality, + null: useStrictEquality, + // Handle boxed boolean + boolean: useObjectValueEquality, + number(a: number, b: number) { + // Handle NaN and boxed number + return a === b || a.valueOf() === b.valueOf() || (isNaN(a.valueOf()) && isNaN(b.valueOf())); + }, + // Handle boxed string + string: useObjectValueEquality, + symbol: useStrictEquality, + date: useObjectValueEquality, + + nan() { + return true; + }, + + regexp(a: RegExp, b: RegExp) { + return ( + a.source === b.source && + // Include flags in the comparison + getRegExpFlags(a) === getRegExpFlags(b) + ); + }, + + // identical reference only + function: useStrictEquality, + + array(a: unknown[], b: unknown[]) { + if (a.length !== b.length) { + // Safe and faster + return false; + } + + for (let i = 0; i < a.length; i++) { + if (!typeEquiv(a[i], b[i])) { + return false; + } + } + return true; + }, + + // Define sets a and b to be equivalent if for each element aVal in a, there + // is some element bVal in b such that aVal and bVal are equivalent. Element + // repetitions are not counted, so these are equivalent: + // a = new Set( [ X={}, Y=[], Y ] ); + // b = new Set( [ Y, X, X ] ); + set(a: Set, b: Set) { + if (a.size !== b.size) { + // This optimization has certain quirks because of the lack of + // repetition counting. For instance, adding the same + // (reference-identical) element to two equivalent sets can + // make them non-equivalent. + return false; + } + + let outerEq = true; + + a.forEach((aVal) => { + // Short-circuit if the result is already known. (Using for...of + // with a break clause would be cleaner here, but it would cause + // a syntax error on older JavaScript implementations even if + // Set is unused) + if (!outerEq) { + return; + } + + let innerEq = false; + + b.forEach((bVal) => { + // Likewise, short-circuit if the result is already known + if (innerEq) { + return; + } + + // Swap out the global memory, as nested typeEquiv() would clobber it + const originalMemory = memory; + memory = []; + if (typeEquiv(bVal, aVal)) { + innerEq = true; + } + // Restore + memory = originalMemory; + }); + + if (!innerEq) { + outerEq = false; + } + }); + + return outerEq; + }, + + // Define maps a and b to be equivalent if for each key-value pair (aKey, aVal) + // in a, there is some key-value pair (bKey, bVal) in b such that + // [ aKey, aVal ] and [ bKey, bVal ] are equivalent. Key repetitions are not + // counted, so these are equivalent: + // a = new Map( [ [ {}, 1 ], [ {}, 1 ], [ [], 1 ] ] ); + // b = new Map( [ [ {}, 1 ], [ [], 1 ], [ [], 1 ] ] ); + map(a: Map, b: Map) { + if (a.size !== b.size) { + // This optimization has certain quirks because of the lack of + // repetition counting. For instance, adding the same + // (reference-identical) key-value pair to two equivalent maps + // can make them non-equivalent. + return false; + } + + let outerEq = true; + + a.forEach((aVal, aKey) => { + // Short-circuit if the result is already known. (Using for...of + // with a break clause would be cleaner here, but it would cause + // a syntax error on older JavaScript implementations even if + // Map is unused) + if (!outerEq) { + return; + } + + let innerEq = false; + + b.forEach((bVal, bKey) => { + // Likewise, short-circuit if the result is already known + if (innerEq) { + return; + } + + // Swap out the global memory, as nested typeEquiv() would clobber it + const originalMemory = memory; + memory = []; + if (objTypeCallbacks.array([bVal, bKey], [aVal, aKey])) { + innerEq = true; + } + // Restore + memory = originalMemory; + }); + + if (!innerEq) { + outerEq = false; + } + }); + + return outerEq; + }, +}; + +// Entry points from typeEquiv, based on `typeof` +const entryTypeCallbacks = { + undefined: useStrictEquality, + null: useStrictEquality, + boolean: useStrictEquality, + number(a: number, b: number) { + // Handle NaN + return a === b || (isNaN(a) && isNaN(b)); + }, + string: useStrictEquality, + symbol: useStrictEquality, + + function: useStrictEquality, + object(a: BetterObj, b: BetterObj) { + // Handle memory (skip recursion) + if (memory.some((pair) => pair.a === a && pair.b === b)) { + return true; + } + memory.push({ a, b }); + + const aObjType = objectType(a); + const bObjType = objectType(b); + if (aObjType !== 'object' || bObjType !== 'object') { + // Handle literal `null` + // Handle: Array, Map/Set, Date, Regxp/Function, boxed primitives + // @ts-expect-error + return aObjType === bObjType && objTypeCallbacks[aObjType](a, b); + } + + // NOTE: Literal null must not make it here as it would throw + if (compareConstructors(a, b) === false) { + return false; + } + + const aProperties = []; + const bProperties = []; + + // Be strict and go deep, no filtering with hasOwnProperty. + for (const i in a) { + // Collect a's properties + aProperties.push(i); + + // Skip OOP methods that look the same + if ( + a.constructor !== Object && + typeof a.constructor !== 'undefined' && + typeof a[i] === 'function' && + typeof b[i] === 'function' && + (a[i] as Function).toString() === (b[i] as Function).toString() + ) { + continue; + } + if (!typeEquiv(a[i], b[i])) { + return false; + } + } + + for (const i in b) { + // Collect b's properties + bProperties.push(i); + } + + return objTypeCallbacks.array(aProperties.sort(), bProperties.sort()); + }, +}; + +function typeEquiv(a: unknown, b: unknown): boolean { + // Optimization: Only perform type-specific comparison when pairs are not strictly equal. + if (a === b) { + return true; + } + + const aType = typeof a; + const bType = typeof b; + if (aType !== bType) { + // Support comparing primitive to boxed primitives + // Try again after possibly unwrapping one + return ( + (aType === 'object' && BOXABLE_TYPES.has(objectType(a)) ? (a as string | number).valueOf() : a) === + (bType === 'object' && BOXABLE_TYPES.has(objectType(b)) ? (b as string | number).valueOf() : b) + ); + } + + // @ts-expect-error + return entryTypeCallbacks[aType](a, b); +} + +function innerEquiv(a: unknown, b: unknown): boolean { + const res = typeEquiv(a, b); + // Release any retained objects and reset recursion detection for next call + memory = []; + return res; +} + +/** + * Test any two types of JavaScript values for equality. + * + * @author Philippe Rathé + * @author David Chan + */ +export default function equiv(a: unknown, b: unknown): boolean { + if (arguments.length === 2) { + return a === b || innerEquiv(a, b); + } + + // Given 0 or 1 arguments, just return true (nothing to compare). + // Given (A,B,C,D) compare C,D then B,C then A,B. + let i = arguments.length - 1; + while (i > 0) { + if (!innerEquiv(arguments[i - 1], arguments[i])) { + return false; + } + i--; + } + + return true; +} diff --git a/packages/diagnostic/src/reporters/dom.ts b/packages/diagnostic/src/reporters/dom.ts new file mode 100644 index 00000000000..1214ee0513b --- /dev/null +++ b/packages/diagnostic/src/reporters/dom.ts @@ -0,0 +1,371 @@ +import type { CompatTestReport, Emitter } from '../-types'; +import type { DiagnosticReport, ModuleReport, Reporter, SuiteReport, TestReport } from '../-types/report'; +import { getSettings, updateConfigValue, updateSuiteState } from '../internals/config'; + +type SuiteLayout = { + report: HTMLElement; + current: HTMLElement; + resultsList: HTMLElement; + results: Map; + cleanup: (() => void)[]; +}; + +export class DOMReporter implements Reporter { + declare element: HTMLElement; + declare settings: ReturnType; + declare suite: SuiteLayout; + declare suiteReport: SuiteReport; + declare currentTests: Map; + declare nextTestId: number; + declare stats: { + diagnostics: number; + diagnosticsPassed: number; + modules: number; + modulesPassed: number; + }; + declare _pendingUpdate: number | null; + declare _socket: Emitter | null; + + constructor(element: HTMLElement, emitter?: Emitter | null) { + this.nextTestId = 1; + this.element = element; + this.settings = getSettings(); + this.stats = { + diagnostics: 0, + diagnosticsPassed: 0, + modules: 0, + modulesPassed: 0, + }; + this._pendingUpdate = null; + this.currentTests = new Map(); + this._socket = emitter || null; + } + + onSuiteStart(report: SuiteReport): void { + if (this.element.children.length) { + this.element.innerHTML = ''; + } + const fragment = document.createDocumentFragment(); + this.suite = renderSuite(fragment, report); + this.element.appendChild(fragment); + this.suiteReport = report; + this._socket?.emit('suite-start', report); + } + + onSuiteFinish(report: SuiteReport): void { + this._socket?.emit('suite-finish', report); + } + + onTestStart(test: TestReport): void { + this.scheduleUpdate(); + if (this._socket) { + const compatTestReport = { + id: this.nextTestId++, + name: test.module.name + ':' + test.name, + items: [], + failed: 0, + passed: 0, + skipped: test.skipped, + todo: test.todo, + total: 0, + runDuration: 0, + testId: test.id, + }; + this.currentTests.set(test.id, compatTestReport); + this._socket.emit('test-start', compatTestReport); + } + } + + onTestFinish(test: TestReport): void { + this.stats.diagnostics += test.result.diagnostics.length; + this.stats.diagnosticsPassed += test.result.diagnostics.filter((d) => d.passed).length; + + if (this._socket) { + const compatTestReport = this.currentTests.get(test.id)!; + console.log(compatTestReport.id, test.name); + this.currentTests.delete(test.id); + compatTestReport.failed += test.result.failed ? 1 : 0; + compatTestReport.passed += test.result.passed ? 1 : 0; + compatTestReport.skipped = test.skipped; + compatTestReport.todo = test.todo; + compatTestReport.total = test.result.diagnostics.length; + compatTestReport.runDuration = test.end!.startTime - test.start!.startTime; + compatTestReport.items = test.result.diagnostics.map((d) => { + // more expensive to serialize the whole diagnostic + if (this.settings.params.debug.value) { + return d; + } + return { + passed: d.passed, + message: d.message, + }; + }); + + if (compatTestReport.failed > 0 || test.result.failed) { + this.settings.params.debug.value && console.log(test, compatTestReport); + } + + this._socket.emit('test-finish', compatTestReport); + } else if (test.result.failed) { + this.settings.params.debug.value && console.log(test); + } + + if (this.settings.params.hideReport.value) { + return; + } + // @ts-expect-error + test.moduleName = test.module.name; + this.suite.results.set(test, null); + this.scheduleUpdate(); + } + + onModuleStart(module: ModuleReport): void {} + + onModuleFinish(module: ModuleReport): void { + this.stats.modules++; + this.stats.modulesPassed += module.passed ? 1 : 0; + this.scheduleUpdate(); + } + + onDiagnostic(_diagnostic: DiagnosticReport): void { + this.scheduleUpdate(); + } + + scheduleUpdate() { + if (this._pendingUpdate) { + return; + } + this._pendingUpdate = requestAnimationFrame(() => { + this._pendingUpdate = null; + this._updateRender(); + }); + } + + _updateRender() { + // render infos + // render any tests + let i = 0; + const fragment = document.createDocumentFragment(); + this.suite.results.forEach((element, test) => { + i++; + if (element) { + return; + } + const tr = document.createElement('tr'); + fragment.appendChild(tr); + tr.classList.add(classForTestStatus(test)); + makeRow(tr, [ + i + '.', + `${iconForTestStatus(test)} ${labelForTestStatus(test)}`, + durationForTest(test), + `${test.module.name} > `, + `${test.name} (${test.result.diagnostics.length})`, + getURL(test.id), + ]); + this.suite.results.set(test, tr); + }); + this.suite.resultsList.appendChild(fragment); + } +} + +function makeRow(tr: HTMLTableRowElement, cells: string[]) { + for (let i = 0; i < cells.length; i++) { + const cell = cells[i]; + const td = document.createElement('td'); + if (i === 3) { + const strong = document.createElement('strong'); + const text = document.createTextNode(cell); + strong.appendChild(text); + td.appendChild(strong); + i++; + const text2 = document.createTextNode(cells[i]); + td.appendChild(text2); + } else if (i === 5) { + const a = document.createElement('a'); + a.href = cell; + a.appendChild(document.createTextNode('rerun')); + td.appendChild(a); + } else { + const text = document.createTextNode(cell); + td.appendChild(text); + } + tr.appendChild(td); + } +} + +function getURL(id: string) { + const currentURL = new URL(window.location.href); + currentURL.searchParams.set('test', id); + return currentURL.href; +} + +function durationForTest(test: TestReport) { + if (!test.start || !test.end) { + return 'N/A'; + } + return `${(test.end.startTime - test.start.startTime).toLocaleString('en-US')}ms`; +} + +function labelForTestStatus(test: TestReport) { + if (test.skipped) { + return 'Skip'; + } + if (test.todo && test.result.passed) { + return 'Todo'; + } + if (test.result.passed) { + return 'Pass'; + } + return 'Fail'; +} + +function iconForTestStatus(test: TestReport) { + if (test.skipped) { + return '⚠️'; + } + if (test.todo && test.result.passed) { + return '🛠️'; + } + if (test.result.passed) { + return '✅' + ''; + } + return '💥'; +} + +function classForTestStatus(test: TestReport) { + if (test.skipped) { + return 'skipped'; + } + if (test.todo && test.result.passed) { + return 'todo'; + } + if (test.result.passed) { + return 'passed'; + } + return 'failed'; +} + +function renderSuite(element: DocumentFragment, suiteReport: SuiteReport): SuiteLayout { + const cleanup: (() => void)[] = []; + + // ==== Create the Header Section + const header = document.createElement('header'); + header.id = 'warp-drive__diagnostic-header'; + element.appendChild(header); + + const title = document.createElement('h1'); + title.innerHTML = `@warp-drive/diagnostic`; + header.appendChild(title); + + const paramsList = document.createElement('ul'); + header.appendChild(paramsList); + + const params = getSettings().params; + type Params = keyof typeof params; + const keys = Object.keys(params) as Params[]; + keys.forEach((key) => { + const value = params[key]; + const param = document.createElement('li'); + paramsList.appendChild(param); + const label = document.createElement('label'); + param.appendChild(label); + + const input = document.createElement('input'); + input.id = value.id; + input.name = value.id; + input.type = 'checkbox'; + input.checked = value.value; + + function update() { + value.value = input.checked; + updateConfigValue(key, value.value); + } + + input.addEventListener('change', update); + cleanup.push(() => input.removeEventListener('change', update)); + + label.appendChild(input); + label.appendChild(document.createTextNode(` ${value.label || value.id}`)); + }); + + // ==== Create the Controls Section + const controls = document.createElement('div'); + controls.id = 'warp-drive__diagnostic-controls'; + element.appendChild(controls); + + function runPrev() { + updateSuiteState(2); + } + function runNext() { + updateSuiteState(3); + } + function runRestart() { + updateSuiteState(4); + } + + const prevButton = el('button', 'prev'); + prevButton.innerText = 'Prev ⏪️'; + prevButton.addEventListener('click', runPrev); + cleanup.push(() => prevButton.removeEventListener('click', runPrev)); + controls.appendChild(prevButton); + + const nextButton = el('button', 'next'); + nextButton.innerText = 'Next ⏩️'; + nextButton.addEventListener('click', runNext); + cleanup.push(() => nextButton.removeEventListener('click', runNext)); + controls.appendChild(nextButton); + + let isRunning = false; + const runButton = el('button', 'pauseResume'); + runButton.innerText = 'Run ▶️'; + + function updateRunState() { + isRunning = !isRunning; + updateSuiteState(isRunning ? 1 : 0); + if (isRunning) { + runButton.innerText = 'Pause ⏸️'; + } else { + runButton.innerText = 'Run ▶️'; + } + } + runButton.addEventListener('click', updateRunState); + cleanup.push(() => runButton.removeEventListener('click', updateRunState)); + controls.appendChild(runButton); + + const restartButton = el('button', 'restart'); + restartButton.innerText = 'Restart 🔄'; + restartButton.addEventListener('click', runRestart); + cleanup.push(() => restartButton.removeEventListener('click', runRestart)); + controls.appendChild(restartButton); + + // ==== Create the Report Section + const report = document.createElement('div'); + report.id = 'warp-drive__diagnostic-report'; + element.appendChild(report); + + const current = document.createElement('div'); + current.classList.add('current-diagnostic'); + element.appendChild(current); + + const resultsTable = document.createElement('table'); + element.appendChild(resultsTable); + + const resultsList = document.createElement('tbody'); + resultsList.classList.add('diagnostic-results'); + resultsTable.appendChild(resultsList); + + const results = new Map(); + + return { cleanup, report, current, resultsList, results }; +} + +function el(tag: 'button', name: string): HTMLButtonElement; +function el(tag: 'div', name: string): HTMLDivElement; +function el(tag: 'div' | 'button', name: string) { + const element = document.createElement(tag); + element.id = `warp-drive__diagnostic-${name}`; + if (tag === 'button') { + (element as HTMLButtonElement).type = 'button'; + } + return element; +} diff --git a/packages/diagnostic/src/runners/dom.ts b/packages/diagnostic/src/runners/dom.ts new file mode 100644 index 00000000000..810fb6bd3a5 --- /dev/null +++ b/packages/diagnostic/src/runners/dom.ts @@ -0,0 +1,36 @@ +import { registerReporter, start as _start } from '../'; +import type { Emitter } from '../-types'; +import { assert, getGlobal } from '../-utils'; +import type { ConfigOptions } from '../internals/config'; +import { configure, getSettings } from '../internals/config'; +import { DOMReporter } from '../reporters/dom'; + +export async function start(config?: ConfigOptions) { + if (config) { + configure(config); + } + + const context = getGlobal(); + const body = context.document?.body; + + assert(`Expected to be in a browser environment`, typeof body !== 'undefined'); + + const container = context.document.getElementById('warp-drive__diagnostic'); + assert( + `Expected to find a diagnostic container element. Make sure your html file has added
`, + container !== null + ); + const settings = getSettings(); + + let emitter: Emitter | null = null; + if (settings.useTestem) { + const { createTestemEmitter } = await import('../emitters/testem'); + emitter = await createTestemEmitter(); + } else if (settings.useDiagnostic) { + const { createDiagnosticEmitter } = await import('../emitters/diagnostic'); + emitter = await createDiagnosticEmitter(); + } + registerReporter(new DOMReporter(container, emitter)); + + await _start(); +} diff --git a/packages/diagnostic/src/styles/dom-reporter.css b/packages/diagnostic/src/styles/dom-reporter.css new file mode 100644 index 00000000000..ef4c581fd57 --- /dev/null +++ b/packages/diagnostic/src/styles/dom-reporter.css @@ -0,0 +1,188 @@ +:root { + /* + --heading-color: #17abab; + --heading-2-color: #e617ab; + */ + --brand-pink: hsl(317, 82%, 50%); + --brand-green: hsl(180, 76%, 50%); + --brand-blue: 212, 92%; + --brand-yellow: #deb008; + --brand-main: var(--brand-green); + --brand-secondary: var(--brand-pink); + --primary-color: 212, 92%; + --secondary-color: #536390; + --heading-3-color: #deb008; + --heading-4-color: #0868de; + --heading-2-color: #999; + --font-color: #fff; + --bg-color: #191919; + --bg-color-2: #222222; + --bg-color-3: #292929; + --heading-color: #292922; +} + +html { + font-size: 125%; +} + +html, +body { + width: 100%; + height: 100%; + margin: 0; + padding: 0; + position: relative; +} + +body { + font-size: 0.75rem; +} + +#warp-drive__diagnostic { + box-sizing: border-box; + color: var(--font-color); + font-family: + system-ui, + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + Oxygen, + Ubuntu, + Cantarell, + "Open Sans", + "Helvetica Neue", + sans-serif; + width: 100%; + position: relative; + min-height: 100%; + line-height: 1.5em; + background-color: var(--bg-color); + background-size: 1.5em 1.5em; + background-image: linear-gradient(to right, var(--bg-color-2) 0.1em, transparent 1px), + linear-gradient(to bottom, var(--bg-color-2) 0.1em, transparent 1px); +} + +#warp-drive__diagnostic * { + box-sizing: border-box; +} + +#warp-drive__diagnostic h2 { + font-size: 1.25em; + font-weight: normal; + color: var(--heading-2-color); + margin: 0; + padding: 0; + line-height: 1.25rem; + margin: 0.25rem 0 1rem; +} + +#warp-drive__diagnostic h1 { + font-size: 1.5em; + font-weight: normal; + color: var(--heading-color); + margin: 0; + padding: 0; + line-height: 3rem; + float: left; + display: block; +} + +#warp-drive__diagnostic-header { + min-width: 800px; +} + +#warp-drive__diagnostic-header ul { + list-style: none; + margin: 0; + padding: 0; + position: relative; + float: right; + top: 0; + width: calc(100% - 250px); +} + +#warp-drive__diagnostic-header ul li { + font-size: 0.85em; + float: right; + margin: 0.25em 0.5em; +} + +#warp-drive__diagnostic-header { + height: 4.5rem; + padding: 0.5rem; + background: var(--bg-color-3); + box-shadow: 0 0 1rem rgba(0, 0, 0, 0.5); + border-bottom: 0.1rem solid hsl(var(--brand-blue), 50%); +} + +#warp-drive__diagnostic h1 span.logo-main { + color: var(--brand-main); + font-weight: 500; +} + +#warp-drive__diagnostic h1 span.logo-pink { + color: var(--brand-secondary); + font-weight: 300; +} + +#warp-drive__diagnostic .text-blue { + color: var(--primary-color); +} + +#warp-drive__diagnostic table { + border-collapse: separate; + border-spacing: 0 0.1rem; + width: 100%; + padding: 1rem; +} + +#warp-drive__diagnostic table tr { + color: lightgrey; + font-size: 0.85em; + line-height: 1rem; + text-align: left; + vertical-align: middle; + height: 1.2rem; + padding: 0.1rem; +} + +#warp-drive__diagnostic table tr td strong { + color: gray; +} + +#warp-drive__diagnostic table tr td a { + color: lightblue; +} + +#warp-drive__diagnostic table tr td:first-of-type { + border-radius: 0.1rem 0 0 0.1rem; + padding-left: 0.5rem; +} +#warp-drive__diagnostic table tr td:last-of-type { + padding-right: 0.5rem; + border-radius: 0 0.1rem 0.1rem 0; +} +#warp-drive__diagnostic table tr:nth-last-of-type(even) { + background: rgba(0, 0, 0, 0.8); +} +#warp-drive__diagnostic table tr:nth-last-of-type(odd) { + background: rgba(0, 0, 0, 0.8); +} +#warp-drive__diagnostic table tr.passed td:nth-child(2) { + color: green; +} +#warp-drive__diagnostic table tr.skipped td:nth-child(2) { + color: yellow; +} +#warp-drive__diagnostic table tr.todo td:nth-child(2) { + color: cyan; +} +#warp-drive__diagnostic table tr.failed td:nth-child(2) { + color: red; +} +#warp-drive__diagnostic table td:nth-child(3) { + color: yellow; + font-size: 0.75em; + line-height: 0.75rem; +} diff --git a/packages/diagnostic/test/diagnostic.js b/packages/diagnostic/test/diagnostic.js new file mode 100644 index 00000000000..186b0f50765 --- /dev/null +++ b/packages/diagnostic/test/diagnostic.js @@ -0,0 +1,3 @@ +import launch from '../server/default-setup'; + +await launch(); diff --git a/packages/diagnostic/test/example-tests.js b/packages/diagnostic/test/example-tests.js new file mode 100644 index 00000000000..8a89e3e5f9c --- /dev/null +++ b/packages/diagnostic/test/example-tests.js @@ -0,0 +1,21 @@ +import { module, test } from './@warp-drive/diagnostic/index.js'; +import { start } from './@warp-drive/diagnostic/runners/dom.js'; + +module('example-tests', function () { + test('An example test', function (assert) { + assert.ok(true, 'We ran a test'); + }); + + test('Another example test 2', function (assert) { + assert.ok(false, 'We ran another test 2'); + assert.ok(true, 'We passed!'); + }); + + test('Another example test 3', function (assert) { + assert.ok(true, 'We ran another test 3'); + }); +}); + +start({ + useDiagnostic: true, +}); diff --git a/packages/diagnostic/test/index.html b/packages/diagnostic/test/index.html new file mode 100644 index 00000000000..c908ac9a3f5 --- /dev/null +++ b/packages/diagnostic/test/index.html @@ -0,0 +1,12 @@ + + + + Diagnostic Test + + + +
+
+ + + diff --git a/packages/diagnostic/tsconfig.json b/packages/diagnostic/tsconfig.json new file mode 100644 index 00000000000..c14300ab125 --- /dev/null +++ b/packages/diagnostic/tsconfig.json @@ -0,0 +1,30 @@ +{ + "include": ["src/**/*"], + "compilerOptions": { + "lib": ["DOM", "ESNext"], + "module": "esnext", + "target": "esnext", + "moduleResolution": "bundler", + "moduleDetection": "force", + "declarationDir": "dist", + "strict": true, + "downlevelIteration": true, + "skipLibCheck": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "allowJs": true, + "noEmit": false, + "emitDeclarationOnly": true, + + // Enable faster builds + // but causes us to not rebuild properly + "composite": true, + "incremental": true, + "rootDir": "src", + + "declaration": true, + "declarationMap": true, + "inlineSourceMap": true, + "inlineSources": true + } +} diff --git a/packages/model/src/-private/hooks.ts b/packages/model/src/-private/hooks.ts new file mode 100644 index 00000000000..315c7cd6c8f --- /dev/null +++ b/packages/model/src/-private/hooks.ts @@ -0,0 +1,27 @@ +import { StableRecordIdentifier } from '@ember-data/types/q/identifier'; + +import Model from './model'; + +// FIXME: Implement or remove invocations +export function buildSchema() { + throw new Error('unimplemented'); +} + +// FIXME: Implement or remove invocations +export function modelFor(this: unknown, modelName: string): typeof Model | void { + throw new Error('unimplemented'); +} + +// FIXME: Implement or remove invocations +export function instantiateRecord( + this: unknown, + identifier: StableRecordIdentifier, + createRecordArgs: { [key: string]: unknown } +): Model { + throw new Error('unimplemented'); +} + +// FIXME: Implement or remove invocations +export function teardownRecord(record: Model) { + throw new Error('unimplemented'); +} diff --git a/packages/model/src/-private/schema-provider.ts b/packages/model/src/-private/schema-provider.ts new file mode 100644 index 00000000000..265461aaf0e --- /dev/null +++ b/packages/model/src/-private/schema-provider.ts @@ -0,0 +1,6 @@ +import { SchemaService } from '@ember-data/types/q/schema-service'; + +// FIXME: Implement or remove invocations +export function buildSchema(store: unknown): SchemaService { + throw new Error('unimplemented'); +} diff --git a/packages/model/src/hooks.ts b/packages/model/src/hooks.ts new file mode 100644 index 00000000000..1c7335ed6b2 --- /dev/null +++ b/packages/model/src/hooks.ts @@ -0,0 +1,2 @@ +export { instantiateRecord, teardownRecord, modelFor } from './-private/hooks'; +export { buildSchema } from './-private/schema-provider'; diff --git a/packages/model/src/index.ts b/packages/model/src/index.ts index c06af98de24..216f4b6093b 100644 --- a/packages/model/src/index.ts +++ b/packages/model/src/index.ts @@ -38,3 +38,5 @@ @main @ember-data/model */ export { Model as default, attr, belongsTo, hasMany } from './-private'; + +export { instantiateRecord, teardownRecord, modelFor } from './-private/hooks'; diff --git a/packages/request-utils/LICENSE.md b/packages/request-utils/LICENSE.md new file mode 100644 index 00000000000..97a483b5d8f --- /dev/null +++ b/packages/request-utils/LICENSE.md @@ -0,0 +1,11 @@ +The MIT License (MIT) + +Copyright (C) 2017-2023 Ember.js contributors +Portions Copyright (C) 2011-2017 Tilde, Inc. and contributors. +Portions Copyright (C) 2011 LivingSocial Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/request-utils/README.md b/packages/request-utils/README.md new file mode 100644 index 00000000000..8437c6260b1 --- /dev/null +++ b/packages/request-utils/README.md @@ -0,0 +1,66 @@ +

+ + +

+ +

Utilities for Requests

+ +This package provides Simple utility function to assist in url building, query params, and other common request operations. + +It's built for [*Ember***Data**](https://github.com/emberjs/data/) but useful more broadly if you're looking for lightweight functions to assist in working with urls and query params. + +## Installation + +Install using your javascript package manager of choice. For instance with [pnpm](https://pnpm.io/) + +```no-highlight +pnpm add @ember-data/request-utils +``` +## Utils + +- [buildBaseUrl]() +- [sortQueryParams]() +- [buildQueryParams]() +- [filterEmpty]() + +### As a Library Primitive + +These primitives may be used directly or composed by request builders to provide a consistent interface for building requests. + +For instance: + +```ts +import { buildBaseURL, buildQueryParams } from '@ember-data/request-utils'; + +const baseURL = buildBaseURL({ + host: 'https://api.example.com', + namespace: 'api/v1', + resourcePath: 'emberDevelopers', + op: 'query', + identifier: { type: 'ember-developer' } +}); +const url = `${baseURL}?${buildQueryParams({ name: 'Chris', include:['pets'] })}`; +// => 'https://api.example.com/api/v1/emberDevelopers?include=pets&name=Chris' +``` + +This is useful, but not as useful as the REST request builder for query which is sugar over this (and more!): + +```ts +import { query } from '@ember-data/rest/request'; + +const options = query('ember-developer', { name: 'Chris', include:['pets'] }); +// => { url: 'https://api.example.com/api/v1/emberDevelopers?include=pets&name=Chris' } +// Note: options will also include other request options like headers, method, etc. +``` diff --git a/packages/request-utils/addon-main.js b/packages/request-utils/addon-main.js new file mode 100644 index 00000000000..459ef9174ca --- /dev/null +++ b/packages/request-utils/addon-main.js @@ -0,0 +1,19 @@ +module.exports = { + name: require('./package.json').name, + + treeForVendor() { + return; + }, + treeForPublic() { + return; + }, + treeForStyles() { + return; + }, + treeForAddonStyles() { + return; + }, + treeForApp() { + return; + }, +}; diff --git a/packages/request-utils/babel.config.json b/packages/request-utils/babel.config.json new file mode 100644 index 00000000000..0e04314a08c --- /dev/null +++ b/packages/request-utils/babel.config.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + "@babel/plugin-transform-runtime", + ["@babel/plugin-transform-typescript", { "allowDeclareFields": true }], + ["@babel/plugin-proposal-decorators", { "legacy": true }], + "@babel/plugin-transform-class-properties" + ] +} diff --git a/packages/request-utils/ember-data-logo-dark.svg b/packages/request-utils/ember-data-logo-dark.svg new file mode 100644 index 00000000000..737a4aa4321 --- /dev/null +++ b/packages/request-utils/ember-data-logo-dark.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/packages/request-utils/ember-data-logo-light.svg b/packages/request-utils/ember-data-logo-light.svg new file mode 100644 index 00000000000..58ac3d4e544 --- /dev/null +++ b/packages/request-utils/ember-data-logo-light.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/packages/request-utils/package.json b/packages/request-utils/package.json new file mode 100644 index 00000000000..e57c3432569 --- /dev/null +++ b/packages/request-utils/package.json @@ -0,0 +1,78 @@ +{ + "name": "@ember-data/request-utils", + "description": "Request Building Utilities for use with EmberData", + "version": "4.12.5", + "private": false, + "license": "MIT", + "author": "Chris Thoburn ", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com:emberjs/data.git", + "directory": "packages/request-utils" + }, + "homepage": "https://github.com/emberjs/data", + "bugs": "https://github.com/emberjs/data/issues", + "engines": { + "node": "16.* || >= 18.*" + }, + "keywords": [ + "ember-addon" + ], + "volta": { + "extends": "../../package.json" + }, + "dependencies": { + "ember-cli-babel": "^8.2.0", + "pnpm-sync-dependencies-meta-injected": "0.0.10" + }, + "files": [ + "unstable-preview-types", + "addon-main.js", + "addon", + "README.md", + "LICENSE.md", + "ember-data-logo-dark.svg", + "ember-data-logo-light.svg" + ], + "exports": { + ".": { + "types": "./unstable-preview-types/index.d.ts", + "default": "./addon/index.js" + } + }, + "scripts": { + "build:types": "tsc --build", + "build:client": "rollup --config && babel ./addon --out-dir addon --plugins=../private-build-infra/src/transforms/babel-plugin-transform-ext.js", + "_build": "bun run build:client && bun run build:types", + "prepack": "pnpm build", + "_syncPnpm": "bun run sync-dependencies-meta-injected" + }, + "ember-addon": { + "main": "addon-main.js", + "type": "addon", + "version": 1 + }, + "devDependencies": { + "@babel/cli": "^7.23.4", + "@babel/core": "^7.23.3", + "@babel/plugin-proposal-decorators": "^7.23.3", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-runtime": "^7.23.4", + "@babel/plugin-transform-typescript": "^7.23.4", + "@babel/preset-env": "^7.23.3", + "@babel/preset-typescript": "^7.23.3", + "@babel/runtime": "^7.23.4", + "@embroider/addon-dev": "^4.1.2", + "@glimmer/component": "^1.1.2", + "@rollup/plugin-babel": "^6.0.4", + "@rollup/plugin-node-resolve": "^15.2.3", + "@warp-drive/internal-config": "workspace:4.12.5", + "ember-source": "~5.4.0", + "rollup": "^4.5.0", + "typescript": "^5.3.2", + "walk-sync": "^3.0.0" + }, + "ember": { + "edition": "octane" + } +} diff --git a/packages/request-utils/rollup.config.mjs b/packages/request-utils/rollup.config.mjs new file mode 100644 index 00000000000..ac33c58f32b --- /dev/null +++ b/packages/request-utils/rollup.config.mjs @@ -0,0 +1,33 @@ +import { Addon } from '@embroider/addon-dev/rollup'; +import babel from '@rollup/plugin-babel'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; + +import { external } from '@warp-drive/internal-config/rollup/external.js'; + +const addon = new Addon({ + srcDir: 'src', + destDir: 'addon', +}); + +export default { + // This provides defaults that work well alongside `publicEntrypoints` below. + // You can augment this if you need to. + output: addon.output(), + + external: external(['@ember/debug']), + + plugins: [ + // These are the modules that users should be able to import from your + // addon. Anything not listed here may get optimized away. + addon.publicEntrypoints(['index.js', '-private.js']), + + nodeResolve({ extensions: ['.ts'] }), + babel({ + extensions: ['.ts'], + babelHelpers: 'runtime', // we should consider "external", + }), + + // Remove leftover build artifacts when starting a new build. + addon.clean(), + ], +}; diff --git a/packages/request-utils/src/.gitkeep b/packages/request-utils/src/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/request-utils/src/index.ts b/packages/request-utils/src/index.ts new file mode 100644 index 00000000000..dc64c421d1a --- /dev/null +++ b/packages/request-utils/src/index.ts @@ -0,0 +1,633 @@ +import { assert } from '@ember/debug'; + +import type { StableDocumentIdentifier } from '@ember-data/types/cache/identifier'; +import type { Cache } from '@ember-data/types/q/cache'; +import type { QueryParamsSerializationOptions, QueryParamsSource, Serializable } from '@ember-data/types/q/params'; + +type Store = { + cache: Cache; +}; + +/** + * Simple utility function to assist in url building, + * query params, and other common request operations. + * + * These primitives may be used directly or composed + * by request builders to provide a consistent interface + * for building requests. + * + * For instance: + * + * ```ts + * import { buildBaseURL, buildQueryParams } from '@ember-data/request-utils'; + * + * const baseURL = buildBaseURL({ + * host: 'https://api.example.com', + * namespace: 'api/v1', + * resourcePath: 'emberDevelopers', + * op: 'query', + * identifier: { type: 'ember-developer' } + * }); + * const url = `${baseURL}?${buildQueryParams({ name: 'Chris', include:['pets'] })}`; + * // => 'https://api.example.com/api/v1/emberDevelopers?include=pets&name=Chris' + * ``` + * + * This is useful, but not as useful as the REST request builder for query which is sugar + * over this (and more!): + * + * ```ts + * import { query } from '@ember-data/rest/request'; + * + * const options = query('ember-developer', { name: 'Chris', include:['pets'] }); + * // => { url: 'https://api.example.com/api/v1/emberDevelopers?include=pets&name=Chris' } + * // Note: options will also include other request options like headers, method, etc. + * ``` + * + * @module @ember-data/request-utils + * @main @ember-data/request-utils + * @public + */ + +// prevents the final constructed object from needing to add +// host and namespace which are provided by the final consuming +// class to the prototype which can result in overwrite errors + +export interface BuildURLConfig { + host: string | null; + namespace: string | null; +} + +let CONFIG: BuildURLConfig = { + host: '', + namespace: '', +}; + +/** + * Sets the global configuration for `buildBaseURL` + * for host and namespace values for the application. + * + * These values may still be overridden by passing + * them to buildBaseURL directly. + * + * This method may be called as many times as needed + * + * ```ts + * type BuildURLConfig = { + * host: string; + * namespace: string' + * } + * ``` + * + * @method setBuildURLConfig + * @static + * @public + * @for @ember-data/request-utils + * @param {BuildURLConfig} config + * @return void + */ +export function setBuildURLConfig(config: BuildURLConfig) { + CONFIG = config; +} + +export interface FindRecordUrlOptions { + op: 'findRecord'; + identifier: { type: string; id: string }; + resourcePath?: string; + host?: string; + namespace?: string; +} + +export interface QueryUrlOptions { + op: 'query'; + identifier: { type: string }; + resourcePath?: string; + host?: string; + namespace?: string; +} + +export interface FindManyUrlOptions { + op: 'findMany'; + identifiers: { type: string; id: string }[]; + resourcePath?: string; + host?: string; + namespace?: string; +} +export interface FindRelatedCollectionUrlOptions { + op: 'findRelatedCollection'; + identifier: { type: string; id: string }; + fieldPath: string; + resourcePath?: string; + host?: string; + namespace?: string; +} + +export interface FindRelatedResourceUrlOptions { + op: 'findRelatedRecord'; + identifier: { type: string; id: string }; + fieldPath: string; + resourcePath?: string; + host?: string; + namespace?: string; +} + +export interface CreateRecordUrlOptions { + op: 'createRecord'; + identifier: { type: string }; + resourcePath?: string; + host?: string; + namespace?: string; +} + +export interface UpdateRecordUrlOptions { + op: 'updateRecord'; + identifier: { type: string; id: string }; + resourcePath?: string; + host?: string; + namespace?: string; +} + +export interface DeleteRecordUrlOptions { + op: 'deleteRecord'; + identifier: { type: string; id: string }; + resourcePath?: string; + host?: string; + namespace?: string; +} + +export type UrlOptions = + | FindRecordUrlOptions + | QueryUrlOptions + | FindManyUrlOptions + | FindRelatedCollectionUrlOptions + | FindRelatedResourceUrlOptions + | CreateRecordUrlOptions + | UpdateRecordUrlOptions + | DeleteRecordUrlOptions; + +const OPERATIONS_WITH_PRIMARY_RECORDS = new Set([ + 'findRecord', + 'findRelatedRecord', + 'findRelatedCollection', + 'updateRecord', + 'deleteRecord', +]); + +function isOperationWithPrimaryRecord( + options: UrlOptions +): options is + | FindRecordUrlOptions + | FindRelatedCollectionUrlOptions + | FindRelatedResourceUrlOptions + | UpdateRecordUrlOptions + | DeleteRecordUrlOptions { + return OPERATIONS_WITH_PRIMARY_RECORDS.has(options.op); +} + +function resourcePathForType(options: UrlOptions): string { + return options.op === 'findMany' ? options.identifiers[0].type : options.identifier.type; +} + +/** + * Builds a URL for a request based on the provided options. + * Does not include support for building query params (see `buildQueryParams`) + * so that it may be composed cleanly with other query-params strategies. + * + * Usage: + * + * ```ts + * import { buildBaseURL } from '@ember-data/request-utils'; + * + * const url = buildBaseURL({ + * host: 'https://api.example.com', + * namespace: 'api/v1', + * resourcePath: 'emberDevelopers', + * op: 'query', + * identifier: { type: 'ember-developer' } + * }); + * + * // => 'https://api.example.com/api/v1/emberDevelopers' + * ``` + * + * On the surface this may seem like a lot of work to do something simple, but + * it is designed to be composable with other utilities and interfaces that the + * average product engineer will never need to see or use. + * + * A few notes: + * + * - `resourcePath` is optional, but if it is not provided, `identifier.type` will be used. + * - `host` and `namespace` are optional, but if they are not provided, the values globally + * configured via `setBuildURLConfig` will be used. + * - `op` is required and must be one of the following: + * - 'findRecord' 'query' 'findMany' 'findRelatedCollection' 'findRelatedRecord'` 'createRecord' 'updateRecord' 'deleteRecord' + * - Depending on the value of `op`, `identifier` or `identifiers` will be required. + * + * @method buildBaseURL + * @static + * @public + * @for @ember-data/request-utils + * @param urlOptions + * @return string + */ +export function buildBaseURL(urlOptions: UrlOptions): string { + const options = Object.assign( + { + host: CONFIG.host, + namespace: CONFIG.namespace, + }, + urlOptions + ); + assert( + `buildBaseURL: You must pass \`op\` as part of options`, + typeof options.op === 'string' && options.op.length > 0 + ); + assert( + `buildBaseURL: You must pass \`identifier\` as part of options`, + options.op === 'findMany' || (options.identifier && typeof options.identifier === 'object') + ); + assert( + `buildBaseURL: You must pass \`identifiers\` as part of options`, + options.op !== 'findMany' || + (options.identifiers && + Array.isArray(options.identifiers) && + options.identifiers.length > 0 && + options.identifiers.every((i) => i && typeof i === 'object')) + ); + assert( + `buildBaseURL: You must pass valid \`identifier\` as part of options, expected 'id'`, + !isOperationWithPrimaryRecord(options) || + (typeof options.identifier.id === 'string' && options.identifier.id.length > 0) + ); + assert( + `buildBaseURL: You must pass \`identifiers\` as part of options`, + options.op !== 'findMany' || options.identifiers.every((i) => typeof i.id === 'string' && i.id.length > 0) + ); + assert( + `buildBaseURL: You must pass valid \`identifier\` as part of options, expected 'type'`, + options.op === 'findMany' || (typeof options.identifier.type === 'string' && options.identifier.type.length > 0) + ); + assert( + `buildBaseURL: You must pass valid \`identifiers\` as part of options, expected 'type'`, + options.op !== 'findMany' || + (typeof options.identifiers[0].type === 'string' && options.identifiers[0].type.length > 0) + ); + + // prettier-ignore + const idPath: string = + isOperationWithPrimaryRecord(options) ? encodeURIComponent(options.identifier.id) + : ''; + const resourcePath = options.resourcePath || resourcePathForType(options); + const { host, namespace } = options; + const fieldPath = 'fieldPath' in options ? options.fieldPath : ''; + + assert( + `buildBaseURL: You tried to build a ${String( + (options as { op: string }).op + )} request to ${resourcePath} but op must be one of "${[ + 'findRecord', + 'findRelatedRecord', + 'findRelatedCollection', + 'updateRecord', + 'deleteRecord', + 'createRecord', + 'query', + 'findMany', + ].join('","')}".`, + [ + 'findRecord', + 'query', + 'findMany', + 'findRelatedCollection', + 'findRelatedRecord', + 'createRecord', + 'updateRecord', + 'deleteRecord', + ].includes(options.op) + ); + + assert(`buildBaseURL: host must NOT end with '/', received '${host}'`, host === '/' || !host.endsWith('/')); + assert(`buildBaseURL: namespace must NOT start with '/', received '${namespace}'`, !namespace.startsWith('/')); + assert(`buildBaseURL: namespace must NOT end with '/', received '${namespace}'`, !namespace.endsWith('/')); + assert( + `buildBaseURL: resourcePath must NOT start with '/', received '${resourcePath}'`, + !resourcePath.startsWith('/') + ); + assert(`buildBaseURL: resourcePath must NOT end with '/', received '${resourcePath}'`, !resourcePath.endsWith('/')); + assert(`buildBaseURL: fieldPath must NOT start with '/', received '${fieldPath}'`, !fieldPath.startsWith('/')); + assert(`buildBaseURL: fieldPath must NOT end with '/', received '${fieldPath}'`, !fieldPath.endsWith('/')); + assert(`buildBaseURL: idPath must NOT start with '/', received '${idPath}'`, !idPath.startsWith('/')); + assert(`buildBaseURL: idPath must NOT end with '/', received '${idPath}'`, !idPath.endsWith('/')); + + const url = [host === '/' ? '' : host, namespace, resourcePath, idPath, fieldPath].filter(Boolean).join('/'); + return host ? url : `/${url}`; +} + +const DEFAULT_QUERY_PARAMS_SERIALIZATION_OPTIONS: QueryParamsSerializationOptions = { + arrayFormat: 'comma', +}; + +function handleInclude(include: string | string[]): string[] { + assert( + `Expected include to be a string or array, got ${typeof include}`, + typeof include === 'string' || Array.isArray(include) + ); + return typeof include === 'string' ? include.split(',') : include; +} + +/** + * filter out keys of an object that have falsy values or point to empty arrays + * returning a new object with only those keys that have truthy values / non-empty arrays + * + * @method filterEmpty + * @static + * @public + * @for @ember-data/request-utils + * @param {Record} source object to filter keys with empty values from + * @return {Record} A new object with the keys that contained empty values removed + */ +export function filterEmpty(source: Record): Record { + const result: Record = {}; + for (const key in source) { + const value = source[key]; + // Allow `0` and `false` but filter falsy values that indicate "empty" + if (value !== undefined && value !== null && value !== '') { + if (!Array.isArray(value) || value.length > 0) { + result[key] = source[key]; + } + } + } + return result; +} + +/** + * Sorts query params by both key and value returning a new URLSearchParams + * object with the keys inserted in sorted order. + * + * Treats `included` specially, splicing it into an array if it is a string and sorting the array. + * + * Options: + * - arrayFormat: 'bracket' | 'indices' | 'repeat' | 'comma' + * + * 'bracket': appends [] to the key for every value e.g. `&ids[]=1&ids[]=2` + * 'indices': appends [i] to the key for every value e.g. `&ids[0]=1&ids[1]=2` + * 'repeat': appends the key for every value e.g. `&ids=1&ids=2` + * 'comma' (default): appends the key once with a comma separated list of values e.g. `&ids=1,2` + * + * @method sortQueryParams + * @static + * @public + * @for @ember-data/request-utils + * @param {URLSearchParams | object} params + * @param {object} options + * @return {URLSearchParams} A URLSearchParams with keys inserted in sorted order + */ +export function sortQueryParams(params: QueryParamsSource, options?: QueryParamsSerializationOptions): URLSearchParams { + const opts = Object.assign({}, DEFAULT_QUERY_PARAMS_SERIALIZATION_OPTIONS, options); + const paramsIsObject = !(params instanceof URLSearchParams); + const urlParams = new URLSearchParams(); + const dictionaryParams: Record = paramsIsObject ? params : {}; + + if (!paramsIsObject) { + params.forEach((value, key) => { + const hasExisting = key in dictionaryParams; + if (!hasExisting) { + dictionaryParams[key] = value; + } else { + const existingValue = dictionaryParams[key]; + if (Array.isArray(existingValue)) { + existingValue.push(value); + } else { + dictionaryParams[key] = [existingValue, value]; + } + } + }); + } + + if ('include' in dictionaryParams) { + dictionaryParams.include = handleInclude(dictionaryParams.include as string | string[]); + } + + const sortedKeys = Object.keys(dictionaryParams).sort(); + sortedKeys.forEach((key) => { + const value = dictionaryParams[key]; + if (Array.isArray(value)) { + value.sort(); + switch (opts.arrayFormat) { + case 'indices': + value.forEach((v, i) => { + urlParams.append(`${key}[${i}]`, String(v)); + }); + return; + case 'bracket': + value.forEach((v) => { + urlParams.append(`${key}[]`, String(v)); + }); + return; + case 'repeat': + value.forEach((v) => { + urlParams.append(key, String(v)); + }); + return; + case 'comma': + default: + urlParams.append(key, value.join(',')); + return; + } + } else { + urlParams.append(key, String(value)); + } + }); + + return urlParams; +} + +/** + * Sorts query params by both key and value, returning a query params string + * + * Treats `included` specially, splicing it into an array if it is a string and sorting the array. + * + * Options: + * - arrayFormat: 'bracket' | 'indices' | 'repeat' | 'comma' + * + * 'bracket': appends [] to the key for every value e.g. `ids[]=1&ids[]=2` + * 'indices': appends [i] to the key for every value e.g. `ids[0]=1&ids[1]=2` + * 'repeat': appends the key for every value e.g. `ids=1&ids=2` + * 'comma' (default): appends the key once with a comma separated list of values e.g. `ids=1,2` + * + * @method buildQueryParams + * @static + * @public + * @for @ember-data/request-utils + * @param {URLSearchParams | object} params + * @param {object} [options] + * @return {string} A sorted query params string without the leading `?` + */ +export function buildQueryParams(params: QueryParamsSource, options?: QueryParamsSerializationOptions): string { + return sortQueryParams(params, options).toString(); +} +export interface CacheControlValue { + immutable?: boolean; + 'max-age'?: number; + 'must-revalidate'?: boolean; + 'must-understand'?: boolean; + 'no-cache'?: boolean; + 'no-store'?: boolean; + 'no-transform'?: boolean; + 'only-if-cached'?: boolean; + private?: boolean; + 'proxy-revalidate'?: boolean; + public?: boolean; + 's-maxage'?: number; + 'stale-if-error'?: number; + 'stale-while-revalidate'?: number; +} + +type CacheControlKey = keyof CacheControlValue; + +const NUMERIC_KEYS = new Set(['max-age', 's-maxage', 'stale-if-error', 'stale-while-revalidate']); + +/** + * Parses a string Cache-Control header value into an object with the following structure: + * + * ```ts + * interface CacheControlValue { + * immutable?: boolean; + * 'max-age'?: number; + * 'must-revalidate'?: boolean; + * 'must-understand'?: boolean; + * 'no-cache'?: boolean; + * 'no-store'?: boolean; + * 'no-transform'?: boolean; + * 'only-if-cached'?: boolean; + * private?: boolean; + * 'proxy-revalidate'?: boolean; + * public?: boolean; + * 's-maxage'?: number; + * 'stale-if-error'?: number; + * 'stale-while-revalidate'?: number; + * } + * ``` + * @method parseCacheControl + * @static + * @public + * @for @ember-data/request-utils + * @param {string} header + * @return {CacheControlValue} + */ +export function parseCacheControl(header: string): CacheControlValue { + let key: CacheControlKey = '' as CacheControlKey; + let value = ''; + let isParsingKey = true; + const cacheControlValue: CacheControlValue = {}; + + function parseCacheControlValue(stringToParse: string): number { + const parsedValue = Number.parseInt(stringToParse); + assert(`Invalid Cache-Control value, expected a number but got - ${stringToParse}`, !Number.isNaN(parsedValue)); + return parsedValue; + } + + for (let i = 0; i < header.length; i++) { + const char = header.charAt(i); + if (char === ',') { + assert(`Invalid Cache-Control value, expected a value`, !isParsingKey || !NUMERIC_KEYS.has(key)); + assert( + `Invalid Cache-Control value, expected a value after "=" but got ","`, + i === 0 || header.charAt(i - 1) !== '=' + ); + isParsingKey = true; + // @ts-expect-error TS incorrectly thinks that optional keys must have a type that includes undefined + cacheControlValue[key] = NUMERIC_KEYS.has(key) ? parseCacheControlValue(value) : true; + key = '' as CacheControlKey; + value = ''; + continue; + } else if (char === '=') { + assert(`Invalid Cache-Control value, expected a value after "="`, i + 1 !== header.length); + isParsingKey = false; + } else if (char === ' ' || char === `\t` || char === `\n`) { + continue; + } else if (isParsingKey) { + key += char; + } else { + value += char; + } + + if (i === header.length - 1) { + cacheControlValue[key] = NUMERIC_KEYS.has(key) ? parseCacheControlValue(value) : true; + } + } + + return cacheControlValue; +} + +function isStale(headers: Headers, expirationTime: number): boolean { + // const age = headers.get('age'); + // const cacheControl = parseCacheControl(headers.get('cache-control') || ''); + // const expires = headers.get('expires'); + // const lastModified = headers.get('last-modified'); + const date = headers.get('date'); + + if (!date) { + return true; + } + + const time = new Date(date).getTime(); + const now = Date.now(); + const deadline = time + expirationTime; + + const result = now > deadline; + + return result; +} + +export type LifetimesConfig = { apiCacheSoftExpires: number; apiCacheHardExpires: number }; + +/** + * A basic LifetimesService that can be added to the Store service. + * + * Determines staleness based on time since the request was last received from the API + * using the `date` header. + * + * This allows the Store's CacheHandler to determine if a request is expired and + * should be refetched upon next request. + * + * The `Fetch` handler provided by `@ember-data/request/fetch` will automatically + * add the `date` header to responses if it is not present. + * + * Usage: + * + * ```ts + * import { LifetimesService } from '@ember-data/request-utils'; + * import DataStore from '@ember-data/store'; + * + * // ... + * + * export class Store extends DataStore { + * constructor(args) { + * super(args); + * this.lifetimes = new LifetimesService(this, { apiCacheSoftExpires: 30_000, apiCacheHardExpires: 60_000 }); + * } + * } + * ``` + * + * @class LifetimesService + * @public + * @module @ember-data/request-utils + */ +// TODO this doesn't get documented correctly on the website because it shares a class name +// with the interface expected by the Store service +export class LifetimesService { + declare store: Store; + declare config: LifetimesConfig; + constructor(store: Store, config: LifetimesConfig) { + this.store = store; + this.config = config; + } + + isHardExpired(identifier: StableDocumentIdentifier): boolean { + const cached = this.store.cache.peekRequest(identifier); + return !cached || !cached.response || isStale(cached.response.headers, this.config.apiCacheHardExpires); + } + isSoftExpired(identifier: StableDocumentIdentifier): boolean { + const cached = this.store.cache.peekRequest(identifier); + return !cached || !cached.response || isStale(cached.response.headers, this.config.apiCacheSoftExpires); + } +} diff --git a/packages/rest/LICENSE.md b/packages/rest/LICENSE.md new file mode 100644 index 00000000000..97a483b5d8f --- /dev/null +++ b/packages/rest/LICENSE.md @@ -0,0 +1,11 @@ +The MIT License (MIT) + +Copyright (C) 2017-2023 Ember.js contributors +Portions Copyright (C) 2011-2017 Tilde, Inc. and contributors. +Portions Copyright (C) 2011 LivingSocial Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/rest/README.md b/packages/rest/README.md new file mode 100644 index 00000000000..c31d8c9a5e4 --- /dev/null +++ b/packages/rest/README.md @@ -0,0 +1,69 @@ +

+ + +

+ +

Elegantly composable. Made for RESTful APIs

+ +This package provides utilities for working with **REST**ful APIs with [*Ember***Data**](https://github.com/emberjs/data/). + +## Installation + +Install using your javascript package manager of choice. For instance with [pnpm](https://pnpm.io/) + +```no-highlight +pnpm add @ember-data/rest +``` + +## Getting Started + +If this package is how you are first learning about EmberData, we recommend starting with learning about the [Store](https://github.com/emberjs/data/blob/main/packages/store/README.md) and [Requests](https://github.com/emberjs/data/blob/main/packages/request/README.md) + +## Request Builders + +Request builders are functions that produce [Fetch Options](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). They take a few contextual inputs about the request you want to make, abstracting away the gnarlier details. + +For instance, to fetch a resource from your API + +```ts +import { findRecord } from '@ember-data/rest/request'; + +const options = findRecord('ember-developer', '1', { include: ['pets', 'friends'] }); + +/* + => { + url: 'https://api.example.com/v1/emberDevelopers/1?include=friends,pets', + method: 'GET', + headers: , // 'Content-Type': 'application/json;charset=utf-8' + op: 'findRecord'; + records: [{ type: 'ember-developer', id: '1' }] + } +*/ +``` + +Request builder output may be used with either `requestManager.request` or `store.request`. + +URLs are stable. The same query will produce the same URL every time, even if the order of keys in +the query or values in an array changes. + +URLs follow the most common REST format (camelCase pluralized resource types). + +### Available Builders + +- [createRecord]() +- [deleteRecord]() +- [findRecord]() +- [query]() +- [updateRecord]() diff --git a/packages/rest/addon-main.js b/packages/rest/addon-main.js new file mode 100644 index 00000000000..459ef9174ca --- /dev/null +++ b/packages/rest/addon-main.js @@ -0,0 +1,19 @@ +module.exports = { + name: require('./package.json').name, + + treeForVendor() { + return; + }, + treeForPublic() { + return; + }, + treeForStyles() { + return; + }, + treeForAddonStyles() { + return; + }, + treeForApp() { + return; + }, +}; diff --git a/packages/rest/babel.config.json b/packages/rest/babel.config.json new file mode 100644 index 00000000000..0e04314a08c --- /dev/null +++ b/packages/rest/babel.config.json @@ -0,0 +1,8 @@ +{ + "plugins": [ + "@babel/plugin-transform-runtime", + ["@babel/plugin-transform-typescript", { "allowDeclareFields": true }], + ["@babel/plugin-proposal-decorators", { "legacy": true }], + "@babel/plugin-transform-class-properties" + ] +} diff --git a/packages/rest/ember-data-logo-dark.svg b/packages/rest/ember-data-logo-dark.svg new file mode 100644 index 00000000000..737a4aa4321 --- /dev/null +++ b/packages/rest/ember-data-logo-dark.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/packages/rest/ember-data-logo-light.svg b/packages/rest/ember-data-logo-light.svg new file mode 100644 index 00000000000..58ac3d4e544 --- /dev/null +++ b/packages/rest/ember-data-logo-light.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/packages/rest/package.json b/packages/rest/package.json new file mode 100644 index 00000000000..58369ce22f1 --- /dev/null +++ b/packages/rest/package.json @@ -0,0 +1,110 @@ +{ + "name": "@ember-data/rest", + "description": "REST Format Support for EmberData", + "version": "4.12.5", + "private": false, + "license": "MIT", + "author": "Chris Thoburn ", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com:emberjs/data.git", + "directory": "packages/rest" + }, + "homepage": "https://github.com/emberjs/data", + "bugs": "https://github.com/emberjs/data/issues", + "engines": { + "node": "16.* || >= 18.*" + }, + "keywords": [ + "ember-addon" + ], + "volta": { + "extends": "../../package.json" + }, + "dependencies": { + "ember-cli-babel": "^8.2.0", + "pnpm-sync-dependencies-meta-injected": "0.0.10" + }, + "peerDependencies": { + "@ember-data/request-utils": "workspace:4.12.5", + "@ember-data/store": "^4.12.0 || ^5.0.0", + "@ember/string": "^3.1.1", + "ember-inflector": "^4.0.2" + }, + "files": [ + "unstable-preview-types", + "addon-main.js", + "addon", + "README.md", + "LICENSE.md", + "ember-data-logo-dark.svg", + "ember-data-logo-light.svg" + ], + "exports": { + "./*": { + "types": "./unstable-preview-types/*.d.ts", + "default": "./addon/*.js" + } + }, + "scripts": { + "build:types": "tsc --build", + "build:client": "rollup --config && babel ./addon --out-dir addon --plugins=../private-build-infra/src/transforms/babel-plugin-transform-ext.js", + "_build": "bun run build:client && bun run build:types", + "prepack": "pnpm build", + "_syncPnpm": "bun run sync-dependencies-meta-injected" + }, + "ember-addon": { + "main": "addon-main.js", + "type": "addon", + "version": 1 + }, + "devDependencies": { + "@babel/cli": "^7.23.4", + "@babel/core": "^7.23.3", + "@babel/plugin-proposal-decorators": "^7.23.3", + "@babel/plugin-transform-class-properties": "^7.23.3", + "@babel/plugin-transform-runtime": "^7.23.4", + "@babel/plugin-transform-typescript": "^7.23.4", + "@babel/preset-env": "^7.23.3", + "@babel/preset-typescript": "^7.23.3", + "@babel/runtime": "^7.23.4", + "@ember-data/request": "workspace:4.12.5", + "@ember-data/request-utils": "workspace:4.12.5", + "@ember-data/store": "workspace:4.12.5", + "@ember-data/tracking": "workspace:4.12.5", + "@ember/string": "^3.1.1", + "@embroider/addon-dev": "^4.1.2", + "@glimmer/component": "^1.1.2", + "@rollup/plugin-babel": "^6.0.4", + "@rollup/plugin-node-resolve": "^15.2.3", + "@warp-drive/internal-config": "workspace:4.12.5", + "ember-inflector": "^4.0.2", + "ember-source": "~5.4.0", + "rollup": "^4.5.0", + "typescript": "^5.3.2", + "walk-sync": "^3.0.0" + }, + "ember": { + "edition": "octane" + }, + "dependenciesMeta": { + "@ember/string": { + "injected": true + }, + "@ember-data/store": { + "injected": true + }, + "@ember-data/request-utils": { + "injected": true + }, + "ember-inflector": { + "injected": true + }, + "@ember-data/request": { + "injected": true + }, + "@ember-data/tracking": { + "injected": true + } + } +} diff --git a/packages/rest/rollup.config.mjs b/packages/rest/rollup.config.mjs new file mode 100644 index 00000000000..683b7c9b8b0 --- /dev/null +++ b/packages/rest/rollup.config.mjs @@ -0,0 +1,33 @@ +import { Addon } from '@embroider/addon-dev/rollup'; +import babel from '@rollup/plugin-babel'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; + +import { external } from '@warp-drive/internal-config/rollup/external.js'; + +const addon = new Addon({ + srcDir: 'src', + destDir: 'addon', +}); + +export default { + // This provides defaults that work well alongside `publicEntrypoints` below. + // You can augment this if you need to. + output: addon.output(), + + external: external(['@ember/debug']), + + plugins: [ + // These are the modules that users should be able to import from your + // addon. Anything not listed here may get optimized away. + addon.publicEntrypoints(['request.js']), + + nodeResolve({ extensions: ['.ts'] }), + babel({ + extensions: ['.ts'], + babelHelpers: 'runtime', // we should consider "external", + }), + + // Remove leftover build artifacts when starting a new build. + addon.clean(), + ], +}; diff --git a/packages/rest/src/-private/builders/-utils.ts b/packages/rest/src/-private/builders/-utils.ts new file mode 100644 index 00000000000..e13004887e8 --- /dev/null +++ b/packages/rest/src/-private/builders/-utils.ts @@ -0,0 +1,25 @@ +import type { UrlOptions } from '@ember-data/request-utils'; +import type { ConstrainedRequestOptions, CacheOptions } from '@ember-data/types/q/request'; + +export function copyForwardUrlOptions(urlOptions: UrlOptions, options: ConstrainedRequestOptions): void { + if ('host' in options) { + urlOptions.host = options.host; + } + if ('namespace' in options) { + urlOptions.namespace = options.namespace; + } + if ('resourcePath' in options) { + urlOptions.resourcePath = options.resourcePath; + } +} + +export function extractCacheOptions(options: ConstrainedRequestOptions) { + const cacheOptions: CacheOptions = {}; + if ('reload' in options) { + cacheOptions.reload = options.reload; + } + if ('backgroundReload' in options) { + cacheOptions.backgroundReload = options.backgroundReload; + } + return cacheOptions; +} diff --git a/packages/rest/src/-private/builders/find-record.ts b/packages/rest/src/-private/builders/find-record.ts new file mode 100644 index 00000000000..5530a4146ed --- /dev/null +++ b/packages/rest/src/-private/builders/find-record.ts @@ -0,0 +1,114 @@ +/** + * @module @ember-data/rest/request + */ +import { camelize } from '@ember/string'; + +import { pluralize } from 'ember-inflector'; + +import { buildBaseURL, buildQueryParams, type FindRecordUrlOptions } from '@ember-data/request-utils'; +import { + ConstrainedRequestOptions, + RemotelyAccessibleIdentifier, + FindRecordRequestOptions, +} from '@ember-data/types/q/request'; + +import { copyForwardUrlOptions, extractCacheOptions } from './-utils'; + +type FindRecordOptions = ConstrainedRequestOptions & { + include?: string | string[]; +}; + +/** + * Builds request options to fetch a single resource by a known id or identifier + * configured for the url and header expectations of most REST APIs. + * + * **Basic Usage** + * + * ```ts + * import { findRecord } from '@ember-data/rest/request'; + * + * const data = await store.request(findRecord('person', '1')); + * ``` + * + * **With Options** + * + * ```ts + * import { findRecord } from '@ember-data/rest/request'; + * + * const options = findRecord('person', '1', { include: ['pets', 'friends'] }); + * const data = await store.request(options); + * ``` + * + * **With an Identifier** + * + * ```ts + * import { findRecord } from '@ember-data/rest/request'; + * + * const options = findRecord({ type: 'person', id: '1' }, { include: ['pets', 'friends'] }); + * const data = await store.request(options); + * ``` + * + * **Supplying Options to Modify the Request Behavior** + * + * The following options are supported: + * + * - `host` - The host to use for the request, defaults to the `host` configured with `setBuildURLConfig`. + * - `namespace` - The namespace to use for the request, defaults to the `namespace` configured with `setBuildURLConfig`. + * - `resourcePath` - The resource path to use for the request, defaults to pluralizing and camelCasing the supplied type + * - `reload` - Whether to forcibly reload the request if it is already in the store, not supplying this + * option will delegate to the store's lifetimes service, defaulting to `false` if none is configured. + * - `backgroundReload` - Whether to reload the request if it is already in the store, but to also resolve the + * promise with the cached value, not supplying this option will delegate to the store's lifetimes service, + * defaulting to `false` if none is configured. + * - `urlParamsSetting` - an object containing options for how to serialize the query params (see `buildQueryParams`) + * + * ```ts + * import { findRecord } from '@ember-data/rest/request'; + * + * const options = findRecord('person', '1', { include: ['pets', 'friends'] }, { namespace: 'api/v2' }); + * const data = await store.request(options); + * ``` + * + * @method findRecord + * @public + * @static + * @for @ember-data/rest/request + * @param identifier + * @param options + */ +export function findRecord( + identifier: RemotelyAccessibleIdentifier, + options?: FindRecordOptions +): FindRecordRequestOptions; +export function findRecord(type: string, id: string, options?: FindRecordOptions): FindRecordRequestOptions; +export function findRecord( + arg1: string | RemotelyAccessibleIdentifier, + arg2: string | FindRecordOptions | undefined, + arg3?: FindRecordOptions +): FindRecordRequestOptions { + const identifier: RemotelyAccessibleIdentifier = typeof arg1 === 'string' ? { type: arg1, id: arg2 as string } : arg1; + const options: FindRecordOptions = (typeof arg1 === 'string' ? arg3 : (arg2 as FindRecordOptions)) || {}; + const cacheOptions = extractCacheOptions(options); + const urlOptions: FindRecordUrlOptions = { + identifier, + op: 'findRecord', + resourcePath: pluralize(camelize(identifier.type)), + }; + + copyForwardUrlOptions(urlOptions, options); + + const url = buildBaseURL(urlOptions); + const headers = new Headers(); + headers.append('Accept', 'application/json;charset=utf-8'); + + return { + url: options.include?.length + ? `${url}?${buildQueryParams({ include: options.include }, options.urlParamsSettings)}` + : url, + method: 'GET', + headers, + cacheOptions, + op: 'findRecord', + records: [identifier], + }; +} diff --git a/packages/rest/src/-private/builders/query.ts b/packages/rest/src/-private/builders/query.ts new file mode 100644 index 00000000000..4647958dc05 --- /dev/null +++ b/packages/rest/src/-private/builders/query.ts @@ -0,0 +1,90 @@ +/** + * @module @ember-data/rest/request + */ +import { camelize } from '@ember/string'; + +import { pluralize } from 'ember-inflector'; + +import { buildBaseURL, buildQueryParams, type QueryUrlOptions } from '@ember-data/request-utils'; +import type { QueryParamsSource } from '@ember-data/types/q/params'; +import type { ConstrainedRequestOptions, QueryRequestOptions } from '@ember-data/types/q/request'; + +import { copyForwardUrlOptions, extractCacheOptions } from './-utils'; + +/** + * Builds request options to query for resources, usually by a primary + * type, configured for the url and header expectations of most REST APIs. + * + * **Basic Usage** + * + * ```ts + * import { query } from '@ember-data/rest/request'; + * + * const data = await store.request(query('person')); + * ``` + * + * **With Query Params** + * + * ```ts + * import { query } from '@ember-data/rest/request'; + * + * const options = query('person', { include: ['pets', 'friends'] }); + * const data = await store.request(options); + * ``` + * + * **Supplying Options to Modify the Request Behavior** + * + * The following options are supported: + * + * - `host` - The host to use for the request, defaults to the `host` configured with `setBuildURLConfig`. + * - `namespace` - The namespace to use for the request, defaults to the `namespace` configured with `setBuildURLConfig`. + * - `resourcePath` - The resource path to use for the request, defaults to pluralizing and camelCasing the supplied type + * - `reload` - Whether to forcibly reload the request if it is already in the store, not supplying this + * option will delegate to the store's lifetimes service, defaulting to `false` if none is configured. + * - `backgroundReload` - Whether to reload the request if it is already in the store, but to also resolve the + * promise with the cached value, not supplying this option will delegate to the store's lifetimes service, + * defaulting to `false` if none is configured. + * - `urlParamsSetting` - an object containing options for how to serialize the query params (see `buildQueryParams`) + * + * ```ts + * import { query } from '@ember-data/rest/request'; + * + * const options = query('person', { include: ['pets', 'friends'] }, { reload: true }); + * const data = await store.request(options); + * ``` + * + * @method query + * @public + * @static + * @for @ember-data/rest/request + * @param identifier + * @param query + * @param options + */ +export function query( + type: string, + // eslint-disable-next-line @typescript-eslint/no-shadow + query: QueryParamsSource = {}, + options: ConstrainedRequestOptions = {} +): QueryRequestOptions { + const cacheOptions = extractCacheOptions(options); + const urlOptions: QueryUrlOptions = { + identifier: { type }, + op: 'query', + resourcePath: pluralize(camelize(type)), + }; + + copyForwardUrlOptions(urlOptions, options); + + const url = buildBaseURL(urlOptions); + const headers = new Headers(); + headers.append('Accept', 'application/json;charset=utf-8'); + + return { + url: `${url}?${buildQueryParams(query, options.urlParamsSettings)}`, + method: 'GET', + headers, + cacheOptions, + op: 'query', + }; +} diff --git a/packages/rest/src/-private/builders/save-record.ts b/packages/rest/src/-private/builders/save-record.ts new file mode 100644 index 00000000000..a062cf76374 --- /dev/null +++ b/packages/rest/src/-private/builders/save-record.ts @@ -0,0 +1,251 @@ +import { assert } from '@ember/debug'; +import { camelize } from '@ember/string'; + +import { pluralize } from 'ember-inflector'; + +import { + buildBaseURL, + type CreateRecordUrlOptions, + type DeleteRecordUrlOptions, + type UpdateRecordUrlOptions, +} from '@ember-data/request-utils'; +import { recordIdentifierFor } from '@ember-data/store'; +import type { StableExistingRecordIdentifier, StableRecordIdentifier } from '@ember-data/types/q/identifier'; +import { RecordInstance } from '@ember-data/types/q/record-instance'; +import type { + ConstrainedRequestOptions, + CreateRequestOptions, + DeleteRequestOptions, + UpdateRequestOptions, +} from '@ember-data/types/q/request'; + +import { copyForwardUrlOptions } from './-utils'; + +function isExisting(identifier: StableRecordIdentifier): identifier is StableExistingRecordIdentifier { + return 'id' in identifier && identifier.id !== null && 'type' in identifier && identifier.type !== null; +} + +/** + * Builds request options to delete record for resources, + * configured for the url, method and header expectations of REST APIs. + * + * **Basic Usage** + * + * ```ts + * import { deleteRecord } from '@ember-data/rest/request'; + * + * const person = this.store.peekRecord('person', '1'); + * + * // mark record as deleted + * store.deleteRecord(person); + * + * // persist deletion + * const data = await store.request(deleteRecord(person)); + * ``` + * + * **Supplying Options to Modify the Request Behavior** + * + * The following options are supported: + * + * - `host` - The host to use for the request, defaults to the `host` configured with `setBuildURLConfig`. + * - `namespace` - The namespace to use for the request, defaults to the `namespace` configured with `setBuildURLConfig`. + * - `resourcePath` - The resource path to use for the request, defaults to pluralizing the supplied type + * - `reload` - Whether to forcibly reload the request if it is already in the store, not supplying this + * option will delegate to the store's lifetimes service, defaulting to `false` if none is configured. + * - `backgroundReload` - Whether to reload the request if it is already in the store, but to also resolve the + * promise with the cached value, not supplying this option will delegate to the store's lifetimes service, + * defaulting to `false` if none is configured. + * - `urlParamsSetting` - an object containing options for how to serialize the query params (see `buildQueryParams`) + * + * ```ts + * import { deleteRecord } from '@ember-data/rest/request'; + * + * const person = this.store.peekRecord('person', '1'); + * + * // mark record as deleted + * store.deleteRecord(person); + * + * // persist deletion + * const options = deleteRecord(person, { namespace: 'api/v1' }); + * const data = await store.request(options); + * ``` + * + * @method deleteRecord + * @public + * @static + * @for @ember-data/rest/request + * @param record + * @param options + */ +export function deleteRecord(record: RecordInstance, options: ConstrainedRequestOptions = {}): DeleteRequestOptions { + const identifier = recordIdentifierFor(record); + assert(`Expected to be given a record instance`, identifier); + assert(`Cannot delete a record that does not have an associated type and id.`, isExisting(identifier)); + + const urlOptions: DeleteRecordUrlOptions = { + identifier: identifier, + op: 'deleteRecord', + resourcePath: pluralize(camelize(identifier.type)), + }; + + copyForwardUrlOptions(urlOptions, options); + + const url = buildBaseURL(urlOptions); + const headers = new Headers(); + headers.append('Accept', 'application/json;charset=utf-8'); + + return { + url, + method: 'DELETE', + headers, + op: 'deleteRecord', + data: { + record: identifier, + }, + }; +} + +/** + * Builds request options to create new record for resources, + * configured for the url, method and header expectations of most REST APIs. + * + * **Basic Usage** + * + * ```ts + * import { createRecord } from '@ember-data/rest/request'; + * + * const person = this.store.createRecord('person', { name: 'Ted' }); + * const data = await store.request(createRecord(person)); + * ``` + * + * **Supplying Options to Modify the Request Behavior** + * + * The following options are supported: + * + * - `host` - The host to use for the request, defaults to the `host` configured with `setBuildURLConfig`. + * - `namespace` - The namespace to use for the request, defaults to the `namespace` configured with `setBuildURLConfig`. + * - `resourcePath` - The resource path to use for the request, defaults to pluralizing the supplied type + * - `reload` - Whether to forcibly reload the request if it is already in the store, not supplying this + * option will delegate to the store's lifetimes service, defaulting to `false` if none is configured. + * - `backgroundReload` - Whether to reload the request if it is already in the store, but to also resolve the + * promise with the cached value, not supplying this option will delegate to the store's lifetimes service, + * defaulting to `false` if none is configured. + * - `urlParamsSetting` - an object containing options for how to serialize the query params (see `buildQueryParams`) + * + * ```ts + * import { createRecord } from '@ember-data/rest/request'; + * + * const person = this.store.createRecord('person', { name: 'Ted' }); + * const options = createRecord(person, { namespace: 'api/v1' }); + * const data = await store.request(options); + * ``` + * + * @method createRecord + * @public + * @static + * @for @ember-data/rest/request + * @param record + * @param options + */ +export function createRecord(record: RecordInstance, options: ConstrainedRequestOptions = {}): CreateRequestOptions { + const identifier = recordIdentifierFor(record); + assert(`Expected to be given a record instance`, identifier); + + const urlOptions: CreateRecordUrlOptions = { + identifier: identifier, + op: 'createRecord', + resourcePath: pluralize(camelize(identifier.type)), + }; + + copyForwardUrlOptions(urlOptions, options); + + const url = buildBaseURL(urlOptions); + const headers = new Headers(); + headers.append('Accept', 'application/json;charset=utf-8'); + + return { + url, + method: 'POST', + headers, + op: 'createRecord', + data: { + record: identifier, + }, + }; +} + +/** + * Builds request options to update existing record for resources, + * configured for the url, method and header expectations of most REST APIs. + * + * **Basic Usage** + * + * ```ts + * import { updateRecord } from '@ember-data/rest/request'; + * + * const person = this.store.peekRecord('person', '1'); + * person.name = 'Chris'; + * const data = await store.request(updateRecord(person)); + * ``` + * + * **Supplying Options to Modify the Request Behavior** + * + * The following options are supported: + * + * - `patch` - Allows caller to specify whether to use a PATCH request instead of a PUT request, defaults to `false`. + * - `host` - The host to use for the request, defaults to the `host` configured with `setBuildURLConfig`. + * - `namespace` - The namespace to use for the request, defaults to the `namespace` configured with `setBuildURLConfig`. + * - `resourcePath` - The resource path to use for the request, defaults to pluralizing the supplied type + * - `reload` - Whether to forcibly reload the request if it is already in the store, not supplying this + * option will delegate to the store's lifetimes service, defaulting to `false` if none is configured. + * - `backgroundReload` - Whether to reload the request if it is already in the store, but to also resolve the + * promise with the cached value, not supplying this option will delegate to the store's lifetimes service, + * defaulting to `false` if none is configured. + * - `urlParamsSetting` - an object containing options for how to serialize the query params (see `buildQueryParams`) + * + * ```ts + * import { updateRecord } from '@ember-data/rest/request'; + * + * const person = this.store.peekRecord('person', '1'); + * person.name = 'Chris'; + * const options = updateRecord(person, { patch: true }); + * const data = await store.request(options); + * ``` + * + * @method updateRecord + * @public + * @static + * @for @ember-data/rest/request + * @param record + * @param options + */ +export function updateRecord( + record: RecordInstance, + options: ConstrainedRequestOptions & { patch?: boolean } = {} +): UpdateRequestOptions { + const identifier = recordIdentifierFor(record); + assert(`Expected to be given a record instance`, identifier); + assert(`Cannot update a record that does not have an associated type and id.`, isExisting(identifier)); + + const urlOptions: UpdateRecordUrlOptions = { + identifier: identifier, + op: 'updateRecord', + resourcePath: pluralize(camelize(identifier.type)), + }; + + copyForwardUrlOptions(urlOptions, options); + + const url = buildBaseURL(urlOptions); + const headers = new Headers(); + headers.append('Accept', 'application/json;charset=utf-8'); + + return { + url, + method: options.patch ? 'PATCH' : 'PUT', + headers, + op: 'updateRecord', + data: { + record: identifier, + }, + }; +} diff --git a/packages/rest/src/.gitkeep b/packages/rest/src/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/rest/src/request.ts b/packages/rest/src/request.ts new file mode 100644 index 00000000000..d1c8c34e436 --- /dev/null +++ b/packages/rest/src/request.ts @@ -0,0 +1,69 @@ +/** + *

+ +

+ +This package provides utilities for working with **REST**ful APIs with [*Ember***Data**](https://github.com/emberjs/data/). + +## Installation + +Install using your javascript package manager of choice. For instance with [pnpm](https://pnpm.io/) + +```no-highlight +pnpm add @ember-data/json-api +``` + +## Usage + +Request builders are functions that produce [Fetch Options](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API). +They take a few contextual inputs about the request you want to make, abstracting away the gnarlier details. + +For instance, to fetch a resource from your API + +```ts +import { findRecord } from '@ember-data/rest/request'; + +const options = findRecord('ember-developer', '1', { include: ['pets', 'friends'] }); + +/* + => { + url: 'https://api.example.com/v1/emberDevelopers/1?include=friends,pets', + method: 'GET', + headers: , // 'Content-Type': 'application/json;charset=utf-8' + op: 'findRecord'; + records: [{ type: 'ember-developer', id: '1' }] + } +* / +``` + +Request builder output is ready to go for use with [store.request](https://api.emberjs.com/ember-data/release/classes/Store/methods/request?anchor=request), +[manager.request](https://api.emberjs.com/ember-data/release/classes/RequestManager/methods/request?anchor=request) and most conventional REST APIs. + +Resource types are pluralized and camelized for the url. + +URLs are stable. The same query will produce the same URL every time, even if the order of keys in +the query or values in an array changes. + +URLs follow the most common REST format (camelCase pluralized resource types). + +### Available Builders + +- [createRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Frest/createRecord) +- [deleteRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Frest/deleteRecord) +- [findRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Frest/findRecord) +- [query](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Frest/query) +- [updateRecord](https://api.emberjs.com/ember-data/release/functions/@ember-data%2Frest/updateRecord) + + * @module @ember-data/rest/request + * @main @ember-data/rest/request + * @public + */ +export { findRecord } from './-private/builders/find-record'; +export { query } from './-private/builders/query'; +export { deleteRecord, createRecord, updateRecord } from './-private/builders/save-record'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6beea75a8b2..7ec09155141 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,7 +47,7 @@ importers: version: 4.0.3(@babel/core@7.21.4) '@types/ember-qunit': specifier: ^5.0.2 - version: 5.0.2(@babel/core@7.21.4)(ember-source@4.12.0) + version: 5.0.2(@babel/core@7.21.4)(ember-source@4.12.0)(webpack@5.77.0) '@types/ember-resolver': specifier: ^5.0.13 version: 5.0.13(@babel/core@7.21.4) @@ -319,6 +319,101 @@ importers: '@ember-data/tracking': injected: true + packages/active-record: + dependencies: + ember-cli-babel: + specifier: ^7.26.11 + version: 7.26.11 + pnpm-sync-dependencies-meta-injected: + specifier: 0.0.10 + version: 0.0.10 + devDependencies: + '@babel/cli': + specifier: ^7.23.4 + version: 7.23.4(@babel/core@7.23.5) + '@babel/core': + specifier: ^7.23.3 + version: 7.23.5 + '@babel/plugin-proposal-decorators': + specifier: ^7.23.3 + version: 7.23.5(@babel/core@7.23.5) + '@babel/plugin-transform-class-properties': + specifier: ^7.23.3 + version: 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-runtime': + specifier: ^7.23.4 + version: 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-typescript': + specifier: ^7.23.4 + version: 7.23.5(@babel/core@7.23.5) + '@babel/preset-env': + specifier: ^7.23.3 + version: 7.23.5(@babel/core@7.23.5) + '@babel/preset-typescript': + specifier: ^7.23.3 + version: 7.23.3(@babel/core@7.23.5) + '@babel/runtime': + specifier: ^7.23.4 + version: 7.23.5 + '@ember-data/request': + specifier: workspace:4.12.5 + version: file:packages/request + '@ember-data/request-utils': + specifier: workspace:4.12.5 + version: file:packages/request-utils + '@ember-data/store': + specifier: workspace:4.12.5 + version: file:packages/store(@babel/core@7.23.5)(@ember-data/tracking@4.12.5)(@ember/string@3.1.1)(ember-source@5.4.0) + '@ember-data/tracking': + specifier: workspace:4.12.5 + version: file:packages/tracking + '@ember/string': + specifier: ^3.1.1 + version: 3.1.1 + '@embroider/addon-dev': + specifier: ^4.1.2 + version: 4.1.2(rollup@4.6.1) + '@glimmer/component': + specifier: ^1.1.2 + version: 1.1.2(@babel/core@7.23.5) + '@rollup/plugin-babel': + specifier: ^6.0.4 + version: 6.0.4(@babel/core@7.23.5)(rollup@4.6.1) + '@rollup/plugin-node-resolve': + specifier: ^15.2.3 + version: 15.2.3(rollup@4.6.1) + '@warp-drive/internal-config': + specifier: workspace:4.12.5 + version: link:../config + ember-inflector: + specifier: ^4.0.2 + version: 4.0.2 + ember-source: + specifier: ~5.4.0 + version: 5.4.0(@babel/core@7.23.5)(@glimmer/component@1.1.2) + rollup: + specifier: ^4.5.0 + version: 4.6.1 + typescript: + specifier: ^5.3.2 + version: 5.3.3 + walk-sync: + specifier: ^3.0.0 + version: 3.0.0 + dependenciesMeta: + '@ember-data/request': + injected: true + '@ember-data/request-utils': + injected: true + '@ember-data/store': + injected: true + '@ember-data/tracking': + injected: true + '@ember/string': + injected: true + ember-inflector: + injected: true + packages/adapter: dependencies: '@ember-data/private-build-infra': @@ -395,6 +490,48 @@ importers: '@ember-data/private-build-infra': injected: true + packages/config: + dependencies: + '@babel/core': + specifier: ^7.23.3 + version: 7.23.5 + '@babel/eslint-parser': + specifier: ^7.23.3 + version: 7.23.3(@babel/core@7.23.5)(eslint@8.55.0) + '@babel/plugin-proposal-decorators': + specifier: ^7.23.3 + version: 7.23.5(@babel/core@7.23.5) + '@typescript-eslint/eslint-plugin': + specifier: ^6.13.1 + version: 6.13.2(@typescript-eslint/parser@6.13.2)(eslint@8.55.0)(typescript@5.3.3) + '@typescript-eslint/parser': + specifier: ^6.13.1 + version: 6.13.2(eslint@8.55.0)(typescript@5.3.3) + eslint: + specifier: ^8.54.0 + version: 8.55.0 + eslint-config-prettier: + specifier: ^9.0.0 + version: 9.1.0(eslint@8.55.0) + eslint-plugin-import: + specifier: ^2.29.0 + version: 2.29.0(@typescript-eslint/parser@6.13.2)(eslint@8.55.0) + eslint-plugin-mocha: + specifier: ^10.2.0 + version: 10.2.0(eslint@8.55.0) + eslint-plugin-n: + specifier: ^16.3.1 + version: 16.3.1(eslint@8.55.0) + eslint-plugin-qunit: + specifier: ^8.0.1 + version: 8.0.1(eslint@8.55.0) + eslint-plugin-simple-import-sort: + specifier: ^10.0.0 + version: 10.0.0(eslint@8.55.0) + typescript: + specifier: ~5.3.2 + version: 5.3.3 + packages/debug: dependencies: '@ember-data/private-build-infra': @@ -420,6 +557,79 @@ importers: '@ember-data/private-build-infra': injected: true + packages/diagnostic: + dependencies: + chalk: + specifier: ^5.3.0 + version: 5.3.0 + debug: + specifier: ^4.3.4 + version: 4.3.4 + pnpm-sync-dependencies-meta-injected: + specifier: 0.0.10 + version: 0.0.10 + tmp: + specifier: ^0.2.1 + version: 0.2.1 + devDependencies: + '@babel/cli': + specifier: ^7.23.4 + version: 7.23.4(@babel/core@7.23.5) + '@babel/core': + specifier: ^7.23.3 + version: 7.23.5 + '@babel/plugin-transform-typescript': + specifier: ^7.23.4 + version: 7.23.5(@babel/core@7.23.5) + '@babel/preset-env': + specifier: ^7.23.3 + version: 7.23.5(@babel/core@7.23.5) + '@babel/preset-typescript': + specifier: ^7.23.3 + version: 7.23.3(@babel/core@7.23.5) + '@babel/runtime': + specifier: ^7.23.4 + version: 7.23.5 + '@ember/test-helpers': + specifier: ^3.2.0 + version: 3.2.1(ember-source@5.4.0) + '@embroider/addon-dev': + specifier: ^4.1.2 + version: 4.1.2(rollup@4.6.1) + '@embroider/addon-shim': + specifier: ^1.8.7 + version: 1.8.7 + '@glimmer/component': + specifier: ^1.1.2 + version: 1.1.2(@babel/core@7.23.5) + '@rollup/plugin-babel': + specifier: ^6.0.4 + version: 6.0.4(@babel/core@7.23.5)(rollup@4.6.1) + '@rollup/plugin-node-resolve': + specifier: ^15.2.3 + version: 15.2.3(rollup@4.6.1) + '@warp-drive/internal-config': + specifier: workspace:4.12.5 + version: link:../config + bun-types: + specifier: ^1.0.14 + version: 1.0.15 + ember-cli-test-loader: + specifier: ^3.1.0 + version: 3.1.0 + ember-source: + specifier: ~5.4.0 + version: 5.4.0(@babel/core@7.23.5)(@glimmer/component@1.1.2) + rollup: + specifier: ^4.5.0 + version: 4.6.1 + typescript: + specifier: ^5.3.2 + version: 5.3.3 + walk-sync: + specifier: ^3.0.0 + version: 3.0.0 + packages/graph: dependencies: '@ember-data/private-build-infra': @@ -877,6 +1087,165 @@ importers: '@ember-data/private-build-infra': injected: true + packages/request-utils: + dependencies: + ember-cli-babel: + specifier: ^7.26.11 + version: 7.26.11 + pnpm-sync-dependencies-meta-injected: + specifier: 0.0.10 + version: 0.0.10 + devDependencies: + '@babel/cli': + specifier: ^7.23.4 + version: 7.23.4(@babel/core@7.23.5) + '@babel/core': + specifier: ^7.23.3 + version: 7.23.5 + '@babel/plugin-proposal-decorators': + specifier: ^7.23.3 + version: 7.23.5(@babel/core@7.23.5) + '@babel/plugin-transform-class-properties': + specifier: ^7.23.3 + version: 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-runtime': + specifier: ^7.23.4 + version: 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-typescript': + specifier: ^7.23.4 + version: 7.23.5(@babel/core@7.23.5) + '@babel/preset-env': + specifier: ^7.23.3 + version: 7.23.5(@babel/core@7.23.5) + '@babel/preset-typescript': + specifier: ^7.23.3 + version: 7.23.3(@babel/core@7.23.5) + '@babel/runtime': + specifier: ^7.23.4 + version: 7.23.5 + '@embroider/addon-dev': + specifier: ^4.1.2 + version: 4.1.2(rollup@4.6.1) + '@glimmer/component': + specifier: ^1.1.2 + version: 1.1.2(@babel/core@7.23.5) + '@rollup/plugin-babel': + specifier: ^6.0.4 + version: 6.0.4(@babel/core@7.23.5)(rollup@4.6.1) + '@rollup/plugin-node-resolve': + specifier: ^15.2.3 + version: 15.2.3(rollup@4.6.1) + '@warp-drive/internal-config': + specifier: workspace:4.12.5 + version: link:../config + ember-source: + specifier: ~5.4.0 + version: 5.4.0(@babel/core@7.23.5)(@glimmer/component@1.1.2) + rollup: + specifier: ^4.5.0 + version: 4.6.1 + typescript: + specifier: ^5.3.2 + version: 5.3.3 + walk-sync: + specifier: ^3.0.0 + version: 3.0.0 + + packages/rest: + dependencies: + ember-cli-babel: + specifier: ^7.26.11 + version: 7.26.11 + pnpm-sync-dependencies-meta-injected: + specifier: 0.0.10 + version: 0.0.10 + devDependencies: + '@babel/cli': + specifier: ^7.23.4 + version: 7.23.4(@babel/core@7.23.5) + '@babel/core': + specifier: ^7.23.3 + version: 7.23.5 + '@babel/plugin-proposal-decorators': + specifier: ^7.23.3 + version: 7.23.5(@babel/core@7.23.5) + '@babel/plugin-transform-class-properties': + specifier: ^7.23.3 + version: 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-runtime': + specifier: ^7.23.4 + version: 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-typescript': + specifier: ^7.23.4 + version: 7.23.5(@babel/core@7.23.5) + '@babel/preset-env': + specifier: ^7.23.3 + version: 7.23.5(@babel/core@7.23.5) + '@babel/preset-typescript': + specifier: ^7.23.3 + version: 7.23.3(@babel/core@7.23.5) + '@babel/runtime': + specifier: ^7.23.4 + version: 7.23.5 + '@ember-data/request': + specifier: workspace:4.12.5 + version: file:packages/request + '@ember-data/request-utils': + specifier: workspace:4.12.5 + version: file:packages/request-utils + '@ember-data/store': + specifier: workspace:4.12.5 + version: file:packages/store(@babel/core@7.23.5)(@ember-data/tracking@4.12.5)(@ember/string@3.1.1)(ember-source@5.4.0) + '@ember-data/tracking': + specifier: workspace:4.12.5 + version: file:packages/tracking + '@ember/string': + specifier: ^3.1.1 + version: 3.1.1 + '@embroider/addon-dev': + specifier: ^4.1.2 + version: 4.1.2(rollup@4.6.1) + '@glimmer/component': + specifier: ^1.1.2 + version: 1.1.2(@babel/core@7.23.5) + '@rollup/plugin-babel': + specifier: ^6.0.4 + version: 6.0.4(@babel/core@7.23.5)(rollup@4.6.1) + '@rollup/plugin-node-resolve': + specifier: ^15.2.3 + version: 15.2.3(rollup@4.6.1) + '@warp-drive/internal-config': + specifier: workspace:4.12.5 + version: link:../config + ember-inflector: + specifier: ^4.0.2 + version: 4.0.2 + ember-source: + specifier: ~5.4.0 + version: 5.4.0(@babel/core@7.23.5)(@glimmer/component@1.1.2) + rollup: + specifier: ^4.5.0 + version: 4.6.1 + typescript: + specifier: ^5.3.2 + version: 5.3.3 + walk-sync: + specifier: ^3.0.0 + version: 3.0.0 + dependenciesMeta: + '@ember-data/request': + injected: true + '@ember-data/request-utils': + injected: true + '@ember-data/store': + injected: true + '@ember-data/tracking': + injected: true + '@ember/string': + injected: true + ember-inflector: + injected: true + packages/serializer: dependencies: '@ember-data/private-build-infra': @@ -1377,104 +1746,270 @@ importers: '@ember-data/unpublished-test-infra': injected: true - tests/debug-encapsulation: + tests/builders: + dependencies: + pnpm-sync-dependencies-meta-injected: + specifier: 0.0.10 + version: 0.0.10 devDependencies: '@babel/core': - specifier: ^7.21.4 - version: 7.21.4 + specifier: ^7.23.3 + version: 7.23.5 '@babel/runtime': - specifier: ^7.21.0 - version: 7.21.0 - '@ember-data/adapter': + specifier: ^7.23.4 + version: 7.23.5 + '@ember-data/active-record': specifier: workspace:4.12.5 - version: file:packages/adapter(@ember-data/store@4.12.5)(@ember/string@3.0.1)(ember-inflector@4.0.2) + version: file:packages/active-record(@ember-data/request-utils@4.12.5)(@ember-data/store@4.12.5)(@ember/string@3.1.1)(ember-inflector@4.0.2) + '@ember-data/debug': + specifier: workspace:4.12.5 + version: file:packages/debug(@ember-data/store@4.12.5)(@ember/string@3.1.1)(webpack@5.89.0) + '@ember-data/graph': + specifier: workspace:4.12.5 + version: file:packages/graph(@ember-data/store@4.12.5) + '@ember-data/json-api': + specifier: workspace:4.12.5 + version: file:packages/json-api(@ember-data/graph@4.12.5)(@ember-data/store@4.12.5) + '@ember-data/legacy-compat': + specifier: workspace:4.12.5 + version: file:packages/legacy-compat(@ember-data/graph@4.12.5)(@ember-data/json-api@4.12.5) '@ember-data/model': specifier: workspace:4.12.5 - version: file:packages/model(@babel/core@7.21.4)(@ember-data/store@4.12.5)(@ember-data/tracking@4.12.5)(@ember/string@3.0.1)(ember-inflector@4.0.2)(ember-source@4.12.0) - '@ember-data/serializer': + version: file:packages/model(@babel/core@7.23.5)(@ember-data/debug@4.12.5)(@ember-data/graph@4.12.5)(@ember-data/json-api@4.12.5)(@ember-data/legacy-compat@4.12.5)(@ember-data/store@4.12.5)(@ember-data/tracking@4.12.5)(@ember/string@3.1.1)(ember-inflector@4.0.2)(ember-source@5.4.0) + '@ember-data/private-build-infra': specifier: workspace:4.12.5 - version: file:packages/serializer(@ember-data/store@4.12.5)(@ember/string@3.0.1)(ember-inflector@4.0.2) + version: file:packages/private-build-infra + '@ember-data/request': + specifier: workspace:4.12.5 + version: file:packages/request + '@ember-data/request-utils': + specifier: workspace:4.12.5 + version: file:packages/request-utils + '@ember-data/rest': + specifier: workspace:4.12.5 + version: file:packages/rest(@ember-data/request-utils@4.12.5)(@ember-data/store@4.12.5)(@ember/string@3.1.1)(ember-inflector@4.0.2) '@ember-data/store': specifier: workspace:4.12.5 - version: file:packages/store(@babel/core@7.21.4)(@ember-data/model@4.12.5)(@ember-data/tracking@4.12.5)(@ember/string@3.0.1)(@glimmer/tracking@1.1.2)(ember-source@4.12.0) + version: file:packages/store(@babel/core@7.23.5)(@ember-data/graph@4.12.5)(@ember-data/json-api@4.12.5)(@ember-data/legacy-compat@4.12.5)(@ember-data/model@4.12.5)(@ember-data/tracking@4.12.5)(@ember/string@3.1.1)(@glimmer/tracking@1.1.2)(ember-source@5.4.0) '@ember-data/tracking': specifier: workspace:4.12.5 version: file:packages/tracking '@ember-data/unpublished-test-infra': specifier: workspace:4.12.5 version: file:packages/unpublished-test-infra + '@ember/edition-utils': + specifier: ^1.2.0 + version: 1.2.0 '@ember/optional-features': specifier: ^2.0.0 version: 2.0.0 '@ember/string': - specifier: ^3.0.1 - version: 3.0.1 + specifier: 3.1.1 + version: 3.1.1 '@ember/test-helpers': - specifier: ^2.9.3 - version: 2.9.3(@babel/core@7.21.4)(ember-source@4.12.0) + specifier: ^3.2.0 + version: 3.2.1(ember-source@5.4.0)(webpack@5.89.0) + '@embroider/addon-shim': + specifier: ^1.8.7 + version: 1.8.7 '@glimmer/component': specifier: ^1.1.2 - version: 1.1.2(@babel/core@7.21.4) + version: 1.1.2(@babel/core@7.23.5) '@glimmer/tracking': specifier: ^1.1.2 version: 1.1.2 - broccoli-asset-rev: - specifier: ^3.0.0 - version: 3.0.0 + '@warp-drive/diagnostic': + specifier: workspace:4.12.5 + version: file:packages/diagnostic(@ember/test-helpers@3.2.1)(@embroider/addon-shim@1.8.7)(ember-cli-test-loader@3.1.0) + '@warp-drive/internal-config': + specifier: workspace:4.12.5 + version: link:../../packages/config ember-auto-import: specifier: ^2.6.1 - version: 2.6.1(webpack@5.77.0) + version: 2.6.1(webpack@5.89.0) ember-cli: - specifier: ~4.11.0 - version: 4.11.0 - ember-cli-app-version: - specifier: ^6.0.0 - version: 6.0.0(ember-source@4.12.0) + specifier: ~5.4.1 + version: 5.4.1 ember-cli-babel: specifier: ^7.26.11 version: 7.26.11 ember-cli-dependency-checker: - specifier: ^3.3.1 - version: 3.3.1(ember-cli@4.11.0) + specifier: ^3.3.2 + version: 3.3.2(ember-cli@5.4.1) ember-cli-htmlbars: specifier: ^6.2.0 version: 6.2.0 ember-cli-inject-live-reload: specifier: ^2.1.0 version: 2.1.0 - ember-export-application-global: - specifier: ^2.0.1 - version: 2.0.1 + ember-cli-test-loader: + specifier: ^3.1.0 + version: 3.1.0 + ember-disable-prototype-extensions: + specifier: ^1.1.3 + version: 1.1.3 ember-inflector: specifier: ^4.0.2 version: 4.0.2 ember-load-initializers: specifier: ^2.1.2 - version: 2.1.2(@babel/core@7.21.4) + version: 2.1.2(@babel/core@7.23.5) ember-maybe-import-regenerator: specifier: ^1.0.0 version: 1.0.0 - ember-qunit: - specifier: ^6.2.0 - version: 6.2.0(@ember/test-helpers@2.9.3)(ember-source@4.12.0)(qunit@2.19.4)(webpack@5.77.0) ember-resolver: - specifier: ^10.0.0 - version: 10.0.0(@ember/string@3.0.1)(ember-source@4.12.0) + specifier: ^11.0.1 + version: 11.0.1(ember-source@5.4.0) ember-source: - specifier: ~4.12.0 - version: 4.12.0(@babel/core@7.21.4)(@glimmer/component@1.1.2)(webpack@5.77.0) + specifier: ~5.4.0 + version: 5.4.0(@babel/core@7.23.5)(@glimmer/component@1.1.2)(webpack@5.89.0) + ember-source-channel-url: + specifier: ^3.0.0 + version: 3.0.0 loader.js: specifier: ^4.7.0 version: 4.7.0 - qunit: - specifier: ^2.19.4 - version: 2.19.4 - qunit-dom: - specifier: ^2.0.0 - version: 2.0.0 + silent-error: + specifier: ^1.1.1 + version: 1.1.1 + typescript: + specifier: ^5.3.2 + version: 5.3.3 webpack: - specifier: ^5.77.0 - version: 5.77.0 + specifier: ^5.89.0 + version: 5.89.0 + dependenciesMeta: + '@ember-data/active-record': + injected: true + '@ember-data/debug': + injected: true + '@ember-data/graph': + injected: true + '@ember-data/json-api': + injected: true + '@ember-data/legacy-compat': + injected: true + '@ember-data/model': + injected: true + '@ember-data/private-build-infra': + injected: true + '@ember-data/request': + injected: true + '@ember-data/request-utils': + injected: true + '@ember-data/rest': + injected: true + '@ember-data/store': + injected: true + '@ember-data/tracking': + injected: true + '@ember-data/unpublished-test-infra': + injected: true + '@ember/string': + injected: true + '@warp-drive/diagnostic': + injected: true + ember-inflector: + injected: true + + tests/debug-encapsulation: + devDependencies: + '@babel/core': + specifier: ^7.21.4 + version: 7.21.4 + '@babel/runtime': + specifier: ^7.21.0 + version: 7.21.0 + '@ember-data/adapter': + specifier: workspace:4.12.5 + version: file:packages/adapter(@ember-data/store@4.12.5)(@ember/string@3.0.1)(ember-inflector@4.0.2) + '@ember-data/model': + specifier: workspace:4.12.5 + version: file:packages/model(@babel/core@7.21.4)(@ember-data/store@4.12.5)(@ember-data/tracking@4.12.5)(@ember/string@3.0.1)(ember-inflector@4.0.2)(ember-source@4.12.0) + '@ember-data/serializer': + specifier: workspace:4.12.5 + version: file:packages/serializer(@ember-data/store@4.12.5)(@ember/string@3.0.1)(ember-inflector@4.0.2) + '@ember-data/store': + specifier: workspace:4.12.5 + version: file:packages/store(@babel/core@7.21.4)(@ember-data/model@4.12.5)(@ember-data/tracking@4.12.5)(@ember/string@3.0.1)(@glimmer/tracking@1.1.2)(ember-source@4.12.0) + '@ember-data/tracking': + specifier: workspace:4.12.5 + version: file:packages/tracking + '@ember-data/unpublished-test-infra': + specifier: workspace:4.12.5 + version: file:packages/unpublished-test-infra + '@ember/optional-features': + specifier: ^2.0.0 + version: 2.0.0 + '@ember/string': + specifier: ^3.0.1 + version: 3.0.1 + '@ember/test-helpers': + specifier: ^2.9.3 + version: 2.9.3(@babel/core@7.21.4)(ember-source@4.12.0) + '@glimmer/component': + specifier: ^1.1.2 + version: 1.1.2(@babel/core@7.21.4) + '@glimmer/tracking': + specifier: ^1.1.2 + version: 1.1.2 + broccoli-asset-rev: + specifier: ^3.0.0 + version: 3.0.0 + ember-auto-import: + specifier: ^2.6.1 + version: 2.6.1(webpack@5.77.0) + ember-cli: + specifier: ~4.11.0 + version: 4.11.0 + ember-cli-app-version: + specifier: ^6.0.0 + version: 6.0.0(ember-source@4.12.0) + ember-cli-babel: + specifier: ^7.26.11 + version: 7.26.11 + ember-cli-dependency-checker: + specifier: ^3.3.1 + version: 3.3.1(ember-cli@4.11.0) + ember-cli-htmlbars: + specifier: ^6.2.0 + version: 6.2.0 + ember-cli-inject-live-reload: + specifier: ^2.1.0 + version: 2.1.0 + ember-export-application-global: + specifier: ^2.0.1 + version: 2.0.1 + ember-inflector: + specifier: ^4.0.2 + version: 4.0.2 + ember-load-initializers: + specifier: ^2.1.2 + version: 2.1.2(@babel/core@7.21.4) + ember-maybe-import-regenerator: + specifier: ^1.0.0 + version: 1.0.0 + ember-qunit: + specifier: ^6.2.0 + version: 6.2.0(@ember/test-helpers@2.9.3)(ember-source@4.12.0)(qunit@2.19.4)(webpack@5.77.0) + ember-resolver: + specifier: ^10.0.0 + version: 10.0.0(@ember/string@3.0.1)(ember-source@4.12.0) + ember-source: + specifier: ~4.12.0 + version: 4.12.0(@babel/core@7.21.4)(@glimmer/component@1.1.2)(webpack@5.77.0) + loader.js: + specifier: ^4.7.0 + version: 4.7.0 + qunit: + specifier: ^2.19.4 + version: 2.19.4 + qunit-dom: + specifier: ^2.0.0 + version: 2.0.0 + webpack: + specifier: ^5.77.0 + version: 5.77.0 dependenciesMeta: '@ember-data/adapter': injected: true @@ -1545,7 +2080,7 @@ importers: version: 4.0.3(@babel/core@7.21.4) '@types/ember-qunit': specifier: ^5.0.2 - version: 5.0.2(@babel/core@7.21.4)(ember-source@4.12.0) + version: 5.0.2(@babel/core@7.21.4)(ember-source@4.12.0)(webpack@5.77.0) '@types/ember-testing-helpers': specifier: ^0.0.4 version: 0.0.4 @@ -1662,7 +2197,7 @@ importers: version: 4.0.3(@babel/core@7.21.4) '@types/ember-qunit': specifier: ^5.0.2 - version: 5.0.2(@babel/core@7.21.4)(ember-source@4.12.0) + version: 5.0.2(@babel/core@7.21.4)(ember-source@4.12.0)(webpack@5.77.0) '@types/ember-testing-helpers': specifier: ^0.0.4 version: 0.0.4 @@ -2284,7 +2819,7 @@ importers: version: 4.0.3(@babel/core@7.21.4) '@types/ember-qunit': specifier: ^5.0.2 - version: 5.0.2(@babel/core@7.21.4)(ember-source@4.12.0) + version: 5.0.2(@babel/core@7.21.4)(ember-source@4.12.0)(webpack@5.77.0) '@types/ember-testing-helpers': specifier: ^0.0.4 version: 0.0.4 @@ -2872,6 +3407,11 @@ importers: packages: + /@aashutoshrathi/word-wrap@1.2.6: + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + dev: false + /@ampproject/remapping@2.2.0: resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} engines: {node: '>=6.0.0'} @@ -2899,6 +3439,26 @@ packages: chokidar: 3.5.3 dev: true + /@babel/cli@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-j3luA9xGKCXVyCa5R7lJvOMM+Kc2JEnAEIgz2ggtjQ/j5YUVgfsg/WsG95bbsgq7YLHuiCOzMnoSasuY16qiCw==} + engines: {node: '>=6.9.0'} + hasBin: true + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@jridgewell/trace-mapping': 0.3.17 + commander: 4.1.1 + convert-source-map: 2.0.0 + fs-readdir-recursive: 1.1.0 + glob: 7.2.3 + make-dir: 2.1.0 + slash: 2.0.0 + optionalDependencies: + '@nicolo-ribaudo/chokidar-2': 2.1.8-no-fsevents.3 + chokidar: 3.5.3 + dev: true + /@babel/code-frame@7.18.6: resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} engines: {node: '>=6.9.0'} @@ -2912,10 +3472,21 @@ packages: dependencies: '@babel/highlight': 7.18.6 + /@babel/code-frame@7.23.5: + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.23.4 + chalk: 2.4.2 + /@babel/compat-data@7.21.4: resolution: {integrity: sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==} engines: {node: '>=6.9.0'} + /@babel/compat-data@7.23.5: + resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} + engines: {node: '>=6.9.0'} + /@babel/core@7.21.4: resolution: {integrity: sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==} engines: {node: '>=6.9.0'} @@ -2938,25 +3509,47 @@ packages: transitivePeerDependencies: - supports-color - /@babel/core@7.21.4(supports-color@8.1.1): - resolution: {integrity: sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==} + /@babel/core@7.23.5: + resolution: {integrity: sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.0 - '@babel/code-frame': 7.21.4 - '@babel/generator': 7.21.4 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.4) - '@babel/helper-module-transforms': 7.21.2(supports-color@8.1.1) - '@babel/helpers': 7.21.0(supports-color@8.1.1) - '@babel/parser': 7.21.4 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.4(supports-color@8.1.1) - '@babel/types': 7.21.4 - convert-source-map: 1.9.0 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.5 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.5) + '@babel/helpers': 7.23.5 + '@babel/parser': 7.23.5 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.5 + '@babel/types': 7.23.5 + convert-source-map: 2.0.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + /@babel/core@7.23.5(supports-color@8.1.1): + resolution: {integrity: sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.0 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.5 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.5) + '@babel/helpers': 7.23.5(supports-color@8.1.1) + '@babel/parser': 7.23.5 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.5(supports-color@8.1.1) + '@babel/types': 7.23.5 + convert-source-map: 2.0.0 debug: 4.3.4(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 - semver: 6.3.0 + semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true @@ -2975,6 +3568,20 @@ packages: semver: 6.3.0 dev: true + /@babel/eslint-parser@7.23.3(@babel/core@7.23.5)(eslint@8.55.0): + resolution: {integrity: sha512-9bTuNlyx7oSstodm1cR1bECj4fkiknsDa1YniISkJemMY3DGhJNYBECbe6QD/q54mp2J8VO66jW3/7uP//iFCw==} + engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} + peerDependencies: + '@babel/core': ^7.11.0 + eslint: ^7.5.0 || ^8.0.0 + dependencies: + '@babel/core': 7.23.5 + '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 + eslint: 8.55.0 + eslint-visitor-keys: 2.1.0 + semver: 6.3.1 + dev: false + /@babel/generator@7.21.4: resolution: {integrity: sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==} engines: {node: '>=6.9.0'} @@ -2984,18 +3591,40 @@ packages: '@jridgewell/trace-mapping': 0.3.17 jsesc: 2.5.2 + /@babel/generator@7.23.5: + resolution: {integrity: sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.5 + '@jridgewell/gen-mapping': 0.3.2 + '@jridgewell/trace-mapping': 0.3.17 + jsesc: 2.5.2 + /@babel/helper-annotate-as-pure@7.18.6: resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.4 + '@babel/types': 7.23.5 + + /@babel/helper-annotate-as-pure@7.22.5: + resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.5 /@babel/helper-builder-binary-assignment-operator-visitor@7.18.9: resolution: {integrity: sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-explode-assignable-expression': 7.18.6 - '@babel/types': 7.21.4 + '@babel/types': 7.23.5 + + /@babel/helper-builder-binary-assignment-operator-visitor@7.22.15: + resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.5 + dev: true /@babel/helper-compilation-targets@7.21.4(@babel/core@7.21.4): resolution: {integrity: sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==} @@ -3010,6 +3639,16 @@ packages: lru-cache: 5.1.1 semver: 6.3.0 + /@babel/helper-compilation-targets@7.22.15: + resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.22.2 + lru-cache: 5.1.1 + semver: 6.3.1 + /@babel/helper-create-class-features-plugin@7.21.0(@babel/core@7.21.4): resolution: {integrity: sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==} engines: {node: '>=6.9.0'} @@ -3022,11 +3661,60 @@ packages: '@babel/helper-function-name': 7.21.0 '@babel/helper-member-expression-to-functions': 7.21.0 '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-replace-supers': 7.20.7 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.21.4) '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/helper-split-export-declaration': 7.18.6 - transitivePeerDependencies: - - supports-color + '@babel/helper-split-export-declaration': 7.22.6 + + /@babel/helper-create-class-features-plugin@7.21.0(@babel/core@7.23.5): + resolution: {integrity: sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.21.0 + '@babel/helper-member-expression-to-functions': 7.21.0 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.5) + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + '@babel/helper-split-export-declaration': 7.22.6 + dev: true + + /@babel/helper-create-class-features-plugin@7.23.5(@babel/core@7.21.4): + resolution: {integrity: sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.21.4 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.21.4) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + semver: 6.3.1 + + /@babel/helper-create-class-features-plugin@7.23.5(@babel/core@7.23.5): + resolution: {integrity: sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.5) + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + semver: 6.3.1 /@babel/helper-create-regexp-features-plugin@7.21.0(@babel/core@7.21.4): resolution: {integrity: sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg==} @@ -3035,8 +3723,31 @@ packages: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-annotate-as-pure': 7.22.5 + regexpu-core: 5.3.2 + + /@babel/helper-create-regexp-features-plugin@7.21.0(@babel/core@7.23.5): + resolution: {integrity: sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-annotate-as-pure': 7.22.5 + regexpu-core: 5.3.2 + dev: true + + /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.23.5): + resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-annotate-as-pure': 7.22.5 regexpu-core: 5.3.2 + semver: 6.3.1 + dev: true /@babel/helper-define-polyfill-provider@0.3.3(@babel/core@7.21.4): resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} @@ -3044,49 +3755,87 @@ packages: '@babel/core': ^7.4.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.4) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 debug: 4.3.4 lodash.debounce: 4.0.8 - resolve: 1.22.1 - semver: 6.3.0 + resolve: 1.22.8 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + /@babel/helper-define-polyfill-provider@0.4.3(@babel/core@7.23.5): + resolution: {integrity: sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + debug: 4.3.4 + lodash.debounce: 4.0.8 + resolve: 1.22.8 transitivePeerDependencies: - supports-color + dev: true /@babel/helper-environment-visitor@7.18.9: resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} engines: {node: '>=6.9.0'} + /@babel/helper-environment-visitor@7.22.20: + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} + engines: {node: '>=6.9.0'} + /@babel/helper-explode-assignable-expression@7.18.6: resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.4 + '@babel/types': 7.23.5 /@babel/helper-function-name@7.21.0: resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.20.7 - '@babel/types': 7.21.4 + '@babel/template': 7.22.15 + '@babel/types': 7.23.5 + + /@babel/helper-function-name@7.23.0: + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/types': 7.23.5 /@babel/helper-hoist-variables@7.18.6: resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.4 + '@babel/types': 7.23.5 + + /@babel/helper-hoist-variables@7.22.5: + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.5 /@babel/helper-member-expression-to-functions@7.21.0: resolution: {integrity: sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.4 + '@babel/types': 7.23.5 + + /@babel/helper-member-expression-to-functions@7.23.0: + resolution: {integrity: sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.5 /@babel/helper-module-imports@7.18.6: resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.4 + '@babel/types': 7.23.5 dev: true /@babel/helper-module-imports@7.21.4: @@ -3095,6 +3844,12 @@ packages: dependencies: '@babel/types': 7.21.4 + /@babel/helper-module-imports@7.22.15: + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.5 + /@babel/helper-module-transforms@7.21.2: resolution: {integrity: sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==} engines: {node: '>=6.9.0'} @@ -3110,32 +3865,52 @@ packages: transitivePeerDependencies: - supports-color - /@babel/helper-module-transforms@7.21.2(supports-color@8.1.1): - resolution: {integrity: sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==} + /@babel/helper-module-transforms@7.23.3(@babel/core@7.21.4): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-module-imports': 7.21.4 - '@babel/helper-simple-access': 7.20.2 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/helper-validator-identifier': 7.19.1 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.4(supports-color@8.1.1) - '@babel/types': 7.21.4 - transitivePeerDependencies: - - supports-color - dev: true + '@babel/core': 7.21.4 + '@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-module-transforms@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.5 + '@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: resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.4 + '@babel/types': 7.23.5 + + /@babel/helper-optimise-call-expression@7.22.5: + resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.5 /@babel/helper-plugin-utils@7.20.2: resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} engines: {node: '>=6.9.0'} + /@babel/helper-plugin-utils@7.22.5: + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + engines: {node: '>=6.9.0'} + /@babel/helper-remap-async-to-generator@7.18.9(@babel/core@7.21.4): resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} engines: {node: '>=6.9.0'} @@ -3143,13 +3918,25 @@ packages: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-wrap-function': 7.20.5 - '@babel/types': 7.21.4 + '@babel/types': 7.23.5 transitivePeerDependencies: - supports-color + /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.23.5): + resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-wrap-function': 7.22.20 + dev: true + /@babel/helper-replace-supers@7.20.7: resolution: {integrity: sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==} engines: {node: '>=6.9.0'} @@ -3157,53 +3944,114 @@ packages: '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-member-expression-to-functions': 7.21.0 '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.4 - '@babel/types': 7.21.4 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.5 + '@babel/types': 7.23.5 transitivePeerDependencies: - supports-color + /@babel/helper-replace-supers@7.22.20(@babel/core@7.21.4): + resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.21.4 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + + /@babel/helper-replace-supers@7.22.20(@babel/core@7.23.5): + resolution: {integrity: sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-member-expression-to-functions': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + /@babel/helper-simple-access@7.20.2: resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.4 + '@babel/types': 7.23.5 + + /@babel/helper-simple-access@7.22.5: + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.5 /@babel/helper-skip-transparent-expression-wrappers@7.20.0: resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.4 + '@babel/types': 7.23.5 + + /@babel/helper-skip-transparent-expression-wrappers@7.22.5: + resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.5 /@babel/helper-split-export-declaration@7.18.6: resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.21.4 + '@babel/types': 7.23.5 + + /@babel/helper-split-export-declaration@7.22.6: + resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.5 /@babel/helper-string-parser@7.19.4: resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} engines: {node: '>=6.9.0'} + /@babel/helper-string-parser@7.23.4: + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + engines: {node: '>=6.9.0'} + /@babel/helper-validator-identifier@7.19.1: resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} engines: {node: '>=6.9.0'} + /@babel/helper-validator-identifier@7.22.20: + resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} + engines: {node: '>=6.9.0'} + /@babel/helper-validator-option@7.21.0: resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} engines: {node: '>=6.9.0'} + /@babel/helper-validator-option@7.23.5: + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + engines: {node: '>=6.9.0'} + /@babel/helper-wrap-function@7.20.5: resolution: {integrity: sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-function-name': 7.21.0 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.4 - '@babel/types': 7.21.4 + '@babel/helper-function-name': 7.23.0 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.5 + '@babel/types': 7.23.5 transitivePeerDependencies: - supports-color + /@babel/helper-wrap-function@7.22.20: + resolution: {integrity: sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.23.0 + '@babel/template': 7.22.15 + '@babel/types': 7.23.5 + dev: true + /@babel/helpers@7.21.0: resolution: {integrity: sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==} engines: {node: '>=6.9.0'} @@ -3214,13 +4062,23 @@ packages: transitivePeerDependencies: - supports-color - /@babel/helpers@7.21.0(supports-color@8.1.1): - resolution: {integrity: sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==} + /@babel/helpers@7.23.5: + resolution: {integrity: sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.4(supports-color@8.1.1) - '@babel/types': 7.21.4 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.5 + '@babel/types': 7.23.5 + transitivePeerDependencies: + - supports-color + + /@babel/helpers@7.23.5(supports-color@8.1.1): + resolution: {integrity: sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.5(supports-color@8.1.1) + '@babel/types': 7.23.5 transitivePeerDependencies: - supports-color dev: true @@ -3233,12 +4091,20 @@ packages: chalk: 2.4.2 js-tokens: 4.0.0 + /@babel/highlight@7.23.4: + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + /@babel/parser@7.21.3: resolution: {integrity: sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.21.4 + '@babel/types': 7.23.5 dev: true /@babel/parser@7.21.4: @@ -3248,6 +4114,13 @@ packages: dependencies: '@babel/types': 7.21.4 + /@babel/parser@7.23.5: + resolution: {integrity: sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.5 + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.18.6(@babel/core@7.21.4): resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} engines: {node: '>=6.9.0'} @@ -3255,7 +4128,17 @@ packages: '@babel/core': ^7.0.0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.20.7(@babel/core@7.21.4): resolution: {integrity: sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==} @@ -3264,10 +4147,33 @@ packages: '@babel/core': ^7.13.0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.21.4) + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.23.5) + dev: true + + /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + /@babel/plugin-proposal-async-generator-functions@7.20.7(@babel/core@7.21.4): resolution: {integrity: sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==} engines: {node: '>=6.9.0'} @@ -3276,7 +4182,7 @@ packages: dependencies: '@babel/core': 7.21.4 '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.21.4) '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.21.4) transitivePeerDependencies: @@ -3291,8 +4197,17 @@ packages: '@babel/core': 7.21.4 '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.21.4) '@babel/helper-plugin-utils': 7.20.2 - transitivePeerDependencies: - - supports-color + + /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.23.5): + resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.20.2 + dev: true /@babel/plugin-proposal-class-static-block@7.21.0(@babel/core@7.21.4): resolution: {integrity: sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==} @@ -3301,11 +4216,9 @@ packages: '@babel/core': ^7.12.0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.21.4) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.21.4) + '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.21.4) - transitivePeerDependencies: - - supports-color /@babel/plugin-proposal-decorators@7.21.0(@babel/core@7.21.4): resolution: {integrity: sha512-MfgX49uRrFUTL/HvWtmx3zmpyzMMr4MTj3d527MLlr/4RTT9G/ytFFP7qet2uM2Ve03b+BkpWUpK+lRXnQ+v9w==} @@ -3322,6 +4235,19 @@ packages: transitivePeerDependencies: - supports-color + /@babel/plugin-proposal-decorators@7.23.5(@babel/core@7.23.5): + resolution: {integrity: sha512-6IsY8jOeWibsengGlWIezp7cuZEFzNlAghFpzh9wiZwhQ42/hRcPnY/QV9HJoKTlujupinSlnQPiEy/u2C1ZfQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.5) + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/plugin-syntax-decorators': 7.23.3(@babel/core@7.23.5) + /@babel/plugin-proposal-dynamic-import@7.18.6(@babel/core@7.21.4): resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} engines: {node: '>=6.9.0'} @@ -3329,7 +4255,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.21.4) /@babel/plugin-proposal-export-namespace-from@7.18.9(@babel/core@7.21.4): @@ -3339,7 +4265,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.21.4) /@babel/plugin-proposal-json-strings@7.18.6(@babel/core@7.21.4): @@ -3349,7 +4275,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.21.4) /@babel/plugin-proposal-logical-assignment-operators@7.20.7(@babel/core@7.21.4): @@ -3359,7 +4285,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.21.4) /@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.21.4): @@ -3369,7 +4295,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.21.4) /@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.21.4): @@ -3379,7 +4305,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.21.4) /@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.21.4): @@ -3390,8 +4316,8 @@ packages: dependencies: '@babel/compat-data': 7.21.4 '@babel/core': 7.21.4 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.4) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.21.4) '@babel/plugin-transform-parameters': 7.21.3(@babel/core@7.21.4) @@ -3402,7 +4328,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.21.4) /@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.21.4): @@ -3412,7 +4338,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.21.4) @@ -3425,8 +4351,6 @@ packages: '@babel/core': 7.21.4 '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.21.4) '@babel/helper-plugin-utils': 7.20.2 - transitivePeerDependencies: - - supports-color /@babel/plugin-proposal-private-property-in-object@7.21.0(@babel/core@7.21.4): resolution: {integrity: sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==} @@ -3436,11 +4360,18 @@ packages: dependencies: '@babel/core': 7.21.4 '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.21.4) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.21.4) + '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.21.4) - transitivePeerDependencies: - - supports-color + + /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.5): + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + dev: true /@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.21.4): resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} @@ -3450,7 +4381,7 @@ packages: dependencies: '@babel/core': 7.21.4 '@babel/helper-create-regexp-features-plugin': 7.21.0(@babel/core@7.21.4) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.21.4): resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} @@ -3458,7 +4389,16 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.5): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.21.4): resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} @@ -3466,7 +4406,16 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.5): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.21.4): resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} @@ -3475,7 +4424,17 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.23.5): + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-syntax-decorators@7.21.0(@babel/core@7.21.4): resolution: {integrity: sha512-tIoPpGBR8UuM4++ccWN3gifhVvQu7ZizuR1fklhRJrd5ewgbkUS+0KVFeWWxELtn18NTLoW32XV7zyOgIAiz+w==} @@ -3484,7 +4443,16 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-decorators@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-cf7Niq4/+/juY67E0PbgH0TDhLQ5J7zS8C/Q5FFx+DWyrRa9sUQdTXkjqKu8zGvuqr7vw1muKiukseihU+PJDA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.21.4): resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} @@ -3492,7 +4460,16 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.23.5): + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.21.4): resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} @@ -3500,7 +4477,16 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.23.5): + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-syntax-import-assertions@7.20.0(@babel/core@7.21.4): resolution: {integrity: sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==} @@ -3509,7 +4495,36 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-import-assertions@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-attributes@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.5): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.21.4): resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} @@ -3517,7 +4532,16 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.5): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-syntax-jsx@7.21.4(@babel/core@7.21.4): resolution: {integrity: sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==} @@ -3526,7 +4550,17 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 dev: true /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.21.4): @@ -3535,7 +4569,16 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.5): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.21.4): resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} @@ -3543,15 +4586,33 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.21.4): - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.5): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.21.4): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.5): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.21.4): resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} @@ -3559,7 +4620,16 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.5): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.21.4): resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} @@ -3567,7 +4637,16 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.5): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.21.4): resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} @@ -3575,7 +4654,16 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.5): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.21.4): resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} @@ -3584,7 +4672,17 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.23.5): + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.21.4): resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} @@ -3593,7 +4691,17 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.5): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-syntax-typescript@7.20.0(@babel/core@7.21.4): resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==} @@ -3602,7 +4710,36 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.21.4): + resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.4 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.23.5): + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-create-regexp-features-plugin': 7.21.0(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-transform-arrow-functions@7.20.7(@babel/core@7.21.4): resolution: {integrity: sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==} @@ -3611,7 +4748,30 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-arrow-functions@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-async-generator-functions@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.5) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.5) + dev: true /@babel/plugin-transform-async-to-generator@7.20.7(@babel/core@7.21.4): resolution: {integrity: sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==} @@ -3620,12 +4780,24 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-module-imports': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.21.4) transitivePeerDependencies: - supports-color + /@babel/plugin-transform-async-to-generator@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.23.5) + dev: true + /@babel/plugin-transform-block-scoped-functions@7.18.6(@babel/core@7.21.4): resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} engines: {node: '>=6.9.0'} @@ -3633,7 +4805,17 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-block-scoped-functions@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-transform-block-scoping@7.21.0(@babel/core@7.21.4): resolution: {integrity: sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==} @@ -3644,6 +4826,38 @@ packages: '@babel/core': 7.21.4 '@babel/helper-plugin-utils': 7.20.2 + /@babel/plugin-transform-block-scoping@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-class-properties@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-class-static-block@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.5) + dev: true + /@babel/plugin-transform-classes@7.21.0(@babel/core@7.21.4): resolution: {integrity: sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==} engines: {node: '>=6.9.0'} @@ -3652,16 +4866,32 @@ packages: dependencies: '@babel/core': 7.21.4 '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.4) + '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.21.0 '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.20.7 - '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.21.4) + '@babel/helper-split-export-declaration': 7.22.6 globals: 11.12.0 - transitivePeerDependencies: - - supports-color + + /@babel/plugin-transform-classes@7.23.5(@babel/core@7.23.5): + resolution: {integrity: sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.5) + '@babel/helper-split-export-declaration': 7.22.6 + globals: 11.12.0 + dev: true /@babel/plugin-transform-computed-properties@7.20.7(@babel/core@7.21.4): resolution: {integrity: sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==} @@ -3670,8 +4900,19 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/template': 7.20.7 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/template': 7.22.15 + + /@babel/plugin-transform-computed-properties@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/template': 7.22.15 + dev: true /@babel/plugin-transform-destructuring@7.21.3(@babel/core@7.21.4): resolution: {integrity: sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==} @@ -3680,7 +4921,17 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-destructuring@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-transform-dotall-regex@7.18.6(@babel/core@7.21.4): resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} @@ -3690,7 +4941,18 @@ packages: dependencies: '@babel/core': 7.21.4 '@babel/helper-create-regexp-features-plugin': 7.21.0(@babel/core@7.21.4) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-dotall-regex@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-transform-duplicate-keys@7.18.9(@babel/core@7.21.4): resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} @@ -3699,7 +4961,28 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-duplicate-keys@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-dynamic-import@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.5) + dev: true /@babel/plugin-transform-exponentiation-operator@7.18.6(@babel/core@7.21.4): resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} @@ -3709,7 +4992,29 @@ packages: dependencies: '@babel/core': 7.21.4 '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-exponentiation-operator@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-export-namespace-from@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.5) + dev: true /@babel/plugin-transform-for-of@7.21.0(@babel/core@7.21.4): resolution: {integrity: sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==} @@ -3718,7 +5023,17 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-for-of@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-transform-function-name@7.18.9(@babel/core@7.21.4): resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} @@ -3727,9 +5042,32 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.21.4) + '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-function-name': 7.21.0 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-function-name@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-json-strings@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.5) + dev: true /@babel/plugin-transform-literals@7.18.9(@babel/core@7.21.4): resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} @@ -3738,7 +5076,28 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-literals@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-logical-assignment-operators@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.5) + dev: true /@babel/plugin-transform-member-expression-literals@7.18.6(@babel/core@7.21.4): resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} @@ -3747,7 +5106,17 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-member-expression-literals@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-transform-modules-amd@7.20.11(@babel/core@7.21.4): resolution: {integrity: sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==} @@ -3756,10 +5125,29 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 - transitivePeerDependencies: - - supports-color + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.21.4) + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-modules-amd@7.20.11(@babel/core@7.23.5): + resolution: {integrity: sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-modules-amd@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-transform-modules-commonjs@7.21.2(@babel/core@7.21.4): resolution: {integrity: sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==} @@ -3768,11 +5156,21 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.21.4) + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-simple-access': 7.20.2 - transitivePeerDependencies: - - supports-color + + /@babel/plugin-transform-modules-commonjs@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-simple-access': 7.22.5 + dev: true /@babel/plugin-transform-modules-systemjs@7.20.11(@babel/core@7.21.4): resolution: {integrity: sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==} @@ -3782,63 +5180,206 @@ packages: dependencies: '@babel/core': 7.21.4 '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.21.4) + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-validator-identifier': 7.19.1 - transitivePeerDependencies: - - supports-color - /@babel/plugin-transform-modules-umd@7.18.6(@babel/core@7.21.4): - resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} + /@babel/plugin-transform-modules-systemjs@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-identifier': 7.22.20 + dev: true + + /@babel/plugin-transform-modules-umd@7.18.6(@babel/core@7.21.4): + resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.4 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.21.4) + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-modules-umd@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-named-capturing-groups-regex@7.20.5(@babel/core@7.21.4): + resolution: {integrity: sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.21.4 + '@babel/helper-create-regexp-features-plugin': 7.21.0(@babel/core@7.21.4) + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.23.5): + resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-new-target@7.18.6(@babel/core@7.21.4): + resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.4 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-new-target@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-nullish-coalescing-operator@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.5) + dev: true + + /@babel/plugin-transform-numeric-separator@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.5) + dev: true + + /@babel/plugin-transform-object-rest-spread@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/core': 7.23.5 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.23.5) + dev: true + + /@babel/plugin-transform-object-super@7.18.6(@babel/core@7.21.4): + resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.4 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.21.4) + + /@babel/plugin-transform-object-super@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.5) + dev: true + + /@babel/plugin-transform-optional-catch-binding@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.5) + dev: true + + /@babel/plugin-transform-optional-chaining@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.4 - '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.5) + dev: true - /@babel/plugin-transform-named-capturing-groups-regex@7.20.5(@babel/core@7.21.4): - resolution: {integrity: sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==} + /@babel/plugin-transform-parameters@7.21.3(@babel/core@7.21.4): + resolution: {integrity: sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==} engines: {node: '>=6.9.0'} peerDependencies: - '@babel/core': ^7.0.0 + '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-create-regexp-features-plugin': 7.21.0(@babel/core@7.21.4) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 - /@babel/plugin-transform-new-target@7.18.6(@babel/core@7.21.4): - resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} + /@babel/plugin-transform-parameters@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@babel/plugin-transform-object-super@7.18.6(@babel/core@7.21.4): - resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} + /@babel/plugin-transform-private-methods@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-replace-supers': 7.20.7 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.23.5 + '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true - /@babel/plugin-transform-parameters@7.21.3(@babel/core@7.21.4): - resolution: {integrity: sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==} + /@babel/plugin-transform-private-property-in-object@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.23.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.5) + dev: true /@babel/plugin-transform-property-literals@7.18.6(@babel/core@7.21.4): resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} @@ -3847,7 +5388,17 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-property-literals@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-transform-regenerator@7.20.5(@babel/core@7.21.4): resolution: {integrity: sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==} @@ -3856,9 +5407,20 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 regenerator-transform: 0.15.1 + /@babel/plugin-transform-regenerator@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + regenerator-transform: 0.15.2 + dev: true + /@babel/plugin-transform-reserved-words@7.18.6(@babel/core@7.21.4): resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} engines: {node: '>=6.9.0'} @@ -3866,7 +5428,17 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-reserved-words@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-transform-runtime@7.21.4(@babel/core@7.21.4): resolution: {integrity: sha512-1J4dhrw1h1PqnNNpzwxQ2UBymJUF8KuPjAAnlLwZcGhHAIqUigFW7cdK6GHoB64ubY4qXQNYknoUeks4Wz7CUA==} @@ -3884,6 +5456,23 @@ packages: transitivePeerDependencies: - supports-color + /@babel/plugin-transform-runtime@7.23.4(@babel/core@7.23.5): + resolution: {integrity: sha512-ITwqpb6V4btwUG0YJR82o2QvmWrLgDnx/p2A3CTPYGaRgULkDiC0DRA2C4jlRB9uXGUEfaSS/IGHfVW+ohzYDw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + babel-plugin-polyfill-corejs2: 0.4.6(@babel/core@7.23.5) + babel-plugin-polyfill-corejs3: 0.8.6(@babel/core@7.23.5) + babel-plugin-polyfill-regenerator: 0.5.3(@babel/core@7.23.5) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/plugin-transform-shorthand-properties@7.18.6(@babel/core@7.21.4): resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} engines: {node: '>=6.9.0'} @@ -3891,7 +5480,17 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-shorthand-properties@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-transform-spread@7.20.7(@babel/core@7.21.4): resolution: {integrity: sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==} @@ -3900,9 +5499,20 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + /@babel/plugin-transform-spread@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + dev: true + /@babel/plugin-transform-sticky-regex@7.18.6(@babel/core@7.21.4): resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} engines: {node: '>=6.9.0'} @@ -3910,7 +5520,17 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-sticky-regex@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-transform-template-literals@7.18.9(@babel/core@7.21.4): resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} @@ -3919,7 +5539,17 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-template-literals@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-transform-typeof-symbol@7.18.9(@babel/core@7.21.4): resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} @@ -3928,7 +5558,17 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-typeof-symbol@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-transform-typescript@7.21.3(@babel/core@7.21.4): resolution: {integrity: sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==} @@ -3941,8 +5581,31 @@ packages: '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.21.4) '@babel/helper-plugin-utils': 7.20.2 '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.21.4) - transitivePeerDependencies: - - supports-color + + /@babel/plugin-transform-typescript@7.23.5(@babel/core@7.21.4): + resolution: {integrity: sha512-2fMkXEJkrmwgu2Bsv1Saxgj30IXZdJ+84lQcKKI7sm719oXs0BBw2ZENKdJdR1PjWndgLCEBNXJOri0fk7RYQA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.4 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.21.4) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.21.4) + dev: true + + /@babel/plugin-transform-typescript@7.23.5(@babel/core@7.23.5): + resolution: {integrity: sha512-2fMkXEJkrmwgu2Bsv1Saxgj30IXZdJ+84lQcKKI7sm719oXs0BBw2ZENKdJdR1PjWndgLCEBNXJOri0fk7RYQA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.5) /@babel/plugin-transform-typescript@7.4.5(@babel/core@7.21.4): resolution: {integrity: sha512-RPB/YeGr4ZrFKNwfuQRlMf2lxoCUaU01MTw39/OFE/RiL8HDjtn68BwEPft1P7JN4akyEmjGWAMNldOV7o9V2g==} @@ -3950,8 +5613,18 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.21.4) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.21.4) + + /@babel/plugin-transform-typescript@7.4.5(@babel/core@7.23.5): + resolution: {integrity: sha512-RPB/YeGr4ZrFKNwfuQRlMf2lxoCUaU01MTw39/OFE/RiL8HDjtn68BwEPft1P7JN4akyEmjGWAMNldOV7o9V2g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.5) + dev: true /@babel/plugin-transform-typescript@7.5.5(@babel/core@7.21.4): resolution: {integrity: sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w==} @@ -3959,11 +5632,20 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-create-class-features-plugin': 7.21.0(@babel/core@7.21.4) - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.21.4) - transitivePeerDependencies: - - supports-color + '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.21.4) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.21.4) + + /@babel/plugin-transform-typescript@7.5.5(@babel/core@7.23.5): + resolution: {integrity: sha512-pehKf4m640myZu5B2ZviLaiBlxMCjSZ1qTEO459AXKX5GnPueyulJeCqZFs1nz/Ya2dDzXQ1NxZ/kKNWyD4h6w==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-create-class-features-plugin': 7.23.5(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.23.5) + dev: true /@babel/plugin-transform-unicode-escapes@7.18.10(@babel/core@7.21.4): resolution: {integrity: sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==} @@ -3972,7 +5654,28 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-unicode-escapes@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-property-regex@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/plugin-transform-unicode-regex@7.18.6(@babel/core@7.21.4): resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} @@ -3982,7 +5685,29 @@ packages: dependencies: '@babel/core': 7.21.4 '@babel/helper-create-regexp-features-plugin': 7.21.0(@babel/core@7.21.4) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 + + /@babel/plugin-transform-unicode-regex@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-sets-regex@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.23.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true /@babel/polyfill@7.12.1: resolution: {integrity: sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==} @@ -4076,17 +5801,119 @@ packages: transitivePeerDependencies: - supports-color + /@babel/preset-env@7.23.5(@babel/core@7.23.5): + resolution: {integrity: sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/core': 7.23.5 + '@babel/helper-compilation-targets': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.23.5) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.5) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.5) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.23.5) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-syntax-import-assertions': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-syntax-import-attributes': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.5) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.5) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.5) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.23.5) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.5) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.23.5) + '@babel/plugin-transform-arrow-functions': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-async-generator-functions': 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-async-to-generator': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-block-scoped-functions': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-class-properties': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-class-static-block': 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-classes': 7.23.5(@babel/core@7.23.5) + '@babel/plugin-transform-computed-properties': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-destructuring': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-dotall-regex': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-duplicate-keys': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-dynamic-import': 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-exponentiation-operator': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-export-namespace-from': 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-for-of': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-function-name': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-json-strings': 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-literals': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-logical-assignment-operators': 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-member-expression-literals': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-modules-amd': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-modules-systemjs': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-modules-umd': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.23.5) + '@babel/plugin-transform-new-target': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-nullish-coalescing-operator': 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-numeric-separator': 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-object-rest-spread': 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-object-super': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-optional-catch-binding': 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-private-methods': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-private-property-in-object': 7.23.4(@babel/core@7.23.5) + '@babel/plugin-transform-property-literals': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-regenerator': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-reserved-words': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-shorthand-properties': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-spread': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-sticky-regex': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-template-literals': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-typeof-symbol': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-unicode-escapes': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-unicode-property-regex': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-unicode-regex': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-unicode-sets-regex': 7.23.3(@babel/core@7.23.5) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.23.5) + babel-plugin-polyfill-corejs2: 0.4.6(@babel/core@7.23.5) + babel-plugin-polyfill-corejs3: 0.8.6(@babel/core@7.23.5) + babel-plugin-polyfill-regenerator: 0.5.3(@babel/core@7.23.5) + core-js-compat: 3.34.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/preset-modules@0.1.5(@babel/core@7.21.4): resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.21.4) '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.21.4) - '@babel/types': 7.21.4 + '@babel/types': 7.23.5 + esutils: 2.0.3 + + /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.23.5): + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/types': 7.23.5 esutils: 2.0.3 + dev: true /@babel/preset-typescript@7.21.4(@babel/core@7.21.4): resolution: {integrity: sha512-sMLNWY37TCdRH/bJ6ZeeOH1nPuanED7Ai9Y/vH31IPqalioJ6ZNFUWONsakhv4r4n+I6gm5lmoE0olkgib/j/A==} @@ -4099,9 +5926,21 @@ packages: '@babel/helper-validator-option': 7.21.0 '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.21.4) '@babel/plugin-transform-modules-commonjs': 7.21.2(@babel/core@7.21.4) - '@babel/plugin-transform-typescript': 7.21.3(@babel/core@7.21.4) - transitivePeerDependencies: - - supports-color + '@babel/plugin-transform-typescript': 7.23.5(@babel/core@7.21.4) + dev: true + + /@babel/preset-typescript@7.23.3(@babel/core@7.23.5): + resolution: {integrity: sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-modules-commonjs': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-typescript': 7.23.5(@babel/core@7.23.5) dev: true /@babel/regjsgen@0.8.0: @@ -4118,6 +5957,12 @@ packages: dependencies: regenerator-runtime: 0.13.11 + /@babel/runtime@7.23.5: + resolution: {integrity: sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.0 + /@babel/template@7.20.7: resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} engines: {node: '>=6.9.0'} @@ -4126,18 +5971,26 @@ packages: '@babel/parser': 7.21.4 '@babel/types': 7.21.4 + /@babel/template@7.22.15: + resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.23.5 + '@babel/parser': 7.23.5 + '@babel/types': 7.23.5 + /@babel/traverse@7.21.3: resolution: {integrity: sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.21.4 - '@babel/generator': 7.21.4 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.5 '@babel/helper-environment-visitor': 7.18.9 '@babel/helper-function-name': 7.21.0 '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.21.4 - '@babel/types': 7.21.4 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.23.5 + '@babel/types': 7.23.5 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: @@ -4161,18 +6014,35 @@ packages: transitivePeerDependencies: - supports-color - /@babel/traverse@7.21.4(supports-color@8.1.1): - resolution: {integrity: sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==} + /@babel/traverse@7.23.5: + resolution: {integrity: sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.21.4 - '@babel/generator': 7.21.4 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.21.0 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.21.4 - '@babel/types': 7.21.4 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.5 + '@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.5 + '@babel/types': 7.23.5 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + /@babel/traverse@7.23.5(supports-color@8.1.1): + resolution: {integrity: sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.5 + '@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.5 + '@babel/types': 7.23.5 debug: 4.3.4(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: @@ -4195,6 +6065,14 @@ packages: '@babel/helper-validator-identifier': 7.19.1 to-fast-properties: 2.0.0 + /@babel/types@7.23.5: + resolution: {integrity: sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.23.4 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + /@cnakazawa/watch@1.0.4: resolution: {integrity: sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==} engines: {node: '>=0.1.95'} @@ -4229,33 +6107,102 @@ packages: transitivePeerDependencies: - supports-color - /@ember/string@3.0.1: - resolution: {integrity: sha512-ntnmXS+upOWVXE+rVw2l03DjdMnaGdWbYVUxUBuPJqnIGZu2XFRsoXc7E6mOw62s8i1Xh1RgTuFHN41QGIolEQ==} - engines: {node: 12.* || 14.* || >= 16} + /@ember/string@3.0.1: + resolution: {integrity: sha512-ntnmXS+upOWVXE+rVw2l03DjdMnaGdWbYVUxUBuPJqnIGZu2XFRsoXc7E6mOw62s8i1Xh1RgTuFHN41QGIolEQ==} + engines: {node: 12.* || 14.* || >= 16} + dependencies: + ember-cli-babel: 7.26.11 + transitivePeerDependencies: + - supports-color + + /@ember/string@3.1.1: + resolution: {integrity: sha512-UbXJ+k3QOrYN4SRPHgXCqYIJ+yWWUg1+vr0H4DhdQPTy8LJfyqwZ2tc5uqpSSnEXE+/1KopHBE5J8GDagAg5cg==} + engines: {node: 12.* || 14.* || >= 16} + dependencies: + ember-cli-babel: 7.26.11 + transitivePeerDependencies: + - supports-color + dev: true + + /@ember/test-helpers@2.9.3(@babel/core@7.21.4)(ember-source@4.12.0): + resolution: {integrity: sha512-ejVg4Dj+G/6zyLvQsYOvmGiOLU6AS94tY4ClaO1E2oVvjjtVJIRmVLFN61I+DuyBg9hS3cFoPjQRTZB9MRIbxQ==} + engines: {node: 10.* || 12.* || 14.* || 15.* || >= 16.*} + peerDependencies: + ember-source: '>=3.8.0' + dependencies: + '@ember/test-waiters': 3.0.2 + '@embroider/macros': 1.10.0 + '@embroider/util': 1.10.0(ember-source@4.12.0) + broccoli-debug: 0.6.5 + broccoli-funnel: 3.0.8 + ember-cli-babel: 7.26.11 + ember-cli-htmlbars: 6.2.0 + ember-destroyable-polyfill: 2.0.3(@babel/core@7.21.4) + ember-source: 4.12.0(@babel/core@7.21.4)(@glimmer/component@1.1.2)(webpack@5.77.0) + transitivePeerDependencies: + - '@babel/core' + - '@glint/template' + - supports-color + + /@ember/test-helpers@3.2.1(ember-source@4.12.0)(webpack@5.77.0): + resolution: {integrity: sha512-DvJSihJPV4xshwEgBrFN4aUVc9m/Y/hVzwcslfSVq/h3dMWCyAj4+agkkdJPQrwBaE+H4IyGNzr555S7bTErEA==} + engines: {node: 16.* || >= 18} + peerDependencies: + ember-source: ^4.0.0 || ^5.0.0 + dependencies: + '@ember/test-waiters': 3.0.2 + '@embroider/macros': 1.10.0 + '@simple-dom/interface': 1.4.0 + broccoli-debug: 0.6.5 + broccoli-funnel: 3.0.8 + ember-auto-import: 2.6.1(webpack@5.77.0) + ember-cli-babel: 7.26.11 + ember-cli-htmlbars: 6.2.0 + ember-source: 4.12.0(@babel/core@7.21.4)(@glimmer/component@1.1.2)(webpack@5.77.0) + transitivePeerDependencies: + - supports-color + - webpack + dev: true + + /@ember/test-helpers@3.2.1(ember-source@5.4.0): + resolution: {integrity: sha512-DvJSihJPV4xshwEgBrFN4aUVc9m/Y/hVzwcslfSVq/h3dMWCyAj4+agkkdJPQrwBaE+H4IyGNzr555S7bTErEA==} + engines: {node: 16.* || >= 18} + peerDependencies: + ember-source: ^4.0.0 || ^5.0.0 dependencies: + '@ember/test-waiters': 3.0.2 + '@embroider/macros': 1.10.0 + '@simple-dom/interface': 1.4.0 + broccoli-debug: 0.6.5 + broccoli-funnel: 3.0.8 + ember-auto-import: 2.6.1 ember-cli-babel: 7.26.11 + ember-cli-htmlbars: 6.2.0 + ember-source: 5.4.0(@babel/core@7.23.5)(@glimmer/component@1.1.2) transitivePeerDependencies: - supports-color + - webpack + dev: true - /@ember/test-helpers@2.9.3(@babel/core@7.21.4)(ember-source@4.12.0): - resolution: {integrity: sha512-ejVg4Dj+G/6zyLvQsYOvmGiOLU6AS94tY4ClaO1E2oVvjjtVJIRmVLFN61I+DuyBg9hS3cFoPjQRTZB9MRIbxQ==} - engines: {node: 10.* || 12.* || 14.* || 15.* || >= 16.*} + /@ember/test-helpers@3.2.1(ember-source@5.4.0)(webpack@5.89.0): + resolution: {integrity: sha512-DvJSihJPV4xshwEgBrFN4aUVc9m/Y/hVzwcslfSVq/h3dMWCyAj4+agkkdJPQrwBaE+H4IyGNzr555S7bTErEA==} + engines: {node: 16.* || >= 18} peerDependencies: - ember-source: '>=3.8.0' + ember-source: ^4.0.0 || ^5.0.0 dependencies: '@ember/test-waiters': 3.0.2 '@embroider/macros': 1.10.0 - '@embroider/util': 1.10.0(ember-source@4.12.0) + '@simple-dom/interface': 1.4.0 broccoli-debug: 0.6.5 broccoli-funnel: 3.0.8 + ember-auto-import: 2.6.1(webpack@5.89.0) ember-cli-babel: 7.26.11 ember-cli-htmlbars: 6.2.0 - ember-destroyable-polyfill: 2.0.3(@babel/core@7.21.4) - ember-source: 4.12.0(@babel/core@7.21.4)(@glimmer/component@1.1.2)(webpack@5.77.0) + ember-source: 5.4.0(@babel/core@7.23.5)(@glimmer/component@1.1.2)(webpack@5.89.0) transitivePeerDependencies: - - '@babel/core' - - '@glint/template' - supports-color + - webpack + dev: true /@ember/test-waiters@3.0.2: resolution: {integrity: sha512-H8Q3Xy9rlqhDKnQpwt2pzAYDouww4TZIGSI1pZJhM7mQIGufQKuB0ijzn/yugA6Z+bNdjYp1HioP8Y4hn2zazQ==} @@ -4290,15 +6237,48 @@ packages: - utf-8-validate dev: true + /@embroider/addon-dev@4.1.2(rollup@4.6.1): + resolution: {integrity: sha512-yvL5Vmfh6oQ5m6qP83eZIkD6/RUtWIrW46gtAZvAPCm+HzjFTYHDlldzgYOxUa7k1g2mWrfJOtzBRqqBsogoSw==} + engines: {node: 12.* || 14.* || >= 16} + hasBin: true + dependencies: + '@embroider/core': 3.4.2 + '@rollup/pluginutils': 4.2.1 + content-tag: 1.1.2 + fs-extra: 10.1.0 + minimatch: 3.1.2 + rollup-plugin-copy-assets: 2.0.3(rollup@4.6.1) + rollup-plugin-delete: 2.0.0 + walk-sync: 3.0.0 + yargs: 17.7.1 + transitivePeerDependencies: + - bufferutil + - canvas + - rollup + - supports-color + - utf-8-validate + dev: true + + /@embroider/addon-shim@1.8.7: + resolution: {integrity: sha512-JGOQNRj3UR0NdWEg8MsM2eqPLncEwSB1IX+rwntIj22TEKj8biqx7GDgSbeH+ZedijmCh354Hf2c5rthrdzUAw==} + engines: {node: 12.* || 14.* || >= 16} + dependencies: + '@embroider/shared-internals': 2.5.1 + broccoli-funnel: 3.0.8 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + dev: true + /@embroider/babel-loader-8@2.0.0(@embroider/core@2.1.1)(supports-color@8.1.1)(webpack@5.77.0): resolution: {integrity: sha512-a1bLodfox8JEgNHuhiIBIcXJ4b8NNnKWYkMIpJx216pn80Jf1jcFosQpxnqC8hYHrnG0XRKzQ9zJYgJXoa1wfg==} engines: {node: 12.* || 14.* || >= 16} peerDependencies: '@embroider/core': ^2.0.0 dependencies: - '@babel/core': 7.21.4(supports-color@8.1.1) + '@babel/core': 7.23.5(supports-color@8.1.1) '@embroider/core': 2.1.1 - babel-loader: 8.3.0(@babel/core@7.21.4)(webpack@5.77.0) + babel-loader: 8.3.0(@babel/core@7.23.5)(webpack@5.77.0) transitivePeerDependencies: - supports-color - webpack @@ -4312,9 +6292,9 @@ packages: '@embroider/core': ^2.0.0 dependencies: '@babel/code-frame': 7.18.6 - '@babel/core': 7.21.4 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.21.4) - '@babel/preset-env': 7.21.4(@babel/core@7.21.4) + '@babel/core': 7.23.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.5) + '@babel/preset-env': 7.23.5(@babel/core@7.23.5) '@babel/traverse': 7.21.3 '@embroider/core': 2.1.1 '@embroider/macros': 1.10.0 @@ -4359,11 +6339,11 @@ packages: resolution: {integrity: sha512-N4rz+r8WjHYmwprvBYC0iUT4EWNpdDjF7JLl8PEYlWbhXDEJL+Ma/aP78S7spMhIpJX9SHK7nbgNxmZAqAe34A==} engines: {node: 12.* || 14.* || >= 16} dependencies: - '@babel/core': 7.21.4 + '@babel/core': 7.23.5 '@babel/parser': 7.21.3 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.21.4) - '@babel/plugin-transform-runtime': 7.21.4(@babel/core@7.21.4) - '@babel/runtime': 7.21.0 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.23.5) + '@babel/plugin-transform-runtime': 7.23.4(@babel/core@7.23.5) + '@babel/runtime': 7.23.5 '@babel/traverse': 7.21.3 '@embroider/macros': 1.10.0 '@embroider/shared-internals': 2.0.0 @@ -4395,6 +6375,41 @@ packages: - utf-8-validate dev: true + /@embroider/core@3.4.2: + resolution: {integrity: sha512-lHJcUosSgA8v9deZ2a3k/zuQCpu+Rjw1PZ4dOHzdoTN7B9J96IIybw1JVN234sdUJi9VWjpQnvE2uWOD9seRjg==} + engines: {node: 12.* || 14.* || >= 16} + dependencies: + '@babel/core': 7.23.5 + '@babel/parser': 7.23.5 + '@babel/traverse': 7.23.5 + '@embroider/macros': 1.10.0 + '@embroider/shared-internals': 2.5.1 + assert-never: 1.2.1 + babel-plugin-ember-template-compilation: 2.2.1 + broccoli-node-api: 1.7.0 + broccoli-persistent-filter: 3.1.3 + broccoli-plugin: 4.0.7 + broccoli-source: 3.0.1 + debug: 4.3.4 + fast-sourcemap-concat: 1.4.0 + filesize: 10.1.0 + fs-extra: 9.1.0 + fs-tree-diff: 2.0.1 + handlebars: 4.7.7 + js-string-escape: 1.0.1 + jsdom: 16.7.0 + lodash: 4.17.21 + resolve: 1.22.8 + resolve-package-path: 4.0.3 + typescript-memoize: 1.1.1 + walk-sync: 3.0.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + dev: true + /@embroider/hbs-loader@2.0.0(@embroider/core@2.1.1)(webpack@5.77.0): resolution: {integrity: sha512-rWcZyZ3n35LwlPTS6/fYsdHqPWUh4QO/cVTIJOSeLqJCATNTho7tjBXS6pBvV9cZgvqP/Xph/08xjdUyOWUOxQ==} engines: {node: 12.* || 14.* || >= 16} @@ -4431,8 +6446,25 @@ packages: js-string-escape: 1.0.1 lodash: 4.17.21 resolve-package-path: 4.0.3 - semver: 7.3.8 + semver: 7.5.4 + typescript-memoize: 1.1.1 + + /@embroider/shared-internals@2.5.1: + resolution: {integrity: sha512-b+TWDBisH1p6HeTbJIO8pgu1WzfTP0ZSAlZBqjXwOyrS0ZxP1qNYRrEX+IxyzIibEFjXBxeLakiejz3DJvZX5A==} + engines: {node: 12.* || 14.* || >= 16} + dependencies: + babel-import-util: 2.0.1 + debug: 4.3.4 + ember-rfc176-data: 0.3.18 + fs-extra: 9.1.0 + js-string-escape: 1.0.1 + lodash: 4.17.21 + resolve-package-path: 4.0.3 + semver: 7.5.4 typescript-memoize: 1.1.1 + transitivePeerDependencies: + - supports-color + dev: true /@embroider/util@1.10.0(ember-source@4.12.0): resolution: {integrity: sha512-utAFKoq6ajI27jyqjvX3PiGL4m+ZyGVlVNbSbE/nOqi2llRyAkh5ltH1WkIK7jhdwQFJouo1NpOSj9J3/HDa3A==} @@ -4458,14 +6490,14 @@ packages: '@embroider/core': ^2.0.0 webpack: ^5.0.0 dependencies: - '@babel/core': 7.21.4(supports-color@8.1.1) + '@babel/core': 7.23.5(supports-color@8.1.1) '@embroider/babel-loader-8': 2.0.0(@embroider/core@2.1.1)(supports-color@8.1.1)(webpack@5.77.0) '@embroider/core': 2.1.1 '@embroider/hbs-loader': 2.0.0(@embroider/core@2.1.1)(webpack@5.77.0) '@embroider/shared-internals': 2.0.0 '@types/source-map': 0.5.7 '@types/supports-color': 8.1.1 - babel-loader: 8.3.0(@babel/core@7.21.4)(webpack@5.77.0) + babel-loader: 8.3.0(@babel/core@7.23.5)(webpack@5.77.0) babel-preset-env: 1.7.0(supports-color@8.1.1) css-loader: 5.2.7(webpack@5.77.0) csso: 4.2.0 @@ -4494,9 +6526,24 @@ packages: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: eslint: 8.37.0 - eslint-visitor-keys: 3.4.0 + eslint-visitor-keys: 3.4.3 dev: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.55.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.55.0 + eslint-visitor-keys: 3.4.3 + dev: false + + /@eslint-community/regexpp@4.10.0: + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: false + /@eslint-community/regexpp@4.4.1: resolution: {integrity: sha512-BISJ6ZE4xQsuL/FmsyRaiffpq977bMlsKfGHTQrOGFErfByxIe6iZTxPf/00Zon9b9a7iUykfQwejN3s2ZW/Bw==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -4508,7 +6555,7 @@ packages: dependencies: ajv: 6.12.6 debug: 4.3.4 - espree: 9.5.1 + espree: 9.6.1 globals: 13.20.0 ignore: 5.2.4 import-fresh: 3.3.0 @@ -4519,15 +6566,47 @@ packages: - supports-color dev: true + /@eslint/eslintrc@2.1.4: + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.6.1 + globals: 13.20.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: false + /@eslint/js@8.37.0: resolution: {integrity: sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@eslint/js@8.55.0: + resolution: {integrity: sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: false + /@gar/promisify@1.1.3: resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} dev: true + /@glimmer/compiler@0.84.3: + resolution: {integrity: sha512-cj9sGlnvExP9httxY6ZMivJRGulyaZ31DddCYB5h6LxupR4Nk2d1nAJCWPLsvuQJ8qR+eYw0y9aiY/VeT0krpQ==} + dependencies: + '@glimmer/interfaces': 0.84.3 + '@glimmer/syntax': 0.84.3 + '@glimmer/util': 0.84.3 + '@glimmer/wire-format': 0.84.3 + '@simple-dom/interface': 1.4.0 + dev: true + /@glimmer/component@1.1.2(@babel/core@7.21.4): resolution: {integrity: sha512-XyAsEEa4kWOPy+gIdMjJ8XlzA3qrGH55ZDv6nA16ibalCR17k74BI0CztxuRds+Rm6CtbUVgheCVlcCULuqD7A==} engines: {node: 6.* || 8.* || >= 10.*} @@ -4550,18 +6629,147 @@ packages: - '@babel/core' - supports-color + /@glimmer/component@1.1.2(@babel/core@7.23.5): + resolution: {integrity: sha512-XyAsEEa4kWOPy+gIdMjJ8XlzA3qrGH55ZDv6nA16ibalCR17k74BI0CztxuRds+Rm6CtbUVgheCVlcCULuqD7A==} + engines: {node: 6.* || 8.* || >= 10.*} + dependencies: + '@glimmer/di': 0.1.11 + '@glimmer/env': 0.1.7 + '@glimmer/util': 0.44.0 + broccoli-file-creator: 2.1.1 + broccoli-merge-trees: 4.2.0 + ember-cli-babel: 7.26.11 + ember-cli-get-component-path-option: 1.0.0 + ember-cli-is-package-missing: 1.0.0 + ember-cli-normalize-entity-name: 1.0.0 + ember-cli-path-utils: 1.0.0 + ember-cli-string-utils: 1.1.0 + ember-cli-typescript: 3.0.0(@babel/core@7.23.5) + ember-cli-version-checker: 3.1.3 + ember-compatibility-helpers: 1.2.6(@babel/core@7.23.5) + transitivePeerDependencies: + - '@babel/core' + - supports-color + dev: true + + /@glimmer/destroyable@0.84.3: + resolution: {integrity: sha512-4tUw5UR4ntuySPvbcWyCMRjqxMJMV1GewjU3zGq22XvuBVFfq2K9WmuYV9H9FHg8X0MgDwcus+LjxrVSel39Sw==} + dependencies: + '@glimmer/env': 0.1.7 + '@glimmer/global-context': 0.84.3 + '@glimmer/interfaces': 0.84.3 + '@glimmer/util': 0.84.3 + dev: true + /@glimmer/di@0.1.11: resolution: {integrity: sha512-moRwafNDwHTnTHzyyZC9D+mUSvYrs1Ak0tRPjjmCghdoHHIvMshVbEnwKb/1WmW5CUlKc2eL9rlAV32n3GiItg==} + /@glimmer/encoder@0.84.3: + resolution: {integrity: sha512-T99YQDhNC/1rOFgiz8k4uzgzQsQ+r1my+WVXRv26o0r+/yOnKYndrb6WH/E9d+XtBIZbm1yCSm2BMFYelR0Nrg==} + dependencies: + '@glimmer/env': 0.1.7 + '@glimmer/interfaces': 0.84.3 + '@glimmer/vm': 0.84.3 + dev: true + /@glimmer/env@0.1.7: resolution: {integrity: sha512-JKF/a9I9jw6fGoz8kA7LEQslrwJ5jms5CXhu/aqkBWk+PmZ6pTl8mlb/eJ/5ujBGTiQzBhy5AIWF712iA+4/mw==} + /@glimmer/global-context@0.84.3: + resolution: {integrity: sha512-8Oy9Wg5IZxMEeAnVmzD2NkObf89BeHoFSzJgJROE/deutd3rxg83mvlOez4zBBGYwnTb+VGU2LYRpet92egJjA==} + dependencies: + '@glimmer/env': 0.1.7 + dev: true + /@glimmer/interfaces@0.84.3: resolution: {integrity: sha512-dk32ykoNojt0mvEaIW6Vli5MGTbQo58uy3Epj7ahCgTHmWOKuw/0G83f2UmFprRwFx689YTXG38I/vbpltEjzg==} dependencies: '@simple-dom/interface': 1.4.0 dev: true + /@glimmer/low-level@0.78.2: + resolution: {integrity: sha512-0S6TWOOd0fzLLysw1pWZN0TgasaHmYs1Sjz9Til1mTByIXU1S+1rhdyr2veSQPO/aRjPuEQyKXZQHvx23Zax6w==} + dev: true + + /@glimmer/manager@0.84.3: + resolution: {integrity: sha512-FtcwvrQ3HWlGRGChwlXiisMeKf9+XcCkMwVrrO0cxQavT01tIHx40OFtPOhXKGbgXGtRKcJI8XR41aK9t2kvyg==} + dependencies: + '@glimmer/destroyable': 0.84.3 + '@glimmer/env': 0.1.7 + '@glimmer/global-context': 0.84.3 + '@glimmer/interfaces': 0.84.3 + '@glimmer/reference': 0.84.3 + '@glimmer/util': 0.84.3 + '@glimmer/validator': 0.84.3 + dev: true + + /@glimmer/node@0.84.3: + resolution: {integrity: sha512-QXlZjr7X6DDTJ3wiYQIHv2Pq/5sdGeTTW15+U+IosjZuQgvwCPJaeXC2CU8yqgA33yHgMgJpkdvLnPUCPrrhwg==} + dependencies: + '@glimmer/interfaces': 0.84.3 + '@glimmer/runtime': 0.84.3 + '@glimmer/util': 0.84.3 + '@simple-dom/document': 1.4.0 + '@simple-dom/interface': 1.4.0 + dev: true + + /@glimmer/opcode-compiler@0.84.3: + resolution: {integrity: sha512-flUuikKLFL9cekJUA10gJxMRCDjUPb61R3UCl1u69TGN0Nm7FTsMhOsVDtJLeeiAROtPx+NvasPw/6UB1rrdyg==} + dependencies: + '@glimmer/encoder': 0.84.3 + '@glimmer/env': 0.1.7 + '@glimmer/interfaces': 0.84.3 + '@glimmer/reference': 0.84.3 + '@glimmer/util': 0.84.3 + '@glimmer/vm': 0.84.3 + '@glimmer/wire-format': 0.84.3 + dev: true + + /@glimmer/owner@0.84.3: + resolution: {integrity: sha512-ZwA0rU4V8m0z4ncXtWD2QEU6eh61wkKKQUThahPYhfB+JYceVM6Grx7uWeiAxc2v3ncpvbYqIGdnICXDMloxAA==} + dependencies: + '@glimmer/util': 0.84.3 + dev: true + + /@glimmer/program@0.84.3: + resolution: {integrity: sha512-D8z1lP8NEMyzT8gByFsZpmbRThZvGLS0Tl5AngaDbI2FqlcpEV0ujvLTzzgecd9QQ1k3Cd60dTgy/2N2CI82SA==} + dependencies: + '@glimmer/encoder': 0.84.3 + '@glimmer/env': 0.1.7 + '@glimmer/interfaces': 0.84.3 + '@glimmer/manager': 0.84.3 + '@glimmer/opcode-compiler': 0.84.3 + '@glimmer/util': 0.84.3 + dev: true + + /@glimmer/reference@0.84.3: + resolution: {integrity: sha512-lV+p/aWPVC8vUjmlvYVU7WQJsLh319SdXuAWoX/SE3pq340BJlAJiEcAc6q52y9JNhT57gMwtjMX96W5Xcx/qw==} + dependencies: + '@glimmer/env': 0.1.7 + '@glimmer/global-context': 0.84.3 + '@glimmer/interfaces': 0.84.3 + '@glimmer/util': 0.84.3 + '@glimmer/validator': 0.84.3 + dev: true + + /@glimmer/runtime@0.84.3: + resolution: {integrity: sha512-LzlJbPDCUH/wjsgJ5kRImvOkqAImSyVRW37t34n/1Qd3v7ZoI8xVQg92lS+2kHZe030sT49ZwKkEIeVZiBreBw==} + dependencies: + '@glimmer/destroyable': 0.84.3 + '@glimmer/env': 0.1.7 + '@glimmer/global-context': 0.84.3 + '@glimmer/interfaces': 0.84.3 + '@glimmer/low-level': 0.78.2 + '@glimmer/owner': 0.84.3 + '@glimmer/program': 0.84.3 + '@glimmer/reference': 0.84.3 + '@glimmer/util': 0.84.3 + '@glimmer/validator': 0.84.3 + '@glimmer/vm': 0.84.3 + '@glimmer/wire-format': 0.84.3 + '@simple-dom/interface': 1.4.0 + dev: true + /@glimmer/syntax@0.84.3: resolution: {integrity: sha512-ioVbTic6ZisLxqTgRBL2PCjYZTFIwobifCustrozRU2xGDiYvVIL0vt25h2c1ioDsX59UgVlDkIK4YTAQQSd2A==} dependencies: @@ -4591,6 +6799,13 @@ packages: /@glimmer/validator@0.44.0: resolution: {integrity: sha512-i01plR0EgFVz69GDrEuFgq1NheIjZcyTy3c7q+w7d096ddPVeVcRzU3LKaqCfovvLJ+6lJx40j45ecycASUUyw==} + /@glimmer/validator@0.84.3: + resolution: {integrity: sha512-RTBV4TokUB0vI31UC7ikpV7lOYpWUlyqaKV//pRC4pexYMlmqnVhkFrdiimB/R1XyNdUOQUmnIAcdic39NkbhQ==} + dependencies: + '@glimmer/env': 0.1.7 + '@glimmer/global-context': 0.84.3 + dev: true + /@glimmer/vm-babel-plugins@0.84.2(@babel/core@7.21.4): resolution: {integrity: sha512-HS2dEbJ3CgXn56wk/5QdudM7rE3vtNMvPIoG7Rrg+GhkGMNxBCIRxOeEF2g520j9rwlA2LAZFpc7MCDMFbTjNA==} dependencies: @@ -4598,10 +6813,47 @@ packages: transitivePeerDependencies: - '@babel/core' + /@glimmer/vm-babel-plugins@0.84.3(@babel/core@7.23.5): + resolution: {integrity: sha512-fucWuuN7Q9QFB0ODd+PCltcTkmH4fLqYyXGArrfLt/TYN8gLv0yo00mPwFOSY7MWti/MUx88xd20/PycvYtg8w==} + dependencies: + babel-plugin-debug-macros: 0.3.4(@babel/core@7.23.5) + transitivePeerDependencies: + - '@babel/core' + dev: true + + /@glimmer/vm@0.84.3: + resolution: {integrity: sha512-3mBWvQLEbB8We2EwdmuALMT3zQEcE13ItfLJ0wxlSO2uj1uegeHat++mli8RMxeYNqex27DC+VuhHeWVve6Ngg==} + dependencies: + '@glimmer/interfaces': 0.84.3 + '@glimmer/util': 0.84.3 + dev: true + + /@glimmer/wire-format@0.84.3: + resolution: {integrity: sha512-aZVfQhqv4k7tTo2vwjy+b4mAxKt7cHH75JR3zAeCilimApa+yYTYUyY73NDNSUVbelgAlQ5s6vTiMSQ55WwVow==} + dependencies: + '@glimmer/interfaces': 0.84.3 + '@glimmer/util': 0.84.3 + dev: true + + /@gwhitney/detect-indent@7.0.1: + resolution: {integrity: sha512-7bQW+gkKa2kKZPeJf6+c6gFK9ARxQfn+FKy9ScTBppyKRWH2KzsmweXUoklqeEiHiNVWaeP5csIdsNq6w7QhzA==} + engines: {node: '>=12.20'} + /@handlebars/parser@2.0.0: resolution: {integrity: sha512-EP9uEDZv/L5Qh9IWuMUGJRfwhXJ4h1dqKTT4/3+tY0eu7sPis7xh23j61SYUnNF4vqCQvvUXpDo9Bh/+q1zASA==} dev: true + /@humanwhocodes/config-array@0.11.13: + resolution: {integrity: sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 2.0.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: false + /@humanwhocodes/config-array@0.11.8: resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==} engines: {node: '>=10.10.0'} @@ -4616,12 +6868,15 @@ packages: /@humanwhocodes/module-importer@1.0.1: resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - dev: true /@humanwhocodes/object-schema@1.2.1: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} dev: true + /@humanwhocodes/object-schema@2.0.1: + resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} + dev: false + /@jridgewell/gen-mapping@0.1.1: resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} engines: {node: '>=6.0.0'} @@ -4660,6 +6915,13 @@ packages: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 + /@ljharb/through@2.3.11: + resolution: {integrity: sha512-ccfcIDlogiXNq5KcbAwbaO7lMh3Tm1i3khMPYpxlK8hH/W53zN81KM9coerRLOnTGu3nfXIniAmQbRI9OxbC0w==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + dev: true + /@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3: resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==} requiresBuild: true @@ -4670,7 +6932,6 @@ packages: resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} dependencies: eslint-scope: 5.1.1 - dev: true /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -4694,7 +6955,7 @@ packages: resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} dependencies: '@gar/promisify': 1.1.3 - semver: 7.3.8 + semver: 7.5.4 dev: true /@npmcli/move-file@1.1.2: @@ -4706,6 +6967,379 @@ packages: rimraf: 3.0.2 dev: true + /@pnpm/cli-meta@5.0.1: + resolution: {integrity: sha512-s7rVArn3s78w2ZDWC2/NzMaYBzq39QBmo1BQ4+qq1liX+ltSErDyAx3M/wvvJQgc+Ur3dZJYuc9t96roPnW3XQ==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/types': 9.1.0 + load-json-file: 6.2.0 + + /@pnpm/cli-utils@2.0.9(@pnpm/logger@5.0.0): + resolution: {integrity: sha512-mNujOPCopIi4r7D2HJ96hHKPEr/UPuZGruQvPVvjoc/pCP0l+y38xZAT72W2WhEM4Fo/zP8L+6g/zf88qUSbbg==} + engines: {node: '>=16.14'} + peerDependencies: + '@pnpm/logger': ^5.0.0 + dependencies: + '@pnpm/cli-meta': 5.0.1 + '@pnpm/config': 18.4.0(@pnpm/logger@5.0.0) + '@pnpm/default-reporter': 12.2.3(@pnpm/logger@5.0.0) + '@pnpm/error': 5.0.1 + '@pnpm/logger': 5.0.0 + '@pnpm/manifest-utils': 5.0.1(@pnpm/logger@5.0.0) + '@pnpm/package-is-installable': 8.0.2(@pnpm/logger@5.0.0) + '@pnpm/read-project-manifest': 5.0.1 + '@pnpm/types': 9.1.0 + chalk: 4.1.2 + load-json-file: 6.2.0 + + /@pnpm/config.env-replace@1.1.0: + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} + + /@pnpm/config@18.4.0(@pnpm/logger@5.0.0): + resolution: {integrity: sha512-8B4Pw7cnMvO3kYUBZYYIjg6BcGhHwxEEkmBAcqAeF9NM6LmG6F0lFNsOf6XPfHZMx2vUTpZxaWo0FQo1uU2AAw==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/constants': 7.1.0 + '@pnpm/error': 5.0.1 + '@pnpm/git-utils': 1.0.0 + '@pnpm/matcher': 5.0.0 + '@pnpm/npm-conf': 2.2.0 + '@pnpm/pnpmfile': 5.0.7(@pnpm/logger@5.0.0) + '@pnpm/read-project-manifest': 5.0.1 + '@pnpm/types': 9.1.0 + better-path-resolve: 1.0.0 + camelcase: 6.3.0 + camelcase-keys: 6.2.2 + can-write-to-dir: 1.1.1 + is-subdir: 1.2.0 + is-windows: 1.0.2 + normalize-registry-url: 2.0.0 + path-absolute: 1.0.1 + path-name: 1.0.0 + ramda: /@pnpm/ramda@0.28.1 + read-ini-file: 4.0.0 + realpath-missing: 1.1.0 + which: 3.0.1 + transitivePeerDependencies: + - '@pnpm/logger' + + /@pnpm/constants@7.1.0: + resolution: {integrity: sha512-PzpiPtGF+bIrmkNaHgOIfBZw669+rkUtt/5UFzHukiETwI4/+BTYz8FAr+m5Dfuns531Y+fYRFOpB0PdbAU0+w==} + engines: {node: '>=16.14'} + + /@pnpm/constants@7.1.1: + resolution: {integrity: sha512-31pZqMtjwV+Vaq7MaPrT1EoDFSYwye3dp6BiHIGRJmVThCQwySRKM7hCvqqI94epNkqFAAYoWrNynWoRYosGdw==} + engines: {node: '>=16.14'} + + /@pnpm/core-loggers@9.0.1(@pnpm/logger@5.0.0): + resolution: {integrity: sha512-qP/kk6OeLSxqhvA4n6u4XB6evqD9h1w9p4qtdBOVbkZloCK7L9btkSmKNolBoQ3wrOz7WRFfjRekYUSKphMMCg==} + engines: {node: '>=16.14'} + peerDependencies: + '@pnpm/logger': ^5.0.0 + dependencies: + '@pnpm/logger': 5.0.0 + '@pnpm/types': 9.1.0 + + /@pnpm/dedupe.issues-renderer@1.0.0: + resolution: {integrity: sha512-vlo2t1ERLH3vsL1PtlCue6qfpWofN2Pt2bvGIPtN6Y4siCZVwjy9GU3yXJk1wS2+a7qj9plPiobebadJgV/VHw==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/dedupe.types': 1.0.0 + archy: 1.0.0 + chalk: 4.1.2 + + /@pnpm/dedupe.types@1.0.0: + resolution: {integrity: sha512-WGZ5E7aMPwaM+WMFYszTCP3Sms/gE0nLgI37gFnNbaKgAh5R7GojSHCxLgXqjiz0Jwx+Qi9BmdDgN1cJs5XBsg==} + engines: {node: '>=16.14'} + + /@pnpm/default-reporter@12.2.3(@pnpm/logger@5.0.0): + resolution: {integrity: sha512-ALV6AQOcRPJ5bZlcCHDFQ4cEqH2B/2Luu0VYoAoofINgbhNDOKCrV6PkqLvnMQps98k1f7mtn4w/u4r99+qr7g==} + engines: {node: '>=16.14'} + peerDependencies: + '@pnpm/logger': ^5.0.0 + dependencies: + '@pnpm/config': 18.4.0(@pnpm/logger@5.0.0) + '@pnpm/core-loggers': 9.0.1(@pnpm/logger@5.0.0) + '@pnpm/dedupe.issues-renderer': 1.0.0 + '@pnpm/dedupe.types': 1.0.0 + '@pnpm/error': 5.0.1 + '@pnpm/logger': 5.0.0 + '@pnpm/render-peer-issues': 4.0.1 + '@pnpm/types': 9.1.0 + ansi-diff: 1.1.1 + boxen: 5.1.2 + chalk: 4.1.2 + normalize-path: 3.0.0 + pretty-bytes: 5.6.0 + pretty-ms: 7.0.1 + ramda: /@pnpm/ramda@0.28.1 + right-pad: 1.0.1 + rxjs: 7.8.1 + semver: 7.5.4 + stacktracey: 2.1.8 + string-length: 4.0.2 + strip-ansi: 6.0.1 + + /@pnpm/error@5.0.1: + resolution: {integrity: sha512-JQSOeSEqrV6k6+kKgrlSJ7gddJRcjxtNCxSVJRIqwckkGSdSTNpXmKEdGgLlaDuEwElPAZUmLDGSqk5InJ5pMA==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/constants': 7.1.0 + + /@pnpm/error@5.0.2: + resolution: {integrity: sha512-0TEm+tWNYm+9uh6DSKyRbv8pv/6b4NL0PastLvMxIoqZbBZ5Zj1cYi332R9xsSUi31ZOsu2wpgn/bC7DA9hrjg==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/constants': 7.1.1 + + /@pnpm/fetcher-base@14.0.1: + resolution: {integrity: sha512-DXPZ33CrmDQXnYzwvqyP7I0BF0MQELo4ah2JGpXhLhgOdzU+vj7zdKFo2x82L8anrK861IRi01V8o14oATq1vA==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/resolver-base': 10.0.1 + '@pnpm/types': 9.1.0 + '@types/ssri': 7.1.5 + + /@pnpm/find-workspace-dir@6.0.2: + resolution: {integrity: sha512-JSrpQUFCs4vY1D5tOmj7qBb+oE2j/lO6341giEdUpvYf3FijY8CY13l8rPjfHV2y3m//utzl0An+q+qx14S6Nw==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/error': 5.0.2 + find-up: 5.0.0 + + /@pnpm/find-workspace-packages@6.0.9(@pnpm/logger@5.0.0): + resolution: {integrity: sha512-80t6m6w3EfOg5k88CR8Eya6aOJi2uXyYGFSv2Y+3DqGAWD2x6CFLM3kop2Zi1nL9THMYpYF3hLnBRbqcJ8rmRg==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/cli-utils': 2.0.9(@pnpm/logger@5.0.0) + '@pnpm/constants': 7.1.0 + '@pnpm/fs.find-packages': 2.0.1 + '@pnpm/types': 9.1.0 + '@pnpm/util.lex-comparator': 1.0.0 + read-yaml-file: 2.1.0 + transitivePeerDependencies: + - '@pnpm/logger' + + /@pnpm/fs.find-packages@2.0.1: + resolution: {integrity: sha512-QxG4YrnqnFdi9zmGxzUUH7YF6hgFqtPjDmiMlUvPbASSFRIr6mIT1rTynos2cbg0bRGXpLpp+0XtyOMdDGnBnQ==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/read-project-manifest': 5.0.1 + '@pnpm/types': 9.1.0 + '@pnpm/util.lex-comparator': 1.0.0 + fast-glob: 3.2.12 + p-filter: 2.1.0 + + /@pnpm/fs.hard-link-dir@2.0.1(@pnpm/logger@5.0.0): + resolution: {integrity: sha512-ZsNyKG9YV9rZRhubj8bLxnysLg1LUwh0rdlVnp6ScIT9CtAA+C74kx2KK9E4TNofgb3qAbRqU4aKOaAoLmTSjg==} + engines: {node: '>=16.14'} + peerDependencies: + '@pnpm/logger': ^5.0.0 + dependencies: + '@pnpm/logger': 5.0.0 + + /@pnpm/git-utils@1.0.0: + resolution: {integrity: sha512-lUI+XrzOJN4zdPGOGnFUrmtXAXpXi8wD8OI0nWOZmlh+raqbLzC3VkXu1zgaduOK6YonOcnQW88O+ojav1rAdA==} + engines: {node: '>=16.14'} + dependencies: + execa: /safe-execa@0.1.2 + + /@pnpm/graceful-fs@3.0.0: + resolution: {integrity: sha512-72kkqIL2sacOVr6Y6B6xDGjRC4QgTLeIGkw/5XYyeMgMeL9mDE0lonZEOL9JuLS0XPOXQoyDtRCSmUrzAA57LQ==} + engines: {node: '>=16.14'} + dependencies: + graceful-fs: 4.2.11 + + /@pnpm/graceful-fs@3.2.0: + resolution: {integrity: sha512-vRoXJxscDpHak7YE9SqCkzfrayn+Lw+YueOeHIPEqkgokrHeYgYeONoc2kGh0ObHaRtNSsonozVfJ456kxLNvA==} + engines: {node: '>=16.14'} + dependencies: + graceful-fs: 4.2.11 + + /@pnpm/hooks.types@1.0.1: + resolution: {integrity: sha512-Zx2hzwxBKv1RmFzyu4pEVY7QeIGUb54smSSYt8GcJgByn+uMXgwJ7ydv9t2Koc90QTqk8J3P2J+RDrZVIQpVQw==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/lockfile-types': 5.1.0 + '@pnpm/types': 9.1.0 + + /@pnpm/lockfile-types@5.1.0: + resolution: {integrity: sha512-14eYp9iOdJ7SyOIVXomXhbVnc14DEhzMLS3eKqxYxi9LkANUfxx1/pwRiRY/lTiP9RFS+OkIcTm2QiLsmNEctw==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/types': 9.1.0 + + /@pnpm/logger@5.0.0: + resolution: {integrity: sha512-YfcB2QrX+Wx1o6LD1G2Y2fhDhOix/bAY/oAnMpHoNLsKkWIRbt1oKLkIFvxBMzLwAEPqnYWguJrYC+J6i4ywbw==} + engines: {node: '>=12.17'} + dependencies: + bole: 5.0.9 + ndjson: 2.0.0 + + /@pnpm/manifest-utils@5.0.1(@pnpm/logger@5.0.0): + resolution: {integrity: sha512-vQUmd0NQNv1yWEeFA4pjuBCs4AqhaHW4bVpuaD19lHE5J9SCs7iNRDpjnxjTm/qgDgO/hqu/spuAXEbPxR8u0A==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/core-loggers': 9.0.1(@pnpm/logger@5.0.0) + '@pnpm/error': 5.0.1 + '@pnpm/types': 9.1.0 + transitivePeerDependencies: + - '@pnpm/logger' + + /@pnpm/matcher@5.0.0: + resolution: {integrity: sha512-uh+JBmW8XHGwz9x0K0Ok+TtMiu3ghEaqHHm7dqIubitBP8y9Y0LLP6D2fxWblogjpVzSlH3DpDR1Vicuhw9/cQ==} + engines: {node: '>=16.14'} + dependencies: + escape-string-regexp: 4.0.0 + + /@pnpm/network.ca-file@1.0.2: + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} + dependencies: + graceful-fs: 4.2.10 + + /@pnpm/npm-conf@2.2.0: + resolution: {integrity: sha512-roLI1ul/GwzwcfcVpZYPdrgW2W/drLriObl1h+yLF5syc8/5ULWw2ALbCHUWF+4YltIqA3xFSbG4IwyJz37e9g==} + engines: {node: '>=12'} + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + + /@pnpm/package-is-installable@8.0.2(@pnpm/logger@5.0.0): + resolution: {integrity: sha512-eYuqNBjzYf5wXbD4Xm6ZupRPjYxn2sp6mtYL9+bMntx1+yoUlCJABrYcSvbTM7kheoHyHRf+gEQDFKdn5trQ6w==} + engines: {node: '>=16.14'} + peerDependencies: + '@pnpm/logger': ^5.0.0 + dependencies: + '@pnpm/core-loggers': 9.0.1(@pnpm/logger@5.0.0) + '@pnpm/error': 5.0.1 + '@pnpm/logger': 5.0.0 + '@pnpm/types': 9.1.0 + detect-libc: 2.0.2 + execa: /safe-execa@0.1.2 + mem: 8.1.1 + semver: 7.5.4 + + /@pnpm/pnpmfile@5.0.7(@pnpm/logger@5.0.0): + resolution: {integrity: sha512-A8uwamvs9jhf3DYLuGHCngWW8WXEDgcm3nwOeRTWJOOgButgXueIRHcEZPiKgQwy6t116ntimNeW5H3/hjim6w==} + engines: {node: '>=16.14'} + peerDependencies: + '@pnpm/logger': ^5.0.0 + dependencies: + '@pnpm/core-loggers': 9.0.1(@pnpm/logger@5.0.0) + '@pnpm/error': 5.0.1 + '@pnpm/hooks.types': 1.0.1 + '@pnpm/lockfile-types': 5.1.0 + '@pnpm/logger': 5.0.0 + '@pnpm/store-controller-types': 15.0.1 + '@pnpm/types': 9.1.0 + chalk: 4.1.2 + path-absolute: 1.0.1 + + /@pnpm/ramda@0.28.1: + resolution: {integrity: sha512-zcAG+lvU0fMziNeGXpPyCyCJYp5ZVrPElEE4t14jAmViaihohocZ+dDkcRIyAomox8pQsuZnv1EyHR+pOhmUWw==} + + /@pnpm/read-project-manifest@5.0.1: + resolution: {integrity: sha512-MDXuQpYFbabSXzAnqP7VIQqBx5Z1fzOhzB/3YmIXJ+tE7Wue//IR3itMSYlWeaFLo1G5PCJklM2zBdvggRw1nw==} + engines: {node: '>=16.14'} + dependencies: + '@gwhitney/detect-indent': 7.0.1 + '@pnpm/error': 5.0.1 + '@pnpm/graceful-fs': 3.0.0 + '@pnpm/text.comments-parser': 2.0.0 + '@pnpm/types': 9.1.0 + '@pnpm/write-project-manifest': 5.0.1 + fast-deep-equal: 3.1.3 + is-windows: 1.0.2 + json5: 2.2.3 + parse-json: 5.2.0 + read-yaml-file: 2.1.0 + sort-keys: 4.2.0 + strip-bom: 4.0.0 + + /@pnpm/read-project-manifest@5.0.8: + resolution: {integrity: sha512-+L+0j9rc7KL9EeE7v2hu/zVbFEhw/KLiGuFvC4lC0VXTMPyyDwRXL5LP412IelIhaKC/irYOZmyRYgHK93lSZQ==} + engines: {node: '>=16.14'} + dependencies: + '@gwhitney/detect-indent': 7.0.1 + '@pnpm/error': 5.0.2 + '@pnpm/graceful-fs': 3.2.0 + '@pnpm/text.comments-parser': 2.0.0 + '@pnpm/types': 9.4.0 + '@pnpm/write-project-manifest': 5.0.4 + fast-deep-equal: 3.1.3 + is-windows: 1.0.2 + json5: 2.2.3 + lodash.clonedeep: 4.5.0 + parse-json: 5.2.0 + read-yaml-file: 2.1.0 + sort-keys: 4.2.0 + strip-bom: 4.0.0 + + /@pnpm/render-peer-issues@4.0.1: + resolution: {integrity: sha512-+SsNmbBHH7lBsFrs6dQCEWRtT+Bmq9MYxu+xgkXRplyvjSEQmM0h/UduIw5s8ZAlUuQcxNVTvl0b7ul6OPEIwg==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/types': 9.1.0 + archy: 1.0.0 + chalk: 4.1.2 + cli-columns: 4.0.0 + + /@pnpm/resolver-base@10.0.1: + resolution: {integrity: sha512-2yufLOpiPKQyNVLbL3dgoytkDuuURB5yBOrFtafiuZieGZJid2AeHmFfPhU9hNc/ZM1+wqH3EuVHe/1DdEgm4Q==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/types': 9.1.0 + + /@pnpm/store-controller-types@15.0.1: + resolution: {integrity: sha512-S88sR6xhQ1ZDhMRIjhaRBA11N2OIDU2W+60szQLU8e2bw+KgGU60LbcXMunTdRnJskuB9UfDyoN6YuRtETBqYA==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/fetcher-base': 14.0.1 + '@pnpm/resolver-base': 10.0.1 + '@pnpm/types': 9.1.0 + + /@pnpm/text.comments-parser@2.0.0: + resolution: {integrity: sha512-DRWtTmmxQQtuWHf1xPt9bqzCSq8d0MQF5x1kdpCDMLd7xk3nP4To2/OGkPrb8MKbrWsgCNDwXyKCFlEKrAg7fg==} + engines: {node: '>=16.14'} + dependencies: + strip-comments-strings: 1.2.0 + + /@pnpm/types@9.1.0: + resolution: {integrity: sha512-MMPDMLOY17bfNhLhR9Qmq6/2keoocnR5DWXZfZDC4dKXugrMsE1jB6RnuU8swJIo4zyCsMT/iVSAtl/XK+9Z+A==} + engines: {node: '>=16.14'} + + /@pnpm/types@9.4.0: + resolution: {integrity: sha512-IRDuIuNobLRQe0UyY2gbrrTzYS46tTNvOEfL6fOf0Qa8NyxUzeXz946v7fQuQE3LSBf8ENBC5SXhRmDl+mBEqA==} + engines: {node: '>=16.14'} + + /@pnpm/util.lex-comparator@1.0.0: + resolution: {integrity: sha512-3aBQPHntVgk5AweBWZn+1I/fqZ9krK/w01197aYVkAJQGftb+BVWgEepxY5GChjSW12j52XX+CmfynYZ/p0DFQ==} + engines: {node: '>=12.22.0'} + + /@pnpm/write-project-manifest@5.0.1: + resolution: {integrity: sha512-zU4vDfBUx/jUBPmR4CzCqPDOPObb/7iLT3UZvhXSJ8ZXDo9214V6agnJvxQ6bYBcypdiKva0hnb3tmo1chQBYg==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/text.comments-parser': 2.0.0 + '@pnpm/types': 9.1.0 + json5: 2.2.3 + write-file-atomic: 5.0.1 + write-yaml-file: 5.0.0 + + /@pnpm/write-project-manifest@5.0.4: + resolution: {integrity: sha512-6HdLY5oUH0Ks0KfbEKnFc5ZUpnlpfNkyu15L8DMxYizQCBI44A/lSsCpDNvgsTXQKpwRdnfczZYrJ3DVEOb77Q==} + engines: {node: '>=16.14'} + dependencies: + '@pnpm/text.comments-parser': 2.0.0 + '@pnpm/types': 9.4.0 + json5: 2.2.3 + write-file-atomic: 5.0.1 + write-yaml-file: 5.0.0 + /@rollup/plugin-babel@6.0.3(@babel/core@7.21.4)(rollup@3.20.2): resolution: {integrity: sha512-fKImZKppa1A/gX73eg4JGo+8kQr/q1HBQaCGKECZ0v4YBBv3lFqi14+7xyApECzvkLTHCifx+7ntcrvtBIRcpg==} engines: {node: '>=14.0.0'} @@ -4725,6 +7359,25 @@ packages: rollup: 3.20.2 dev: true + /@rollup/plugin-babel@6.0.4(@babel/core@7.23.5)(rollup@4.6.1): + resolution: {integrity: sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@types/babel__core': ^7.1.9 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + '@types/babel__core': + optional: true + rollup: + optional: true + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-module-imports': 7.22.15 + '@rollup/pluginutils': 5.0.2(rollup@4.6.1) + rollup: 4.6.1 + dev: true + /@rollup/plugin-node-resolve@15.0.1(rollup@3.20.2): resolution: {integrity: sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==} engines: {node: '>=14.0.0'} @@ -4743,6 +7396,24 @@ packages: rollup: 3.20.2 dev: true + /@rollup/plugin-node-resolve@15.2.3(rollup@4.6.1): + resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@rollup/pluginutils': 5.0.2(rollup@4.6.1) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-builtin-module: 3.2.1 + is-module: 1.0.0 + resolve: 1.22.1 + rollup: 4.6.1 + dev: true + /@rollup/pluginutils@4.2.1: resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} @@ -4766,6 +7437,117 @@ packages: rollup: 3.20.2 dev: true + /@rollup/pluginutils@5.0.2(rollup@4.6.1): + resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.0 + estree-walker: 2.0.2 + picomatch: 2.3.1 + rollup: 4.6.1 + dev: true + + /@rollup/rollup-android-arm-eabi@4.6.1: + resolution: {integrity: sha512-0WQ0ouLejaUCRsL93GD4uft3rOmB8qoQMU05Kb8CmMtMBe7XUDLAltxVZI1q6byNqEtU7N1ZX1Vw5lIpgulLQA==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-android-arm64@4.6.1: + resolution: {integrity: sha512-1TKm25Rn20vr5aTGGZqo6E4mzPicCUD79k17EgTLAsXc1zysyi4xXKACfUbwyANEPAEIxkzwue6JZ+stYzWUTA==} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-arm64@4.6.1: + resolution: {integrity: sha512-cEXJQY/ZqMACb+nxzDeX9IPLAg7S94xouJJCNVE5BJM8JUEP4HeTF+ti3cmxWeSJo+5D+o8Tc0UAWUkfENdeyw==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-x64@4.6.1: + resolution: {integrity: sha512-LoSU9Xu56isrkV2jLldcKspJ7sSXmZWkAxg7sW/RfF7GS4F5/v4EiqKSMCFbZtDu2Nc1gxxFdQdKwkKS4rwxNg==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.6.1: + resolution: {integrity: sha512-EfI3hzYAy5vFNDqpXsNxXcgRDcFHUWSx5nnRSCKwXuQlI5J9dD84g2Usw81n3FLBNsGCegKGwwTVsSKK9cooSQ==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.6.1: + resolution: {integrity: sha512-9lhc4UZstsegbNLhH0Zu6TqvDfmhGzuCWtcTFXY10VjLLUe4Mr0Ye2L3rrtHaDd/J5+tFMEuo5LTCSCMXWfUKw==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-musl@4.6.1: + resolution: {integrity: sha512-FfoOK1yP5ksX3wwZ4Zk1NgyGHZyuRhf99j64I5oEmirV8EFT7+OhUZEnP+x17lcP/QHJNWGsoJwrz4PJ9fBEXw==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.6.1: + resolution: {integrity: sha512-DNGZvZDO5YF7jN5fX8ZqmGLjZEXIJRdJEdTFMhiyXqyXubBa0WVLDWSNlQ5JR2PNgDbEV1VQowhVRUh+74D+RA==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-musl@4.6.1: + resolution: {integrity: sha512-RkJVNVRM+piYy87HrKmhbexCHg3A6Z6MU0W9GHnJwBQNBeyhCJG9KDce4SAMdicQnpURggSvtbGo9xAWOfSvIQ==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.6.1: + resolution: {integrity: sha512-v2FVT6xfnnmTe3W9bJXl6r5KwJglMK/iRlkKiIFfO6ysKs0rDgz7Cwwf3tjldxQUrHL9INT/1r4VA0n9L/F1vQ==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.6.1: + resolution: {integrity: sha512-YEeOjxRyEjqcWphH9dyLbzgkF8wZSKAKUkldRY6dgNR5oKs2LZazqGB41cWJ4Iqqcy9/zqYgmzBkRoVz3Q9MLw==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-x64-msvc@4.6.1: + resolution: {integrity: sha512-0zfTlFAIhgz8V2G8STq8toAjsYYA6eci1hnXuyOTUFnymrtJwnS6uGKiv3v5UrPZkBlamLvrLV2iiaeqCKzb0A==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@simple-dom/document@1.4.0: resolution: {integrity: sha512-/RUeVH4kuD3rzo5/91+h4Z1meLSLP66eXqpVAw/4aZmYozkeqUkMprq0znL4psX/adEed5cBgiNJcfMz/eKZLg==} dependencies: @@ -4856,25 +7638,25 @@ packages: dependencies: '@types/node': 18.15.10 - /@types/ember-qunit@5.0.2(@babel/core@7.21.4)(ember-source@4.12.0): + /@types/ember-qunit@5.0.2(@babel/core@7.21.4)(ember-source@4.12.0)(webpack@5.77.0): resolution: {integrity: sha512-LXp0Ew4wPhaCMuw49cNDHWs/bROn+Msb4ypMG1t60EMBx0UaEoX0tZlkf5bQJfdD249WZTu5cCtKvl47xbQzxA==} dependencies: '@types/ember-resolver': 5.0.13(@babel/core@7.21.4) '@types/ember__test': 4.0.1(@babel/core@7.21.4) - '@types/ember__test-helpers': 2.9.1(@babel/core@7.21.4)(ember-source@4.12.0) + '@types/ember__test-helpers': 2.9.1(ember-source@4.12.0)(webpack@5.77.0) '@types/qunit': 2.19.4 transitivePeerDependencies: - '@babel/core' - - '@glint/template' - ember-source - supports-color + - webpack dev: true /@types/ember-resolver@5.0.13(@babel/core@7.21.4): resolution: {integrity: sha512-pO964cAPhAaFJoS28M8+b5MzAhQ/tVuNM4GDUIAexheQat36axG2WTG8LQ5ea07MSFPesrRFk2T3z88pfvdYKA==} dependencies: '@types/ember__object': 4.0.5(@babel/core@7.21.4) - '@types/ember__owner': 4.0.3 + '@types/ember__owner': 4.0.8 transitivePeerDependencies: - '@babel/core' - supports-color @@ -4920,7 +7702,7 @@ packages: '@types/ember': 4.0.3(@babel/core@7.21.4) '@types/ember__engine': 4.0.4(@babel/core@7.21.4) '@types/ember__object': 4.0.5(@babel/core@7.21.4) - '@types/ember__owner': 4.0.3 + '@types/ember__owner': 4.0.8 '@types/ember__routing': 4.0.12(@babel/core@7.21.4) transitivePeerDependencies: - '@babel/core' @@ -4966,7 +7748,7 @@ packages: resolution: {integrity: sha512-LvSLFgNlzpbsdb479ohS2szCFwkAsaqPnTjyPML7xFF3r3VGFMQjVNTXQpFYQCKTMAC1FYRX1N6hw/8lpXWHKA==} dependencies: '@types/ember__object': 4.0.5(@babel/core@7.21.4) - '@types/ember__owner': 4.0.3 + '@types/ember__owner': 4.0.8 transitivePeerDependencies: - '@babel/core' - supports-color @@ -4976,7 +7758,7 @@ packages: resolution: {integrity: sha512-dxQf3ESRjTJtCHbd42/ReUpQUAUsn/VtI6+S07jrsgCbAQEr8Qkh/dJpd9Cta8N+DpbY1CUH58D4HxdOC4Ip3A==} dependencies: '@types/ember__object': 4.0.5(@babel/core@7.21.4) - '@types/ember__owner': 4.0.3 + '@types/ember__owner': 4.0.8 transitivePeerDependencies: - '@babel/core' - supports-color @@ -5003,8 +7785,8 @@ packages: - supports-color dev: true - /@types/ember__owner@4.0.3: - resolution: {integrity: sha512-vwVKdLNYKXMOxJXwMnFQh7TkWfkp6berH6Kc/VK8is1bPgaBB7X/c50rjNmM2o7zI5LJSPm1khxcDidfyXnimg==} + /@types/ember__owner@4.0.8: + resolution: {integrity: sha512-rBFFXjJpumFrw/cTNudU5gKIXYs34HoaMpGCfYiZ15tjrlLikW5QVFJqRtU7bOTL/Lj3pMm3xUGmrH8iFI/gyQ==} dev: true /@types/ember__polyfills@4.0.1: @@ -5055,16 +7837,15 @@ packages: resolution: {integrity: sha512-hAxzdJa0zNvZSoHoCbtd0KGt6Dls4Aph9EwdtbUcdnlMiSUtEDUdKTtDbUrysqJjxGBr4vWIdJEqWtZ0/Y8KBw==} dev: true - /@types/ember__test-helpers@2.9.1(@babel/core@7.21.4)(ember-source@4.12.0): + /@types/ember__test-helpers@2.9.1(ember-source@4.12.0)(webpack@5.77.0): resolution: {integrity: sha512-KZ6jYr0ZiQHlklLcfyuy1j+FkvygEayf5mZ9FcaSOahw9ghK3K5TYSRDCuIBELRw//OB/WP9J7v9NduFRNfRgg==} deprecated: This is a stub types definition. @ember/test-helpers provides its own type definitions, so you do not need this installed. dependencies: - '@ember/test-helpers': 2.9.3(@babel/core@7.21.4)(ember-source@4.12.0) + '@ember/test-helpers': 3.2.1(ember-source@4.12.0)(webpack@5.77.0) transitivePeerDependencies: - - '@babel/core' - - '@glint/template' - ember-source - supports-color + - webpack dev: true /@types/ember__test@4.0.1(@babel/core@7.21.4): @@ -5153,9 +7934,11 @@ packages: /@types/json-schema@7.0.11: resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} + /@types/json-schema@7.0.15: + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + /@types/json5@0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - dev: true /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} @@ -5209,6 +7992,10 @@ packages: resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==} dev: true + /@types/semver@7.5.6: + resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} + dev: false + /@types/serve-static@1.15.1: resolution: {integrity: sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==} dependencies: @@ -5226,6 +8013,11 @@ packages: source-map: 0.7.4 dev: true + /@types/ssri@7.1.5: + resolution: {integrity: sha512-odD/56S3B51liILSk5aXJlnYt99S6Rt9EFDDqGtJM26rKHApHcwyU/UoYHrzKkdkHMAIquGWCuHtQTbes+FRQw==} + dependencies: + '@types/node': 18.15.10 + /@types/supports-color@8.1.1: resolution: {integrity: sha512-dPWnWsf+kzIG140B8z2w3fr5D03TLWbOAFQl45xUpI3vcizeXriNR5VYkWZ+WTMsUHqZ9Xlt3hrxGNANFyNQfw==} dev: true @@ -5275,6 +8067,35 @@ packages: - supports-color dev: true + /@typescript-eslint/eslint-plugin@6.13.2(@typescript-eslint/parser@6.13.2)(eslint@8.55.0)(typescript@5.3.3): + resolution: {integrity: sha512-3+9OGAWHhk4O1LlcwLBONbdXsAhLjyCFogJY/cWy2lxdVJ2JrcTF2pTGMaLl2AE7U1l31n8Py4a8bx5DLf/0dQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.10.0 + '@typescript-eslint/parser': 6.13.2(eslint@8.55.0)(typescript@5.3.3) + '@typescript-eslint/scope-manager': 6.13.2 + '@typescript-eslint/type-utils': 6.13.2(eslint@8.55.0)(typescript@5.3.3) + '@typescript-eslint/utils': 6.13.2(eslint@8.55.0)(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.13.2 + debug: 4.3.4 + eslint: 8.55.0 + graphemer: 1.4.0 + ignore: 5.2.4 + natural-compare: 1.4.0 + semver: 7.5.4 + ts-api-utils: 1.0.3(typescript@5.3.3) + typescript: 5.3.3 + transitivePeerDependencies: + - supports-color + dev: false + /@typescript-eslint/parser@5.57.1(eslint@8.37.0)(typescript@5.0.3): resolution: {integrity: sha512-hlA0BLeVSA/wBPKdPGxoVr9Pp6GutGoY380FEhbVi0Ph4WNe8kLvqIRx76RSQt1lynZKfrXKs0/XeEk4zZycuA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -5295,6 +8116,27 @@ packages: - supports-color dev: true + /@typescript-eslint/parser@6.13.2(eslint@8.55.0)(typescript@5.3.3): + resolution: {integrity: sha512-MUkcC+7Wt/QOGeVlM8aGGJZy1XV5YKjTpq9jK6r6/iLsGXhBVaGP5N0UYvFsu9BFlSpwY9kMretzdBH01rkRXg==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 6.13.2 + '@typescript-eslint/types': 6.13.2 + '@typescript-eslint/typescript-estree': 6.13.2(typescript@5.3.3) + '@typescript-eslint/visitor-keys': 6.13.2 + debug: 4.3.4 + eslint: 8.55.0 + typescript: 5.3.3 + transitivePeerDependencies: + - supports-color + dev: false + /@typescript-eslint/scope-manager@5.57.1: resolution: {integrity: sha512-N/RrBwEUKMIYxSKl0oDK5sFVHd6VI7p9K5MyUlVYAY6dyNb/wHUqndkTd3XhpGlXgnQsBkRZuu4f9kAHghvgPw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -5303,6 +8145,14 @@ packages: '@typescript-eslint/visitor-keys': 5.57.1 dev: true + /@typescript-eslint/scope-manager@6.13.2: + resolution: {integrity: sha512-CXQA0xo7z6x13FeDYCgBkjWzNqzBn8RXaE3QVQVIUm74fWJLkJkaHmHdKStrxQllGh6Q4eUGyNpMe0b1hMkXFA==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.13.2 + '@typescript-eslint/visitor-keys': 6.13.2 + dev: false + /@typescript-eslint/type-utils@5.57.1(eslint@8.37.0)(typescript@5.0.3): resolution: {integrity: sha512-/RIPQyx60Pt6ga86hKXesXkJ2WOS4UemFrmmq/7eOyiYjYv/MUSHPlkhU6k9T9W1ytnTJueqASW+wOmW4KrViw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -5323,11 +8173,36 @@ packages: - supports-color dev: true + /@typescript-eslint/type-utils@6.13.2(eslint@8.55.0)(typescript@5.3.3): + resolution: {integrity: sha512-Qr6ssS1GFongzH2qfnWKkAQmMUyZSyOr0W54nZNU1MDfo+U4Mv3XveeLZzadc/yq8iYhQZHYT+eoXJqnACM1tw==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 6.13.2(typescript@5.3.3) + '@typescript-eslint/utils': 6.13.2(eslint@8.55.0)(typescript@5.3.3) + debug: 4.3.4 + eslint: 8.55.0 + ts-api-utils: 1.0.3(typescript@5.3.3) + typescript: 5.3.3 + transitivePeerDependencies: + - supports-color + dev: false + /@typescript-eslint/types@5.57.1: resolution: {integrity: sha512-bSs4LOgyV3bJ08F5RDqO2KXqg3WAdwHCu06zOqcQ6vqbTJizyBhuh1o1ImC69X4bV2g1OJxbH71PJqiO7Y1RuA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@typescript-eslint/types@6.13.2: + resolution: {integrity: sha512-7sxbQ+EMRubQc3wTfTsycgYpSujyVbI1xw+3UMRUcrhSy+pN09y/lWzeKDbvhoqcRbHdc+APLs/PWYi/cisLPg==} + engines: {node: ^16.0.0 || >=18.0.0} + dev: false + /@typescript-eslint/typescript-estree@5.57.1(typescript@5.0.3): resolution: {integrity: sha512-A2MZqD8gNT0qHKbk2wRspg7cHbCDCk2tcqt6ScCFLr5Ru8cn+TCfM786DjPhqwseiS+PrYwcXht5ztpEQ6TFTw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -5342,12 +8217,33 @@ packages: debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.3.8 + semver: 7.5.4 tsutils: 3.21.0(typescript@5.0.3) typescript: 5.0.3 transitivePeerDependencies: - supports-color - dev: true + dev: true + + /@typescript-eslint/typescript-estree@6.13.2(typescript@5.3.3): + resolution: {integrity: sha512-SuD8YLQv6WHnOEtKv8D6HZUzOub855cfPnPMKvdM/Bh1plv1f7Q/0iFUDLKKlxHcEstQnaUU4QZskgQq74t+3w==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 6.13.2 + '@typescript-eslint/visitor-keys': 6.13.2 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.5.4 + ts-api-utils: 1.0.3(typescript@5.3.3) + typescript: 5.3.3 + transitivePeerDependencies: + - supports-color + dev: false /@typescript-eslint/utils@5.57.1(eslint@8.37.0)(typescript@5.0.3): resolution: {integrity: sha512-kN6vzzf9NkEtawECqze6v99LtmDiUJCVpvieTFA1uL7/jDghiJGubGZ5csicYHU1Xoqb3oH/R5cN5df6W41Nfg==} @@ -5363,35 +8259,81 @@ packages: '@typescript-eslint/typescript-estree': 5.57.1(typescript@5.0.3) eslint: 8.37.0 eslint-scope: 5.1.1 - semver: 7.3.8 + semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript dev: true + /@typescript-eslint/utils@6.13.2(eslint@8.55.0)(typescript@5.3.3): + resolution: {integrity: sha512-b9Ptq4eAZUym4idijCRzl61oPCwwREcfDI8xGk751Vhzig5fFZR9CyzDz4Sp/nxSLBYxUPyh4QdIDqWykFhNmQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.6 + '@typescript-eslint/scope-manager': 6.13.2 + '@typescript-eslint/types': 6.13.2 + '@typescript-eslint/typescript-estree': 6.13.2(typescript@5.3.3) + eslint: 8.55.0 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + - typescript + dev: false + /@typescript-eslint/visitor-keys@5.57.1: resolution: {integrity: sha512-RjQrAniDU0CEk5r7iphkm731zKlFiUjvcBS2yHAg8WWqFMCaCrD0rKEVOMUyMMcbGPZ0bPp56srkGWrgfZqLRA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: '@typescript-eslint/types': 5.57.1 - eslint-visitor-keys: 3.4.0 + eslint-visitor-keys: 3.4.3 dev: true + /@typescript-eslint/visitor-keys@6.13.2: + resolution: {integrity: sha512-OGznFs0eAQXJsp+xSd6k/O1UbFi/K/L7WjqeRoFE7vadjAF9y0uppXhYNQNEqygjou782maGClOoZwPqF0Drlw==} + engines: {node: ^16.0.0 || >=18.0.0} + dependencies: + '@typescript-eslint/types': 6.13.2 + eslint-visitor-keys: 3.4.3 + dev: false + + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + dev: false + /@webassemblyjs/ast@1.11.1: resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==} dependencies: '@webassemblyjs/helper-numbers': 1.11.1 '@webassemblyjs/helper-wasm-bytecode': 1.11.1 + /@webassemblyjs/ast@1.11.6: + resolution: {integrity: sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==} + dependencies: + '@webassemblyjs/helper-numbers': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + /@webassemblyjs/floating-point-hex-parser@1.11.1: resolution: {integrity: sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==} + /@webassemblyjs/floating-point-hex-parser@1.11.6: + resolution: {integrity: sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==} + /@webassemblyjs/helper-api-error@1.11.1: resolution: {integrity: sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==} + /@webassemblyjs/helper-api-error@1.11.6: + resolution: {integrity: sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==} + /@webassemblyjs/helper-buffer@1.11.1: resolution: {integrity: sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==} + /@webassemblyjs/helper-buffer@1.11.6: + resolution: {integrity: sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==} + /@webassemblyjs/helper-numbers@1.11.1: resolution: {integrity: sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==} dependencies: @@ -5399,9 +8341,19 @@ packages: '@webassemblyjs/helper-api-error': 1.11.1 '@xtuc/long': 4.2.2 + /@webassemblyjs/helper-numbers@1.11.6: + resolution: {integrity: sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==} + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.11.6 + '@webassemblyjs/helper-api-error': 1.11.6 + '@xtuc/long': 4.2.2 + /@webassemblyjs/helper-wasm-bytecode@1.11.1: resolution: {integrity: sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==} + /@webassemblyjs/helper-wasm-bytecode@1.11.6: + resolution: {integrity: sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==} + /@webassemblyjs/helper-wasm-section@1.11.1: resolution: {integrity: sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==} dependencies: @@ -5410,19 +8362,40 @@ packages: '@webassemblyjs/helper-wasm-bytecode': 1.11.1 '@webassemblyjs/wasm-gen': 1.11.1 + /@webassemblyjs/helper-wasm-section@1.11.6: + resolution: {integrity: sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-buffer': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/wasm-gen': 1.11.6 + /@webassemblyjs/ieee754@1.11.1: resolution: {integrity: sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==} dependencies: '@xtuc/ieee754': 1.2.0 + /@webassemblyjs/ieee754@1.11.6: + resolution: {integrity: sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==} + dependencies: + '@xtuc/ieee754': 1.2.0 + /@webassemblyjs/leb128@1.11.1: resolution: {integrity: sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==} dependencies: '@xtuc/long': 4.2.2 + /@webassemblyjs/leb128@1.11.6: + resolution: {integrity: sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==} + dependencies: + '@xtuc/long': 4.2.2 + /@webassemblyjs/utf8@1.11.1: resolution: {integrity: sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==} + /@webassemblyjs/utf8@1.11.6: + resolution: {integrity: sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==} + /@webassemblyjs/wasm-edit@1.11.1: resolution: {integrity: sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==} dependencies: @@ -5435,6 +8408,18 @@ packages: '@webassemblyjs/wasm-parser': 1.11.1 '@webassemblyjs/wast-printer': 1.11.1 + /@webassemblyjs/wasm-edit@1.11.6: + resolution: {integrity: sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-buffer': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/helper-wasm-section': 1.11.6 + '@webassemblyjs/wasm-gen': 1.11.6 + '@webassemblyjs/wasm-opt': 1.11.6 + '@webassemblyjs/wasm-parser': 1.11.6 + '@webassemblyjs/wast-printer': 1.11.6 + /@webassemblyjs/wasm-gen@1.11.1: resolution: {integrity: sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==} dependencies: @@ -5444,6 +8429,15 @@ packages: '@webassemblyjs/leb128': 1.11.1 '@webassemblyjs/utf8': 1.11.1 + /@webassemblyjs/wasm-gen@1.11.6: + resolution: {integrity: sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ieee754': 1.11.6 + '@webassemblyjs/leb128': 1.11.6 + '@webassemblyjs/utf8': 1.11.6 + /@webassemblyjs/wasm-opt@1.11.1: resolution: {integrity: sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==} dependencies: @@ -5452,6 +8446,14 @@ packages: '@webassemblyjs/wasm-gen': 1.11.1 '@webassemblyjs/wasm-parser': 1.11.1 + /@webassemblyjs/wasm-opt@1.11.6: + resolution: {integrity: sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-buffer': 1.11.6 + '@webassemblyjs/wasm-gen': 1.11.6 + '@webassemblyjs/wasm-parser': 1.11.6 + /@webassemblyjs/wasm-parser@1.11.1: resolution: {integrity: sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==} dependencies: @@ -5462,12 +8464,28 @@ packages: '@webassemblyjs/leb128': 1.11.1 '@webassemblyjs/utf8': 1.11.1 + /@webassemblyjs/wasm-parser@1.11.6: + resolution: {integrity: sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/helper-api-error': 1.11.6 + '@webassemblyjs/helper-wasm-bytecode': 1.11.6 + '@webassemblyjs/ieee754': 1.11.6 + '@webassemblyjs/leb128': 1.11.6 + '@webassemblyjs/utf8': 1.11.6 + /@webassemblyjs/wast-printer@1.11.1: resolution: {integrity: sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==} dependencies: '@webassemblyjs/ast': 1.11.1 '@xtuc/long': 4.2.2 + /@webassemblyjs/wast-printer@1.11.6: + resolution: {integrity: sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==} + dependencies: + '@webassemblyjs/ast': 1.11.6 + '@xtuc/long': 4.2.2 + /@xmldom/xmldom@0.8.6: resolution: {integrity: sha512-uRjjusqpoqfmRkTaNuLJ2VohVr67Q5YwDATW3VU7PfzTj6IRaihGrYI7zckGZjxQPBIp63nfvJbM+Yu5ICh0Bg==} engines: {node: '>=10.0.0'} @@ -5478,6 +8496,13 @@ packages: /@xtuc/long@4.2.2: resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + /@zkochan/which@2.0.3: + resolution: {integrity: sha512-C1ReN7vt2/2O0fyTsx5xnbQuxBrmG5NMSbcIkPKCCfCTJgpZBsuRYzFXHj3nVq8vTfK7vxHUmzfCpSHgO7j4rg==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + /abab@2.0.6: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} dev: true @@ -5506,6 +8531,20 @@ packages: dependencies: acorn: 8.8.2 + /acorn-import-assertions@1.9.0(acorn@8.8.2): + resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + peerDependencies: + acorn: ^8 + dependencies: + acorn: 8.8.2 + + /acorn-jsx@5.3.2(acorn@8.11.2): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.11.2 + /acorn-jsx@5.3.2(acorn@8.8.2): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -5525,6 +8564,11 @@ packages: hasBin: true dev: true + /acorn@8.11.2: + resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} + engines: {node: '>=0.4.0'} + hasBin: true + /acorn@8.8.2: resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} engines: {node: '>=0.4.0'} @@ -5617,11 +8661,21 @@ packages: resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==} engines: {node: '>=0.4.2'} + /ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + dependencies: + string-width: 4.2.3 + /ansi-colors@4.1.1: resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} engines: {node: '>=6'} dev: true + /ansi-diff@1.1.1: + resolution: {integrity: sha512-XnTdFDQzbEewrDx8epWXdw7oqHMvv315vEtfqDiEhhWghIf4++h26c3/FMz7iTLhNrnj56DNIXpbxHZq+3s6qw==} + dependencies: + ansi-split: 1.0.1 + /ansi-escapes@3.2.0: resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==} engines: {node: '>=4'} @@ -5653,6 +8707,11 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + /ansi-split@1.0.1: + resolution: {integrity: sha512-RRxQym4DFtDNmHIkW6aeFVvrXURb11lGAEPXNiryjCe8bK8RsANjzJ0M2aGOkvBYwP4Bl/xZ8ijtr6D3j1x/eg==} + dependencies: + ansi-regex: 3.0.1 + /ansi-styles@2.2.1: resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} engines: {node: '>=0.10.0'} @@ -5701,6 +8760,9 @@ packages: /aproba@2.0.0: resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + /archy@1.0.0: + resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} + /are-we-there-yet@3.0.1: resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -5756,6 +8818,17 @@ packages: is-string: 1.0.7 dev: true + /array-includes@3.1.7: + resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 + is-string: 1.0.7 + dev: false + /array-to-error@1.1.1: resolution: {integrity: sha512-kqcQ8s7uQfg3UViYON3kCMcck3A9exxgq+riVuKy08Mx00VN4EJhK30L2VpjE58LQHKhcE/GRpvbVUhqTvqzGQ==} dependencies: @@ -5772,6 +8845,17 @@ packages: resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} engines: {node: '>=0.10.0'} + /array.prototype.findlastindex@1.2.3: + resolution: {integrity: sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.0 + get-intrinsic: 1.2.2 + dev: false + /array.prototype.flat@1.3.1: resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} engines: {node: '>= 0.4'} @@ -5782,6 +8866,16 @@ packages: es-shim-unscopables: 1.0.0 dev: true + /array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.0 + dev: false + /array.prototype.flatmap@1.3.1: resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==} engines: {node: '>= 0.4'} @@ -5792,6 +8886,33 @@ packages: es-shim-unscopables: 1.0.0 dev: true + /array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.3 + es-shim-unscopables: 1.0.0 + dev: false + + /arraybuffer.prototype.slice@1.0.2: + resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + call-bind: 1.0.5 + define-properties: 1.2.0 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 + is-array-buffer: 3.0.2 + is-shared-array-buffer: 1.0.2 + + /as-table@1.0.55: + resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + dependencies: + printable-characters: 1.0.42 + /asn1@0.1.11: resolution: {integrity: sha512-Fh9zh3G2mZ8qM/kwsiKwL2U2FmXxVsboP4x1mXjnhKHv3SmzaBZoYvxEQJz/YS2gnCgd8xlAVWcZnQyC9qZBsA==} engines: {node: '>=0.4.9'} @@ -6014,6 +9135,11 @@ packages: resolution: {integrity: sha512-PPzUT17eAI18zn6ek1R3sB4Krc/MbnmT1MkZQFmyhjoaEGBVwNABhfVU9+EKcDSKrrOm9OIpGhjxukx1GCiy1g==} engines: {node: '>= 12.*'} + /babel-import-util@2.0.1: + resolution: {integrity: sha512-N1ZfNprtf/37x0R05J0QCW/9pCAcuI+bjZIK9tlu0JEkwEST7ssdD++gxHRbD58AiG5QE5OuNYhRoEFsc1wESw==} + engines: {node: '>= 12.*'} + dev: true + /babel-loader@8.3.0(@babel/core@7.21.4): resolution: {integrity: sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==} engines: {node: '>= 8.9'} @@ -6041,6 +9167,35 @@ packages: schema-utils: 2.7.1 webpack: 5.77.0 + /babel-loader@8.3.0(@babel/core@7.21.4)(webpack@5.89.0): + resolution: {integrity: sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==} + engines: {node: '>= 8.9'} + peerDependencies: + '@babel/core': ^7.0.0 + webpack: '>=2' + dependencies: + '@babel/core': 7.21.4 + find-cache-dir: 3.3.2 + loader-utils: 2.0.4 + make-dir: 3.1.0 + schema-utils: 2.7.1 + webpack: 5.89.0 + + /babel-loader@8.3.0(@babel/core@7.23.5)(webpack@5.77.0): + resolution: {integrity: sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q==} + engines: {node: '>= 8.9'} + peerDependencies: + '@babel/core': ^7.0.0 + webpack: '>=2' + dependencies: + '@babel/core': 7.23.5(supports-color@8.1.1) + find-cache-dir: 3.3.2 + loader-utils: 2.0.4 + make-dir: 3.1.0 + schema-utils: 2.7.1 + webpack: 5.77.0 + dev: true + /babel-messages@6.23.0: resolution: {integrity: sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==} dependencies: @@ -6071,6 +9226,16 @@ packages: '@babel/core': 7.21.4 semver: 5.7.1 + /babel-plugin-debug-macros@0.2.0(@babel/core@7.23.5): + resolution: {integrity: sha512-Wpmw4TbhR3Eq2t3W51eBAQSdKlr+uAyF0GI4GtPfMCD12Y4cIdpKC9l0RjNTH/P9isFypSqqewMPm7//fnZlNA==} + engines: {node: '>=4'} + peerDependencies: + '@babel/core': ^7.0.0-beta.42 + dependencies: + '@babel/core': 7.23.5 + semver: 5.7.1 + dev: true + /babel-plugin-debug-macros@0.3.4(@babel/core@7.21.4): resolution: {integrity: sha512-wfel/vb3pXfwIDZUrkoDrn5FHmlWI96PCJ3UCDv2a86poJ3EQrnArNW5KfHSVJ9IOgxHbo748cQt7sDU+0KCEw==} engines: {node: '>=6'} @@ -6080,6 +9245,15 @@ packages: '@babel/core': 7.21.4 semver: 5.7.1 + /babel-plugin-debug-macros@0.3.4(@babel/core@7.23.5): + resolution: {integrity: sha512-wfel/vb3pXfwIDZUrkoDrn5FHmlWI96PCJ3UCDv2a86poJ3EQrnArNW5KfHSVJ9IOgxHbo748cQt7sDU+0KCEw==} + engines: {node: '>=6'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.5 + semver: 5.7.1 + /babel-plugin-ember-data-packages-polyfill@0.1.2: resolution: {integrity: sha512-kTHnOwoOXfPXi00Z8yAgyD64+jdSXk3pknnS7NlqnCKAU6YDkXZ4Y7irl66kaZjZn0FBBt0P4YOZFZk85jYOww==} engines: {node: 6.* || 8.* || 10.* || >= 12.*} @@ -6098,6 +9272,14 @@ packages: dependencies: babel-import-util: 1.3.0 + /babel-plugin-ember-template-compilation@2.2.1: + resolution: {integrity: sha512-alinprIQcLficqkuIyeKKfD4HQOpMOiHK6pt6Skj/yjoPoQYBuwAJ2BoPAlRe9k/URPeVkpMefbN3m6jEp7RsA==} + engines: {node: '>= 12.*'} + dependencies: + '@glimmer/syntax': 0.84.3 + babel-import-util: 2.0.1 + dev: true + /babel-plugin-filter-imports@4.0.0: resolution: {integrity: sha512-jDLlxI8QnfKd7PtieH6pl4tZJzymzfCDCPGdTq/grgbiYAikwDPp/oL0IlFJn0HQjLpcLkyYhPKkUVneRESw5w==} engines: {node: '>=8'} @@ -6133,7 +9315,7 @@ packages: glob: 7.2.3 pkg-up: 3.1.0 reselect: 4.1.7 - resolve: 1.22.1 + resolve: 1.22.8 /babel-plugin-polyfill-corejs2@0.3.3(@babel/core@7.21.4): resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} @@ -6143,9 +9325,22 @@ packages: '@babel/compat-data': 7.21.4 '@babel/core': 7.21.4 '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.21.4) - semver: 6.3.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + /babel-plugin-polyfill-corejs2@0.4.6(@babel/core@7.23.5): + resolution: {integrity: sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/core': 7.23.5 + '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.5) + semver: 6.3.1 transitivePeerDependencies: - supports-color + dev: true /babel-plugin-polyfill-corejs3@0.6.0(@babel/core@7.21.4): resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} @@ -6158,6 +9353,18 @@ packages: transitivePeerDependencies: - supports-color + /babel-plugin-polyfill-corejs3@0.8.6(@babel/core@7.23.5): + resolution: {integrity: sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.5) + core-js-compat: 3.34.0 + transitivePeerDependencies: + - supports-color + dev: true + /babel-plugin-polyfill-regenerator@0.4.1(@babel/core@7.21.4): resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} peerDependencies: @@ -6168,6 +9375,17 @@ packages: transitivePeerDependencies: - supports-color + /babel-plugin-polyfill-regenerator@0.5.3(@babel/core@7.23.5): + resolution: {integrity: sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + dependencies: + '@babel/core': 7.23.5 + '@babel/helper-define-polyfill-provider': 0.4.3(@babel/core@7.23.5) + transitivePeerDependencies: + - supports-color + dev: true + /babel-plugin-syntax-async-functions@6.13.0: resolution: {integrity: sha512-4Zp4unmHgw30A1eWI5EpACji2qMocisdXhAftfhXoSV9j0Tvj6nRFE3tOmRY912E0FMRm/L5xWE7MGVT2FoLnw==} dev: true @@ -6498,6 +9716,10 @@ packages: dependencies: underscore: 1.13.6 + /backburner.js@2.8.0: + resolution: {integrity: sha512-zYXY0KvpD7/CWeOLF576mV8S+bQsaIoj/GNLXXB+Eb8SJcQy5lqSjkRrZ0MZhdKUs9QoqmGNIEIe3NQfGiiscQ==} + dev: true + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -6526,6 +9748,12 @@ packages: dependencies: safe-buffer: 5.1.2 + /better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + dependencies: + is-windows: 1.0.2 + /big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} @@ -6603,6 +9831,12 @@ packages: raw-body: 1.1.7 safe-json-parse: 1.0.1 + /bole@5.0.9: + resolution: {integrity: sha512-35GeBG6T7GW9VmLDF2IoKAtFCqMjmmq1uICbsICI0pID7ZAyUKlf7dg1wpXmn9GcMKHtg0S19CPMU5yfY3tv+g==} + dependencies: + fast-safe-stringify: 2.1.1 + individual: 3.0.0 + /boom@0.4.2: resolution: {integrity: sha512-OvfN8y1oAxxphzkl2SnCS+ztV/uVKTATtgLjWYg/7KwcNyf3rzpHxNQJZCKtsZd4+MteKczhWbSjtEX4bGgU9g==} engines: {node: '>=0.8.0'} @@ -6627,6 +9861,19 @@ packages: resolution: {integrity: sha512-YWZHhWkPdXtIfH3VRu3QIV95sa75O9vrQWBOHjexWCLBCTy5qJvRr36LXTqFwTchSXVlzy5piYJOjzHr7qhsNg==} engines: {node: '>=0.8.0'} + /boxen@5.1.2: + resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} + engines: {node: '>=10'} + dependencies: + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 2.2.1 + string-width: 4.2.3 + type-fest: 0.20.2 + widest-line: 3.1.0 + wrap-ansi: 7.0.0 + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -6691,7 +9938,7 @@ packages: resolution: {integrity: sha512-6IXBgfRt7HZ61g67ssBc6lBb3Smw3DPZ9dEYirgtvXWpRZ2A9M22nxy6opEwJDgDJzlu/bB7ToppW33OFkA1gA==} engines: {node: '>= 6'} dependencies: - '@babel/core': 7.21.4 + '@babel/core': 7.23.5 '@babel/polyfill': 7.12.1 broccoli-funnel: 3.0.8 broccoli-merge-trees: 4.2.0 @@ -7052,7 +10299,7 @@ packages: ensure-posix-path: 1.1.1 fs-extra: 5.0.0 minimatch: 3.1.2 - resolve: 1.22.1 + resolve: 1.22.8 rsvp: 4.8.5 symlink-or-copy: 1.3.1 walk-sync: 0.3.4 @@ -7224,6 +10471,16 @@ packages: node-releases: 2.0.10 update-browserslist-db: 1.0.10(browserslist@4.21.5) + /browserslist@4.22.2: + resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001566 + electron-to-chromium: 1.4.606 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.22.2) + /bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} dependencies: @@ -7241,12 +10498,15 @@ packages: /builtin-modules@3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} - dev: true /builtins@5.0.1: resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} dependencies: - semver: 7.3.8 + semver: 7.5.4 + + /bun-types@1.0.15: + resolution: {integrity: sha512-XkEvWLV1JIhcVIpf2Lu6FXnZUxRUkQVJmgY+VT7os6Tk5X1nkXx11q4Rtu6txsqpDJZfUeZXblnnD59K+6wsVA==} + dev: true /bytes@1.0.0: resolution: {integrity: sha512-/x68VkHLeTl3/Ll8IvxdwzhrT+IyKc52e/oyHhA2RwqPqswSnjVbSddfPRwAsJtbilMAPSRWwAlpxdYsSWOTKQ==} @@ -7324,14 +10584,32 @@ packages: function-bind: 1.1.1 get-intrinsic: 1.2.0 + /call-bind@1.0.5: + resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} + dependencies: + function-bind: 1.1.2 + get-intrinsic: 1.2.2 + set-function-length: 1.1.1 + /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + /camelcase-keys@6.2.2: + resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + map-obj: 4.3.0 + quick-lru: 4.0.1 + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + /camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - dev: true /can-symlink@1.0.0: resolution: {integrity: sha512-RbsNrFyhwkx+6psk/0fK/Q9orOUr9VMxohGd8vTa4djf4TGLfblBgUfqZChrZuW0Q+mz2eBPFLusw9Jfukzmhg==} @@ -7339,9 +10617,18 @@ packages: dependencies: tmp: 0.0.28 + /can-write-to-dir@1.1.1: + resolution: {integrity: sha512-eOgiEWqjppB+3DN/5E82EQ8dTINus8d9GXMCbEsUnp2hcUIcXmBvzWmD3tXMk3CuBK0v+ddK9qw0EAF+JVRMjQ==} + engines: {node: '>=10.13'} + dependencies: + path-temp: 2.1.0 + /caniuse-lite@1.0.30001470: resolution: {integrity: sha512-065uNwY6QtHCBOExzbV6m236DDhYCCtPmQUCoQtwkVqzud8v5QPidoMr6CoMkC2nfp6nksjttqWQRRh75LqUmA==} + /caniuse-lite@1.0.30001566: + resolution: {integrity: sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA==} + /capture-exit@2.0.0: resolution: {integrity: sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==} engines: {node: 6.* || 8.* || >= 10.*} @@ -7421,6 +10708,14 @@ packages: ansi-styles: 4.3.0 supports-color: 7.2.0 + /chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + /char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + /chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} @@ -7494,6 +10789,17 @@ packages: /clean-up-path@1.0.0: resolution: {integrity: sha512-PHGlEF0Z6976qQyN6gM7kKH6EH0RdfZcc8V+QhFe36eRxV0SMH5OUBZG7Bxa9YcreNzyNbK63cGiZxdSZgosRw==} + /cli-boxes@2.2.1: + resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} + engines: {node: '>=6'} + + /cli-columns@4.0.0: + resolution: {integrity: sha512-XW2Vg+w+L9on9wtwKpyzluIPCWXjaBahI7mTcYjx+BVIYD9c3yqcv/yKC7CmdCZat4rq2yiE1UMSJC5ivKfMtQ==} + engines: {node: '>= 10'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + /cli-cursor@2.1.0: resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==} engines: {node: '>=4'} @@ -7545,6 +10851,11 @@ packages: resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} engines: {node: '>= 10'} + /cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + dev: true + /cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} dependencies: @@ -7560,7 +10871,6 @@ packages: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - dev: true /clone-response@1.0.3: resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} @@ -7688,6 +10998,12 @@ packages: /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + /config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + /configstore@5.0.1: resolution: {integrity: sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==} engines: {node: '>=8'} @@ -7897,6 +11213,10 @@ packages: dependencies: safe-buffer: 5.2.1 + /content-tag@1.1.2: + resolution: {integrity: sha512-AZkfc6TUmW+/RbZJioPzOQPAHHXqyqK4B0GNckJDjBAPK3SyGrMfn21bfFky/qwi5uoLph5sjAHUkO3CL6/IgQ==} + dev: true + /content-type@1.0.5: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} @@ -7907,6 +11227,9 @@ packages: /convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + /cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} @@ -7930,6 +11253,12 @@ packages: dependencies: browserslist: 4.21.5 + /core-js-compat@3.34.0: + resolution: {integrity: sha512-4ZIyeNbW/Cn1wkMMDy+mvrRUxrwFNjKwbhCfQpDd+eLgYipDqp8oGFGtLmhh18EDPKA0g3VUBYOxQGGwvWLVpA==} + dependencies: + browserslist: 4.22.2 + dev: true + /core-js@2.6.12: resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. @@ -7997,7 +11326,7 @@ packages: postcss-modules-values: 4.0.0(postcss@8.4.21) postcss-value-parser: 4.2.0 schema-utils: 3.1.1 - semver: 7.3.8 + semver: 7.5.4 /css-loader@5.2.7(webpack@5.77.0): resolution: {integrity: sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==} @@ -8014,8 +11343,26 @@ packages: postcss-modules-values: 4.0.0(postcss@8.4.21) postcss-value-parser: 4.2.0 schema-utils: 3.1.1 - semver: 7.3.8 - webpack: 5.77.0 + semver: 7.5.4 + webpack: 5.77.0 + + /css-loader@5.2.7(webpack@5.89.0): + resolution: {integrity: sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.27.0 || ^5.0.0 + dependencies: + icss-utils: 5.1.0(postcss@8.4.21) + loader-utils: 2.0.4 + postcss: 8.4.21 + postcss-modules-extract-imports: 3.0.0(postcss@8.4.21) + postcss-modules-local-by-default: 4.0.0(postcss@8.4.21) + postcss-modules-scope: 3.0.0(postcss@8.4.21) + postcss-modules-values: 4.0.0(postcss@8.4.21) + postcss-value-parser: 4.2.0 + schema-utils: 3.1.1 + semver: 7.5.4 + webpack: 5.89.0 /css-tree@1.1.3: resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} @@ -8073,6 +11420,9 @@ packages: /dag-map@2.0.2: resolution: {integrity: sha512-xnsprIzYuDeiyu5zSKwilV/ajRHxnoMlAhEREfyfTgTSViMVY2fGP1ZcHJbtwup26oCkofySU/m6oKJ3HrkW7w==} + /data-uri-to-buffer@2.0.2: + resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} + /data-urls@2.0.0: resolution: {integrity: sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==} engines: {node: '>=10'} @@ -8147,6 +11497,18 @@ packages: supports-color: 8.1.1 dev: true + /debug@4.3.4(supports-color@9.4.0): + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + supports-color: 9.4.0 + /decamelize@4.0.0: resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} engines: {node: '>=10'} @@ -8185,7 +11547,6 @@ packages: /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dev: true /deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} @@ -8201,6 +11562,14 @@ packages: resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==} dev: true + /define-data-property@1.1.1: + resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.0 + /define-properties@1.2.0: resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} engines: {node: '>= 0.4'} @@ -8275,10 +11644,17 @@ packages: resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} engines: {node: '>=8'} + /detect-libc@2.0.2: + resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} + engines: {node: '>=8'} + /detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} + /dettle@1.0.1: + resolution: {integrity: sha512-/oD3At60ZfhgzpofJtyClNTrIACyMdRe+ih0YiHzAniN0IZnLdLpEzgR6RtGs3kowxUkTnvV/4t1FBxXMUdusQ==} + /diff@5.0.0: resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} engines: {node: '>=0.3.1'} @@ -8299,14 +11675,12 @@ packages: engines: {node: '>=0.10.0'} dependencies: esutils: 2.0.3 - dev: true /doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} dependencies: esutils: 2.0.3 - dev: true /domexception@2.0.1: resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==} @@ -8348,7 +11722,7 @@ packages: engines: {node: '>=0.8'} dependencies: errlop: 2.2.0 - semver: 6.3.0 + semver: 6.3.1 /ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -8356,6 +11730,9 @@ packages: /electron-to-chromium@1.4.340: resolution: {integrity: sha512-zx8hqumOqltKsv/MF50yvdAlPF9S/4PXbyfzJS6ZGhbddGkRegdwImmfSVqCkEziYzrIGZ/TlrzBND4FysfkDg==} + /electron-to-chromium@1.4.606: + resolution: {integrity: sha512-Zdv0XuhfyWZUsQ5Uq59d43ZmZOdoGZNWjeN4WCxxlQaP8crAWdnWcTxfHKcaJl6PW2SWpHx6DsxSx7v6KcGCuw==} + /ember-auto-import@2.6.1: resolution: {integrity: sha512-3bCRi/pXp4QslmuCXGlSz9xwR7DF5oDx3zZO5OXKzNZihtkqAM1xvGuRIdQSl46pvbAXOkp8Odl5fOen1i0dRw==} engines: {node: 12.* || 14.* || >= 16} @@ -8432,6 +11809,44 @@ packages: - supports-color - webpack + /ember-auto-import@2.6.1(webpack@5.89.0): + resolution: {integrity: sha512-3bCRi/pXp4QslmuCXGlSz9xwR7DF5oDx3zZO5OXKzNZihtkqAM1xvGuRIdQSl46pvbAXOkp8Odl5fOen1i0dRw==} + engines: {node: 12.* || 14.* || >= 16} + dependencies: + '@babel/core': 7.21.4 + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.21.4) + '@babel/plugin-proposal-decorators': 7.21.0(@babel/core@7.21.4) + '@babel/preset-env': 7.21.4(@babel/core@7.21.4) + '@embroider/macros': 1.10.0 + '@embroider/shared-internals': 2.0.0 + babel-loader: 8.3.0(@babel/core@7.21.4)(webpack@5.89.0) + babel-plugin-ember-modules-api-polyfill: 3.5.0 + babel-plugin-htmlbars-inline-precompile: 5.3.1 + babel-plugin-syntax-dynamic-import: 6.18.0 + broccoli-debug: 0.6.5 + broccoli-funnel: 3.0.8 + broccoli-merge-trees: 4.2.0 + broccoli-plugin: 4.0.7 + broccoli-source: 3.0.1 + css-loader: 5.2.7(webpack@5.89.0) + debug: 4.3.4 + fs-extra: 10.1.0 + fs-tree-diff: 2.0.1 + handlebars: 4.7.7 + js-string-escape: 1.0.1 + lodash: 4.17.21 + mini-css-extract-plugin: 2.7.5(webpack@5.89.0) + parse5: 6.0.1 + resolve: 1.22.1 + resolve-package-path: 4.0.3 + semver: 7.3.8 + style-loader: 2.0.0(webpack@5.89.0) + typescript-memoize: 1.1.1 + walk-sync: 3.0.0 + transitivePeerDependencies: + - supports-color + - webpack + /ember-cache-primitive-polyfill@1.0.1: resolution: {integrity: sha512-hSPcvIKarA8wad2/b6jDd/eU+OtKmi6uP+iYQbzi5TQpjsqV6b4QdRqrLk7ClSRRKBAtdTuutx+m+X+WlEd2lw==} engines: {node: 10.* || >= 12} @@ -8457,6 +11872,19 @@ packages: - '@babel/core' - supports-color + /ember-cache-primitive-polyfill@1.0.1(@babel/core@7.23.5): + resolution: {integrity: sha512-hSPcvIKarA8wad2/b6jDd/eU+OtKmi6uP+iYQbzi5TQpjsqV6b4QdRqrLk7ClSRRKBAtdTuutx+m+X+WlEd2lw==} + engines: {node: 10.* || >= 12} + dependencies: + ember-cli-babel: 7.26.11 + ember-cli-version-checker: 5.1.2 + ember-compatibility-helpers: 1.2.6(@babel/core@7.23.5) + silent-error: 1.1.1 + transitivePeerDependencies: + - '@babel/core' + - supports-color + dev: true + /ember-cached-decorator-polyfill@1.0.1: resolution: {integrity: sha512-VDgrpIJ6rDDHIfkYrsFR1BM3fpcC0+zFWIOsX0qY44zPrIXjhQWVXs2iVXLIPHprSgf+tFQ3ESxwDscpeRe/0A==} engines: {node: 14.* || >= 16} @@ -8491,6 +11919,24 @@ packages: - '@babel/core' - supports-color + /ember-cached-decorator-polyfill@1.0.1(@babel/core@7.23.5)(ember-source@5.4.0): + resolution: {integrity: sha512-VDgrpIJ6rDDHIfkYrsFR1BM3fpcC0+zFWIOsX0qY44zPrIXjhQWVXs2iVXLIPHprSgf+tFQ3ESxwDscpeRe/0A==} + engines: {node: 14.* || >= 16} + peerDependencies: + ember-source: ^3.13.0 || ^4.0.0 + dependencies: + '@embroider/macros': 1.10.0 + '@glimmer/tracking': 1.1.2 + babel-import-util: 1.3.0 + ember-cache-primitive-polyfill: 1.0.1(@babel/core@7.23.5) + ember-cli-babel: 7.26.11 + ember-cli-babel-plugin-helpers: 1.1.1 + ember-source: 5.4.0(@babel/core@7.23.5)(@glimmer/component@1.1.2) + transitivePeerDependencies: + - '@babel/core' + - supports-color + dev: true + /ember-cli-app-version@6.0.0(ember-source@4.12.0): resolution: {integrity: sha512-XhzETSTy+RMTIyxM/FaZ/8aJvAwT/iIp8HC9zukpOaSPEm5i6Vm4tskeXY4OBnY3VwFWNXWssDt1hgIkUP76WQ==} engines: {node: 14.* || 16.* || >= 18} @@ -8574,6 +12020,22 @@ packages: transitivePeerDependencies: - supports-color + /ember-cli-dependency-checker@3.3.2(ember-cli@5.4.1): + resolution: {integrity: sha512-PwkrW5oYsdPWwt+0Tojufmv/hxVETTjkrEdK7ANQB2VSnqpA5UcYubwpQM9ONuR2J8wyNDMwEHlqIrk/FYtBsQ==} + engines: {node: '>= 6'} + peerDependencies: + ember-cli: ^3.2.0 || >=4.0.0 + dependencies: + chalk: 2.4.2 + ember-cli: 5.4.1 + find-yarn-workspace-root: 1.2.1 + is-git-url: 1.0.0 + resolve: 1.22.8 + semver: 5.7.1 + transitivePeerDependencies: + - supports-color + dev: true + /ember-cli-fastboot-testing@0.6.0(webpack@5.77.0): resolution: {integrity: sha512-ppZyrb4qKjaF+JqsHgDtSic04V5Ut4i1z3FkT2n0IizzL1duQN3rqQgE0sKa8wR7B4tBd7Fc+JQL3VIkVwzBow==} engines: {node: 12.* || 14.* || >= 16} @@ -8700,6 +12162,16 @@ packages: transitivePeerDependencies: - supports-color + /ember-cli-preprocess-registry@5.0.1: + resolution: {integrity: sha512-Jb2zbE5Kfe56Nf4IpdaQ10zZ72p/RyLdgE5j5/lKG3I94QHlq+7AkAd18nPpb5OUeRUT13yQTAYpU+MbjpKTtg==} + engines: {node: 16.* || >= 18} + dependencies: + broccoli-funnel: 3.0.8 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + /ember-cli-sri@2.1.1: resolution: {integrity: sha512-YG/lojDxkur9Bnskt7xB6gUOtJ6aPl/+JyGYm9HNDk3GECVHB3SMN3rlGhDKHa1ndS5NK2W2TSLb9bzRbGlMdg==} engines: {node: '>= 0.10.0'} @@ -8733,6 +12205,15 @@ packages: ember-cli-babel: 7.26.11 transitivePeerDependencies: - supports-color + dev: true + + /ember-cli-test-loader@3.1.0: + resolution: {integrity: sha512-0aocZV9SIoOHiU3hrH3IuLR6busWhTX6UVXgd490hmJkIymmOXNH2+jJoC7Ebkeo3PiOfAdjqhb765QDlHSJOw==} + engines: {node: 10.* || >= 12} + dependencies: + ember-cli-babel: 7.26.11 + transitivePeerDependencies: + - supports-color /ember-cli-typescript-blueprint-polyfill@0.1.0: resolution: {integrity: sha512-g0weUTOnHmPGqVZzkQTl3Nbk9fzEdFkEXydCs5mT1qBjXh8eQ6VlmjjGD5/998UXKuA0pLSCVVMbSp/linLzGA==} @@ -8753,14 +12234,35 @@ packages: ember-cli-babel-plugin-helpers: 1.1.1 execa: 1.0.0 fs-extra: 7.0.1 - resolve: 1.22.1 + resolve: 1.22.8 rsvp: 4.8.5 - semver: 6.3.0 + semver: 6.3.1 + stagehand: 1.0.1 + walk-sync: 1.1.4 + transitivePeerDependencies: + - '@babel/core' + - supports-color + + /ember-cli-typescript@2.0.2(@babel/core@7.23.5): + resolution: {integrity: sha512-7I5azCTxOgRDN8aSSnJZIKSqr+MGnT+jLTUbBYqF8wu6ojs2DUnTePxUcQMcvNh3Q3B1ySv7Q/uZFSjdU9gSjA==} + engines: {node: 6.* || 8.* || >= 10.*} + dependencies: + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.23.5) + '@babel/plugin-transform-typescript': 7.4.5(@babel/core@7.23.5) + ansi-to-html: 0.6.15 + debug: 4.3.4 + ember-cli-babel-plugin-helpers: 1.1.1 + execa: 1.0.0 + fs-extra: 7.0.1 + resolve: 1.22.8 + rsvp: 4.8.5 + semver: 6.3.1 stagehand: 1.0.1 walk-sync: 1.1.4 transitivePeerDependencies: - '@babel/core' - supports-color + dev: true /ember-cli-typescript@3.0.0(@babel/core@7.21.4): resolution: {integrity: sha512-lo5YArbJzJi5ssvaGqTt6+FnhTALnSvYVuxM7lfyL1UCMudyNJ94ovH5C7n5il7ATd6WsNiAPRUO/v+s5Jq/aA==} @@ -8781,6 +12283,26 @@ packages: - '@babel/core' - supports-color + /ember-cli-typescript@3.0.0(@babel/core@7.23.5): + resolution: {integrity: sha512-lo5YArbJzJi5ssvaGqTt6+FnhTALnSvYVuxM7lfyL1UCMudyNJ94ovH5C7n5il7ATd6WsNiAPRUO/v+s5Jq/aA==} + engines: {node: 8.* || >= 10.*} + dependencies: + '@babel/plugin-transform-typescript': 7.5.5(@babel/core@7.23.5) + ansi-to-html: 0.6.15 + debug: 4.3.4 + ember-cli-babel-plugin-helpers: 1.1.1 + execa: 2.1.0 + fs-extra: 8.1.0 + resolve: 1.22.1 + rsvp: 4.8.5 + semver: 6.3.0 + stagehand: 1.0.1 + walk-sync: 2.2.0 + transitivePeerDependencies: + - '@babel/core' + - supports-color + dev: true + /ember-cli-version-checker@3.1.3: resolution: {integrity: sha512-PZNSvpzwWgv68hcXxyjREpj3WWb81A7rtYNQq1lLEgrWIchF8ApKJjWP3NBpHjaatwILkZAV8klair5WFlXAKg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -8793,7 +12315,7 @@ packages: engines: {node: 8.* || 10.* || >= 12.*} dependencies: resolve-package-path: 2.0.0 - semver: 6.3.0 + semver: 6.3.1 silent-error: 1.1.1 transitivePeerDependencies: - supports-color @@ -8808,13 +12330,171 @@ packages: transitivePeerDependencies: - supports-color - /ember-cli@4.11.0: + /ember-cli@4.11.0: + resolution: {integrity: sha512-X0Ep67O/r2nCViILV8wEvI0xiRlLRS8GgeDklQ3SvDXQp2d3xbI8ARW76pcb1du39HPgIi0G6F/OpJ1uOr4ZQQ==} + engines: {node: '>= 14'} + hasBin: true + dependencies: + '@babel/core': 7.23.5 + '@babel/plugin-transform-modules-amd': 7.20.11(@babel/core@7.23.5) + amd-name-resolver: 1.3.1 + babel-plugin-module-resolver: 4.1.0 + bower-config: 1.4.3 + bower-endpoint-parser: 0.2.2 + broccoli: 3.5.2 + broccoli-amd-funnel: 2.0.1 + broccoli-babel-transpiler: 7.8.1 + broccoli-builder: 0.18.14 + broccoli-concat: 4.2.5 + broccoli-config-loader: 1.0.1 + broccoli-config-replace: 1.1.2 + broccoli-debug: 0.6.5 + broccoli-funnel: 3.0.8 + broccoli-funnel-reducer: 1.0.0 + broccoli-merge-trees: 4.2.0 + broccoli-middleware: 2.1.1 + broccoli-slow-trees: 3.1.0 + broccoli-source: 3.0.1 + broccoli-stew: 3.0.0 + calculate-cache-key-for-tree: 2.0.0 + capture-exit: 2.0.0 + chalk: 4.1.2 + ci-info: 3.8.0 + clean-base-url: 1.0.0 + compression: 1.7.4 + configstore: 5.0.1 + console-ui: 3.1.2 + core-object: 3.1.5 + dag-map: 2.0.2 + diff: 5.1.0 + ember-cli-is-package-missing: 1.0.0 + ember-cli-lodash-subset: 2.0.1 + ember-cli-normalize-entity-name: 1.0.0 + ember-cli-preprocess-registry: 3.3.0 + ember-cli-string-utils: 1.1.0 + ember-source-channel-url: 3.0.0 + ensure-posix-path: 1.1.1 + execa: 5.1.1 + exit: 0.1.2 + express: 4.18.2 + filesize: 10.0.6 + find-up: 5.0.0 + find-yarn-workspace-root: 2.0.0 + fixturify-project: 2.1.1 + fs-extra: 10.1.0 + fs-tree-diff: 2.0.1 + get-caller-file: 2.0.5 + git-repo-info: 2.1.1 + glob: 8.1.0 + heimdalljs: 0.2.6 + heimdalljs-fs-monitor: 1.1.1 + heimdalljs-graph: 1.0.0 + heimdalljs-logger: 0.1.10 + http-proxy: 1.18.1 + inflection: 2.0.1 + inquirer: 8.2.5 + is-git-url: 1.0.0 + is-language-code: 3.1.0 + isbinaryfile: 5.0.0 + js-yaml: 4.1.0 + leek: 0.0.24 + lodash.template: 4.5.0 + markdown-it: 13.0.1 + markdown-it-terminal: 0.4.0(markdown-it@13.0.1) + minimatch: 5.1.6 + morgan: 1.10.0 + nopt: 3.0.6 + npm-package-arg: 10.1.0 + os-locale: 5.0.0 + p-defer: 3.0.0 + portfinder: 1.0.32 + promise-map-series: 0.3.0 + promise.hash.helper: 1.0.8 + quick-temp: 0.1.8 + remove-types: 1.0.0 + resolve: 1.22.1 + resolve-package-path: 4.0.3 + safe-stable-stringify: 2.4.3 + sane: 5.0.1 + semver: 7.3.8 + silent-error: 1.1.1 + sort-package-json: 1.57.0 + symlink-or-copy: 1.3.1 + temp: 0.9.4 + testem: 3.10.1 + tiny-lr: 2.0.0 + tree-sync: 2.1.0 + uuid: 8.3.2 + walk-sync: 3.0.0 + watch-detector: 1.0.2 + workerpool: 6.4.0 + yam: 1.0.0 + transitivePeerDependencies: + - arc-templates + - atpl + - babel-core + - bracket-template + - bufferutil + - coffee-script + - debug + - dot + - dust + - dustjs-helpers + - dustjs-linkedin + - eco + - ect + - ejs + - encoding + - haml-coffee + - hamlet + - hamljs + - handlebars + - hogan.js + - htmling + - jade + - jazz + - jqtpl + - just + - liquid-node + - liquor + - lodash + - marko + - mote + - nunjucks + - plates + - pug + - qejs + - ractive + - razor-tmpl + - react + - react-dom + - slm + - squirrelly + - supports-color + - swig + - swig-templates + - teacup + - templayed + - then-jade + - then-pug + - tinyliquid + - toffee + - twig + - twing + - underscore + - utf-8-validate + - vash + - velocityjs + - walrus + - whiskers + + /ember-cli@4.11.0(debug@4.3.4): resolution: {integrity: sha512-X0Ep67O/r2nCViILV8wEvI0xiRlLRS8GgeDklQ3SvDXQp2d3xbI8ARW76pcb1du39HPgIi0G6F/OpJ1uOr4ZQQ==} engines: {node: '>= 14'} hasBin: true dependencies: - '@babel/core': 7.21.4 - '@babel/plugin-transform-modules-amd': 7.20.11(@babel/core@7.21.4) + '@babel/core': 7.23.5 + '@babel/plugin-transform-modules-amd': 7.20.11(@babel/core@7.23.5) amd-name-resolver: 1.3.1 babel-plugin-module-resolver: 4.1.0 bower-config: 1.4.3 @@ -8868,7 +12548,7 @@ packages: heimdalljs-fs-monitor: 1.1.1 heimdalljs-graph: 1.0.0 heimdalljs-logger: 0.1.10 - http-proxy: 1.18.1 + http-proxy: 1.18.1(debug@4.3.4) inflection: 2.0.1 inquirer: 8.2.5 is-git-url: 1.0.0 @@ -8899,7 +12579,7 @@ packages: sort-package-json: 1.57.0 symlink-or-copy: 1.3.1 temp: 0.9.4 - testem: 3.10.1 + testem: 3.10.1(debug@4.3.4) tiny-lr: 2.0.0 tree-sync: 2.1.0 uuid: 8.3.2 @@ -8965,21 +12645,15 @@ packages: - velocityjs - walrus - whiskers + dev: true - /ember-cli@4.11.0(debug@4.3.4): - resolution: {integrity: sha512-X0Ep67O/r2nCViILV8wEvI0xiRlLRS8GgeDklQ3SvDXQp2d3xbI8ARW76pcb1du39HPgIi0G6F/OpJ1uOr4ZQQ==} - engines: {node: '>= 14'} + /ember-cli@5.4.1: + resolution: {integrity: sha512-+jwp63OPT0zkUnXP563DkIwb1GiI6kGYHg6DyzJKY48BCdevqcgxsMFn8/RENXoF7krg18A5B9cSa8Y1v15tIw==} + engines: {node: '>= 18'} hasBin: true dependencies: - '@babel/core': 7.21.4 - '@babel/plugin-transform-modules-amd': 7.20.11(@babel/core@7.21.4) - amd-name-resolver: 1.3.1 - babel-plugin-module-resolver: 4.1.0 - bower-config: 1.4.3 - bower-endpoint-parser: 0.2.2 + '@pnpm/find-workspace-dir': 6.0.2 broccoli: 3.5.2 - broccoli-amd-funnel: 2.0.1 - broccoli-babel-transpiler: 7.8.1 broccoli-builder: 0.18.14 broccoli-concat: 4.2.5 broccoli-config-loader: 1.0.1 @@ -9006,18 +12680,17 @@ packages: ember-cli-is-package-missing: 1.0.0 ember-cli-lodash-subset: 2.0.1 ember-cli-normalize-entity-name: 1.0.0 - ember-cli-preprocess-registry: 3.3.0 + ember-cli-preprocess-registry: 5.0.1 ember-cli-string-utils: 1.1.0 - ember-source-channel-url: 3.0.0 ensure-posix-path: 1.1.1 execa: 5.1.1 exit: 0.1.2 express: 4.18.2 - filesize: 10.0.6 + filesize: 10.1.0 find-up: 5.0.0 find-yarn-workspace-root: 2.0.0 fixturify-project: 2.1.1 - fs-extra: 10.1.0 + fs-extra: 11.2.0 fs-tree-diff: 2.0.1 get-caller-file: 2.0.5 git-repo-info: 2.1.1 @@ -9026,18 +12699,16 @@ packages: heimdalljs-fs-monitor: 1.1.1 heimdalljs-graph: 1.0.0 heimdalljs-logger: 0.1.10 - http-proxy: 1.18.1(debug@4.3.4) + http-proxy: 1.18.1 inflection: 2.0.1 - inquirer: 8.2.5 + inquirer: 9.2.12 is-git-url: 1.0.0 is-language-code: 3.1.0 isbinaryfile: 5.0.0 - js-yaml: 4.1.0 - leek: 0.0.24 lodash.template: 4.5.0 markdown-it: 13.0.1 markdown-it-terminal: 0.4.0(markdown-it@13.0.1) - minimatch: 5.1.6 + minimatch: 7.4.6 morgan: 1.10.0 nopt: 3.0.6 npm-package-arg: 10.1.0 @@ -9048,19 +12719,18 @@ packages: promise.hash.helper: 1.0.8 quick-temp: 0.1.8 remove-types: 1.0.0 - resolve: 1.22.1 + resolve: 1.22.8 resolve-package-path: 4.0.3 safe-stable-stringify: 2.4.3 sane: 5.0.1 - semver: 7.3.8 + semver: 7.5.4 silent-error: 1.1.1 sort-package-json: 1.57.0 symlink-or-copy: 1.3.1 temp: 0.9.4 - testem: 3.10.1(debug@4.3.4) + testem: 3.10.1 tiny-lr: 2.0.0 tree-sync: 2.1.0 - uuid: 8.3.2 walk-sync: 3.0.0 watch-detector: 1.0.2 workerpool: 6.4.0 @@ -9080,7 +12750,6 @@ packages: - eco - ect - ejs - - encoding - haml-coffee - hamlet - hamljs @@ -9152,6 +12821,20 @@ packages: - '@babel/core' - supports-color + /ember-compatibility-helpers@1.2.6(@babel/core@7.23.5): + resolution: {integrity: sha512-2UBUa5SAuPg8/kRVaiOfTwlXdeVweal1zdNPibwItrhR0IvPrXpaqwJDlEZnWKEoB+h33V0JIfiWleSG6hGkkA==} + engines: {node: 10.* || >= 12.*} + dependencies: + babel-plugin-debug-macros: 0.2.0(@babel/core@7.23.5) + ember-cli-version-checker: 5.1.2 + find-up: 5.0.0 + fs-extra: 9.1.0 + semver: 5.7.1 + transitivePeerDependencies: + - '@babel/core' + - supports-color + dev: true + /ember-decorators-polyfill@1.1.5(@babel/core@7.21.4): resolution: {integrity: sha512-O154i8sLoVjsiKzSqxGRfHGr+N+drT6mRrLDbNgJCnW/V5uLg/ppZFpUsrdxuXnp5Q9us3OfXV1nX2CH+7bUpA==} engines: {node: 8.* || >= 10.*} @@ -9211,6 +12894,17 @@ packages: - '@babel/core' - supports-color + /ember-load-initializers@2.1.2(@babel/core@7.23.5): + resolution: {integrity: sha512-CYR+U/wRxLbrfYN3dh+0Tb6mFaxJKfdyz+wNql6cqTrA0BBi9k6J3AaKXj273TqvEpyyXegQFFkZEiuZdYtgJw==} + engines: {node: 6.* || 8.* || >= 10.*} + dependencies: + ember-cli-babel: 7.26.11 + ember-cli-typescript: 2.0.2(@babel/core@7.23.5) + transitivePeerDependencies: + - '@babel/core' + - supports-color + dev: true + /ember-maybe-import-regenerator@1.0.0: resolution: {integrity: sha512-wtjgjEV0Hk4fgiAwFjOfPrGWfmFrbRW3zgNZO4oA3H5FlbMssMvWuR8blQ3QSWYHODVK9r+ThsRAs8lG4kbxqA==} engines: {node: '>= 12.*'} @@ -9236,7 +12930,7 @@ packages: common-tags: 1.8.2 ember-auto-import: 2.6.1(webpack@5.77.0) ember-cli-babel: 7.26.11 - ember-cli-test-loader: 3.0.0 + ember-cli-test-loader: 3.1.0 ember-source: 4.12.0(@babel/core@7.21.4)(@glimmer/component@1.1.2)(webpack@5.77.0) qunit: 2.19.4 resolve-package-path: 4.0.3 @@ -9278,6 +12972,21 @@ packages: - supports-color dev: true + /ember-resolver@11.0.1(ember-source@5.4.0): + resolution: {integrity: sha512-ucBk3oM+PR+AfYoSUXeQh8cDQS1sSiEKp4Pcgbew5cFMSqPxJfqd1zyZsfQKNTuyubeGmWxBOyMVSTvX2LeCyg==} + engines: {node: 14.* || 16.* || >= 18} + peerDependencies: + ember-source: ^4.8.3 || >= 5.0.0 + peerDependenciesMeta: + ember-source: + optional: true + dependencies: + ember-cli-babel: 7.26.11 + ember-source: 5.4.0(@babel/core@7.23.5)(@glimmer/component@1.1.2)(webpack@5.89.0) + transitivePeerDependencies: + - supports-color + dev: true + /ember-rfc176-data@0.3.18: resolution: {integrity: sha512-JtuLoYGSjay1W3MQAxt3eINWXNYYQliK90tLwtb8aeCuQK8zKGCRbBodVIrkcTqshULMnRuTOS6t1P7oQk3g6Q==} @@ -9388,6 +13097,124 @@ packages: - supports-color - webpack + /ember-source@5.4.0(@babel/core@7.23.5)(@glimmer/component@1.1.2): + resolution: {integrity: sha512-y2fPd7DJ8D9IBjHSf6CPwU8TqNpqytpMgFyzf+9tPvu/u2Wdd45jEd2W1weKE3URQwPTcA0vK8Q1w6uzLOx/EA==} + engines: {node: '>= 16.*'} + peerDependencies: + '@glimmer/component': ^1.1.2 + dependencies: + '@babel/helper-module-imports': 7.22.15 + '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.23.5) + '@ember/edition-utils': 1.2.0 + '@glimmer/compiler': 0.84.3 + '@glimmer/component': 1.1.2(@babel/core@7.23.5) + '@glimmer/destroyable': 0.84.3 + '@glimmer/env': 0.1.7 + '@glimmer/global-context': 0.84.3 + '@glimmer/interfaces': 0.84.3 + '@glimmer/manager': 0.84.3 + '@glimmer/node': 0.84.3 + '@glimmer/opcode-compiler': 0.84.3 + '@glimmer/owner': 0.84.3 + '@glimmer/program': 0.84.3 + '@glimmer/reference': 0.84.3 + '@glimmer/runtime': 0.84.3 + '@glimmer/syntax': 0.84.3 + '@glimmer/util': 0.84.3 + '@glimmer/validator': 0.84.3 + '@glimmer/vm-babel-plugins': 0.84.3(@babel/core@7.23.5) + '@simple-dom/interface': 1.4.0 + babel-plugin-debug-macros: 0.3.4(@babel/core@7.23.5) + babel-plugin-filter-imports: 4.0.0 + backburner.js: 2.8.0 + broccoli-concat: 4.2.5 + broccoli-debug: 0.6.5 + broccoli-file-creator: 2.1.1 + broccoli-funnel: 3.0.8 + broccoli-merge-trees: 4.2.0 + chalk: 4.1.2 + ember-auto-import: 2.6.1 + ember-cli-babel: 7.26.11 + ember-cli-get-component-path-option: 1.0.0 + ember-cli-is-package-missing: 1.0.0 + ember-cli-normalize-entity-name: 1.0.0 + ember-cli-path-utils: 1.0.0 + ember-cli-string-utils: 1.1.0 + ember-cli-typescript-blueprint-polyfill: 0.1.0 + ember-cli-version-checker: 5.1.2 + ember-router-generator: 2.0.0 + inflection: 2.0.1 + resolve: 1.22.8 + route-recognizer: 0.3.4 + router_js: 8.0.3(route-recognizer@0.3.4) + semver: 7.5.4 + silent-error: 1.1.1 + transitivePeerDependencies: + - '@babel/core' + - rsvp + - supports-color + - webpack + dev: true + + /ember-source@5.4.0(@babel/core@7.23.5)(@glimmer/component@1.1.2)(webpack@5.89.0): + resolution: {integrity: sha512-y2fPd7DJ8D9IBjHSf6CPwU8TqNpqytpMgFyzf+9tPvu/u2Wdd45jEd2W1weKE3URQwPTcA0vK8Q1w6uzLOx/EA==} + engines: {node: '>= 16.*'} + peerDependencies: + '@glimmer/component': ^1.1.2 + dependencies: + '@babel/helper-module-imports': 7.22.15 + '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.23.5) + '@ember/edition-utils': 1.2.0 + '@glimmer/compiler': 0.84.3 + '@glimmer/component': 1.1.2(@babel/core@7.23.5) + '@glimmer/destroyable': 0.84.3 + '@glimmer/env': 0.1.7 + '@glimmer/global-context': 0.84.3 + '@glimmer/interfaces': 0.84.3 + '@glimmer/manager': 0.84.3 + '@glimmer/node': 0.84.3 + '@glimmer/opcode-compiler': 0.84.3 + '@glimmer/owner': 0.84.3 + '@glimmer/program': 0.84.3 + '@glimmer/reference': 0.84.3 + '@glimmer/runtime': 0.84.3 + '@glimmer/syntax': 0.84.3 + '@glimmer/util': 0.84.3 + '@glimmer/validator': 0.84.3 + '@glimmer/vm-babel-plugins': 0.84.3(@babel/core@7.23.5) + '@simple-dom/interface': 1.4.0 + babel-plugin-debug-macros: 0.3.4(@babel/core@7.23.5) + babel-plugin-filter-imports: 4.0.0 + backburner.js: 2.8.0 + broccoli-concat: 4.2.5 + broccoli-debug: 0.6.5 + broccoli-file-creator: 2.1.1 + broccoli-funnel: 3.0.8 + broccoli-merge-trees: 4.2.0 + chalk: 4.1.2 + ember-auto-import: 2.6.1(webpack@5.89.0) + ember-cli-babel: 7.26.11 + ember-cli-get-component-path-option: 1.0.0 + ember-cli-is-package-missing: 1.0.0 + ember-cli-normalize-entity-name: 1.0.0 + ember-cli-path-utils: 1.0.0 + ember-cli-string-utils: 1.1.0 + ember-cli-typescript-blueprint-polyfill: 0.1.0 + ember-cli-version-checker: 5.1.2 + ember-router-generator: 2.0.0 + inflection: 2.0.1 + resolve: 1.22.8 + route-recognizer: 0.3.4 + router_js: 8.0.3(route-recognizer@0.3.4) + semver: 7.5.4 + silent-error: 1.1.1 + transitivePeerDependencies: + - '@babel/core' + - rsvp + - supports-color + - webpack + dev: true + /ember-strict-resolver@1.3.0: resolution: {integrity: sha512-GeI1LLLt470sjaq/huKGQTDJPDOH0FlrX8FFVcSZPXO2U9FQH7Kc8BaXb4GpViJbfLLC4d7tIUZI4NBnuXSmKg==} engines: {node: 10.* || >= 12} @@ -9422,7 +13249,7 @@ packages: lodash: 4.17.21 package-json: 6.5.0 remote-git-tags: 3.0.0 - semver: 7.3.8 + semver: 7.5.4 transitivePeerDependencies: - encoding dev: true @@ -9500,6 +13327,13 @@ packages: graceful-fs: 4.2.11 tapable: 2.2.1 + /enhanced-resolve@5.15.0: + resolution: {integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==} + engines: {node: '>=10.13.0'} + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + /ensure-posix-path@1.1.1: resolution: {integrity: sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw==} @@ -9522,6 +13356,11 @@ packages: resolution: {integrity: sha512-e64Qj9+4aZzjzzFpZC7p5kmm/ccCrbLhAJplhsDXQFs87XTsXwOpH4s1Io2s90Tau/8r2j9f4l/thhDevRjzxw==} engines: {node: '>=0.8'} + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + /error@7.2.1: resolution: {integrity: sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==} dependencies: @@ -9566,9 +13405,56 @@ packages: unbox-primitive: 1.0.2 which-typed-array: 1.1.9 + /es-abstract@1.22.3: + resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + arraybuffer.prototype.slice: 1.0.2 + available-typed-arrays: 1.0.5 + call-bind: 1.0.5 + es-set-tostringtag: 2.0.1 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.2 + get-symbol-description: 1.0.0 + globalthis: 1.0.3 + gopd: 1.0.1 + has-property-descriptors: 1.0.0 + has-proto: 1.0.1 + has-symbols: 1.0.3 + hasown: 2.0.0 + internal-slot: 1.0.5 + is-array-buffer: 3.0.2 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-typed-array: 1.1.12 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.5.1 + safe-array-concat: 1.0.1 + safe-regex-test: 1.0.0 + string.prototype.trim: 1.2.8 + string.prototype.trimend: 1.0.7 + string.prototype.trimstart: 1.0.7 + typed-array-buffer: 1.0.0 + typed-array-byte-length: 1.0.0 + typed-array-byte-offset: 1.0.0 + typed-array-length: 1.0.4 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.13 + /es-module-lexer@0.9.3: resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==} + /es-module-lexer@1.4.1: + resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} + /es-set-tostringtag@2.0.1: resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} engines: {node: '>= 0.4'} @@ -9581,7 +13467,6 @@ packages: resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} dependencies: has: 1.0.3 - dev: true /es-to-primitive@1.2.1: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} @@ -9605,6 +13490,10 @@ packages: /escape-string-regexp@4.0.0: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + + /escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} dev: true /escodegen@2.0.0: @@ -9620,6 +13509,15 @@ packages: source-map: 0.6.1 dev: true + /eslint-compat-utils@0.1.2(eslint@8.55.0): + resolution: {integrity: sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + eslint: 8.55.0 + dev: false + /eslint-config-prettier@8.8.0(eslint@8.37.0): resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} hasBin: true @@ -9629,18 +13527,66 @@ packages: eslint: 8.37.0 dev: true + /eslint-config-prettier@9.1.0(eslint@8.55.0): + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.55.0 + dev: false + /eslint-import-resolver-node@0.3.7: resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==} dependencies: debug: 3.2.7 - is-core-module: 2.11.0 - resolve: 1.22.1 + is-core-module: 2.13.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + dependencies: + debug: 3.2.7 + is-core-module: 2.13.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + dev: false + + /eslint-module-utils@2.7.4(@typescript-eslint/parser@5.57.1)(eslint-import-resolver-node@0.3.7)(eslint@8.37.0): + resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 5.57.1(eslint@8.37.0)(typescript@5.0.3) + debug: 3.2.7 + eslint: 8.37.0 + eslint-import-resolver-node: 0.3.7 transitivePeerDependencies: - supports-color dev: true - /eslint-module-utils@2.7.4(@typescript-eslint/parser@5.57.1)(eslint-import-resolver-node@0.3.7)(eslint@8.37.0): - resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.13.2)(eslint-import-resolver-node@0.3.9)(eslint@8.55.0): + resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -9660,13 +13606,13 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.57.1(eslint@8.37.0)(typescript@5.0.3) + '@typescript-eslint/parser': 6.13.2(eslint@8.55.0)(typescript@5.3.3) debug: 3.2.7 - eslint: 8.37.0 - eslint-import-resolver-node: 0.3.7 + eslint: 8.55.0 + eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - dev: true + dev: false /eslint-plugin-ember@11.4.9(eslint@8.37.0): resolution: {integrity: sha512-1nAgMSwAJrntfvsiyIyHtYY+AvAPZ1wxcoa+gsui/VviQqULCtZLF8+1UAOTAGJ5bEjhe3f8TTcyRGHXRPHzeQ==} @@ -9691,6 +13637,18 @@ packages: - supports-color dev: true + /eslint-plugin-es-x@7.5.0(eslint@8.55.0): + resolution: {integrity: sha512-ODswlDSO0HJDzXU0XvgZ3lF3lS3XAZEossh15Q2UHjwrJggWeBoKqqEsLTZLXl+dh5eOAozG0zRcYtuE35oTuQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) + '@eslint-community/regexpp': 4.10.0 + eslint: 8.55.0 + eslint-compat-utils: 0.1.2(eslint@8.55.0) + dev: false + /eslint-plugin-es@3.0.1(eslint@8.37.0): resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} engines: {node: '>=8.10.0'} @@ -9735,6 +13693,41 @@ packages: - supports-color dev: true + /eslint-plugin-import@2.29.0(@typescript-eslint/parser@6.13.2)(eslint@8.55.0): + resolution: {integrity: sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 6.13.2(eslint@8.55.0)(typescript@5.3.3) + array-includes: 3.1.7 + array.prototype.findlastindex: 1.2.3 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.55.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.13.2)(eslint-import-resolver-node@0.3.9)(eslint@8.55.0) + hasown: 2.0.0 + is-core-module: 2.13.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.7 + object.groupby: 1.0.1 + object.values: 1.1.7 + semver: 6.3.1 + tsconfig-paths: 3.14.2 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: false + /eslint-plugin-mocha@10.1.0(eslint@8.37.0): resolution: {integrity: sha512-xLqqWUF17llsogVOC+8C6/jvQ+4IoOREbN7ZCHuOHuD6cT5cDD4h7f2LgsZuzMAiwswWE21tO7ExaknHVDrSkw==} engines: {node: '>=14.0.0'} @@ -9746,6 +13739,36 @@ packages: rambda: 7.5.0 dev: true + /eslint-plugin-mocha@10.2.0(eslint@8.55.0): + resolution: {integrity: sha512-ZhdxzSZnd1P9LqDPF0DBcFLpRIGdh1zkF2JHnQklKQOvrQtT73kdP5K9V2mzvbLR+cCAO9OI48NXK/Ax9/ciCQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.55.0 + eslint-utils: 3.0.0(eslint@8.55.0) + rambda: 7.5.0 + dev: false + + /eslint-plugin-n@16.3.1(eslint@8.55.0): + resolution: {integrity: sha512-w46eDIkxQ2FaTHcey7G40eD+FhTXOdKudDXPUO2n9WNcslze/i/HT2qJ3GXjHngYSGDISIgPNhwGtgoix4zeOw==} + engines: {node: '>=16.0.0'} + peerDependencies: + eslint: '>=7.0.0' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) + builtins: 5.0.1 + eslint: 8.55.0 + eslint-plugin-es-x: 7.5.0(eslint@8.55.0) + get-tsconfig: 4.7.2 + ignore: 5.2.4 + is-builtin-module: 3.2.1 + is-core-module: 2.13.1 + minimatch: 3.1.2 + resolve: 1.22.8 + semver: 7.5.4 + dev: false + /eslint-plugin-node@11.1.0(eslint@8.37.0): resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} engines: {node: '>=8.10.0'} @@ -9788,6 +13811,16 @@ packages: - eslint dev: true + /eslint-plugin-qunit@8.0.1(eslint@8.55.0): + resolution: {integrity: sha512-3bFOPryXoQOez95oP/JfWTxHBc/bgDQQZqTuv9uYTwH5sdIvSM2TES1iHDcy/F/LvqiqIpscDAOPAjlqSCnNPg==} + engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} + dependencies: + eslint-utils: 3.0.0(eslint@8.55.0) + requireindex: 1.2.0 + transitivePeerDependencies: + - eslint + dev: false + /eslint-plugin-simple-import-sort@10.0.0(eslint@8.37.0): resolution: {integrity: sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==} peerDependencies: @@ -9796,6 +13829,14 @@ packages: eslint: 8.37.0 dev: true + /eslint-plugin-simple-import-sort@10.0.0(eslint@8.55.0): + resolution: {integrity: sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw==} + peerDependencies: + eslint: '>=5.0.0' + dependencies: + eslint: 8.55.0 + dev: false + /eslint-scope@5.1.1: resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} engines: {node: '>=8.0.0'} @@ -9811,6 +13852,14 @@ packages: estraverse: 5.3.0 dev: true + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: false + /eslint-utils@2.1.0: resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} engines: {node: '>=6'} @@ -9828,6 +13877,16 @@ packages: eslint-visitor-keys: 2.1.0 dev: true + /eslint-utils@3.0.0(eslint@8.55.0): + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 8.55.0 + eslint-visitor-keys: 2.1.0 + dev: false + /eslint-visitor-keys@1.3.0: resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} engines: {node: '>=4'} @@ -9836,13 +13895,16 @@ packages: /eslint-visitor-keys@2.1.0: resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} engines: {node: '>=10'} - dev: true /eslint-visitor-keys@3.4.0: resolution: {integrity: sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + /eslint@8.37.0: resolution: {integrity: sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -9892,6 +13954,53 @@ packages: - supports-color dev: true + /eslint@8.55.0: + resolution: {integrity: sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.55.0 + '@humanwhocodes/config-array': 0.11.13 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.20.0 + graphemer: 1.4.0 + ignore: 5.2.4 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: false + /esm@3.2.25: resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==} engines: {node: '>=6'} @@ -9902,9 +14011,17 @@ packages: dependencies: acorn: 8.8.2 acorn-jsx: 5.3.2(acorn@8.8.2) - eslint-visitor-keys: 3.4.0 + eslint-visitor-keys: 3.4.3 dev: true + /espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.11.2 + acorn-jsx: 5.3.2(acorn@8.11.2) + eslint-visitor-keys: 3.4.3 + /esprima@3.0.0: resolution: {integrity: sha512-xoBq/MIShSydNZOkjkoCEjqod963yHNXTLC40ypBhop6yPqflPz/vTinmCfSrGcywVLnSftRf6a0kJLdFdzemw==} engines: {node: '>=0.10.0'} @@ -9920,7 +14037,6 @@ packages: engines: {node: '>=0.10'} dependencies: estraverse: 5.3.0 - dev: true /esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} @@ -10150,7 +14266,9 @@ packages: /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - dev: true + + /fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} /fast-sourcemap-concat@1.4.0: resolution: {integrity: sha512-x90Wlx/2C83lfyg7h4oguTZN4MyaVfaiUSJQNpU+YEA0Odf9u659Opo44b0LfoVg9G/bOE++GdID/dkyja+XcA==} @@ -10213,7 +14331,7 @@ packages: cookie: 0.4.2 debug: 4.3.4 jsdom: 19.0.0 - resolve: 1.22.1 + resolve: 1.22.8 simple-dom: 1.4.0 source-map-support: 0.5.21 transitivePeerDependencies: @@ -10231,7 +14349,7 @@ packages: cookie: 0.4.2 debug: 4.3.4 jsdom: 19.0.0 - resolve: 1.22.1 + resolve: 1.22.8 simple-dom: 1.4.0 source-map-support: 0.5.21 transitivePeerDependencies: @@ -10269,17 +14387,29 @@ packages: dependencies: escape-string-regexp: 1.0.5 + /figures@5.0.0: + resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} + engines: {node: '>=14'} + dependencies: + escape-string-regexp: 5.0.0 + is-unicode-supported: 1.3.0 + dev: true + /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: flat-cache: 3.0.4 - dev: true /filesize@10.0.6: resolution: {integrity: sha512-rzpOZ4C9vMFDqOa6dNpog92CoLYjD79dnjLk2TYDDtImRIyLTOzqojCb05Opd1WuiWjs+fshhCgTd8cl7y5t+g==} engines: {node: '>= 10.4.0'} + /filesize@10.1.0: + resolution: {integrity: sha512-GTLKYyBSDz3nPhlLVPjPWZCnhkd9TrrRArNcy8Z+J2cqScB7h2McAzR6NBX6nYOoWafql0roY8hrocxnZBv9CQ==} + engines: {node: '>= 10.4.0'} + dev: true + /filesize@5.0.3: resolution: {integrity: sha512-RM123v6KPqgZJmVCh4rLvCo8tLKr4sgD92DeZ+AuoUE8teGZJHKs1cTORwETcpIJSlGsz2WYdwKDQUXby5hNqQ==} engines: {node: '>= 0.4.0'} @@ -10470,7 +14600,6 @@ packages: dependencies: flatted: 3.2.7 rimraf: 3.0.2 - dev: true /flat@5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} @@ -10479,7 +14608,6 @@ packages: /flatted@3.2.7: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} - dev: true /follow-redirects@1.15.2: resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} @@ -10587,6 +14715,14 @@ packages: jsonfile: 6.1.0 universalify: 2.0.0 + /fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.0 + /fs-extra@4.0.3: resolution: {integrity: sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==} dependencies: @@ -10704,6 +14840,9 @@ packages: /function-bind@1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + /function.prototype.name@1.1.5: resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} engines: {node: '>= 0.4'} @@ -10713,6 +14852,15 @@ packages: es-abstract: 1.21.2 functions-have-names: 1.2.3 + /function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.0 + es-abstract: 1.22.3 + functions-have-names: 1.2.3 + /functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} @@ -10747,6 +14895,20 @@ packages: has: 1.0.3 has-symbols: 1.0.3 + /get-intrinsic@1.2.2: + resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} + dependencies: + function-bind: 1.1.2 + has-proto: 1.0.1 + has-symbols: 1.0.3 + hasown: 2.0.0 + + /get-source@2.0.12: + resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} + dependencies: + data-uri-to-buffer: 2.0.2 + source-map: 0.6.1 + /get-stdin@4.0.1: resolution: {integrity: sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==} engines: {node: '>=0.10.0'} @@ -10774,6 +14936,12 @@ packages: call-bind: 1.0.2 get-intrinsic: 1.2.0 + /get-tsconfig@4.7.2: + resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} + dependencies: + resolve-pkg-maps: 1.0.0 + dev: false + /get-value@2.0.6: resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} engines: {node: '>=0.10.0'} @@ -10807,7 +14975,6 @@ packages: engines: {node: '>=10.13.0'} dependencies: is-glob: 4.0.3 - dev: true /glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} @@ -10888,7 +15055,6 @@ packages: engines: {node: '>=8'} dependencies: type-fest: 0.20.2 - dev: true /globals@9.18.0: resolution: {integrity: sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==} @@ -10941,7 +15107,6 @@ packages: ignore: 5.2.4 merge2: 1.4.1 slash: 3.0.0 - dev: true /globrex@0.1.2: resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} @@ -10970,6 +15135,9 @@ packages: url-parse-lax: 3.0.0 dev: true + /graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -10980,6 +15148,10 @@ packages: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} dev: true + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: false + /growly@1.3.0: resolution: {integrity: sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==} @@ -11080,11 +15252,17 @@ packages: heimdalljs: 0.2.6 heimdalljs-logger: 0.1.10 path-root: 0.1.1 - resolve: 1.22.1 + resolve: 1.22.8 resolve-package-path: 1.2.7 transitivePeerDependencies: - supports-color + /hasown@2.0.0: + resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + /hawk@1.1.1: resolution: {integrity: sha512-am8sVA2bCJIw8fuuVcKvmmNnGFUGW8spTkVtj2fXTEZVkfN42bwFZFtDem57eFi+NSxurJB8EQ7Jd3uCHLn8Vw==} engines: {node: '>=0.8.0'} @@ -11337,7 +15515,6 @@ packages: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - dev: true /imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} @@ -11348,6 +15525,9 @@ packages: engines: {node: '>=8'} dev: true + /individual@3.0.0: + resolution: {integrity: sha512-rUY5vtT748NMRbEMrTNiFfy29BgGZwGXUi2NFUVMWQrogSLzlJvQV9eeMWi+g1aVaQ53tpyLAQtd5x/JH0Nh1g==} + /infer-owner@1.0.4: resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} dev: true @@ -11375,6 +15555,10 @@ packages: /ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + /ini@3.0.1: + resolution: {integrity: sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + /inline-source-map-comment@1.0.5: resolution: {integrity: sha512-a3/m6XgooVCXkZCduOb7pkuvUtNKt4DaqaggKKJrMQHQsqt6JcJXEreExeZiiK4vWL/cM/uF6+chH05pz2/TdQ==} hasBin: true @@ -11441,6 +15625,27 @@ packages: through: 2.3.8 wrap-ansi: 7.0.0 + /inquirer@9.2.12: + resolution: {integrity: sha512-mg3Fh9g2zfuVWJn6lhST0O7x4n03k7G8Tx5nvikJkbq8/CK47WDVm+UznF0G6s5Zi0KcyUisr6DU8T67N5U+1Q==} + engines: {node: '>=14.18.0'} + dependencies: + '@ljharb/through': 2.3.11 + ansi-escapes: 4.3.2 + chalk: 5.3.0 + cli-cursor: 3.1.0 + cli-width: 4.1.0 + external-editor: 3.1.0 + figures: 5.0.0 + lodash: 4.17.21 + mute-stream: 1.0.0 + ora: 5.4.1 + run-async: 3.0.0 + rxjs: 7.8.1 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: true + /internal-slot@1.0.5: resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} engines: {node: '>= 0.4'} @@ -11486,6 +15691,9 @@ packages: get-intrinsic: 1.2.0 is-typed-array: 1.1.10 + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + /is-bigint@1.0.4: resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} dependencies: @@ -11513,7 +15721,6 @@ packages: engines: {node: '>=6'} dependencies: builtin-modules: 3.3.0 - dev: true /is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} @@ -11524,6 +15731,11 @@ packages: dependencies: has: 1.0.3 + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.0 + /is-data-descriptor@0.1.4: resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==} engines: {node: '>=0.10.0'} @@ -11613,7 +15825,7 @@ packages: /is-language-code@3.1.0: resolution: {integrity: sha512-zJdQ3QTeLye+iphMeK3wks+vXSRFKh68/Pnlw7aOfApFSEIOhYa8P9vwwa6QrImNNBMJTiL1PpYF0f4BxDuEgA==} dependencies: - '@babel/runtime': 7.21.0 + '@babel/runtime': 7.23.5 /is-module@1.0.0: resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} @@ -11651,7 +15863,6 @@ packages: /is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} - dev: true /is-plain-obj@1.1.0: resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} @@ -11701,6 +15912,12 @@ packages: dependencies: has-tostringtag: 1.0.0 + /is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + dependencies: + better-path-resolve: 1.0.0 + /is-symbol@1.0.4: resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} engines: {node: '>= 0.4'} @@ -11722,6 +15939,12 @@ packages: gopd: 1.0.1 has-tostringtag: 1.0.0 + /is-typed-array@1.1.12: + resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.13 + /is-typedarray@1.0.0: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} @@ -11729,6 +15952,11 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + /is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + dev: true + /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: @@ -11750,6 +15978,9 @@ packages: /isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + /isbinaryfile@5.0.0: resolution: {integrity: sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg==} engines: {node: '>= 14.0.0'} @@ -11913,7 +16144,7 @@ packages: optional: true dependencies: abab: 2.0.6 - acorn: 8.8.2 + acorn: 8.11.2 acorn-globals: 6.0.0 cssom: 0.5.0 cssstyle: 2.3.0 @@ -11981,7 +16212,6 @@ packages: /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - dev: true /json-stable-stringify@1.0.2: resolution: {integrity: sha512-eunSSaEnxV12z+Z73y/j5N37/In40GK4GmsSy+tEHJMxknvqnA7/djeYtAgW0GsWHUfg+847WJjKaEylk2y09g==} @@ -11990,7 +16220,6 @@ packages: /json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - dev: true /json-typescript@1.1.2: resolution: {integrity: sha512-Np07MUsYMKbB0nNlw/MMIRjUK7ehO48LA4FsrzrhCfTUxMKbvOBAo0sc0b4nQ80ge9d32sModCunCgoyUojgUA==} @@ -12005,7 +16234,6 @@ packages: hasBin: true dependencies: minimist: 1.2.8 - dev: true /json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} @@ -12110,7 +16338,6 @@ packages: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 - dev: true /line-column@1.0.2: resolution: {integrity: sha512-Ktrjk5noGYlHsVnYWh62FLVs4hTb8A3e+vucNZMgPeAOITdshMSgv4cCZQeRDjm7+goqmo6+liZwTXo+U3sVww==} @@ -12118,6 +16345,9 @@ packages: isarray: 1.0.0 isobject: 2.1.0 + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + /linkify-it@1.2.4: resolution: {integrity: sha512-eGHwtlABkp1NOJSiKUNqBf3SYAS5jPHtvRXPAgNaQwTqmkTahjtiLH9NtxdR5IOPhNvwNMN/diswSfZKzUkhGg==} dependencies: @@ -12132,6 +16362,15 @@ packages: /livereload-js@3.4.1: resolution: {integrity: sha512-5MP0uUeVCec89ZbNOT/i97Mc+q3SxXmiUGhRFOTmhrGPn//uWVQdCvcLJDy64MSBR5MidFdOR7B9viumoavy6g==} + /load-json-file@6.2.0: + resolution: {integrity: sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==} + engines: {node: '>=8'} + dependencies: + graceful-fs: 4.2.11 + parse-json: 5.2.0 + strip-bom: 4.0.0 + type-fest: 0.6.0 + /loader-runner@4.3.0: resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} engines: {node: '>=6.11.5'} @@ -12377,7 +16616,7 @@ packages: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} dependencies: - semver: 6.3.0 + semver: 6.3.1 /make-fetch-happen@9.1.0: resolution: {integrity: sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==} @@ -12419,6 +16658,10 @@ packages: resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} engines: {node: '>=0.10.0'} + /map-obj@4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + /map-visit@1.0.0: resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} engines: {node: '>=0.10.0'} @@ -12503,6 +16746,13 @@ packages: mimic-fn: 2.1.0 p-is-promise: 2.1.0 + /mem@8.1.1: + resolution: {integrity: sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA==} + engines: {node: '>=10'} + dependencies: + map-age-cleaner: 0.1.3 + mimic-fn: 3.1.0 + /memory-streams@0.1.3: resolution: {integrity: sha512-qVQ/CjkMyMInPaaRMrwWNDvf6boRZXaT/DbQeMYcCWuXPEBf1v8qChOc9OlEVQp2uOvRXa1Qu30fLmKhY6NipA==} dependencies: @@ -12590,6 +16840,10 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + /mimic-fn@3.1.0: + resolution: {integrity: sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==} + engines: {node: '>=8'} + /mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} @@ -12612,6 +16866,15 @@ packages: schema-utils: 4.0.0 webpack: 5.77.0 + /mini-css-extract-plugin@2.7.5(webpack@5.89.0): + resolution: {integrity: sha512-9HaR++0mlgom81s95vvNjxkg52n2b5s//3ZTI1EtzFb98awsLSivs2LMsVqnQ3ay0PVhqWcGNyDaTE961FOcjQ==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^5.0.0 + dependencies: + schema-utils: 4.0.0 + webpack: 5.89.0 + /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: @@ -12630,6 +16893,13 @@ packages: dependencies: brace-expansion: 2.0.1 + /minimatch@7.4.6: + resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minimatch@8.0.3: resolution: {integrity: sha512-tEEvU9TkZgnFDCtpnrEYnPsjT7iUx42aXfs4bzmQ5sMA09/6hZY0jeZcGkXyDagiBOvkUjNo8Viom+Me6+2x7g==} engines: {node: '>=16 || 14 >=14.17'} @@ -12790,6 +17060,11 @@ packages: /mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + /mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dev: true + /mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} dependencies: @@ -12833,7 +17108,17 @@ packages: /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - dev: true + + /ndjson@2.0.0: + resolution: {integrity: sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==} + engines: {node: '>=10'} + hasBin: true + dependencies: + json-stringify-safe: 5.0.1 + minimist: 1.2.8 + readable-stream: 3.6.2 + split2: 3.2.2 + through2: 4.0.2 /negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} @@ -12886,7 +17171,7 @@ packages: dependencies: growly: 1.3.0 is-wsl: 2.2.0 - semver: 7.3.8 + semver: 7.5.4 shellwords: 0.1.1 uuid: 8.3.2 which: 2.0.2 @@ -12894,6 +17179,9 @@ packages: /node-releases@2.0.10: resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + /node-uuid@1.4.8: resolution: {integrity: sha512-TkCET/3rr9mUuRp+CpO7qfgT++aAxfDRaalQhwPFzI9BY/2rCDn6OfpZOVggi1AXfTPpfkTrg5f5WQx5G1uLxA==} deprecated: Use uuid module instead @@ -12920,6 +17208,9 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + /normalize-registry-url@2.0.0: + resolution: {integrity: sha512-3e9FwDyRAhbxXw4slm4Tjv40u78yPwMc/WZkACpqNQOs5sM7wic853AeTLkMFEVhivZkclGYlse8iYsklz0Yvg==} + /normalize-url@4.5.1: resolution: {integrity: sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==} engines: {node: '>=8'} @@ -12934,7 +17225,7 @@ packages: dependencies: hosted-git-info: 6.1.1 proc-log: 3.0.0 - semver: 7.3.8 + semver: 7.5.4 validate-npm-package-name: 5.0.0 /npm-run-path@2.0.2: @@ -12993,6 +17284,9 @@ packages: /object-inspect@1.12.3: resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} @@ -13009,8 +17303,26 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.2.0 - has-symbols: 1.0.3 - object-keys: 1.1.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + /object.fromentries@2.0.7: + resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.3 + dev: false + + /object.groupby@1.0.1: + resolution: {integrity: sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.3 + get-intrinsic: 1.2.2 + dev: false /object.pick@1.3.0: resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} @@ -13027,6 +17339,15 @@ packages: es-abstract: 1.21.2 dev: true + /object.values@1.1.7: + resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.22.3 + dev: false + /on-finished@2.3.0: resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==} engines: {node: '>= 0.8'} @@ -13084,6 +17405,18 @@ packages: word-wrap: 1.2.3 dev: true + /optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: false + /ora@3.4.0: resolution: {integrity: sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==} engines: {node: '>=6'} @@ -13144,6 +17477,12 @@ packages: resolution: {integrity: sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw==} engines: {node: '>=8'} + /p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + dependencies: + p-map: 2.1.0 + /p-finally@1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} @@ -13198,6 +17537,10 @@ packages: dependencies: p-limit: 3.1.0 + /p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + /p-map@3.0.0: resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==} engines: {node: '>=8'} @@ -13227,7 +17570,7 @@ packages: got: 9.6.0 registry-auth-token: 4.2.2 registry-url: 5.1.0 - semver: 6.3.0 + semver: 6.3.1 dev: true /parent-module@1.0.1: @@ -13235,7 +17578,19 @@ packages: engines: {node: '>=6'} dependencies: callsites: 3.1.0 - dev: true + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.23.5 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + /parse-ms@2.1.0: + resolution: {integrity: sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==} + engines: {node: '>=6'} /parse-passwd@1.0.0: resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} @@ -13265,6 +17620,10 @@ packages: resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} engines: {node: '>=0.10.0'} + /path-absolute@1.0.1: + resolution: {integrity: sha512-gds5iRhSeOcDtj8gfWkRHLtZKTPsFVuh7utbjYtvnclw4XM+ffRzJrwqMhOD1PVqef7nBLmgsu1vIujjvAJrAw==} + engines: {node: '>=4'} + /path-exists@3.0.0: resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} engines: {node: '>=4'} @@ -13285,6 +17644,9 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + /path-name@1.0.0: + resolution: {integrity: sha512-/dcAb5vMXH0f51yvMuSUqFpxUcA8JelbRmE5mW/p4CUJxrNgK24IkstnV7ENtg2IDGBOu6izKTG6eilbnbNKWQ==} + /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -13308,6 +17670,12 @@ packages: lru-cache: 7.18.3 minipass: 4.2.5 + /path-temp@2.1.0: + resolution: {integrity: sha512-cMMJTAZlion/RWRRC48UbrDymEIt+/YSD/l8NqjneyDw2rDOBQcP5yRkMB4CYGn47KMhZvbblBP7Z79OsMw72w==} + engines: {node: '>=8.15'} + dependencies: + unique-string: 2.0.0 + /path-to-regexp@0.1.7: resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} @@ -13358,6 +17726,24 @@ packages: dependencies: find-up: 3.0.0 + /pnpm-sync-dependencies-meta-injected@0.0.10: + resolution: {integrity: sha512-kPcYZLaLgo5WhlgWciCJFqdxprIqaR52cY1C8KH3RGdia1YwT1wO/AOKyvOydNBJmpdcLxka2a0La9CaStxG/A==} + engines: {node: '>=16.0.0'} + hasBin: true + dependencies: + '@pnpm/find-workspace-dir': 6.0.2 + '@pnpm/find-workspace-packages': 6.0.9(@pnpm/logger@5.0.0) + '@pnpm/fs.hard-link-dir': 2.0.1(@pnpm/logger@5.0.0) + '@pnpm/logger': 5.0.0 + '@pnpm/read-project-manifest': 5.0.8 + debug: 4.3.4(supports-color@9.4.0) + fs-extra: 11.2.0 + proper-lockfile: 4.1.2 + resolve-package-path: 4.0.3 + supports-color: 9.4.0 + watcher: 2.3.0 + yargs: 17.7.2 + /portfinder@1.0.32: resolution: {integrity: sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==} engines: {node: '>= 0.12.0'} @@ -13435,7 +17821,6 @@ packages: /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - dev: true /prepend-http@2.0.0: resolution: {integrity: sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==} @@ -13461,6 +17846,19 @@ packages: engines: {node: '>=10.13.0'} hasBin: true + /pretty-bytes@5.6.0: + resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} + engines: {node: '>=6'} + + /pretty-ms@7.0.1: + resolution: {integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==} + engines: {node: '>=10'} + dependencies: + parse-ms: 2.1.0 + + /printable-characters@1.0.42: + resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + /printf@0.6.1: resolution: {integrity: sha512-is0ctgGdPJ5951KulgfzvHGwJtZ5ck8l042vRkV6jrkpBzTmb/lueTqguWHy2JfVA+RY6gFVlaZgUS0j7S/dsw==} engines: {node: '>= 0.9.0'} @@ -13492,6 +17890,9 @@ packages: optional: true dev: true + /promise-make-naked@2.1.1: + resolution: {integrity: sha512-BLvgZSNRkQNM5RGL4Cz8wK76WSb+t3VeMJL+/kxRBHI5+nliqZezranGGtiu/ePeFo5+CaLRvvGMzXrBuu2tAA==} + /promise-map-series@0.2.3: resolution: {integrity: sha512-wx9Chrutvqu1N/NHzTayZjE1BgIwt6SJykQoCOic4IZ9yUDjKyVYrpLa/4YCNsV61eRENfs29hrEquVuB13Zlw==} dependencies: @@ -13519,7 +17920,7 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.2.0 - es-abstract: 1.21.2 + es-abstract: 1.22.3 dev: true /propagate@2.0.1: @@ -13527,6 +17928,16 @@ packages: engines: {node: '>= 8'} dev: true + /proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + + /proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + /proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -13586,7 +17997,11 @@ packages: engines: {node: '>= 0.14.0'} dependencies: lodash: 4.17.21 - resolve: 1.22.1 + resolve: 1.22.8 + + /quick-lru@4.0.1: + resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} + engines: {node: '>=8'} /quick-temp@0.1.8: resolution: {integrity: sha512-YsmIFfD9j2zaFwJkzI6eMG7y0lQP7YeWzgtFgNl38pGWZBSXJooZbOWwkcRot7Vt0Fg9L23pX0tqWU3VvLDsiA==} @@ -13626,7 +18041,6 @@ packages: /rambda@7.5.0: resolution: {integrity: sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA==} - dev: true /randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} @@ -13673,6 +18087,20 @@ packages: strip-json-comments: 2.0.1 dev: true + /read-ini-file@4.0.0: + resolution: {integrity: sha512-zz4qv/sKETv7nAkATqSJ9YMbKD8NXRPuA8d17VdYCuNYrVstB1S6UAMU6aytf5vRa9MESbZN7jLZdcmrOxz4gg==} + engines: {node: '>=14.6'} + dependencies: + ini: 3.0.1 + strip-bom: 4.0.0 + + /read-yaml-file@2.1.0: + resolution: {integrity: sha512-UkRNRIwnhG+y7hpqnycCL/xbTk7+ia9VuVTC0S+zVbwd65DI9eUpRMfsWIGrCWxTU/mi+JW8cHQCrv+zfCbEPQ==} + engines: {node: '>=10.13'} + dependencies: + js-yaml: 4.1.0 + strip-bom: 4.0.0 + /readable-stream@1.0.34: resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} dependencies: @@ -13696,6 +18124,10 @@ packages: picomatch: 2.3.1 dev: true + /realpath-missing@1.1.0: + resolution: {integrity: sha512-wnWtnywepjg/eHIgWR97R7UuM5i+qHLA195qdN9UPKvcMqfn60+67S8sPPW3vDlSEfYHoFkKU8IvpCNty3zQvQ==} + engines: {node: '>=10'} + /recast@0.18.10: resolution: {integrity: sha512-XNvYvkfdAN9QewbrxeTOjgINkdY/odTgTS56ZNEWL9Ml0weT4T3sFtvnTuF+Gxyu46ANcRm1ntrF6F5LAJPAaQ==} engines: {node: '>= 4'} @@ -13736,6 +18168,9 @@ packages: /regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + /regenerator-runtime@0.14.0: + resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} + /regenerator-transform@0.10.1: resolution: {integrity: sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==} dependencies: @@ -13747,7 +18182,13 @@ packages: /regenerator-transform@0.15.1: resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} dependencies: - '@babel/runtime': 7.21.0 + '@babel/runtime': 7.23.5 + + /regenerator-transform@0.15.2: + resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + dependencies: + '@babel/runtime': 7.23.5 + dev: true /regex-not@1.0.2: resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} @@ -13764,6 +18205,14 @@ packages: define-properties: 1.2.0 functions-have-names: 1.2.3 + /regexp.prototype.flags@1.5.1: + resolution: {integrity: sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.0 + set-function-name: 2.0.1 + /regexpp@3.2.0: resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} engines: {node: '>=8'} @@ -13830,9 +18279,9 @@ packages: /remove-types@1.0.0: resolution: {integrity: sha512-G7Hk1Q+UJ5DvlNAoJZObxANkBZGiGdp589rVcTW/tYqJWJ5rwfraSnKSQaETN8Epaytw8J40nS/zC7bcHGv36w==} dependencies: - '@babel/core': 7.21.4 - '@babel/plugin-syntax-decorators': 7.21.0(@babel/core@7.21.4) - '@babel/plugin-transform-typescript': 7.21.3(@babel/core@7.21.4) + '@babel/core': 7.23.5 + '@babel/plugin-syntax-decorators': 7.23.3(@babel/core@7.23.5) + '@babel/plugin-transform-typescript': 7.23.5(@babel/core@7.23.5) prettier: 2.8.7 transitivePeerDependencies: - supports-color @@ -13869,7 +18318,6 @@ packages: /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - dev: true /require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} @@ -13878,7 +18326,6 @@ packages: /requireindex@1.2.0: resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} engines: {node: '>=0.10.5'} - dev: true /requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} @@ -13899,7 +18346,6 @@ packages: /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} - dev: true /resolve-package-path@1.2.7: resolution: {integrity: sha512-fVEKHGeK85bGbVFuwO9o1aU0n3vqQGrezPc51JGu9UTXpFQfWq5qCeKxyaRUSvephs+06c5j5rPq/dzHGEo8+Q==} @@ -13912,7 +18358,7 @@ packages: engines: {node: 8.* || 10.* || >= 12} dependencies: path-root: 0.1.1 - resolve: 1.22.1 + resolve: 1.22.8 /resolve-package-path@3.1.0: resolution: {integrity: sha512-2oC2EjWbMJwvSN6Z7DbDfJMnD8MYEouaLn5eIX0j8XwPsYCVIyY9bbnX88YHVkbr8XHqvZrYbxaLPibfTYKZMA==} @@ -13934,6 +18380,10 @@ packages: http-errors: 1.6.3 path-is-absolute: 1.0.1 + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: false + /resolve-url@0.2.1: resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} deprecated: https://github.com/lydell/resolve-url#deprecated @@ -13946,6 +18396,14 @@ packages: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + /responselike@1.0.2: resolution: {integrity: sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==} dependencies: @@ -13973,12 +18431,15 @@ packages: /retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} - dev: true /reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + /right-pad@1.0.1: + resolution: {integrity: sha512-bYBjgxmkvTAfgIYy328fmkwhp39v8lwVgWhhrzxPV3yHtcSqyYKe9/XOhvW48UFjATg3VuJbpsp5822ACNvkmw==} + engines: {node: '>= 0.10'} + /rimraf@2.6.3: resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} hasBin: true @@ -14013,6 +18474,15 @@ packages: rollup: 3.20.2 dev: true + /rollup-plugin-copy-assets@2.0.3(rollup@4.6.1): + resolution: {integrity: sha512-ETShhQGb9SoiwcNrvb3BhUNSGR89Jao0+XxxfzzLW1YsUzx8+rMO4z9oqWWmo6OHUmfNQRvqRj0cAyPkS9lN9w==} + peerDependencies: + rollup: '>=1.1.2' + dependencies: + fs-extra: 7.0.1 + rollup: 4.6.1 + dev: true + /rollup-plugin-delete@2.0.0: resolution: {integrity: sha512-/VpLMtDy+8wwRlDANuYmDa9ss/knGsAgrDhM+tEwB1npHwNu4DYNmDfUL55csse/GHs9Q+SMT/rw9uiaZ3pnzA==} engines: {node: '>=10'} @@ -14040,10 +18510,41 @@ packages: fsevents: 2.3.2 dev: true + /rollup@4.6.1: + resolution: {integrity: sha512-jZHaZotEHQaHLgKr8JnQiDT1rmatjgKlMekyksz+yk9jt/8z9quNjnKNRoaM0wd9DC2QKXjmWWuDYtM3jfF8pQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.6.1 + '@rollup/rollup-android-arm64': 4.6.1 + '@rollup/rollup-darwin-arm64': 4.6.1 + '@rollup/rollup-darwin-x64': 4.6.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.6.1 + '@rollup/rollup-linux-arm64-gnu': 4.6.1 + '@rollup/rollup-linux-arm64-musl': 4.6.1 + '@rollup/rollup-linux-x64-gnu': 4.6.1 + '@rollup/rollup-linux-x64-musl': 4.6.1 + '@rollup/rollup-win32-arm64-msvc': 4.6.1 + '@rollup/rollup-win32-ia32-msvc': 4.6.1 + '@rollup/rollup-win32-x64-msvc': 4.6.1 + fsevents: 2.3.2 + dev: true + /route-recognizer@0.3.4: resolution: {integrity: sha512-2+MhsfPhvauN1O8KaXpXAOfR/fwe8dnUXVM+xw7yt40lJRfPVQxV6yryZm0cgRvAj5fMF/mdRZbL2ptwbs5i2g==} dev: true + /router_js@8.0.3(route-recognizer@0.3.4): + resolution: {integrity: sha512-lSgNMksk/wp8nspLX3Pn6QD499FUjwYMkgP99RxqKEScil4DKC/59YezpEZ318zGtkq8WR01VBhH+/u3InlLgg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + route-recognizer: ^0.3.4 + rsvp: ^4.8.5 + dependencies: + '@glimmer/env': 0.1.7 + route-recognizer: 0.3.4 + dev: true + /rsvp@3.2.1: resolution: {integrity: sha512-Rf4YVNYpKjZ6ASAmibcwTNciQ5Co5Ztq6iZPEykHpkoflnD/K5ryE/rHehFsTm4NJj8nKDhbi3eKBWGogmNnkg==} @@ -14059,6 +18560,11 @@ packages: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} + /run-async@3.0.0: + resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} + engines: {node: '>=0.12.0'} + dev: true + /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: @@ -14075,12 +18581,34 @@ packages: dependencies: tslib: 2.5.0 + /rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + dependencies: + tslib: 2.5.0 + + /safe-array-concat@1.0.1: + resolution: {integrity: sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + has-symbols: 1.0.3 + isarray: 2.0.5 + /safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + /safe-execa@0.1.2: + resolution: {integrity: sha512-vdTshSQ2JsRCgT8eKZWNJIL26C6bVqy1SOmuCMlKHegVeo8KYRobRrefOdUq9OozSPUUiSxrylteeRmLOMFfWg==} + engines: {node: '>=12'} + dependencies: + '@zkochan/which': 2.0.3 + execa: 5.1.1 + path-name: 1.0.0 + /safe-json-parse@1.0.1: resolution: {integrity: sha512-o0JmTu17WGUaUOHa1l0FPGXKBfijbxK6qoHzlkihsDXxzBHvJcA7zgviKR92Xs841rX9pK16unfphLq0/KqX7A==} @@ -14159,6 +18687,14 @@ packages: ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) + /schema-utils@3.3.0: + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + ajv-keywords: 3.5.2(ajv@6.12.6) + /schema-utils@4.0.0: resolution: {integrity: sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==} engines: {node: '>= 12.13.0'} @@ -14176,6 +18712,10 @@ packages: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} hasBin: true + /semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + /semver@7.3.8: resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} engines: {node: '>=10'} @@ -14183,6 +18723,13 @@ packages: dependencies: lru-cache: 6.0.0 + /semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + /send@0.18.0: resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} engines: {node: '>= 0.8.0'} @@ -14228,6 +18775,23 @@ packages: /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + /set-function-length@1.1.1: + resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + get-intrinsic: 1.2.2 + gopd: 1.0.1 + has-property-descriptors: 1.0.0 + + /set-function-name@2.0.1: + resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.1 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.0 + /set-value@2.0.1: resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} engines: {node: '>=0.10.0'} @@ -14276,6 +18840,10 @@ packages: /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + /silent-error@1.1.1: resolution: {integrity: sha512-n4iEKyNcg4v6/jpb3c0/iyH2G1nzUNl7Gpqtn/mHIJK9S/q/7MCfoO4rwVOoO59qPFIc0hVHvMbiOJ0NdtxKKw==} dependencies: @@ -14407,6 +18975,12 @@ packages: smart-buffer: 4.2.0 dev: true + /sort-keys@4.2.0: + resolution: {integrity: sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==} + engines: {node: '>=8'} + dependencies: + is-plain-obj: 2.1.0 + /sort-object-keys@1.1.3: resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==} @@ -14496,6 +19070,11 @@ packages: dependencies: extend-shallow: 3.0.2 + /split2@3.2.2: + resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + dependencies: + readable-stream: 3.6.2 + /sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -14514,6 +19093,12 @@ packages: minipass: 3.3.6 dev: true + /stacktracey@2.1.8: + resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} + dependencies: + as-table: 1.0.55 + get-source: 2.0.12 + /stagehand@1.0.1: resolution: {integrity: sha512-GqXBq2SPWv9hTXDFKS8WrKK1aISB0aKGHZzH+uD4ShAgs+Fz20ZfoerLOm8U+f62iRWLrw6nimOY/uYuTcVhvg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -14537,6 +19122,13 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + /string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + /string-template@0.2.1: resolution: {integrity: sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==} @@ -14575,6 +19167,14 @@ packages: define-properties: 1.2.0 es-abstract: 1.21.2 + /string.prototype.trim@1.2.8: + resolution: {integrity: sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.0 + es-abstract: 1.22.3 + /string.prototype.trimend@1.0.6: resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} dependencies: @@ -14582,6 +19182,13 @@ packages: define-properties: 1.2.0 es-abstract: 1.21.2 + /string.prototype.trimend@1.0.7: + resolution: {integrity: sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.0 + es-abstract: 1.22.3 + /string.prototype.trimstart@1.0.6: resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} dependencies: @@ -14589,6 +19196,13 @@ packages: define-properties: 1.2.0 es-abstract: 1.21.2 + /string.prototype.trimstart@1.0.7: + resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} + dependencies: + call-bind: 1.0.5 + define-properties: 1.2.0 + es-abstract: 1.22.3 + /string_decoder@0.10.31: resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} @@ -14637,7 +19251,13 @@ packages: /strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} - dev: true + + /strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + /strip-comments-strings@1.2.0: + resolution: {integrity: sha512-zwF4bmnyEjZwRhaak9jUWNxc0DoeKBJ7lwSN/LEc8dQXZcUFG6auaaTQJokQWXopLdM3iTx01nQT8E4aL29DAQ==} /strip-eof@1.0.0: resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} @@ -14655,7 +19275,9 @@ packages: /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - dev: true + + /stubborn-fs@1.2.5: + resolution: {integrity: sha512-H2N9c26eXjzL/S/K+i/RHHcFanE74dptvvjM8iwzwbVcWY/zjBbgRqF3K0DY4+OD+uTTASTBvDoxPDaPN02D7g==} /style-loader@2.0.0: resolution: {integrity: sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==} @@ -14676,6 +19298,16 @@ packages: schema-utils: 3.1.1 webpack: 5.77.0 + /style-loader@2.0.0(webpack@5.89.0): + resolution: {integrity: sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.1.1 + webpack: 5.89.0 + /styled_string@0.0.1: resolution: {integrity: sha512-DU2KZiB6VbPkO2tGSqQ9n96ZstUPjW7X4sGO6V2m1myIQluX0p1Ol8BrA/l6/EesqhMqXOIXs3cJNOy1UuU2BA==} @@ -14706,6 +19338,10 @@ packages: dependencies: has-flag: 4.0.0 + /supports-color@9.4.0: + resolution: {integrity: sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==} + engines: {node: '>=12'} + /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -14794,6 +19430,29 @@ packages: terser: 5.16.8 webpack: 5.77.0 + /terser-webpack-plugin@5.3.7(webpack@5.89.0): + resolution: {integrity: sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + dependencies: + '@jridgewell/trace-mapping': 0.3.17 + jest-worker: 27.5.1 + schema-utils: 3.1.1 + serialize-javascript: 6.0.1 + terser: 5.16.8 + webpack: 5.89.0 + /terser@5.16.8: resolution: {integrity: sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA==} engines: {node: '>=10'} @@ -15000,7 +19659,6 @@ packages: /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - dev: true /textextensions@2.6.0: resolution: {integrity: sha512-49WtAWS+tcsy93dRt6P0P3AMD2m5PvXRhuEA0kaXos5ZLlujtYmpmFsB+QvWUSxE1ZsstmYXfQ7L40+EcQgpAQ==} @@ -15042,6 +19700,11 @@ packages: inherits: 2.0.4 readable-stream: 3.6.2 + /through2@4.0.2: + resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + dependencies: + readable-stream: 3.6.2 + /through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} @@ -15063,6 +19726,11 @@ packages: transitivePeerDependencies: - supports-color + /tiny-readdir@2.3.0: + resolution: {integrity: sha512-MEp9nzly4ps44xibXacCQ76pgx2DjSLNUbJGJRT6ERkBZCuOVF4TMRGwexkNA0nO6LcCI9j2XQOsDOLZHhA7wQ==} + dependencies: + promise-make-naked: 2.1.1 + /tmp-sync@1.1.2: resolution: {integrity: sha512-npRDYJiMaPWhcLf6q06v/vA3o/ZG4hfHDiBuj1N3Yeh3GTkFQb1YLFs6inDGMWIHjGidl4Oc1+oXHNKKj5vkDQ==} engines: {node: '>=0.8.0'} @@ -15088,6 +19756,12 @@ packages: dependencies: rimraf: 2.7.1 + /tmp@0.2.1: + resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==} + engines: {node: '>=8.17.0'} + dependencies: + rimraf: 3.0.2 + /tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} @@ -15187,6 +19861,15 @@ packages: transitivePeerDependencies: - supports-color + /ts-api-utils@1.0.3(typescript@5.3.3): + resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} + engines: {node: '>=16.13.0'} + peerDependencies: + typescript: '>=4.2.0' + dependencies: + typescript: 5.3.3 + dev: false + /tsconfig-paths@3.14.2: resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} dependencies: @@ -15194,7 +19877,6 @@ packages: json5: 1.0.2 minimist: 1.2.8 strip-bom: 3.0.0 - dev: true /tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} @@ -15230,7 +19912,6 @@ packages: engines: {node: '>= 0.8.0'} dependencies: prelude-ls: 1.2.1 - dev: true /type-detect@0.1.1: resolution: {integrity: sha512-5rqszGVwYgBoDkIm2oUtvkfZMQ0vk29iDMU0W2qCa3rG0vPDNczCMT4hV/bLBgLg8k8ri6+u3Zbt+S/14eMzlA==} @@ -15249,12 +19930,15 @@ packages: /type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} - dev: true /type-fest@0.21.3: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} + /type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + /type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} @@ -15262,6 +19946,33 @@ packages: media-typer: 0.3.0 mime-types: 2.1.35 + /typed-array-buffer@1.0.0: + resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + get-intrinsic: 1.2.2 + is-typed-array: 1.1.12 + + /typed-array-byte-length@1.0.0: + resolution: {integrity: sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.5 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + + /typed-array-byte-offset@1.0.0: + resolution: {integrity: sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.5 + for-each: 0.3.3 + has-proto: 1.0.1 + is-typed-array: 1.1.12 + /typed-array-length@1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} dependencies: @@ -15283,6 +19994,11 @@ packages: hasBin: true dev: true + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + engines: {node: '>=14.17'} + hasBin: true + /typical@4.0.0: resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} engines: {node: '>=8'} @@ -15401,6 +20117,16 @@ packages: escalade: 3.1.1 picocolors: 1.0.0 + /update-browserslist-db@1.0.13(browserslist@4.22.2): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.22.2 + escalade: 3.1.1 + picocolors: 1.0.0 + /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: @@ -15459,7 +20185,7 @@ packages: resolution: {integrity: sha512-nd2HUpKc6RWblPZQ2GDuI65sxJ2n/UqZwSBVtj64xlWjMx0m7ZB2m9b2JS3v1f+n9VWH/dd1CMhkHfP6pIdckA==} dependencies: resolve-package-path: 3.1.0 - semver: 7.3.8 + semver: 7.5.4 dev: true /validate-peer-dependencies@2.2.0: @@ -15467,7 +20193,7 @@ packages: engines: {node: '>= 12'} dependencies: resolve-package-path: 4.0.3 - semver: 7.3.8 + semver: 7.5.4 /vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} @@ -15560,6 +20286,13 @@ packages: transitivePeerDependencies: - supports-color + /watcher@2.3.0: + resolution: {integrity: sha512-6hVpT1OhmYTZhsgUND2o2gTL79TosB1rH8DWzDO7KBlyR9Yuxg/LXUGeHJqjjvwpnyHT7uUdDwWczprJuqae9Q==} + dependencies: + dettle: 1.0.1 + stubborn-fs: 1.2.5 + tiny-readdir: 2.3.0 + /watchpack@2.4.0: resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} engines: {node: '>=10.13.0'} @@ -15633,6 +20366,45 @@ packages: - esbuild - uglify-js + /webpack@5.89.0: + resolution: {integrity: sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + dependencies: + '@types/eslint-scope': 3.7.4 + '@types/estree': 1.0.0 + '@webassemblyjs/ast': 1.11.6 + '@webassemblyjs/wasm-edit': 1.11.6 + '@webassemblyjs/wasm-parser': 1.11.6 + acorn: 8.8.2 + acorn-import-assertions: 1.9.0(acorn@8.8.2) + browserslist: 4.21.5 + chrome-trace-event: 1.0.3 + enhanced-resolve: 5.15.0 + es-module-lexer: 1.4.1 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.3.0 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.7(webpack@5.89.0) + watchpack: 2.4.0 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + /websocket-driver@0.7.4: resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} engines: {node: '>=0.8.0'} @@ -15711,6 +20483,16 @@ packages: is-string: 1.0.7 is-symbol: 1.0.4 + /which-typed-array@1.1.13: + resolution: {integrity: sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.5 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + /which-typed-array@1.1.9: resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} engines: {node: '>= 0.4'} @@ -15735,11 +20517,24 @@ packages: dependencies: isexe: 2.0.0 + /which@3.0.1: + resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + dependencies: + isexe: 2.0.0 + /wide-align@1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} dependencies: string-width: 4.2.3 + /widest-line@3.1.0: + resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} + engines: {node: '>=8'} + dependencies: + string-width: 4.2.3 + /word-wrap@1.2.3: resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} engines: {node: '>=0.10.0'} @@ -15755,7 +20550,7 @@ packages: /workerpool@3.1.2: resolution: {integrity: sha512-WJFA0dGqIK7qj7xPTqciWBH5DlJQzoPjsANvc3Y4hNB0SScT+Emjvt0jPPkDBUjBNngX1q9hHgt1Gfwytu6pug==} dependencies: - '@babel/core': 7.21.4 + '@babel/core': 7.23.5 object-assign: 4.1.1 rsvp: 4.8.5 transitivePeerDependencies: @@ -15768,6 +20563,15 @@ packages: /workerpool@6.4.0: resolution: {integrity: sha512-i3KR1mQMNwY2wx20ozq2EjISGtQWDIfV56We+yGJ5yDs8jTwQiLLaqHlkBHITlCuJnYlVRmXegxFxZg7gqI++A==} + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + /wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -15787,6 +20591,20 @@ packages: signal-exit: 3.0.7 typedarray-to-buffer: 3.1.5 + /write-file-atomic@5.0.1: + resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.1.0 + + /write-yaml-file@5.0.0: + resolution: {integrity: sha512-FdNA4RyH1L43TlvGG8qOMIfcEczwA5ij+zLXUy3Z83CjxhLvcV7/Q/8pk22wnCgYw7PJhtK+7lhO+qqyT4NdvQ==} + engines: {node: '>=16.14'} + dependencies: + js-yaml: 4.1.0 + write-file-atomic: 5.0.1 + /ws@7.5.9: resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} engines: {node: '>=8.3.0'} @@ -15849,7 +20667,6 @@ packages: /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - dev: true /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} @@ -15872,7 +20689,6 @@ packages: /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - dev: true /yargs-unparser@2.0.0: resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} @@ -15910,6 +20726,18 @@ packages: yargs-parser: 21.1.1 dev: true + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -15977,6 +20805,28 @@ packages: - supports-color - webpack + file:packages/active-record(@ember-data/request-utils@4.12.5)(@ember-data/store@4.12.5)(@ember/string@3.1.1)(ember-inflector@4.0.2): + resolution: {directory: packages/active-record, type: directory} + id: file:packages/active-record + name: '@ember-data/active-record' + version: 4.12.5 + engines: {node: 16.* || >= 18.*} + peerDependencies: + '@ember-data/request-utils': workspace:4.12.5 + '@ember-data/store': ^4.12.0 || ^5.0.0 + '@ember/string': ^3.1.1 + ember-inflector: ^4.0.2 + dependencies: + '@ember-data/request-utils': file:packages/request-utils + '@ember-data/store': file:packages/store(@babel/core@7.23.5)(@ember-data/graph@4.12.5)(@ember-data/json-api@4.12.5)(@ember-data/legacy-compat@4.12.5)(@ember-data/model@4.12.5)(@ember-data/tracking@4.12.5)(@ember/string@3.1.1)(@glimmer/tracking@1.1.2)(ember-source@5.4.0) + '@ember/string': 3.1.1 + ember-cli-babel: 7.26.11 + ember-inflector: 4.0.2 + pnpm-sync-dependencies-meta-injected: 0.0.10 + transitivePeerDependencies: + - supports-color + dev: true + file:packages/adapter: resolution: {directory: packages/adapter, type: directory} name: '@ember-data/adapter' @@ -16058,6 +20908,28 @@ packages: - supports-color - webpack + file:packages/debug(@ember-data/store@4.12.5)(@ember/string@3.1.1)(webpack@5.89.0): + resolution: {directory: packages/debug, type: directory} + id: file:packages/debug + name: '@ember-data/debug' + version: 4.12.5 + engines: {node: 16.* || >= 18.*} + peerDependencies: + '@ember-data/store': workspace:4.12.5 + '@ember/string': ^3.0.1 + dependencies: + '@ember-data/private-build-infra': file:packages/private-build-infra + '@ember-data/store': file:packages/store(@babel/core@7.23.5)(@ember-data/graph@4.12.5)(@ember-data/json-api@4.12.5)(@ember-data/legacy-compat@4.12.5)(@ember-data/model@4.12.5)(@ember-data/tracking@4.12.5)(@ember/string@3.1.1)(@glimmer/tracking@1.1.2)(ember-source@5.4.0) + '@ember/edition-utils': 1.2.0 + '@ember/string': 3.1.1 + '@embroider/macros': 1.10.0 + ember-auto-import: 2.6.1(webpack@5.89.0) + ember-cli-babel: 7.26.11 + transitivePeerDependencies: + - supports-color + - webpack + dev: true + file:packages/debug(@ember-data/store@4.12.5)(webpack@5.77.0): resolution: {directory: packages/debug, type: directory} id: file:packages/debug @@ -16078,6 +20950,35 @@ packages: - supports-color - webpack + file:packages/diagnostic(@ember/test-helpers@3.2.1)(@embroider/addon-shim@1.8.7)(ember-cli-test-loader@3.1.0): + resolution: {directory: packages/diagnostic, type: directory} + id: file:packages/diagnostic + name: '@warp-drive/diagnostic' + version: 4.12.5 + engines: {node: 16.* || >= 18.*} + peerDependencies: + '@ember/test-helpers': '>= 3.2.0' + '@embroider/addon-shim': '>= 1.8.7' + ember-cli-test-loader: '>= 3.1.0' + peerDependenciesMeta: + '@ember/test-helpers': + optional: true + '@embroider/addon-shim': + optional: true + ember-cli-test-loader: + optional: true + dependencies: + '@ember/test-helpers': 3.2.1(ember-source@5.4.0)(webpack@5.89.0) + '@embroider/addon-shim': 1.8.7 + chalk: 5.3.0 + debug: 4.3.4 + ember-cli-test-loader: 3.1.0 + pnpm-sync-dependencies-meta-injected: 0.0.10 + tmp: 0.2.1 + transitivePeerDependencies: + - supports-color + dev: true + file:packages/graph(@ember-data/store@4.12.5): resolution: {directory: packages/graph, type: directory} id: file:packages/graph @@ -16408,19 +21309,64 @@ packages: - ember-source - supports-color + file:packages/model(@babel/core@7.23.5)(@ember-data/debug@4.12.5)(@ember-data/graph@4.12.5)(@ember-data/json-api@4.12.5)(@ember-data/legacy-compat@4.12.5)(@ember-data/store@4.12.5)(@ember-data/tracking@4.12.5)(@ember/string@3.1.1)(ember-inflector@4.0.2)(ember-source@5.4.0): + resolution: {directory: packages/model, type: directory} + id: file:packages/model + name: '@ember-data/model' + version: 4.12.5 + engines: {node: 16.* || >= 18.*} + peerDependencies: + '@ember-data/debug': workspace:4.12.5 + '@ember-data/graph': workspace:4.12.5 + '@ember-data/json-api': workspace:4.12.5 + '@ember-data/legacy-compat': workspace:4.12.5 + '@ember-data/store': workspace:4.12.5 + '@ember-data/tracking': workspace:4.12.5 + '@ember/string': ^3.0.1 + ember-inflector: ^4.0.2 + peerDependenciesMeta: + '@ember-data/debug': + optional: true + '@ember-data/graph': + optional: true + '@ember-data/json-api': + optional: true + dependencies: + '@ember-data/debug': file:packages/debug(@ember-data/store@4.12.5)(@ember/string@3.1.1)(webpack@5.89.0) + '@ember-data/graph': file:packages/graph(@ember-data/store@4.12.5) + '@ember-data/json-api': file:packages/json-api(@ember-data/graph@4.12.5)(@ember-data/store@4.12.5) + '@ember-data/legacy-compat': file:packages/legacy-compat(@ember-data/graph@4.12.5)(@ember-data/json-api@4.12.5) + '@ember-data/private-build-infra': file:packages/private-build-infra + '@ember-data/store': file:packages/store(@babel/core@7.23.5)(@ember-data/graph@4.12.5)(@ember-data/json-api@4.12.5)(@ember-data/legacy-compat@4.12.5)(@ember-data/model@4.12.5)(@ember-data/tracking@4.12.5)(@ember/string@3.1.1)(@glimmer/tracking@1.1.2)(ember-source@5.4.0) + '@ember-data/tracking': file:packages/tracking + '@ember/edition-utils': 1.2.0 + '@ember/string': 3.1.1 + '@embroider/macros': 1.10.0 + ember-cached-decorator-polyfill: 1.0.1(@babel/core@7.23.5)(ember-source@5.4.0) + ember-cli-babel: 7.26.11 + ember-cli-string-utils: 1.1.0 + ember-cli-test-info: 1.0.0 + ember-inflector: 4.0.2 + inflection: 2.0.1 + transitivePeerDependencies: + - '@babel/core' + - ember-source + - supports-color + dev: true + file:packages/private-build-infra: resolution: {directory: packages/private-build-infra, type: directory} name: '@ember-data/private-build-infra' version: 4.12.5 engines: {node: 16.* || >= 18.*} dependencies: - '@babel/core': 7.21.4 - '@babel/plugin-transform-block-scoping': 7.21.0(@babel/core@7.21.4) - '@babel/runtime': 7.21.0 + '@babel/core': 7.23.5 + '@babel/plugin-transform-block-scoping': 7.23.4(@babel/core@7.23.5) + '@babel/runtime': 7.23.5 '@ember/edition-utils': 1.2.0 '@embroider/macros': 1.10.0 babel-import-util: 1.3.0 - babel-plugin-debug-macros: 0.3.4(@babel/core@7.21.4) + babel-plugin-debug-macros: 0.3.4(@babel/core@7.23.5) babel-plugin-filter-imports: 4.0.0 babel6-plugin-strip-class-callcheck: 6.0.0 broccoli-debug: 0.6.5 @@ -16439,7 +21385,7 @@ packages: npm-git-info: 1.0.3 rimraf: 4.4.1 rsvp: 4.8.5 - semver: 7.3.8 + semver: 7.5.4 silent-error: 1.1.1 transitivePeerDependencies: - supports-color @@ -16457,6 +21403,40 @@ packages: transitivePeerDependencies: - supports-color + file:packages/request-utils: + resolution: {directory: packages/request-utils, type: directory} + name: '@ember-data/request-utils' + version: 4.12.5 + engines: {node: 16.* || >= 18.*} + dependencies: + ember-cli-babel: 7.26.11 + pnpm-sync-dependencies-meta-injected: 0.0.10 + transitivePeerDependencies: + - supports-color + dev: true + + file:packages/rest(@ember-data/request-utils@4.12.5)(@ember-data/store@4.12.5)(@ember/string@3.1.1)(ember-inflector@4.0.2): + resolution: {directory: packages/rest, type: directory} + id: file:packages/rest + name: '@ember-data/rest' + version: 4.12.5 + engines: {node: 16.* || >= 18.*} + peerDependencies: + '@ember-data/request-utils': workspace:4.12.5 + '@ember-data/store': ^4.12.0 || ^5.0.0 + '@ember/string': ^3.1.1 + ember-inflector: ^4.0.2 + dependencies: + '@ember-data/request-utils': file:packages/request-utils + '@ember-data/store': file:packages/store(@babel/core@7.23.5)(@ember-data/graph@4.12.5)(@ember-data/json-api@4.12.5)(@ember-data/legacy-compat@4.12.5)(@ember-data/model@4.12.5)(@ember-data/tracking@4.12.5)(@ember/string@3.1.1)(@glimmer/tracking@1.1.2)(ember-source@5.4.0) + '@ember/string': 3.1.1 + ember-cli-babel: 7.26.11 + ember-inflector: 4.0.2 + pnpm-sync-dependencies-meta-injected: 0.0.10 + transitivePeerDependencies: + - supports-color + dev: true + file:packages/serializer: resolution: {directory: packages/serializer, type: directory} name: '@ember-data/serializer' @@ -16748,6 +21728,83 @@ packages: - supports-color dev: true + file:packages/store(@babel/core@7.23.5)(@ember-data/graph@4.12.5)(@ember-data/json-api@4.12.5)(@ember-data/legacy-compat@4.12.5)(@ember-data/model@4.12.5)(@ember-data/tracking@4.12.5)(@ember/string@3.1.1)(@glimmer/tracking@1.1.2)(ember-source@5.4.0): + resolution: {directory: packages/store, type: directory} + id: file:packages/store + name: '@ember-data/store' + version: 4.12.5 + engines: {node: 16.* || >= 18.*} + peerDependencies: + '@ember-data/graph': workspace:4.12.5 + '@ember-data/json-api': workspace:4.12.5 + '@ember-data/legacy-compat': workspace:4.12.5 + '@ember-data/model': workspace:4.12.5 + '@ember-data/tracking': workspace:4.12.5 + '@ember/string': ^3.0.1 + '@glimmer/tracking': ^1.1.2 + peerDependenciesMeta: + '@ember-data/graph': + optional: true + '@ember-data/json-api': + optional: true + '@ember-data/legacy-compat': + optional: true + '@ember-data/model': + optional: true + dependencies: + '@ember-data/graph': file:packages/graph(@ember-data/store@4.12.5) + '@ember-data/json-api': file:packages/json-api(@ember-data/graph@4.12.5)(@ember-data/store@4.12.5) + '@ember-data/legacy-compat': file:packages/legacy-compat(@ember-data/graph@4.12.5)(@ember-data/json-api@4.12.5) + '@ember-data/model': file:packages/model(@babel/core@7.23.5)(@ember-data/debug@4.12.5)(@ember-data/graph@4.12.5)(@ember-data/json-api@4.12.5)(@ember-data/legacy-compat@4.12.5)(@ember-data/store@4.12.5)(@ember-data/tracking@4.12.5)(@ember/string@3.1.1)(ember-inflector@4.0.2)(ember-source@5.4.0) + '@ember-data/private-build-infra': file:packages/private-build-infra + '@ember-data/tracking': file:packages/tracking + '@ember/string': 3.1.1 + '@embroider/macros': 1.10.0 + '@glimmer/tracking': 1.1.2 + ember-cached-decorator-polyfill: 1.0.1(@babel/core@7.23.5)(ember-source@5.4.0) + ember-cli-babel: 7.26.11 + transitivePeerDependencies: + - '@babel/core' + - ember-source + - supports-color + dev: true + + file:packages/store(@babel/core@7.23.5)(@ember-data/tracking@4.12.5)(@ember/string@3.1.1)(ember-source@5.4.0): + resolution: {directory: packages/store, type: directory} + id: file:packages/store + name: '@ember-data/store' + version: 4.12.5 + engines: {node: 16.* || >= 18.*} + peerDependencies: + '@ember-data/graph': workspace:4.12.5 + '@ember-data/json-api': workspace:4.12.5 + '@ember-data/legacy-compat': workspace:4.12.5 + '@ember-data/model': workspace:4.12.5 + '@ember-data/tracking': workspace:4.12.5 + '@ember/string': ^3.0.1 + '@glimmer/tracking': ^1.1.2 + peerDependenciesMeta: + '@ember-data/graph': + optional: true + '@ember-data/json-api': + optional: true + '@ember-data/legacy-compat': + optional: true + '@ember-data/model': + optional: true + dependencies: + '@ember-data/private-build-infra': file:packages/private-build-infra + '@ember-data/tracking': file:packages/tracking + '@ember/string': 3.1.1 + '@embroider/macros': 1.10.0 + ember-cached-decorator-polyfill: 1.0.1(@babel/core@7.23.5)(ember-source@5.4.0) + ember-cli-babel: 7.26.11 + transitivePeerDependencies: + - '@babel/core' + - ember-source + - supports-color + dev: true + file:packages/tracking: resolution: {directory: packages/tracking, type: directory} name: '@ember-data/tracking' @@ -16770,16 +21827,16 @@ packages: '@ember/edition-utils': 1.2.0 '@embroider/macros': 1.10.0 broccoli-merge-trees: 4.2.0 - ember-auto-import: 2.6.1(webpack@5.77.0) + ember-auto-import: 2.6.1(webpack@5.89.0) ember-cli-babel: 7.26.11 ember-cli-blueprint-test-helpers: 0.19.2 ember-get-config: 2.1.1 qunit: 2.19.4 qunit-dom: 2.0.0 rsvp: 4.8.5 - semver: 7.3.8 + semver: 7.5.4 testem: 3.10.1 - webpack: 5.77.0 + webpack: 5.89.0 transitivePeerDependencies: - '@swc/core' - arc-templates diff --git a/tests/builders/README.md b/tests/builders/README.md new file mode 100644 index 00000000000..d506f5d27d5 --- /dev/null +++ b/tests/builders/README.md @@ -0,0 +1,8 @@ +# Builder Tests + +Provides testing for the Request and URL Building Utils + +- @ember-data/active-record/request +- @ember-data/json-api/request +- @ember-data/rest/request +- @ember-data/request-utils diff --git a/tests/builders/app/app.ts b/tests/builders/app/app.ts new file mode 100644 index 00000000000..1f39476ae86 --- /dev/null +++ b/tests/builders/app/app.ts @@ -0,0 +1,16 @@ +import Application from '@ember/application'; + +import loadInitializers from 'ember-load-initializers'; + +import config from './config/environment'; +import Resolver from './resolver'; + +class App extends Application { + modulePrefix = config.modulePrefix; + podModulePrefix = config.podModulePrefix; + Resolver = Resolver; +} + +loadInitializers(App, config.modulePrefix); + +export default App; diff --git a/tests/builders/app/config/environment.d.ts b/tests/builders/app/config/environment.d.ts new file mode 100644 index 00000000000..f989849605d --- /dev/null +++ b/tests/builders/app/config/environment.d.ts @@ -0,0 +1,16 @@ +export default config; + +/** + * Type declarations for + * import config from './config/environment' + * + * For now these need to be managed by the developer + * since different ember addons can materialize new entries. + */ +declare const config: { + environment: 'production' | 'development' | 'testing'; + modulePrefix: string; + podModulePrefix: string; + locationType: string; + rootURL: string; +}; diff --git a/tests/builders/app/index.html b/tests/builders/app/index.html new file mode 100644 index 00000000000..15be5ed9d19 --- /dev/null +++ b/tests/builders/app/index.html @@ -0,0 +1,25 @@ + + + + + + EmberData Request Builders Test App + + + + {{content-for "head"}} + + + + + {{content-for "head-footer"}} + + + {{content-for "body"}} + + + + + {{content-for "body-footer"}} + + diff --git a/tests/builders/app/models/user-setting.ts b/tests/builders/app/models/user-setting.ts new file mode 100644 index 00000000000..e8f3511d0a0 --- /dev/null +++ b/tests/builders/app/models/user-setting.ts @@ -0,0 +1,5 @@ +import Model, { attr } from '@ember-data/model'; + +export default class UserSetting extends Model { + @attr declare name: string; +} diff --git a/tests/builders/app/resolver.ts b/tests/builders/app/resolver.ts new file mode 100644 index 00000000000..2fb563d6c04 --- /dev/null +++ b/tests/builders/app/resolver.ts @@ -0,0 +1,3 @@ +import Resolver from 'ember-resolver'; + +export default Resolver; diff --git a/tests/builders/app/router.ts b/tests/builders/app/router.ts new file mode 100644 index 00000000000..7525f056ab3 --- /dev/null +++ b/tests/builders/app/router.ts @@ -0,0 +1,12 @@ +import EmberRouter from '@ember/routing/router'; + +import config from './config/environment'; + +const Router = EmberRouter.extend({ + location: config.locationType, + rootURL: config.rootURL, +}); + +Router.map(function () {}); + +export default Router; diff --git a/tests/builders/app/services/store.ts b/tests/builders/app/services/store.ts new file mode 100644 index 00000000000..a531cfe4489 --- /dev/null +++ b/tests/builders/app/services/store.ts @@ -0,0 +1,45 @@ +import JSONAPICache from '@ember-data/json-api'; +import type Model from '@ember-data/model'; +import { instantiateRecord, teardownRecord } from '@ember-data/model'; +import { buildSchema, modelFor } from '@ember-data/model/hooks'; +import RequestManager from '@ember-data/request'; +import Fetch from '@ember-data/request/fetch'; +import DataStore, { CacheHandler } from '@ember-data/store'; +// @ts-expect-error FIXME: IDK where to get this +import type { CacheCapabilitiesManager } from '@ember-data/store/-types/q/cache-store-wrapper'; +import type { Cache } from '@ember-data/types/q/cache'; +import type { ModelSchema } from '@ember-data/types/q/ds-model'; +import type { StableRecordIdentifier } from '@ember-data/types/q/identifier'; +import { RecordInstance } from '@ember-data/types/q/record-instance'; + +export default class Store extends DataStore { + constructor(args: Record | undefined) { + super(args); + + const manager = (this.requestManager = new RequestManager()); + manager.use([Fetch]); + manager.useCache(CacheHandler); + + this.registerSchema(buildSchema(this)); + } + + override createCache(capabilities: CacheCapabilitiesManager): Cache { + return new JSONAPICache(capabilities); + } + + override instantiateRecord( + identifier: StableRecordIdentifier, + createRecordArgs: { [key: string]: unknown } + ): RecordInstance { + return instantiateRecord.call(this, identifier, createRecordArgs); + } + + override teardownRecord(record: Model): void { + return teardownRecord.call(this, record); + } + + // @ts-expect-error FIXME: + override modelFor(type: string): ModelSchema { + return modelFor.call(this, type)!; + } +} diff --git a/tests/builders/app/styles/app.css b/tests/builders/app/styles/app.css new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/builders/app/templates/.gitkeep b/tests/builders/app/templates/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/builders/app/templates/application.hbs b/tests/builders/app/templates/application.hbs new file mode 100644 index 00000000000..578920ea827 --- /dev/null +++ b/tests/builders/app/templates/application.hbs @@ -0,0 +1,7 @@ +
+

EmberData Graph Tests

+ + {{outlet}} + + Tests +
diff --git a/tests/builders/config/environment.js b/tests/builders/config/environment.js new file mode 100644 index 00000000000..08309c1f849 --- /dev/null +++ b/tests/builders/config/environment.js @@ -0,0 +1,51 @@ +'use strict'; + +module.exports = function (environment) { + const ENV = { + modulePrefix: 'builders-test-app', + environment, + rootURL: '/', + locationType: 'history', + EmberENV: { + FEATURES: { + // Here you can enable experimental features on an ember canary build + // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true + }, + EXTEND_PROTOTYPES: { + // Prevent Ember Data from overriding Date.parse. + Date: false, + }, + }, + + APP: { + // Here you can pass flags/options to your application instance + // when it is created + }, + }; + + if (environment === 'development') { + // ENV.APP.LOG_RESOLVER = true; + // ENV.APP.LOG_ACTIVE_GENERATION = true; + // ENV.APP.LOG_TRANSITIONS = true; + // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; + // ENV.APP.LOG_VIEW_LOOKUPS = true; + } + + if (environment === 'test') { + // Testem prefers this... + ENV.locationType = 'none'; + + // keep test console output quieter + ENV.APP.LOG_ACTIVE_GENERATION = false; + ENV.APP.LOG_VIEW_LOOKUPS = false; + + ENV.APP.rootElement = '#ember-testing'; + ENV.APP.autoboot = false; + } + + if (environment === 'production') { + // here you can enable a production-specific feature + } + + return ENV; +}; diff --git a/tests/builders/config/optional-features.json b/tests/builders/config/optional-features.json new file mode 100644 index 00000000000..b26286e2ecd --- /dev/null +++ b/tests/builders/config/optional-features.json @@ -0,0 +1,6 @@ +{ + "application-template-wrapper": false, + "default-async-observers": true, + "jquery-integration": false, + "template-only-glimmer-components": true +} diff --git a/tests/builders/config/targets.js b/tests/builders/config/targets.js new file mode 100644 index 00000000000..b6756da2517 --- /dev/null +++ b/tests/builders/config/targets.js @@ -0,0 +1,13 @@ +'use strict'; + +let browsers = ['last 1 Chrome versions', 'last 1 Firefox versions', 'last 1 Safari versions']; +const isProd = process.env.EMBER_ENV === 'production'; + +if (isProd) { + browsers = ['last 2 Chrome versions', 'last 2 Firefox versions', 'Safari 12', 'last 2 Edge versions']; +} + +module.exports = { + browsers, + node: 'current', +}; diff --git a/tests/builders/diagnostic.js b/tests/builders/diagnostic.js new file mode 100644 index 00000000000..ede75dbb1ad --- /dev/null +++ b/tests/builders/diagnostic.js @@ -0,0 +1,3 @@ +import launch from '@warp-drive/diagnostic/server/default-setup.js'; + +await launch(); diff --git a/tests/builders/ember-cli-build.js b/tests/builders/ember-cli-build.js new file mode 100644 index 00000000000..35799698982 --- /dev/null +++ b/tests/builders/ember-cli-build.js @@ -0,0 +1,40 @@ +'use strict'; + +const EmberApp = require('ember-cli/lib/broccoli/ember-app'); + +module.exports = function (defaults) { + const compatWith = process.env.EMBER_DATA_FULL_COMPAT ? '99.0' : null; + const app = new EmberApp(defaults, { + emberData: { + compatWith, + }, + tests: true, + babel: { + // this ensures that the same build-time code stripping that is done + // for library packages is also done for our tests and dummy app + plugins: [ + ...require('@ember-data/private-build-infra/src/debug-macros')({ + compatWith, + debug: {}, + features: {}, + deprecations: {}, + env: require('@ember-data/private-build-infra/src/utilities/get-env')(), + }), + ], + }, + 'ember-cli-babel': { + throwUnlessParallelizable: true, + enableTypeScriptTransform: true, + }, + }); + + /* + This build file specifies the options for the dummy test app of this + addon, located in `/tests/dummy` + This build file does *not* influence how the addon or the app using it + behave. You most likely want to be modifying `./index.js` or app's build file + */ + app.import('node_modules/@warp-drive/diagnostic/dist/styles/dom-reporter.css'); + + return app.toTree(); +}; diff --git a/tests/builders/package.json b/tests/builders/package.json new file mode 100644 index 00000000000..cc53152883e --- /dev/null +++ b/tests/builders/package.json @@ -0,0 +1,130 @@ +{ + "name": "builders-test-app", + "version": "4.12.5", + "description": "Provides tests for URL and Request Building Capabilities", + "keywords": [], + "repository": { + "type": "git", + "url": "git+ssh://git@github.com:emberjs/data.git", + "directory": "tests/builders" + }, + "license": "MIT", + "author": "", + "directories": { + "test": "tests" + }, + "scripts": { + "build:tests": "IS_TESTING=true EMBER_CLI_TEST_COMMAND=true ember build --output-path=dist-test --suppress-sizes", + "build:production": "pnpm build:tests -e production", + "test": "bun ./diagnostic.js", + "test:production": "bun ./diagnostic.js", + "_syncPnpm": "bun run sync-dependencies-meta-injected" + }, + "dependenciesMeta": { + "@ember-data/json-api": { + "injected": true + }, + "@ember-data/rest": { + "injected": true + }, + "@ember-data/store": { + "injected": true + }, + "@ember-data/model": { + "injected": true + }, + "@ember-data/legacy-compat": { + "injected": true + }, + "@ember-data/request": { + "injected": true + }, + "@ember-data/request-utils": { + "injected": true + }, + "@ember-data/active-record": { + "injected": true + }, + "@ember-data/private-build-infra": { + "injected": true + }, + "@ember-data/unpublished-test-infra": { + "injected": true + }, + "@warp-drive/diagnostic": { + "injected": true + }, + "@ember-data/graph": { + "injected": true + }, + "@ember-data/tracking": { + "injected": true + }, + "@ember/string": { + "injected": true + }, + "ember-inflector": { + "injected": true + }, + "@ember-data/debug": { + "injected": true + } + }, + "devDependencies": { + "@babel/core": "^7.23.3", + "@babel/runtime": "^7.23.4", + "@ember-data/active-record": "workspace:4.12.5", + "@ember-data/debug": "workspace:4.12.5", + "@ember-data/graph": "workspace:4.12.5", + "@ember-data/json-api": "workspace:4.12.5", + "@ember-data/legacy-compat": "workspace:4.12.5", + "@ember-data/model": "workspace:4.12.5", + "@ember-data/private-build-infra": "workspace:4.12.5", + "@ember-data/request": "workspace:4.12.5", + "@ember-data/request-utils": "workspace:4.12.5", + "@ember-data/rest": "workspace:4.12.5", + "@ember-data/store": "workspace:4.12.5", + "@ember-data/tracking": "workspace:4.12.5", + "@ember-data/unpublished-test-infra": "workspace:4.12.5", + "@ember/edition-utils": "^1.2.0", + "@ember/optional-features": "^2.0.0", + "@ember/string": "3.1.1", + "@ember/test-helpers": "^3.2.0", + "@embroider/addon-shim": "^1.8.7", + "@glimmer/component": "^1.1.2", + "@glimmer/tracking": "^1.1.2", + "@warp-drive/diagnostic": "workspace:4.12.5", + "@warp-drive/internal-config": "workspace:4.12.5", + "ember-auto-import": "^2.6.3", + "ember-cli": "~5.4.1", + "ember-cli-babel": "^8.2.0", + "ember-cli-dependency-checker": "^3.3.2", + "ember-cli-htmlbars": "^6.3.0", + "ember-cli-inject-live-reload": "^2.1.0", + "ember-cli-test-loader": "^3.1.0", + "ember-disable-prototype-extensions": "^1.1.3", + "ember-inflector": "^4.0.2", + "ember-load-initializers": "^2.1.2", + "ember-maybe-import-regenerator": "^1.0.0", + "ember-resolver": "^11.0.1", + "ember-source": "~5.4.0", + "ember-source-channel-url": "^3.0.0", + "loader.js": "^4.7.0", + "silent-error": "^1.1.1", + "typescript": "^5.3.2", + "webpack": "^5.89.0" + }, + "ember": { + "edition": "octane" + }, + "engines": { + "node": "16.* || >= 18.*" + }, + "volta": { + "extends": "../../package.json" + }, + "packageManager": "pnpm@8.11.0", + "dependencies": { + "pnpm-sync-dependencies-meta-injected": "0.0.10" + } +} diff --git a/tests/builders/tests/.gitkeep b/tests/builders/tests/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/builders/tests/helpers/utils.ts b/tests/builders/tests/helpers/utils.ts new file mode 100644 index 00000000000..3c2163ea19f --- /dev/null +++ b/tests/builders/tests/helpers/utils.ts @@ -0,0 +1,7 @@ +export function headersToObject(headers: Headers) { + const result: { [key: string]: string } = {}; + headers.forEach((value, key) => { + result[key] = value; + }); + return result; +} diff --git a/tests/builders/tests/index.html b/tests/builders/tests/index.html new file mode 100644 index 00000000000..644b3bd1094 --- /dev/null +++ b/tests/builders/tests/index.html @@ -0,0 +1,37 @@ + + + + + + Request Builder Tests + + + + {{content-for "head"}} + {{content-for "test-head"}} + + + + + {{content-for "head-footer"}} + {{content-for "test-head-footer"}} + + + {{content-for "body"}} + {{content-for "test-body"}} + +
+
+
+
+ + + + + + + {{content-for "body-footer"}} + {{content-for "test-body-footer"}} + + + diff --git a/tests/builders/tests/integration/create-record-test.ts b/tests/builders/tests/integration/create-record-test.ts new file mode 100644 index 00000000000..ef8ea932548 --- /dev/null +++ b/tests/builders/tests/integration/create-record-test.ts @@ -0,0 +1,5 @@ +import { module, todo } from '@warp-drive/diagnostic'; + +module('Integration - createRecord', function (hooks) { + todo('backport @ember-data/json-api/request tests', () => {}); +}); diff --git a/tests/builders/tests/integration/delete-record-test.ts b/tests/builders/tests/integration/delete-record-test.ts new file mode 100644 index 00000000000..604ad68f3d6 --- /dev/null +++ b/tests/builders/tests/integration/delete-record-test.ts @@ -0,0 +1,5 @@ +import { module, todo } from '@warp-drive/diagnostic'; + +module('Integration - deleteRecord', function (hooks) { + todo('backport @ember-data/json-api/request tests', () => {}); +}); diff --git a/tests/builders/tests/integration/update-record-test.ts b/tests/builders/tests/integration/update-record-test.ts new file mode 100644 index 00000000000..6f822096fc8 --- /dev/null +++ b/tests/builders/tests/integration/update-record-test.ts @@ -0,0 +1,5 @@ +import { module, todo } from '@warp-drive/diagnostic'; + +module('Integration - updateRecord', function (hooks) { + todo('backport @ember-data/json-api/request tests', () => {}); +}); diff --git a/tests/builders/tests/test-helper.js b/tests/builders/tests/test-helper.js new file mode 100644 index 00000000000..9f4f19ec6fd --- /dev/null +++ b/tests/builders/tests/test-helper.js @@ -0,0 +1,19 @@ +import { setApplication } from '@ember/test-helpers'; + +import { configure } from '@warp-drive/diagnostic/ember'; +import { start } from '@warp-drive/diagnostic/runners/dom'; + +import Application from '../app'; +import config from '../config/environment'; + +configure(); + +setApplication(Application.create(config.APP)); +start({ + tryCatch: false, + debug: false, + groupLogs: false, + instrument: true, + hideReport: true, + useDiagnostic: true, +}); diff --git a/tests/builders/tests/unit/active-record-builder-test.ts b/tests/builders/tests/unit/active-record-builder-test.ts new file mode 100644 index 00000000000..5da51d9fdf3 --- /dev/null +++ b/tests/builders/tests/unit/active-record-builder-test.ts @@ -0,0 +1,277 @@ +import type { TestContext } from '@ember/test-helpers'; + +import { module, test } from '@warp-drive/diagnostic'; +import { setupTest } from '@warp-drive/diagnostic/ember'; + +import { createRecord, deleteRecord, findRecord, query, updateRecord } from '@ember-data/active-record/request'; +import { setBuildURLConfig } from '@ember-data/request-utils'; +import type Store from '@ember-data/store'; +import { recordIdentifierFor } from '@ember-data/store'; + +import type UserSetting from '../../app/models/user-setting'; +import { headersToObject } from '../helpers/utils'; + +const ACTIVE_RECORD_HEADERS = { accept: 'application/json;charset=utf-8' }; + +module('ActiveRecord | Request Builders', function (hooks) { + setupTest(hooks); + + hooks.beforeEach(function () { + setBuildURLConfig({ host: 'https://api.example.com', namespace: 'api/v1' }); + }); + + hooks.afterEach(function () { + setBuildURLConfig({ host: '', namespace: '' }); + }); + + test('findRecord by identifier', function (this: TestContext, assert) { + const result = findRecord({ type: 'user-setting', id: '1' }); + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/user_settings/1', + method: 'GET', + headers: new Headers(ACTIVE_RECORD_HEADERS), + cacheOptions: {}, + op: 'findRecord', + records: [{ type: 'user-setting', id: '1' }], + }, + `findRecord works with an identifier` + ); + assert.deepEqual(headersToObject(result.headers), ACTIVE_RECORD_HEADERS); + }); + + test('findRecord by type+id', function (this: TestContext, assert) { + const result = findRecord('user-setting', '1'); + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/user_settings/1', + method: 'GET', + headers: new Headers(ACTIVE_RECORD_HEADERS), + cacheOptions: {}, + op: 'findRecord', + records: [{ type: 'user-setting', id: '1' }], + }, + `findRecord works with type+id` + ); + assert.deepEqual(headersToObject(result.headers), ACTIVE_RECORD_HEADERS); + }); + + test('findRecord by identifier with options', function (this: TestContext, assert) { + const result = findRecord( + { type: 'user-setting', id: '1' }, + { reload: true, backgroundReload: false, include: 'user,friends' } + ); + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/user_settings/1?include=friends%2Cuser', + method: 'GET', + headers: new Headers(ACTIVE_RECORD_HEADERS), + cacheOptions: { + reload: true, + backgroundReload: false, + }, + op: 'findRecord', + records: [{ type: 'user-setting', id: '1' }], + }, + `findRecord works with an identifier and options` + ); + assert.deepEqual(headersToObject(result.headers), ACTIVE_RECORD_HEADERS); + }); + + test('findRecord by type+id with options', function (this: TestContext, assert) { + const result = findRecord('user-setting', '1', { reload: true, backgroundReload: false, include: 'user,friends' }); + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/user_settings/1?include=friends%2Cuser', + method: 'GET', + headers: new Headers(ACTIVE_RECORD_HEADERS), + cacheOptions: { reload: true, backgroundReload: false }, + op: 'findRecord', + records: [{ type: 'user-setting', id: '1' }], + }, + `findRecord works with type+id and options` + ); + assert.deepEqual(headersToObject(result.headers), ACTIVE_RECORD_HEADERS); + }); + + test('query', function (this: TestContext, assert) { + const result = query( + 'user-setting', + { include: 'user,friends', sort: 'name:asc', search: ['zeta', 'beta'] }, + { reload: true, backgroundReload: false } + ); + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/user_settings?include=friends%2Cuser&search=beta%2Czeta&sort=name%3Aasc', + method: 'GET', + headers: new Headers(ACTIVE_RECORD_HEADERS), + cacheOptions: { reload: true, backgroundReload: false }, + op: 'query', + }, + `query works with type and options` + ); + assert.deepEqual(headersToObject(result.headers), ACTIVE_RECORD_HEADERS); + }); + + test('createRecord passing store record', function (this: TestContext, assert) { + const store = this.owner.lookup('service:store') as Store; + const userSetting = store.createRecord('user-setting', { + name: 'test', + }); + const identifier = recordIdentifierFor(userSetting); + const result = createRecord(userSetting); + + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/user_settings', + method: 'POST', + headers: new Headers(ACTIVE_RECORD_HEADERS), + op: 'createRecord', + data: { + record: identifier, + }, + }, + `createRecord works with record identifier passed` + ); + assert.deepEqual(headersToObject(result.headers), ACTIVE_RECORD_HEADERS, "headers are set to ActiveRecord API's"); + }); + + test('createRecord passing store record and options', function (this: TestContext, assert) { + const store = this.owner.lookup('service:store') as Store; + const userSetting = store.createRecord('user-setting', { + name: 'test', + }); + const identifier = recordIdentifierFor(userSetting); + const result = createRecord(userSetting, { resourcePath: 'user-settings/new' }); + + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/user-settings/new', + method: 'POST', + headers: new Headers(ACTIVE_RECORD_HEADERS), + op: 'createRecord', + data: { + record: identifier, + }, + }, + `createRecord works with record identifier passed` + ); + assert.deepEqual(headersToObject(result.headers), ACTIVE_RECORD_HEADERS, "headers are set to ActiveRecord API's"); + }); + + test('updateRecord passing store record', function (this: TestContext, assert) { + const store = this.owner.lookup('service:store') as Store; + + const expectedData = { + data: { + id: '12', + type: 'user-setting', + attributes: { + name: 'test', + }, + }, + }; + store.push(expectedData); + + const userSetting = store.peekRecord('user-setting', '12') as UserSetting; + const identifier = recordIdentifierFor(userSetting); + + userSetting.name = 'test2'; + + const result = updateRecord(userSetting); + + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/user_settings/12', + method: 'PUT', + headers: new Headers(ACTIVE_RECORD_HEADERS), + op: 'updateRecord', + data: { + record: identifier, + }, + }, + `updateRecord works with record identifier passed` + ); + assert.deepEqual(headersToObject(result.headers), ACTIVE_RECORD_HEADERS, "headers are set to ActiveRecord API's"); + }); + + test('updateRecord with PATCH method', function (this: TestContext, assert) { + const store = this.owner.lookup('service:store') as Store; + + const expectedData = { + data: { + id: '12', + type: 'user-setting', + attributes: { + name: 'test', + }, + }, + }; + store.push(expectedData); + + const userSetting = store.peekRecord('user-setting', '12') as UserSetting; + const identifier = recordIdentifierFor(userSetting); + + userSetting.name = 'test2'; + + const result = updateRecord(userSetting, { patch: true }); + + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/user_settings/12', + method: 'PATCH', + headers: new Headers(ACTIVE_RECORD_HEADERS), + op: 'updateRecord', + data: { + record: identifier, + }, + }, + `updateRecord works with patch option` + ); + assert.deepEqual(headersToObject(result.headers), ACTIVE_RECORD_HEADERS, "headers are set to ActiveRecord API's"); + }); + + test('deleteRecord with identifier', function (this: TestContext, assert) { + const store = this.owner.lookup('service:store') as Store; + + const expectedData = { + data: { + id: '12', + type: 'user-setting', + attributes: { + name: 'test', + }, + }, + }; + store.push(expectedData); + + const userSetting = store.peekRecord('user-setting', '12')!; + const identifier = recordIdentifierFor(userSetting); + + const result = deleteRecord(userSetting); + + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/user_settings/12', + method: 'DELETE', + headers: new Headers(ACTIVE_RECORD_HEADERS), + op: 'deleteRecord', + data: { + record: identifier, + }, + }, + `deleteRecord works with patch option` + ); + assert.deepEqual(headersToObject(result.headers), ACTIVE_RECORD_HEADERS, "headers are set to ActiveRecord API's"); + }); +}); diff --git a/tests/builders/tests/unit/build-base-url-test.ts b/tests/builders/tests/unit/build-base-url-test.ts new file mode 100644 index 00000000000..bd27f78dd5a --- /dev/null +++ b/tests/builders/tests/unit/build-base-url-test.ts @@ -0,0 +1,289 @@ +import { buildBaseURL, setBuildURLConfig } from '@ember-data/request-utils'; +import { test as debug } from '@ember-data/unpublished-test-infra/test-support/test-in-debug'; +import { module, test } from '@warp-drive/diagnostic'; + +module('buildBaseURL', function (hooks) { + hooks.afterEach(function () { + setBuildURLConfig({ host: '', namespace: '' }); + }); + + test('simple cases (no optional options and no global config)', function (assert) { + assert.equal( + buildBaseURL({ + op: 'findRecord', + identifier: { type: 'user', id: '1' }, + }), + '/user/1', + `buildBaseURL works for findRecord` + ); + assert.equal( + buildBaseURL({ + op: 'updateRecord', + identifier: { type: 'user', id: '1' }, + }), + '/user/1', + `buildBaseURL works for updateRecord` + ); + + assert.equal( + buildBaseURL({ + op: 'deleteRecord', + identifier: { type: 'user', id: '1' }, + }), + '/user/1', + `buildBaseURL works for deleteRecord` + ); + + assert.equal( + buildBaseURL({ + op: 'findRelatedRecord', + identifier: { type: 'user', id: '1' }, + fieldPath: 'bestFriend', + }), + '/user/1/bestFriend', + `buildBaseURL works for findRelatedRecord` + ); + + assert.equal( + buildBaseURL({ + op: 'findRelatedCollection', + identifier: { type: 'user', id: '1' }, + fieldPath: 'friends', + }), + '/user/1/friends', + `buildBaseURL works for findRelatedCollection` + ); + + assert.equal( + buildBaseURL({ + op: 'query', + identifier: { type: 'user' }, + }), + '/user', + `buildBaseURL works for query` + ); + + assert.equal( + buildBaseURL({ + op: 'findMany', + identifiers: [ + { type: 'user', id: '1' }, + { type: 'user', id: '2' }, + ], + }), + '/user', + `buildBaseURL works for findMany` + ); + }); + + test('resourcePath (no global config)', function (assert) { + assert.equal( + buildBaseURL({ + op: 'findRecord', + identifier: { type: 'user', id: '1' }, + resourcePath: 'people', + }), + '/people/1', + `buildBaseURL works for findRecord` + ); + assert.equal( + buildBaseURL({ + op: 'updateRecord', + identifier: { type: 'user', id: '1' }, + resourcePath: 'people', + }), + '/people/1', + `buildBaseURL works for updateRecord` + ); + + assert.equal( + buildBaseURL({ + op: 'deleteRecord', + identifier: { type: 'user', id: '1' }, + resourcePath: 'people', + }), + '/people/1', + `buildBaseURL works for deleteRecord` + ); + + assert.equal( + buildBaseURL({ + op: 'findRelatedRecord', + identifier: { type: 'user', id: '1' }, + resourcePath: 'people', + fieldPath: 'bestFriend', + }), + '/people/1/bestFriend', + `buildBaseURL works for findRelatedRecord` + ); + + assert.equal( + buildBaseURL({ + op: 'findRelatedCollection', + identifier: { type: 'user', id: '1' }, + resourcePath: 'people', + fieldPath: 'friends', + }), + '/people/1/friends', + `buildBaseURL works for findRelatedCollection` + ); + + assert.equal( + buildBaseURL({ + op: 'query', + identifier: { type: 'user' }, + resourcePath: 'people', + }), + '/people', + `buildBaseURL works for query` + ); + + assert.equal( + buildBaseURL({ + op: 'findMany', + identifiers: [ + { type: 'user', id: '1' }, + { type: 'user', id: '2' }, + ], + resourcePath: 'people', + }), + '/people', + `buildBaseURL works for findMany` + ); + }); + + test('namespace uses local when present (no global config)', function (assert) { + assert.equal( + buildBaseURL({ + op: 'findRelatedRecord', + identifier: { type: 'user', id: '1' }, + resourcePath: 'people', + fieldPath: 'bestFriend', + namespace: 'api/v1', + }), + '/api/v1/people/1/bestFriend', + `buildBaseURL works as expected` + ); + }); + + test('namespace (global config)', function (assert) { + setBuildURLConfig({ namespace: 'api/v2', host: '' }); + assert.equal( + buildBaseURL({ + op: 'findRelatedRecord', + identifier: { type: 'user', id: '1' }, + resourcePath: 'people', + fieldPath: 'bestFriend', + }), + '/api/v2/people/1/bestFriend', + `buildBaseURL works as expected` + ); + }); + + test('namespace uses local when present (global config)', function (assert) { + setBuildURLConfig({ namespace: 'api/v2', host: '' }); + assert.equal( + buildBaseURL({ + op: 'findRelatedRecord', + identifier: { type: 'user', id: '1' }, + resourcePath: 'people', + fieldPath: 'bestFriend', + namespace: 'api/v3', + }), + '/api/v3/people/1/bestFriend', + `buildBaseURL works as expected` + ); + }); + + test('host uses local when present (no global config)', function (assert) { + assert.equal( + buildBaseURL({ + op: 'findRelatedRecord', + identifier: { type: 'user', id: '1' }, + resourcePath: 'people', + fieldPath: 'bestFriend', + host: 'https://api.example.com', + }), + 'https://api.example.com/people/1/bestFriend', + `buildBaseURL works as expected` + ); + }); + + test('host (global config)', function (assert) { + setBuildURLConfig({ namespace: '', host: 'https://api2.example.com' }); + assert.equal( + buildBaseURL({ + op: 'findRelatedRecord', + identifier: { type: 'user', id: '1' }, + resourcePath: 'people', + fieldPath: 'bestFriend', + }), + 'https://api2.example.com/people/1/bestFriend', + `buildBaseURL works as expected` + ); + }); + + test('host uses local when present (global config)', function (assert) { + setBuildURLConfig({ namespace: '', host: 'https://api2.example.com' }); + assert.equal( + buildBaseURL({ + op: 'findRelatedRecord', + identifier: { type: 'user', id: '1' }, + resourcePath: 'people', + fieldPath: 'bestFriend', + host: 'https://api3.example.com', + }), + 'https://api3.example.com/people/1/bestFriend', + `buildBaseURL works as expected` + ); + }); + + test('host may start with a /', function (assert) { + assert.equal( + buildBaseURL({ + op: 'findRelatedRecord', + identifier: { type: 'user', id: '1' }, + resourcePath: 'people', + host: '/api', + fieldPath: 'bestFriend', + }), + '/api/people/1/bestFriend', + `buildBaseURL works as expected` + ); + }); + + debug('throws when no op is provided', async function (assert) { + await assert.expectAssertion(() => { + // @ts-expect-error testing invalid input + buildBaseURL({}); + }, /buildBaseURL: You must pass `op` as part of options/); + }); + + debug('throws when an invalid op is provided', async function (assert) { + await assert.expectAssertion(() => { + // @ts-expect-error testing invalid input + buildBaseURL({ op: 'not-an-op', identifier: { type: 'user', id: '1' } }); + }, /buildBaseURL: You tried to build a not-an-op request to user but op must be one of/); + }); + + debug('throws when no identifier is provided', async function (assert) { + await assert.expectAssertion(() => { + // @ts-expect-error testing invalid input + buildBaseURL({ op: 'findRecord' }); + }, /buildBaseURL: You must pass `identifier` as part of options/); + }); + + debug('throws when identifier is missing type', async function (assert) { + await assert.expectAssertion(() => { + // @ts-expect-error testing invalid input + buildBaseURL({ op: 'findRecord', identifier: { id: '1' } }); + }, /You must pass valid `identifier` as part of options, expected 'type'/); + }); + + debug('throws when identifier is missing id', async function (assert) { + await assert.expectAssertion(() => { + // @ts-expect-error testing invalid input + buildBaseURL({ op: 'findRecord', identifier: { type: 'user' } }); + }, /You must pass valid `identifier` as part of options, expected 'id'/); + }); +}); diff --git a/tests/builders/tests/unit/build-query-params-test.ts b/tests/builders/tests/unit/build-query-params-test.ts new file mode 100644 index 00000000000..12cf7004ee8 --- /dev/null +++ b/tests/builders/tests/unit/build-query-params-test.ts @@ -0,0 +1,138 @@ +import { buildQueryParams } from '@ember-data/request-utils'; +import { module, test } from '@warp-drive/diagnostic'; + +module('buildQueryParams', function (hooks) { + test('It serializes objects with stable key order', function (assert) { + assert.equal( + buildQueryParams({ + foo: 'bar', + baz: 'qux', + }), + 'baz=qux&foo=bar', + `buildQueryParams works` + ); + assert.equal( + buildQueryParams({ + baz: 'qux', + foo: 'bar', + }), + 'baz=qux&foo=bar', + `buildQueryParams works` + ); + }); + + test('It serializes URLSearchParams with stable key order', function (assert) { + const params1 = new URLSearchParams(); + params1.append('foo', 'bar'); + params1.append('baz', 'qux'); + const params2 = new URLSearchParams(); + params2.append('baz', 'qux'); + params2.append('foo', 'bar'); + + assert.equal(buildQueryParams(params1), 'baz=qux&foo=bar', `buildQueryParams works`); + assert.equal(buildQueryParams(params2), 'baz=qux&foo=bar', `buildQueryParams works`); + }); + + test('It serializes objects with stable value order', function (assert) { + assert.equal( + buildQueryParams({ + foo: ['c', 'b', 'a'], + baz: ['f', 'd', 'e'], + }), + 'baz=d%2Ce%2Cf&foo=a%2Cb%2Cc', + `buildQueryParams works` + ); + assert.equal( + buildQueryParams({ + foo: ['c', 'b', 'a'], + baz: ['f', 'd', 'e'], + }), + 'baz=d%2Ce%2Cf&foo=a%2Cb%2Cc', + `buildQueryParams works` + ); + }); + + test('It serializes URLSearchParams with stable value order', function (assert) { + const params1 = new URLSearchParams(); + params1.append('foo', 'c'); + params1.append('foo', 'b'); + params1.append('foo', 'a'); + params1.append('baz', 'f'); + params1.append('baz', 'd'); + params1.append('baz', 'e'); + const params2 = new URLSearchParams(); + params2.append('foo', 'c'); + params2.append('foo', 'b'); + params2.append('foo', 'a'); + params2.append('baz', 'f'); + params2.append('baz', 'd'); + params2.append('baz', 'e'); + + assert.equal(buildQueryParams(params1), 'baz=d%2Ce%2Cf&foo=a%2Cb%2Cc', `buildQueryParams works`); + assert.equal(buildQueryParams(params2), 'baz=d%2Ce%2Cf&foo=a%2Cb%2Cc', `buildQueryParams works`); + }); + + test('It special cases object.include', function (assert) { + assert.equal( + buildQueryParams({ + include: ['foo', 'bar'], + }), + 'include=bar%2Cfoo', + `buildQueryParams works` + ); + assert.equal( + buildQueryParams({ + include: 'foo,bar', + }), + 'include=bar%2Cfoo', + `buildQueryParams works` + ); + }); + + test('It allows for customizing the arrayFormat', function (assert) { + assert.equal( + buildQueryParams( + { + foo: ['c', 'b', 'a'], + baz: ['f', 'd', 'e'], + }, + { arrayFormat: 'bracket' } + ), + 'baz%5B%5D=d&baz%5B%5D=e&baz%5B%5D=f&foo%5B%5D=a&foo%5B%5D=b&foo%5B%5D=c', + `buildQueryParams works` + ); + assert.equal( + buildQueryParams( + { + foo: ['c', 'b', 'a'], + baz: ['f', 'd', 'e'], + }, + { arrayFormat: 'indices' } + ), + 'baz%5B0%5D=d&baz%5B1%5D=e&baz%5B2%5D=f&foo%5B0%5D=a&foo%5B1%5D=b&foo%5B2%5D=c', + `buildQueryParams works` + ); + assert.equal( + buildQueryParams( + { + foo: ['c', 'b', 'a'], + baz: ['f', 'd', 'e'], + }, + { arrayFormat: 'repeat' } + ), + 'baz=d&baz=e&baz=f&foo=a&foo=b&foo=c', + `buildQueryParams works` + ); + assert.equal( + buildQueryParams( + { + foo: ['c', 'b', 'a'], + baz: ['f', 'd', 'e'], + }, + { arrayFormat: 'comma' } + ), + 'baz=d%2Ce%2Cf&foo=a%2Cb%2Cc', + `buildQueryParams works` + ); + }); +}); diff --git a/tests/builders/tests/unit/filter-empty-test.ts b/tests/builders/tests/unit/filter-empty-test.ts new file mode 100644 index 00000000000..fb767a94702 --- /dev/null +++ b/tests/builders/tests/unit/filter-empty-test.ts @@ -0,0 +1,28 @@ +import { filterEmpty } from '@ember-data/request-utils'; +import { module, test } from '@warp-drive/diagnostic'; + +module('filterEmpty', function () { + test('it returns an empty object when given an empty object', function (assert) { + assert.deepEqual(filterEmpty({}), {}); + }); + + test('it returns an object with truthy values and meaningful falsy values like `false` and `0`', function (assert) { + assert.deepEqual( + filterEmpty({ + foo: 'bar', + baz: null, + zero: 0, + booleanFalse: false, + emptyString: '', + emptyArray: [], + fullArray: [1, 2, 3], + }), + { + zero: 0, + booleanFalse: false, + foo: 'bar', + fullArray: [1, 2, 3], + } + ); + }); +}); diff --git a/tests/builders/tests/unit/json-api-builder-test.ts b/tests/builders/tests/unit/json-api-builder-test.ts new file mode 100644 index 00000000000..fed8d7b81b1 --- /dev/null +++ b/tests/builders/tests/unit/json-api-builder-test.ts @@ -0,0 +1,5 @@ +import { module, todo } from '@warp-drive/diagnostic'; + +module('JSON:API | Request Builders', function (hooks) { + todo('backport @ember-data/json-api/request tests', () => {}); +}); diff --git a/tests/builders/tests/unit/parse-cache-control-test.ts b/tests/builders/tests/unit/parse-cache-control-test.ts new file mode 100644 index 00000000000..0f3f5381ecb --- /dev/null +++ b/tests/builders/tests/unit/parse-cache-control-test.ts @@ -0,0 +1,68 @@ +import { parseCacheControl } from '@ember-data/request-utils'; +import { test as debug } from '@ember-data/unpublished-test-infra/test-support/test-in-debug'; +import { module, test } from '@warp-drive/diagnostic'; + +module('parseCacheControl', function (hooks) { + test('should parse a single Cache-Control directive', function (assert) { + const header = 'max-age=3600'; + const result = parseCacheControl(header); + assert.deepEqual(result, { 'max-age': 3600 }); + }); + + test('should parse multiple Cache-Control directives', function (assert) { + const header = 'max-age=3600, must-revalidate'; + const result = parseCacheControl(header); + assert.deepEqual(result, { 'max-age': 3600, 'must-revalidate': true }); + }); + + test('should parse Cache-Control directives with multiple delta-seconds values', function (assert) { + const header = 'max-age=3600, s-maxage=7200'; + const result = parseCacheControl(header); + assert.deepEqual(result, { 'max-age': 3600, 's-maxage': 7200 }); + }); + + test('should parse Cache-Control directives with a single token value', function (assert) { + const header = 'no-cache'; + const result = parseCacheControl(header); + assert.deepEqual(result, { 'no-cache': true }); + }); + + test('should parse Cache-Control directives with multiple token values', function (assert) { + const header = 'no-cache, no-store'; + const result = parseCacheControl(header); + assert.deepEqual(result, { 'no-cache': true, 'no-store': true }); + }); + + test('should parse Cache-Control directives with a single byte-range-set value', function (assert) { + const header = + 'max-age=3600, no-transform, only-if-cached, public, must-revalidate, proxy-revalidate, no-cache, s-maxage=7200, stale-while-revalidate=3600, stale-if-error=7200, immutable'; + const result = parseCacheControl(header); + assert.deepEqual(result, { + 'max-age': 3600, + 'no-transform': true, + 'only-if-cached': true, + public: true, + 'must-revalidate': true, + 'proxy-revalidate': true, + 'no-cache': true, + 's-maxage': 7200, + 'stale-while-revalidate': 3600, + 'stale-if-error': 7200, + immutable: true, + }); + }); + + debug('throws when Cache-Control has invalid directives', async function (assert) { + await assert.expectAssertion(() => { + const header = 'max-age=,'; + parseCacheControl(header); + }, /Assertion Failed: Invalid Cache-Control value, expected a value after "=" but got ","/); + }); + + debug('throws when Cache-Control has invalid value type', async function (assert) { + await assert.expectAssertion(() => { + const header = 'max-age="3600"'; + parseCacheControl(header); + }, /Assertion Failed: Invalid Cache-Control value, expected a number but got - "3600"/); + }); +}); diff --git a/tests/builders/tests/unit/rest-builder-test.ts b/tests/builders/tests/unit/rest-builder-test.ts new file mode 100644 index 00000000000..f90218eca3b --- /dev/null +++ b/tests/builders/tests/unit/rest-builder-test.ts @@ -0,0 +1,277 @@ +import type { TestContext } from '@ember/test-helpers'; + +import { module, test } from '@warp-drive/diagnostic'; +import { setupTest } from '@warp-drive/diagnostic/ember'; + +import { setBuildURLConfig } from '@ember-data/request-utils'; +import { createRecord, deleteRecord, findRecord, query, updateRecord } from '@ember-data/rest/request'; +import type Store from '@ember-data/store'; +import { recordIdentifierFor } from '@ember-data/store'; + +import type UserSetting from '../../app/models/user-setting'; +import { headersToObject } from '../helpers/utils'; + +const REST_HEADERS = { accept: 'application/json;charset=utf-8' }; + +module('REST | Request Builders', function (hooks) { + setupTest(hooks); + + hooks.beforeEach(function () { + setBuildURLConfig({ host: 'https://api.example.com', namespace: 'api/v1' }); + }); + + hooks.afterEach(function () { + setBuildURLConfig({ host: '', namespace: '' }); + }); + + test('findRecord by identifier', function (this: TestContext, assert) { + const result = findRecord({ type: 'user-setting', id: '1' }); + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/userSettings/1', + method: 'GET', + headers: new Headers(REST_HEADERS), + cacheOptions: {}, + op: 'findRecord', + records: [{ type: 'user-setting', id: '1' }], + }, + `findRecord works with an identifier` + ); + assert.deepEqual(headersToObject(result.headers), REST_HEADERS); + }); + + test('findRecord by type+id', function (this: TestContext, assert) { + const result = findRecord('user-setting', '1'); + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/userSettings/1', + method: 'GET', + headers: new Headers(REST_HEADERS), + cacheOptions: {}, + op: 'findRecord', + records: [{ type: 'user-setting', id: '1' }], + }, + `findRecord works with type+id` + ); + assert.deepEqual(headersToObject(result.headers), REST_HEADERS); + }); + + test('findRecord by identifier with options', function (this: TestContext, assert) { + const result = findRecord( + { type: 'user-setting', id: '1' }, + { reload: true, backgroundReload: false, include: 'user,friends' } + ); + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/userSettings/1?include=friends%2Cuser', + method: 'GET', + headers: new Headers(REST_HEADERS), + cacheOptions: { + reload: true, + backgroundReload: false, + }, + op: 'findRecord', + records: [{ type: 'user-setting', id: '1' }], + }, + `findRecord works with an identifier and options` + ); + assert.deepEqual(headersToObject(result.headers), REST_HEADERS); + }); + + test('findRecord by type+id with options', function (this: TestContext, assert) { + const result = findRecord('user-setting', '1', { reload: true, backgroundReload: false, include: 'user,friends' }); + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/userSettings/1?include=friends%2Cuser', + method: 'GET', + headers: new Headers(REST_HEADERS), + cacheOptions: { reload: true, backgroundReload: false }, + op: 'findRecord', + records: [{ type: 'user-setting', id: '1' }], + }, + `findRecord works with type+id and options` + ); + assert.deepEqual(headersToObject(result.headers), REST_HEADERS); + }); + + test('query', function (this: TestContext, assert) { + const result = query( + 'user-setting', + { include: 'user,friends', sort: 'name:asc', search: ['zeta', 'beta'] }, + { reload: true, backgroundReload: false } + ); + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/userSettings?include=friends%2Cuser&search=beta%2Czeta&sort=name%3Aasc', + method: 'GET', + headers: new Headers(REST_HEADERS), + cacheOptions: { reload: true, backgroundReload: false }, + op: 'query', + }, + `query works with type and options` + ); + assert.deepEqual(headersToObject(result.headers), REST_HEADERS); + }); + + test('createRecord passing store record', function (this: TestContext, assert) { + const store = this.owner.lookup('service:store') as Store; + const userSetting = store.createRecord('user-setting', { + name: 'test', + }); + const identifier = recordIdentifierFor(userSetting); + const result = createRecord(userSetting); + + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/userSettings', + method: 'POST', + headers: new Headers(REST_HEADERS), + op: 'createRecord', + data: { + record: identifier, + }, + }, + `createRecord works with record identifier passed` + ); + assert.deepEqual(headersToObject(result.headers), REST_HEADERS, "headers are set to REST API's"); + }); + + test('createRecord passing store record and options', function (this: TestContext, assert) { + const store = this.owner.lookup('service:store') as Store; + const userSetting = store.createRecord('user-setting', { + name: 'test', + }); + const identifier = recordIdentifierFor(userSetting); + const result = createRecord(userSetting, { resourcePath: 'userSettings/new' }); + + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/userSettings/new', + method: 'POST', + headers: new Headers(REST_HEADERS), + op: 'createRecord', + data: { + record: identifier, + }, + }, + `createRecord works with record identifier passed` + ); + assert.deepEqual(headersToObject(result.headers), REST_HEADERS, "headers are set to REST API's"); + }); + + test('updateRecord passing store record', function (this: TestContext, assert) { + const store = this.owner.lookup('service:store') as Store; + + const expectedData = { + data: { + id: '12', + type: 'user-setting', + attributes: { + name: 'test', + }, + }, + }; + store.push(expectedData); + + const userSetting = store.peekRecord('user-setting', '12') as UserSetting; + const identifier = recordIdentifierFor(userSetting); + + userSetting.name = 'test2'; + + const result = updateRecord(userSetting); + + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/userSettings/12', + method: 'PUT', + headers: new Headers(REST_HEADERS), + op: 'updateRecord', + data: { + record: identifier, + }, + }, + `updateRecord works with record identifier passed` + ); + assert.deepEqual(headersToObject(result.headers), REST_HEADERS, "headers are set to REST API's"); + }); + + test('updateRecord with PATCH method', function (this: TestContext, assert) { + const store = this.owner.lookup('service:store') as Store; + + const expectedData = { + data: { + id: '12', + type: 'user-setting', + attributes: { + name: 'test', + }, + }, + }; + store.push(expectedData); + + const userSetting = store.peekRecord('user-setting', '12') as UserSetting; + const identifier = recordIdentifierFor(userSetting); + + userSetting.name = 'test2'; + + const result = updateRecord(userSetting, { patch: true }); + + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/userSettings/12', + method: 'PATCH', + headers: new Headers(REST_HEADERS), + op: 'updateRecord', + data: { + record: identifier, + }, + }, + `updateRecord works with patch option` + ); + assert.deepEqual(headersToObject(result.headers), REST_HEADERS, "headers are set to REST API's"); + }); + + test('deleteRecord with identifier', function (this: TestContext, assert) { + const store = this.owner.lookup('service:store') as Store; + + const expectedData = { + data: { + id: '12', + type: 'user-setting', + attributes: { + name: 'test', + }, + }, + }; + store.push(expectedData); + + const userSetting = store.peekRecord('user-setting', '12')!; + const identifier = recordIdentifierFor(userSetting); + + const result = deleteRecord(userSetting); + + assert.deepEqual( + result, + { + url: 'https://api.example.com/api/v1/userSettings/12', + method: 'DELETE', + headers: new Headers(REST_HEADERS), + op: 'deleteRecord', + data: { + record: identifier, + }, + }, + `deleteRecord works with patch option` + ); + assert.deepEqual(headersToObject(result.headers), REST_HEADERS, "headers are set to REST API's"); + }); +}); diff --git a/tsconfig.root.json b/tsconfig.root.json index 0331bd15181..a6cf5f9079b 100644 --- a/tsconfig.root.json +++ b/tsconfig.root.json @@ -68,6 +68,12 @@ "@ember-data/json-api/*": ["packages/json-api/src/*"], "@ember-data/legacy-compat": ["packages/legacy-compat/src"], "@ember-data/legacy-compat/*": ["packages/legacy-compat/src/*"], + "@ember-data/active-record": ["packages/active-record/src"], + "@ember-data/active-record/*": ["packages/active-record/src/*"], + "@ember-data/request-utils": ["packages/request-utils/src"], + "@ember-data/request-utils/*": ["packages/request-utils/src/*"], + "@ember-data/rest": ["packages/rest/src"], + "@ember-data/rest/*": ["packages/rest/src/*"], "@ember-data/canary-features": ["packages/private-build-infra/virtual-packages/canary-features.d.ts"], "@ember-data/debugging": ["packages/private-build-infra/virtual-packages/debugging.d.ts"], "@ember-data/deprecations": ["packages/private-build-infra/virtual-packages/deprecations.d.ts"], @@ -84,32 +90,44 @@ "request-test-app/tests/*": ["tests/request/tests/*"], "request-test-app/*": ["tests/request/app/*"], "*": ["@types/*", "packages/fastboot-test-app/types/*"], - "ember-inflector": ["tests/main/node_modules/ember-inflector","packages/-ember-data/node_modules/ember-inflector"] + "ember-inflector": [ + "tests/main/node_modules/ember-inflector", + "packages/-ember-data/node_modules/ember-inflector" + ] } }, "include": [ "@types/**/*", "ember-data-types/**/*", - "packages/**/app/**/*", + "packages/**/addon-test-support/**/*", "packages/**/addon/**/*", + "packages/**/app/**/*", + "packages/**/test-support/**/*", "packages/**/tests/**/*", - "packages/tracking/src/**/*", - "packages/request/src/**/*", - "packages/store/src/**/*", + "packages/active-record/src/**/*", "packages/adapter/src/**/*", - "packages/graph/src/**/*", - "packages/model/src/**/*", - "packages/legacy-compat/src/**/*", - "packages/json-api/src/**/*", - "packages/serializer/src/**/*", "packages/experimental-preview-types/src/**/*", "packages/fastboot-test-app/types/**/*", + "packages/graph/src/**/*", + "packages/json-api/src/**/*", + "packages/legacy-compat/src/**/*", + "packages/model/src/**/*", "packages/private-build-infra/canary-features/**/*", - "packages/**/test-support/**/*", - "packages/**/addon-test-support/**/*", + "packages/request-utils/src/**/*", + "packages/request/src/**/*", + "packages/rest/src/**/*", + "packages/serializer/src/**/*", + "packages/store/src/**/*", + "packages/tracking/src/**/*", "tests/**/app/**/*", "tests/**/addon/**/*", "tests/**/tests/**/*" ], - "exclude": ["node_modules", "packages/**/node_modules", "packages/**/dist", "packages/**/DEBUG"] + "exclude": [ + "node_modules", + "packages/**/node_modules", + "packages/**/dist", + "packages/**/DEBUG", + "packages/diagnostic" + ] }