diff --git a/npm/grep/README.md b/npm/grep/README.md index 9466d08098de..7114b854bed9 100644 --- a/npm/grep/README.md +++ b/npm/grep/README.md @@ -84,12 +84,12 @@ yarn add -D @cypress/grep ```js // cypress/support/index.js // load and register the grep feature using "require" function -// https://github.com/cypress-io/cypress-grep -const registerCypressGrep = require('cypress-grep') +// https://github.com/cypress-io/cypress/tree/develop/npm/grep +const registerCypressGrep = require('@cypress/grep') registerCypressGrep() // if you want to use the "import" keyword -import registerCypressGrep from 'cypress-grep' +import registerCypressGrep from '@cypress/grep' registerCypressGrep() ``` @@ -102,7 +102,7 @@ registerCypressGrep() { e2e: { setupNodeEvents(on, config) { - require('cypress-grep/src/plugin')(config); + require('@cypress/grep/src/plugin')(config); return config; }, } diff --git a/npm/grep/src/support.js b/npm/grep/src/support.js index 844ef51ecf0e..5fd42b5db588 100644 --- a/npm/grep/src/support.js +++ b/npm/grep/src/support.js @@ -4,7 +4,7 @@ const { parseGrep, shouldTestRun } = require('./utils') // @ts-ignore const { version } = require('../package.json') -const debug = require('debug')('cypress-grep') +const debug = require('debug')('@cypress/grep') debug.log = console.info.bind(console) diff --git a/npm/vite-dev-server/CHANGELOG.md b/npm/vite-dev-server/CHANGELOG.md index 6fcb11e650f6..65687aa877a3 100644 --- a/npm/vite-dev-server/CHANGELOG.md +++ b/npm/vite-dev-server/CHANGELOG.md @@ -1,3 +1,10 @@ +# [@cypress/vite-dev-server-v4.0.1](https://github.com/cypress-io/cypress/compare/@cypress/vite-dev-server-v4.0.0...@cypress/vite-dev-server-v4.0.1) (2022-11-08) + + +### Bug Fixes + +* vite-dev-server hoisting issue in binary ([#24599](https://github.com/cypress-io/cypress/issues/24599)) ([2513bea](https://github.com/cypress-io/cypress/commit/2513beac307e95267ab736a93a39cd1cd1280506)) + # [@cypress/vite-dev-server-v4.0.0](https://github.com/cypress-io/cypress/compare/@cypress/vite-dev-server-v3.4.0...@cypress/vite-dev-server-v4.0.0) (2022-11-07) diff --git a/npm/vite-dev-server/package.json b/npm/vite-dev-server/package.json index d102af69b040..ac9f49f2a45e 100644 --- a/npm/vite-dev-server/package.json +++ b/npm/vite-dev-server/package.json @@ -15,7 +15,7 @@ "test-unit": "mocha -r ts-node/register/transpile-only --config ./test/.mocharc.js" }, "dependencies": { - "debug": "4.3.3", + "debug": "^4.3.4", "find-up": "6.3.0", "node-html-parser": "5.3.3" }, diff --git a/npm/webpack-dev-server/CHANGELOG.md b/npm/webpack-dev-server/CHANGELOG.md index f088b3f3df03..5bbe93bd80ea 100644 --- a/npm/webpack-dev-server/CHANGELOG.md +++ b/npm/webpack-dev-server/CHANGELOG.md @@ -1,3 +1,10 @@ +# [@cypress/webpack-dev-server-v3.0.1](https://github.com/cypress-io/cypress/compare/@cypress/webpack-dev-server-v3.0.0...@cypress/webpack-dev-server-v3.0.1) (2022-11-08) + + +### Bug Fixes + +* revert dynamic import of webpack config file ([#24598](https://github.com/cypress-io/cypress/issues/24598)) ([69f7dab](https://github.com/cypress-io/cypress/commit/69f7dabc94a5adb25edc7fda6057e92b8bd2e072)) + # [@cypress/webpack-dev-server-v3.0.0](https://github.com/cypress-io/cypress/compare/@cypress/webpack-dev-server-v2.5.0...@cypress/webpack-dev-server-v3.0.0) (2022-11-07) diff --git a/npm/webpack-dev-server/package.json b/npm/webpack-dev-server/package.json index 0e216e896d6e..810ddf973f9e 100644 --- a/npm/webpack-dev-server/package.json +++ b/npm/webpack-dev-server/package.json @@ -21,6 +21,7 @@ "fs-extra": "9.1.0", "html-webpack-plugin-4": "npm:html-webpack-plugin@^4", "html-webpack-plugin-5": "npm:html-webpack-plugin@^5", + "local-pkg": "0.4.1", "speed-measure-webpack-plugin": "1.4.2", "tslib": "^2.3.1", "webpack-dev-server": "^4.7.4", diff --git a/npm/webpack-dev-server/src/makeWebpackConfig.ts b/npm/webpack-dev-server/src/makeWebpackConfig.ts index 9e97472e5970..d428fe68ea25 100644 --- a/npm/webpack-dev-server/src/makeWebpackConfig.ts +++ b/npm/webpack-dev-server/src/makeWebpackConfig.ts @@ -1,11 +1,12 @@ import { debug as debugFn } from 'debug' import * as path from 'path' import { merge } from 'webpack-merge' +import { importModule } from 'local-pkg' import type { Configuration, EntryObject } from 'webpack' import { makeCypressWebpackConfig } from './makeDefaultWebpackConfig' import type { CreateFinalWebpackConfig } from './createWebpackDevServer' import { configFiles } from './constants' -import { dynamicAbsoluteImport, dynamicImport } from './dynamic-import' +import { dynamicImport } from './dynamic-import' const debug = debugFn('cypress:webpack-dev-server:makeWebpackConfig') @@ -90,7 +91,7 @@ export async function makeWebpackConfig ( if (configFile) { debug('found webpack config %s', configFile) - const sourcedConfig = await dynamicAbsoluteImport(configFile) + const sourcedConfig = await importModule(configFile) debug('config contains %o', sourcedConfig) if (sourcedConfig && typeof sourcedConfig === 'object') { diff --git a/package.json b/package.json index c08631d16b83..f364b3b8b21b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cypress", - "version": "10.11.0", + "version": "11.0.0", "description": "Cypress is a next generation front end testing tool built for the modern web", "private": true, "scripts": { diff --git a/packages/config/src/browser.ts b/packages/config/src/browser.ts index d9b85e52a1e5..75150ea41c97 100644 --- a/packages/config/src/browser.ts +++ b/packages/config/src/browser.ts @@ -156,7 +156,7 @@ export const matchesConfigKey = (key: string) => { } export const validate = (cfg: any, onErr: (property: ErrResult | string) => void, testingType: TestingType | null) => { - debug('validating configuration') + debug('validating configuration', cfg) return _.each(cfg, (value, key) => { const validationFn = validationRules[key] @@ -166,7 +166,7 @@ export const validate = (cfg: any, onErr: (property: ErrResult | string) => void const result = validationFn(key, value, { testingType, // TODO: remove with experimentalSessionAndOrigin. Fixed with: https://github.com/cypress-io/cypress/issues/21471 - experimentalSessionAndOrigin: cfg.experimentalSessionAndOrigin, + experimentalSessionAndOrigin: cfg.e2e?.experimentalSessionAndOrigin || cfg.experimentalSessionAndOrigin, }) if (result !== true) { diff --git a/packages/driver/cypress/e2e/e2e/origin/origin.cy.ts b/packages/driver/cypress/e2e/e2e/origin/origin.cy.ts index c76c2f174dff..88b7220da32f 100644 --- a/packages/driver/cypress/e2e/e2e/origin/origin.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/origin.cy.ts @@ -10,6 +10,44 @@ describe('cy.origin', { browser: '!webkit' }, () => { }) }) + it('creates and injects into google subdomains', () => { + // Intercept google to keep our tests independent from google. + cy.intercept('https://www.google.com', { + body: '

google.com

', + }) + + cy.intercept('https://accounts.google.com', { + body: '

accounts.google.com

', + }) + + cy.visit('https://www.google.com') + cy.visit('https://accounts.google.com') + cy.origin('https://accounts.google.com', () => { + cy.window().then((win) => { + expect(win.Cypress).to.exist + }) + }) + }) + + it('creates and injects into google subdomains when visiting in an origin block', () => { + // Intercept google to keep our tests independent from google. + cy.intercept('https://www.google.com', { + body: '

google.com

', + }) + + cy.intercept('https://accounts.google.com', { + body: '

accounts.google.com

', + }) + + cy.visit('https://www.google.com') + cy.origin('https://accounts.google.com', () => { + cy.visit('https://accounts.google.com') + cy.window().then((win) => { + expect(win.Cypress).to.exist + }) + }) + }) + it('passes viewportWidth/Height state to the secondary origin', () => { const expectedViewport = [320, 480] diff --git a/packages/driver/cypress/e2e/e2e/origin/validation.cy.ts b/packages/driver/cypress/e2e/e2e/origin/validation.cy.ts index ba15a29cb2f4..e726cee2f56c 100644 --- a/packages/driver/cypress/e2e/e2e/origin/validation.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/validation.cy.ts @@ -1,4 +1,8 @@ describe('cy.origin', { browser: '!webkit' }, () => { + beforeEach(() => { + cy.visit('') + }) + describe('successes', () => { it('succeeds on a localhost domain name', () => { cy.origin('localhost', () => undefined) @@ -357,3 +361,83 @@ describe('cy.origin', { browser: '!webkit' }, () => { }) }) }) + +describe('cy.origin - external hosts', { browser: '!webkit' }, () => { + describe('successes', () => { + it('succeeds on a complete origin from https using https', () => { + cy.visit('https://www.foobar.com:3502/fixtures/primary-origin.html') + cy.origin('https://www.idp.com:3502', () => undefined) + cy.then(() => { + const expectedSrc = `https://www.idp.com:3502/__cypress/spec-bridge-iframes` + const iframe = window.top?.document.getElementById('Spec\ Bridge:\ https://www.idp.com:3502') as HTMLIFrameElement + + expect(iframe.src).to.equal(expectedSrc) + }) + }) + + it('succeeds if url is the super domain as top but the super domain is excepted and must be strictly same origin', () => { + // Intercept google to keep our tests independent from google. + cy.intercept('https://www.google.com', { + body: '

', + }) + + cy.visit('https://www.google.com') + cy.origin('accounts.google.com', () => undefined) + cy.then(() => { + const expectedSrc = `https://accounts.google.com/__cypress/spec-bridge-iframes` + const iframe = window.top?.document.getElementById('Spec\ Bridge:\ https://accounts.google.com') as HTMLIFrameElement + + expect(iframe.src).to.equal(expectedSrc) + }) + }) + }) + + describe('errors', () => { + it('errors if the url param is same superDomainOrigin as top', (done) => { + cy.on('fail', (err) => { + expect(err.message).to.include('`cy.origin()` requires the first argument to be a different domain than top. You passed `http://app.foobar.com` to the origin command, while top is at `http://www.foobar.com`.') + + done() + }) + + cy.intercept('http://www.foobar.com', { + body: '

', + }) + + cy.intercept('http://app.foobar.com', { + body: '

', + }) + + cy.visit('http://www.foobar.com') + + cy.origin('http://app.foobar.com', () => undefined) + }) + + it('errors if the url param is same origin as top', (done) => { + cy.on('fail', (err) => { + expect(err.message).to.include('`cy.origin()` requires the first argument to be a different origin than top. You passed `https://www.google.com` to the origin command, while top is at `https://www.google.com`.') + + done() + }) + + // Intercept google to keep our tests independent from google. + cy.intercept('https://www.google.com', { + body: '

', + }) + + cy.visit('https://www.google.com') + cy.origin('https://www.google.com', () => undefined) + }) + + it('errors and does not hang when throwing a mixed content error creating the spec bridge', { defaultCommandTimeout: 50 }, (done) => { + cy.on('fail', (err) => { + expect(err.message).to.include(`\`cy.origin()\` failed to create a spec bridge to communicate with the specified origin. This can happen when you attempt to create a spec bridge to an insecure (http) frame from a secure (https) frame.`) + + done() + }) + + cy.visit('https://www.foobar.com:3502/fixtures/primary-origin.html') + cy.origin('http://www.foobar.com:3500', () => {}) + }) + }) +}) diff --git a/packages/driver/src/cy/commands/origin/index.ts b/packages/driver/src/cy/commands/origin/index.ts index b1227e565ae7..5cc24e6ffd73 100644 --- a/packages/driver/src/cy/commands/origin/index.ts +++ b/packages/driver/src/cy/commands/origin/index.ts @@ -38,7 +38,7 @@ export default (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: State communicator.userInvocationStack = userInvocationStack // this command runs for as long as the commands in the secondary - // origin run, so it can't have its own timeout + // origin run, so it can't have its own timeout except in the case where we're creating the spec bridge. cy.clearTimeout() if (!config('experimentalSessionAndOrigin')) { @@ -47,6 +47,7 @@ export default (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: State let options let callbackFn + const timeout = Cypress.config('defaultCommandTimeout') if (fn) { callbackFn = fn @@ -64,7 +65,7 @@ export default (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: State name: 'origin', type: 'parent', message: urlOrDomain, - timeout: 0, + timeout, // @ts-ignore TODO: revisit once log-grouping has more implementations }, (_log) => { log = _log @@ -84,7 +85,7 @@ export default (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: State const url = new URL(normalizeOrigin(urlOrDomain)).toString() const location = $Location.create(url) - validator.validateLocation(location, urlOrDomain) + validator.validateLocation(location, urlOrDomain, window.location.href) const origin = location.origin @@ -92,7 +93,7 @@ export default (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: State cy.state('currentActiveOrigin', origin) return new Bluebird((resolve, reject, onCancel) => { - const cleanup = ({ readyForOriginFailed }: {readyForOriginFailed?: boolean} = {}): void => { + const cleanup = (): void => { cy.state('currentActiveOrigin', undefined) communicator.off('queue:finished', onQueueFinished) @@ -108,8 +109,10 @@ export default (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: State resolve(unserializableSubjectType ? createUnserializableSubjectProxy(unserializableSubjectType) : subject) } - const _reject = (err, cleanupOptions: {readyForOriginFailed?: boolean} = {}) => { - cleanup(cleanupOptions) + const _reject = (err) => { + // Prevent cypress from trying to add the function to the error log + err.onFail = () => {} + cleanup() log?.error(err) reject(err) } @@ -141,9 +144,6 @@ export default (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: State wrappedErr.name = err.name wrappedErr.stack = $stackUtils.replacedStack(wrappedErr, err.stack) - // Prevent cypress from trying to add the function to the error log - wrappedErr.onFail = () => {} - return _reject(wrappedErr) } @@ -168,9 +168,15 @@ export default (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: State }) } + // If the spec bridge isn't created in time, it likely failed and we shouldn't hang the test. + const timeoutId = setTimeout(() => { + _reject($errUtils.errByPath('origin.failed_to_create_spec_bridge')) + }, timeout) + // fired once the spec bridge is set up and ready to receive messages communicator.once('bridge:ready', async (_data, { origin: specBridgeOrigin }) => { if (specBridgeOrigin === origin) { + clearTimeout(timeoutId) // now that the spec bridge is ready, instantiate Cypress with the current app config and environment variables for initial sync when creating the instance communicator.toSpecBridge(origin, 'initialize:cypress', { config: preprocessConfig(Cypress.config()), @@ -229,11 +235,7 @@ export default (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: State // It tries to add a bunch of stuff that's not useful and ends up // messing up the stack that we want on the error wrappedErr.__stackCleaned__ = true - - // Prevent cypress from trying to add the function to the error log - wrappedErr.onFail = () => {} - - _reject(wrappedErr, { readyForOriginFailed: true }) + _reject(wrappedErr) } } }) diff --git a/packages/driver/src/cy/commands/origin/validator.ts b/packages/driver/src/cy/commands/origin/validator.ts index eb9d1ee6a0d7..eead76728ff7 100644 --- a/packages/driver/src/cy/commands/origin/validator.ts +++ b/packages/driver/src/cy/commands/origin/validator.ts @@ -1,6 +1,8 @@ import $utils from '../../../cypress/utils' import $errUtils from '../../../cypress/error_utils' import { difference, isPlainObject, isString } from 'lodash' +import type { LocationObject } from '../../../cypress/location' +import * as cors from '@packages/network/lib/cors' const validOptionKeys = Object.freeze(['args']) @@ -67,13 +69,35 @@ export class Validator { return false } - validateLocation (location, urlOrDomain) { + /** + * Validates the location parameter of the cy.origin call. + * @param originLocation - the location passed into the cy.origin command. + * @param urlOrDomain - the original string param passed in. + * @param specHref - the address of the current spec. + */ + validateLocation (originLocation: LocationObject, urlOrDomain: string, specHref: string): void { // we don't support query params - if (location.search.length > 0) { + if (originLocation.search.length > 0) { $errUtils.throwErrByPath('origin.invalid_url_argument', { onFail: this.log, args: { arg: $utils.stringify(urlOrDomain) }, }) } + + // Users would be better off not using cy.origin if the origin is part of the same super domain. + if (cors.urlMatchesPolicyBasedOnDomain(originLocation.href, specHref)) { + // this._isSameSuperDomainOriginWithExceptions({ originLocation, specLocation })) { + + const policy = cors.policyForDomain(originLocation.href) + + $errUtils.throwErrByPath('origin.invalid_url_argument_same_origin', { + onFail: this.log, + args: { + originUrl: $utils.stringify(urlOrDomain), + topOrigin: (window.location.origin), + policy, + }, + }) + } } } diff --git a/packages/driver/src/cypress/error_messages.ts b/packages/driver/src/cypress/error_messages.ts index 005e1f77b25f..19b8b1b2ccfb 100644 --- a/packages/driver/src/cypress/error_messages.ts +++ b/packages/driver/src/cypress/error_messages.ts @@ -1191,6 +1191,13 @@ export default { invalid_url_argument: { message: `${cmd('origin')} requires the first argument to be either a url (\`https://www.example.com/path\`) or a domain name (\`example.com\`). Query parameters are not allowed. You passed: \`{{arg}}\``, }, + invalid_url_argument_same_origin ({ originUrl, topOrigin, policy }) { + return stripIndent`\ + ${cmd('origin')} requires the first argument to be a different ${policy === 'same-origin' ? 'origin' : 'domain' } than top. You passed \`${originUrl}\` to the origin command, while top is at \`${topOrigin}\`. + + Either the intended page was not visited prior to running the cy.origin block or the cy.origin block may not be needed at all. + ` + }, invalid_options_argument: { message: `${cmd('origin')} requires the 'options' argument to be an object. You passed: \`{{arg}}\``, }, @@ -1260,6 +1267,13 @@ export default { message: stripIndent`\ ${cmd('origin')} could not serialize the thrown value. Please make sure the value being thrown is supported by the structured clone algorithm.`, }, + failed_to_create_spec_bridge: { + message: stripIndent`\ + ${cmd('origin')} failed to create a spec bridge to communicate with the specified origin. This can happen when you attempt to create a spec bridge to an insecure (http) frame from a secure (https) frame. + + Check your Developer Tools Console for the actual error - it should be printed there. + `, + }, unsupported: { route: { message: `${cmd('route')} has been deprecated and its use is not supported in the ${cmd('origin')} callback. Consider using ${cmd('intercept')} (outside of the callback) instead.`, diff --git a/packages/network/lib/cors.ts b/packages/network/lib/cors.ts index 2e4eab92f248..a88c9e0af734 100644 --- a/packages/network/lib/cors.ts +++ b/packages/network/lib/cors.ts @@ -11,6 +11,8 @@ const debug = debugModule('cypress:network:cors') // match IP addresses or anything following the last . const customTldsRe = /(^[\d\.]+$|\.[^\.]+$)/ +const strictSameOriginDomains = Object.freeze(['google.com']) + export function getSuperDomain (url) { const parsed = parseUrlIntoHostProtocolDomainTldPort(url) @@ -81,30 +83,30 @@ export function getDomainNameFromParsedHost (parsedHost: ParsedHost) { * same-super-domain-origin: Whether or not a url's scheme, domain, top-level domain, and port match * same-site: Whether or not a url's scheme, domain, and top-level domain match. @see https://developer.mozilla.org/en-US/docs/Glossary/Site * @param {Policy} policy - the policy being used - * @param {string} url - the url being compared - * @param {ParsedHostWithProtocolAndHost} props - the props being compared against the url + * @param {string} frameUrl - the url being compared + * @param {ParsedHostWithProtocolAndHost} topProps - the props being compared against the url * @returns {boolean} whether or not the props and url fit the policy */ -function urlMatchesPolicyProps ({ policy, url, props }: { +function urlMatchesPolicyProps ({ policy, frameUrl, topProps }: { policy: Policy - url: string - props: ParsedHostWithProtocolAndHost + frameUrl: string + topProps: ParsedHostWithProtocolAndHost }): boolean { - if (!policy || !url || !props) { + if (!policy || !frameUrl || !topProps) { return false } - const urlProps = parseUrlIntoHostProtocolDomainTldPort(url) + const urlProps = parseUrlIntoHostProtocolDomainTldPort(frameUrl) switch (policy) { case 'same-origin': { // if same origin, all parts of the props needs to match, including subdomain and scheme - return _.isEqual(urlProps, props) + return _.isEqual(urlProps, topProps) } case 'same-super-domain-origin': case 'schemeful-same-site': { const { port: port1, subdomain: _unused1, ...parsedUrl } = urlProps - const { port: port2, subdomain: _unused2, ...relevantProps } = props + const { port: port2, subdomain: _unused2, ...relevantProps } = topProps let doPortsPassSameSchemeCheck: boolean @@ -124,67 +126,81 @@ function urlMatchesPolicyProps ({ policy, url, props }: { } } -function urlMatchesPolicy ({ policy, url1, url2 }: { +function urlMatchesPolicy ({ policy, frameUrl, topUrl }: { policy: Policy - url1: string - url2: string + frameUrl: string + topUrl: string }): boolean { - if (!policy || !url1 || !url2) { + if (!policy || !frameUrl || !topUrl) { return false } return urlMatchesPolicyProps({ policy, - url: url1, - props: parseUrlIntoHostProtocolDomainTldPort(url2), + frameUrl, + topProps: parseUrlIntoHostProtocolDomainTldPort(topUrl), }) } -export function urlMatchesOriginProps (url, props) { - return urlMatchesPolicyProps({ +export function urlOriginsMatch (frameUrl: string, topUrl: string): boolean { + return urlMatchesPolicy({ policy: 'same-origin', - url, - props, - }) -} - -export function urlMatchesSuperDomainOriginProps (url, props) { - return urlMatchesPolicyProps({ - policy: 'same-super-domain-origin', - url, - props, + frameUrl, + topUrl, }) } -export function urlMatchesSameSiteProps (url: string, props: ParsedHostWithProtocolAndHost) { - return urlMatchesPolicyProps({ +export const urlSameSiteMatch = (frameUrl: string, topUrl: string): boolean => { + return urlMatchesPolicy({ policy: 'schemeful-same-site', - url, - props, + frameUrl, + topUrl, }) } -export function urlOriginsMatch (url1: string, url2: string) { - return urlMatchesPolicy({ - policy: 'same-origin', - url1, - url2, - }) +/** + * Returns the policy that will be used for the specified url. + * @param url - the url to check the policy against. + * @returns a Policy string. + */ +export const policyForDomain = (url: string): Policy => { + const obj = parseUrlIntoHostProtocolDomainTldPort(url) + + return strictSameOriginDomains.includes(`${obj.domain}.${obj.tld}`) ? 'same-origin' : 'same-super-domain-origin' } -export function urlsSuperDomainOriginMatch (url1: string, url2: string) { +/** + * Checks the supplied url's against the determined policy. + * The policy is same-super-domain-origin unless the domain is in the list of strict same origin domains, + * in which case the policy is 'same-origin' + * @param frameUrl - The url you are testing the policy for. + * @param topUrl - The url you are testing the policy in context of. + * @returns boolean, true if matching, false if not. + */ +export const urlMatchesPolicyBasedOnDomain = (frameUrl: string, topUrl: string): boolean => { return urlMatchesPolicy({ - policy: 'same-super-domain-origin', - url1, - url2, + policy: policyForDomain(frameUrl), + frameUrl, + topUrl, }) } -export const urlSameSiteMatch = (url1: string, url2: string) => { - return urlMatchesPolicy({ - policy: 'schemeful-same-site', - url1, - url2, +/** + * Checks the supplied url and props against the determined policy. + * The policy is same-super-domain-origin unless the domain is in the list of strict same origin domains, + * in which case the policy is 'same-origin' + * @param frameUrl - The url you are testing the policy for. + * @param topProps - The props of the url you are testing the policy in context of. + * @returns boolean, true if matching, false if not. + */ +export const urlMatchesPolicyBasedOnDomainProps = (frameUrl: string, topProps: ParsedHostWithProtocolAndHost): boolean => { + const obj = parseUrlIntoHostProtocolDomainTldPort(frameUrl) + const policy = strictSameOriginDomains.includes(`${obj.domain}.${obj.tld}`) ? 'same-origin' : 'same-super-domain-origin' + + return urlMatchesPolicyProps({ + policy, + frameUrl, + topProps, }) } diff --git a/packages/network/test/unit/cors_spec.ts b/packages/network/test/unit/cors_spec.ts index 8ed22d55cca3..348e65ddd2f3 100644 --- a/packages/network/test/unit/cors_spec.ts +++ b/packages/network/test/unit/cors_spec.ts @@ -109,357 +109,270 @@ describe('lib/cors', () => { }) }) - context('.urlMatchesOriginProps', () => { - const assertOriginsDoNotMatch = (url, props) => { - expect(cors.urlMatchesOriginProps(url, props)).to.be.false + context('.urlOriginsMatch', () => { + const assertOriginsDoNotMatch = (url1, url2) => { + expect(cors.urlOriginsMatch(url1, url2)).to.be.false } - const assertOriginsDoMatch = (url, props) => { - expect(cors.urlMatchesOriginProps(url, props)).to.be.true + const assertOriginsDoMatch = (url1, url2) => { + expect(cors.urlOriginsMatch(url1, url2)).to.be.true } describe('domain + subdomain', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('https://staging.google.com') + const url = 'https://staging.google.com' it('does not match', function () { - assertOriginsDoNotMatch('https://foo.bar:443', props) - assertOriginsDoNotMatch('http://foo.bar:80', props) - assertOriginsDoNotMatch('http://foo.bar', props) - assertOriginsDoNotMatch('http://staging.google.com', props) - assertOriginsDoNotMatch('http://staging.google.com:80', props) - assertOriginsDoNotMatch('https://staging.google2.com:443', props) - assertOriginsDoNotMatch('https://staging.google.net:443', props) - assertOriginsDoNotMatch('https://google.net:443', props) - assertOriginsDoNotMatch('http://google.com', props) - assertOriginsDoNotMatch('https://google.com:443', props) - assertOriginsDoNotMatch('https://foo.google.com:443', props) - assertOriginsDoNotMatch('https://foo.bar.google.com:443', props) + assertOriginsDoNotMatch('https://foo.bar:443', url) + assertOriginsDoNotMatch('http://foo.bar:80', url) + assertOriginsDoNotMatch('http://foo.bar', url) + assertOriginsDoNotMatch('http://staging.google.com', url) + assertOriginsDoNotMatch('http://staging.google.com:80', url) + assertOriginsDoNotMatch('https://staging.google2.com:443', url) + assertOriginsDoNotMatch('https://staging.google.net:443', url) + assertOriginsDoNotMatch('https://google.net:443', url) + assertOriginsDoNotMatch('http://google.com', url) + assertOriginsDoNotMatch('https://google.com:443', url) + assertOriginsDoNotMatch('https://foo.google.com:443', url) + assertOriginsDoNotMatch('https://foo.bar.google.com:443', url) }) it('matches', function () { - assertOriginsDoMatch('https://staging.google.com:443', props) + assertOriginsDoMatch('https://staging.google.com:443', url) }) }) describe('public suffix', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('https://example.gitlab.io') + const url = 'https://example.gitlab.io' it('does not match', function () { - assertOriginsDoNotMatch('http://example.gitlab.io', props) - assertOriginsDoNotMatch('https://foo.gitlab.io:443', props) - assertOriginsDoNotMatch('https://foo.example.gitlab.io:443', props) + assertOriginsDoNotMatch('http://example.gitlab.io', url) + assertOriginsDoNotMatch('https://foo.gitlab.io:443', url) + assertOriginsDoNotMatch('https://foo.example.gitlab.io:443', url) }) it('matches', function () { - assertOriginsDoMatch('https://example.gitlab.io:443', props) + assertOriginsDoMatch('https://example.gitlab.io:443', url) }) }) describe('localhost', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://localhost:4200') + const url = 'http://localhost:4200' it('does not match', function () { - assertOriginsDoNotMatch('http://localhost:4201', props) - assertOriginsDoNotMatch('http://localhoss:4200', props) + assertOriginsDoNotMatch('http://localhoss:4200', url) + assertOriginsDoNotMatch('http://localhost:4201', url) }) it('matches', function () { - assertOriginsDoMatch('http://localhost:4200', props) + assertOriginsDoMatch('http://localhost:4200', url) }) }) describe('app.localhost', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://app.localhost:4200') + const url = 'http://app.localhost:4200' it('does not match', function () { - assertOriginsDoNotMatch('http://app.localhost:4201', props) - assertOriginsDoNotMatch('http://app.localhoss:4200', props) - assertOriginsDoNotMatch('http://name.app.localhost:4200', props) + assertOriginsDoNotMatch('http://app.localhoss:4200', url) + assertOriginsDoNotMatch('http://app.localhost:4201', url) + assertOriginsDoNotMatch('http://name.app.localhost:4200', url) }) it('matches', function () { - assertOriginsDoMatch('http://app.localhost:4200', props) + assertOriginsDoMatch('http://app.localhost:4200', url) }) }) describe('local', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://brian.dev.local') + const url = 'http://brian.dev.local' it('does not match', function () { - assertOriginsDoNotMatch('https://brian.dev.local:443', props) - assertOriginsDoNotMatch('https://brian.dev.local', props) - assertOriginsDoNotMatch('http://brian.dev2.local:81', props) - assertOriginsDoNotMatch('http://jennifer.dev.local:80', props) - assertOriginsDoNotMatch('http://jennifer.dev.local', props) - }) - - it('matches', function () { - assertOriginsDoMatch('http://brian.dev.local:80', props) + assertOriginsDoNotMatch('https://brian.dev.local:443', url) + assertOriginsDoNotMatch('https://brian.dev.local', url) + assertOriginsDoNotMatch('http://brian.dev2.local:81', url) + assertOriginsDoNotMatch('http://jennifer.dev.local:4201', url) + assertOriginsDoNotMatch('http://jennifer.dev.local:80', url) + assertOriginsDoNotMatch('http://jennifer.dev.local', url) }) }) describe('ip address', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://192.168.5.10') + const url = 'http://192.168.5.10' it('does not match', function () { - assertOriginsDoNotMatch('http://192.168.5.10:443', props) - assertOriginsDoNotMatch('https://192.168.5.10', props) - assertOriginsDoNotMatch('http://193.168.5.10', props) - assertOriginsDoNotMatch('http://193.168.5.10:80', props) + assertOriginsDoNotMatch('http://192.168.5.10:443', url) + assertOriginsDoNotMatch('https://192.168.5.10', url) + assertOriginsDoNotMatch('http://193.168.5.10', url) + assertOriginsDoNotMatch('http://193.168.5.10:80', url) + assertOriginsDoNotMatch('http://192.168.5.10:12345', url) }) it('matches', function () { - assertOriginsDoMatch('http://192.168.5.10', props) - assertOriginsDoMatch('http://192.168.5.10:80', props) + assertOriginsDoMatch('http://192.168.5.10', url) + assertOriginsDoMatch('http://192.168.5.10:80', url) }) }) }) - context('.urlMatchesSuperDomainOriginProps', () => { - const assertSuperDomainOriginDoesNotMatch = (url, props) => { - expect(cors.urlMatchesSuperDomainOriginProps(url, props)).to.be.false + context('.urlSameSiteMatch', () => { + const assertsUrlsAreNotSameSite = (url1, url2) => { + expect(cors.urlSameSiteMatch(url1, url2)).to.be.false } - const assertSuperDomainOriginDoesMatch = (url, props) => { - expect(cors.urlMatchesSuperDomainOriginProps(url, props)).to.be.true + const assertsUrlsAreSameSite = (url1, url2) => { + expect(cors.urlSameSiteMatch(url1, url2)).to.be.true } describe('domain + subdomain', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('https://staging.google.com') + const url = 'https://staging.google.com' it('does not match', function () { - assertSuperDomainOriginDoesNotMatch('https://foo.bar:443', props) - assertSuperDomainOriginDoesNotMatch('http://foo.bar:80', props) - assertSuperDomainOriginDoesNotMatch('http://foo.bar', props) - assertSuperDomainOriginDoesNotMatch('http://staging.google.com', props) - assertSuperDomainOriginDoesNotMatch('http://staging.google.com:80', props) - assertSuperDomainOriginDoesNotMatch('https://staging.google2.com:443', props) - assertSuperDomainOriginDoesNotMatch('https://staging.google.net:443', props) - assertSuperDomainOriginDoesNotMatch('https://google.net:443', props) - assertSuperDomainOriginDoesNotMatch('http://google.com', props) + assertsUrlsAreNotSameSite('https://foo.bar:443', url) + assertsUrlsAreNotSameSite('http://foo.bar:80', url) + assertsUrlsAreNotSameSite('http://foo.bar', url) + assertsUrlsAreNotSameSite('http://staging.google.com', url) + assertsUrlsAreNotSameSite('http://staging.google.com:80', url) + assertsUrlsAreNotSameSite('https://staging.google2.com:443', url) + assertsUrlsAreNotSameSite('https://staging.google.net:443', url) + assertsUrlsAreNotSameSite('https://google.net:443', url) + assertsUrlsAreNotSameSite('http://google.com', url) }) it('matches', function () { - assertSuperDomainOriginDoesMatch('https://staging.google.com:443', props) - assertSuperDomainOriginDoesMatch('https://google.com:443', props) - assertSuperDomainOriginDoesMatch('https://foo.google.com:443', props) - assertSuperDomainOriginDoesMatch('https://foo.bar.google.com:443', props) + assertsUrlsAreSameSite('https://staging.google.com:443', url) + assertsUrlsAreSameSite('https://google.com:443', url) + assertsUrlsAreSameSite('https://foo.google.com:443', url) + assertsUrlsAreSameSite('https://foo.bar.google.com:443', url) }) }) describe('public suffix', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('https://example.gitlab.io') + const url = 'https://example.gitlab.io' it('does not match', function () { - assertSuperDomainOriginDoesNotMatch('http://example.gitlab.io', props) - assertSuperDomainOriginDoesNotMatch('https://foo.gitlab.io:443', props) + assertsUrlsAreNotSameSite('http://example.gitlab.io', url) + assertsUrlsAreNotSameSite('https://foo.gitlab.io:443', url) }) it('matches', function () { - assertSuperDomainOriginDoesMatch('https://example.gitlab.io:443', props) - assertSuperDomainOriginDoesMatch('https://foo.example.gitlab.io:443', props) + assertsUrlsAreSameSite('https://example.gitlab.io:443', url) + assertsUrlsAreSameSite('https://foo.example.gitlab.io:443', url) }) }) describe('localhost', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://localhost:4200') + const url = 'http://localhost:4200' it('does not match', function () { - assertSuperDomainOriginDoesNotMatch('http://localhoss:4200', props) - assertSuperDomainOriginDoesNotMatch('http://localhost:4201', props) + assertsUrlsAreNotSameSite('http://localhoss:4200', url) }) it('matches', function () { - assertSuperDomainOriginDoesMatch('http://localhost:4200', props) + assertsUrlsAreSameSite('http://localhost:4200', url) + assertsUrlsAreSameSite('http://localhost:4201', url) }) }) describe('app.localhost', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://app.localhost:4200') + const url = 'http://app.localhost:4200' it('does not match', function () { - assertSuperDomainOriginDoesNotMatch('http://app.localhoss:4200', props) - assertSuperDomainOriginDoesNotMatch('http://app.localhost:4201', props) + assertsUrlsAreNotSameSite('http://app.localhoss:4200', url) }) it('matches', function () { - assertSuperDomainOriginDoesMatch('http://app.localhost:4200', props) - assertSuperDomainOriginDoesMatch('http://name.app.localhost:4200', props) + assertsUrlsAreSameSite('http://app.localhost:4200', url) + assertsUrlsAreSameSite('http://name.app.localhost:4200', url) + assertsUrlsAreSameSite('http://app.localhost:4201', url) }) }) describe('local', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://brian.dev.local') + const url = 'http://brian.dev.local' it('does not match', function () { - assertSuperDomainOriginDoesNotMatch('https://brian.dev.local:443', props) - assertSuperDomainOriginDoesNotMatch('https://brian.dev.local', props) - assertSuperDomainOriginDoesNotMatch('http://brian.dev2.local:81', props) - assertSuperDomainOriginDoesNotMatch('http://brian.dev.local:8081', props) + assertsUrlsAreNotSameSite('https://brian.dev.local:443', url) + assertsUrlsAreNotSameSite('https://brian.dev.local', url) + assertsUrlsAreNotSameSite('http://brian.dev2.local:81', url) }) it('matches', function () { - assertSuperDomainOriginDoesMatch('http://brian.dev.local:80', props) - assertSuperDomainOriginDoesMatch('http://jennifer.dev.local:80', props) - assertSuperDomainOriginDoesMatch('http://jennifer.dev.local', props) + assertsUrlsAreSameSite('http://jennifer.dev.local:4201', url) + assertsUrlsAreSameSite('http://jennifer.dev.local:80', url) + assertsUrlsAreSameSite('http://jennifer.dev.local', url) + assertsUrlsAreSameSite('http://brian.dev.local:8081', url) }) }) describe('ip address', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://192.168.5.10') + const url = 'http://192.168.5.10' it('does not match', function () { - assertSuperDomainOriginDoesNotMatch('http://192.168.5.10:443', props) - assertSuperDomainOriginDoesNotMatch('https://192.168.5.10', props) - assertSuperDomainOriginDoesNotMatch('http://193.168.5.10', props) - assertSuperDomainOriginDoesNotMatch('http://193.168.5.10:80', props) - assertSuperDomainOriginDoesNotMatch('http://192.168.5.10:8081', props) + assertsUrlsAreNotSameSite('http://192.168.5.10:443', url) + assertsUrlsAreNotSameSite('https://192.168.5.10', url) + assertsUrlsAreNotSameSite('http://193.168.5.10', url) + assertsUrlsAreNotSameSite('http://193.168.5.10:80', url) }) it('matches', function () { - assertSuperDomainOriginDoesMatch('http://192.168.5.10', props) - assertSuperDomainOriginDoesMatch('http://192.168.5.10:80', props) + assertsUrlsAreSameSite('http://192.168.5.10', url) + assertsUrlsAreSameSite('http://192.168.5.10:80', url) + assertsUrlsAreSameSite('http://192.168.5.10:12345', url) }) }) }) - context('.urlMatchesSameSiteProps', () => { - const assertSameSiteDoesNotMatch = (url, props) => { - expect(cors.urlMatchesSameSiteProps(url, props)).to.be.false + context('.urlMatchesPolicyBasedOnDomain', () => { + const assertsUrlsAreNotAPolicyMatch = (url1, url2) => { + expect(cors.urlMatchesPolicyBasedOnDomain(url1, url2)).to.be.false } - const assertSameSiteDoesMatch = (url, props) => { - expect(cors.urlMatchesSameSiteProps(url, props)).to.be.true + const assertsUrlsAreAPolicyOriginMatch = (url1, url2) => { + expect(cors.urlMatchesPolicyBasedOnDomain(url1, url2)).to.be.true } describe('domain + subdomain', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('https://staging.google.com') - - it('does not match', function () { - assertSameSiteDoesNotMatch('https://foo.bar:443', props) - assertSameSiteDoesNotMatch('http://foo.bar:80', props) - assertSameSiteDoesNotMatch('http://foo.bar', props) - assertSameSiteDoesNotMatch('http://staging.google.com', props) - assertSameSiteDoesNotMatch('http://staging.google.com:80', props) - assertSameSiteDoesNotMatch('https://staging.google2.com:443', props) - assertSameSiteDoesNotMatch('https://staging.google.net:443', props) - assertSameSiteDoesNotMatch('https://google.net:443', props) - assertSameSiteDoesNotMatch('http://google.com', props) - }) - - it('matches', function () { - assertSameSiteDoesMatch('https://staging.google.com:443', props) - assertSameSiteDoesMatch('https://google.com:443', props) - assertSameSiteDoesMatch('https://foo.google.com:443', props) - assertSameSiteDoesMatch('https://foo.bar.google.com:443', props) - }) - }) - - describe('public suffix', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('https://example.gitlab.io') - - it('does not match', function () { - assertSameSiteDoesNotMatch('http://example.gitlab.io', props) - assertSameSiteDoesNotMatch('https://foo.gitlab.io:443', props) - }) - - it('matches', function () { - assertSameSiteDoesMatch('https://example.gitlab.io:443', props) - assertSameSiteDoesMatch('https://foo.example.gitlab.io:443', props) - }) - }) - - describe('localhost', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://localhost:4200') - - it('does not match', function () { - assertSameSiteDoesNotMatch('http://localhoss:4200', props) - }) - - it('matches', function () { - assertSameSiteDoesMatch('http://localhost:4201', props) - assertSameSiteDoesMatch('http://localhost:4200', props) - }) - }) - - describe('app.localhost', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://app.localhost:4200') - - it('does not match', function () { - assertSameSiteDoesNotMatch('http://app.localhoss:4200', props) - }) - - it('matches', function () { - assertSameSiteDoesMatch('http://app.localhost:4200', props) - assertSameSiteDoesMatch('http://name.app.localhost:4200', props) - assertSameSiteDoesMatch('http://app.localhost:4201', props) - }) - }) - - describe('local', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://brian.dev.local') - - it('does not match', function () { - assertSameSiteDoesNotMatch('https://brian.dev.local:443', props) - assertSameSiteDoesNotMatch('https://brian.dev.local', props) - assertSameSiteDoesNotMatch('http://brian.dev2.local:81', props) - }) - - it('matches', function () { - assertSameSiteDoesMatch('http://brian.dev.local:80', props) - assertSameSiteDoesMatch('http://jennifer.dev.local:80', props) - assertSameSiteDoesMatch('http://jennifer.dev.local', props) - assertSameSiteDoesMatch('http://brian.dev.local:8081', props) - }) - }) - - describe('ip address', () => { - const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://192.168.5.10') + const url = 'https://staging.gurgle.com' it('does not match', function () { - assertSameSiteDoesNotMatch('http://192.168.5.10:443', props) - assertSameSiteDoesNotMatch('https://192.168.5.10', props) - assertSameSiteDoesNotMatch('http://193.168.5.10', props) - assertSameSiteDoesNotMatch('http://193.168.5.10:80', props) + assertsUrlsAreNotAPolicyMatch('https://foo.bar:443', url) + assertsUrlsAreNotAPolicyMatch('http://foo.bar:80', url) + assertsUrlsAreNotAPolicyMatch('http://foo.bar', url) + assertsUrlsAreNotAPolicyMatch('http://staging.gurgle.com', url) + assertsUrlsAreNotAPolicyMatch('http://staging.gurgle.com:80', url) + assertsUrlsAreNotAPolicyMatch('https://staging.gurgle2.com:443', url) + assertsUrlsAreNotAPolicyMatch('https://staging.gurgle.net:443', url) + assertsUrlsAreNotAPolicyMatch('https://gurgle.net:443', url) + assertsUrlsAreNotAPolicyMatch('http://gurgle.com', url) }) it('matches', function () { - assertSameSiteDoesMatch('http://192.168.5.10', props) - assertSameSiteDoesMatch('http://192.168.5.10:80', props) - assertSameSiteDoesMatch('http://192.168.5.10:8081', props) + assertsUrlsAreAPolicyOriginMatch('https://staging.gurgle.com:443', url) + assertsUrlsAreAPolicyOriginMatch('https://gurgle.com:443', url) + assertsUrlsAreAPolicyOriginMatch('https://foo.gurgle.com:443', url) + assertsUrlsAreAPolicyOriginMatch('https://foo.bar.gurgle.com:443', url) }) }) - }) - - context('.urlOriginsMatch', () => { - const assertOriginsDoNotMatch = (url1, url2) => { - expect(cors.urlOriginsMatch(url1, url2)).to.be.false - } - const assertOriginsDoMatch = (url1, url2) => { - expect(cors.urlOriginsMatch(url1, url2)).to.be.true - } - - describe('domain + subdomain', () => { + describe('google (strict same-origin policy)', () => { const url = 'https://staging.google.com' it('does not match', function () { - assertOriginsDoNotMatch('https://foo.bar:443', url) - assertOriginsDoNotMatch('http://foo.bar:80', url) - assertOriginsDoNotMatch('http://foo.bar', url) - assertOriginsDoNotMatch('http://staging.google.com', url) - assertOriginsDoNotMatch('http://staging.google.com:80', url) - assertOriginsDoNotMatch('https://staging.google2.com:443', url) - assertOriginsDoNotMatch('https://staging.google.net:443', url) - assertOriginsDoNotMatch('https://google.net:443', url) - assertOriginsDoNotMatch('http://google.com', url) - assertOriginsDoNotMatch('https://google.com:443', url) - assertOriginsDoNotMatch('https://foo.google.com:443', url) - assertOriginsDoNotMatch('https://foo.bar.google.com:443', url) + assertsUrlsAreNotAPolicyMatch('https://foo.bar:443', url) + assertsUrlsAreNotAPolicyMatch('http://foo.bar:80', url) + assertsUrlsAreNotAPolicyMatch('http://foo.bar', url) + assertsUrlsAreNotAPolicyMatch('http://staging.google.com', url) + assertsUrlsAreNotAPolicyMatch('http://staging.google.com:80', url) + assertsUrlsAreNotAPolicyMatch('https://staging.google2.com:443', url) + assertsUrlsAreNotAPolicyMatch('https://staging.google.net:443', url) + assertsUrlsAreNotAPolicyMatch('https://google.net:443', url) + assertsUrlsAreNotAPolicyMatch('http://google.com', url) + assertsUrlsAreNotAPolicyMatch('https://google.com:443', url) + assertsUrlsAreNotAPolicyMatch('https://foo.google.com:443', url) + assertsUrlsAreNotAPolicyMatch('https://foo.bar.google.com:443', url) }) it('matches', function () { - assertOriginsDoMatch('https://staging.google.com:443', url) + assertsUrlsAreAPolicyOriginMatch('https://staging.google.com:443', url) }) }) @@ -467,13 +380,13 @@ describe('lib/cors', () => { const url = 'https://example.gitlab.io' it('does not match', function () { - assertOriginsDoNotMatch('http://example.gitlab.io', url) - assertOriginsDoNotMatch('https://foo.gitlab.io:443', url) - assertOriginsDoNotMatch('https://foo.example.gitlab.io:443', url) + assertsUrlsAreNotAPolicyMatch('http://example.gitlab.io', url) + assertsUrlsAreNotAPolicyMatch('https://foo.gitlab.io:443', url) }) it('matches', function () { - assertOriginsDoMatch('https://example.gitlab.io:443', url) + assertsUrlsAreAPolicyOriginMatch('https://example.gitlab.io:443', url) + assertsUrlsAreAPolicyOriginMatch('https://foo.example.gitlab.io:443', url) }) }) @@ -481,12 +394,12 @@ describe('lib/cors', () => { const url = 'http://localhost:4200' it('does not match', function () { - assertOriginsDoNotMatch('http://localhoss:4200', url) - assertOriginsDoNotMatch('http://localhost:4201', url) + assertsUrlsAreNotAPolicyMatch('http://localhoss:4200', url) + assertsUrlsAreNotAPolicyMatch('http://localhost:4201', url) }) it('matches', function () { - assertOriginsDoMatch('http://localhost:4200', url) + assertsUrlsAreAPolicyOriginMatch('http://localhost:4200', url) }) }) @@ -494,13 +407,13 @@ describe('lib/cors', () => { const url = 'http://app.localhost:4200' it('does not match', function () { - assertOriginsDoNotMatch('http://app.localhoss:4200', url) - assertOriginsDoNotMatch('http://app.localhost:4201', url) - assertOriginsDoNotMatch('http://name.app.localhost:4200', url) + assertsUrlsAreNotAPolicyMatch('http://app.localhoss:4200', url) + assertsUrlsAreNotAPolicyMatch('http://app.localhost:4201', url) }) it('matches', function () { - assertOriginsDoMatch('http://app.localhost:4200', url) + assertsUrlsAreAPolicyOriginMatch('http://app.localhost:4200', url) + assertsUrlsAreAPolicyOriginMatch('http://name.app.localhost:4200', url) }) }) @@ -508,12 +421,16 @@ describe('lib/cors', () => { const url = 'http://brian.dev.local' it('does not match', function () { - assertOriginsDoNotMatch('https://brian.dev.local:443', url) - assertOriginsDoNotMatch('https://brian.dev.local', url) - assertOriginsDoNotMatch('http://brian.dev2.local:81', url) - assertOriginsDoNotMatch('http://jennifer.dev.local:4201', url) - assertOriginsDoNotMatch('http://jennifer.dev.local:80', url) - assertOriginsDoNotMatch('http://jennifer.dev.local', url) + assertsUrlsAreNotAPolicyMatch('https://brian.dev.local:443', url) + assertsUrlsAreNotAPolicyMatch('https://brian.dev.local', url) + assertsUrlsAreNotAPolicyMatch('http://brian.dev2.local:81', url) + assertsUrlsAreNotAPolicyMatch('http://brian.dev.local:8081', url) + }) + + it('matches', function () { + assertsUrlsAreAPolicyOriginMatch('http://jennifer.dev.local', url) + assertsUrlsAreAPolicyOriginMatch('http://jennifer.dev.local:80', url) + assertsUrlsAreAPolicyOriginMatch('http://jennifer.dev.local', url) }) }) @@ -521,232 +438,147 @@ describe('lib/cors', () => { const url = 'http://192.168.5.10' it('does not match', function () { - assertOriginsDoNotMatch('http://192.168.5.10:443', url) - assertOriginsDoNotMatch('https://192.168.5.10', url) - assertOriginsDoNotMatch('http://193.168.5.10', url) - assertOriginsDoNotMatch('http://193.168.5.10:80', url) - assertOriginsDoNotMatch('http://192.168.5.10:12345', url) + assertsUrlsAreNotAPolicyMatch('http://192.168.5.10:443', url) + assertsUrlsAreNotAPolicyMatch('https://192.168.5.10', url) + assertsUrlsAreNotAPolicyMatch('http://193.168.5.10', url) + assertsUrlsAreNotAPolicyMatch('http://193.168.5.10:80', url) + assertsUrlsAreNotAPolicyMatch('http://192.168.5.10:12345', url) }) it('matches', function () { - assertOriginsDoMatch('http://192.168.5.10', url) - assertOriginsDoMatch('http://192.168.5.10:80', url) + assertsUrlsAreAPolicyOriginMatch('http://192.168.5.10', url) + assertsUrlsAreAPolicyOriginMatch('http://192.168.5.10:80', url) }) }) }) - context('.urlsSuperDomainOriginMatch', () => { - const assertsUrlsAreNotASuperDomainOriginMatch = (url1, url2) => { - expect(cors.urlsSuperDomainOriginMatch(url1, url2)).to.be.false + context('.urlMatchesPolicyBasedOnDomainProps', () => { + const assertsUrlsAreNotAPolicyMatch = (url1, props) => { + expect(cors.urlMatchesPolicyBasedOnDomainProps(url1, props)).to.be.false } - const assertsUrlsAreASuperDomainOriginMatch = (url1, url2) => { - expect(cors.urlsSuperDomainOriginMatch(url1, url2)).to.be.true + const assertsUrlsAreAPolicyOriginMatch = (url1, props) => { + expect(cors.urlMatchesPolicyBasedOnDomainProps(url1, props)).to.be.true } describe('domain + subdomain', () => { - const url = 'https://staging.google.com' - - it('does not match', function () { - assertsUrlsAreNotASuperDomainOriginMatch('https://foo.bar:443', url) - assertsUrlsAreNotASuperDomainOriginMatch('http://foo.bar:80', url) - assertsUrlsAreNotASuperDomainOriginMatch('http://foo.bar', url) - assertsUrlsAreNotASuperDomainOriginMatch('http://staging.google.com', url) - assertsUrlsAreNotASuperDomainOriginMatch('http://staging.google.com:80', url) - assertsUrlsAreNotASuperDomainOriginMatch('https://staging.google2.com:443', url) - assertsUrlsAreNotASuperDomainOriginMatch('https://staging.google.net:443', url) - assertsUrlsAreNotASuperDomainOriginMatch('https://google.net:443', url) - assertsUrlsAreNotASuperDomainOriginMatch('http://google.com', url) - }) - - it('matches', function () { - assertsUrlsAreASuperDomainOriginMatch('https://staging.google.com:443', url) - assertsUrlsAreASuperDomainOriginMatch('https://google.com:443', url) - assertsUrlsAreASuperDomainOriginMatch('https://foo.google.com:443', url) - assertsUrlsAreASuperDomainOriginMatch('https://foo.bar.google.com:443', url) - }) - }) - - describe('public suffix', () => { - const url = 'https://example.gitlab.io' - - it('does not match', function () { - assertsUrlsAreNotASuperDomainOriginMatch('http://example.gitlab.io', url) - assertsUrlsAreNotASuperDomainOriginMatch('https://foo.gitlab.io:443', url) - }) - - it('matches', function () { - assertsUrlsAreASuperDomainOriginMatch('https://example.gitlab.io:443', url) - assertsUrlsAreASuperDomainOriginMatch('https://foo.example.gitlab.io:443', url) - }) - }) - - describe('localhost', () => { - const url = 'http://localhost:4200' - - it('does not match', function () { - assertsUrlsAreNotASuperDomainOriginMatch('http://localhoss:4200', url) - assertsUrlsAreNotASuperDomainOriginMatch('http://localhost:4201', url) - }) - - it('matches', function () { - assertsUrlsAreASuperDomainOriginMatch('http://localhost:4200', url) - }) - }) - - describe('app.localhost', () => { - const url = 'http://app.localhost:4200' + const props = cors.parseUrlIntoHostProtocolDomainTldPort('https://staging.gurgle.com') it('does not match', function () { - assertsUrlsAreNotASuperDomainOriginMatch('http://app.localhoss:4200', url) - assertsUrlsAreNotASuperDomainOriginMatch('http://app.localhost:4201', url) + assertsUrlsAreNotAPolicyMatch('https://foo.bar:443', props) + assertsUrlsAreNotAPolicyMatch('http://foo.bar:80', props) + assertsUrlsAreNotAPolicyMatch('http://foo.bar', props) + assertsUrlsAreNotAPolicyMatch('http://staging.gurgle.com', props) + assertsUrlsAreNotAPolicyMatch('http://staging.gurgle.com:80', props) + assertsUrlsAreNotAPolicyMatch('https://staging.gurgle2.com:443', props) + assertsUrlsAreNotAPolicyMatch('https://staging.gurgle.net:443', props) + assertsUrlsAreNotAPolicyMatch('https://gurgle.net:443', props) + assertsUrlsAreNotAPolicyMatch('http://gurgle.com', props) }) it('matches', function () { - assertsUrlsAreASuperDomainOriginMatch('http://app.localhost:4200', url) - assertsUrlsAreASuperDomainOriginMatch('http://name.app.localhost:4200', url) + assertsUrlsAreAPolicyOriginMatch('https://staging.gurgle.com:443', props) + assertsUrlsAreAPolicyOriginMatch('https://gurgle.com:443', props) + assertsUrlsAreAPolicyOriginMatch('https://foo.gurgle.com:443', props) + assertsUrlsAreAPolicyOriginMatch('https://foo.bar.gurgle.com:443', props) }) }) - describe('local', () => { - const url = 'http://brian.dev.local' - - it('does not match', function () { - assertsUrlsAreNotASuperDomainOriginMatch('https://brian.dev.local:443', url) - assertsUrlsAreNotASuperDomainOriginMatch('https://brian.dev.local', url) - assertsUrlsAreNotASuperDomainOriginMatch('http://brian.dev2.local:81', url) - assertsUrlsAreNotASuperDomainOriginMatch('http://brian.dev.local:8081', url) - }) - - it('matches', function () { - assertsUrlsAreASuperDomainOriginMatch('http://jennifer.dev.local', url) - assertsUrlsAreASuperDomainOriginMatch('http://jennifer.dev.local:80', url) - assertsUrlsAreASuperDomainOriginMatch('http://jennifer.dev.local', url) - }) - }) - - describe('ip address', () => { - const url = 'http://192.168.5.10' + describe('google (strict same-origin policy)', () => { + const props = cors.parseUrlIntoHostProtocolDomainTldPort('https://staging.google.com') it('does not match', function () { - assertsUrlsAreNotASuperDomainOriginMatch('http://192.168.5.10:443', url) - assertsUrlsAreNotASuperDomainOriginMatch('https://192.168.5.10', url) - assertsUrlsAreNotASuperDomainOriginMatch('http://193.168.5.10', url) - assertsUrlsAreNotASuperDomainOriginMatch('http://193.168.5.10:80', url) - assertsUrlsAreNotASuperDomainOriginMatch('http://192.168.5.10:12345', url) + assertsUrlsAreNotAPolicyMatch('https://foo.bar:443', props) + assertsUrlsAreNotAPolicyMatch('http://foo.bar:80', props) + assertsUrlsAreNotAPolicyMatch('http://foo.bar', props) + assertsUrlsAreNotAPolicyMatch('http://staging.google.com', props) + assertsUrlsAreNotAPolicyMatch('http://staging.google.com:80', props) + assertsUrlsAreNotAPolicyMatch('https://staging.google2.com:443', props) + assertsUrlsAreNotAPolicyMatch('https://staging.google.net:443', props) + assertsUrlsAreNotAPolicyMatch('https://google.net:443', props) + assertsUrlsAreNotAPolicyMatch('http://google.com', props) + assertsUrlsAreNotAPolicyMatch('https://google.com:443', props) + assertsUrlsAreNotAPolicyMatch('https://foo.google.com:443', props) + assertsUrlsAreNotAPolicyMatch('https://foo.bar.google.com:443', props) }) it('matches', function () { - assertsUrlsAreASuperDomainOriginMatch('http://192.168.5.10', url) - assertsUrlsAreASuperDomainOriginMatch('http://192.168.5.10:80', url) - }) - }) - }) - - context('.urlSameSiteMatch', () => { - const assertsUrlsAreNotSameSite = (url1, url2) => { - expect(cors.urlSameSiteMatch(url1, url2)).to.be.false - } - - const assertsUrlsAreSameSite = (url1, url2) => { - expect(cors.urlSameSiteMatch(url1, url2)).to.be.true - } - - describe('domain + subdomain', () => { - const url = 'https://staging.google.com' - - it('does not match', function () { - assertsUrlsAreNotSameSite('https://foo.bar:443', url) - assertsUrlsAreNotSameSite('http://foo.bar:80', url) - assertsUrlsAreNotSameSite('http://foo.bar', url) - assertsUrlsAreNotSameSite('http://staging.google.com', url) - assertsUrlsAreNotSameSite('http://staging.google.com:80', url) - assertsUrlsAreNotSameSite('https://staging.google2.com:443', url) - assertsUrlsAreNotSameSite('https://staging.google.net:443', url) - assertsUrlsAreNotSameSite('https://google.net:443', url) - assertsUrlsAreNotSameSite('http://google.com', url) - }) - - it('matches', function () { - assertsUrlsAreSameSite('https://staging.google.com:443', url) - assertsUrlsAreSameSite('https://google.com:443', url) - assertsUrlsAreSameSite('https://foo.google.com:443', url) - assertsUrlsAreSameSite('https://foo.bar.google.com:443', url) + assertsUrlsAreAPolicyOriginMatch('https://staging.google.com:443', props) }) }) describe('public suffix', () => { - const url = 'https://example.gitlab.io' + const props = cors.parseUrlIntoHostProtocolDomainTldPort('https://example.gitlab.io') it('does not match', function () { - assertsUrlsAreNotSameSite('http://example.gitlab.io', url) - assertsUrlsAreNotSameSite('https://foo.gitlab.io:443', url) + assertsUrlsAreNotAPolicyMatch('http://example.gitlab.io', props) + assertsUrlsAreNotAPolicyMatch('https://foo.gitlab.io:443', props) }) it('matches', function () { - assertsUrlsAreSameSite('https://example.gitlab.io:443', url) - assertsUrlsAreSameSite('https://foo.example.gitlab.io:443', url) + assertsUrlsAreAPolicyOriginMatch('https://example.gitlab.io:443', props) + assertsUrlsAreAPolicyOriginMatch('https://foo.example.gitlab.io:443', props) }) }) describe('localhost', () => { - const url = 'http://localhost:4200' + const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://localhost:4200') it('does not match', function () { - assertsUrlsAreNotSameSite('http://localhoss:4200', url) + assertsUrlsAreNotAPolicyMatch('http://localhoss:4200', props) + assertsUrlsAreNotAPolicyMatch('http://localhost:4201', props) }) it('matches', function () { - assertsUrlsAreSameSite('http://localhost:4200', url) - assertsUrlsAreSameSite('http://localhost:4201', url) + assertsUrlsAreAPolicyOriginMatch('http://localhost:4200', props) }) }) describe('app.localhost', () => { - const url = 'http://app.localhost:4200' + const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://app.localhost:4200') it('does not match', function () { - assertsUrlsAreNotSameSite('http://app.localhoss:4200', url) + assertsUrlsAreNotAPolicyMatch('http://app.localhoss:4200', props) + assertsUrlsAreNotAPolicyMatch('http://app.localhost:4201', props) }) it('matches', function () { - assertsUrlsAreSameSite('http://app.localhost:4200', url) - assertsUrlsAreSameSite('http://name.app.localhost:4200', url) - assertsUrlsAreSameSite('http://app.localhost:4201', url) + assertsUrlsAreAPolicyOriginMatch('http://app.localhost:4200', props) + assertsUrlsAreAPolicyOriginMatch('http://name.app.localhost:4200', props) }) }) describe('local', () => { - const url = 'http://brian.dev.local' + const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://brian.dev.local') it('does not match', function () { - assertsUrlsAreNotSameSite('https://brian.dev.local:443', url) - assertsUrlsAreNotSameSite('https://brian.dev.local', url) - assertsUrlsAreNotSameSite('http://brian.dev2.local:81', url) + assertsUrlsAreNotAPolicyMatch('https://brian.dev.local:443', props) + assertsUrlsAreNotAPolicyMatch('https://brian.dev.local', props) + assertsUrlsAreNotAPolicyMatch('http://brian.dev2.local:81', props) + assertsUrlsAreNotAPolicyMatch('http://brian.dev.local:8081', props) }) it('matches', function () { - assertsUrlsAreSameSite('http://jennifer.dev.local:4201', url) - assertsUrlsAreSameSite('http://jennifer.dev.local:80', url) - assertsUrlsAreSameSite('http://jennifer.dev.local', url) - assertsUrlsAreSameSite('http://brian.dev.local:8081', url) + assertsUrlsAreAPolicyOriginMatch('http://jennifer.dev.local', props) + assertsUrlsAreAPolicyOriginMatch('http://jennifer.dev.local:80', props) + assertsUrlsAreAPolicyOriginMatch('http://jennifer.dev.local', props) }) }) describe('ip address', () => { - const url = 'http://192.168.5.10' + const props = cors.parseUrlIntoHostProtocolDomainTldPort('http://192.168.5.10') it('does not match', function () { - assertsUrlsAreNotSameSite('http://192.168.5.10:443', url) - assertsUrlsAreNotSameSite('https://192.168.5.10', url) - assertsUrlsAreNotSameSite('http://193.168.5.10', url) - assertsUrlsAreNotSameSite('http://193.168.5.10:80', url) + assertsUrlsAreNotAPolicyMatch('http://192.168.5.10:443', props) + assertsUrlsAreNotAPolicyMatch('https://192.168.5.10', props) + assertsUrlsAreNotAPolicyMatch('http://193.168.5.10', props) + assertsUrlsAreNotAPolicyMatch('http://193.168.5.10:80', props) + assertsUrlsAreNotAPolicyMatch('http://192.168.5.10:12345', props) }) it('matches', function () { - assertsUrlsAreSameSite('http://192.168.5.10', url) - assertsUrlsAreSameSite('http://192.168.5.10:80', url) - assertsUrlsAreSameSite('http://192.168.5.10:12345', url) + assertsUrlsAreAPolicyOriginMatch('http://192.168.5.10', props) + assertsUrlsAreAPolicyOriginMatch('http://192.168.5.10:80', props) }) }) }) diff --git a/packages/proxy/lib/http/request-middleware.ts b/packages/proxy/lib/http/request-middleware.ts index 63bff1b259af..e2b41509e2ae 100644 --- a/packages/proxy/lib/http/request-middleware.ts +++ b/packages/proxy/lib/http/request-middleware.ts @@ -159,7 +159,7 @@ const MaybeEndRequestWithBufferedResponse: RequestMiddleware = function () { this.debug('ending request with buffered response') // NOTE: Only inject fullCrossOrigin here if experimental is on and // the super domain origins do not match in order to keep parity with cypress application reloads - this.res.wantsInjection = this.config.experimentalSessionAndOrigin && buffer.isCrossSuperDomainOrigin ? 'fullCrossOrigin' : 'full' + this.res.wantsInjection = this.config.experimentalSessionAndOrigin && buffer.urlDoesNotMatchPolicyBasedOnDomain ? 'fullCrossOrigin' : 'full' return this.onResponse(buffer.response, buffer.stream) } diff --git a/packages/proxy/lib/http/response-middleware.ts b/packages/proxy/lib/http/response-middleware.ts index 6e3029171a86..74de86a93166 100644 --- a/packages/proxy/lib/http/response-middleware.ts +++ b/packages/proxy/lib/http/response-middleware.ts @@ -55,9 +55,9 @@ function getNodeCharsetFromResponse (headers: IncomingHttpHeaders, body: Buffer, return 'latin1' } -function reqMatchesSuperDomainOrigin (req: CypressIncomingRequest, remoteState) { +function reqMatchesPolicyBasedOnDomain (req: CypressIncomingRequest, remoteState) { if (remoteState.strategy === 'http') { - return cors.urlMatchesSuperDomainOriginProps(req.proxiedUrl, remoteState.props) + return cors.urlMatchesPolicyBasedOnDomainProps(req.proxiedUrl, remoteState.props) } if (remoteState.strategy === 'file') { @@ -250,7 +250,7 @@ const SetInjectionLevel: ResponseMiddleware = function () { this.debug('determine injection') - const isReqMatchSuperDomainOrigin = reqMatchesSuperDomainOrigin(this.req, this.remoteStates.current()) + const isReqMatchSuperDomainOrigin = reqMatchesPolicyBasedOnDomain(this.req, this.remoteStates.current()) const getInjectionLevel = () => { if (this.incomingRes.headers['x-cypress-file-server-error'] && !this.res.isInitial) { this.debug('- partial injection (x-cypress-file-server-error)') @@ -259,11 +259,11 @@ const SetInjectionLevel: ResponseMiddleware = function () { } // NOTE: Only inject fullCrossOrigin if the super domain origins do not match in order to keep parity with cypress application reloads - const isCrossSuperDomainOrigin = !reqMatchesSuperDomainOrigin(this.req, this.remoteStates.getPrimary()) + const urlDoesNotMatchPolicyBasedOnDomain = !reqMatchesPolicyBasedOnDomain(this.req, this.remoteStates.getPrimary()) const isAUTFrame = this.req.isAUTFrame const isHTMLLike = isHTML || isRenderedHTML - if (this.config.experimentalSessionAndOrigin && isCrossSuperDomainOrigin && isAUTFrame && isHTMLLike) { + if (this.config.experimentalSessionAndOrigin && urlDoesNotMatchPolicyBasedOnDomain && isAUTFrame && isHTMLLike) { this.debug('- cross origin injection') return 'fullCrossOrigin' diff --git a/packages/proxy/lib/http/util/buffers.ts b/packages/proxy/lib/http/util/buffers.ts index afaa8f01da03..36a38eba3795 100644 --- a/packages/proxy/lib/http/util/buffers.ts +++ b/packages/proxy/lib/http/util/buffers.ts @@ -12,7 +12,7 @@ export type HttpBuffer = { response: IncomingMessage stream: Readable url: string - isCrossSuperDomainOrigin: boolean + urlDoesNotMatchPolicyBasedOnDomain: boolean } const stripPort = (url) => { diff --git a/packages/proxy/test/unit/http/request-middleware.spec.ts b/packages/proxy/test/unit/http/request-middleware.spec.ts index d3f1faf68095..c2a22b9fa8c9 100644 --- a/packages/proxy/test/unit/http/request-middleware.spec.ts +++ b/packages/proxy/test/unit/http/request-middleware.spec.ts @@ -548,7 +548,7 @@ describe('http/request-middleware', () => { it('sets wantsInjection to full when a request is buffered', async () => { const buffers = new HttpBuffers() - const buffer = { url: 'https://www.cypress.io/', isCrossSuperDomainOrigin: false } as HttpBuffer + const buffer = { url: 'https://www.cypress.io/', urlDoesNotMatchPolicyBasedOnDomain: false } as HttpBuffer buffers.set(buffer) @@ -568,7 +568,7 @@ describe('http/request-middleware', () => { it('sets wantsInjection to fullCrossOrigin when a cross origin request is buffered and experimentalSessionAndOrigin=true', async () => { const buffers = new HttpBuffers() - const buffer = { url: 'https://www.cypress.io/', isCrossSuperDomainOrigin: true } as HttpBuffer + const buffer = { url: 'https://www.cypress.io/', urlDoesNotMatchPolicyBasedOnDomain: true } as HttpBuffer buffers.set(buffer) @@ -591,7 +591,7 @@ describe('http/request-middleware', () => { it('sets wantsInjection to full when a cross origin request is buffered and experimentalSessionAndOrigin=false', async () => { const buffers = new HttpBuffers() - const buffer = { url: 'https://www.cypress.io/', isCrossSuperDomainOrigin: true } as HttpBuffer + const buffer = { url: 'https://www.cypress.io/', urlDoesNotMatchPolicyBasedOnDomain: true } as HttpBuffer buffers.set(buffer) @@ -614,7 +614,7 @@ describe('http/request-middleware', () => { it('wantsInjection is not set when the request is not buffered', async () => { const buffers = new HttpBuffers() - const buffer = { url: 'https://www.cypress.io/', isCrossSuperDomainOrigin: true } as HttpBuffer + const buffer = { url: 'https://www.cypress.io/', urlDoesNotMatchPolicyBasedOnDomain: true } as HttpBuffer buffers.set(buffer) diff --git a/packages/server/lib/controllers/files.js b/packages/server/lib/controllers/files.js index d5516d13a043..48b54f853fe0 100644 --- a/packages/server/lib/controllers/files.js +++ b/packages/server/lib/controllers/files.js @@ -39,13 +39,14 @@ module.exports = { }) }, - handleCrossOriginIframe (req, res) { + handleCrossOriginIframe (req, res, namespace) { const iframePath = cwd('lib', 'html', 'spec-bridge-iframe.html') const domain = cors.getSuperDomain(req.proxiedUrl) const iframeOptions = { domain, title: `Cypress for ${domain}`, + namespace, } debug('cross origin iframe with options %o', iframeOptions) diff --git a/packages/server/lib/html/spec-bridge-iframe.html b/packages/server/lib/html/spec-bridge-iframe.html index 5c75ad416ef2..7c4976525802 100644 --- a/packages/server/lib/html/spec-bridge-iframe.html +++ b/packages/server/lib/html/spec-bridge-iframe.html @@ -8,6 +8,6 @@ - + diff --git a/packages/server/lib/remote_states.ts b/packages/server/lib/remote_states.ts index e2ba2bca6dd1..4a011cfce407 100644 --- a/packages/server/lib/remote_states.ts +++ b/packages/server/lib/remote_states.ts @@ -91,7 +91,7 @@ export class RemoteStates { if (_.isString(urlOrState)) { const remoteOrigin = uri.origin(urlOrState) - const { subdomain: _unused, ...remoteProps } = cors.parseUrlIntoHostProtocolDomainTldPort(remoteOrigin) + const remoteProps = cors.parseUrlIntoHostProtocolDomainTldPort(remoteOrigin) if ((urlOrState === '') || !fullyQualifiedRe.test(urlOrState)) { state = { diff --git a/packages/server/lib/routes-e2e.ts b/packages/server/lib/routes-e2e.ts index 409a3e5d23bd..f74c6071c4c7 100644 --- a/packages/server/lib/routes-e2e.ts +++ b/packages/server/lib/routes-e2e.ts @@ -89,10 +89,16 @@ export const createRoutesE2E = ({ res.sendFile(file, { etag: false }) }) + // TODO: The below route is not technically correct for cypress in cypress tests. + // We should be using 'config.namespace' to provide the namespace instead of hard coding __cypress, however, + // In the runner when we create the spec bridge we have no knowledge of the namespace used by the server so + // we create a spec bridge for the namespace of the server specified in the config, but that server hasn't been created. + // To fix this I think we need to find a way to listen in the cypress in cypress server for routes from the server the + // cypress instance thinks should exist, but that's outside the current scope. routesE2E.get('/__cypress/spec-bridge-iframes', (req, res) => { debug('handling cross-origin iframe for domain: %s', req.hostname) - files.handleCrossOriginIframe(req, res) + files.handleCrossOriginIframe(req, res, config.namespace) }) return routesE2E diff --git a/packages/server/lib/server-e2e.ts b/packages/server/lib/server-e2e.ts index b1afcde27400..d3e70e282ac9 100644 --- a/packages/server/lib/server-e2e.ts +++ b/packages/server/lib/server-e2e.ts @@ -307,10 +307,10 @@ export class ServerE2E extends ServerBase { // TODO: think about moving this logic back into the frontend so that the driver can be in control // of when to buffer and set the remote state if (isOk && details.isHtml) { - const isCrossSuperDomainOrigin = options.hasAlreadyVisitedUrl && !cors.urlsSuperDomainOriginMatch(primaryRemoteState.origin, newUrl || '') || options.isFromSpecBridge + const urlDoesNotMatchPolicyBasedOnDomain = options.hasAlreadyVisitedUrl && !cors.urlMatchesPolicyBasedOnDomain(primaryRemoteState.origin, newUrl || '') || options.isFromSpecBridge if (!handlingLocalFile) { - this._remoteStates.set(newUrl as string, options, !isCrossSuperDomainOrigin) + this._remoteStates.set(newUrl as string, options, !urlDoesNotMatchPolicyBasedOnDomain) } const responseBufferStream = new stream.PassThrough({ @@ -325,7 +325,7 @@ export class ServerE2E extends ServerBase { details, originalUrl, response: incomingRes, - isCrossSuperDomainOrigin, + urlDoesNotMatchPolicyBasedOnDomain, }) } else { // TODO: move this logic to the driver too for diff --git a/packages/server/test/integration/http_requests_spec.js b/packages/server/test/integration/http_requests_spec.js index bfb0c0baaf3d..43c2c06291f5 100644 --- a/packages/server/test/integration/http_requests_spec.js +++ b/packages/server/test/integration/http_requests_spec.js @@ -2628,7 +2628,7 @@ describe('Routes', () => { }) }) - it('injects document.domain on matching super domains but different subdomain', function () { + it('does not inject document.domain on matching super domains but different subdomain - when the domain is set to strict same origin (google)', function () { nock('http://mail.google.com') .get('/iframe') .reply(200, '', { @@ -2647,7 +2647,7 @@ describe('Routes', () => { const body = cleanResponseBody(res.body) - expect(body).to.eq(' ') + expect(body).to.eq('') }) }) @@ -2791,6 +2791,35 @@ describe('Routes', () => { }) }) + context('content injection', () => { + beforeEach(function () { + return this.setup('http://www.foo.com') + }) + + it('injects document.domain on matching super domains but different subdomain - non google domain', function () { + nock('http://mail.foo.com') + .get('/iframe') + .reply(200, '', { + 'Content-Type': 'text/html', + }) + + return this.rp({ + url: 'http://mail.foo.com/iframe', + headers: { + 'Cookie': '__cypress.initial=false', + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', + }, + }) + .then((res) => { + expect(res.statusCode).to.eq(200) + + const body = cleanResponseBody(res.body) + + expect(body).to.eq(' ') + }) + }) + }) + context('security rewriting', () => { describe('on by default', () => { beforeEach(function () { diff --git a/packages/server/test/integration/server_spec.js b/packages/server/test/integration/server_spec.js index cc313586e7ec..ae39a68996fe 100644 --- a/packages/server/test/integration/server_spec.js +++ b/packages/server/test/integration/server_spec.js @@ -606,6 +606,7 @@ describe('Server', () => { domain: 'go', tld: 'com', port: '80', + subdomain: 'espn', protocol: 'http:', }, }) @@ -923,6 +924,7 @@ describe('Server', () => { domain: 'google', tld: 'com', port: '80', + subdomain: null, protocol: 'http:', }, }) @@ -954,6 +956,7 @@ describe('Server', () => { domain: 'cypress', port: '80', tld: 'io', + subdomain: null, protocol: 'http:', }, origin: 'http://cypress.io', @@ -983,7 +986,7 @@ describe('Server', () => { const buffer = this.buffers.take('http://www.cypress.io/') expect(buffer).to.not.be.empty - expect(buffer.isCrossSuperDomainOrigin).to.be.true + expect(buffer.urlDoesNotMatchPolicyBasedOnDomain).to.be.true // Verify the secondary remote state is returned expect(this.server.remoteStates.current()).to.deep.eq({ @@ -992,6 +995,7 @@ describe('Server', () => { domain: 'cypress', port: '80', tld: 'io', + subdomain: 'www', protocol: 'http:', }, origin: 'http://www.cypress.io', @@ -1026,6 +1030,7 @@ describe('Server', () => { domain: '', port: '3500', tld: 'localhost', + subdomain: null, protocol: 'http:', }, origin: 'http://localhost:3500', @@ -1057,6 +1062,7 @@ describe('Server', () => { domain: '', port: '3500', tld: 'localhost', + subdomain: null, protocol: 'http:', }, origin: 'http://localhost:3500', @@ -1093,6 +1099,7 @@ describe('Server', () => { domain: '', port: '3500', tld: 'localhost', + subdomain: null, protocol: 'http:', }, origin: 'http://localhost:3500', @@ -1182,6 +1189,7 @@ describe('Server', () => { domain: 'google', tld: 'com', port: '80', + subdomain: 'www', protocol: 'http:', }, }) @@ -1265,6 +1273,7 @@ describe('Server', () => { domain: 'google', tld: 'com', port: '80', + subdomain: 'www', protocol: 'http:', }, }) @@ -1339,6 +1348,7 @@ describe('Server', () => { domain: 'google', tld: 'com', port: '80', + subdomain: 'www', protocol: 'http:', }, }) @@ -1384,6 +1394,7 @@ describe('Server', () => { domain: 'foobar', tld: 'com', port: '8443', + subdomain: 'www', protocol: 'https:', }, }) @@ -1458,6 +1469,7 @@ describe('Server', () => { domain: 'foobar', tld: 'com', port: '8443', + subdomain: 'www', protocol: 'https:', }, }) @@ -1511,6 +1523,7 @@ describe('Server', () => { domain: '', tld: 's3.amazonaws.com', port: '443', + subdomain: null, protocol: 'https:', }, }) @@ -1591,6 +1604,7 @@ describe('Server', () => { domain: '', tld: 's3.amazonaws.com', port: '443', + subdomain: null, protocol: 'https:', }, }) diff --git a/packages/server/test/unit/remote_states.spec.ts b/packages/server/test/unit/remote_states.spec.ts index 64420a358154..ab067af71b6c 100644 --- a/packages/server/test/unit/remote_states.spec.ts +++ b/packages/server/test/unit/remote_states.spec.ts @@ -29,6 +29,7 @@ describe('remote states', () => { port: '3500', domain: '', tld: 'localhost', + subdomain: null, protocol: 'http:', }, }) @@ -53,6 +54,7 @@ describe('remote states', () => { port: '3500', domain: '', tld: 'localhost', + subdomain: null, protocol: 'http:', }, }) @@ -71,6 +73,7 @@ describe('remote states', () => { port: '3500', domain: '', tld: 'localhost', + subdomain: null, protocol: 'http:', }, }) @@ -91,6 +94,7 @@ describe('remote states', () => { port: '3500', domain: '', tld: 'localhost', + subdomain: null, protocol: 'http:', }, }) @@ -111,6 +115,7 @@ describe('remote states', () => { port: '3500', domain: '', tld: 'localhost', + subdomain: null, protocol: 'http:', }, }) @@ -161,6 +166,7 @@ describe('remote states', () => { port: '443', domain: 'google', tld: 'com', + subdomain: 'staging', protocol: 'https:', }, }) @@ -183,6 +189,7 @@ describe('remote states', () => { port: '443', domain: 'google', tld: 'com', + subdomain: 'staging', protocol: 'https:', }, }) @@ -207,6 +214,7 @@ describe('remote states', () => { port: '443', domain: 'google', tld: 'com', + subdomain: 'staging', protocol: 'https:', }, }) @@ -232,6 +240,7 @@ describe('remote states', () => { port: '443', domain: 'google', tld: 'com', + subdomain: 'staging', protocol: 'https:', }, }) @@ -250,6 +259,7 @@ describe('remote states', () => { port: '443', domain: 'google', tld: 'com', + subdomain: 'prod', protocol: 'https:', }, }) @@ -268,6 +278,7 @@ describe('remote states', () => { port: '443', domain: 'google', tld: 'com', + subdomain: 'staging', protocol: 'https:', }, }) @@ -286,6 +297,7 @@ describe('remote states', () => { port: '80', domain: 'google', tld: 'com', + subdomain: 'staging', protocol: 'http:', }, }) @@ -304,6 +316,7 @@ describe('remote states', () => { port: '4200', domain: '', tld: 'localhost', + subdomain: null, protocol: 'http:', }, }) @@ -346,6 +359,7 @@ describe('remote states', () => { port: '80', domain: 'foobar', tld: 'com', + subdomain: 'www', protocol: 'http:', }, } diff --git a/system-tests/projects/session-and-origin-e2e-specs/cypress/e2e/origin/simple_origin.cy.js b/system-tests/projects/session-and-origin-e2e-specs/cypress/e2e/origin/simple_origin.cy.js index b4aaba980af1..5c75e36a2e69 100644 --- a/system-tests/projects/session-and-origin-e2e-specs/cypress/e2e/origin/simple_origin.cy.js +++ b/system-tests/projects/session-and-origin-e2e-specs/cypress/e2e/origin/simple_origin.cy.js @@ -2,7 +2,7 @@ // REPLACE THIS COMMENT FOR HOT RELOAD describe('simple origin', () => { it('passes', () => { - cy.origin('http://localhost:4455', () => { + cy.origin('http://foobar:4455', () => { cy.log('log me once') cy.log('log me twice') }) diff --git a/system-tests/projects/webpack-dev-server-ts/cypress.config.ts b/system-tests/projects/webpack-dev-server-ts/cypress.config.ts new file mode 100644 index 000000000000..d9e53e230f7b --- /dev/null +++ b/system-tests/projects/webpack-dev-server-ts/cypress.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'cypress' + +export default defineConfig({ + component: { + devServer: { + bundler: 'webpack', + } as any, + supportFile: false, + }, +}) diff --git a/system-tests/projects/webpack-dev-server-ts/cypress/support/component-index.html b/system-tests/projects/webpack-dev-server-ts/cypress/support/component-index.html new file mode 100644 index 000000000000..5f9622ae2945 --- /dev/null +++ b/system-tests/projects/webpack-dev-server-ts/cypress/support/component-index.html @@ -0,0 +1,12 @@ + + + + + + + Components App + + +

+ + diff --git a/system-tests/projects/webpack-dev-server-ts/helloWorld.ts b/system-tests/projects/webpack-dev-server-ts/helloWorld.ts new file mode 100644 index 000000000000..6ff55a23aedb --- /dev/null +++ b/system-tests/projects/webpack-dev-server-ts/helloWorld.ts @@ -0,0 +1,3 @@ +export const helloWorld = () => { + return 'Hello World' +} diff --git a/system-tests/projects/webpack-dev-server-ts/package.json b/system-tests/projects/webpack-dev-server-ts/package.json new file mode 100644 index 000000000000..9d3e066522bc --- /dev/null +++ b/system-tests/projects/webpack-dev-server-ts/package.json @@ -0,0 +1,19 @@ +{ + "name": "ct-webpack-ts", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "dependencies": { + "html-webpack-plugin": "^5.5.0", + "ts-loader": "^9.4.1", + "typescript": "^4.8.4", + "webpack": "^5.74.0", + "webpack-dev-server": "^4.11.1" + }, + "license": "ISC", + "author": "", + "keywords": [] +} diff --git a/system-tests/projects/webpack-dev-server-ts/test.cy.ts b/system-tests/projects/webpack-dev-server-ts/test.cy.ts new file mode 100644 index 000000000000..39e244077fcb --- /dev/null +++ b/system-tests/projects/webpack-dev-server-ts/test.cy.ts @@ -0,0 +1,5 @@ +import { helloWorld } from './helloWorld' + +it('should return "Hello World"', () => { + expect(helloWorld()).eq('Hello World') +}) diff --git a/system-tests/projects/webpack-dev-server-ts/tsconfig.json b/system-tests/projects/webpack-dev-server-ts/tsconfig.json new file mode 100644 index 000000000000..bb7ae23aa3a4 --- /dev/null +++ b/system-tests/projects/webpack-dev-server-ts/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "module": "esnext", + "moduleResolution": "node" + }, + "include": ["**/*.ts"] +} diff --git a/system-tests/projects/webpack-dev-server-ts/webpack.config.ts b/system-tests/projects/webpack-dev-server-ts/webpack.config.ts new file mode 100644 index 000000000000..51067b6899e2 --- /dev/null +++ b/system-tests/projects/webpack-dev-server-ts/webpack.config.ts @@ -0,0 +1,24 @@ +export default { + mode: 'development', + devtool: 'inline-source-map', + entry: './app.ts', + output: { + filename: 'bundle.js', + }, + resolve: { + // Add `.ts` and `.tsx` as a resolvable extension. + extensions: ['.ts', '.tsx', '.js'], + // Add support for TypeScripts fully qualified ESM imports. + extensionAlias: { + '.js': ['.js', '.ts'], + '.cjs': ['.cjs', '.cts'], + '.mjs': ['.mjs', '.mts'], + }, + }, + module: { + rules: [ + // all files with a `.ts`, `.cts`, `.mts` or `.tsx` extension will be handled by `ts-loader` + { test: /\.([cm]?ts|tsx)$/, loader: 'ts-loader' }, + ], + }, +} diff --git a/system-tests/projects/webpack-dev-server-ts/yarn.lock b/system-tests/projects/webpack-dev-server-ts/yarn.lock new file mode 100644 index 000000000000..907f04188626 --- /dev/null +++ b/system-tests/projects/webpack-dev-server-ts/yarn.lock @@ -0,0 +1,2135 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@jridgewell/gen-mapping@^0.3.0": + version "0.3.2" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.14" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.17" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz" + integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" + +"@types/connect-history-api-fallback@^1.3.5": + version "1.3.5" + resolved "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz" + integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/eslint-scope@^3.7.3": + version "3.7.4" + resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz" + integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "8.4.10" + resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz" + integrity sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*": + version "1.0.0" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + +"@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.31" + resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.31.tgz" + integrity sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.14" + resolved "https://registry.npmjs.org/@types/express/-/express-4.17.14.tgz" + integrity sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/html-minifier-terser@^6.0.0": + version "6.1.0" + resolved "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz" + integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== + +"@types/http-proxy@^1.17.8": + version "1.17.9" + resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz" + integrity sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw== + dependencies: + "@types/node" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.11" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + +"@types/mime@*": + version "3.0.1" + resolved "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz" + integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== + +"@types/node@*": + version "18.11.9" + resolved "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz" + integrity sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg== + +"@types/qs@*": + version "6.9.7" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*", "@types/serve-static@^1.13.10": + version "1.15.0" + resolved "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz" + integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== + dependencies: + "@types/mime" "*" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + +"@types/ws@^8.5.1": + version "8.5.3" + resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + dependencies: + "@types/node" "*" + +"@webassemblyjs/ast@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz" + integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + +"@webassemblyjs/floating-point-hex-parser@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz" + integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== + +"@webassemblyjs/helper-api-error@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz" + integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + +"@webassemblyjs/helper-buffer@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz" + integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== + +"@webassemblyjs/helper-numbers@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz" + integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz" + integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== + +"@webassemblyjs/helper-wasm-section@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz" + integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + +"@webassemblyjs/ieee754@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz" + integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz" + integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz" + integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== + +"@webassemblyjs/wasm-edit@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz" + integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-wasm-section" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-opt" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + "@webassemblyjs/wast-printer" "1.11.1" + +"@webassemblyjs/wasm-gen@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz" + integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wasm-opt@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz" + integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-buffer" "1.11.1" + "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + +"@webassemblyjs/wasm-parser@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz" + integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/ieee754" "1.11.1" + "@webassemblyjs/leb128" "1.11.1" + "@webassemblyjs/utf8" "1.11.1" + +"@webassemblyjs/wast-printer@1.11.1": + version "1.11.1" + resolved "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz" + integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== + dependencies: + "@webassemblyjs/ast" "1.11.1" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +acorn-import-assertions@^1.7.6: + version "1.8.0" + resolved "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz" + integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== + +acorn@^8.5.0, acorn@^8.7.1: + version "8.8.1" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz" + integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + +ajv-keywords@^5.0.0: + version "5.1.0" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ajv@^8.0.0, ajv@^8.8.0: + version "8.11.0" + resolved "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz" + integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +array-flatten@^2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +batch@0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +bonjour-service@^1.0.11: + version "1.0.14" + resolved "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.14.tgz" + integrity sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ== + dependencies: + array-flatten "^2.1.2" + dns-equal "^1.0.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.14.5: + version "4.21.4" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz" + integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== + dependencies: + caniuse-lite "^1.0.30001400" + electron-to-chromium "^1.4.251" + node-releases "^2.0.6" + update-browserslist-db "^1.0.9" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +camel-case@^4.1.2: + version "4.1.2" + resolved "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== + dependencies: + pascal-case "^3.1.2" + tslib "^2.0.3" + +caniuse-lite@^1.0.30001400: + version "1.0.30001431" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz" + integrity sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ== + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + +clean-css@^5.2.2: + version "5.3.1" + resolved "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz" + integrity sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg== + dependencies: + source-map "~0.6.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^2.0.10: + version "2.0.19" + resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +connect-history-api-fallback@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz" + integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +css-select@^4.1.3: + version "4.3.0" + resolved "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== + dependencies: + boolbase "^1.0.0" + css-what "^6.0.1" + domhandler "^4.3.1" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-what@^6.0.1: + version "6.1.0" + resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^4.1.0: + version "4.3.4" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + +dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz" + integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== + +dns-packet@^5.2.2: + version "5.4.0" + resolved "https://registry.npmjs.org/dns-packet/-/dns-packet-5.4.0.tgz" + integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + +dom-converter@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + +dom-serializer@^1.0.1: + version "1.4.1" + resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.5.2, domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.251: + version "1.4.284" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz" + integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +enhanced-resolve@^5.0.0, enhanced-resolve@^5.10.0: + version "5.10.0" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz" + integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +express@^4.17.3: + version "4.18.2" + resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +follow-redirects@^1.0.0: + version "1.15.2" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs-monkey@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz" + integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +get-intrinsic@^1.0.2: + version "1.1.3" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz" + integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.10" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +he@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/he/-/he-1.2.0.tgz" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz" + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.3.3" + resolved "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz" + integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== + +html-minifier-terser@^6.0.2: + version "6.1.0" + resolved "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz" + integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== + dependencies: + camel-case "^4.1.2" + clean-css "^5.2.2" + commander "^8.3.0" + he "^1.2.0" + param-case "^3.0.4" + relateurl "^0.2.7" + terser "^5.10.0" + +html-webpack-plugin@^5.5.0: + version "5.5.0" + resolved "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz" + integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw== + dependencies: + "@types/html-minifier-terser" "^6.0.0" + html-minifier-terser "^6.0.2" + lodash "^4.17.21" + pretty-error "^4.0.0" + tapable "^2.0.0" + +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +http-proxy-middleware@^2.0.3: + version "2.0.6" + resolved "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +lodash@^4.17.20, lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memfs@^3.4.3: + version "3.4.10" + resolved "https://registry.npmjs.org/memfs/-/memfs-3.4.10.tgz" + integrity sha512-0bCUP+L79P4am30yP1msPzApwuMQG23TjwlwdHeEV5MxioDR1a0AgB0T9FfggU52eJuDCq8WVwb5ekznFyWiTQ== + dependencies: + fs-monkey "^1.0.3" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.0, micromatch@^4.0.2: + version "4.0.5" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +multicast-dns@^7.2.5: + version "7.2.5" + resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== + dependencies: + dns-packet "^5.2.2" + thunky "^1.0.2" + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + +node-forge@^1: + version "1.3.1" + resolved "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9: + version "8.4.0" + resolved "https://registry.npmjs.org/open/-/open-8.4.0.tgz" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + +p-retry@^4.5.0: + version "4.6.2" + resolved "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== + dependencies: + "@types/retry" "0.12.0" + retry "^0.13.1" + +param-case@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + +parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pretty-error@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz" + integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== + dependencies: + lodash "^4.17.20" + renderkid "^3.0.0" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +readable-stream@^2.0.1: + version "2.3.7" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.6.0" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +relateurl@^0.2.7: + version "0.2.7" + resolved "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz" + integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== + +renderkid@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz" + integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== + dependencies: + css-select "^4.1.3" + dom-converter "^0.2.0" + htmlparser2 "^6.1.0" + lodash "^4.17.21" + strip-ansi "^6.0.1" + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +schema-utils@^3.1.0, schema-utils@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz" + integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +schema-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz" + integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.8.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.0.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== + +selfsigned@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz" + integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== + dependencies: + node-forge "^1" + +semver@^7.3.4: + version "7.3.8" + resolved "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz" + integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +sockjs@^0.3.24: + version "0.3.24" + resolved "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@~0.6.0: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: + version "2.2.1" + resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + +terser-webpack-plugin@^5.1.3: + version "5.3.6" + resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz" + integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ== + dependencies: + "@jridgewell/trace-mapping" "^0.3.14" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + terser "^5.14.1" + +terser@^5.10.0, terser@^5.14.1: + version "5.15.1" + resolved "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz" + integrity sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw== + dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +ts-loader@^9.4.1: + version "9.4.1" + resolved "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.1.tgz" + integrity sha512-384TYAqGs70rn9F0VBnh6BPTfhga7yFNdC5gXbQpDrBj9/KsT4iRkGqKXhziofHOlE2j6YEaiTYVGKKvPhGWvw== + dependencies: + chalk "^4.1.0" + enhanced-resolve "^5.0.0" + micromatch "^4.0.0" + semver "^7.3.4" + +tslib@^2.0.3: + version "2.4.1" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz" + integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +typescript@^4.8.4: + version "4.8.4" + resolved "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz" + integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +update-browserslist-db@^1.0.9: + version "1.0.10" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz" + integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +utila@~0.4: + version "0.4.0" + resolved "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz" + integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + +webpack-dev-middleware@^5.3.1: + version "5.3.3" + resolved "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz" + integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + dependencies: + colorette "^2.0.10" + memfs "^3.4.3" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@^4.11.1: + version "4.11.1" + resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz" + integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.1" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^2.0.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.1.1" + serve-index "^1.9.1" + sockjs "^0.3.24" + spdy "^4.0.2" + webpack-dev-middleware "^5.3.1" + ws "^8.4.2" + +webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + +webpack@^5.74.0: + version "5.74.0" + resolved "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz" + integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.7.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.10.0" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@^8.4.2: + version "8.11.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz" + integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/system-tests/test/webpack_dev_server_spec.ts b/system-tests/test/webpack_dev_server_spec.ts index aa2483ce035a..6d6c4cc433ea 100644 --- a/system-tests/test/webpack_dev_server_spec.ts +++ b/system-tests/test/webpack_dev_server_spec.ts @@ -10,4 +10,12 @@ describe('@cypress/webpack-dev-server', function () { browser: 'chrome', expectedExitCode: 0, }) + + systemTests.it('successfully loads and runs all specs with typescript config', { + project: 'webpack-dev-server-ts', + testingType: 'component', + spec: 'test.cy.ts', + browser: 'chrome', + expectedExitCode: 0, + }) }) diff --git a/tooling/v8-snapshot/cache/dev-darwin/snapshot-meta.cache.json b/tooling/v8-snapshot/cache/dev-darwin/snapshot-meta.cache.json index 97f8be8d4649..7a427286e35c 100644 --- a/tooling/v8-snapshot/cache/dev-darwin/snapshot-meta.cache.json +++ b/tooling/v8-snapshot/cache/dev-darwin/snapshot-meta.cache.json @@ -3528,5 +3528,5 @@ "./tooling/v8-snapshot/cache/dev-darwin/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "ce60d1d6cc0c77f20dcfc741105a5c53593752f814bf3cab816a3024faf68bfc" + "deferredHash": "8b71698b89d3804ed712295c20a140cfcd674fa5c3ad9569530282dd6c3e9906" } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index a27db9913aff..6cf60f529def 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22504,6 +22504,11 @@ loader-utils@^2.0.0: emojis-list "^3.0.0" json5 "^2.1.2" +local-pkg@0.4.1, local-pkg@^0.4.0, local-pkg@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.4.1.tgz#e7b0d7aa0b9c498a1110a5ac5b00ba66ef38cfff" + integrity sha512-lL87ytIGP2FU5PWwNDo0w3WhIo2gopIAxPg9RxDYF7m4rr5ahuZxP22xnJHIvaLTe4Z9P6uKKY2UHiwyB4pcrw== + local-pkg@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.1.0.tgz#7422b2ae8fc1e3b9ef2f132b0a0e92d879df52ef" @@ -22511,11 +22516,6 @@ local-pkg@^0.1.0: dependencies: mlly "^0.2.2" -local-pkg@^0.4.0, local-pkg@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.4.1.tgz#e7b0d7aa0b9c498a1110a5ac5b00ba66ef38cfff" - integrity sha512-lL87ytIGP2FU5PWwNDo0w3WhIo2gopIAxPg9RxDYF7m4rr5ahuZxP22xnJHIvaLTe4Z9P6uKKY2UHiwyB4pcrw== - locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"