diff --git a/examples/framework-preact/src/pages/index.astro b/examples/framework-preact/src/pages/index.astro
index aea8b83a4..00ac11e14 100644
--- a/examples/framework-preact/src/pages/index.astro
+++ b/examples/framework-preact/src/pages/index.astro
@@ -1,6 +1,6 @@
---
// Component Imports
-import Counter from '../components/Counter.jsx'
+import Counter from '../components/Counter.tsx'
// Full Astro Component Syntax:
diff --git a/examples/minimal/src/pages/index.astro b/examples/minimal/src/pages/index.astro
index 8e9209641..94a12e9de 100644
--- a/examples/minimal/src/pages/index.astro
+++ b/examples/minimal/src/pages/index.astro
@@ -1,5 +1,6 @@
---
---
+
@@ -7,6 +8,7 @@
Welcome to Astro
+
diff --git a/package.json b/package.json
index cc71dc224..7cbad4381 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,7 @@
},
"devDependencies": {
"@changesets/cli": "^2.16.0",
- "@octokit/action": "^3.15.4",
+ "@types/jest": "^27.0.1",
"@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.18.0",
"autoprefixer": "^10.2.6",
@@ -56,11 +56,11 @@
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0",
"execa": "^5.0.0",
+ "jest": "^27.1.0",
"lerna": "^4.0.0",
"prettier": "^2.3.2",
"tiny-glob": "^0.2.8",
- "typescript": "^4.4.2",
- "uvu": "^0.5.1"
+ "typescript": "^4.4.2"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
diff --git a/packages/astro/components/Markdown.astro b/packages/astro/components/Markdown.astro
index 609d015d4..99999751e 100644
--- a/packages/astro/components/Markdown.astro
+++ b/packages/astro/components/Markdown.astro
@@ -1,12 +1,14 @@
-
-import fetch from 'node-fetch';
+---
import { renderMarkdown } from '@astrojs/markdown-support';
-import { __astro_slot } from 'astro/runtime/__astro_slot.js';
-if(!('fetch' in globalThis)) {
- globalThis.fetch = fetch;
+export interface Props {
+ content?: string;
}
+// Internal props that should not be part of the external interface.
+interface InternalProps extends Props {
+ $scope: string;
+}
const __TopLevelAstro = {
site: new URL("http://localhost:3000"),
@@ -64,11 +66,11 @@ async function __render(props, ...children) {
$scope
} = Astro.props;
let html = null;
+
+// This flow is only triggered if a user passes ` `
if (content) {
- const {
- content: htmlContent
- } = await renderMarkdown(content, {
- mode: "md",
+ const { content: htmlContent } = await renderMarkdown(content, {
+ mode: 'md',
$: {
scopedClassName: $scope
}
@@ -76,55 +78,9 @@ if (content) {
html = htmlContent;
}
- return h(Fragment, null, h(Fragment, null,(html ? html : h(Fragment, null, h(__astro_slot, { [__astroContext]: props[__astroContext] }, children)))));
-}
-export default { isAstroComponent: true, __render };
-
-// `__renderPage()`: Render the contents of the Astro module as a page. This is a special flow,
-// triggered by loading a component directly by URL.
-export async function __renderPage({request, children, props, css}) {
- const currentChild = {
- isAstroComponent: true,
- layout: typeof __layout === 'undefined' ? undefined : __layout,
- content: typeof __content === 'undefined' ? undefined : __content,
- __render,
- };
-
- const isLayout = (__astroContext in props);
- if(!isLayout) {
- let astroRootUIDCounter = 0;
- Object.defineProperty(props, __astroContext, {
- value: {
- pageCSS: css,
- request,
- createAstroRootUID(seed) { return seed + astroRootUIDCounter++; },
- },
- writable: false,
- enumerable: false
- });
- }
-
- Object.defineProperty(props, __astroInternal, {
- value: {
- isPage: !isLayout
- },
- writable: false,
- enumerable: false
- });
-
- const childBodyResult = await currentChild.__render(props, children);
-
- // find layout, if one was given.
- if (currentChild.layout) {
- return currentChild.layout({
- request,
- props: {content: currentChild.content, [__astroContext]: props[__astroContext]},
- children: [childBodyResult],
- });
- }
-
- return childBodyResult;
-};
-
-
-
+/*
+ If we have rendered `html` for `content`, render that
+ Otherwise, just render the slotted content
+*/
+---
+{html ? html : }
diff --git a/packages/astro/package.json b/packages/astro/package.json
index eefa26212..7c6b54014 100644
--- a/packages/astro/package.json
+++ b/packages/astro/package.json
@@ -17,7 +17,8 @@
"./debug": "./components/Debug.astro",
"./components/*": "./components/*",
"./package.json": "./package.json",
- "./runtime/*": "./dist/runtime/*"
+ "./runtime/*": "./dist/runtime/*.js",
+ "./internal": "./dist/internal/index.js"
},
"imports": {
"#astro/*": "./dist/*.js"
@@ -35,12 +36,12 @@
"dev": "astro-scripts dev \"src/**/*.ts\"",
"postbuild": "astro-scripts copy \"src/**/*.astro\"",
"benchmark": "node test/benchmark/dev.bench.js && node test/benchmark/build.bench.js",
- "test": "uvu test -i fixtures -i benchmark -i test-utils.js"
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest"
},
"dependencies": {
+ "@astrojs/compiler": "^0.1.0-canary.36",
"@astrojs/language-server": "^0.7.16",
"@astrojs/markdown-support": "0.3.1",
- "@astrojs/parser": "0.20.2",
"@astrojs/prism": "0.2.2",
"@astrojs/renderer-preact": "0.2.2",
"@astrojs/renderer-react": "0.2.2",
@@ -68,10 +69,12 @@
"es-module-lexer": "^0.7.1",
"esbuild": "^0.12.23",
"estree-util-value-to-estree": "^1.2.0",
+ "etag": "^1.8.1",
"fast-xml-parser": "^3.19.0",
"fdir": "^5.1.0",
"kleur": "^4.1.4",
"mime": "^2.5.2",
+ "morphdom": "^2.6.1",
"node-fetch": "^2.6.1",
"path-to-regexp": "^6.2.0",
"picomatch": "^2.3.0",
@@ -85,7 +88,7 @@
"srcset-parse": "^1.1.0",
"string-width": "^5.0.0",
"supports-esm": "^1.0.0",
- "vite": "^2.5.1",
+ "vite": "^2.5.2",
"yargs-parser": "^20.2.9",
"zod": "^3.8.1"
},
@@ -93,6 +96,7 @@
"@astrojs/parser": "^0.20.2",
"@types/babel__core": "^7.1.15",
"@types/connect": "^3.4.35",
+ "@types/etag": "^1.8.1",
"@types/mime": "^2.0.3",
"@types/node-fetch": "^2.5.12",
"@types/send": "^0.17.1",
diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts
index 07fbfdebd..762e3eca0 100644
--- a/packages/astro/src/@types/astro.ts
+++ b/packages/astro/src/@types/astro.ts
@@ -3,15 +3,16 @@ import type babel from '@babel/core';
import type vite from 'vite';
import type { z } from 'zod';
import type { AstroConfigSchema } from '../config';
+import type { AstroComponentFactory } from '../internal';
export { AstroMarkdownOptions };
export interface AstroComponentMetadata {
displayName: string;
hydrate?: 'load' | 'idle' | 'visible' | 'media' | 'only';
+ hydrateArgs?: any;
componentUrl?: string;
componentExport?: { value: string; namespace?: boolean };
- value?: undefined | string;
}
/**
@@ -140,12 +141,7 @@ export interface CollectionRSS {
/** Generic interface for a component (Astro, Svelte, React, etc.) */
export interface ComponentInstance {
- default: {
- isAstroComponent: boolean;
- __render?(props: Props, ...children: any[]): string;
- __renderer?: Renderer;
- };
- __renderPage?: (options: RenderPageOptions) => string;
+ default: AstroComponentFactory;
css?: string[];
getStaticPaths?: (options: GetStaticPathsOptions) => GetStaticPathsResult;
}
diff --git a/packages/astro/src/@types/compiler.d.ts b/packages/astro/src/@types/compiler.d.ts
new file mode 100644
index 000000000..213e1c503
--- /dev/null
+++ b/packages/astro/src/@types/compiler.d.ts
@@ -0,0 +1,45 @@
+declare module '@astrojs/compiler' {
+ export type Platform = 'browser' | 'node' | 'neutral';
+ export type SourceMap = any;
+
+ export interface TransformOptions {}
+
+ export interface TransformResult {
+ code: string;
+ map: SourceMap;
+ warnings: any[];
+ }
+
+ export interface TransformResults {
+ js: TransformResult;
+ css?: TransformResult;
+ }
+
+ // This function transforms a single JavaScript file. It can be used to minify
+ // JavaScript, convert TypeScript/JSX to JavaScript, or convert newer JavaScript
+ // to older JavaScript. It returns a promise that is either resolved with a
+ // "TransformResult" object or rejected with a "TransformFailure" object.
+ //
+ // Works in node: yes
+ // Works in browser: yes
+ export declare function transform(input: string, options?: TransformOptions): Promise;
+
+ // This configures the browser-based version of astro. It is necessary to
+ // call this first and wait for the returned promise to be resolved before
+ // making other API calls when using astro in the browser.
+ //
+ // Works in node: yes
+ // Works in browser: yes ("options" is required)
+ export declare function initialize(options: InitializeOptions): Promise;
+
+ export interface InitializeOptions {
+ // The URL of the "astro.wasm" file. This must be provided when running
+ // astro in the browser.
+ wasmURL?: string;
+
+ // By default astro runs the WebAssembly-based browser API in a web worker
+ // to avoid blocking the UI thread. This can be disabled by setting "worker"
+ // to false.
+ worker?: boolean;
+ }
+}
diff --git a/packages/astro/src/build/index.ts b/packages/astro/src/build/index.ts
index 3dac614d8..3967e8b57 100644
--- a/packages/astro/src/build/index.ts
+++ b/packages/astro/src/build/index.ts
@@ -75,7 +75,7 @@ class AstroBuilder {
// static pages
if (pathname) {
allPages.push(
- ssr({ filePath, logging, mode: 'production', origin, route, routeCache: this.routeCache, pathname, viteServer }).then((html) => ({
+ ssr({ astroConfig: this.config, filePath, logging, mode: 'production', origin, route, routeCache: this.routeCache, pathname, viteServer }).then((html) => ({
html,
name: pathname.replace(/\/?$/, '/index.html').replace(/^\//, ''),
}))
@@ -97,7 +97,7 @@ class AstroBuilder {
// TODO: throw error if conflict
staticPaths.paths.forEach((staticPath) => {
allPages.push(
- ssr({ filePath, logging, mode: 'production', origin, route, routeCache: this.routeCache, pathname: staticPath, viteServer }).then((html) => ({
+ ssr({ astroConfig: this.config, filePath, logging, mode: 'production', origin, route, routeCache: this.routeCache, pathname: staticPath, viteServer }).then((html) => ({
html,
name: staticPath.replace(/\/?$/, '/index.html').replace(/^\//, ''),
}))
diff --git a/packages/astro/src/cli/index.ts b/packages/astro/src/cli/index.ts
index b4777da6e..79010725e 100644
--- a/packages/astro/src/cli/index.ts
+++ b/packages/astro/src/cli/index.ts
@@ -10,7 +10,7 @@ import { z } from 'zod';
import { defaultLogDestination } from '../logger.js';
import build from '../build/index.js';
import devServer from '../dev/index.js';
-import { preview } from '../preview/index.js';
+import preview from '../preview/index.js';
import { reload } from './reload.js';
import { check } from './check.js';
import { formatConfigError, loadConfig } from '../config.js';
diff --git a/packages/astro/src/dev/index.ts b/packages/astro/src/dev/index.ts
index 73819616a..1bec87310 100644
--- a/packages/astro/src/dev/index.ts
+++ b/packages/astro/src/dev/index.ts
@@ -1,13 +1,18 @@
import type { NextFunction } from 'connect';
import type http from 'http';
-import type { AstroConfig, ManifestData, RouteCache } from '../@types/astro';
+import type { AstroConfig, ManifestData, RouteCache, RouteData } from '../@types/astro';
import type { LogOptions } from '../logger';
+import type { HmrContext, ModuleNode } from 'vite';
import chokidar from 'chokidar';
import connect from 'connect';
import mime from 'mime';
+import getEtag from 'etag';
import { performance } from 'perf_hooks';
import { fileURLToPath } from 'url';
+import { createRequire } from 'module';
+import path from 'path';
+import { promises as fs } from 'fs';
import vite from 'vite';
import { defaultLogOptions, error, info } from '../logger.js';
import { createRouteManifest, matchRoute } from '../runtime/routing.js';
@@ -16,6 +21,8 @@ import { loadViteConfig } from '../runtime/vite/config.js';
import * as msg from './messages.js';
import { errorTemplate } from './template/error.js';
+const require = createRequire(import.meta.url);
+
export interface DevOptions {
logging: LogOptions;
}
@@ -39,16 +46,18 @@ export default async function dev(config: AstroConfig, options: DevOptions = { l
hostname: server.hostname,
port: server.port,
server: server.app,
- stop: server.stop,
+ stop: () => server.stop(),
};
}
/** Dev server */
-class AstroDevServer {
+export class AstroDevServer {
app = connect();
+ httpServer: http.Server | undefined;
hostname: string;
port: number;
+ private internalCache: Map;
private config: AstroConfig;
private logging: LogOptions;
private manifest: ManifestData;
@@ -56,8 +65,10 @@ class AstroDevServer {
private routeCache: RouteCache = {};
private viteServer: vite.ViteDevServer | undefined;
private watcher: chokidar.FSWatcher;
+ private mostRecentRoute?: RouteData;
constructor(config: AstroConfig, options: DevOptions) {
+ this.internalCache = new Map();
this.config = config;
this.hostname = config.devOptions.hostname || 'localhost';
this.logging = options.logging;
@@ -94,7 +105,7 @@ class AstroDevServer {
host: this.hostname,
},
},
- { astroConfig: this.config, logging: this.logging }
+ { astroConfig: this.config, logging: this.logging, devServer: this }
);
this.viteServer = await vite.createServer(viteConfig);
@@ -104,27 +115,24 @@ class AstroDevServer {
this.app.use((req, res, next) => this.renderError(req, res, next));
// 4. listen on port
- await new Promise((resolve, reject) => {
- this.app
- .listen(this.port, this.hostname, () => {
- info(this.logging, 'astro', msg.devStart({ startupTime: performance.now() - devStart }));
- info(this.logging, 'astro', msg.devHost({ host: `http://${this.hostname}:${this.port}` }));
- resolve();
- })
- .on('error', (err: NodeJS.ErrnoException) => {
- if (err.code && err.code === 'EADDRINUSE') {
- error(this.logging, 'astro', `Address ${this.hostname}:${this.port} already in use. Try changing devOptions.port in your config file`);
- } else {
- error(this.logging, 'astro', err.stack);
- }
- reject();
- process.exit(1);
- });
+ this.httpServer = this.app.listen(this.port, this.hostname, () => {
+ info(this.logging, 'astro', msg.devStart({ startupTime: performance.now() - devStart }));
+ info(this.logging, 'astro', msg.devHost({ host: `http://${this.hostname}:${this.port}` }));
+ });
+ this.httpServer.on('error', (err: NodeJS.ErrnoException) => {
+ if (err.code && err.code === 'EADDRINUSE') {
+ error(this.logging, 'astro', `Address ${this.hostname}:${this.port} already in use. Try changing devOptions.port in your config file`);
+ } else {
+ error(this.logging, 'astro', err.stack);
+ }
+ process.exit(1);
});
}
/** Stop dev server */
async stop() {
+ this.internalCache = new Map();
+ if (this.httpServer) this.httpServer.close(); // close HTTP server
await Promise.all([
...(this.viteServer ? [this.viteServer.close()] : []), // close Vite server
this.watcher.close(), // close chokidar
@@ -138,6 +146,13 @@ class AstroDevServer {
let pathname = req.url || '/'; // original request
const reqStart = performance.now();
+ if (pathname.startsWith('/@astro')) {
+ const spec = pathname.slice(2);
+ const url = await this.viteServer.moduleGraph.resolveUrl(spec);
+ req.url = url[1];
+ return this.viteServer.middlewares.handle(req, res, next);
+ }
+
try {
const route = matchRoute(pathname, this.manifest);
@@ -147,8 +162,11 @@ class AstroDevServer {
return;
}
+ this.mostRecentRoute = route;
+
// handle .astro and .md pages
const html = await ssr({
+ astroConfig: this.config,
filePath: new URL(`./${route.component}`, this.config.projectRoot),
logging: this.logging,
mode: 'development',
@@ -168,7 +186,7 @@ class AstroDevServer {
} catch (e) {
const err = e as Error;
this.viteServer.ssrFixStacktrace(err);
- console.error(err.stack);
+ console.log(err.stack);
const statusCode = 500;
const html = errorTemplate({ statusCode, title: 'Internal Error', tabTitle: '500: Error', message: err.message });
info(this.logging, 'astro', msg.req({ url: pathname, statusCode: 500, reqTime: performance.now() - reqStart }));
@@ -195,6 +213,7 @@ class AstroDevServer {
const userDefined404 = this.manifest.routes.find((route) => route.component === relPages + '404.astro');
if (userDefined404) {
html = await ssr({
+ astroConfig: this.config,
filePath: new URL(`./${userDefined404.component}`, this.config.projectRoot),
logging: this.logging,
mode: 'development',
@@ -216,4 +235,53 @@ class AstroDevServer {
res.write(html);
res.end();
}
+
+ public async handleHotUpdate({ file, modules }: HmrContext): Promise {
+ if (!this.viteServer) throw new Error(`AstroDevServer.start() not called`);
+
+ for (const module of modules) {
+ this.viteServer.moduleGraph.invalidateModule(module);
+ }
+
+ const route = this.mostRecentRoute;
+ const pathname = route?.pathname ?? '/';
+
+ if (!route) {
+ this.viteServer.ws.send({
+ type: 'full-reload',
+ });
+ return [];
+ }
+
+ try {
+ // try to update the most recent route
+ const html = await ssr({
+ astroConfig: this.config,
+ filePath: new URL(`./${route.component}`, this.config.projectRoot),
+ logging: this.logging,
+ mode: 'development',
+ origin: this.origin,
+ pathname,
+ route,
+ routeCache: this.routeCache,
+ viteServer: this.viteServer,
+ });
+
+ // TODO: log update
+ this.viteServer.ws.send({
+ type: 'custom',
+ event: 'astro:reload',
+ data: { html },
+ });
+ return [];
+ } catch (e) {
+ const err = e as Error;
+ this.viteServer.ssrFixStacktrace(err);
+ console.log(err.stack);
+ this.viteServer.ws.send({
+ type: 'full-reload',
+ });
+ return [];
+ }
+ }
}
diff --git a/packages/astro/src/dev/messages.ts b/packages/astro/src/dev/messages.ts
index c3fc5b94c..725d9a0f8 100644
--- a/packages/astro/src/dev/messages.ts
+++ b/packages/astro/src/dev/messages.ts
@@ -15,6 +15,12 @@ export function req({ url, statusCode, reqTime }: { url: string; statusCode: num
return `${color(statusCode)} ${pad(url, 40)} ${dim(Math.round(reqTime) + 'ms')}`;
}
+/** Display */
+export function reload({ url, reqTime }: { url: string; reqTime: number }): string {
+ let color = yellow;
+ return `${pad(url, 40)} ${dim(Math.round(reqTime) + 'ms')}`;
+}
+
/** Display dev server host and startup time */
export function devStart({ startupTime }: { startupTime: number }): string {
return `${pad(`Server started`, 44)} ${dim(`${Math.round(startupTime)}ms`)}`;
diff --git a/packages/astro/src/internal/index.ts b/packages/astro/src/internal/index.ts
new file mode 100644
index 000000000..5b9592d88
--- /dev/null
+++ b/packages/astro/src/internal/index.ts
@@ -0,0 +1,211 @@
+import type { AstroComponentMetadata } from '../@types/astro';
+import { renderAstroComponent } from '../runtime/ssr.js';
+
+import { valueToEstree, Value } from 'estree-util-value-to-estree';
+import * as astring from 'astring';
+import shorthash from 'shorthash';
+const { generate, GENERATOR } = astring;
+// A more robust version alternative to `JSON.stringify` that can handle most values
+// see https://github.com/remcohaszing/estree-util-value-to-estree#readme
+const customGenerator: astring.Generator = {
+ ...GENERATOR,
+ Literal(node, state) {
+ if (node.raw != null) {
+ // escape closing script tags in strings so browsers wouldn't interpret them as
+ // closing the actual end tag in HTML
+ state.write(node.raw.replace('', '<\\/script>'));
+ } else {
+ GENERATOR.Literal(node, state);
+ }
+ },
+};
+const serialize = (value: Value) =>
+ generate(valueToEstree(value), {
+ generator: customGenerator,
+ });
+
+async function _render(child: any) {
+ // Special: If a child is a function, call it automatically.
+ // This lets you do {() => ...} without the extra boilerplate
+ // of wrapping it in a function and calling it.
+ if (typeof child === 'function') {
+ return await child();
+ } else if (typeof child === 'string') {
+ return child;
+ } else if (!child && child !== 0) {
+ // do nothing, safe to ignore falsey values.
+ } else {
+ return child;
+ }
+}
+
+export class AstroComponent {
+ private htmlParts: string[];
+ private expressions: TemplateStringsArray;
+
+ constructor(htmlParts: string[], expressions: TemplateStringsArray) {
+ this.htmlParts = htmlParts;
+ this.expressions = expressions;
+ }
+
+ *[Symbol.iterator]() {
+ const { htmlParts, expressions } = this;
+
+ for (let i = 0; i < htmlParts.length; i++) {
+ const html = htmlParts[i];
+ const expression = expressions[i];
+
+ yield _render(html);
+ yield _render(expression);
+ }
+ }
+}
+
+export function render(htmlParts: string[], ...expressions: TemplateStringsArray) {
+ return new AstroComponent(htmlParts, expressions);
+}
+
+export interface AstroComponentFactory {
+ (result: any, props: any, slots: any): ReturnType;
+ isAstroComponentFactory?: boolean;
+}
+
+export const createComponent = (cb: AstroComponentFactory) => {
+ // Add a flag to this callback to mark it as an Astro component
+ (cb as any).isAstroComponentFactory = true;
+ return cb;
+}
+
+function extractHydrationDirectives(inputProps: Record): { hydrationDirective: [string, any] | null; props: Record } {
+ let props: Record = {};
+ let hydrationDirective: [string, any] | null = null;
+ for (const [key, value] of Object.entries(inputProps)) {
+ if (key.startsWith('client:')) {
+ hydrationDirective = [key.split(':')[1], value];
+ } else {
+ props[key] = value;
+ }
+ }
+ return { hydrationDirective, props };
+}
+
+interface HydrateScriptOptions {
+ renderer: any;
+ astroId: string;
+ props: any;
+}
+
+/** For hydrated components, generate a
+`;
+
+ return hydrationScript;
+}
+
+export const renderComponent = async (result: any, displayName: string, Component: unknown, _props: Record, children: any) => {
+ Component = await Component;
+ // children = await renderGenerator(children);
+ const { renderers } = result._metadata;
+ if (Component && (Component as any).isAstroComponentFactory) {
+ const output = await renderAstroComponent(await (Component as any)(result, Component, _props, children))
+ return output;
+ }
+
+ let metadata: AstroComponentMetadata = { displayName };
+
+ if (Component == null) {
+ throw new Error(`Unable to render ${metadata.displayName} because it is ${Component}!\nDid you forget to import the component or is it possible there is a typo?`);
+ }
+ // else if (typeof Component === 'string' && !isCustomElementTag(Component)) {
+ // throw new Error(`Astro is unable to render ${metadata.displayName}!\nIs there a renderer to handle this type of component defined in your Astro config?`);
+ // }
+ const { hydrationDirective, props } = extractHydrationDirectives(_props);
+ let html = '';
+
+ if (!hydrationDirective) {
+ return 'Not implemented ';
+ }
+ metadata.hydrate = hydrationDirective[0] as AstroComponentMetadata['hydrate'];
+ metadata.hydrateArgs = hydrationDirective[1];
+
+ for (const [url, exported] of Object.entries(result._metadata.importedModules)) {
+ for (const [key, value] of Object.entries(exported as any)) {
+ if (Component === value) {
+ metadata.componentExport = { value: key };
+ metadata.componentUrl = url;
+ break;
+ }
+ }
+ }
+
+ let renderer = null;
+ for (const r of renderers) {
+ if (await r.ssr.check(Component, props, null)) {
+ renderer = r;
+ }
+ }
+
+ ({ html } = await renderer.ssr.renderToStaticMarkup(Component, props, null));
+ const astroId = shorthash.unique(html);
+
+ result.scripts.add(await generateHydrateScript({ renderer, astroId, props }, metadata as Required));
+
+ return `${html} `;
+};
+
+export const addAttribute = (value: any, key: string) => {
+ if (value == null || value === false) {
+ return '';
+ }
+ return ` ${key}="${value}"`;
+};
+
+export const spreadAttributes = (values: Record) => {
+ let output = '';
+ for (const [key, value] of Object.entries(values)) {
+ output += addAttribute(value, key);
+ }
+ return output;
+};
+
+export const defineStyleVars = (astroId: string, vars: Record) => {
+ let output = '\n';
+ for (const [key, value] of Object.entries(vars)) {
+ output += ` --${key}: ${value};\n`;
+ }
+ return `.${astroId} {${output}}`;
+};
+
+export const defineScriptVars = (vars: Record) => {
+ let output = '';
+ for (const [key, value] of Object.entries(vars)) {
+ output += `let ${key} = ${JSON.stringify(value)};\n`;
+ }
+ return output;
+};
diff --git a/packages/astro/src/preview/index.ts b/packages/astro/src/preview/index.ts
index 24d8873a8..69234c988 100644
--- a/packages/astro/src/preview/index.ts
+++ b/packages/astro/src/preview/index.ts
@@ -13,7 +13,7 @@ interface PreviewOptions {
}
/** The primary dev action */
-export async function preview(config: AstroConfig, { logging }: PreviewOptions) {
+export default async function preview(config: AstroConfig, { logging }: PreviewOptions) {
const {
dist,
devOptions: { hostname, port },
diff --git a/packages/astro/src/runtime/__astro_component.ts b/packages/astro/src/runtime/__astro_component.ts
deleted file mode 100644
index a1f9080bb..000000000
--- a/packages/astro/src/runtime/__astro_component.ts
+++ /dev/null
@@ -1,242 +0,0 @@
-import type { AstroComponentMetadata, ComponentInstance, Renderer } from '../@types/astro';
-
-import hash from 'shorthash';
-import { valueToEstree, Value } from 'estree-util-value-to-estree';
-import * as astring from 'astring';
-import * as astroHtml from './html.js';
-
-const { generate, GENERATOR } = astring;
-
-// A more robust version alternative to `JSON.stringify` that can handle most values
-// see https://github.com/remcohaszing/estree-util-value-to-estree#readme
-const customGenerator: astring.Generator = {
- ...GENERATOR,
- Literal(node, state) {
- if (node.raw != null) {
- // escape closing script tags in strings so browsers wouldn't interpret them as
- // closing the actual end tag in HTML
- state.write(node.raw.replace('', '<\\/script>'));
- } else {
- GENERATOR.Literal(node, state);
- }
- },
-};
-const serialize = (value: Value) =>
- generate(valueToEstree(value), {
- generator: customGenerator,
- });
-
-declare let rendererInstances: Renderer[];
-
-function isCustomElementTag(name: unknown) {
- return typeof name === 'string' && /-/.test(name);
-}
-
-const rendererCache = new Map();
-
-/** For client:only components, attempt to infer the required renderer. */
-function inferClientRenderer(metadata: Partial) {
- // If there's only one renderer, assume it's the required renderer
- if (rendererInstances.length === 1) {
- return rendererInstances[0];
- } else if (metadata.value) {
- // Attempt to find the renderer by matching the hydration value
- const hint = metadata.value;
- let match = rendererInstances.find((instance) => instance.name === hint);
-
- if (!match) {
- // Didn't find an exact match, try shorthand hints for the internal renderers
- const fullHintName = `@astrojs/renderer-${hint}`;
- match = rendererInstances.find((instance) => instance.name === fullHintName);
- }
-
- if (!match) {
- throw new Error(
- `Couldn't find a renderer for <${metadata.displayName} client:only="${metadata.value}" />. Is there a renderer that matches the "${metadata.value}" hint in your Astro config?`
- );
- }
- return match;
- } else {
- // Multiple renderers included but no hint was provided
- throw new Error(
- `Can't determine the renderer for ${metadata.displayName}. Include a hint similar to <${metadata.displayName} client:only="react" /> when multiple renderers are included in your Astro config.`
- );
- }
-}
-
-/** For a given component, resolve the renderer. Results are cached if this instance is encountered again */
-async function resolveRenderer(Component: any, props: any = {}, children?: string, metadata: Partial = {}): Promise {
- // For client:only components, the component can't be imported
- // during SSR. We need to infer the required renderer.
- if (metadata.hydrate === 'only') {
- return inferClientRenderer(metadata);
- }
-
- if (rendererCache.has(Component)) {
- return rendererCache.get(Component);
- }
-
- const errors: Error[] = [];
- for (const renderer of rendererInstances) {
- // Yes, we do want to `await` inside of this loop!
- // __renderer.check can't be run in parallel, it
- // returns the first match and skips any subsequent checks
- try {
- const shouldUse: boolean = await renderer.ssr.check(Component, props, children);
-
- if (shouldUse) {
- rendererCache.set(Component, renderer);
- return renderer;
- }
- } catch (err) {
- errors.push(err as any);
- }
- }
-
- if (errors.length) {
- // For now just throw the first error we encounter.
- throw errors[0];
- }
-}
-
-interface HydrateScriptOptions {
- renderer: Renderer;
- astroId: string;
- props: any;
-}
-
-const astroHtmlRendererInstance: Renderer = {
- name: '@astrojs/renderer-html',
- source: '',
- ssr: astroHtml as any,
- polyfills: [],
- hydrationPolyfills: [],
-};
-
-/** For hydrated components, generate a
-`;
-
- return hydrationScript;
-}
-
-const getComponentName = (Component: any, componentProps: any) => {
- if (componentProps.displayName) return componentProps.displayName;
- switch (typeof Component) {
- case 'function':
- return Component.displayName ?? Component.name;
- case 'string':
- return Component;
- default: {
- return Component;
- }
- }
-};
-
-const prepareSlottedChildren = (children: string | Record[]) => {
- const $slots: Record = {
- default: '',
- };
- for (const child of children) {
- if (typeof child === 'string') {
- $slots.default += child;
- } else if (typeof child === 'object' && child['$slot']) {
- if (!$slots[child['$slot']]) $slots[child['$slot']] = '';
- $slots[child['$slot']] += child.children.join('').replace(new RegExp(`slot="${child['$slot']}"\s*`, ''));
- }
- }
-
- return { $slots };
-};
-
-const removeSlottedChildren = (_children: string | Record[]) => {
- let children = '';
- for (const child of _children) {
- if (typeof child === 'string') {
- children += child;
- } else if (typeof child === 'object' && child['$slot']) {
- children += child.children.join('');
- }
- }
-
- return children;
-};
-
-/** The main wrapper for any components in Astro files */
-export function __astro_component(Component: ComponentInstance['default'], metadata: AstroComponentMetadata = {} as any) {
- if (Component == null) {
- throw new Error(`Unable to render ${metadata.displayName} because it is ${Component}!\nDid you forget to import the component or is it possible there is a typo?`);
- } else if (typeof Component === 'string' && !isCustomElementTag(Component)) {
- throw new Error(`Astro is unable to render ${metadata.displayName}!\nIs there a renderer to handle this type of component defined in your Astro config?`);
- }
-
- return async function __astro_component_internal(props: any, ..._children: any[]) {
- if (Component.isAstroComponent && Component.__render) {
- return Component.__render(props, prepareSlottedChildren(_children));
- }
- const children = removeSlottedChildren(_children);
- let renderer = await resolveRenderer(Component, props, children, metadata);
-
- if (!renderer) {
- if (isCustomElementTag(Component as any)) {
- renderer = astroHtmlRendererInstance;
- } else {
- // If the user only specifies a single renderer, but the check failed
- // for some reason... just default to their preferred renderer.
- renderer = rendererInstances.length === 2 ? rendererInstances[1] : undefined;
- }
-
- if (!renderer) {
- const name = getComponentName(Component, metadata);
- throw new Error(`No renderer found for ${name}! Did you forget to add a renderer to your Astro config?`);
- }
- }
-
- let html = '';
- // Skip SSR for components using client:only hydration
- if (metadata.hydrate !== 'only') {
- const rendered = await renderer.ssr.renderToStaticMarkup(Component, props, children, metadata);
- html = rendered.html;
- }
-
- if (renderer.polyfills) {
- let polyfillScripts = renderer.polyfills.map((src: string) => ``).join('');
- html = html + polyfillScripts;
- }
-
- // If we're NOT hydrating this component, just return the HTML
- if (!metadata.hydrate) {
- // It's safe to remove , static content doesn't need the wrapper
- return html.replace(/\<\/?astro-fragment\>/g, '');
- }
-
- // If we ARE hydrating this component, let's generate the hydration script
- const uniqueId = props[Symbol.for('astro.context')].createAstroRootUID(html);
- const uniqueIdHashed = hash.unique(uniqueId);
- const script = await generateHydrateScript({ renderer, astroId: uniqueIdHashed, props }, metadata as Required);
- const astroRoot = `${html} `;
- return [astroRoot, script].join('\n');
- };
-}
diff --git a/packages/astro/src/runtime/hmr.ts b/packages/astro/src/runtime/hmr.ts
new file mode 100644
index 000000000..c64ddb6d7
--- /dev/null
+++ b/packages/astro/src/runtime/hmr.ts
@@ -0,0 +1,33 @@
+import 'vite/client';
+
+if (import.meta.hot) {
+ const parser = new DOMParser();
+ import.meta.hot.on('astro:reload', async ({ html }: { html: string }) => {
+ const { default: morphdom } = await import('morphdom');
+ const doc = parser.parseFromString(html, 'text/html');
+
+ morphdom(document.head, doc.head, {
+ onBeforeElUpdated: function (fromEl, toEl) {
+ if (fromEl.isEqualNode(toEl)) {
+ return false;
+ }
+
+ return true;
+ },
+ });
+
+ morphdom(document.body, doc.body, {
+ onBeforeElUpdated: function (fromEl, toEl) {
+ if (fromEl.localName === 'astro-root') {
+ return fromEl.getAttribute('uid') !== toEl.getAttribute('uid');
+ }
+
+ if (fromEl.isEqualNode(toEl)) {
+ return false;
+ }
+
+ return true;
+ },
+ });
+ });
+}
diff --git a/packages/astro/src/runtime/ssr.ts b/packages/astro/src/runtime/ssr.ts
index af576ac77..26fc3964e 100644
--- a/packages/astro/src/runtime/ssr.ts
+++ b/packages/astro/src/runtime/ssr.ts
@@ -1,15 +1,19 @@
import cheerio from 'cheerio';
import * as eslexer from 'es-module-lexer';
import type { ViteDevServer } from 'vite';
-import type { ComponentInstance, GetStaticPathsResult, Params, Props, RouteCache, RouteData, RuntimeMode } from '../@types/astro';
+import type { ComponentInstance, GetStaticPathsResult, Params, Props, RouteCache, RouteData, RuntimeMode, AstroConfig } from '../@types/astro';
import type { LogOptions } from '../logger';
import { fileURLToPath } from 'url';
+import path from 'path';
import { generatePaginateFunction } from './paginate.js';
import { getParams, validateGetStaticPathsModule, validateGetStaticPathsResult } from './routing.js';
-import { canonicalURL, parseNpmName } from './util.js';
+import { parseNpmName, canonicalURL as getCanonicalURL } from './util.js';
+import type { AstroComponent, AstroComponentFactory } from '../internal';
interface SSROptions {
+ /** an instance of the AstroConfig */
+ astroConfig: AstroConfig,
/** location of file on disk */
filePath: URL;
/** logging options */
@@ -32,11 +36,129 @@ interface SSROptions {
// this prevents client-side errors such as the "double React bug" (https://reactjs.org/warnings/invalid-hook-call-warning.html#mismatching-versions-of-react-and-react-dom)
let browserHash: string | undefined;
+export async function renderAstroComponent(component: InstanceType) {
+ let template = '';
+
+ for await (const value of component) {
+ if (value || value === 0) {
+ template += value;
+ }
+ }
+
+ return template;
+}
+
+export async function renderToString(result: any, componentFactory: AstroComponentFactory, props: any, children: any) {
+ const Component = componentFactory(result, props, children);
+ let template = await renderAstroComponent(Component);
+ return template
+}
+
+async function renderPage(result: any, Component: AstroComponentFactory, props: any, children: any) {
+ const template = await renderToString(result, Component, props, children);
+ const styles = Array.from(result.styles).map(style => ``);
+ const scripts = Array.from(result.scripts);
+ return template.replace("", styles.join('\n') + scripts.join('\n') + "");
+}
+
+const cache = new Map();
+
+// TODO: improve validation and error handling here.
+async function resolveRenderers(viteServer: ViteDevServer, ids: string[]) {
+ const resolve = viteServer.config.createResolver();
+ const renderers = await Promise.all(ids.map(async renderer => {
+ if (cache.has(renderer)) return cache.get(renderer);
+ const resolvedRenderer: any = {};
+
+ // We can dynamically import the renderer by itself because it shouldn't have
+ // any non-standard imports, the index is just meta info.
+ // The other entrypoints need to be loaded through Vite.
+ const { default: instance } = await import(renderer);
+
+ // This resolves the renderer's entrypoints to a final URL through Vite
+ const getPath = async (src: string) => {
+ const spec = path.posix.join(instance.name, src);
+ const resolved = await resolve(spec);
+ if (!resolved) {
+ throw new Error(`Unable to resolve "${spec}" to a package!`)
+ }
+ return resolved;
+ }
+
+ resolvedRenderer.name = instance.name;
+ if (instance.client) {
+ resolvedRenderer.source = await getPath(instance.client);
+ }
+ if (Array.isArray(instance.hydrationPolyfills)) {
+ resolvedRenderer.hydrationPolyfills = await Promise.all(instance.hydrationPolyfills.map((src: string) => getPath(src)));
+ }
+ if (Array.isArray(instance.polyfills)) {
+ resolvedRenderer.polyfills = await Promise.all(instance.polyfills.map((src: string) => getPath(src)));
+ }
+
+ const { url } = await viteServer.moduleGraph.ensureEntryFromUrl(await getPath(instance.server));
+ const { default: server } = await viteServer.ssrLoadModule(url);
+ resolvedRenderer.ssr = server;
+
+ cache.set(renderer, resolvedRenderer);
+ return resolvedRenderer
+ }));
+
+ return renderers;
+}
+
+async function resolveImportedModules(viteServer: ViteDevServer, file: string) {
+ const { url } = await viteServer.moduleGraph.ensureEntryFromUrl(file);
+ const modulesByFile = viteServer.moduleGraph.getModulesByFile(url);
+ if (!modulesByFile) {
+ return {};
+ }
+
+ let importedModules: Record = {};
+ const moduleNodes = Array.from(modulesByFile);
+
+ // Loop over the importedModules and grab the exports from each one.
+ // We'll pass these to the shared $$result so renderers can match
+ // components to their exported identifier and URL
+ // NOTE: Important that this is parallelized as much as possible!
+ await Promise.all(moduleNodes.map(moduleNode => {
+ const entries = Array.from(moduleNode.importedModules);
+
+ return Promise.all(entries.map(entry => {
+ // Skip our internal import that every module will have
+ if (entry.id?.endsWith('astro/dist/internal/index.js')) {
+ return;
+ }
+
+ return viteServer.moduleGraph.ensureEntryFromUrl(entry.url).then(mod => {
+ if (mod.ssrModule) {
+ importedModules[mod.url] = mod.ssrModule;
+ return;
+ } else {
+ return viteServer.ssrLoadModule(mod.url).then(result => {
+ importedModules[mod.url] = result.ssrModule;
+ return;
+ })
+ }
+ })
+ }))
+ }))
+
+ return importedModules
+}
+
/** use Vite to SSR */
-export async function ssr({ filePath, logging, mode, origin, pathname, route, routeCache, viteServer }: SSROptions): Promise {
+export async function ssr({ astroConfig, filePath, logging, mode, origin, pathname, route, routeCache, viteServer }: SSROptions): Promise {
// 1. load module
const mod = (await viteServer.ssrLoadModule(fileURLToPath(filePath))) as ComponentInstance;
+ // 1.5. resolve renderers and imported modules.
+ // important that this happens _after_ ssrLoadModule, otherwise `importedModules` would be empty
+ const [renderers, importedModules] = await Promise.all([
+ resolveRenderers(viteServer, astroConfig.renderers),
+ resolveImportedModules(viteServer, fileURLToPath(filePath))
+ ]);
+
// 2. handle dynamic routes
let params: Params = {};
let pageProps: Props = {};
@@ -68,24 +190,34 @@ export async function ssr({ filePath, logging, mode, origin, pathname, route, ro
// 3. render page
if (!browserHash && (viteServer as any)._optimizeDepsMetadata?.browserHash) browserHash = (viteServer as any)._optimizeDepsMetadata.browserHash; // note: this is "private" and may change over time
const fullURL = new URL(pathname, origin);
- if (!mod.__renderPage) throw new Error(`__renderPage() undefined (${route?.component})`);
- let html = await mod.__renderPage({
- request: {
- params,
- url: fullURL,
- canonicalURL: canonicalURL(fullURL.pathname, fullURL.origin),
+
+ const Component = await mod.default;
+ if (!Component)
+ throw new Error(`Expected an exported Astro component but recieved typeof ${typeof Component}`);
+ if (!Component.isAstroComponentFactory) throw new Error(`Unable to SSR non-Astro component (${route?.component})`);
+
+ let html = await renderPage({
+ styles: new Set(),
+ scripts: new Set(),
+ /** This function returns the `Astro` faux-global */
+ createAstro(props: any) {
+ const site = new URL(origin);
+ const url = new URL('.' + pathname, site);
+ const canonicalURL = getCanonicalURL(pathname, astroConfig.buildOptions.site || origin)
+ return { isPage: true, site, request: { url, canonicalURL }, props };
},
- children: [],
- props: pageProps,
- css: mod.css || [],
- });
+ _metadata: { importedModules, renderers },
+ }, Component, { }, null);
// 4. modify response
- // inject Vite HMR code (dev only)
- if (mode === 'development') html = injectViteClient(html);
-
- // replace client hydration scripts
- if (mode === 'development') html = resolveNpmImports(html);
+ if (mode === 'development') {
+ // inject Astro HMR code
+ html = injectAstroHMR(html);
+ // inject Vite HMR code
+ html = injectViteClient(html);
+ // replace client hydration scripts
+ html = resolveNpmImports(html);
+ }
// 5. finish
return html;
@@ -96,6 +228,11 @@ function injectViteClient(html: string): string {
return html.replace('', ``);
}
+/** Injects Astro HMR client code */
+function injectAstroHMR(html: string): string {
+ return html.replace('', ``);
+}
+
/** Convert npm specifier into Vite URL */
function resolveViteNpmPackage(spec: string): string {
const pkg = parseNpmName(spec);
diff --git a/packages/astro/src/runtime/vite/config.ts b/packages/astro/src/runtime/vite/config.ts
index 69e7d800e..f5828ccde 100644
--- a/packages/astro/src/runtime/vite/config.ts
+++ b/packages/astro/src/runtime/vite/config.ts
@@ -10,6 +10,7 @@ import { createRequire } from 'module';
import { getPackageJSON, parseNpmName } from '../util.js';
import astro from './plugin-astro.js';
import jsx from './plugin-jsx.js';
+import { AstroDevServer } from '../../dev';
const require = createRequire(import.meta.url);
@@ -17,7 +18,7 @@ const require = createRequire(import.meta.url);
type ViteConfigWithSSR = InlineConfig & { ssr?: { external?: string[]; noExternal?: string[] } };
/** Return a common starting point for all Vite actions */
-export async function loadViteConfig(viteConfig: ViteConfigWithSSR, { astroConfig, logging }: { astroConfig: AstroConfig; logging: LogOptions }): Promise {
+export async function loadViteConfig(viteConfig: ViteConfigWithSSR, { astroConfig, logging, devServer }: { astroConfig: AstroConfig; logging: LogOptions, devServer?: AstroDevServer }): Promise {
const optimizedDeps = new Set(); // dependencies that must be bundled for the client (Vite may not detect all of these)
const dedupe = new Set(); // dependencies that can’t be duplicated (e.g. React & SolidJS)
const plugins: Plugin[] = []; // Vite plugins
@@ -73,7 +74,7 @@ export async function loadViteConfig(viteConfig: ViteConfigWithSSR, { astroConfi
/** Always include these dependencies for optimization */
include: [...optimizedDeps],
},
- plugins: [astro(astroConfig), jsx({ config: astroConfig, logging }), ...plugins],
+ plugins: [astro({ config: astroConfig, devServer }), jsx({ config: astroConfig, logging }), ...plugins],
publicDir: fileURLToPath(astroConfig.public),
resolve: {
dedupe: [...dedupe],
@@ -82,6 +83,8 @@ export async function loadViteConfig(viteConfig: ViteConfigWithSSR, { astroConfi
server: {
/** prevent serving outside of project root (will become new default soon) */
fs: { strict: true },
+ /** disable HMR for test */
+ hmr: process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'production' ? false : undefined,
/** handle Vite URLs */
proxy: {
// add proxies here
diff --git a/packages/astro/src/runtime/vite/plugin-astro.ts b/packages/astro/src/runtime/vite/plugin-astro.ts
index 052ec7e31..a7996ae4d 100644
--- a/packages/astro/src/runtime/vite/plugin-astro.ts
+++ b/packages/astro/src/runtime/vite/plugin-astro.ts
@@ -1,58 +1,36 @@
import type { Plugin } from 'vite';
import type { AstroConfig, Renderer } from '../../@types/astro.js';
+import type { LogOptions } from '../../logger';
-import { camelCase } from 'camel-case';
+import esbuild from 'esbuild';
import fs from 'fs';
-import { fileURLToPath } from 'url';
-import { markdownToH } from '../markdown.js';
+import { transform } from '@astrojs/compiler';
+import { AstroDevServer } from '../../dev/index.js';
+
+interface AstroPluginOptions {
+ config: AstroConfig;
+ devServer?: AstroDevServer;
+}
/** Transform .astro files for Vite */
-export default function astro(config: AstroConfig): Plugin {
+export default function astro({ devServer }: AstroPluginOptions): Plugin {
return {
name: '@astrojs/vite-plugin-astro',
enforce: 'pre', // run transforms before other plugins can
// note: don’t claim .astro files with resolveId() — it prevents Vite from transpiling the final JS (import.meta.globEager, etc.)
async load(id) {
if (id.endsWith('.astro') || id.endsWith('.md')) {
- // TODO: replace with compiler
- let code = await fs.promises.readFile(id, 'utf8');
- return {
- code: code,
- map: null,
- };
- }
- // inject renderers (TODO: improve this?)
- if (id.endsWith('runtime/__astro_component.js')) {
- let code = await fs.promises.readFile(id, 'utf8');
- let rendererCode = '';
+ let source = await fs.promises.readFile(id, 'utf8');
- // add imports
- config.renderers.forEach((name) => {
- rendererCode += `import ${jsRef(name)} from '${name}';
-import ${jsRef(name, '_ssr')} from '${name}/server';
-`;
- });
+ // 1. Transform from `.astro` to valid `.ts`
+ const tsResult = await transform(source, { sourcefile: id });
- // initialize renderers
- rendererCode += `
-function initRenderer(name, entry, ssr) {
- const join = (...parts) => parts.map((part) => part.replace(/^\\./, '')).join('');
- const renderer = {};
- renderer.name = name;
- renderer.ssr = ssr;
- if (entry.client) renderer.source = join(name, entry.client);
- if (Array.isArray(entry.hydrationPolyfills)) renderer.hydrationPolyfills = entry.hydrationPolyfills.map((src) => join(name, src));
- if (Array.isArray(entry.polyfills)) renderer.polyfills = entry.polyfills.map((src) => join(name, src));
- return renderer;
-}
-let rendererInstances = [
- ${config.renderers.map((name) => `initRenderer('${name}', ${jsRef(name)}, ${jsRef(name, '_ssr')})`).join(',\n')}
-];
-`;
+ // 2. Compile `.ts` to `.js`
+ const { code, map } = await esbuild.transform(tsResult, { loader: 'ts', sourcemap: 'inline', sourcefile: id });
return {
- code: rendererCode + code,
- map: null,
+ code,
+ map,
};
}
@@ -64,34 +42,10 @@ let rendererInstances = [
// }
return null;
},
- async handleHotUpdate({ file, modules, timestamp, server, read }) {
- // invalidate module
- const module = server.moduleGraph.getModuleById(file);
- if (module) server.moduleGraph.invalidateModule(module);
-
- try {
- const {
- default: { __render: render },
- } = await server.ssrLoadModule(file);
- const html = await render();
- server.ws.send({
- type: 'custom',
- event: 'astro:reload',
- data: {
- html,
- },
- });
- } catch (e) {
- server.ws.send({
- type: 'full-reload',
- });
+ async handleHotUpdate(context) {
+ if (devServer) {
+ return devServer.handleHotUpdate(context);
}
- return [];
},
};
}
-
-/** Given any string (e.g. npm package name), generate a JS-friendly ref */
-function jsRef(name: string, suffix = ''): string {
- return `__${camelCase(name)}${suffix}`;
-}
diff --git a/packages/astro/test/astro-assets.test.js b/packages/astro/test/astro-assets.test.js
index 52890dcf6..f1d78986c 100644
--- a/packages/astro/test/astro-assets.test.js
+++ b/packages/astro/test/astro-assets.test.js
@@ -1,20 +1,22 @@
-import { suite } from 'uvu';
-import * as assert from 'uvu/assert';
-import build from '../dist/build/index.js';
+import { loadFixture } from './test-utils';
-const Assets = suite('Assets');
+let fixture;
-await build({ projectRoot: 'test/fixtures/astro-assets/' });
+describe('Assets', () => {
+ beforeAll(async () => {
+ fixture = await loadFixture({ projectRoot: './fixtures/astro-assets/' });
+ await fixture.build();
+ });
-Assets('build the base image', () => {});
+ test('built the base image', async () => {
+ await fixture.readFile('/images/twitter.png');
+ });
-// let oneX = await readFile('/_astro/src/images/twitter.png');
-// assert.ok(oneX, 'built the base image');
+ test('built the 2x image', async () => {
+ await fixture.readFile('/images/twitter@2x.png');
+ });
-// let twoX = await readFile('/_astro/src/images/twitter@2x.png');
-// assert.ok(twoX, 'built the 2x image');
-
-// let threeX = await readFile('/_astro/src/images/twitter@3x.png');
-// assert.ok(threeX, 'build the 3x image');
-
-Assets.run();
+ test('built the 3x image', async () => {
+ await fixture.readFile('/images/twitter@3x.png');
+ });
+});
diff --git a/packages/astro/test/astro-attrs.test.js b/packages/astro/test/astro-attrs.test.js
index 7db6e7239..f9dccccdd 100644
--- a/packages/astro/test/astro-attrs.test.js
+++ b/packages/astro/test/astro-attrs.test.js
@@ -1,59 +1,62 @@
-import { suite } from 'uvu';
-import * as assert from 'uvu/assert';
-import { doc } from './test-utils.js';
-import { setup } from './helpers.js';
+import cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
-const Attributes = suite('Attributes test');
+let fixture;
+let devServer;
-setup(Attributes, './fixtures/astro-attrs');
+describe('Attributes', () => {
+ beforeAll(async () => {
+ fixture = await loadFixture({ projectRoot: './fixtures/astro-attrs/' });
+ devServer = await fixture.dev();
+ });
-Attributes('Passes attributes to elements as expected', async ({ runtime }) => {
- const result = await runtime.load('/');
- assert.ok(!result.error, `build error: ${result.error}`);
+ test('Passes attributes to elements as expected', async () => {
+ const html = await fixture.fetch('/').then((res) => res.html());
+ const $ = cheerio.load(html);
- const $ = doc(result.contents);
+ const attrs = {
+ 'false-str': 'false',
+ 'true-str': 'true',
+ false: undefined,
+ true: '',
+ empty: '',
+ null: undefined,
+ undefined: undefined,
+ };
- const ids = ['false-str', 'true-str', 'false', 'true', 'empty', 'null', 'undefined'];
- const specs = ['false', 'true', undefined, '', '', undefined, undefined];
+ for (const [k, v] of Object.entries(attrs)) {
+ const attr = $(`#${k}`).attr('attr');
+ expect(attr).toBe(v);
+ }
+ });
- let i = 0;
- for (const id of ids) {
- const spec = specs[i];
- const attr = $(`#${id}`).attr('attr');
- assert.equal(attr, spec, `Passes ${id} as "${spec}"`);
- i++;
- }
+ test('Passes boolean attributes to components as expected', async () => {
+ const html = await fixture.fetch('/component').then((res) => res.text());
+ const $ = cheerio.load(html);
+
+ expect($('#true').attr('attr')).toBe('attr-true');
+ expect($('#true').attr('type')).toBe('boolean');
+ expect($('#false').attr('attr')).toBe('attr-false');
+ expect($('#false').attr('type')).toBe('boolean');
+ });
+
+ test('Passes namespaced attributes as expected', async () => {
+ const html = await fixture.fetch('/namespaced').then((res) => res.text());
+ const $ = cheerio.load(result.contents);
+
+ expect($('div').attr('xmlns:happy')).toBe('https://example.com/schemas/happy');
+ expect($('img').attr('happy:smile')).toBe('sweet');
+ });
+
+ test('Passes namespaced attributes to components as expected', async () => {
+ const html = await fixture.fetch('/namespaced-component');
+ const $ = cheerio.load(html);
+
+ expect($('span').attr('on:click')).toEqual(Function.prototype.toString.call((event) => console.log(event)));
+ });
+
+ // important: close dev server (free up port and connection)
+ afterAll(async () => {
+ await devServer.close();
+ });
});
-
-Attributes('Passes boolean attributes to components as expected', async ({ runtime }) => {
- const result = await runtime.load('/component');
- assert.ok(!result.error, `build error: ${result.error}`);
-
- const $ = doc(result.contents);
- assert.equal($('#true').attr('attr'), 'attr-true');
- assert.equal($('#true').attr('type'), 'boolean');
- assert.equal($('#false').attr('attr'), 'attr-false');
- assert.equal($('#false').attr('type'), 'boolean');
-});
-
-Attributes('Passes namespaced attributes as expected', async ({ runtime }) => {
- const result = await runtime.load('/namespaced');
- assert.ok(!result.error, `build error: ${result.error}`);
-
- const $ = doc(result.contents);
- assert.equal($('div').attr('xmlns:happy'), 'https://example.com/schemas/happy');
- assert.equal($('img').attr('happy:smile'), 'sweet');
-});
-
-Attributes('Passes namespaced attributes to components as expected', async ({ runtime }) => {
- const result = await runtime.load('/namespaced-component');
- assert.ok(!result.error, `build error: ${result.error}`);
-
- const $ = doc(result.contents);
- assert.equal(
- $('span').attr('on:click'),
- Function.prototype.toString.call((event) => console.log(event))
- );
-});
-
-Attributes.run();
diff --git a/packages/astro/test/astro-basic.test.js b/packages/astro/test/astro-basic.test.js
index 164db697b..e56337099 100644
--- a/packages/astro/test/astro-basic.test.js
+++ b/packages/astro/test/astro-basic.test.js
@@ -1,123 +1,109 @@
-import { suite } from 'uvu';
-import http from 'http';
-import { promisify } from 'util';
-import * as assert from 'uvu/assert';
-import { doc } from './test-utils.js';
-import { setup, setupBuild, setupPreview } from './helpers.js';
+import cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
-const Basics = suite('Basic test');
+describe('Astro basics', () => {
+ describe('dev', () => {
+ let fixture; // fixture #1. Note that .dev() and .preview() share a port, so these fixtures must be kept separate.
+ let devServer;
-setup(Basics, './fixtures/astro-basic', {
- runtimeOptions: {
- mode: 'development',
- },
-});
-setupBuild(Basics, './fixtures/astro-basic');
-setupPreview(Basics, './fixtures/astro-basic');
+ beforeAll(async () => {
+ fixture = await loadFixture({ projectRoot: './fixtures/astro-basic/' });
+ devServer = await fixture.dev();
+ });
-Basics('Can load page', async ({ runtime }) => {
- const result = await runtime.load('/');
- assert.ok(!result.error, `build error: ${result.error}`);
+ test('Can load page', async () => {
+ const html = await fixture.fetch(`/`).then((res) => res.text());
+ const $ = cheerio.load(html);
- const $ = doc(result.contents);
+ expect($('h1').text()).toBe('Hello world!');
+ });
- assert.equal($('h1').text(), 'Hello world!');
-});
+ test('Correctly serializes boolean attributes', async () => {
+ const html = await fixture.fetch('/').then((res) => res.text());
+ const $ = cheerio.load(html);
-Basics('Sets the HMR port when dynamic components used', async ({ runtime }) => {
- const result = await runtime.load('/client');
- const html = result.contents;
- assert.ok(/HMR_WEBSOCKET_PORT/.test(html), 'Sets the websocket port');
-});
+ expect($('h1').attr('data-something')).toBe('');
+ expect($('h2').attr('not-data-ok')).toBe('');
+ });
-Basics('Correctly serializes boolean attributes', async ({ runtime }) => {
- const result = await runtime.load('/');
- const html = result.contents;
- const $ = doc(html);
- assert.equal($('h1').attr('data-something'), '');
- assert.equal($('h2').attr('not-data-ok'), '');
-});
+ test('Selector with an empty body', async () => {
+ const html = await fixture.fetch('/empty-class').then((res) => res.text());
+ const $ = cheerio.load(html);
-Basics('Selector with an empty body', async ({ runtime }) => {
- const result = await runtime.load('/empty-class');
- const html = result.contents;
- const $ = doc(html);
- assert.equal($('.author').length, 1, 'author class added');
-});
+ expect($('.author')).toHaveLength(1);
+ });
-Basics('Build does not include HMR client', async ({ build, readFile }) => {
- await build().catch((err) => {
- assert.ok(!err, 'Error during the build');
+ test('Allows forward-slashes in mustache tags (#407)', async () => {
+ const html = await fixture.fetch('/forward-slash').then((res) => res.text());
+ const $ = cheerio.load(html);
+
+ expect($('a[href="/post/one"]')).toHaveLength(1);
+ expect($('a[href="/post/two"]')).toHaveLength(1);
+ expect($('a[href="/post/three"]')).toHaveLength(1);
+ });
+
+ test('Allows spread attributes (#521)', async () => {
+ const html = await fixture.fetch('/spread').then((res) => res.text());
+ const $ = cheerio.load(html);
+
+ expect($('#spread-leading')).toHaveLength(1);
+ expect($('#spread-leading').attr('a')).toBe('0');
+ expect($('#spread-leading').attr('b')).toBe('1');
+ expect($('#spread-leading').attr('c')).toBe('2');
+
+ expect($('#spread-trailing')).toHaveLength(1);
+ expect($('#spread-trailing').attr('a')).toBe('0');
+ expect($('#spread-trailing').attr('b')).toBe('1');
+ expect($('#spread-trailing').attr('c')).toBe('2');
+ });
+
+ test('Allows spread attributes with TypeScript (#521)', async () => {
+ const html = await fixture.fetch('/spread').then((res) => res.text());
+ const $ = cheerio.load(html);
+
+ expect($('#spread-ts')).toHaveLength(1);
+ expect($('#spread-ts').attr('a')).toBe('0');
+ expect($('#spread-ts').attr('b')).toBe('1');
+ expect($('#spread-ts').attr('c')).toBe('2');
+ });
+
+ test('Allows using the Fragment element to be used', async () => {
+ const html = await fixture.fetch('/fragment').then((res) => res.text());
+ const $ = cheerio.load(html);
+
+ // will be 1 if element rendered correctly
+ expect($('#one')).toHaveLength(1);
+ });
+
+ // important: close dev server (free up port and connection)
+ afterAll(async () => {
+ await devServer.stop();
+ });
});
- const clientHTML = await readFile('/client/index.html');
- const $ = doc(clientHTML);
- assert.equal($('script[src="/_snowpack/hmr-client.js"]').length, 0, 'No HMR client script');
- const hmrPortScript = $('script').filter((i, el) => {
- return $(el)
- .text()
- .match(/window\.HMR_WEBSOCKET_PORT/);
+ describe('preview', () => {
+ let fixture; // fixture #2. Note that .dev() and .preview() share a port, so these fixtures must be kept separate.
+ let previewServer;
+
+ beforeAll(async () => {
+ fixture = await loadFixture({ projectRoot: './fixtures/astro-basic' });
+ await fixture.build();
+ previewServer = await fixture.preview();
+ });
+
+ test('returns 200 for valid URLs', async () => {
+ const result = fixture.fetch('/');
+ expect(result.statusCode).toBe(200);
+ });
+
+ test('returns 404 for invalid URLs', async () => {
+ const result = fixture.fetch('/bad-url');
+ expect(result.statusCode).toBe(404);
+ });
+
+ // important: close preview server (free up port and connection)
+ afterAll(() => {
+ previewServer.close();
+ });
});
- assert.equal(hmrPortScript.length, 0, 'No script setting the websocket port');
});
-
-Basics('Preview server works as expected', async ({ build, previewServer }) => {
- await build().catch((err) => {
- assert.ok(!err, 'Error during the build');
- });
- {
- const resultOrError = await promisify(http.get)(`http://localhost:${previewServer.address().port}/`).catch((err) => err);
- assert.equal(resultOrError.statusCode, 200);
- }
- {
- const resultOrError = await promisify(http.get)(`http://localhost:${previewServer.address().port}/bad-url`).catch((err) => err);
- assert.equal(resultOrError.statusCode, 404);
- }
-});
-
-Basics('Allows forward-slashes in mustache tags (#407)', async ({ runtime }) => {
- const result = await runtime.load('/forward-slash');
- const html = result.contents;
- const $ = doc(html);
-
- assert.equal($('a[href="/post/one"]').length, 1);
- assert.equal($('a[href="/post/two"]').length, 1);
- assert.equal($('a[href="/post/three"]').length, 1);
-});
-
-Basics('Allows spread attributes (#521)', async ({ runtime }) => {
- const result = await runtime.load('/spread');
- const html = result.contents;
- const $ = doc(html);
-
- assert.equal($('#spread-leading').length, 1);
- assert.equal($('#spread-leading').attr('a'), '0');
- assert.equal($('#spread-leading').attr('b'), '1');
- assert.equal($('#spread-leading').attr('c'), '2');
-
- assert.equal($('#spread-trailing').length, 1);
- assert.equal($('#spread-trailing').attr('a'), '0');
- assert.equal($('#spread-trailing').attr('b'), '1');
- assert.equal($('#spread-trailing').attr('c'), '2');
-});
-
-Basics('Allows spread attributes with TypeScript (#521)', async ({ runtime }) => {
- const result = await runtime.load('/spread');
- const html = result.contents;
- const $ = doc(html);
-
- assert.equal($('#spread-ts').length, 1);
- assert.equal($('#spread-ts').attr('a'), '0');
- assert.equal($('#spread-ts').attr('b'), '1');
- assert.equal($('#spread-ts').attr('c'), '2');
-});
-
-Basics('Allows using the Fragment element to be used', async ({ runtime }) => {
- const result = await runtime.load('/fragment');
- assert.ok(!result.error, 'No errors thrown');
- const html = result.contents;
- const $ = doc(html);
- assert.equal($('#one').length, 1, 'Element in a fragment rendered');
-});
-
-Basics.run();
diff --git a/packages/astro/test/astro-children.test.js b/packages/astro/test/astro-children.test.js
index 9bacbd217..05f11be9c 100644
--- a/packages/astro/test/astro-children.test.js
+++ b/packages/astro/test/astro-children.test.js
@@ -1,75 +1,81 @@
-import { suite } from 'uvu';
-import * as assert from 'uvu/assert';
-import { doc } from './test-utils.js';
-import { setup, setupBuild } from './helpers.js';
+import cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
-const ComponentChildren = suite('Component children tests');
+describe('Component children', () => {
+ let fixture;
+ let devServer;
-setup(ComponentChildren, './fixtures/astro-children');
-setupBuild(ComponentChildren, './fixtures/astro-children');
+ beforeAll(async () => {
+ fixture = await loadFixture({
+ projectRoot: './fixtures/astro-children/',
+ renderers: ['@astrojs/renderer-preact', '@astrojs/renderer-vue', '@astrojs/renderer-svelte'],
+ });
+ devServer = await fixture.dev();
+ });
-ComponentChildren('Passes string children to framework components', async ({ runtime }) => {
- let result = await runtime.load('/strings');
- assert.ok(!result.error, `build error: ${result.error}`);
+ test('Passes string children to framework components', async () => {
+ const html = await fixture.fetch('/strings').then((res) => res.text());
+ const $ = cheerio.load(html);
- const $ = doc(result.contents);
+ // test 1: Can pass text to Preact components
+ const $preact = $('#preact');
+ expect($preact.text().trim()).toBe('Hello world');
- const $preact = $('#preact');
- assert.equal($preact.text().trim(), 'Hello world', 'Can pass text to Preact components');
+ // test 2: Can pass text to Vue components
+ const $vue = $('#vue');
+ expect($vue.text().trim()).toBe('Hello world');
- const $vue = $('#vue');
- assert.equal($vue.text().trim(), 'Hello world', 'Can pass text to Vue components');
+ // test 3: Can pass text to Svelte components
+ const $svelte = $('#svelte');
+ expect($svelte.text().trim()).toBe('Hello world');
+ });
- const $svelte = $('#svelte');
- assert.equal($svelte.text().trim(), 'Hello world', 'Can pass text to Svelte components');
+ test('Passes markup children to framework components', async () => {
+ const html = await fixture.fetch('/markup').then((res) => res.text());
+ const $ = cheerio.load(html);
+
+ // test 1: Can pass markup to Preact components
+ const $preact = $('#preact h1');
+ expect($preact.text().trim()).toBe('Hello world');
+
+ // test 2: Can pass markup to Vue components
+ const $vue = $('#vue h1');
+ expect($vue.text().trim()).toBe('Hello world');
+
+ // test 3: Can pass markup to Svelte components
+ const $svelte = $('#svelte h1');
+ expect($svelte.text().trim()).toBe('Hello world');
+ });
+
+ test('Passes multiple children to framework components', async () => {
+ const html = await fixture.fetch('/multiple').then((res) => res.text());
+ const $ = cheerio.load(html);
+
+ // test 1: Can pass multiple children to Preact components
+ const $preact = $('#preact');
+ expect($preact.children()).toHaveLength(2);
+ expect($preact.children(':first-child').text().trim()).toBe('Hello world');
+ expect($preact.children(':last-child').text().trim()).toBe('Goodbye world');
+
+ // test 2: Can pass multiple children to Vue components
+ const $vue = $('#vue');
+ expect($vue.children()).toHaveLength(2);
+ expect($vue.children(':first-child').text().trim()).toBe('Hello world');
+ expect($vue.children(':last-child').text().trim()).toBe('Goodbye world');
+
+ // test 3: Can pass multiple children to Svelte components
+ const $svelte = $('#svelte');
+ expect($svelte.children()).toHaveLength(2);
+ expect($svelte.children(':first-child').text().trim()).toBe('Hello world');
+ expect($svelte.children(':last-child').text().trim()).toBe('Goodbye world');
+ });
+
+ test('Can build a project with component children', async () => {
+ expect(() => fixture.build()).not.toThrow();
+ });
+
+ // important: close dev server (free up port and connection)
+ afterAll(async () => {
+ await devServer.close();
+ });
});
-
-ComponentChildren('Passes markup children to framework components', async ({ runtime }) => {
- let result = await runtime.load('/markup');
- assert.ok(!result.error, `build error: ${result.error}`);
-
- const $ = doc(result.contents);
-
- const $preact = $('#preact h1');
- assert.equal($preact.text().trim(), 'Hello world', 'Can pass markup to Preact components');
-
- const $vue = $('#vue h1');
- assert.equal($vue.text().trim(), 'Hello world', 'Can pass markup to Vue components');
-
- const $svelte = $('#svelte h1');
- assert.equal($svelte.text().trim(), 'Hello world', 'Can pass markup to Svelte components');
-});
-
-ComponentChildren('Passes multiple children to framework components', async ({ runtime }) => {
- let result = await runtime.load('/multiple');
- assert.ok(!result.error, `build error: ${result.error}`);
-
- const $ = doc(result.contents);
-
- const $preact = $('#preact');
- assert.equal($preact.children().length, 2, 'Can pass multiple children to Preact components');
- assert.equal($preact.children(':first-child').text().trim(), 'Hello world');
- assert.equal($preact.children(':last-child').text().trim(), 'Goodbye world');
-
- const $vue = $('#vue');
- assert.equal($vue.children().length, 2, 'Can pass multiple children to Vue components');
- assert.equal($vue.children(':first-child').text().trim(), 'Hello world');
- assert.equal($vue.children(':last-child').text().trim(), 'Goodbye world');
-
- const $svelte = $('#svelte');
- assert.equal($svelte.children().length, 2, 'Can pass multiple children to Svelte components');
- assert.equal($svelte.children(':first-child').text().trim(), 'Hello world');
- assert.equal($svelte.children(':last-child').text().trim(), 'Goodbye world');
-});
-
-ComponentChildren('Can be built', async ({ build }) => {
- try {
- await build();
- assert.ok(true, 'Can build a project with component children');
- } catch (err) {
- console.log(err);
- assert.ok(false, 'build threw');
- }
-});
-
-ComponentChildren.run();
diff --git a/packages/astro/test/astro-client-only.test.js b/packages/astro/test/astro-client-only.test.js
index 1c4534807..c3b2cc577 100644
--- a/packages/astro/test/astro-client-only.test.js
+++ b/packages/astro/test/astro-client-only.test.js
@@ -1,44 +1,43 @@
-import { suite } from 'uvu';
-import * as assert from 'uvu/assert';
-import { setup, setupBuild } from './helpers.js';
+import cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
-const ClientOnlyComponents = suite('Client only components tests');
+describe('Client only components', () => {
+ let fixture;
+ let devServer;
-setup(ClientOnlyComponents, './fixtures/astro-client-only');
-setupBuild(ClientOnlyComponents, './fixtures/astro-client-only');
+ beforeAll(async () => {
+ fixture = await loadFixture({ projectRoot: './fixtures/astro-client-only/' });
+ devServer = await fixture.dev();
+ });
-ClientOnlyComponents('Loads pages using client:only hydrator', async ({ runtime }) => {
- let result = await runtime.load('/');
- assert.ok(!result.error, `build error: ${result.error}`);
+ test('Loads pages using client:only hydrator', async () => {
+ const html = await fixture.fetch('/').then((res) => res.html());
+ const $ = cheerio.load(html);
- let html = result.contents;
+ // test 1: is empty
+ expect($('astro-root').html()).toBe('');
- const rootExp = /]*><\/astro-root>/;
- assert.ok(rootExp.exec(html), 'astro-root is empty');
-
- // Grab the svelte import
- const exp = /import\("(.+?)"\)/g;
- let match, svelteRenderer;
- while ((match = exp.exec(result.contents))) {
- if (match[1].includes('renderers/renderer-svelte/client.js')) {
- svelteRenderer = match[1];
+ // test 2: svelte renderer is on the page
+ const exp = /import\("(.+?)"\)/g;
+ let match, svelteRenderer;
+ while ((match = exp.exec(result.contents))) {
+ if (match[1].includes('renderers/renderer-svelte/client.js')) {
+ svelteRenderer = match[1];
+ }
}
- }
+ expect(svelteRenderer).toBeTruthy();
- assert.ok(svelteRenderer, 'Svelte renderer is on the page');
+ // test 3: can load svelte renderer
+ result = await fixture.fetch(svelteRenderer);
+ expect(result.statusCode).toBe(200);
+ });
- result = await runtime.load(svelteRenderer);
- assert.equal(result.statusCode, 200, 'Can load svelte renderer');
+ test('Can build a project with svelte dynamic components', async () => {
+ expect(() => fixture.build()).not.toThrow();
+ });
+
+ // important: close dev server (free up port and connection)
+ afterAll(async () => {
+ await devServer.close();
+ });
});
-
-ClientOnlyComponents('Can be built', async ({ build }) => {
- try {
- await build();
- assert.ok(true, 'Can build a project with svelte dynamic components');
- } catch (err) {
- console.log(err);
- assert.ok(false, 'build threw');
- }
-});
-
-ClientOnlyComponents.run();
diff --git a/packages/astro/test/astro-components.test.js b/packages/astro/test/astro-components.test.js
index cc1f6b759..048a21f6e 100644
--- a/packages/astro/test/astro-components.test.js
+++ b/packages/astro/test/astro-components.test.js
@@ -1,53 +1,55 @@
-import { suite } from 'uvu';
-import * as assert from 'uvu/assert';
-import { doc } from './test-utils.js';
-import { setup, setupBuild } from './helpers.js';
+import cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
-const Components = suite('Components tests');
+describe('Components tests', () => {
+ let fixture;
+ let devServer;
-setup(Components, './fixtures/astro-components');
+ beforeAll(async () => {
+ fixture = await loadFixture({ projectRoot: './fixtures/astro-components/' });
+ devServer = await fixture.dev();
+ });
-Components('Astro components are able to render framework components', async ({ runtime }) => {
- let result = await runtime.load('/');
- assert.ok(!result.error, `build error: ${result.error}`);
+ test('Astro components are able to render framework components', async () => {
+ const html = await fixture.fetch('/').then((res) => res.html());
+ const $ = cheerio.load(html);
- const $ = doc(result.contents);
+ // test 1: Renders Astro component
+ const $astro = $('#astro');
+ expect($astro.children()).toHaveLength(3);
- const $astro = $('#astro');
- assert.equal($astro.children().length, 3, 'Renders astro component');
+ // test 2: Renders React component
+ const $react = $('#react');
+ expect($react).not.toHaveLength(0);
- const $react = $('#react');
- assert.not.type($react, 'undefined', 'Renders React component');
+ // test 3: Renders Vue component
+ const $vue = $('#vue');
+ expect($vue).not.toHaveLength(0);
- const $vue = $('#vue');
- assert.not.type($vue, 'undefined', 'Renders Vue component');
+ // test 4: Renders Svelte component
+ const $svelte = $('#svelte');
+ expect($svelte).not.toHaveLength(0);
+ });
- const $svelte = $('#svelte');
- assert.not.type($svelte, 'undefined', 'Renders Svelte component');
+ test('Allows Components defined in frontmatter', async () => {
+ const html = await fixture.fetch('/frontmatter-component').then((res) => res.text());
+ const $ = cheerio.load(html);
+
+ expect($('h1')).toHaveLength(1);
+ });
+
+ test('Still throws an error for undefined components', async () => {
+ const result = await fixture.fetch('/undefined-component');
+ expect(result.statusCode).toBe(500);
+ });
+
+ test('Client attrs not added', async () => {
+ const html = await fixture.fetch('/client').then((res) => res.text());
+ expect(html).not.toEqual(expect.stringMatching(/"client:load": true/));
+ });
+
+ // important: close dev server (free up port and connection)
+ afterAll(async () => {
+ await devServer.close();
+ });
});
-
-Components('Allows Components defined in frontmatter', async ({ runtime }) => {
- const result = await runtime.load('/frontmatter-component');
- const html = result.contents;
- const $ = doc(html);
-
- assert.equal($('h1').length, 1);
-});
-
-Components('Allows variables named props', async ({ runtime }) => {
- const result = await runtime.load('/props-shadowing');
- assert.equal(result.statusCode, 500);
-});
-
-Components('Still throws an error for undefined components', async ({ runtime }) => {
- const result = await runtime.load('/undefined-component');
- assert.equal(result.statusCode, 500);
-});
-
-Components('Svelte component', async ({ runtime }) => {
- const result = await runtime.load('/client');
- const html = result.contents;
- assert.ok(!/"client:load": true/.test(html), 'Client attrs not added');
-});
-
-Components.run();
diff --git a/packages/astro/test/astro-css-bundling.test.js b/packages/astro/test/astro-css-bundling.test.js
index 2ae4db91f..78610116b 100644
--- a/packages/astro/test/astro-css-bundling.test.js
+++ b/packages/astro/test/astro-css-bundling.test.js
@@ -1,11 +1,5 @@
import cheerio from 'cheerio';
-import { suite } from 'uvu';
-import * as assert from 'uvu/assert';
-import { setupBuild } from './helpers.js';
-
-const CSSBundling = suite('CSS Bundling');
-
-setupBuild(CSSBundling, './fixtures/astro-css-bundling');
+import { loadFixture } from './test-utils';
// note: the hashes should be deterministic, but updating the file contents will change hashes
// be careful not to test that the HTML simply contains CSS, because it always will! filename and quanity matter here (bundling).
@@ -18,70 +12,75 @@ const EXPECTED_CSS = {
};
const UNEXPECTED_CSS = ['/_astro/components/nav.css', '../css/typography.css', '../css/colors.css', '../css/page-index.css', '../css/page-one.css', '../css/page-two.css'];
-CSSBundling('Bundles CSS', async (context) => {
- await context.build();
+describe('CSS Bundling', () => {
+ let fixture;
- const builtCSS = new Set();
+ beforeAll(async () => {
+ fixture = await loadFixture({ projectRoot: './fixtures/astro-css-bundling/' });
+ await fixture.build();
+ });
- // for all HTML files…
- for (const [filepath, css] of Object.entries(EXPECTED_CSS)) {
- const html = await context.readFile(filepath);
- const $ = cheerio.load(html);
+ test('Bundles CSS', async () => {
+ const builtCSS = new Set();
- // test 1: assert new bundled CSS is present
- for (const href of css) {
- const link = $(`link[rel="stylesheet"][href^="${href}"]`);
- assert.equal(link.length, 1, 'New bundled CSS is not present');
- builtCSS.add(link.attr('href'));
+ // for all HTML files…
+ for (const [filepath, css] of Object.entries(EXPECTED_CSS)) {
+ const html = await fixture.readFile(filepath);
+ const $ = cheerio.load(html);
+
+ // test 1: assert new bundled CSS is present
+ for (const href of css) {
+ const link = $(`link[rel="stylesheet"][href^="${href}"]`);
+ expect(link).toHaveLength(1);
+ builtCSS.add(link.attr('href'));
+ }
+
+ // test 2: assert old CSS was removed
+ for (const href of UNEXPECTED_CSS) {
+ const link = $(`link[rel="stylesheet"][href="${href}"]`);
+ expect(link).toHaveLength(0);
+ }
+
+ // test 3: preload tags was not removed and attributes was preserved
+ if (filepath === '/preload/index.html') {
+ const stylesheet = $('link[rel="stylesheet"][href^="/_astro/preload/index-"]');
+ const preload = $('link[rel="preload"][href^="/_astro/preload/index-"]');
+ expect(stylesheet[0].attribs.media).toBe('print');
+ expect(preload).toHaveLength(1); // Preload tag was removed
+ }
+
+ // test 4: preload tags was not removed and attributes was preserved
+ if (filepath === '/preload-merge/index.html') {
+ const preload = $('link[rel="preload"]');
+ expect(preload).toHaveLength(1);
+ }
+
+ // test 5: assert all bundled CSS was built and contains CSS
+ for (const url of builtCSS.keys()) {
+ const css = await context.readFile(url);
+ expect(css).toBeTruthy();
+ }
+
+ // test 6: assert ordering is preserved (typography.css before colors.css)
+ const bundledLoc = [...builtCSS].find((k) => k.startsWith('/_astro/common-'));
+ const bundledContents = await context.readFile(bundledLoc);
+ const typographyIndex = bundledContents.indexOf('body{');
+ const colorsIndex = bundledContents.indexOf(':root{');
+ expect(typographyIndex).toBeLessThan(colorsIndex);
+
+ // test 7: assert multiple style blocks were bundled (Nav.astro includes 2 scoped style blocks)
+ const scopedNavStyles = [...bundledContents.matchAll('.nav.astro-')];
+ expect(scopedNavStyles).toHaveLength(2);
+
+ // test 8: assert
Icons
-
-
+
-
-
-
-
\ No newline at end of file
+
diff --git a/packages/astro/test/fixtures/astro-attrs/snowpack.config.json b/packages/astro/test/fixtures/astro-attrs/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-attrs/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-basic/snowpack.config.json b/packages/astro/test/fixtures/astro-basic/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-basic/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-children/astro.config.mjs b/packages/astro/test/fixtures/astro-children/astro.config.mjs
deleted file mode 100644
index 2de93dc60..000000000
--- a/packages/astro/test/fixtures/astro-children/astro.config.mjs
+++ /dev/null
@@ -1,7 +0,0 @@
-export default {
- renderers: [
- '@astrojs/renderer-preact',
- '@astrojs/renderer-vue',
- '@astrojs/renderer-svelte',
- ],
-};
diff --git a/packages/astro/test/fixtures/astro-children/snowpack.config.json b/packages/astro/test/fixtures/astro-children/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-children/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-client-only/astro.config.mjs b/packages/astro/test/fixtures/astro-client-only/astro.config.mjs
deleted file mode 100644
index 7e94b713a..000000000
--- a/packages/astro/test/fixtures/astro-client-only/astro.config.mjs
+++ /dev/null
@@ -1,8 +0,0 @@
-export default {
- buildOptions: {
- sitemap: false,
- },
- renderers: [
- '@astrojs/renderer-svelte',
- ],
-};
diff --git a/packages/astro/test/fixtures/astro-client-only/snowpack.config.json b/packages/astro/test/fixtures/astro-client-only/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-client-only/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-components/snowpack.config.json b/packages/astro/test/fixtures/astro-components/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-components/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-css-bundling/snowpack.config.json b/packages/astro/test/fixtures/astro-css-bundling/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-css-bundling/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-doctype/snowpack.config.json b/packages/astro/test/fixtures/astro-doctype/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-doctype/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-dynamic/astro.config.mjs b/packages/astro/test/fixtures/astro-dynamic/astro.config.mjs
deleted file mode 100644
index 09731ba28..000000000
--- a/packages/astro/test/fixtures/astro-dynamic/astro.config.mjs
+++ /dev/null
@@ -1,5 +0,0 @@
-export default {
- buildOptions: {
- sitemap: false,
- },
-};
diff --git a/packages/astro/test/fixtures/astro-dynamic/snowpack.config.json b/packages/astro/test/fixtures/astro-dynamic/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-dynamic/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-expr/astro.config.mjs b/packages/astro/test/fixtures/astro-expr/astro.config.mjs
deleted file mode 100644
index 6c6bb575d..000000000
--- a/packages/astro/test/fixtures/astro-expr/astro.config.mjs
+++ /dev/null
@@ -1,5 +0,0 @@
-export default {
- renderers: [
- '@astrojs/renderer-preact'
- ]
-}
diff --git a/packages/astro/test/fixtures/astro-expr/snowpack.config.json b/packages/astro/test/fixtures/astro-expr/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-expr/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-fallback/astro.config.mjs b/packages/astro/test/fixtures/astro-fallback/astro.config.mjs
deleted file mode 100644
index 6c6bb575d..000000000
--- a/packages/astro/test/fixtures/astro-fallback/astro.config.mjs
+++ /dev/null
@@ -1,5 +0,0 @@
-export default {
- renderers: [
- '@astrojs/renderer-preact'
- ]
-}
diff --git a/packages/astro/test/fixtures/astro-fallback/snowpack.config.json b/packages/astro/test/fixtures/astro-fallback/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-fallback/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-get-static-paths/astro.config.mjs b/packages/astro/test/fixtures/astro-get-static-paths/astro.config.mjs
deleted file mode 100644
index c601c31ad..000000000
--- a/packages/astro/test/fixtures/astro-get-static-paths/astro.config.mjs
+++ /dev/null
@@ -1,6 +0,0 @@
-export default {
- buildOptions: {
- site: 'https://mysite.dev/blog/',
- sitemap: false,
- },
-};
diff --git a/packages/astro/test/fixtures/astro-get-static-paths/snowpack.config.json b/packages/astro/test/fixtures/astro-get-static-paths/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-get-static-paths/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-global/astro.config.mjs b/packages/astro/test/fixtures/astro-global/astro.config.mjs
deleted file mode 100644
index c601c31ad..000000000
--- a/packages/astro/test/fixtures/astro-global/astro.config.mjs
+++ /dev/null
@@ -1,6 +0,0 @@
-export default {
- buildOptions: {
- site: 'https://mysite.dev/blog/',
- sitemap: false,
- },
-};
diff --git a/packages/astro/test/fixtures/astro-global/snowpack.config.json b/packages/astro/test/fixtures/astro-global/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-global/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-hmr/snowpack.config.json b/packages/astro/test/fixtures/astro-hmr/snowpack.config.json
deleted file mode 100644
index 6fddc0add..000000000
--- a/packages/astro/test/fixtures/astro-hmr/snowpack.config.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "workspaceRoot": "../../../../../",
- "devOptions": {
- "hmrPort": 5555
- }
-}
diff --git a/packages/astro/test/fixtures/astro-markdown-plugins/astro.config.mjs b/packages/astro/test/fixtures/astro-markdown-plugins/astro.config.mjs
deleted file mode 100644
index 1e95e71e3..000000000
--- a/packages/astro/test/fixtures/astro-markdown-plugins/astro.config.mjs
+++ /dev/null
@@ -1,19 +0,0 @@
-export default {
- renderers: [
- '@astrojs/renderer-preact'
- ],
- markdownOptions: {
- remarkPlugins: [
- 'remark-code-titles',
- 'remark-slug',
- ['rehype-autolink-headings', { behavior: 'prepend' }],
- ],
- rehypePlugins: [
- ['rehype-toc', { headings: ["h2", "h3"] }],
- ['rehype-add-classes', { 'h1,h2,h3': 'title', }],
- ]
- },
- buildOptions: {
- sitemap: false,
- },
-};
diff --git a/packages/astro/test/fixtures/astro-markdown-plugins/snowpack.config.json b/packages/astro/test/fixtures/astro-markdown-plugins/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-markdown-plugins/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-markdown/astro.config.mjs b/packages/astro/test/fixtures/astro-markdown/astro.config.mjs
deleted file mode 100644
index d940a67c9..000000000
--- a/packages/astro/test/fixtures/astro-markdown/astro.config.mjs
+++ /dev/null
@@ -1,8 +0,0 @@
-export default {
- renderers: [
- '@astrojs/renderer-preact'
- ],
- buildOptions: {
- sitemap: false,
- },
-};
diff --git a/packages/astro/test/fixtures/astro-markdown/snowpack.config.json b/packages/astro/test/fixtures/astro-markdown/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-markdown/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-page-directory-url/astro.config.mjs b/packages/astro/test/fixtures/astro-page-directory-url/astro.config.mjs
deleted file mode 100644
index 309bb9d5a..000000000
--- a/packages/astro/test/fixtures/astro-page-directory-url/astro.config.mjs
+++ /dev/null
@@ -1,5 +0,0 @@
-export default {
- buildOptions: {
- pageUrlFormat: 'file'
- }
-};
diff --git a/packages/astro/test/fixtures/astro-page-directory-url/snowpack.config.json b/packages/astro/test/fixtures/astro-page-directory-url/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-page-directory-url/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-pages/snowpack.config.json b/packages/astro/test/fixtures/astro-pages/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-pages/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-pagination/astro.config.mjs b/packages/astro/test/fixtures/astro-pagination/astro.config.mjs
deleted file mode 100644
index c601c31ad..000000000
--- a/packages/astro/test/fixtures/astro-pagination/astro.config.mjs
+++ /dev/null
@@ -1,6 +0,0 @@
-export default {
- buildOptions: {
- site: 'https://mysite.dev/blog/',
- sitemap: false,
- },
-};
diff --git a/packages/astro/test/fixtures/astro-pagination/snowpack.config.json b/packages/astro/test/fixtures/astro-pagination/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-pagination/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-public/snowpack.config.json b/packages/astro/test/fixtures/astro-public/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-public/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-rss/astro.config.mjs b/packages/astro/test/fixtures/astro-rss/astro.config.mjs
deleted file mode 100644
index c19ba79f1..000000000
--- a/packages/astro/test/fixtures/astro-rss/astro.config.mjs
+++ /dev/null
@@ -1,5 +0,0 @@
-export default {
- buildOptions: {
- site: 'https://mysite.dev',
- },
-};
diff --git a/packages/astro/test/fixtures/astro-rss/snowpack.config.json b/packages/astro/test/fixtures/astro-rss/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-rss/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-scripts/snowpack.config.json b/packages/astro/test/fixtures/astro-scripts/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-scripts/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-slots/snowpack.config.json b/packages/astro/test/fixtures/astro-slots/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-slots/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-styles-ssr/snowpack.config.json b/packages/astro/test/fixtures/astro-styles-ssr/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-styles-ssr/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/astro-throw/snowpack.config.json b/packages/astro/test/fixtures/astro-throw/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/astro-throw/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/builtins-polyfillnode/snowpack.config.json b/packages/astro/test/fixtures/builtins-polyfillnode/snowpack.config.json
deleted file mode 100644
index 3c503c831..000000000
--- a/packages/astro/test/fixtures/builtins-polyfillnode/snowpack.config.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "workspaceRoot": "../../../../../",
- "packageOptions": {
- "polyfillNode": false
- }
-}
diff --git a/packages/astro/test/fixtures/builtins/snowpack.config.json b/packages/astro/test/fixtures/builtins/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/builtins/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/config-port/astro.config.mjs b/packages/astro/test/fixtures/config-port/astro.config.mjs
index 61858cdae..c4407033a 100644
--- a/packages/astro/test/fixtures/config-port/astro.config.mjs
+++ b/packages/astro/test/fixtures/config-port/astro.config.mjs
@@ -1,6 +1,5 @@
-
export default {
devOptions: {
- port: 3001
+ port: 5001
}
-}
\ No newline at end of file
+}
diff --git a/packages/astro/test/fixtures/custom-elements/astro.config.mjs b/packages/astro/test/fixtures/custom-elements/astro.config.mjs
deleted file mode 100644
index bb82dbd14..000000000
--- a/packages/astro/test/fixtures/custom-elements/astro.config.mjs
+++ /dev/null
@@ -1,6 +0,0 @@
-
-export default {
- renderers: [
- '@astrojs/test-custom-element-renderer'
- ]
-}
\ No newline at end of file
diff --git a/packages/astro/test/fixtures/custom-elements/snowpack.config.json b/packages/astro/test/fixtures/custom-elements/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/custom-elements/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/fetch/snowpack.config.json b/packages/astro/test/fixtures/fetch/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/fetch/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/lit-element/astro.config.mjs b/packages/astro/test/fixtures/lit-element/astro.config.mjs
deleted file mode 100644
index 20f741ec6..000000000
--- a/packages/astro/test/fixtures/lit-element/astro.config.mjs
+++ /dev/null
@@ -1,17 +0,0 @@
-export default {
- // projectRoot: '.', // Where to resolve all URLs relative to. Useful if you have a monorepo project.
- // pages: './src/pages', // Path to Astro components, pages, and data
- // dist: './dist', // When running `astro build`, path to final static output
- // public: './public', // A folder of static files Astro will copy to the root. Useful for favicons, images, and other files that don’t need processing.
- buildOptions: {
- // site: 'http://example.com', // Your public domain, e.g.: https://my-site.dev/. Used to generate sitemaps and canonical URLs.
- // sitemap: true, // Generate sitemap (set to "false" to disable)
- },
- devOptions: {
- // port: 3000, // The port to run the dev server on.
- // tailwindConfig: '', // Path to tailwind.config.js if used, e.g. './tailwind.config.js'
- },
- renderers: [
- '@astrojs/renderer-lit'
- ]
-};
\ No newline at end of file
diff --git a/packages/astro/test/fixtures/lit-element/snowpack.config.json b/packages/astro/test/fixtures/lit-element/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/lit-element/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/no-head-el/snowpack.config.json b/packages/astro/test/fixtures/no-head-el/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/no-head-el/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/plain-markdown/astro.config.mjs b/packages/astro/test/fixtures/plain-markdown/astro.config.mjs
deleted file mode 100644
index d940a67c9..000000000
--- a/packages/astro/test/fixtures/plain-markdown/astro.config.mjs
+++ /dev/null
@@ -1,8 +0,0 @@
-export default {
- renderers: [
- '@astrojs/renderer-preact'
- ],
- buildOptions: {
- sitemap: false,
- },
-};
diff --git a/packages/astro/test/fixtures/plain-markdown/snowpack.config.json b/packages/astro/test/fixtures/plain-markdown/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/plain-markdown/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/preact-component/snowpack.config.json b/packages/astro/test/fixtures/preact-component/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/preact-component/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/react-component/snowpack.config.json b/packages/astro/test/fixtures/react-component/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/react-component/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/fixtures/vue-component/snowpack.config.json b/packages/astro/test/fixtures/vue-component/snowpack.config.json
deleted file mode 100644
index 8f034781d..000000000
--- a/packages/astro/test/fixtures/vue-component/snowpack.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "workspaceRoot": "../../../../../"
-}
diff --git a/packages/astro/test/helpers.js b/packages/astro/test/helpers.js
deleted file mode 100644
index 569a254cc..000000000
--- a/packages/astro/test/helpers.js
+++ /dev/null
@@ -1,175 +0,0 @@
-import { fileURLToPath } from 'url';
-import { build as astroBuild } from '#astro/build';
-import { preview as astroPreview } from '#astro/preview';
-import { readFileSync } from 'fs';
-import { createRuntime } from '#astro/runtime';
-import { loadConfig } from '#astro/config';
-import execa from 'execa';
-import del from 'del';
-
-const MAX_STARTUP_TIME = 20000; // max time startup may take
-const MAX_TEST_TIME = 10000; // max time an individual test may take
-const MAX_SHUTDOWN_TIME = 3000; // max time shutdown() may take
-
-/** setup fixtures for tests */
-
-/**
- * @typedef {Object} SetupOptions
- * @prop {import('../src/runtime').RuntimeOptions} runtimeOptions
- */
-
-/**
- * @param {{}} Suite
- * @param {string} fixturePath
- * @param {SetupOptions} setupOptions
- */
-export function setup(Suite, fixturePath, { runtimeOptions = {} } = {}) {
- let runtime, createRuntimeError;
- const timers = {};
-
- Suite.before(async (context) => {
- let timeout = setTimeout(() => {
- throw new Error('Startup did not complete within allowed time');
- }, MAX_STARTUP_TIME);
-
- const astroConfig = await loadConfig(fileURLToPath(new URL(fixturePath, import.meta.url)));
-
- runtime = await createRuntime(astroConfig, {
- logging: { level: 'error' },
- ...runtimeOptions,
- }).catch((err) => {
- createRuntimeError = err;
- });
-
- if (createRuntimeError) {
- setTimeout(() => {
- throw createRuntimeError;
- });
- }
-
- context.runtime = runtime;
-
- clearTimeout(timeout);
- });
-
- Suite.before.each(({ __test__ }) => {
- if (timers[__test__]) throw new Error(`Test "${__test__}" already declared`);
- timers[__test__] = setTimeout(() => {
- throw new Error(`"${__test__}" did not finish within allowed time`);
- }, MAX_TEST_TIME);
- });
-
- Suite.after(async () => {
- let timeout = setTimeout(() => {
- throw new Error('Shutdown did not complete within allowed time');
- }, MAX_SHUTDOWN_TIME);
-
- (await runtime) && runtime.shutdown();
-
- clearTimeout(timeout);
- });
-
- Suite.after.each(({ __test__ }) => {
- clearTimeout(timers[__test__]);
- });
-}
-
-/**
- * @param {{}} Suite
- * @param {string} fixturePath
- * @param {SetupOptions} setupOptions
- */
-export function setupPreview(Suite, fixturePath, { runtimeOptions = {} } = {}) {
- let server, createRuntimeError;
- const timers = {};
-
- Suite.before(async (context) => {
- let timeout = setTimeout(() => {
- throw new Error('Startup did not complete within allowed time');
- }, MAX_STARTUP_TIME);
-
- const astroConfig = await loadConfig(fileURLToPath(new URL(fixturePath, import.meta.url)));
-
- server = await astroPreview(astroConfig).catch((err) => {
- createRuntimeError = err;
- });
-
- if (createRuntimeError) {
- setTimeout(() => {
- throw createRuntimeError;
- });
- }
-
- context.previewServer = server;
-
- clearTimeout(timeout);
- });
-
- Suite.before.each(({ __test__ }) => {
- if (timers[__test__]) throw new Error(`Test "${__test__}" already declared`);
- timers[__test__] = setTimeout(() => {
- throw new Error(`"${__test__}" did not finish within allowed time`);
- }, MAX_TEST_TIME);
- });
-
- Suite.after(async () => {
- let timeout = setTimeout(() => {
- throw new Error('Shutdown did not complete within allowed time');
- }, MAX_SHUTDOWN_TIME);
-
- server && server.close();
-
- clearTimeout(timeout);
- });
-
- Suite.after.each(({ __test__ }) => {
- clearTimeout(timers[__test__]);
- });
-}
-
-export function setupBuild(Suite, fixturePath) {
- const timers = {};
-
- Suite.before(async (context) => {
- let timeout = setTimeout(() => {
- throw new Error('Startup did not complete within allowed time');
- }, MAX_STARTUP_TIME);
-
- const astroConfig = await loadConfig(fileURLToPath(new URL(fixturePath, import.meta.url)));
-
- context.build = () => astroBuild(astroConfig, { level: 'error' });
- context.readFile = async (path) => {
- const resolved = fileURLToPath(new URL(path.replace(/^\//, ''), astroConfig.dist));
- return readFileSync(resolved, { encoding: 'utf8' });
- };
-
- clearTimeout(timeout);
- });
-
- Suite.before.each(({ __test__ }) => {
- if (timers[__test__]) throw new Error(`Test "${__test__}" already declared`);
- timers[__test__] = setTimeout(() => {
- throw new Error(`"${__test__}" did not finish within allowed time`);
- }, MAX_TEST_TIME);
- });
-
- Suite.after(async () => {
- // Shutdown i guess.
- });
-
- Suite.after.each(({ __test__ }) => {
- clearTimeout(timers[__test__]);
- });
-}
-
-const cliURL = new URL('../astro.mjs', import.meta.url);
-export function runDevServer(root, additionalArgs = []) {
- const args = [cliURL.pathname, 'dev', '--project-root', root.pathname].concat(additionalArgs);
- const proc = execa('node', args);
- return proc;
-}
-
-export async function clearCache() {
- const cacheDir = new URL('../../../node_modules/.cache', import.meta.url);
- await del(fileURLToPath(cacheDir));
-}
diff --git a/packages/astro/test/integration-docs.test.js b/packages/astro/test/integration-docs.test.js
deleted file mode 100644
index 8a693f3c9..000000000
--- a/packages/astro/test/integration-docs.test.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import path from 'path';
-import glob from 'tiny-glob/sync.js';
-import { fileURLToPath } from 'url';
-import { suite } from 'uvu';
-import * as assert from 'uvu/assert';
-import { setup } from './helpers.js';
-
-const SnowpackDev = suite('docs.astro.build');
-setup(SnowpackDev, '../../../docs');
-
-// convert file path to its final url
-function formatURL(filepath) {
- return filepath
- .replace(/^\/?/, '/') // add / to beginning, if missing
- .replace(/(index)?\.(astro|md)$/, '') // remove .astro and .md extensions
- .replace(/\/$/, ''); // remove trailing slash, if any
-}
-
-// declaring routes individually helps us run many quick tests rather than one giant slow test
-const root = path.join(path.dirname(fileURLToPath(import.meta.url)), '../../../docs/src/pages');
-let pages = glob('**/*.{astro,md}', { cwd: root, onlyFiles: true }).map(formatURL);
-
-SnowpackDev('Pages successfully scanned', () => {
- assert.ok(pages.length > 0);
-});
-
-for (const pathname of pages) {
- SnowpackDev(`Loads "${pathname}"`, async ({ runtime }) => {
- const result = await runtime.load(pathname);
- if (result.statusCode !== 200) {
- console.error(result);
- }
- assert.equal(result.statusCode, 200);
- return;
- });
-}
-
-// Skipped on Node '14') {
- SnowpackDev.run();
-}
diff --git a/packages/astro/test/lit-element.test.js b/packages/astro/test/lit-element.test.js
index 6f44d055e..d2abcbe85 100644
--- a/packages/astro/test/lit-element.test.js
+++ b/packages/astro/test/lit-element.test.js
@@ -1,44 +1,54 @@
-import { suite } from 'uvu';
-import * as assert from 'uvu/assert';
-import { doc } from './test-utils.js';
-import { setup } from './helpers.js';
+import cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
-const LitElement = suite('LitElement test');
+describe('LitElement test', () => {
+ let fixture;
+ let devServer;
-setup(LitElement, './fixtures/lit-element');
+ beforeAll(async () => {
+ fixture = await loadFixture({
+ projectRoot: './fixtures/lit-element/',
+ renderers: ['@astrojs/renderer-lit'],
+ });
+ devServer = await fixture.dev();
+ });
-LitElement('Renders a custom element by tag name', async ({ runtime }) => {
- // lit SSR is not currently supported on Node.js < 13
- if (process.versions.node <= '13') {
- return;
- }
- const result = await runtime.load('/');
- assert.ok(!result.error, `build error: ${result.error}`);
+ test('Renders a custom element by tag name', async () => {
+ // lit SSR is not currently supported on Node.js < 13
+ if (process.versions.node <= '13') {
+ return;
+ }
+ const html = await fixture.fetch('/').then((res) => res.text());
+ const $ = doc(html);
- const $ = doc(result.contents);
+ // test 1: attributes rendered
+ expect($('my-element').attr('foo')).toBe('bar');
- assert.equal($('my-element').attr('foo'), 'bar', 'attributes rendered');
- assert.ok($('my-element').html().includes(`Testing...
`), 'shadow rendered');
+ // test 2: shadow rendered
+ expect($('my-element').html()).toEqual(expect.stringContaining(`Testing...
`));
+ });
+
+ // Skipped because not supported by Lit
+ test.skip('Renders a custom element by the constructor', async () => {
+ const html = await fixture.fetch('/ctr').then((res) => res.text());
+ const $ = doc(html);
+
+ // test 1: attributes rendered
+ expect($('my-element').attr('foo')).toBe('bar');
+
+ // test 2: shadow rendered
+ expect($('my-element').html()).toEqual(expect.stringContaining(`Testing...
`));
+ });
+
+ afterAll(async () => {
+ // important: close dev server (free up port and connection)
+ await devServer.stop();
+
+ // The Lit renderer adds browser globals that interfere with other tests, so remove them now.
+ const globals = Object.keys(globalThis.window || {});
+ globals.splice(globals.indexOf('global'), 1);
+ for (let name of globals) {
+ delete globalThis[name];
+ }
+ });
});
-
-// Skipped because not supported by Lit
-LitElement.skip('Renders a custom element by the constructor', async ({ runtime }) => {
- const result = await runtime.load('/ctr');
- assert.ok(!result.error, `build error: ${result.error}`);
-
- const $ = doc(result.contents);
-
- assert.equal($('my-element').attr('foo'), 'bar', 'attributes rendered');
- assert.ok($('my-element').html().includes(`Testing...
`), 'shadow rendered');
-});
-
-// The Lit renderer adds browser globals that interfere with other tests, so remove them now.
-LitElement.after(() => {
- const globals = Object.keys(globalThis.window || {});
- globals.splice(globals.indexOf('global'), 1);
- for (let name of globals) {
- delete globalThis[name];
- }
-});
-
-LitElement.run();
diff --git a/packages/astro/test/no-head-el.test.js b/packages/astro/test/no-head-el.test.js
index d3c4d9fde..e5bf6ef71 100644
--- a/packages/astro/test/no-head-el.test.js
+++ b/packages/astro/test/no-head-el.test.js
@@ -1,28 +1,35 @@
-import { suite } from 'uvu';
-import * as assert from 'uvu/assert';
-import { doc } from './test-utils.js';
-import { setup } from './helpers.js';
+import cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
-const NoHeadEl = suite('Documents without a head');
+describe('Documents without a head', () => {
+ let fixture;
+ let devServer;
-setup(NoHeadEl, './fixtures/no-head-el', {
- runtimeOptions: {
- mode: 'development',
- },
+ beforeAll(async () => {
+ fixture = await loadFixture({ projectRoot: './fixtures/no-head-el/' });
+ devServer = await fixture.dev();
+ });
+
+ test('Places style and scripts before the first non-head element', async () => {
+ const html = await fixture.fetch('/').then((res) => res.text());
+ const $ = cheerio.load(html);
+
+ // test 1: Link to css placed after
+ expect($('title').next().is('link')).toBe(true);
+
+ // test 2: Link for a child component
+ expect($('title').next().next().is('link')).toBe(true);
+
+ // test 3: style placed after
+ expect($('title').next().next().next().is('style')).toBe(true);
+
+ // note(drew): commented-out with Vite now handling HMR
+ // assert.equal($('title').next().next().next().next().is('script'), true, 'HMR script after the style');
+ // assert.equal($('script[src="/_snowpack/hmr-client.js"]').length, 1, 'Only the hmr client for the page');
+ });
+
+ // important: close dev server (free up port and connection)
+ afterAll(async () => {
+ await devServer.stop();
+ });
});
-
-NoHeadEl('Places style and scripts before the first non-head element', async ({ runtime }) => {
- const result = await runtime.load('/');
- assert.ok(!result.error, `build error: ${result.error}`);
-
- const html = result.contents;
- const $ = doc(html);
- assert.equal($('title').next().is('link'), true, 'Link to css placed after the title');
- assert.equal($('title').next().next().is('link'), true, 'Link for a child component');
- assert.equal($('title').next().next().next().is('style'), true, 'astro-root style placed after the link');
- assert.equal($('title').next().next().next().next().is('script'), true, 'HMR script after the style');
-
- assert.equal($('script[src="/_snowpack/hmr-client.js"]').length, 1, 'Only the hmr client for the page');
-});
-
-NoHeadEl.run();
diff --git a/packages/astro/test/plain-markdown.test.js b/packages/astro/test/plain-markdown.test.js
index 7a2852af9..7f11da2d6 100644
--- a/packages/astro/test/plain-markdown.test.js
+++ b/packages/astro/test/plain-markdown.test.js
@@ -1,37 +1,51 @@
-import { suite } from 'uvu';
-import * as assert from 'uvu/assert';
-import { doc } from './test-utils.js';
-import { setup, setupBuild } from './helpers.js';
+import cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
-const Markdown = suite('Plain Markdown tests');
+describe('Plain Markdown tests', () => {
+ let fixture;
-setup(Markdown, './fixtures/plain-markdown');
-setupBuild(Markdown, './fixtures/plain-markdown');
+ beforeAll(async () => {
+ fixture = await loadFixture({
+ projectRoot: './fixtures/markdown-plain/',
+ buildOptions: {
+ sitemap: false,
+ },
+ renderers: ['@astrojs/renderer-preact'],
+ });
+ });
-Markdown('Can load a simple markdown page with Astro', async ({ runtime }) => {
- const result = await runtime.load('/post');
+ describe('dev', () => {
+ let devServer;
- assert.equal(result.statusCode, 200);
+ beforeAll(async () => {
+ devServer = await fixture.dev();
+ });
- const $ = doc(result.contents);
+ test('Can load a simple markdown page with Astro', async () => {
+ const html = await fixture.fetch('/post').then((res) => res.text());
+ const $ = cheerio.load(html);
- assert.equal($('p').first().text(), 'Hello world!');
- assert.equal($('#first').text(), 'Some content');
- assert.equal($('#interesting-topic').text(), 'Interesting Topic');
+ expect($('p').first().text()).toBe('Hello world!');
+ expect($('#first').text()).toBe('Some content');
+ expect($('#interesting-topic').text()).toBe('Interesting Topic');
+ });
+
+ test('Can load a realworld markdown page with Astro', async () => {
+ const html = await fixture.fetch('/realworld').then((res) => res.text());
+ const $ = cheerio.load(html);
+
+ expect($('pre')).toHaveLength(7);
+ });
+
+ // important: close dev server (free up port and connection)
+ afterAll(async () => {
+ await devServer.stop();
+ });
+ });
+
+ describe('build', () => {
+ test('Builds markdown pages for prod', () => {
+ expect(() => fixture.build()).not.toThrow();
+ });
+ });
});
-
-Markdown('Can load a realworld markdown page with Astro', async ({ runtime }) => {
- const result = await runtime.load('/realworld');
- assert.ok(!result.error, `build error: ${result.error}`);
-
- assert.equal(result.statusCode, 200);
- const $ = doc(result.contents);
-
- assert.equal($('pre').length, 7);
-});
-
-Markdown('Builds markdown pages for prod', async (context) => {
- await context.build();
-});
-
-Markdown.run();
diff --git a/packages/astro/test/preact-component.test.js b/packages/astro/test/preact-component.test.js
index 021b7e8a5..64b6c6bc5 100644
--- a/packages/astro/test/preact-component.test.js
+++ b/packages/astro/test/preact-component.test.js
@@ -1,77 +1,84 @@
-import { suite } from 'uvu';
-import * as assert from 'uvu/assert';
-import { doc } from './test-utils.js';
-import { setup, setupBuild } from './helpers.js';
+import cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
-const PreactComponent = suite('Preact component test');
+describe('Preact component', () => {
+ let fixture;
+ let devServer;
-setup(PreactComponent, './fixtures/preact-component');
-setupBuild(PreactComponent, './fixtures/preact-component');
+ beforeAll(async () => {
+ fixture = await loadFixture({ projectRoot: './fixtures/preact-component/' });
+ devServer = await fixture.dev();
+ });
-PreactComponent('Can load class component', async ({ runtime }) => {
- const result = await runtime.load('/class');
- assert.ok(!result.error, `build error: ${result.error}`);
+ test('Can load class component', async () => {
+ const html = await fixture.fetch('/class').then((res) => res.text());
+ const $ = cheerio.load(html);
- const $ = doc(result.contents);
- assert.equal($('#class-component').length, 1, 'Can use class components');
-});
+ // test 1: Can use class components
+ expect($('#class-component')).toHaveLength(1);
+ });
-PreactComponent('Can load function component', async ({ runtime }) => {
- const result = await runtime.load('/fn');
- assert.ok(!result.error, `build error: ${result.error}`);
+ test('Can load function component', async () => {
+ const html = await fixture.fetch('/fn').then((res) => res.text());
+ const $ = cheerio.load(html);
- const $ = doc(result.contents);
- assert.equal($('#fn-component').length, 1, 'Can use function components');
- assert.equal($('#arrow-fn-component').length, 1, 'Can use function components');
-});
+ // test 1: Can use function components
+ expect($('#fn-component')).toHaveLength(1);
+ // test 2: Can use function components
+ expect($('#arrow-fn-component')).toHaveLength(1);
+ });
-PreactComponent('Can load TS component', async ({ runtime }) => {
- const result = await runtime.load('/ts-components');
- assert.ok(!result.error, `build error: ${result.error}`);
- const $ = doc(result.contents);
- assert.equal($('.ts-component').length, 1, 'Can use TS components');
-});
+ test('Can load TS component', async () => {
+ const html = await fixture.fetch('/ts-components').then((res) => res.text());
+ const $ = cheerio.load(html);
-PreactComponent('Can use hooks', async ({ runtime }) => {
- const result = await runtime.load('/hooks');
- assert.ok(!result.error, `build error: ${result.error}`);
+ // test 1: Can use TS components
+ expect($('.ts-component')).toHaveLength(1);
+ });
- const $ = doc(result.contents);
- assert.equal($('#world').length, 1);
-});
+ test('Can use hooks', async () => {
+ const html = await fixture.fetch('/hooks').then((res) => res.text());
+ const $ = cheerio.load(html);
+ expect($('#world')).toHaveLength(1);
+ });
-PreactComponent('Can export a Fragment', async ({ runtime }) => {
- const result = await runtime.load('/frag');
- assert.ok(!result.error, `build error: ${result.error}`);
+ test('Can export a Fragment', async () => {
+ const html = await fixture.fetch('/frag').then((res) => res.text());
+ const $ = cheerio.load(html);
- const $ = doc(result.contents);
- assert.equal($('body').children().length, 0, "nothing rendered but it didn't throw.");
-});
+ // test 1: nothing rendered but it didn’t throw
+ expect($('body').children()).toHaveLength(0);
+ });
-PreactComponent('Can use a pragma comment', async ({ runtime }) => {
- const result = await runtime.load('/pragma-comment');
- assert.ok(!result.error, `build error: ${result.error}`);
+ test('Can use a pragma comment', async () => {
+ const html = await fixture.fetch('/pragma-comment').then((res) => res.text());
+ const $ = cheerio.load(html);
- const $ = doc(result.contents);
- assert.equal($('.pragma-comment').length, 2, 'rendered the PragmaComment component.');
-});
+ // test 1: rendered the PragmaComment component
+ expect($('.pragma-comment')).toHaveLength(2);
+ });
-PreactComponent('Uses the new JSX transform', async ({ runtime }) => {
- const result = await runtime.load('/pragma-comment');
+ test('Uses the new JSX transform', async () => {
+ const html = await fixture.fetch('/pragma-comment').then((res) => res.text());
- // Grab the imports
- const exp = /import\("(.+?)"\)/g;
- let match, componentUrl;
- while ((match = exp.exec(result.contents))) {
- if (match[1].includes('PragmaComment.js')) {
- componentUrl = match[1];
- break;
+ // Grab the imports
+ const exp = /import\("(.+?)"\)/g;
+ let match, componentUrl;
+ while ((match = exp.exec(html))) {
+ if (match[1].includes('PragmaComment.js')) {
+ componentUrl = match[1];
+ break;
+ }
}
- }
- const component = await runtime.load(componentUrl);
- const jsxRuntime = component.imports.filter((i) => i.specifier.includes('jsx-runtime'));
+ const component = await fixture.fetch(componentUrl).then((res) => res.text());
+ const jsxRuntime = component.imports.filter((i) => i.specifier.includes('jsx-runtime'));
- assert.ok(jsxRuntime, 'preact/jsx-runtime is used for the component');
+ // test 1: preact/jsx-runtime is used for the component
+ expect(jsxRuntime).toBeTruthy();
+ });
+
+ // important: close dev server (free up port and connection)
+ afterAll(async () => {
+ await devServer.stop();
+ });
});
-
-PreactComponent.run();
diff --git a/packages/astro/test/react-component.test.js b/packages/astro/test/react-component.test.js
index 390573bbb..774c40ae0 100644
--- a/packages/astro/test/react-component.test.js
+++ b/packages/astro/test/react-component.test.js
@@ -1,105 +1,101 @@
-import { fileURLToPath } from 'url';
-import { suite } from 'uvu';
-import * as assert from 'uvu/assert';
-import { createRuntime } from '#astro/runtime';
-import { loadConfig } from '#astro/config';
-import { doc } from './test-utils.js';
+import cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
-const React = suite('React Components');
+describe('React Components', () => {
+ let fixture;
+ let devServer;
-let runtime, setupError;
+ beforeAll(async () => {
+ fixture = await loadFixture({ projectRoot: './fixtures/react-component/' });
+ devServer = await fixture.dev();
+ });
-React.before(async () => {
- const astroConfig = await loadConfig(fileURLToPath(new URL('./fixtures/react-component', import.meta.url)));
+ test('Can load React', async () => {
+ const html = await fixture.fetch('/').then((res) => res.text());
+ const $ = cheerio.load(html);
- const logging = {
- level: 'error',
- dest: process.stderr,
- };
+ // test 1: basic component renders
+ expect($('#react-h2').text()).toBe('Hello world!');
- try {
- runtime = await createRuntime(astroConfig, { logging });
- } catch (err) {
- console.error(err);
- setupError = err;
- }
-});
+ // test 2: no reactroot
+ expect($('#react-h2').attr('data-reactroot')).toBe(undefined);
-React.after(async () => {
- (await runtime) && runtime.shutdown();
-});
+ // test 3: Can use function components
+ expect($('#arrow-fn-component')).toHaveLength(1);
-React('No error creating the runtime', () => {
- assert.equal(setupError, undefined);
-});
+ // test 4: Can use spread for components
+ expect($('#component-spread-props')).toHaveLength(1);
-React('Can load React', async () => {
- const result = await runtime.load('/');
- assert.ok(!result.error, `build error: ${result.error}`);
+ // test 5: spread props renders
+ expect($('#component-spread-props').text(), 'Hello world!');
- const $ = doc(result.contents);
- assert.equal($('#react-h2').text(), 'Hello world!');
- assert.equal($('#react-h2').attr('data-reactroot'), undefined, 'no reactroot');
- assert.equal($('#arrow-fn-component').length, 1, 'Can use function components');
- assert.equal($('#component-spread-props').length, 1, 'Can use spread for components');
- assert.equal($('#component-spread-props').text(), 'Hello world!');
- assert.equal($('.ts-component').length, 1, 'Can use TS components');
- assert.equal($('#pure').length, 1, 'Can use Pure components');
-});
+ // test 6: Can use TS components
+ expect($('.ts-component')).toHaveLength(1);
-React('Includes reactroot on hydrating components', async () => {
- const result = await runtime.load('/');
- assert.ok(!result.error, `build error: ${result.error}`);
+ // test 7: Can use Pure components
+ expect($('#pure')).toHaveLength(1);
+ });
- const $ = doc(result.contents);
- const div = $('#research');
- assert.equal(div.attr('data-reactroot'), '', 'Has the hydration attr');
- assert.equal(div.html(), 'foo bar 1');
-});
+ test('Includes reactroot on hydrating components', async () => {
+ const html = await fixture.fetch('/').then((res) => res.text());
+ const $ = cheerio.load(html);
-React('Throws helpful error message on window SSR', async () => {
- const result = await runtime.load('/window');
- assert.match(
- result.error.toString('utf8'),
- `[/window]
+ const div = $('#research');
+
+ // test 1: has the hydration attr
+ expect(div.attr('data-reactroot')).toBeTruthy();
+
+ // test 2: renders correctly
+ expect(div.html()).toBe('foo bar 1');
+ });
+
+ test('Throws helpful error message on window SSR', async () => {
+ const html = await fixture.fetch('/window').then((res) => res.text());
+ expect(html).toEqual(
+ expect.stringContaining(
+ `[/window]
The window object is not available during server-side rendering (SSR).
Try using \`import.meta.env.SSR\` to write SSR-friendly code.
https://docs.astro.build/reference/api-reference/#importmeta`
- );
-});
+ )
+ );
+ });
-React('Can load Vue', async () => {
- const result = await runtime.load('/');
- assert.ok(!result.error, `build error: ${result.error}`);
+ test('Can load Vue', async () => {
+ const html = await fixture.fetch('/').then((res) => res.text());
+ const $ = cheerio.load(html);
+ expect($('#vue-h2').text()).toBe('Hasta la vista, baby');
+ });
- const $ = doc(result.contents);
- assert.equal($('#vue-h2').text(), 'Hasta la vista, baby');
-});
+ test('Can use a pragma comment', async () => {
+ const html = await fixture.fetch('/pragma-comment').then((res) => res.text());
+ const $ = cheerio.load(html);
-React('Can use a pragma comment', async () => {
- const result = await runtime.load('/pragma-comment');
- assert.ok(!result.error, `build error: ${result.error}`);
- const $ = doc(result.contents);
- assert.equal($('.pragma-comment').length, 2, 'rendered the PragmaComment component.');
-});
+ // test 1: rendered the PragmaComment component
+ expect($('.pragma-comment')).toHaveLength(2);
+ });
-React('uses the new JSX transform', async () => {
- const result = await runtime.load('/');
- assert.ok(!result.error, `build error: ${result.error}`);
+ test('uses the new JSX transform', async () => {
+ const html = await fixture.fetch('/').then((res) => res.text());
- // Grab the imports
- const exp = /import\("(.+?)"\)/g;
- let match, componentUrl;
- while ((match = exp.exec(result.contents))) {
- if (match[1].includes('Research.js')) {
- componentUrl = match[1];
- break;
+ // Grab the imports
+ const exp = /import\("(.+?)"\)/g;
+ let match, componentUrl;
+ while ((match = exp.exec(html))) {
+ if (match[1].includes('Research.js')) {
+ componentUrl = match[1];
+ break;
+ }
}
- }
- const component = await runtime.load(componentUrl);
- const jsxRuntime = component.imports.filter((i) => i.specifier.includes('jsx-runtime'));
+ const component = await fixture.fetch(componentUrl).then((res) => res.text());
+ const jsxRuntime = component.imports.filter((i) => i.specifier.includes('jsx-runtime'));
- assert.ok(jsxRuntime, 'react/jsx-runtime is used for the component');
+ // test 1: react/jsx-runtime is used for the component
+ expect(jsxRuntime).toBeTruthy();
+ });
+
+ // important: close dev server (free up port and connection)
+ afterAll(async () => {
+ await devServer.stop();
+ });
});
-
-React.run();
diff --git a/packages/astro/test/route-manifest.test.js b/packages/astro/test/route-manifest.test.js
index 7f110bba6..afdc881f7 100644
--- a/packages/astro/test/route-manifest.test.js
+++ b/packages/astro/test/route-manifest.test.js
@@ -1,12 +1,10 @@
import { fileURLToPath } from 'url';
-import { test } from 'uvu';
-import * as assert from 'uvu/assert';
-import { createManifest } from '../dist/manifest/create.js';
+import { createRouteManifest } from '../dist/runtime/routing.js';
const cwd = new URL('./fixtures/route-manifest/', import.meta.url);
const create = (dir, trailingSlash) => {
- return createManifest({
+ return createRouteManifest({
config: {
projectRoot: cwd,
pages: new URL(dir, cwd),
@@ -24,199 +22,185 @@ function cleanRoutes(routes) {
});
}
-test('creates routes with trailingSlashes = always', () => {
- const { routes } = create('basic', 'always');
- assert.equal(cleanRoutes(routes), [
- {
- type: 'page',
- pattern: /^\/$/,
- params: [],
- component: 'basic/index.astro',
- path: '/',
- },
+describe('route manifest', () => {
+ test('creates routes with trailingSlashes = always', () => {
+ const { routes } = create('basic', 'always');
+ expect(cleanRoutes(routes)).toEqual([
+ {
+ type: 'page',
+ pattern: /^\/$/,
+ params: [],
+ component: 'basic/index.astro',
+ pathname: '/',
+ },
- {
- type: 'page',
- pattern: /^\/about\/$/,
- params: [],
- component: 'basic/about.astro',
- path: '/about',
- },
+ {
+ type: 'page',
+ pattern: /^\/about\/$/,
+ params: [],
+ component: 'basic/about.astro',
+ pathname: '/about',
+ },
- {
- type: 'page',
- pattern: /^\/blog\/$/,
- params: [],
- component: 'basic/blog/index.astro',
- path: '/blog',
- },
+ {
+ type: 'page',
+ pattern: /^\/blog\/$/,
+ params: [],
+ component: 'basic/blog/index.astro',
+ pathname: '/blog',
+ },
- {
- type: 'page',
- pattern: /^\/blog\/([^/]+?)\/$/,
- params: ['slug'],
- component: 'basic/blog/[slug].astro',
- path: null,
- },
- ]);
-});
+ {
+ type: 'page',
+ pattern: /^\/blog\/([^/]+?)\/$/,
+ params: ['slug'],
+ component: 'basic/blog/[slug].astro',
+ pathname: undefined,
+ },
+ ]);
+ });
-test('creates routes with trailingSlashes = never', () => {
- const { routes } = create('basic', 'never');
- assert.equal(cleanRoutes(routes), [
- {
- type: 'page',
- pattern: /^\/$/,
- params: [],
- component: 'basic/index.astro',
- path: '/',
- },
+ test('creates routes with trailingSlashes = never', () => {
+ const { routes } = create('basic', 'never');
+ expect(cleanRoutes(routes)).toEqual([
+ {
+ type: 'page',
+ pattern: /^\/$/,
+ params: [],
+ component: 'basic/index.astro',
+ pathname: '/',
+ },
- {
- type: 'page',
- pattern: /^\/about$/,
- params: [],
- component: 'basic/about.astro',
- path: '/about',
- },
+ {
+ type: 'page',
+ pattern: /^\/about$/,
+ params: [],
+ component: 'basic/about.astro',
+ pathname: '/about',
+ },
- {
- type: 'page',
- pattern: /^\/blog$/,
- params: [],
- component: 'basic/blog/index.astro',
- path: '/blog',
- },
+ {
+ type: 'page',
+ pattern: /^\/blog$/,
+ params: [],
+ component: 'basic/blog/index.astro',
+ pathname: '/blog',
+ },
- {
- type: 'page',
- pattern: /^\/blog\/([^/]+?)$/,
- params: ['slug'],
- component: 'basic/blog/[slug].astro',
- path: null,
- },
- ]);
-});
+ {
+ type: 'page',
+ pattern: /^\/blog\/([^/]+?)$/,
+ params: ['slug'],
+ component: 'basic/blog/[slug].astro',
+ pathname: undefined,
+ },
+ ]);
+ });
-test('creates routes with trailingSlashes = ignore', () => {
- const { routes } = create('basic', 'ignore');
- assert.equal(cleanRoutes(routes), [
- {
- type: 'page',
- pattern: /^\/$/,
- params: [],
- component: 'basic/index.astro',
- path: '/',
- },
+ test('creates routes with trailingSlashes = ignore', () => {
+ const { routes } = create('basic', 'ignore');
+ expect(cleanRoutes(routes)).toEqual([
+ {
+ type: 'page',
+ pattern: /^\/$/,
+ params: [],
+ component: 'basic/index.astro',
+ pathname: '/',
+ },
- {
- type: 'page',
- pattern: /^\/about\/?$/,
- params: [],
- component: 'basic/about.astro',
- path: '/about',
- },
+ {
+ type: 'page',
+ pattern: /^\/about\/?$/,
+ params: [],
+ component: 'basic/about.astro',
+ pathname: '/about',
+ },
- {
- type: 'page',
- pattern: /^\/blog\/?$/,
- params: [],
- component: 'basic/blog/index.astro',
- path: '/blog',
- },
+ {
+ type: 'page',
+ pattern: /^\/blog\/?$/,
+ params: [],
+ component: 'basic/blog/index.astro',
+ pathname: '/blog',
+ },
- {
- type: 'page',
- pattern: /^\/blog\/([^/]+?)\/?$/,
- params: ['slug'],
- component: 'basic/blog/[slug].astro',
- path: null,
- },
- ]);
-});
+ {
+ type: 'page',
+ pattern: /^\/blog\/([^/]+?)\/?$/,
+ params: ['slug'],
+ component: 'basic/blog/[slug].astro',
+ pathname: undefined,
+ },
+ ]);
+ });
-test('encodes invalid characters', () => {
- const { routes } = create('encoding', 'always');
+ test('encodes invalid characters', () => {
+ const { routes } = create('encoding', 'always');
- // had to remove ? and " because windows
+ // had to remove ? and " because windows
- // const quote = 'encoding/".astro';
- const hash = 'encoding/#.astro';
- // const question_mark = 'encoding/?.astro';
+ // const quote = 'encoding/".astro';
+ const hash = 'encoding/#.astro';
+ // const question_mark = 'encoding/?.astro';
- assert.equal(
- routes.map((p) => p.pattern),
- [
+ expect(routes.map((p) => p.pattern)).toEqual([
// /^\/%22$/,
/^\/%23\/$/,
// /^\/%3F$/
- ]
- );
-});
+ ]);
+ });
-test('ignores files and directories with leading underscores', () => {
- const { routes } = create('hidden-underscore', 'always');
+ test('ignores files and directories with leading underscores', () => {
+ const { routes } = create('hidden-underscore', 'always');
- assert.equal(routes.map((r) => r.component).filter(Boolean), ['hidden-underscore/index.astro', 'hidden-underscore/e/f/g/h.astro']);
-});
+ expect(routes.map((r) => r.component).filter(Boolean)).toEqual(['hidden-underscore/index.astro', 'hidden-underscore/e/f/g/h.astro']);
+ });
-test('ignores files and directories with leading dots except .well-known', () => {
- const { routes } = create('hidden-dot', 'always');
+ test('ignores files and directories with leading dots except .well-known', () => {
+ const { routes } = create('hidden-dot', 'always');
- assert.equal(routes.map((r) => r.component).filter(Boolean), ['hidden-dot/.well-known/dnt-policy.astro']);
-});
+ expect(routes.map((r) => r.component).filter(Boolean)).toEqual(['hidden-dot/.well-known/dnt-policy.astro']);
+ });
-test('fails if dynamic params are not separated', () => {
- assert.throws(() => {
- create('invalid-params', 'always');
- }, /Invalid route invalid-params\/\[foo\]\[bar\]\.astro — parameters must be separated/);
-});
+ test('fails if dynamic params are not separated', () => {
+ expect(() => create('invalid-params', 'always')).toThrowError('Invalid route invalid-params/[foo][bar].astro — parameters must be separated');
+ });
-test('disallows rest parameters inside segments', () => {
- assert.throws(
- () => {
- create('invalid-rest', 'always');
- },
- /** @param {Error} e */
- (e) => {
- return e.message === 'Invalid route invalid-rest/foo-[...rest]-bar.astro — rest parameter must be a standalone segment';
- }
- );
-});
+ test('disallows rest parameters inside segments', () => {
+ expect(() => create('invalid-rest', 'always')).toThrowError('Invalid route invalid-rest/foo-[...rest]-bar.astro — rest parameter must be a standalone segment');
+ });
-test('ignores things that look like lockfiles', () => {
- const { routes } = create('lockfiles', 'always');
- assert.equal(cleanRoutes(routes), [
- {
- type: 'page',
- pattern: /^\/foo\/$/,
- params: [],
- component: 'lockfiles/foo.astro',
- path: '/foo',
- },
- ]);
-});
+ test('ignores things that look like lockfiles', () => {
+ const { routes } = create('lockfiles', 'always');
+ expect(cleanRoutes(routes)).toEqual([
+ {
+ type: 'page',
+ pattern: /^\/foo\/$/,
+ params: [],
+ component: 'lockfiles/foo.astro',
+ pathname: '/foo',
+ },
+ ]);
+ });
-test('allows multiple slugs', () => {
- const { routes } = create('multiple-slugs', 'always');
+ test('allows multiple slugs', () => {
+ const { routes } = create('multiple-slugs', 'always');
- assert.equal(cleanRoutes(routes), [
- {
- type: 'page',
- pattern: /^\/([^/]+?)\.([^/]+?)\/$/,
- component: 'multiple-slugs/[file].[ext].astro',
- params: ['file', 'ext'],
- path: null,
- },
- ]);
-});
+ expect(cleanRoutes(routes)).toEqual([
+ {
+ type: 'page',
+ pattern: /^\/([^/]+?)\.([^/]+?)\/$/,
+ component: 'multiple-slugs/[file].[ext].astro',
+ params: ['file', 'ext'],
+ pathname: undefined,
+ },
+ ]);
+ });
-test('sorts routes correctly', () => {
- const { routes } = create('sorting', 'always');
+ test('sorts routes correctly', () => {
+ const { routes } = create('sorting', 'always');
- assert.equal(
- routes.map((p) => p.component),
- [
+ expect(routes.map((p) => p.component)).toEqual([
'sorting/index.astro',
'sorting/about.astro',
'sorting/post/index.astro',
@@ -231,8 +215,6 @@ test('sorts routes correctly', () => {
'sorting/[...rest]/deep/index.astro',
'sorting/[...rest]/abc.astro',
'sorting/[...rest]/index.astro',
- ]
- );
+ ]);
+ });
});
-
-test.run();
diff --git a/packages/astro/test/snowpack-log.test.js b/packages/astro/test/snowpack-log.test.js
deleted file mode 100644
index 31a67a589..000000000
--- a/packages/astro/test/snowpack-log.test.js
+++ /dev/null
@@ -1,83 +0,0 @@
-import { suite } from 'uvu';
-import * as assert from 'uvu/assert';
-import { clearCache, runDevServer } from './helpers.js';
-import isWindows from 'is-windows';
-
-// Skipping this entire suite for now as it is flakey.
-const skip = true;
-
-// For some reason Windows isn't getting anything from stdout in this test, not sure why.
-if (!skip && !isWindows()) {
- const SnowpackLogging = suite('snowpack logging');
- const MAX_TEST_TIME = 10000; // max time this test suite may take
-
- function numberOfEntries(stdout, message) {
- const exp = new RegExp(message, 'g');
- let count = 0;
- let res;
- while ((res = exp.exec(stdout))) {
- count++;
- }
- return count;
- }
-
- const root = new URL('./fixtures/astro/basic/', import.meta.url);
- const timers = {};
- let runError = null;
- SnowpackLogging.before(async (context) => {
- await clearCache();
-
- let importantMessages = 0;
- let stdout = '';
- try {
- const process = runDevServer(root, []);
-
- process.stdout.setEncoding('utf8');
- for await (const chunk of process.stdout) {
- stdout += chunk;
- if (/Server started/.test(chunk)) {
- importantMessages++;
- }
- if (/Ready/.test(chunk)) {
- importantMessages++;
- }
- if (/watching for file changes/.test(chunk)) {
- importantMessages++;
- }
- if (importantMessages === 3) {
- break;
- }
- }
-
- context.stdout = stdout;
- process.kill();
- } catch (err) {
- console.error(err);
- runError = runError;
- }
- });
-
- SnowpackLogging.before.each(({ __test__ }) => {
- timers[__test__] = setTimeout(() => {
- throw new Error(`Test "${__test__}" did not finish within allowed time`);
- }, MAX_TEST_TIME);
- });
-
- SnowpackLogging('dev server started up', () => {
- assert.equal(runError, null);
- });
-
- SnowpackLogging('Logs Ready message once', async ({ stdout }) => {
- assert.equal(numberOfEntries(stdout, 'Ready'), 1);
- });
-
- SnowpackLogging('Logs [waiting for file changes] once', ({ stdout }) => {
- assert.equal(numberOfEntries(stdout, 'watching for file changes'), 1);
- });
-
- SnowpackLogging.after.each(({ __test__ }) => {
- clearTimeout(timers[__test__]);
- });
-
- SnowpackLogging.run();
-}
diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js
index b53ff2f0f..3efe2d38c 100644
--- a/packages/astro/test/test-utils.js
+++ b/packages/astro/test/test-utils.js
@@ -1,6 +1,101 @@
-import cheerio from 'cheerio';
+import execa from 'execa';
+import fs from 'fs';
+import fetch from 'node-fetch';
+import { loadConfig } from '../dist/config.js';
+import dev from '../dist/dev/index.js';
+import build from '../dist/build/index.js';
+import preview from '../dist/preview/index.js';
-/** load html */
-export function doc(html) {
- return cheerio.load(html);
+let lastPort = 3000;
+
+/**
+ * Load Astro fixture
+ * @param {Object} inlineConfig Astro config partial (note: must specify projectRoot)
+ * @returns {Object} Fixture. Has the following properties:
+ * .config - Returns the final config. Will be automatically passed to the methods below:
+ *
+ * Dev
+ * .dev() - Async. Starts a dev server (note: you must call `await server.stop()` before test exit)
+ * .fetch() - Async. Returns a URL from the dev server (must have called .dev() before)
+ *
+ * Build
+ * .build() - Async. Builds into current folder (will erase previous build)
+ * .readFile(path) - Async. Read a file from the build.
+ * .preview() - Async. Starts a preview server. Note this can’t be running in same fixture as .dev() as they share ports. Also, you must call `server.close()` before test exit
+ * .fetch(url) - Async. Returns a URL from the prevew server (must have called .preview() before)
+ */
+export async function loadFixture(inlineConfig) {
+ if (!inlineConfig || !inlineConfig.projectRoot) throw new Error("Must provide { projectRoot: './fixtures/...' }");
+
+ // load config
+ let cwd = inlineConfig.projectRoot;
+ if (typeof cwd === 'string') {
+ try {
+ cwd = new URL(cwd.replace(/\/?$/, '/'));
+ } catch (err1) {
+ cwd = new URL(cwd.replace(/\/?$/, '/'), import.meta.url);
+ }
+ }
+
+ // get unique port
+ lastPort += 1; // note: tests run in parallel, and every test/fixture needs its own port. Increment by 1 every time this is called (can support thousands of tests)
+ if (!inlineConfig.devOptions) inlineConfig.devOptions = {};
+ inlineConfig.devOptions.port = lastPort;
+
+ // merge configs
+ if (!inlineConfig.buildOptions) inlineConfig.buildOptions = {};
+ if (inlineConfig.buildOptions.sitemap === undefined) inlineConfig.buildOptions.sitemap = false;
+ if (!inlineConfig.devOptions.hostname) inlineConfig.devOptions.hostname = 'localhost';
+ if (!inlineConfig.dist) inlineConfig.dist = './dist/';
+ if (!inlineConfig.pages) inlineConfig.pages = './src/pages/';
+ if (!inlineConfig.public) inlineConfig.public = './public/';
+ if (!inlineConfig.src) inlineConfig.src = './src/';
+ let config = await loadConfig(cwd);
+ config = merge(config, {
+ ...inlineConfig,
+ projectRoot: cwd,
+ dist: new URL(inlineConfig.dist, cwd),
+ pages: new URL(inlineConfig.pages, cwd),
+ public: new URL(inlineConfig.public, cwd),
+ src: new URL(inlineConfig.src, cwd),
+ });
+
+ return {
+ build: (opts = {}) => build(config, { logging: 'error', ...opts }),
+ dev: (opts = {}) => dev(config, { logging: 'error', ...opts }),
+ config,
+ fetch: (url) => fetch(`http://${config.devOptions.hostname}:${config.devOptions.port}${url}`),
+ readFile: (filePath) => fs.promises.readFile(new URL(`${filePath.replace(/^\/?/, '')}`, config.dist), 'utf8'),
+ preview: (opts = {}) => preview(config, { logging: 'error', ...opts }),
+ };
+}
+
+/**
+ * Basic object merge utility. Returns new copy of merged Object.
+ * @param {Object} a
+ * @param {Object} b
+ * @returns {Object}
+ */
+function merge(a, b) {
+ const allKeys = new Set([...Object.keys(a), ...Object.keys(b)]);
+ const c = {};
+ for (const k of allKeys) {
+ const needsObjectMerge =
+ typeof a[k] === 'object' && typeof b[k] === 'object' && Object.keys(a[k]).length && Object.keys(b[k]).length && !Array.isArray(a[k]) && !Array.isArray(b[k]);
+ if (needsObjectMerge) {
+ c[k] = merge(a[k] || {}, b[k] || {});
+ continue;
+ }
+ c[k] = a[k];
+ if (b[k] !== undefined) c[k] = b[k];
+ }
+ return c;
+}
+
+const cliURL = new URL('../astro.js', import.meta.url);
+/** Start Dev server via CLI */
+export function devCLI(root, additionalArgs = []) {
+ const args = [cliURL.pathname, 'dev', '--project-root', root.pathname].concat(additionalArgs);
+ const proc = execa('node', args);
+ return proc;
}
diff --git a/packages/astro/test/vue-component.test.js b/packages/astro/test/vue-component.test.js
index 1529d1f15..c0a62bdf8 100644
--- a/packages/astro/test/vue-component.test.js
+++ b/packages/astro/test/vue-component.test.js
@@ -1,26 +1,39 @@
-import { suite } from 'uvu';
-import * as assert from 'uvu/assert';
-import { doc } from './test-utils.js';
-import { setup, setupBuild } from './helpers.js';
+import cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
-const Vue = suite('Vue component test');
+describe('Vue component', () => {
+ let fixture;
+ let devServer;
-setup(Vue, './fixtures/vue-component');
-setupBuild(Vue, './fixtures/vue-component');
+ beforeAll(async () => {
+ fixture = await loadFixture({ projectRoot: './fixtures/vue-component/' });
+ devServer = await fixture.dev();
+ });
-Vue('Can load Vue', async ({ runtime }) => {
- const result = await runtime.load('/');
- assert.ok(!result.error, `build error: ${result.error}`);
+ test('Can load Vue', async () => {
+ const html = await fixture.fetch('/').then((res) => res.text());
+ const $ = cheerio.load(html);
- const $ = doc(result.contents);
- const allPreValues = $('pre')
- .toArray()
- .map((el) => $(el).text());
- assert.equal(allPreValues, ['0', '1', '10', '100', '1000'], 'renders all components correctly');
- assert.equal($('astro-root').length, 4, 'renders 3 astro-roots');
- assert.equal($('astro-root[uid]').length, 4, 'all astro-roots have uid attributes');
- const uniqueRootUIDs = $('astro-root').map((i, el) => $(el).attr('uid'));
- assert.equal(new Set(uniqueRootUIDs).size, 4, 'all astro-roots have unique uid attributes');
+ const allPreValues = $('pre')
+ .toArray()
+ .map((el) => $(el).text());
+
+ // test 1: renders all components correctly
+ expect(allPreValues).toEqual(['0', '1', '10', '100', '1000']);
+
+ // test 2: renders 3 s
+ expect($('astro-root')).toHaveLength(4);
+
+ // test 3: all s have uid attributes
+ expect($('astro-root[uid]')).toHaveLength(4);
+
+ // test 5: all s have unique uid attributes
+ const uniqueRootUIDs = $('astro-root').map((i, el) => $(el).attr('uid'));
+ expect(new Set(uniqueRootUIDs).size).toBe(4);
+ });
+
+ // important: close dev server (free up port and connection)
+ afterAll(async () => {
+ await devServer.stop();
+ });
});
-
-Vue.run();
diff --git a/yarn.lock b/yarn.lock
index f5e30d1f6..c532df5da 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -106,6 +106,13 @@
"@algolia/logger-common" "4.10.5"
"@algolia/requester-common" "4.10.5"
+"@astrojs/compiler@^0.1.0-canary.36":
+ version "0.1.0-canary.36"
+ resolved "https://registry.yarnpkg.com/@astrojs/compiler/-/compiler-0.1.0-canary.36.tgz#097b364e28093cca883e73797db9e8d1407e4dab"
+ integrity sha512-T4pTA+GJQoMzfJYb9SQnQEQjqUZo1LgcLNFNkziZijAANnbCF6GBGg5d1IWCyHuMaCKvPUrAWBi0olLzzuracw==
+ dependencies:
+ typescript "^4.3.5"
+
"@astrojs/language-server@^0.7.16":
version "0.7.16"
resolved "https://registry.yarnpkg.com/@astrojs/language-server/-/language-server-0.7.16.tgz#54ac89c70ec7a6ab2712d4f15357017e795db34a"
@@ -148,7 +155,7 @@
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176"
integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==
-"@babel/core@^7.15.0":
+"@babel/core@^7.1.0", "@babel/core@^7.15.0", "@babel/core@^7.7.2", "@babel/core@^7.7.5":
version "7.15.0"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.0.tgz#749e57c68778b73ad8082775561f67f5196aafa8"
integrity sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw==
@@ -178,7 +185,7 @@
jsesc "^2.5.1"
source-map "^0.5.0"
-"@babel/generator@^7.14.8", "@babel/generator@^7.15.0":
+"@babel/generator@^7.14.8", "@babel/generator@^7.15.0", "@babel/generator@^7.7.2":
version "7.15.0"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.0.tgz#a7d0c172e0d814974bad5aa77ace543b97917f15"
integrity sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==
@@ -294,7 +301,7 @@
dependencies:
"@babel/types" "^7.14.5"
-"@babel/helper-plugin-utils@^7.14.5":
+"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9"
integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==
@@ -358,7 +365,7 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
-"@babel/parser@^7.1.0", "@babel/parser@^7.14.8", "@babel/parser@^7.15.0":
+"@babel/parser@^7.1.0", "@babel/parser@^7.14.8", "@babel/parser@^7.15.0", "@babel/parser@^7.7.2":
version "7.15.3"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.3.tgz#3416d9bea748052cfcb63dbcc27368105b1ed862"
integrity sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==
@@ -373,6 +380,41 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.8.tgz#66fd41666b2d7b840bd5ace7f7416d5ac60208d4"
integrity sha512-syoCQFOoo/fzkWDeM0dLEZi5xqurb5vuyzwIMNZRNun+N/9A4cUZeQaE7dTrB8jGaKuJRBtEOajtnmw0I5hvvA==
+"@babel/plugin-syntax-async-generators@^7.8.4":
+ version "7.8.4"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d"
+ integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-bigint@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea"
+ integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-class-properties@^7.8.3":
+ version "7.12.13"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10"
+ integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.12.13"
+
+"@babel/plugin-syntax-import-meta@^7.8.3":
+ version "7.10.4"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51"
+ integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.4"
+
+"@babel/plugin-syntax-json-strings@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a"
+ integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
"@babel/plugin-syntax-jsx@^7.10.4", "@babel/plugin-syntax-jsx@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.14.5.tgz#000e2e25d8673cce49300517a3eda44c263e4201"
@@ -380,6 +422,62 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
+"@babel/plugin-syntax-logical-assignment-operators@^7.8.3":
+ version "7.10.4"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699"
+ integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.4"
+
+"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9"
+ integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-numeric-separator@^7.8.3":
+ version "7.10.4"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97"
+ integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.10.4"
+
+"@babel/plugin-syntax-object-rest-spread@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871"
+ integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-optional-catch-binding@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1"
+ integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-optional-chaining@^7.8.3":
+ version "7.8.3"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a"
+ integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.8.0"
+
+"@babel/plugin-syntax-top-level-await@^7.8.3":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c"
+ integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.14.5"
+
+"@babel/plugin-syntax-typescript@^7.7.2":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716"
+ integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.14.5"
+
"@babel/plugin-transform-react-jsx@^7.14.5":
version "7.14.9"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.14.9.tgz#3314b2163033abac5200a869c4de242cd50a914c"
@@ -398,7 +496,7 @@
dependencies:
regenerator-runtime "^0.13.4"
-"@babel/template@^7.14.5":
+"@babel/template@^7.14.5", "@babel/template@^7.3.3":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4"
integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==
@@ -416,6 +514,21 @@
"@babel/parser" "^7.15.4"
"@babel/types" "^7.15.4"
+"@babel/traverse@^7.1.0", "@babel/traverse@^7.15.0", "@babel/traverse@^7.7.2":
+ version "7.15.0"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.0.tgz#4cca838fd1b2a03283c1f38e141f639d60b3fc98"
+ integrity sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==
+ dependencies:
+ "@babel/code-frame" "^7.14.5"
+ "@babel/generator" "^7.15.0"
+ "@babel/helper-function-name" "^7.14.5"
+ "@babel/helper-hoist-variables" "^7.14.5"
+ "@babel/helper-split-export-declaration" "^7.14.5"
+ "@babel/parser" "^7.15.0"
+ "@babel/types" "^7.15.0"
+ debug "^4.1.0"
+ globals "^11.1.0"
+
"@babel/traverse@^7.13.15":
version "7.15.4"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d"
@@ -431,21 +544,6 @@
debug "^4.1.0"
globals "^11.1.0"
-"@babel/traverse@^7.15.0":
- version "7.15.0"
- resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.0.tgz#4cca838fd1b2a03283c1f38e141f639d60b3fc98"
- integrity sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==
- dependencies:
- "@babel/code-frame" "^7.14.5"
- "@babel/generator" "^7.15.0"
- "@babel/helper-function-name" "^7.14.5"
- "@babel/helper-hoist-variables" "^7.14.5"
- "@babel/helper-split-export-declaration" "^7.14.5"
- "@babel/parser" "^7.15.0"
- "@babel/types" "^7.15.0"
- debug "^4.1.0"
- globals "^11.1.0"
-
"@babel/traverse@^7.4.5":
version "7.14.8"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.8.tgz#c0253f02677c5de1a8ff9df6b0aacbec7da1a8ce"
@@ -469,7 +567,7 @@
"@babel/helper-validator-identifier" "^7.14.8"
to-fast-properties "^2.0.0"
-"@babel/types@^7.14.9", "@babel/types@^7.15.0", "@babel/types@^7.3.0":
+"@babel/types@^7.14.9", "@babel/types@^7.15.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3":
version "7.15.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd"
integrity sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==
@@ -485,6 +583,11 @@
"@babel/helper-validator-identifier" "^7.14.9"
to-fast-properties "^2.0.0"
+"@bcoe/v8-coverage@^0.2.3":
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
+ integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
+
"@changesets/apply-release-plan@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@changesets/apply-release-plan/-/apply-release-plan-5.0.0.tgz#11bf168acecbf4cfa2b0e6425160bac5ceeec1c3"
@@ -759,6 +862,191 @@
resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340"
integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==
+"@istanbuljs/load-nyc-config@^1.0.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced"
+ integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==
+ dependencies:
+ camelcase "^5.3.1"
+ find-up "^4.1.0"
+ get-package-type "^0.1.0"
+ js-yaml "^3.13.1"
+ resolve-from "^5.0.0"
+
+"@istanbuljs/schema@^0.1.2":
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98"
+ integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==
+
+"@jest/console@^27.1.0":
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.1.0.tgz#de13b603cb1d389b50c0dc6296e86e112381e43c"
+ integrity sha512-+Vl+xmLwAXLNlqT61gmHEixeRbS4L8MUzAjtpBCOPWH+izNI/dR16IeXjkXJdRtIVWVSf9DO1gdp67B1XorZhQ==
+ dependencies:
+ "@jest/types" "^27.1.0"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ jest-message-util "^27.1.0"
+ jest-util "^27.1.0"
+ slash "^3.0.0"
+
+"@jest/core@^27.1.0":
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.1.0.tgz#622220f18032f5869e579cecbe744527238648bf"
+ integrity sha512-3l9qmoknrlCFKfGdrmiQiPne+pUR4ALhKwFTYyOeKw6egfDwJkO21RJ1xf41rN8ZNFLg5W+w6+P4fUqq4EMRWA==
+ dependencies:
+ "@jest/console" "^27.1.0"
+ "@jest/reporters" "^27.1.0"
+ "@jest/test-result" "^27.1.0"
+ "@jest/transform" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ "@types/node" "*"
+ ansi-escapes "^4.2.1"
+ chalk "^4.0.0"
+ emittery "^0.8.1"
+ exit "^0.1.2"
+ graceful-fs "^4.2.4"
+ jest-changed-files "^27.1.0"
+ jest-config "^27.1.0"
+ jest-haste-map "^27.1.0"
+ jest-message-util "^27.1.0"
+ jest-regex-util "^27.0.6"
+ jest-resolve "^27.1.0"
+ jest-resolve-dependencies "^27.1.0"
+ jest-runner "^27.1.0"
+ jest-runtime "^27.1.0"
+ jest-snapshot "^27.1.0"
+ jest-util "^27.1.0"
+ jest-validate "^27.1.0"
+ jest-watcher "^27.1.0"
+ micromatch "^4.0.4"
+ p-each-series "^2.1.0"
+ rimraf "^3.0.0"
+ slash "^3.0.0"
+ strip-ansi "^6.0.0"
+
+"@jest/environment@^27.1.0":
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.1.0.tgz#c7224a67004759ec203d8fa44e8bc0db93f66c44"
+ integrity sha512-wRp50aAMY2w1U2jP1G32d6FUVBNYqmk8WaGkiIEisU48qyDV0WPtw3IBLnl7orBeggveommAkuijY+RzVnNDOQ==
+ dependencies:
+ "@jest/fake-timers" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ "@types/node" "*"
+ jest-mock "^27.1.0"
+
+"@jest/fake-timers@^27.1.0":
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.1.0.tgz#c0b343d8a16af17eab2cb6862e319947c0ea2abe"
+ integrity sha512-22Zyn8il8DzpS+30jJNVbTlm7vAtnfy1aYvNeOEHloMlGy1PCYLHa4PWlSws0hvNsMM5bON6GISjkLoQUV3oMA==
+ dependencies:
+ "@jest/types" "^27.1.0"
+ "@sinonjs/fake-timers" "^7.0.2"
+ "@types/node" "*"
+ jest-message-util "^27.1.0"
+ jest-mock "^27.1.0"
+ jest-util "^27.1.0"
+
+"@jest/globals@^27.1.0":
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.1.0.tgz#e093a49c718dd678a782c197757775534c88d3f2"
+ integrity sha512-73vLV4aNHAlAgjk0/QcSIzzCZSqVIPbmFROJJv9D3QUR7BI4f517gVdJpSrCHxuRH3VZFhe0yGG/tmttlMll9g==
+ dependencies:
+ "@jest/environment" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ expect "^27.1.0"
+
+"@jest/reporters@^27.1.0":
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.1.0.tgz#02ed1e6601552c2f6447378533f77aad002781d4"
+ integrity sha512-5T/zlPkN2HnK3Sboeg64L5eC8iiaZueLpttdktWTJsvALEtP2YMkC5BQxwjRWQACG9SwDmz+XjjkoxXUDMDgdw==
+ dependencies:
+ "@bcoe/v8-coverage" "^0.2.3"
+ "@jest/console" "^27.1.0"
+ "@jest/test-result" "^27.1.0"
+ "@jest/transform" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ chalk "^4.0.0"
+ collect-v8-coverage "^1.0.0"
+ exit "^0.1.2"
+ glob "^7.1.2"
+ graceful-fs "^4.2.4"
+ istanbul-lib-coverage "^3.0.0"
+ istanbul-lib-instrument "^4.0.3"
+ istanbul-lib-report "^3.0.0"
+ istanbul-lib-source-maps "^4.0.0"
+ istanbul-reports "^3.0.2"
+ jest-haste-map "^27.1.0"
+ jest-resolve "^27.1.0"
+ jest-util "^27.1.0"
+ jest-worker "^27.1.0"
+ slash "^3.0.0"
+ source-map "^0.6.0"
+ string-length "^4.0.1"
+ terminal-link "^2.0.0"
+ v8-to-istanbul "^8.0.0"
+
+"@jest/source-map@^27.0.6":
+ version "27.0.6"
+ resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.0.6.tgz#be9e9b93565d49b0548b86e232092491fb60551f"
+ integrity sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==
+ dependencies:
+ callsites "^3.0.0"
+ graceful-fs "^4.2.4"
+ source-map "^0.6.0"
+
+"@jest/test-result@^27.1.0":
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.1.0.tgz#9345ae5f97f6a5287af9ebd54716cd84331d42e8"
+ integrity sha512-Aoz00gpDL528ODLghat3QSy6UBTD5EmmpjrhZZMK/v1Q2/rRRqTGnFxHuEkrD4z/Py96ZdOHxIWkkCKRpmnE1A==
+ dependencies:
+ "@jest/console" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ "@types/istanbul-lib-coverage" "^2.0.0"
+ collect-v8-coverage "^1.0.0"
+
+"@jest/test-sequencer@^27.1.0":
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.1.0.tgz#04e8b3bd735570d3d48865e74977a14dc99bff2d"
+ integrity sha512-lnCWawDr6Z1DAAK9l25o3AjmKGgcutq1iIbp+hC10s/HxnB8ZkUsYq1FzjOoxxZ5hW+1+AthBtvS4x9yno3V1A==
+ dependencies:
+ "@jest/test-result" "^27.1.0"
+ graceful-fs "^4.2.4"
+ jest-haste-map "^27.1.0"
+ jest-runtime "^27.1.0"
+
+"@jest/transform@^27.1.0":
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.1.0.tgz#962e385517e3d1f62827fa39c305edcc3ca8544b"
+ integrity sha512-ZRGCA2ZEVJ00ubrhkTG87kyLbN6n55g1Ilq0X9nJb5bX3MhMp3O6M7KG+LvYu+nZRqG5cXsQnJEdZbdpTAV8pQ==
+ dependencies:
+ "@babel/core" "^7.1.0"
+ "@jest/types" "^27.1.0"
+ babel-plugin-istanbul "^6.0.0"
+ chalk "^4.0.0"
+ convert-source-map "^1.4.0"
+ fast-json-stable-stringify "^2.0.0"
+ graceful-fs "^4.2.4"
+ jest-haste-map "^27.1.0"
+ jest-regex-util "^27.0.6"
+ jest-util "^27.1.0"
+ micromatch "^4.0.4"
+ pirates "^4.0.1"
+ slash "^3.0.0"
+ source-map "^0.6.1"
+ write-file-atomic "^3.0.0"
+
+"@jest/types@^27.1.0":
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.1.0.tgz#674a40325eab23c857ebc0689e7e191a3c5b10cc"
+ integrity sha512-pRP5cLIzN7I7Vp6mHKRSaZD7YpBTK7hawx5si8trMKqk4+WOdK8NEKOTO2G8PKWD1HbKMVckVB6/XHh/olhf2g==
+ dependencies:
+ "@types/istanbul-lib-coverage" "^2.0.0"
+ "@types/istanbul-reports" "^3.0.0"
+ "@types/node" "*"
+ "@types/yargs" "^16.0.0"
+ chalk "^4.0.0"
+
"@jsdevtools/rehype-toc@3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@jsdevtools/rehype-toc/-/rehype-toc-3.0.2.tgz#29c32e6b40cd4b5dafd96cb90d5057ac5dab4a51"
@@ -1463,9 +1751,9 @@
resolve "^1.10.1"
"@lit/reactive-element@^1.0.0":
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-1.0.0.tgz#7b6e6a85709cda0370c47e425ac2f3b553696a4b"
- integrity sha512-Kpgenb8UNFsKCsFhggiVvUkCbcFQSd6N8hffYEEGjz27/4rw3cTSsmP9t3q1EHOAsdum60Wo64HvuZDFpEwexA==
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-1.0.1.tgz#853cacd4d78d79059f33f66f8e7b0e5c34bee294"
+ integrity sha512-nSD5AA2AZkKuXuvGs8IK7K5ZczLAogfDd26zT9l6S7WzvqALdVWcW5vMUiTnZyj5SPcNwNNANj0koeV1ieqTFQ==
"@ljharb/has-package-exports-patterns@0.0.1":
version "0.0.1"
@@ -1571,34 +1859,14 @@
node-gyp "^7.1.0"
read-package-json-fast "^2.0.1"
-"@octokit/action@^3.15.4":
- version "3.15.4"
- resolved "https://registry.yarnpkg.com/@octokit/action/-/action-3.15.4.tgz#b7bf36e34082c046231927d12537dfd08f6f1d5a"
- integrity sha512-MQRdhjl03FefgJiHRQhyHVsAOIZWUwrZi9m6Kw0tS3/QWM3P64s4Nfs7rd+Vk8KvFyZE5x8c/sb/90pBVrqFPw==
- dependencies:
- "@octokit/auth-action" "^1.2.0"
- "@octokit/core" "^3.0.0"
- "@octokit/plugin-paginate-rest" "^2.2.4"
- "@octokit/plugin-rest-endpoint-methods" "5.10.1"
- "@octokit/types" "^6.16.1"
- https-proxy-agent "^5.0.0"
-
-"@octokit/auth-action@^1.2.0":
- version "1.3.3"
- resolved "https://registry.yarnpkg.com/@octokit/auth-action/-/auth-action-1.3.3.tgz#20004fbf0b4a7012f4f7fc2c54d263749239cd5f"
- integrity sha512-8v4c/pw6HTxsF7pCgJoox/q4KKov4zkgLxEGGqLOZPSZaHf1LqdLlj5m5x5c1bKNn38uQXNvJKEnKX1qJlGeQQ==
- dependencies:
- "@octokit/auth-token" "^2.4.0"
- "@octokit/types" "^6.0.3"
-
-"@octokit/auth-token@^2.4.0", "@octokit/auth-token@^2.4.4":
+"@octokit/auth-token@^2.4.4":
version "2.4.5"
resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.4.5.tgz#568ccfb8cb46f36441fac094ce34f7a875b197f3"
integrity sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==
dependencies:
"@octokit/types" "^6.0.3"
-"@octokit/core@^3.0.0", "@octokit/core@^3.5.0":
+"@octokit/core@^3.5.0":
version "3.5.1"
resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.5.1.tgz#8601ceeb1ec0e1b1b8217b960a413ed8e947809b"
integrity sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==
@@ -1629,16 +1897,6 @@
"@octokit/types" "^6.0.3"
universal-user-agent "^6.0.0"
-"@octokit/openapi-types@^10.0.0":
- version "10.0.0"
- resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-10.0.0.tgz#db4335de99509021f501fc4e026e6ff495fe1e62"
- integrity sha512-k1iO2zKuEjjRS1EJb4FwSLk+iF6EGp+ZV0OMRViQoWhQ1fZTk9hg1xccZII5uyYoiqcbC73MRBmT45y1vp2PPg==
-
-"@octokit/openapi-types@^10.2.2":
- version "10.2.2"
- resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-10.2.2.tgz#6c1c839d7d169feabaf1d2a69c79439c75d979cd"
- integrity sha512-EVcXQ+ZrC04cg17AMg1ofocWMxHDn17cB66ZHgYc0eUwjFtxS0oBzkyw2VqIrHBwVgtfoYrq1WMQfQmMjUwthw==
-
"@octokit/openapi-types@^9.5.0":
version "9.7.0"
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-9.7.0.tgz#9897cdefd629cd88af67b8dbe2e5fb19c63426b2"
@@ -1649,13 +1907,6 @@
resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437"
integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==
-"@octokit/plugin-paginate-rest@^2.2.4":
- version "2.16.0"
- resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.0.tgz#09dbda2e5fbca022e3cdf76b63618f7b357c9f0c"
- integrity sha512-8YYzALPMvEZ35kgy5pdYvQ22Roz+BIuEaedO575GwE2vb/ACDqQn0xQrTJR4tnZCJn7pi8+AWPVjrFDaERIyXQ==
- dependencies:
- "@octokit/types" "^6.26.0"
-
"@octokit/plugin-paginate-rest@^2.6.2":
version "2.15.1"
resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.15.1.tgz#264189dd3ce881c6c33758824aac05a4002e056a"
@@ -1668,14 +1919,6 @@
resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85"
integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==
-"@octokit/plugin-rest-endpoint-methods@5.10.1":
- version "5.10.1"
- resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.10.1.tgz#9683c4cf476fb6c80f668c4b468919e69c71f66a"
- integrity sha512-Rf1iMl40I0dIxjh1g32qZ6Ym/uT8QWZMm2vYGG5Vi8SX1MwZvbuxEGXYgmzTUWSD3PYWSLilE2+4L8kmdLGTMg==
- dependencies:
- "@octokit/types" "^6.27.0"
- deprecation "^2.3.1"
-
"@octokit/plugin-rest-endpoint-methods@5.8.0":
version "5.8.0"
resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.8.0.tgz#33b342fe41f2603fdf8b958e6652103bb3ea3f3b"
@@ -1722,20 +1965,6 @@
dependencies:
"@octokit/openapi-types" "^9.5.0"
-"@octokit/types@^6.26.0":
- version "6.26.0"
- resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.26.0.tgz#b8af298485d064ad9424cb41520541c1bf820346"
- integrity sha512-RDxZBAFMtqs1ZPnbUu1e7ohPNfoNhTiep4fErY7tZs995BeHu369Vsh5woMIaFbllRWEZBfvTCS4hvDnMPiHrA==
- dependencies:
- "@octokit/openapi-types" "^10.0.0"
-
-"@octokit/types@^6.27.0":
- version "6.28.1"
- resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.28.1.tgz#ab990d1fe952226055e81c7650480e6bacfb877c"
- integrity sha512-XlxDoQLFO5JnFZgKVQTYTvXRsQFfr/GwDUU108NJ9R5yFPkA2qXhTJjYuul3vE4eLXP40FA2nysOu2zd6boE+w==
- dependencies:
- "@octokit/openapi-types" "^10.2.2"
-
"@rollup/pluginutils@^4.1.1":
version "4.1.1"
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.1.tgz#1d4da86dd4eded15656a57d933fda2b9a08d47ec"
@@ -1770,6 +1999,20 @@
retext-smartypants "^4.0.0"
unist-util-visit "^2.0.1"
+"@sinonjs/commons@^1.7.0":
+ version "1.8.3"
+ resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d"
+ integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==
+ dependencies:
+ type-detect "4.0.8"
+
+"@sinonjs/fake-timers@^7.0.2":
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5"
+ integrity sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==
+ dependencies:
+ "@sinonjs/commons" "^1.7.0"
+
"@snowpack/plugin-dotenv@^2.1.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@snowpack/plugin-dotenv/-/plugin-dotenv-2.2.0.tgz#624348a83e28ae523a7d2695cbe81f53381bc964"
@@ -1832,7 +2075,7 @@
dependencies:
"@types/estree" "*"
-"@types/babel__core@^7.1.15":
+"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.15":
version "7.1.15"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.15.tgz#2ccfb1ad55a02c83f8e0ad327cbc332f55eb1024"
integrity sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew==
@@ -1858,7 +2101,7 @@
"@babel/parser" "^7.1.0"
"@babel/types" "^7.0.0"
-"@types/babel__traverse@*":
+"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6":
version "7.14.2"
resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43"
integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==
@@ -1901,11 +2144,25 @@
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.48.tgz#18dc8091b285df90db2f25aa7d906cfc394b7f74"
integrity sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew==
+"@types/etag@^1.8.1":
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/@types/etag/-/etag-1.8.1.tgz#593ca8ddb43acb3db049bd0955fd64d281ab58b9"
+ integrity sha512-bsKkeSqN7HYyYntFRAmzcwx/dKW4Wa+KVMTInANlI72PWLQmOpZu96j0OqHZGArW4VQwCmJPteQlXaUDeOB0WQ==
+ dependencies:
+ "@types/node" "*"
+
"@types/github-slugger@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@types/github-slugger/-/github-slugger-1.3.0.tgz#16ab393b30d8ae2a111ac748a015ac05a1fc5524"
integrity sha512-J/rMZa7RqiH/rT29TEVZO4nBoDP9XJOjnbbIofg7GQKs4JIduEO3WLpte+6WeUz/TcrXKlY+bM7FYrp8yFB+3g==
+"@types/graceful-fs@^4.1.2":
+ version "4.1.5"
+ resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15"
+ integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==
+ dependencies:
+ "@types/node" "*"
+
"@types/hast@^2.0.0", "@types/hast@^2.3.2":
version "2.3.4"
resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc"
@@ -1913,6 +2170,33 @@
dependencies:
"@types/unist" "*"
+"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1":
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762"
+ integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==
+
+"@types/istanbul-lib-report@*":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686"
+ integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==
+ dependencies:
+ "@types/istanbul-lib-coverage" "*"
+
+"@types/istanbul-reports@^3.0.0":
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff"
+ integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==
+ dependencies:
+ "@types/istanbul-lib-report" "*"
+
+"@types/jest@^27.0.1":
+ version "27.0.1"
+ resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.0.1.tgz#fafcc997da0135865311bb1215ba16dba6bdf4ca"
+ integrity sha512-HTLpVXHrY69556ozYkcq47TtQJXpcWAWfkoqz+ZGz2JnmZhzlRjprCIyFnetSy8gpDWwTTGBcRVv1J1I1vBrHw==
+ dependencies:
+ jest-diff "^27.0.0"
+ pretty-format "^27.0.0"
+
"@types/json-schema@^7.0.7":
version "7.0.9"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
@@ -1993,6 +2277,11 @@
resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.1.tgz#f8ae4fbcd2b9ba4ff934698e28778961f9cb22ca"
integrity sha512-ARATsLdrGPUnaBvxLhUlnltcMgn7pQG312S8ccdYlnyijabrX9RN/KN/iGj9Am96CoW8e/K9628BA7Bv4XHdrA==
+"@types/prettier@^2.1.5":
+ version "2.3.2"
+ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.2.tgz#fc8c2825e4ed2142473b4a81064e6e081463d1b3"
+ integrity sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==
+
"@types/prompts@^2.0.12":
version "2.0.14"
resolved "https://registry.yarnpkg.com/@types/prompts/-/prompts-2.0.14.tgz#10cb8899844bb0771cabe57c1becaaaca9a3b521"
@@ -2013,6 +2302,11 @@
"@types/mime" "^1"
"@types/node" "*"
+"@types/stack-utils@^2.0.0":
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
+ integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==
+
"@types/trusted-types@^2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756"
@@ -2023,11 +2317,18 @@
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
-"@types/yargs-parser@^20.2.1":
+"@types/yargs-parser@*", "@types/yargs-parser@^20.2.1":
version "20.2.1"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129"
integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==
+"@types/yargs@^16.0.0":
+ version "16.0.4"
+ resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977"
+ integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==
+ dependencies:
+ "@types/yargs-parser" "*"
+
"@typescript-eslint/eslint-plugin@^4.22.0":
version "4.29.3"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.3.tgz#95cb8029a8bd8bd9c7f4ab95074a7cb2115adefa"
@@ -2232,6 +2533,11 @@ JSONStream@^1.0.4:
jsonparse "^1.2.0"
through ">=2.2.7 <3"
+abab@^2.0.3, abab@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a"
+ integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==
+
abbrev@1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
@@ -2245,6 +2551,14 @@ accepts@^1.3.5:
mime-types "~2.1.24"
negotiator "0.6.2"
+acorn-globals@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45"
+ integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==
+ dependencies:
+ acorn "^7.1.1"
+ acorn-walk "^7.1.1"
+
acorn-jsx@^5.3.1:
version "5.3.2"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
@@ -2259,16 +2573,21 @@ acorn-node@^1.6.1:
acorn-walk "^7.0.0"
xtend "^4.0.2"
-acorn-walk@^7.0.0:
+acorn-walk@^7.0.0, acorn-walk@^7.1.1:
version "7.2.0"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
-acorn@^7.0.0, acorn@^7.4.0:
+acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0:
version "7.4.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
+acorn@^8.2.4:
+ version "8.4.1"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c"
+ integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==
+
add-stream@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa"
@@ -2413,12 +2732,17 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
dependencies:
color-convert "^2.0.1"
+ansi-styles@^5.0.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
+ integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
+
any-promise@^1.1.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
-anymatch@~3.1.2:
+anymatch@^3.0.3, anymatch@~3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
@@ -2608,6 +2932,41 @@ axios@^0.21.1:
dependencies:
follow-redirects "^1.10.0"
+babel-jest@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.1.0.tgz#e96ca04554fd32274439869e2b6d24de9d91bc4e"
+ integrity sha512-6NrdqzaYemALGCuR97QkC/FkFIEBWP5pw5TMJoUHZTVXyOgocujp6A0JE2V6gE0HtqAAv6VKU/nI+OCR1Z4gHA==
+ dependencies:
+ "@jest/transform" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ "@types/babel__core" "^7.1.14"
+ babel-plugin-istanbul "^6.0.0"
+ babel-preset-jest "^27.0.6"
+ chalk "^4.0.0"
+ graceful-fs "^4.2.4"
+ slash "^3.0.0"
+
+babel-plugin-istanbul@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765"
+ integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==
+ dependencies:
+ "@babel/helper-plugin-utils" "^7.0.0"
+ "@istanbuljs/load-nyc-config" "^1.0.0"
+ "@istanbuljs/schema" "^0.1.2"
+ istanbul-lib-instrument "^4.0.0"
+ test-exclude "^6.0.0"
+
+babel-plugin-jest-hoist@^27.0.6:
+ version "27.0.6"
+ resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.6.tgz#f7c6b3d764af21cb4a2a1ab6870117dbde15b456"
+ integrity sha512-CewFeM9Vv2gM7Yr9n5eyyLVPRSiBnk6lKZRjgwYnGKSl9M14TMn2vkN02wTF04OGuSDLEzlWiMzvjXuW9mB6Gw==
+ dependencies:
+ "@babel/template" "^7.3.3"
+ "@babel/types" "^7.3.3"
+ "@types/babel__core" "^7.0.0"
+ "@types/babel__traverse" "^7.0.6"
+
babel-plugin-jsx-dom-expressions@^0.29.14:
version "0.29.14"
resolved "https://registry.yarnpkg.com/babel-plugin-jsx-dom-expressions/-/babel-plugin-jsx-dom-expressions-0.29.14.tgz#f5bd1c5da2f32dd1db89d5b654c9fa02a8cd5213"
@@ -2628,6 +2987,32 @@ babel-plugin-module-resolver@^4.1.0:
reselect "^4.0.0"
resolve "^1.13.1"
+babel-preset-current-node-syntax@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b"
+ integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==
+ dependencies:
+ "@babel/plugin-syntax-async-generators" "^7.8.4"
+ "@babel/plugin-syntax-bigint" "^7.8.3"
+ "@babel/plugin-syntax-class-properties" "^7.8.3"
+ "@babel/plugin-syntax-import-meta" "^7.8.3"
+ "@babel/plugin-syntax-json-strings" "^7.8.3"
+ "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3"
+ "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
+ "@babel/plugin-syntax-numeric-separator" "^7.8.3"
+ "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
+ "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
+ "@babel/plugin-syntax-optional-chaining" "^7.8.3"
+ "@babel/plugin-syntax-top-level-await" "^7.8.3"
+
+babel-preset-jest@^27.0.6:
+ version "27.0.6"
+ resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.0.6.tgz#909ef08e9f24a4679768be2f60a3df0856843f9d"
+ integrity sha512-WObA0/Biw2LrVVwZkF/2GqbOdzhKD6Fkdwhoy9ASIrOWr/zodcSpQh72JOkEn6NWyjmnPDjNSqaGN4KnpKzhXw==
+ dependencies:
+ babel-plugin-jest-hoist "^27.0.6"
+ babel-preset-current-node-syntax "^1.0.0"
+
babel-preset-solid@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/babel-preset-solid/-/babel-preset-solid-1.1.1.tgz#be8a381cdc92323e3bc636f216cd24622d8183a1"
@@ -2786,6 +3171,11 @@ broken-link-checker@^0.7.8:
urlcache "~0.7.0"
urlobj "0.0.11"
+browser-process-hrtime@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626"
+ integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==
+
browserslist@^4.16.6:
version "4.16.8"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.8.tgz#cb868b0b554f137ba6e33de0ecff2eda403c4fb0"
@@ -2808,6 +3198,13 @@ browserslist@^4.17.3:
node-releases "^2.0.0"
picocolors "^1.0.0"
+bser@2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05"
+ integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==
+ dependencies:
+ node-int64 "^0.4.0"
+
buffer-crc32@~0.2.3:
version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
@@ -2941,6 +3338,11 @@ camelcase@^5.0.0, camelcase@^5.3.1:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
+camelcase@^6.2.0:
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
+ integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
+
caniuse-lite@^1.0.30001243, caniuse-lite@^1.0.30001251:
version "1.0.30001251"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz#6853a606ec50893115db660f82c094d18f096d85"
@@ -3008,6 +3410,11 @@ chalk@~0.5.1:
strip-ansi "^0.3.0"
supports-color "^0.2.0"
+char-regex@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf"
+ integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==
+
char-spinner@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/char-spinner/-/char-spinner-1.0.1.tgz#e6ea67bd247e107112983b7ab0479ed362800081"
@@ -3113,11 +3520,16 @@ ci-info@^2.0.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46"
integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==
-ci-info@^3.2.0:
+ci-info@^3.1.1, ci-info@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.2.0.tgz#2876cb948a498797b5236f0095bc057d0dca38b6"
integrity sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==
+cjs-module-lexer@^1.0.0:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40"
+ integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==
+
clean-css@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
@@ -3208,6 +3620,11 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
+collect-v8-coverage@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59"
+ integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==
+
color-convert@^1.9.0, color-convert@^1.9.3:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@@ -3475,7 +3892,7 @@ conventional-recommended-bump@^6.1.0:
meow "^8.0.0"
q "^1.5.1"
-convert-source-map@^1.7.0:
+convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369"
integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==
@@ -3582,6 +3999,23 @@ cssesc@^3.0.0:
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
+cssom@^0.4.4:
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10"
+ integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==
+
+cssom@~0.3.6:
+ version "0.3.8"
+ resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a"
+ integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==
+
+cssstyle@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852"
+ integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==
+ dependencies:
+ cssom "~0.3.6"
+
csstype@^2.6.8:
version "2.6.17"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.17.tgz#4cf30eb87e1d1a005d8b6510f95292413f6a1c0e"
@@ -3624,6 +4058,15 @@ dashdash@^1.12.0:
dependencies:
assert-plus "^1.0.0"
+data-urls@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b"
+ integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==
+ dependencies:
+ abab "^2.0.3"
+ whatwg-mimetype "^2.3.0"
+ whatwg-url "^8.0.0"
+
dateformat@^3.0.0:
version "3.0.3"
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
@@ -3675,6 +4118,11 @@ decamelize@^1.1.0, decamelize@^1.2.0:
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
+decimal.js@^10.2.1:
+ version "10.3.1"
+ resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783"
+ integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==
+
decode-uri-component@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
@@ -3690,7 +4138,7 @@ deep-equal@~1.0.1:
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=
-deep-is@^0.1.3:
+deep-is@^0.1.3, deep-is@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
@@ -3790,6 +4238,11 @@ detect-indent@^6.0.0:
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6"
integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==
+detect-newline@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
+ integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==
+
detective@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.0.tgz#feb2a77e85b904ecdea459ad897cc90a99bd2a7b"
@@ -3817,6 +4270,11 @@ didyoumean@^1.2.2:
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==
+diff-sequences@^27.0.6:
+ version "27.0.6"
+ resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.6.tgz#3305cb2e55a033924054695cc66019fd7f8e5723"
+ integrity sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==
+
diff@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b"
@@ -3855,6 +4313,13 @@ domelementtype@^2.0.1, domelementtype@^2.1.0, domelementtype@^2.2.0:
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
+domexception@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304"
+ integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==
+ dependencies:
+ webidl-conversions "^5.0.0"
+
domhandler@^4.0.0, domhandler@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059"
@@ -3931,6 +4396,11 @@ electron-to-chromium@^1.3.867:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.870.tgz#c15c921e66a46985181b261f8093b91c2abb6604"
integrity sha512-PiJMshfq6PL+i1V+nKLwhHbCKeD8eAz8rvO9Cwk/7cChOHJBtufmjajLyYLsSRHguRFiOCVx3XzJLeZsIAYfSA==
+emittery@^0.8.1:
+ version "0.8.1"
+ resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860"
+ integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==
+
emmet@^2.1.5:
version "2.3.4"
resolved "https://registry.yarnpkg.com/emmet/-/emmet-2.3.4.tgz#5ba0d7a5569a68c7697dfa890c772e4f3179d123"
@@ -4108,6 +4578,11 @@ escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2, escape-string-regexp@^
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
+escape-string-regexp@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
+ integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
+
escape-string-regexp@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
@@ -4118,6 +4593,18 @@ escape-string-regexp@^5.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8"
integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==
+escodegen@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd"
+ integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==
+ dependencies:
+ esprima "^4.0.1"
+ estraverse "^5.2.0"
+ esutils "^2.0.2"
+ optionator "^0.8.1"
+ optionalDependencies:
+ source-map "~0.6.1"
+
eslint-config-prettier@^8.3.0:
version "8.3.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a"
@@ -4217,7 +4704,7 @@ espree@^7.3.0, espree@^7.3.1:
acorn-jsx "^5.3.1"
eslint-visitor-keys "^1.3.0"
-esprima@^4.0.0:
+esprima@^4.0.0, esprima@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
@@ -4271,7 +4758,7 @@ esutils@^2.0.2:
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
-etag@~1.8.1:
+etag@^1.8.1, etag@~1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
@@ -4322,6 +4809,23 @@ execa@^0.7.0:
signal-exit "^3.0.0"
strip-eof "^1.0.0"
+exit@^0.1.2:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c"
+ integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=
+
+expect@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/expect/-/expect-27.1.0.tgz#380de0abb3a8f2299c4c6c66bbe930483b5dba9b"
+ integrity sha512-9kJngV5hOJgkFil4F/uXm3hVBubUK2nERVfvqNNwxxuW8ZOUwSTTSysgfzckYtv/LBzj/LJXbiAF7okHCXgdug==
+ dependencies:
+ "@jest/types" "^27.1.0"
+ ansi-styles "^5.0.0"
+ jest-get-type "^27.0.6"
+ jest-matcher-utils "^27.1.0"
+ jest-message-util "^27.1.0"
+ jest-regex-util "^27.0.6"
+
extend@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-2.0.2.tgz#1b74985400171b85554894459c978de6ef453ab7"
@@ -4392,7 +4896,7 @@ fast-json-stable-stringify@^2.0.0:
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
-fast-levenshtein@^2.0.6:
+fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
@@ -4409,6 +4913,13 @@ fastq@^1.6.0:
dependencies:
reusify "^1.0.4"
+fb-watchman@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85"
+ integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==
+ dependencies:
+ bser "2.1.1"
+
fd-slicer@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
@@ -4649,7 +5160,7 @@ fs.realpath@^1.0.0:
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
-fsevents@~2.3.2:
+fsevents@^2.3.2, fsevents@~2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
@@ -4704,6 +5215,11 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
has "^1.0.3"
has-symbols "^1.0.1"
+get-package-type@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
+ integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==
+
get-pkg-repo@^4.0.0:
version "4.1.2"
resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-4.1.2.tgz#c4ffd60015cf091be666a0212753fc158f01a4c0"
@@ -4811,7 +5327,7 @@ glob-parent@^6.0.0:
dependencies:
is-glob "^4.0.1"
-glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
+glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
version "7.1.7"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
@@ -5142,6 +5658,18 @@ hosted-git-info@^4.0.0, hosted-git-info@^4.0.1:
dependencies:
lru-cache "^6.0.0"
+html-encoding-sniffer@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3"
+ integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==
+ dependencies:
+ whatwg-encoding "^1.0.5"
+
+html-escaper@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
+ integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
+
html-minifier-terser@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054"
@@ -5286,7 +5814,7 @@ humanize-ms@^1.2.1:
dependencies:
ms "^2.0.0"
-iconv-lite@^0.4.24:
+iconv-lite@0.4.24, iconv-lite@^0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
@@ -5522,6 +6050,13 @@ is-ci@^2.0.0:
dependencies:
ci-info "^2.0.0"
+is-ci@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.0.tgz#c7e7be3c9d8eef7d0fa144390bd1e4b88dc4c994"
+ integrity sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==
+ dependencies:
+ ci-info "^3.1.1"
+
is-core-module@^2.2.0, is-core-module@^2.5.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.6.0.tgz#d7553b2526fe59b92ba3e40c8df757ec8a709e19"
@@ -5568,6 +6103,11 @@ is-fullwidth-code-point@^4.0.0:
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88"
integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==
+is-generator-fn@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118"
+ integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==
+
is-generator-function@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72"
@@ -5669,6 +6209,11 @@ is-plain-object@^5.0.0:
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
+is-potential-custom-element-name@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
+ integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==
+
is-regex@^1.1.3:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
@@ -5778,6 +6323,458 @@ isstream@~0.1.2:
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
+istanbul-lib-coverage@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec"
+ integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==
+
+istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3:
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d"
+ integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==
+ dependencies:
+ "@babel/core" "^7.7.5"
+ "@istanbuljs/schema" "^0.1.2"
+ istanbul-lib-coverage "^3.0.0"
+ semver "^6.3.0"
+
+istanbul-lib-report@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6"
+ integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==
+ dependencies:
+ istanbul-lib-coverage "^3.0.0"
+ make-dir "^3.0.0"
+ supports-color "^7.1.0"
+
+istanbul-lib-source-maps@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9"
+ integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==
+ dependencies:
+ debug "^4.1.1"
+ istanbul-lib-coverage "^3.0.0"
+ source-map "^0.6.1"
+
+istanbul-reports@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b"
+ integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==
+ dependencies:
+ html-escaper "^2.0.0"
+ istanbul-lib-report "^3.0.0"
+
+jest-changed-files@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.1.0.tgz#42da6ea00f06274172745729d55f42b60a9dffe0"
+ integrity sha512-eRcb13TfQw0xiV2E98EmiEgs9a5uaBIqJChyl0G7jR9fCIvGjXovnDS6Zbku3joij4tXYcSK4SE1AXqOlUxjWg==
+ dependencies:
+ "@jest/types" "^27.1.0"
+ execa "^5.0.0"
+ throat "^6.0.1"
+
+jest-circus@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.1.0.tgz#24c280c90a625ea57da20ee231d25b1621979a57"
+ integrity sha512-6FWtHs3nZyZlMBhRf1wvAC5CirnflbGJAY1xssSAnERLiiXQRH+wY2ptBVtXjX4gz4AA2EwRV57b038LmifRbA==
+ dependencies:
+ "@jest/environment" "^27.1.0"
+ "@jest/test-result" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ co "^4.6.0"
+ dedent "^0.7.0"
+ expect "^27.1.0"
+ is-generator-fn "^2.0.0"
+ jest-each "^27.1.0"
+ jest-matcher-utils "^27.1.0"
+ jest-message-util "^27.1.0"
+ jest-runtime "^27.1.0"
+ jest-snapshot "^27.1.0"
+ jest-util "^27.1.0"
+ pretty-format "^27.1.0"
+ slash "^3.0.0"
+ stack-utils "^2.0.3"
+ throat "^6.0.1"
+
+jest-cli@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.1.0.tgz#118438e4d11cf6fb66cb2b2eb5778817eab3daeb"
+ integrity sha512-h6zPUOUu+6oLDrXz0yOWY2YXvBLk8gQinx4HbZ7SF4V3HzasQf+ncoIbKENUMwXyf54/6dBkYXvXJos+gOHYZw==
+ dependencies:
+ "@jest/core" "^27.1.0"
+ "@jest/test-result" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ chalk "^4.0.0"
+ exit "^0.1.2"
+ graceful-fs "^4.2.4"
+ import-local "^3.0.2"
+ jest-config "^27.1.0"
+ jest-util "^27.1.0"
+ jest-validate "^27.1.0"
+ prompts "^2.0.1"
+ yargs "^16.0.3"
+
+jest-config@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.1.0.tgz#e6826e2baaa34c07c3839af86466870e339d9ada"
+ integrity sha512-GMo7f76vMYUA3b3xOdlcKeKQhKcBIgurjERO2hojo0eLkKPGcw7fyIoanH+m6KOP2bLad+fGnF8aWOJYxzNPeg==
+ dependencies:
+ "@babel/core" "^7.1.0"
+ "@jest/test-sequencer" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ babel-jest "^27.1.0"
+ chalk "^4.0.0"
+ deepmerge "^4.2.2"
+ glob "^7.1.1"
+ graceful-fs "^4.2.4"
+ is-ci "^3.0.0"
+ jest-circus "^27.1.0"
+ jest-environment-jsdom "^27.1.0"
+ jest-environment-node "^27.1.0"
+ jest-get-type "^27.0.6"
+ jest-jasmine2 "^27.1.0"
+ jest-regex-util "^27.0.6"
+ jest-resolve "^27.1.0"
+ jest-runner "^27.1.0"
+ jest-util "^27.1.0"
+ jest-validate "^27.1.0"
+ micromatch "^4.0.4"
+ pretty-format "^27.1.0"
+
+jest-diff@^27.0.0, jest-diff@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.1.0.tgz#c7033f25add95e2218f3c7f4c3d7b634ab6b3cd2"
+ integrity sha512-rjfopEYl58g/SZTsQFmspBODvMSytL16I+cirnScWTLkQVXYVZfxm78DFfdIIXc05RCYuGjxJqrdyG4PIFzcJg==
+ dependencies:
+ chalk "^4.0.0"
+ diff-sequences "^27.0.6"
+ jest-get-type "^27.0.6"
+ pretty-format "^27.1.0"
+
+jest-docblock@^27.0.6:
+ version "27.0.6"
+ resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.0.6.tgz#cc78266acf7fe693ca462cbbda0ea4e639e4e5f3"
+ integrity sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==
+ dependencies:
+ detect-newline "^3.0.0"
+
+jest-each@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.1.0.tgz#36ac75f7aeecb3b8da2a8e617ccb30a446df408c"
+ integrity sha512-K/cNvQlmDqQMRHF8CaQ0XPzCfjP5HMJc2bIJglrIqI9fjwpNqITle63IWE+wq4p+3v+iBgh7Wq0IdGpLx5xjDg==
+ dependencies:
+ "@jest/types" "^27.1.0"
+ chalk "^4.0.0"
+ jest-get-type "^27.0.6"
+ jest-util "^27.1.0"
+ pretty-format "^27.1.0"
+
+jest-environment-jsdom@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.1.0.tgz#5fb3eb8a67e02e6cc623640388d5f90e33075f18"
+ integrity sha512-JbwOcOxh/HOtsj56ljeXQCUJr3ivnaIlM45F5NBezFLVYdT91N5UofB1ux2B1CATsQiudcHdgTaeuqGXJqjJYQ==
+ dependencies:
+ "@jest/environment" "^27.1.0"
+ "@jest/fake-timers" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ "@types/node" "*"
+ jest-mock "^27.1.0"
+ jest-util "^27.1.0"
+ jsdom "^16.6.0"
+
+jest-environment-node@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.1.0.tgz#feea6b765f1fd4582284d4f1007df2b0a8d15b7f"
+ integrity sha512-JIyJ8H3wVyM4YCXp7njbjs0dIT87yhGlrXCXhDKNIg1OjurXr6X38yocnnbXvvNyqVTqSI4M9l+YfPKueqL1lw==
+ dependencies:
+ "@jest/environment" "^27.1.0"
+ "@jest/fake-timers" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ "@types/node" "*"
+ jest-mock "^27.1.0"
+ jest-util "^27.1.0"
+
+jest-get-type@^27.0.6:
+ version "27.0.6"
+ resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.6.tgz#0eb5c7f755854279ce9b68a9f1a4122f69047cfe"
+ integrity sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==
+
+jest-haste-map@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.1.0.tgz#a39f456823bd6a74e3c86ad25f6fa870428326bf"
+ integrity sha512-7mz6LopSe+eA6cTFMf10OfLLqRoIPvmMyz5/OnSXnHO7hB0aDP1iIeLWCXzAcYU5eIJVpHr12Bk9yyq2fTW9vg==
+ dependencies:
+ "@jest/types" "^27.1.0"
+ "@types/graceful-fs" "^4.1.2"
+ "@types/node" "*"
+ anymatch "^3.0.3"
+ fb-watchman "^2.0.0"
+ graceful-fs "^4.2.4"
+ jest-regex-util "^27.0.6"
+ jest-serializer "^27.0.6"
+ jest-util "^27.1.0"
+ jest-worker "^27.1.0"
+ micromatch "^4.0.4"
+ walker "^1.0.7"
+ optionalDependencies:
+ fsevents "^2.3.2"
+
+jest-jasmine2@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.1.0.tgz#324a3de0b2ee20d238b2b5b844acc4571331a206"
+ integrity sha512-Z/NIt0wBDg3przOW2FCWtYjMn3Ip68t0SL60agD/e67jlhTyV3PIF8IzT9ecwqFbeuUSO2OT8WeJgHcalDGFzQ==
+ dependencies:
+ "@babel/traverse" "^7.1.0"
+ "@jest/environment" "^27.1.0"
+ "@jest/source-map" "^27.0.6"
+ "@jest/test-result" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ co "^4.6.0"
+ expect "^27.1.0"
+ is-generator-fn "^2.0.0"
+ jest-each "^27.1.0"
+ jest-matcher-utils "^27.1.0"
+ jest-message-util "^27.1.0"
+ jest-runtime "^27.1.0"
+ jest-snapshot "^27.1.0"
+ jest-util "^27.1.0"
+ pretty-format "^27.1.0"
+ throat "^6.0.1"
+
+jest-leak-detector@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.1.0.tgz#fe7eb633c851e06280ec4dd248067fe232c00a79"
+ integrity sha512-oHvSkz1E80VyeTKBvZNnw576qU+cVqRXUD3/wKXh1zpaki47Qty2xeHg2HKie9Hqcd2l4XwircgNOWb/NiGqdA==
+ dependencies:
+ jest-get-type "^27.0.6"
+ pretty-format "^27.1.0"
+
+jest-matcher-utils@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.1.0.tgz#68afda0885db1f0b9472ce98dc4c535080785301"
+ integrity sha512-VmAudus2P6Yt/JVBRdTPFhUzlIN8DYJd+et5Rd9QDsO/Z82Z4iwGjo43U8Z+PTiz8CBvKvlb6Fh3oKy39hykkQ==
+ dependencies:
+ chalk "^4.0.0"
+ jest-diff "^27.1.0"
+ jest-get-type "^27.0.6"
+ pretty-format "^27.1.0"
+
+jest-message-util@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.1.0.tgz#e77692c84945d1d10ef00afdfd3d2c20bd8fb468"
+ integrity sha512-Eck8NFnJ5Sg36R9XguD65cf2D5+McC+NF5GIdEninoabcuoOfWrID5qJhufq5FB0DRKoiyxB61hS7MKoMD0trQ==
+ dependencies:
+ "@babel/code-frame" "^7.12.13"
+ "@jest/types" "^27.1.0"
+ "@types/stack-utils" "^2.0.0"
+ chalk "^4.0.0"
+ graceful-fs "^4.2.4"
+ micromatch "^4.0.4"
+ pretty-format "^27.1.0"
+ slash "^3.0.0"
+ stack-utils "^2.0.3"
+
+jest-mock@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.1.0.tgz#7ca6e4d09375c071661642d1c14c4711f3ab4b4f"
+ integrity sha512-iT3/Yhu7DwAg/0HvvLCqLvrTKTRMyJlrrfJYWzuLSf9RCAxBoIXN3HoymZxMnYsC3eD8ewGbUa9jUknwBenx2w==
+ dependencies:
+ "@jest/types" "^27.1.0"
+ "@types/node" "*"
+
+jest-pnp-resolver@^1.2.2:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c"
+ integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==
+
+jest-regex-util@^27.0.6:
+ version "27.0.6"
+ resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.6.tgz#02e112082935ae949ce5d13b2675db3d8c87d9c5"
+ integrity sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==
+
+jest-resolve-dependencies@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.1.0.tgz#d32ea4a2c82f76410f6157d0ec6cde24fbff2317"
+ integrity sha512-Kq5XuDAELuBnrERrjFYEzu/A+i2W7l9HnPWqZEeKGEQ7m1R+6ndMbdXCVCx29Se1qwLZLgvoXwinB3SPIaitMQ==
+ dependencies:
+ "@jest/types" "^27.1.0"
+ jest-regex-util "^27.0.6"
+ jest-snapshot "^27.1.0"
+
+jest-resolve@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.1.0.tgz#bb22303c9e240cccdda28562e3c6fbcc6a23ac86"
+ integrity sha512-TXvzrLyPg0vLOwcWX38ZGYeEztSEmW+cQQKqc4HKDUwun31wsBXwotRlUz4/AYU/Fq4GhbMd/ileIWZEtcdmIA==
+ dependencies:
+ "@jest/types" "^27.1.0"
+ chalk "^4.0.0"
+ escalade "^3.1.1"
+ graceful-fs "^4.2.4"
+ jest-haste-map "^27.1.0"
+ jest-pnp-resolver "^1.2.2"
+ jest-util "^27.1.0"
+ jest-validate "^27.1.0"
+ resolve "^1.20.0"
+ slash "^3.0.0"
+
+jest-runner@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.1.0.tgz#1b28d114fb3b67407b8354c9385d47395e8ff83f"
+ integrity sha512-ZWPKr9M5w5gDplz1KsJ6iRmQaDT/yyAFLf18fKbb/+BLWsR1sCNC2wMT0H7pP3gDcBz0qZ6aJraSYUNAGSJGaw==
+ dependencies:
+ "@jest/console" "^27.1.0"
+ "@jest/environment" "^27.1.0"
+ "@jest/test-result" "^27.1.0"
+ "@jest/transform" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ emittery "^0.8.1"
+ exit "^0.1.2"
+ graceful-fs "^4.2.4"
+ jest-docblock "^27.0.6"
+ jest-environment-jsdom "^27.1.0"
+ jest-environment-node "^27.1.0"
+ jest-haste-map "^27.1.0"
+ jest-leak-detector "^27.1.0"
+ jest-message-util "^27.1.0"
+ jest-resolve "^27.1.0"
+ jest-runtime "^27.1.0"
+ jest-util "^27.1.0"
+ jest-worker "^27.1.0"
+ source-map-support "^0.5.6"
+ throat "^6.0.1"
+
+jest-runtime@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.1.0.tgz#1a98d984ffebc16a0b4f9eaad8ab47c00a750cf5"
+ integrity sha512-okiR2cpGjY0RkWmUGGado6ETpFOi9oG3yV0CioYdoktkVxy5Hv0WRLWnJFuArSYS8cHMCNcceUUMGiIfgxCO9A==
+ dependencies:
+ "@jest/console" "^27.1.0"
+ "@jest/environment" "^27.1.0"
+ "@jest/fake-timers" "^27.1.0"
+ "@jest/globals" "^27.1.0"
+ "@jest/source-map" "^27.0.6"
+ "@jest/test-result" "^27.1.0"
+ "@jest/transform" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ "@types/yargs" "^16.0.0"
+ chalk "^4.0.0"
+ cjs-module-lexer "^1.0.0"
+ collect-v8-coverage "^1.0.0"
+ execa "^5.0.0"
+ exit "^0.1.2"
+ glob "^7.1.3"
+ graceful-fs "^4.2.4"
+ jest-haste-map "^27.1.0"
+ jest-message-util "^27.1.0"
+ jest-mock "^27.1.0"
+ jest-regex-util "^27.0.6"
+ jest-resolve "^27.1.0"
+ jest-snapshot "^27.1.0"
+ jest-util "^27.1.0"
+ jest-validate "^27.1.0"
+ slash "^3.0.0"
+ strip-bom "^4.0.0"
+ yargs "^16.0.3"
+
+jest-serializer@^27.0.6:
+ version "27.0.6"
+ resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.0.6.tgz#93a6c74e0132b81a2d54623251c46c498bb5bec1"
+ integrity sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==
+ dependencies:
+ "@types/node" "*"
+ graceful-fs "^4.2.4"
+
+jest-snapshot@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.1.0.tgz#2a063ab90064017a7e9302528be7eaea6da12d17"
+ integrity sha512-eaeUBoEjuuRwmiRI51oTldUsKOohB1F6fPqWKKILuDi/CStxzp2IWekVUXbuHHoz5ik33ioJhshiHpgPFbYgcA==
+ dependencies:
+ "@babel/core" "^7.7.2"
+ "@babel/generator" "^7.7.2"
+ "@babel/parser" "^7.7.2"
+ "@babel/plugin-syntax-typescript" "^7.7.2"
+ "@babel/traverse" "^7.7.2"
+ "@babel/types" "^7.0.0"
+ "@jest/transform" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ "@types/babel__traverse" "^7.0.4"
+ "@types/prettier" "^2.1.5"
+ babel-preset-current-node-syntax "^1.0.0"
+ chalk "^4.0.0"
+ expect "^27.1.0"
+ graceful-fs "^4.2.4"
+ jest-diff "^27.1.0"
+ jest-get-type "^27.0.6"
+ jest-haste-map "^27.1.0"
+ jest-matcher-utils "^27.1.0"
+ jest-message-util "^27.1.0"
+ jest-resolve "^27.1.0"
+ jest-util "^27.1.0"
+ natural-compare "^1.4.0"
+ pretty-format "^27.1.0"
+ semver "^7.3.2"
+
+jest-util@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.1.0.tgz#06a53777a8cb7e4940ca8e20bf9c67dd65d9bd68"
+ integrity sha512-edSLD2OneYDKC6gZM1yc+wY/877s/fuJNoM1k3sOEpzFyeptSmke3SLnk1dDHk9CgTA+58mnfx3ew3J11Kes/w==
+ dependencies:
+ "@jest/types" "^27.1.0"
+ "@types/node" "*"
+ chalk "^4.0.0"
+ graceful-fs "^4.2.4"
+ is-ci "^3.0.0"
+ picomatch "^2.2.3"
+
+jest-validate@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.1.0.tgz#d9e82024c5e3f5cef52a600cfc456793a84c0998"
+ integrity sha512-QiJ+4XuSuMsfPi9zvdO//IrSRSlG6ybJhOpuqYSsuuaABaNT84h0IoD6vvQhThBOKT+DIKvl5sTM0l6is9+SRA==
+ dependencies:
+ "@jest/types" "^27.1.0"
+ camelcase "^6.2.0"
+ chalk "^4.0.0"
+ jest-get-type "^27.0.6"
+ leven "^3.1.0"
+ pretty-format "^27.1.0"
+
+jest-watcher@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.1.0.tgz#2511fcddb0e969a400f3d1daa74265f93f13ce93"
+ integrity sha512-ivaWTrA46aHWdgPDgPypSHiNQjyKnLBpUIHeBaGg11U+pDzZpkffGlcB1l1a014phmG0mHgkOHtOgiqJQM6yKQ==
+ dependencies:
+ "@jest/test-result" "^27.1.0"
+ "@jest/types" "^27.1.0"
+ "@types/node" "*"
+ ansi-escapes "^4.2.1"
+ chalk "^4.0.0"
+ jest-util "^27.1.0"
+ string-length "^4.0.1"
+
+jest-worker@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.1.0.tgz#65f4a88e37148ed984ba8ca8492d6b376938c0aa"
+ integrity sha512-mO4PHb2QWLn9yRXGp7rkvXLAYuxwhq1ZYUo0LoDhg8wqvv4QizP1ZWEJOeolgbEgAWZLIEU0wsku8J+lGWfBhg==
+ dependencies:
+ "@types/node" "*"
+ merge-stream "^2.0.0"
+ supports-color "^8.0.0"
+
+jest@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/jest/-/jest-27.1.0.tgz#eaab62dfdc02d8b7c814cd27b8d2d92bc46d3d69"
+ integrity sha512-pSQDVwRSwb109Ss13lcMtdfS9r8/w2Zz8+mTUA9VORD66GflCdl8nUFCqM96geOD2EBwWCNURrNAfQsLIDNBdg==
+ dependencies:
+ "@jest/core" "^27.1.0"
+ import-local "^3.0.2"
+ jest-cli "^27.1.0"
+
joi@^17.4.0:
version "17.4.2"
resolved "https://registry.yarnpkg.com/joi/-/joi-17.4.2.tgz#02f4eb5cf88e515e614830239379dcbbe28ce7f7"
@@ -5807,6 +6804,39 @@ jsbn@~0.1.0:
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
+jsdom@^16.6.0:
+ version "16.7.0"
+ resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710"
+ integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==
+ dependencies:
+ abab "^2.0.5"
+ acorn "^8.2.4"
+ acorn-globals "^6.0.0"
+ cssom "^0.4.4"
+ cssstyle "^2.3.0"
+ data-urls "^2.0.0"
+ decimal.js "^10.2.1"
+ domexception "^2.0.1"
+ escodegen "^2.0.0"
+ form-data "^3.0.0"
+ html-encoding-sniffer "^2.0.1"
+ http-proxy-agent "^4.0.1"
+ https-proxy-agent "^5.0.0"
+ is-potential-custom-element-name "^1.0.1"
+ nwsapi "^2.2.0"
+ parse5 "6.0.1"
+ saxes "^5.0.1"
+ symbol-tree "^3.2.4"
+ tough-cookie "^4.0.0"
+ w3c-hr-time "^1.0.2"
+ w3c-xmlserializer "^2.0.0"
+ webidl-conversions "^6.1.0"
+ whatwg-encoding "^1.0.5"
+ whatwg-mimetype "^2.3.0"
+ whatwg-url "^8.5.0"
+ ws "^7.4.6"
+ xml-name-validator "^3.0.0"
+
jsesc@^2.5.1:
version "2.5.2"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
@@ -6033,6 +7063,11 @@ lerna@^4.0.0:
import-local "^3.0.2"
npmlog "^4.1.2"
+leven@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
+ integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==
+
levn@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
@@ -6041,6 +7076,14 @@ levn@^0.4.1:
prelude-ls "^1.2.1"
type-check "~0.4.0"
+levn@~0.3.0:
+ version "0.3.0"
+ resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
+ integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=
+ dependencies:
+ prelude-ls "~1.1.2"
+ type-check "~0.3.2"
+
libnpmaccess@^4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-4.0.3.tgz#dfb0e5b0a53c315a2610d300e46b4ddeb66e7eec"
@@ -6086,24 +7129,24 @@ link-types@^1.1.0:
integrity sha1-r2XlnbUucMH/sYrEw8sFa/55aDA=
lit-element@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-3.0.0.tgz#0e9e64ddbc3dd6a8da4d6fbfadbc070a54cf0597"
- integrity sha512-oPqRhhBBhs+AlI62QLwtWQNU/bNK/h2L1jI3IDroqZubo6XVAkyNy2dW3CRfjij8mrNlY7wULOfyyKKOnfEePA==
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-3.0.1.tgz#3c545af17d8a46268bc1dd5623a47486e6ff76f4"
+ integrity sha512-vs9uybH9ORyK49CFjoNGN85HM9h5bmisU4TQ63phe/+GYlwvY/3SIFYKdjV6xNvzz8v2MnVC+9+QOkPqh+Q3Ew==
dependencies:
"@lit/reactive-element" "^1.0.0"
lit-html "^2.0.0"
lit-html@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/lit-html/-/lit-html-2.0.0.tgz#ba6779269c382e66d7403a96ed99516ccc3d658b"
- integrity sha512-tJsCapCmc0vtLj6harqd6HfCxnlt/RSkgowtz4SC9dFE3nSL38Tb33I5HMDiyJsRjQZRTgpVsahrnDrR9wg27w==
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/lit-html/-/lit-html-2.0.1.tgz#63241015efa07bc9259b6f96f04abd052d2a1f95"
+ integrity sha512-KF5znvFdXbxTYM/GjpdOOnMsjgRcFGusTnB54ixnCTya5zUR0XqrDRj29ybuLS+jLXv1jji6Y8+g4W7WP8uL4w==
dependencies:
"@types/trusted-types" "^2.0.2"
lit@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/lit/-/lit-2.0.0.tgz#7710095dc518d9858dde579e9c76b9eed71e98ba"
- integrity sha512-pqi5O/wVzQ9Bn4ERRoYQlt1EAUWyY5Wv888vzpoArbtChc+zfUv1XohRqSdtQZYCogl0eHKd+MQwymg2XJfECg==
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/lit/-/lit-2.0.2.tgz#5e6f422924e0732258629fb379556b6d23f7179c"
+ integrity sha512-hKA/1YaSB+P+DvKWuR2q1Xzy/iayhNrJ3aveD0OQ9CKn6wUjsdnF/7LavDOJsKP/K5jzW/kXsuduPgRvTFrFJw==
dependencies:
"@lit/reactive-element" "^1.0.0"
lit-element "^3.0.0"
@@ -6349,6 +7392,13 @@ make-fetch-happen@^9.0.1:
socks-proxy-agent "^6.0.0"
ssri "^8.0.0"
+makeerror@1.0.x:
+ version "1.0.11"
+ resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c"
+ integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=
+ dependencies:
+ tmpl "1.0.x"
+
map-obj@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
@@ -7054,6 +8104,11 @@ modify-values@^1.0.0:
resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==
+morphdom@^2.6.1:
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/morphdom/-/morphdom-2.6.1.tgz#e868e24f989fa3183004b159aed643e628b4306e"
+ integrity sha512-Y8YRbAEP3eKykroIBWrjcfMw7mmwJfjhqdpSvoqinu8Y702nAwikpXcNFDiIkyvfCLxLM9Wu95RZqo4a9jFBaA==
+
mri@^1.1.0:
version "1.1.6"
resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.6.tgz#49952e1044db21dbf90f6cd92bc9c9a777d415a6"
@@ -7183,6 +8238,16 @@ node-gyp@^7.1.0:
tar "^6.0.2"
which "^2.0.2"
+node-int64@^0.4.0:
+ version "0.4.0"
+ resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
+ integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=
+
+node-modules-regexp@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40"
+ integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=
+
node-releases@^1.1.75:
version "1.1.75"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.75.tgz#6dd8c876b9897a1b8e5a02de26afa79bb54ebbfe"
@@ -7423,6 +8488,11 @@ number-is-nan@^1.0.0:
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
+nwsapi@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7"
+ integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==
+
oauth-sign@~0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
@@ -7513,6 +8583,18 @@ only@~0.0.2:
resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4"
integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q=
+optionator@^0.8.1:
+ version "0.8.3"
+ resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495"
+ integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==
+ dependencies:
+ deep-is "~0.1.3"
+ fast-levenshtein "~2.0.6"
+ levn "~0.3.0"
+ prelude-ls "~1.1.2"
+ type-check "~0.3.2"
+ word-wrap "~1.2.3"
+
optionator@^0.9.1:
version "0.9.1"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
@@ -7563,6 +8645,11 @@ outdent@^0.5.0:
resolved "https://registry.yarnpkg.com/outdent/-/outdent-0.5.0.tgz#9e10982fdc41492bb473ad13840d22f9655be2ff"
integrity sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==
+p-each-series@^2.1.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a"
+ integrity sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==
+
p-filter@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c"
@@ -7867,6 +8954,11 @@ parse5-htmlparser2-tree-adapter@^6.0.1:
dependencies:
parse5 "^6.0.1"
+parse5@6.0.1, parse5@^6.0.0, parse5@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
+ integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
+
parse5@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c"
@@ -7879,11 +8971,6 @@ parse5@^5.1.0:
resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178"
integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==
-parse5@^6.0.0, parse5@^6.0.1:
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
- integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
-
parseurl@^1.3.2, parseurl@~1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
@@ -8018,6 +9105,13 @@ pinkie@^2.0.0:
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
+pirates@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87"
+ integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==
+ dependencies:
+ node-modules-regexp "^1.0.0"
+
pkg-dir@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
@@ -8152,6 +9246,11 @@ prelude-ls@^1.2.1:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
+prelude-ls@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
+ integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
+
prepend-http@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-3.0.1.tgz#3e724d58fd5867465b300bb9615009fa2f8ee3b6"
@@ -8174,6 +9273,16 @@ prettier@^2.3.2:
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d"
integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==
+pretty-format@^27.0.0, pretty-format@^27.1.0:
+ version "27.1.0"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.1.0.tgz#022f3fdb19121e0a2612f3cff8d724431461b9ca"
+ integrity sha512-4aGaud3w3rxAO6OXmK3fwBFQ0bctIOG3/if+jYEFGNGIs0EvuidQm3bZ9mlP2/t9epLNC/12czabfy7TZNSwVA==
+ dependencies:
+ "@jest/types" "^27.1.0"
+ ansi-regex "^5.0.0"
+ ansi-styles "^5.0.0"
+ react-is "^17.0.1"
+
pretty-format@^3.8.0:
version "3.8.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385"
@@ -8212,7 +9321,7 @@ promise-retry@^2.0.1:
err-code "^2.0.2"
retry "^0.12.0"
-prompts@^2.4.1:
+prompts@^2.0.1, prompts@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.1.tgz#befd3b1195ba052f9fd2fde8a486c4e82ee77f61"
integrity sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==
@@ -8277,7 +9386,7 @@ pseudomap@^1.0.2:
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
-psl@^1.1.28:
+psl@^1.1.28, psl@^1.1.33:
version "1.8.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
@@ -8375,6 +9484,11 @@ react-dom@^17.0.2:
object-assign "^4.1.1"
scheduler "^0.20.2"
+react-is@^17.0.1:
+ version "17.0.2"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
+ integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
+
react@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
@@ -8920,6 +10034,13 @@ sass@^1.38.1:
dependencies:
chokidar ">=3.0.0 <4.0.0"
+saxes@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d"
+ integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==
+ dependencies:
+ xmlchars "^2.2.0"
+
scheduler@^0.20.2:
version "0.20.2"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
@@ -9150,7 +10271,7 @@ source-map-js@^0.6.2:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e"
integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==
-source-map-support@~0.5.12:
+source-map-support@^0.5.6, source-map-support@~0.5.12:
version "0.5.19"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
@@ -9285,6 +10406,13 @@ ssri@^8.0.0, ssri@^8.0.1:
dependencies:
minipass "^3.1.1"
+stack-utils@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277"
+ integrity sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==
+ dependencies:
+ escape-string-regexp "^2.0.0"
+
start-server-and-test@^1.12.6:
version "1.13.1"
resolved "https://registry.yarnpkg.com/start-server-and-test/-/start-server-and-test-1.13.1.tgz#c06eb18c3f31d610724722b7eecbdf2550b03582"
@@ -9342,6 +10470,14 @@ string-hash@^1.1.1:
resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b"
integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=
+string-length@^4.0.1:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"
+ integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==
+ dependencies:
+ char-regex "^1.0.2"
+ strip-ansi "^6.0.0"
+
string-width@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
@@ -9536,13 +10672,20 @@ supports-color@^5.3.0:
dependencies:
has-flag "^3.0.0"
-supports-color@^7.1.0:
+supports-color@^7.0.0, supports-color@^7.1.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
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.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
+ integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
+ dependencies:
+ has-flag "^4.0.0"
+
supports-esm@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/supports-esm/-/supports-esm-1.0.0.tgz#7cc567747d0745e2b77b331c9b9cae13cf4dc60e"
@@ -9550,6 +10693,14 @@ supports-esm@^1.0.0:
dependencies:
has-package-exports "^1.1.0"
+supports-hyperlinks@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz#4f77b42488765891774b70c79babd87f9bd594bb"
+ integrity sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==
+ dependencies:
+ has-flag "^4.0.0"
+ supports-color "^7.0.0"
+
svelte-hmr@^0.14.7:
version "0.14.7"
resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.7.tgz#7fa8261c7b225d9409f0a86f3b9ea5c3ca6f6607"
@@ -9560,6 +10711,11 @@ svelte@^3.42.3:
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.42.3.tgz#a7687a43ff6aa12263e03cf56219cd21eff5372d"
integrity sha512-pbdtdNZEx2GBqSM6XEgPoHbwtvWBwFLt/1bRmzsyXZO+i424wFnPe7O5B3GOJDPFSxPRztumAW3mL5LPzecWUg==
+symbol-tree@^3.2.4:
+ version "3.2.4"
+ resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
+ integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
+
table@^6.0.9:
version "6.7.1"
resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2"
@@ -9662,6 +10818,14 @@ term-size@^2.1.0:
resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54"
integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==
+terminal-link@^2.0.0:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994"
+ integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==
+ dependencies:
+ ansi-escapes "^4.2.1"
+ supports-hyperlinks "^2.0.0"
+
terser@^4.6.3:
version "4.8.0"
resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17"
@@ -9671,6 +10835,15 @@ terser@^4.6.3:
source-map "~0.6.1"
source-map-support "~0.5.12"
+test-exclude@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e"
+ integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==
+ dependencies:
+ "@istanbuljs/schema" "^0.1.2"
+ glob "^7.1.4"
+ minimatch "^3.0.4"
+
text-extensions@^1.0.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26"
@@ -9681,6 +10854,11 @@ text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
+throat@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375"
+ integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==
+
through2-sink@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/through2-sink/-/through2-sink-1.0.0.tgz#5f106bba1d7330dad3cba5c0ab1863923256c399"
@@ -9747,6 +10925,11 @@ tmp@^0.2.1:
dependencies:
rimraf "^3.0.0"
+tmpl@1.0.x:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
+ integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=
+
to-fast-properties@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
@@ -9777,6 +10960,15 @@ tough-cookie@^2.3.1, tough-cookie@~2.5.0:
psl "^1.1.28"
punycode "^2.1.1"
+tough-cookie@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4"
+ integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==
+ dependencies:
+ psl "^1.1.33"
+ punycode "^2.1.1"
+ universalify "^0.1.2"
+
tr46@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240"
@@ -9875,6 +11067,18 @@ type-check@^0.4.0, type-check@~0.4.0:
dependencies:
prelude-ls "^1.2.1"
+type-check@~0.3.2:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
+ integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=
+ dependencies:
+ prelude-ls "~1.1.2"
+
+type-detect@4.0.8:
+ version "4.0.8"
+ resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
+ integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
+
type-fest@^0.13.1:
version "0.13.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934"
@@ -9935,7 +11139,7 @@ typescript@^4.3.1-rc:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.3.tgz#bdc5407caa2b109efd4f82fe130656f977a29324"
integrity sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==
-typescript@^4.4.2:
+typescript@^4.3.5, typescript@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.4.2.tgz#6d618640d430e3569a1dfb44f7d7e600ced3ee86"
integrity sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==
@@ -10153,7 +11357,7 @@ universal-user-agent@^6.0.0:
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee"
integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==
-universalify@^0.1.0:
+universalify@^0.1.0, universalify@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
@@ -10259,6 +11463,15 @@ v8-compile-cache@^2.0.3:
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
+v8-to-istanbul@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz#4229f2a99e367f3f018fa1d5c2b8ec684667c69c"
+ integrity sha512-LkmXi8UUNxnCC+JlH7/fsfsKr5AU110l+SYGJimWNkWhxbN5EyeOtm1MJ0hhvqMMOhGwBj1Fp70Yv9i+hX0QAg==
+ dependencies:
+ "@types/istanbul-lib-coverage" "^2.0.1"
+ convert-source-map "^1.6.0"
+ source-map "^0.7.3"
+
validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"
@@ -10332,10 +11545,10 @@ vfile@^5.0.0:
unist-util-stringify-position "^3.0.0"
vfile-message "^3.0.0"
-vite@^2.5.1:
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/vite/-/vite-2.5.1.tgz#953c71a034c07b3ae0448d57664ec9c6862f23a8"
- integrity sha512-FwmLbbz8MB1pBs9dKoRDgpiqoijif8hSK1+NNUYc12/cnf+pM2UFhhQ1rcpXgbMhm/5c2USZdVAf0FSkSxaFDA==
+vite@^2.5.2:
+ version "2.5.2"
+ resolved "https://registry.yarnpkg.com/vite/-/vite-2.5.2.tgz#3963a4ec1e6ecae49359eddfdd67f6cb1e6e07a1"
+ integrity sha512-JK5uhiVyMqHiAJbgBa8rCvpP8bEhAE9dKDv1gCmP+EUP2FSPmEeW3WXlCXauPB3MDa8behPW+ntyNXqnGaxslg==
dependencies:
esbuild "^0.12.17"
postcss "^8.3.6"
@@ -10440,6 +11653,20 @@ vue@^3.2.6:
"@vue/runtime-dom" "3.2.6"
"@vue/shared" "3.2.6"
+w3c-hr-time@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"
+ integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==
+ dependencies:
+ browser-process-hrtime "^1.0.0"
+
+w3c-xmlserializer@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a"
+ integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==
+ dependencies:
+ xml-name-validator "^3.0.0"
+
wait-on@6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-6.0.0.tgz#7e9bf8e3d7fe2daecbb7a570ac8ca41e9311c7e7"
@@ -10451,6 +11678,13 @@ wait-on@6.0.0:
minimist "^1.2.5"
rxjs "^7.1.0"
+walker@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
+ integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=
+ dependencies:
+ makeerror "1.0.x"
+
wcwidth@^1.0.0, wcwidth@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
@@ -10463,12 +11697,29 @@ web-namespaces@^2.0.0:
resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.0.tgz#1f6a2d7b5823329abaedeb6bdf09ef2fed35db13"
integrity sha512-dE7ELZRVWh0ceQsRgkjLgsAvwTuv3kcjSY/hLjqL0llleUlQBDjE9JkB9FCBY5F2mnFEwiyJoowl8+NVGHe8dw==
+webidl-conversions@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
+ integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==
+
webidl-conversions@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514"
integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==
-whatwg-url@^8.4.0:
+whatwg-encoding@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0"
+ integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==
+ dependencies:
+ iconv-lite "0.4.24"
+
+whatwg-mimetype@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf"
+ integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==
+
+whatwg-url@^8.0.0, whatwg-url@^8.4.0, whatwg-url@^8.5.0:
version "8.7.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77"
integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==
@@ -10548,7 +11799,7 @@ win-release@^1.0.0:
dependencies:
semver "^5.0.1"
-word-wrap@^1.2.3:
+word-wrap@^1.2.3, word-wrap@~1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
@@ -10645,6 +11896,21 @@ ws@^6.1.0:
dependencies:
async-limiter "~1.0.0"
+ws@^7.4.6:
+ version "7.5.4"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.4.tgz#56bfa20b167427e138a7795de68d134fe92e21f9"
+ integrity sha512-zP9z6GXm6zC27YtspwH99T3qTG7bBFv2VIkeHstMLrLlDJuzA7tQ5ls3OJ1hOGGCzTQPniNJoHXIAOS0Jljohg==
+
+xml-name-validator@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
+ integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
+
+xmlchars@^2.2.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
+ integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
+
xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
@@ -10720,7 +11986,7 @@ yargs@^15.1.0:
y18n "^4.0.0"
yargs-parser "^18.1.2"
-yargs@^16.2.0:
+yargs@^16.0.3, yargs@^16.2.0:
version "16.2.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==