This commit is contained in:
Jessica Sachs
2022-03-02 16:33:42 -05:00
parent 78d5bed75d
commit 7c715d0673
11 changed files with 513 additions and 80 deletions
+8 -11
View File
@@ -1,16 +1,6 @@
// This file is merged in a <script type=module> into index.html
// it will be used to load and kick start the selected spec
import specLoaders from 'cypress:spec-loaders'
import { hasSupportPath, originAutUrl } from 'cypress:config'
const specPath = window.location.pathname.replace(originAutUrl, '')
const specLoader = specLoaders[specPath]
const importsToLoad = [specLoader || (() => import(/* @vite-ignore */ specPath))]
if (hasSupportPath) {
importsToLoad.unshift(() => import('cypress:support-path'))
}
import { hasSupportPath } from '@cypress:config'
const CypressInstance = window.Cypress = parent.Cypress
@@ -18,6 +8,13 @@ if (!CypressInstance) {
throw new Error('Tests cannot run without a reference to Cypress!')
}
const specPath = CypressInstance.spec.relative
const importsToLoad = [() => import(/* @vite-ignore */ `/${specPath}`)]
if (hasSupportPath) {
importsToLoad.unshift(() => import('@cypress:support-path'))
}
// load the support and spec
CypressInstance.onSpecWindow(window, importsToLoad)
-1
View File
@@ -1,7 +1,6 @@
import { defineConfig } from 'cypress'
import { devServer } from './dist'
console.log('top level')
export default defineConfig({
'pluginsFile': 'cypress/plugins.js',
'video': false,
+4
View File
@@ -0,0 +1,4 @@
const t = document.createElement('h1')
t.innerText = 'It is I! Foo.js, relative to the cypress folder'
document.body.appendChild(t)
+4
View File
@@ -0,0 +1,4 @@
const t = document.createElement('h1')
t.innerText = 'It is I! Foo.js, relative to the VITE CONFIG'
document.body.appendChild(t)
+1 -1
View File
@@ -33,7 +33,7 @@
"mocha-junit-reporter": "^2.0.0",
"mocha-multi-reporters": "^1.5.1",
"react": "17.0.2",
"vite": "2.5.0",
"vite": "2.8.0",
"vite-plugin-inspect": "0.4.3",
"vue": "3.2.6",
"vue-eslint-parser": "7.11.0"
+3 -4
View File
@@ -7,8 +7,7 @@ import type { CypressViteDevServerConfig, StartDevServer } from './types'
const debug = debugFn('cypress:vite-dev-server:index')
export const startDevServer = async ({ options, viteConfig = {} }: StartDevServer) => {
debug('user has registered startDevServer for Vite')
debug('startDevServer has received options', options)
debug('Starting Vite Server')
let server
try {
@@ -19,11 +18,11 @@ export const startDevServer = async ({ options, viteConfig = {} }: StartDevServe
throw new Error(err as string)
}
debug('vite server created successfully')
debug('Vite server created')
const port = await getPort({ port: 3000 })
await server.listen(port)
debug('successfully launched the vite server on port', port)
debug('Successfully launched the vite server on port', port)
return {
port,
+194 -10
View File
@@ -1,18 +1,202 @@
import { ViteDevServer } from 'vite'
import { CypressViteDevServer } from './server'
// import { Plugin, ViteDevServer } from 'vite'
// import { CypressViteDevServer } from './server'
// export const Cypress = (options): Plugin => {
// return {
// name: 'cypress:main',
// enforce: 'pre',
// // configureServer (viteServer: ViteDevServer) {
// // return () => {
// // const cyServer = new CypressViteDevServer(viteServer, options)
// // viteServer.middlewares.use('/', cyServer.handleAllRoutes.bind(cyServer))
// // viteServer.middlewares.use('/', cyServer.handle404.bind(cyServer))
// // }
// // },
// }
// }
import { resolve, sep } from 'path'
import { readFile } from 'fs/promises'
import Debug from 'debug'
import { ModuleNode, normalizePath, Plugin, ViteDevServer } from 'vite'
const debug = Debug('cypress:vite-dev-server:plugin')
const pluginName = 'cypress-transform-html'
const OSSepRE = new RegExp(`\\${sep}`, 'g')
function convertPathToPosix (path: string): string {
return sep === '/'
? path
: path.replace(OSSepRE, '/')
}
const INIT_FILEPATH = resolve(__dirname, '../../client/initCypressTests.js')
const HMR_DEPENDENCY_LOOKUP_MAX_ITERATION = 50
function getSpecsPathsSet (specs: Spec[]) {
return new Set<string>(
specs.map((spec) => spec.absolute),
)
}
interface Spec{
absolute: string
relative: string
}
export const Cypress = (
options,
): Plugin => {
let base = '/'
const projectRoot = options.config.projectRoot
const supportFilePath = options.config.supportFile
const devServerEvents = options.devServerEvents
const specs = options.specs
const namespace = options.namespace
const indexHtml = options.indexHtml
let specsPathsSet = getSpecsPathsSet(specs)
devServerEvents.on('dev-server:specs:changed', (specs: Spec[]) => {
specsPathsSet = getSpecsPathsSet(specs)
})
const posixSupportFilePath = supportFilePath ? convertPathToPosix(resolve(projectRoot, supportFilePath)) : undefined
const posixIndexHtml = indexHtml ? convertPathToPosix(resolve(projectRoot, indexHtml)) : undefined
export const Cypress = (options) => {
return {
name: 'cypress:main',
name: pluginName,
enforce: 'pre',
configureServer (viteServer: ViteDevServer) {
return () => {
const cyServer = new CypressViteDevServer(viteServer, options.specs)
configResolved (config) {
base = config.base
},
async transformIndexHtml () {
const indexHtmlPath = indexHtml ? resolve(projectRoot, indexHtml) : resolve(__dirname, '..', '..', 'index.html')
const indexHtmlContent = await readFile(indexHtmlPath, { encoding: 'utf8' })
// find </body> last index
const endOfBody = indexHtmlContent.lastIndexOf('</body>')
viteServer.middlewares.use('/', cyServer.handleAllRoutes)
viteServer.middlewares.use('/', cyServer.handle404)
// insert the script in the end of the body
return `${indexHtmlContent.substring(0, endOfBody)
}<script src="/@cypress:client-init-test" type="module"></script>${
indexHtmlContent.substring(endOfBody)
}`
},
resolveId (id) {
if (id === '@cypress:config') {
return id
}
if (id === '@cypress:support-path') {
return posixSupportFilePath
}
if (id === '@cypress:spec-loaders') {
return id
}
if (id === '/@cypress:client-init-test') {
return INIT_FILEPATH
}
},
load (id) {
if (id === '@cypress:spec-loaders') {
return `export default {\n${specs.map((s) => {
return `${JSON.stringify(s.relative)}:()=>import(${JSON.stringify(s.absolute)})`
}).join(',\n')}\n}`
}
if (id === '@cypress:config') {
return `
export const hasSupportPath = ${JSON.stringify(!!supportFilePath)}`
}
},
configureServer: async (server: ViteDevServer) => {
server.middlewares.use(`${base}index.html`, async (req, res) => {
const transformedIndexHtml = await server.transformIndexHtml(base, '')
return res.end(transformedIndexHtml)
})
},
handleHotUpdate: ({ server, file }) => {
debug('handleHotUpdate - file', file)
// If the user provided IndexHtml is changed, do a full-reload
if (file === posixIndexHtml) {
server.ws.send({
type: 'full-reload',
})
return
}
// get the graph node for the file that just got updated
let moduleImporters = server.moduleGraph.fileToModulesMap.get(file)
let iterationNumber = 0
const exploredFiles = new Set<string>()
// until we reached a point where the current module is imported by no other
while (moduleImporters?.size) {
if (iterationNumber > HMR_DEPENDENCY_LOOKUP_MAX_ITERATION) {
debug(`max hmr iteration reached: ${HMR_DEPENDENCY_LOOKUP_MAX_ITERATION}; Rerun will not happen on this file change.`)
return []
}
// as soon as we find one of the specs, we trigger the re-run of tests
for (const mod of moduleImporters.values()) {
debug('handleHotUpdate - mod.file', mod.file)
if (mod.file === supportFilePath) {
debug('handleHotUpdate - support compile success')
devServerEvents.emit('dev-server:compile:success')
// if we update support we know we have to re-run it all
// no need to ckeck further
return []
}
if (mod.file && specsPathsSet.has(mod.file)) {
debug('handleHotUpdate - spec compile success', mod.file)
devServerEvents.emit('dev-server:compile:success', { specFile: mod.file })
// if we find one spec, does not mean we are done yet,
// there could be other spec files to re-run
// see https://github.com/cypress-io/cypress/issues/17691
}
}
// get all the modules that import the current one
moduleImporters = getImporters(moduleImporters, exploredFiles)
iterationNumber += 1
}
return []
},
}
}
/**
* Gets all the modules that import the set of modules passed in parameters
* @param modules the set of module whose dependents to return
* @param alreadyExploredFiles set of files that have already been looked at and should be avoided in case of circular dependency
* @returns a set of ModuleMode that import directly the current modules
*/
function getImporters (modules: Set<ModuleNode>, alreadyExploredFiles: Set<string>): Set<ModuleNode> {
const allImporters = new Set<ModuleNode>()
modules.forEach((m) => {
if (m.file && !alreadyExploredFiles.has(m.file)) {
alreadyExploredFiles.add(m.file)
m.importers.forEach((imp) => {
allImporters.add(imp)
})
}
})
return allImporters
}
@@ -3,7 +3,6 @@ import type { PluginOption } from 'vite'
const debug = debugFn('cypress:vite-dev-server:plugins:inspect')
console.log('anything')
export const CypressInspect = async (): (() => PluginOption) | null => {
if (!process.env.DEBUG) return null
+141 -37
View File
@@ -1,22 +1,46 @@
import { relative, resolve } from 'pathe'
import { promises as fsp } from 'fs'
import { decode, isSamePath } from 'ufo'
import { parse, join, resolve } from 'path'
import { parse, join } from 'path'
import debugFn from 'debug'
import type { ViteDevServer } from 'vite'
import type { Connect, ViteDevServer } from 'vite'
import { normalizePath } from 'vite'
import { commonSpecExtensions } from '../constants'
import { IncomingMessage, ServerResponse } from 'http'
import { pathToFileURL } from 'url'
const debug = debugFn('cypress:vite-dev-server:server')
export type RequestType = 'index' | '404' | 'current-spec' | 'module'
const matchRequest = (url: string, specs): RequestType => {
const normalizedUrl = normalizePath(decode(url))
const isIndex = isSamePath(normalizedUrl, '/index.html') || isSamePath(normalizedUrl, '/')
// TODO: pass this into each dev server in the options
const specHeader = '__cypress_spec_path'
const iframeRoute = '/__cypress/iframes/'
if (isIndex) return 'index'
const matchRequest = (req, specs): RequestType => {
// const url = req.originalUrl
// const normalizedUrl = normalizePath(decode(url))
if (getCurrentSpecFile(url, specs)) return 'current-spec'
debug('from original url', req.originalUrl)
debug('with headers', req.headers)
// Cypress proxies all requests through index.html using different headers
// If the route matches index.html it can mean two things:
// 1. Cypress is trying to load a spec (spec header will not be present)
// 2. The user is requesting the server from their browser (header is present)
if (isCypressSpecRequest(req)) {
if (getCurrentSpecFile(req, specs)) {
debug('is current spec')
return 'current-spec'
}
}
// const isIndex = isSamePath(normalizedUrl, '/index.html') || isSamePath(normalizedUrl, '/')
// if (isIndex) return 'index'
debug('is module')
return 'module'
}
@@ -37,44 +61,81 @@ const cleanSpecFileName = (file) => {
return cleanPath
}
const getCurrentSpecFile = (url: string, specs: any[]) => {
return specs.find((spec) => {
if (isSamePath(`/${ spec}`, decode(url))) return false
const isRequestFromWithinCyIframe = (req) => {
return req.headers.referer.includes(iframeRoute)
}
return isSamePath(cleanSpecFileName(parse(spec)), normalizePath(decode(url)))
})
const isCypressSpecRequest = (req) => {
if (req.headers[specHeader]) return true
return false
}
const getSpecPathFromHeader = (req): string | null => {
const specPaths = req.headers[specHeader]
if (specPaths) {
return Array.isArray(specPaths) ? specPaths[0] : specPaths
}
return null
}
const getCurrentSpecFile = (req, specs: Cypress.DevServerConfig['specs']) => {
// Route by header (Cypress does this when it forwards on the request to the dev server)
const specPaths = req.headers['__cypress_spec_path']
if (specPaths) {
debug('spec paths', specPaths)
return Array.isArray(specPaths) ? specPaths[0] : specPaths
}
// Route by url (You, navigating to your browser)
// return specs.find((spec) => {
// if (isSamePath(`/${spec.relative}`, decode(req.originalUrl))) return false
// debug('clean spec file name', cleanSpecFileName(parse(spec.relative)))
// debug('normalizePath', normalizePath(decode(req.originalUrl)))
// debug('decode', decode(req.originalUrl))
// return isSamePath(cleanSpecFileName(parse(spec.relative)), normalizePath(decode(url)))
// })?.absolute
}
export class CypressViteDevServer {
server: ViteDevServer
indexHtmlPath: string
options: Cypress.DevServerConfig
_template?: string
specs: any[]
_client?: string
constructor (server: ViteDevServer, specs) {
constructor (server: ViteDevServer, options: Cypress.DevServerConfig) {
debug('Setting up Cypress\'s Vite plugin')
this.specs = specs
this.options = options
this.server = server
this.indexHtmlPath = resolve('index.html')
this.getTemplate()
debug('Resolved html path at', this.indexHtmlPath)
this.getClient()
}
async getTemplate () {
if (this._template) {
debug('The html template has already been loaded. It was loaded from', this.indexHtmlPath)
const indexHtmlPath = resolve('index.html')
return this._template
}
this._template = await fsp.readFile(this.indexHtmlPath, 'utf-8')
debug('Loaded html template successfully')
this._template = await fsp.readFile(indexHtmlPath, 'utf-8')
debug('Loaded html template successfully from', indexHtmlPath)
return this._template
}
async getClient () {
const clientPath = resolve(process.cwd(), join('client', 'initCypressTests.js'))
this._client = await fsp.readFile(clientPath, 'utf-8')
debug('Loaded client successfully from', clientPath)
return this._client
}
/**
* Route matching and handling.
*
@@ -85,32 +146,75 @@ export class CypressViteDevServer {
* 4. User is trying to visit an HTML page that does not exist.
*/
handleAllRoutes (req, res, next) {
const matched = matchRequest(req.originalUrl, this.specs)
handleAllRoutes (req: Connect.IncomingMessage, res: ServerResponse, next: Function) {
if (isCypressSpecRequest(req)) {
// We're going to request the same route with the same headers,
// But from this time, it'll be inside of the iframe.
if (isRequestFromWithinCyIframe(req)) {
return next()
}
if (matched === 'index') return this.handleIndexRoute(req, res)
if (matched === 'current-spec') return this.handleCurrentSpecRoute(req, res)
// If you request a non-existent from top, you'll end up here...
// That's not great :/
return this.handleCurrentSpecRoute(req, res)
}
return next()
}
getCurrentSpecFile (req) {
const specPaths = req.headers['__cypress_spec_path']
if (specPaths) {
debug('spec paths', specPaths)
const absolutePath = Array.isArray(specPaths) ? specPaths[0] : specPaths
return this.options.specs.find((s) => {
return s.absolute === absolutePath
})
}
}
getSupportFile () {
const supportFile = this.options.config.supportFile
if (supportFile) {
return relative(this.options.config.projectRoot, supportFile)
}
}
// When the user requests `/` and is not trying to load a spec
async handleIndexRoute (req, res) {
return res.end(await this.server.transformIndexHtml(req.url, `<html><body><h1>Hello Index</h1></body></html>`, req.originalUrl))
return res.end(await this.server.transformIndexHtml(req.originalUrl, `<html><body><h1>Hello Index</h1></body></html>`, req.originalUrl))
}
async handleCurrentSpecRoute (req, res) {
const html = (await this.getTemplate()).replace('</body>', `
<script src="./${getCurrentSpecFile(req, res)}"></script>
</body>
`)
const specFile = this.getCurrentSpecFile(req)
const supportFile = this.getSupportFile()
return res.end(await this.server.transformIndexHtml(req.url, html))
if (!specFile) {
throw new Error('Attempted to resolve request to Vite Dev Server, but no specs were found. Re-run Cypress with `DEBUG=cypress:vite-dev-server:*` for more details')
}
let client = '<script type="module">'
if (supportFile) client += `await import('/${supportFile}');`
client += `await import('/${specFile.relative}');`
client += `;(function () { ${await this.getClient()} })()`
const html = (await this.getTemplate()).replace('</body>', `${client}</script></body>`)
const ret = await this.server.transformIndexHtml(req.url, html, req.originalUrl)
return res.end(ret)
}
// When the user requests `/does-not-exist`
handle404 (req, res) {
debug('res end 404')
return res.end(`<html><body>404!</body></html>`)
}
}
+15 -4
View File
@@ -3,7 +3,7 @@
* Vitest's own config resolution logic.
* You can find it here https://github.com/vitest-dev/vitest/blob/main/packages/vitest/src/node/create.ts
*/
import { resolve } from 'pathe'
import { resolve, relative } from 'pathe'
import { mergeConfig } from 'vite'
import { configFiles } from './constants'
import { Cypress, CypressInspect } from './plugins/index'
@@ -14,7 +14,7 @@ import { importModule } from 'local-pkg'
const debug = debugFn('cypress:vite-dev-server:resolve-config')
export const createConfig = async ({ options, viteConfig: viteOverrides = {} }: StartDevServer) => {
const root = resolve(process.cwd())
const root = options.config.projectRoot || resolve(process.cwd())
const { default: findUp } = await importModule('find-up')
const configFile = await findUp(configFiles, { cwd: root } as { cwd: string })
@@ -30,12 +30,23 @@ export const createConfig = async ({ options, viteConfig: viteOverrides = {} }:
const config = {
root,
base: `/${options.config.namespace}/src/`,
configFile,
optimizeDeps: {
entries: [
...options.specs.map((s) => relative(root, s.relative)),
options.config.supportFile ?? resolve(root, options.config.supportFile),
].filter((v) => v != null),
},
plugins: [
Cypress(options),
await CypressInspect(),
// await CypressInspect(),
],
}
return mergeConfig(config, viteOverrides)
const finalConfig = mergeConfig(config, viteOverrides)
debug('The resolved server config is', JSON.stringify(finalConfig, null, 2))
return finalConfig
}
+143 -11
View File
@@ -19668,11 +19668,131 @@ es6-weak-map@^2.0.1:
es6-iterator "^2.0.3"
es6-symbol "^3.1.1"
esbuild-android-arm64@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.23.tgz#c89b3c50b4f47668dcbeb0b34ee4615258818e71"
integrity sha512-k9sXem++mINrZty1v4FVt6nC5BQCFG4K2geCIUUqHNlTdFnuvcqsY7prcKZLFhqVC1rbcJAr9VSUGFL/vD4vsw==
esbuild-darwin-64@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.23.tgz#1c131e8cb133ed935ca32f824349a117c896a15b"
integrity sha512-lB0XRbtOYYL1tLcYw8BoBaYsFYiR48RPrA0KfA/7RFTr4MV7Bwy/J4+7nLsVnv9FGuQummM3uJ93J3ptaTqFug==
esbuild-darwin-arm64@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.23.tgz#3c6245a50109dd84953f53d7833bd3b4f0e8c6fa"
integrity sha512-yat73Z/uJ5tRcfRiI4CCTv0FSnwErm3BJQeZAh+1tIP0TUNh6o+mXg338Zl5EKChD+YGp6PN+Dbhs7qa34RxSw==
esbuild-freebsd-64@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.23.tgz#0cdc54e72d3dd9cd992f9c2960055e68a7f8650c"
integrity sha512-/1xiTjoLuQ+LlbfjJdKkX45qK/M7ARrbLmyf7x3JhyQGMjcxRYVR6Dw81uH3qlMHwT4cfLW4aEVBhP1aNV7VsA==
esbuild-freebsd-arm64@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.23.tgz#1d11faed3a0c429e99b7dddef84103eb509788b2"
integrity sha512-uyPqBU/Zcp6yEAZS4LKj5jEE0q2s4HmlMBIPzbW6cTunZ8cyvjG6YWpIZXb1KK3KTJDe62ltCrk3VzmWHp+iLg==
esbuild-linux-32@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.23.tgz#fd9f033fc27dcab61100cb1eb1c936893a68c841"
integrity sha512-37R/WMkQyUfNhbH7aJrr1uCjDVdnPeTHGeDhZPUNhfoHV0lQuZNCKuNnDvlH/u/nwIYZNdVvz1Igv5rY/zfrzQ==
esbuild-linux-64@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.23.tgz#c04c438514f1359ecb1529205d0c836d4165f198"
integrity sha512-H0gztDP60qqr8zoFhAO64waoN5yBXkmYCElFklpd6LPoobtNGNnDe99xOQm28+fuD75YJ7GKHzp/MLCLhw2+vQ==
esbuild-linux-arm64@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.23.tgz#d1b3ab2988ab0734886eb9e811726f7db099ab96"
integrity sha512-c4MLOIByNHR55n3KoYf9hYDfBRghMjOiHLaoYLhkQkIabb452RWi+HsNgB41sUpSlOAqfpqKPFNg7VrxL3UX9g==
esbuild-linux-arm@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.23.tgz#df7558b6a5076f5eb9fd387c8704f768b61d97fb"
integrity sha512-x64CEUxi8+EzOAIpCUeuni0bZfzPw/65r8tC5cy5zOq9dY7ysOi5EVQHnzaxS+1NmV+/RVRpmrzGw1QgY2Xpmw==
esbuild-linux-mips64le@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.23.tgz#bb4c47fccc9493d460ffeb1f88e8a97a98a14f8b"
integrity sha512-kHKyKRIAedYhKug2EJpyJxOUj3VYuamOVA1pY7EimoFPzaF3NeY7e4cFBAISC/Av0/tiV0xlFCt9q0HJ68IBIw==
esbuild-linux-ppc64le@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.23.tgz#a332dbc8a1b4e30cfe1261bfaa5cef57c9c8c02a"
integrity sha512-7ilAiJEPuJJnJp/LiDO0oJm5ygbBPzhchJJh9HsHZzeqO+3PUzItXi+8PuicY08r0AaaOe25LA7sGJ0MzbfBag==
esbuild-linux-riscv64@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.23.tgz#85675f3f931f5cd7cfb238fd82f77a62ffcb6d86"
integrity sha512-fbL3ggK2wY0D8I5raPIMPhpCvODFE+Bhb5QGtNP3r5aUsRR6TQV+ZBXIaw84iyvKC8vlXiA4fWLGhghAd/h/Zg==
esbuild-linux-s390x@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.23.tgz#a526282a696e6d846f4c628f5315475518c0c0f0"
integrity sha512-GHMDCyfy7+FaNSO8RJ8KCFsnax8fLUsOrj9q5Gi2JmZMY0Zhp75keb5abTFCq2/Oy6KVcT0Dcbyo/bFb4rIFJA==
esbuild-netbsd-64@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.23.tgz#8e456605694719aa1be4be266d6cd569c06dfaf5"
integrity sha512-ovk2EX+3rrO1M2lowJfgMb/JPN1VwVYrx0QPUyudxkxLYrWeBxDKQvc6ffO+kB4QlDyTfdtAURrVzu3JeNdA2g==
esbuild-openbsd-64@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.23.tgz#f2fc51714b4ddabc86e4eb30ca101dd325db2f7d"
integrity sha512-uYYNqbVR+i7k8ojP/oIROAHO9lATLN7H2QeXKt2H310Fc8FJj4y3Wce6hx0VgnJ4k1JDrgbbiXM8rbEgQyg8KA==
esbuild-sunos-64@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.23.tgz#a408f33ea20e215909e20173a0fd78b1aaad1f8e"
integrity sha512-hAzeBeET0+SbScknPzS2LBY6FVDpgE+CsHSpe6CEoR51PApdn2IB0SyJX7vGelXzlyrnorM4CAsRyb9Qev4h9g==
esbuild-windows-32@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.23.tgz#b9005bbff54dac3975ff355d5de2b5e37165d128"
integrity sha512-Kttmi3JnohdaREbk6o9e25kieJR379TsEWF0l39PQVHXq3FR6sFKtVPgY8wk055o6IB+rllrzLnbqOw/UV60EA==
esbuild-windows-64@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.23.tgz#2b5a99befeaca6aefdad32d738b945730a60a060"
integrity sha512-JtIT0t8ymkpl6YlmOl6zoSWL5cnCgyLaBdf/SiU/Eg3C13r0NbHZWNT/RDEMKK91Y6t79kTs3vyRcNZbfu5a8g==
esbuild-windows-arm64@0.14.23:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.23.tgz#edc560bbadb097eb45fc235aeacb942cb94a38c0"
integrity sha512-cTFaQqT2+ik9e4hePvYtRZQ3pqOvKDVNarzql0VFIzhc0tru/ZgdLoXd6epLiKT+SzoSce6V9YJ+nn6RCn6SHw==
esbuild@^0.12.17, esbuild@^0.12.28:
version "0.12.29"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.29.tgz#be602db7c4dc78944a9dbde0d1ea19d36c1f882d"
integrity sha512-w/XuoBCSwepyiZtIRsKsetiLDUVGPVw1E/R3VTFSecIy8UR7Cq3SOtwKHJMFoVqqVG36aGkzh4e8BvpO1Fdc7g==
esbuild@^0.14.14:
version "0.14.23"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.23.tgz#95e842cb22bc0c7d82c140adc16788aac91469fe"
integrity sha512-XjnIcZ9KB6lfonCa+jRguXyRYcldmkyZ99ieDksqW/C8bnyEX299yA4QH2XcgijCgaddEZePPTgvx/2imsq7Ig==
optionalDependencies:
esbuild-android-arm64 "0.14.23"
esbuild-darwin-64 "0.14.23"
esbuild-darwin-arm64 "0.14.23"
esbuild-freebsd-64 "0.14.23"
esbuild-freebsd-arm64 "0.14.23"
esbuild-linux-32 "0.14.23"
esbuild-linux-64 "0.14.23"
esbuild-linux-arm "0.14.23"
esbuild-linux-arm64 "0.14.23"
esbuild-linux-mips64le "0.14.23"
esbuild-linux-ppc64le "0.14.23"
esbuild-linux-riscv64 "0.14.23"
esbuild-linux-s390x "0.14.23"
esbuild-netbsd-64 "0.14.23"
esbuild-openbsd-64 "0.14.23"
esbuild-sunos-64 "0.14.23"
esbuild-windows-32 "0.14.23"
esbuild-windows-64 "0.14.23"
esbuild-windows-arm64 "0.14.23"
escalade@^3.0.2, escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
@@ -30220,7 +30340,7 @@ nanoid@3.2.0:
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
nanoid@^3.1.16, nanoid@^3.1.22, nanoid@^3.2.0:
nanoid@^3.1.16, nanoid@^3.1.22, nanoid@^3.2.0, nanoid@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35"
integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==
@@ -34070,12 +34190,12 @@ postcss@^7, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.11, postcss@^7.0.14, po
source-map "^0.6.1"
supports-color "^6.1.0"
postcss@^8.1.10, postcss@^8.1.4, postcss@^8.2.8, postcss@^8.3.6:
version "8.4.6"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.6.tgz#c5ff3c3c457a23864f32cb45ac9b741498a09ae1"
integrity sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==
postcss@^8.1.10, postcss@^8.1.4, postcss@^8.2.8, postcss@^8.3.6, postcss@^8.4.5:
version "8.4.7"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.7.tgz#f99862069ec4541de386bf57f5660a6c7a0875a8"
integrity sha512-L9Ye3r6hkkCeOETQX6iOaWZgjp3LL6Lpqm6EtgbKrgqGGteRMNb9vzBfRL96YOSu8o7x3MfIH9Mo5cPJFGrW6A==
dependencies:
nanoid "^3.2.0"
nanoid "^3.3.1"
picocolors "^1.0.0"
source-map-js "^1.0.2"
@@ -36784,7 +36904,7 @@ resolve@^0.6.3:
resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46"
integrity sha1-3ZV5gufnNt699TtYpN2RdUV13UY=
resolve@^1.1.4, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.15.1, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.8.1:
resolve@^1.1.4, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.11.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.15.1, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.8.1:
version "1.22.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
@@ -37046,10 +37166,10 @@ rollup@2.38.4:
optionalDependencies:
fsevents "~2.3.1"
rollup@^2.38.5, rollup@^2.56.1:
version "2.67.1"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.67.1.tgz#4402665706fa00f321d446ce45f880e02cf54f01"
integrity sha512-1Sbcs4OuW+aD+hhqpIRl+RqooIpF6uQcfzU/QSI7vGkwADY6cM4iLsBGRM2CGLXDTDN5y/yShohFmnKegSPWzg==
rollup@^2.38.5, rollup@^2.56.1, rollup@^2.59.0:
version "2.68.0"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.68.0.tgz#6ccabfd649447f8f21d62bf41662e5caece3bd66"
integrity sha512-XrMKOYK7oQcTio4wyTz466mucnd8LzkiZLozZ4Rz0zQD+HeX4nUK4B8GrTX/2EvN2/vBF/i2WnaXboPxo0JylA==
optionalDependencies:
fsevents "~2.3.2"
@@ -42693,6 +42813,18 @@ vite@2.5.0:
optionalDependencies:
fsevents "~2.3.2"
vite@2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/vite/-/vite-2.8.0.tgz#0646ab9eee805fb24b667889644ac04bc516d0d3"
integrity sha512-ed5rjyeysttuPJX/aKSA0gTB/8ZKLM5xF6FtEuKy1B9DiQbDNFMVMQxnb9JesgBPUMMIJxC8w5KZ/KNWLKFXoA==
dependencies:
esbuild "^0.14.14"
postcss "^8.4.5"
resolve "^1.22.0"
rollup "^2.59.0"
optionalDependencies:
fsevents "~2.3.2"
vm-browserify@1.1.2, vm-browserify@^1.0.0, vm-browserify@^1.0.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"