diff options
author | 2022-03-29 17:36:10 -0300 | |
---|---|---|
committer | 2022-03-29 17:36:10 -0300 | |
commit | 7e5f6f1cbb2c4dd3eb9f3a1188cc44e3d8d63b37 (patch) | |
tree | 7017ca4f97413c40fd7c44384d929f0a8a84a36c | |
parent | d6f0d5cf3cc1e2606a09a2b9a98740716bf8ed62 (diff) | |
parent | 23b8ee2738076225da57ce5e3826373c8964717c (diff) | |
download | astro-7e5f6f1cbb2c4dd3eb9f3a1188cc44e3d8d63b37.tar.gz astro-7e5f6f1cbb2c4dd3eb9f3a1188cc44e3d8d63b37.tar.zst astro-7e5f6f1cbb2c4dd3eb9f3a1188cc44e3d8d63b37.zip |
Merge branch 'main' into feat/vercel-adapter
121 files changed, 1315 insertions, 1122 deletions
diff --git a/.changeset/forty-coins-attend.md b/.changeset/forty-coins-attend.md new file mode 100644 index 000000000..467e520fd --- /dev/null +++ b/.changeset/forty-coins-attend.md @@ -0,0 +1,16 @@ +--- +"astro": minor +--- + +Implement RFC [#0017](https://github.com/withastro/rfcs/blob/main/proposals/0017-markdown-content-redesign.md) + +- New Markdown API +- New `Astro.glob()` API +- **BREAKING CHANGE:** Removed `Astro.fetchContent()` (replaced by `Astro.glob()`) + +```diff +// v0.25 +- let allPosts = Astro.fetchContent('./posts/*.md'); +// v0.26+ ++ let allPosts = await Astro.glob('./posts/*.md'); +``` diff --git a/.changeset/perfect-dogs-turn.md b/.changeset/perfect-dogs-turn.md new file mode 100644 index 000000000..61517d560 --- /dev/null +++ b/.changeset/perfect-dogs-turn.md @@ -0,0 +1,5 @@ +--- +'astro': minor +--- + +Implements the Astro.request RFC diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 000000000..5b9fb8f21 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,61 @@ +{ + "mode": "pre", + "tag": "next", + "initialVersions": { + "@example/blog": "0.0.1", + "@example/blog-multiple-authors": "0.0.1", + "@example/component": "0.0.1", + "@example/my-component-demo": "0.0.1", + "@example/my-component": "0.0.1", + "@example/docs": "0.0.1", + "@example/env-vars": "0.0.1", + "@example/framework-alpine": "0.0.1", + "@example/framework-lit": "0.0.1", + "@example/framework-multiple": "0.0.1", + "@example/framework-preact": "0.0.1", + "@example/framework-react": "0.0.1", + "@example/framework-solid": "0.0.1", + "@example/framework-svelte": "0.0.1", + "@example/framework-vue": "0.0.1", + "@example/integrations-playground": "0.0.1", + "@example/minimal": "0.0.1", + "@example/non-html-pages": "0.0.1", + "@example/portfolio": "0.0.1", + "@example/ssr": "0.0.1", + "@example/starter": "0.0.1", + "@example/subpath": "0.0.1", + "@example/with-markdown": "0.0.1", + "@example/with-markdown-plugins": "0.0.2", + "@example/with-markdown-shiki": "0.0.1", + "@example/with-nanostores": "0.0.1", + "@example/with-tailwindcss": "0.0.1", + "@example/with-vite-plugin-pwa": "0.0.1", + "astro": "0.25.4", + "@astrojs/prism": "0.4.1", + "@test/custom-element-renderer": "0.1.0", + "@test/static-build-pkg": "0.0.0", + "create-astro": "0.8.0", + "@astrojs/lit": "0.0.2", + "@astrojs/netlify": "0.0.2", + "@astrojs/node": "0.0.2", + "@astrojs/partytown": "0.0.2", + "@astrojs/preact": "0.0.2", + "@astrojs/react": "0.0.2", + "@astrojs/sitemap": "0.0.2", + "@astrojs/solid-js": "0.0.3", + "@astrojs/svelte": "0.0.2", + "@astrojs/tailwind": "0.0.2", + "@astrojs/turbolinks": "0.0.2", + "@astrojs/vue": "0.0.2", + "@astrojs/markdown-remark": "0.7.0", + "@astrojs/renderer-lit": "0.4.0", + "@astrojs/renderer-preact": "0.5.0", + "@astrojs/renderer-react": "0.5.0", + "@astrojs/renderer-solid": "0.4.0", + "@astrojs/renderer-svelte": "0.5.2", + "@astrojs/renderer-vue": "0.4.0", + "@astrojs/webapi": "0.11.0", + "astro-scripts": "0.0.2" + }, + "changesets": [] +} diff --git a/.changeset/real-starfishes-turn.md b/.changeset/real-starfishes-turn.md deleted file mode 100644 index bccddb3fe..000000000 --- a/.changeset/real-starfishes-turn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'astro': patch ---- - -Fix typing of `integrations` array in user config diff --git a/.changeset/small-radios-remain.md b/.changeset/small-radios-remain.md new file mode 100644 index 000000000..d0747a700 --- /dev/null +++ b/.changeset/small-radios-remain.md @@ -0,0 +1,5 @@ +--- +'astro': patch +--- + +Update CLI error format and style diff --git a/.changeset/stale-walls-whisper.md b/.changeset/stale-walls-whisper.md new file mode 100644 index 000000000..4f51e1504 --- /dev/null +++ b/.changeset/stale-walls-whisper.md @@ -0,0 +1,5 @@ +--- +'@example/portfolio': patch +--- + +fix import in astro config diff --git a/examples/blog-multiple-authors/package.json b/examples/blog-multiple-authors/package.json index 26a149981..10ac77139 100644 --- a/examples/blog-multiple-authors/package.json +++ b/examples/blog-multiple-authors/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/preact": "^0.0.2", - "astro": "^0.25.3", + "astro": "^0.25.4", "sass": "^1.49.9" }, "dependencies": { diff --git a/examples/blog-multiple-authors/src/components/PostPreview.astro b/examples/blog-multiple-authors/src/components/PostPreview.astro index 81e80ba6c..5a9808348 100644 --- a/examples/blog-multiple-authors/src/components/PostPreview.astro +++ b/examples/blog-multiple-authors/src/components/PostPreview.astro @@ -4,6 +4,7 @@ export interface Props { author: string; } const { post, author } = Astro.props; +const { frontmatter } = post; function formatDate(date) { return new Date(date).toUTCString().replace(/(\d\d\d\d) .*/, '$1'); // remove everything after YYYY @@ -12,12 +13,12 @@ function formatDate(date) { <article class="post"> <div class="data"> - <h2>{post.title}</h2> - <a class="author" href={`/authors/${post.author}`}>{author.name}</a> - <time class="date" datetime={post.date}>{formatDate(post.date)}</time> + <h2>{frontmatter.title}</h2> + <a class="author" href={`/authors/${frontmatter.author}`}>{author.name}</a> + <time class="date" datetime={frontmatter.date}>{formatDate(frontmatter.date)}</time> <p class="description"> - {post.description} - <a class="link" href={post.url} aria-label={`Read ${post.title}`}>Read</a> + {frontmatter.description} + <a class="link" href={post.url} aria-label={`Read ${frontmatter.title}`}>Read</a> </p> </div> </article> diff --git a/examples/blog-multiple-authors/src/layouts/post.astro b/examples/blog-multiple-authors/src/layouts/post.astro index fd8fcefa6..bbfc7b335 100644 --- a/examples/blog-multiple-authors/src/layouts/post.astro +++ b/examples/blog-multiple-authors/src/layouts/post.astro @@ -4,7 +4,7 @@ import Nav from '../components/Nav.astro'; import authorData from '../data/authors.json'; const { content } = Astro.props; -let canonicalURL = Astro.request.canonicalURL; +let canonicalURL = Astro.canonicalURL; --- <html lang={content.lang || 'en'}> diff --git a/examples/blog-multiple-authors/src/pages/about.astro b/examples/blog-multiple-authors/src/pages/about.astro index ad101368b..f1097a6f4 100644 --- a/examples/blog-multiple-authors/src/pages/about.astro +++ b/examples/blog-multiple-authors/src/pages/about.astro @@ -4,7 +4,7 @@ import Nav from '../components/Nav.astro'; let title = 'About'; let description = 'About page of an example blog on Astro'; -let canonicalURL = Astro.request.canonicalURL; +let canonicalURL = Astro.canonicalURL; --- <html lang="en"> diff --git a/examples/blog-multiple-authors/src/pages/authors/[author].astro b/examples/blog-multiple-authors/src/pages/authors/[author].astro index 21aab27a5..c2ba49d39 100644 --- a/examples/blog-multiple-authors/src/pages/authors/[author].astro +++ b/examples/blog-multiple-authors/src/pages/authors/[author].astro @@ -2,36 +2,28 @@ import MainHead from '../../components/MainHead.astro'; import Nav from '../../components/Nav.astro'; import PostPreview from '../../components/PostPreview.astro'; -import Pagination from '../../components/Pagination.astro'; import authorData from '../../data/authors.json'; -export function getStaticPaths() { - const allPosts = Astro.fetchContent<MarkdownFrontmatter>('../post/*.md'); - let allAuthorsUnique = [...new Set(allPosts.map((p) => p.author))]; +export async function getStaticPaths() { + const allPosts = await Astro.glob('../post/*.md'); + let allAuthorsUnique = [...new Set(allPosts.map((p) => p.frontmatter.author))]; return allAuthorsUnique.map((author) => ({ params: { author }, props: { allPosts } })); } -interface MarkdownFrontmatter { - date: number; - description: string; - title: string; - author: string; -} - const { allPosts } = Astro.props; const { params, canonicalURL } = Astro.request; const title = 'Don’s Blog'; const description = 'An example blog on Astro'; /** filter posts by author, sort by date */ -const posts = allPosts.filter((post) => post.author === params.author).sort((a, b) => new Date(b.date).valueOf() - new Date(a.date).valueOf()); -const author = authorData[posts[0].author]; +const posts = allPosts.filter((post) => post.frontmatter.author === params.author).sort((a, b) => new Date(b.frontmatter.date).valueOf() - new Date(a.frontmatter.date).valueOf()); +const author = authorData[posts[0].frontmatter.author]; --- <html lang="en"> <head> <title>{title}</title> - <MainHead {title} {description} image={posts[0].image} canonicalURL={canonicalURL.toString()} /> + <MainHead {title} {description} image={posts[0].frontmatter.image} canonicalURL={canonicalURL.toString()} /> <style lang="scss"> .title { diff --git a/examples/blog-multiple-authors/src/pages/index.astro b/examples/blog-multiple-authors/src/pages/index.astro index 8ad01c190..0c8d701ea 100644 --- a/examples/blog-multiple-authors/src/pages/index.astro +++ b/examples/blog-multiple-authors/src/pages/index.astro @@ -6,25 +6,18 @@ import PostPreview from '../components/PostPreview.astro'; import Pagination from '../components/Pagination.astro'; import authorData from '../data/authors.json'; -interface MarkdownFrontmatter { - date: number; - image: string; - author: string; -} - // Component Script: // You can write any JavaScript/TypeScript that you'd like here. // It will run during the build, but never in the browser. // All variables are available to use in the HTML template below. let title = 'Don’s Blog'; let description = 'An example blog on Astro'; -let canonicalURL = Astro.request.canonicalURL; +let canonicalURL = Astro.canonicalURL; // Data Fetching: List all Markdown posts in the repo. -let allPosts = Astro.fetchContent<MarkdownFrontmatter>('./post/*.md'); -allPosts.sort((a, b) => new Date(b.date).valueOf() - new Date(a.date).valueOf()); +let allPosts = await Astro.glob('./post/*.md'); +allPosts.sort((a, b) => new Date(b.frontmatter.date).valueOf() - new Date(a.frontmatter.date).valueOf()); let firstPage = allPosts.slice(0, 2); - // Full Astro Component Syntax: // https://docs.astro.build/core-concepts/astro-components/ --- @@ -32,14 +25,14 @@ let firstPage = allPosts.slice(0, 2); <html lang="en"> <head> <title>{title}</title> - <MainHead {title} {description} image={allPosts[0].image} {canonicalURL} /> + <MainHead {title} {description} image={allPosts[0].frontmatter.image} {canonicalURL} /> </head> <body> <Nav {title} /> <main class="wrapper"> - {allPosts.map((post) => <PostPreview post={post} author={authorData[post.author]} />)} + {allPosts.map((post) => <PostPreview post={post} author={authorData[post.frontmatter.author]} />)} </main> <footer> diff --git a/examples/blog-multiple-authors/src/pages/posts/[...page].astro b/examples/blog-multiple-authors/src/pages/posts/[...page].astro index d0f95ce5b..7711a940c 100644 --- a/examples/blog-multiple-authors/src/pages/posts/[...page].astro +++ b/examples/blog-multiple-authors/src/pages/posts/[...page].astro @@ -6,8 +6,8 @@ import Pagination from '../../components/Pagination.astro'; import authorData from '../../data/authors.json'; export async function getStaticPaths({ paginate, rss }) { - const allPosts = Astro.fetchContent<MarkdownFrontmatter>('../post/*.md'); - const sortedPosts = allPosts.sort((a, b) => new Date(b.date).valueOf() - new Date(a.date).valueOf()); + const allPosts = await Astro.glob('../post/*.md'); + const sortedPosts = allPosts.sort((a, b) => new Date(b.frontmatter.date).valueOf() - new Date(a.frontmatter.date).valueOf()); // Generate an RSS feed from this collection of posts. // NOTE: This is disabled by default, since it requires `buildOptions.site` to be set in your "astro.config.mjs" file. @@ -28,24 +28,16 @@ export async function getStaticPaths({ paginate, rss }) { } // page -let title = 'Don’s Blog'; -let description = 'An example blog on Astro'; -let canonicalURL = Astro.request.canonicalURL; - -// collection -interface MarkdownFrontmatter { - date: number; - description: string; - title: string; -} - +const title = 'Don’s Blog'; +const description = 'An example blog on Astro'; +const { canonicalURL } = Astro; const { page } = Astro.props; --- <html lang="en"> <head> <title>{title}</title> - <MainHead {title} {description} image={page.data[0].image} canonicalURL={canonicalURL.toString()} prev={page.url.prev} next={page.url.next} /> + <MainHead {title} {description} image={page.data[0].frontmatter.image} canonicalURL={canonicalURL.toString()} prev={page.url.prev} next={page.url.next} /> <style lang="scss"> .title { @@ -70,7 +62,7 @@ const { page } = Astro.props; <main class="wrapper"> <h2 class="title">All Posts</h2> <small class="count">{page.start + 1}–{page.end + 1} of {page.total}</small> - {page.data.map((post) => <PostPreview post={post} author={authorData[post.author]} />)} + {page.data.map((post) => <PostPreview post={post} author={authorData[post.frontmatter.author]} />)} </main> <footer> diff --git a/examples/blog/package.json b/examples/blog/package.json index 2aa6de6fb..a817c7e67 100644 --- a/examples/blog/package.json +++ b/examples/blog/package.json @@ -9,7 +9,7 @@ "preview": "astro preview" }, "devDependencies": { - "astro": "^0.25.3", + "astro": "^0.25.4", "@astrojs/preact": "^0.0.2" }, "dependencies": { diff --git a/examples/blog/src/components/BlogPostPreview.astro b/examples/blog/src/components/BlogPostPreview.astro index 4841d3a65..f935ff8b2 100644 --- a/examples/blog/src/components/BlogPostPreview.astro +++ b/examples/blog/src/components/BlogPostPreview.astro @@ -8,10 +8,10 @@ const { post } = Astro.props; <article class="post-preview"> <header> - <p class="publish-date">{post.publishDate}</p> - <a href={post.url}><h1 class="title">{post.title}</h1></a> + <p class="publish-date">{post.frontmatter.publishDate}</p> + <a href={post.url}><h1 class="title">{post.frontmatter.title}</h1></a> </header> - <p>{post.description}</p> + <p>{post.frontmatter.description}</p> <a href={post.url}>Read more</a> </article> diff --git a/examples/blog/src/pages/index.astro b/examples/blog/src/pages/index.astro index c7bc3ea32..1e1264533 100644 --- a/examples/blog/src/pages/index.astro +++ b/examples/blog/src/pages/index.astro @@ -4,10 +4,6 @@ import BaseHead from '../components/BaseHead.astro'; import BlogHeader from '../components/BlogHeader.astro'; import BlogPostPreview from '../components/BlogPostPreview.astro'; -interface MarkdownFrontmatter { - publishDate: number; -} - // Component Script: // You can write any JavaScript/TypeScript that you'd like here. // It will run during the build, but never in the browser. @@ -18,8 +14,8 @@ let permalink = 'https://example.com/'; // Data Fetching: List all Markdown posts in the repo. -let allPosts = await Astro.fetchContent('./posts/*.md'); -allPosts = allPosts.sort((a, b) => new Date(b.publishDate).valueOf() - new Date(a.publishDate).valueOf()); +let allPosts = await Astro.glob('./posts/*.md'); +allPosts = allPosts.sort((a, b) => new Date(b.frontmatter.publishDate).valueOf() - new Date(a.frontmatter.publishDate).valueOf()); // Full Astro Component Syntax: // https://docs.astro.build/core-concepts/astro-components/ diff --git a/examples/component/demo/package.json b/examples/component/demo/package.json index a327d59cf..9b54773f6 100644 --- a/examples/component/demo/package.json +++ b/examples/component/demo/package.json @@ -10,6 +10,6 @@ }, "devDependencies": { "@example/my-component": "workspace:*", - "astro": "^0.25.3" + "astro": "^0.25.4" } } diff --git a/examples/component/package.json b/examples/component/package.json index 665cd0667..e7e63cb83 100644 --- a/examples/component/package.json +++ b/examples/component/package.json @@ -8,6 +8,6 @@ "serve": "astro --project-root demo preview" }, "devDependencies": { - "astro": "^0.25.3" + "astro": "^0.25.4" } } diff --git a/examples/docs/package.json b/examples/docs/package.json index 3529de1c7..dba62dc47 100644 --- a/examples/docs/package.json +++ b/examples/docs/package.json @@ -20,6 +20,6 @@ "devDependencies": { "@astrojs/preact": "^0.0.2", "@astrojs/react": "^0.0.2", - "astro": "^0.25.3" + "astro": "^0.25.4" } } diff --git a/examples/docs/src/layouts/MainLayout.astro b/examples/docs/src/layouts/MainLayout.astro index 92e0bcf44..8c46278fe 100644 --- a/examples/docs/src/layouts/MainLayout.astro +++ b/examples/docs/src/layouts/MainLayout.astro @@ -17,7 +17,7 @@ const githubEditUrl = CONFIG.GITHUB_EDIT_URL && CONFIG.GITHUB_EDIT_URL + current <html dir={content.dir ?? 'ltr'} lang={content.lang ?? 'en-us'} class="initial"> <head> <HeadCommon /> - <HeadSEO {content} canonicalURL={Astro.request.canonicalURL} /> + <HeadSEO {content} canonicalURL={Astro.canonicalURL} /> <title>{content.title ? `${content.title} 🚀 ${CONFIG.SITE.title}` : CONFIG.SITE.title}</title> <style> body { diff --git a/examples/env-vars/package.json b/examples/env-vars/package.json index 1d934f60e..e0011d2df 100644 --- a/examples/env-vars/package.json +++ b/examples/env-vars/package.json @@ -9,6 +9,6 @@ "preview": "astro preview" }, "devDependencies": { - "astro": "^0.25.3" + "astro": "^0.25.4" } } diff --git a/examples/framework-alpine/package.json b/examples/framework-alpine/package.json index 89ce3a5d9..41fb3eca2 100644 --- a/examples/framework-alpine/package.json +++ b/examples/framework-alpine/package.json @@ -9,6 +9,6 @@ "preview": "astro preview" }, "devDependencies": { - "astro": "^0.25.3" + "astro": "^0.25.4" } } diff --git a/examples/framework-lit/package.json b/examples/framework-lit/package.json index d2c789019..444d29ac6 100644 --- a/examples/framework-lit/package.json +++ b/examples/framework-lit/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/lit": "^0.0.2", - "astro": "^0.25.3" + "astro": "^0.25.4" }, "dependencies": { "@webcomponents/template-shadowroot": "^0.1.0", diff --git a/examples/framework-multiple/package.json b/examples/framework-multiple/package.json index cf7162a5e..8f95c6935 100644 --- a/examples/framework-multiple/package.json +++ b/examples/framework-multiple/package.json @@ -15,7 +15,7 @@ "@astrojs/solid-js": "^0.0.3", "@astrojs/svelte": "^0.0.2", "@astrojs/vue": "^0.0.2", - "astro": "^0.25.3" + "astro": "^0.25.4" }, "dependencies": { "@webcomponents/template-shadowroot": "^0.1.0", diff --git a/examples/framework-preact/package.json b/examples/framework-preact/package.json index 1f10b5bc2..5be07dd77 100644 --- a/examples/framework-preact/package.json +++ b/examples/framework-preact/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/preact": "^0.0.2", - "astro": "^0.25.3" + "astro": "^0.25.4" }, "dependencies": { "preact": "^10.6.6" diff --git a/examples/framework-react/package.json b/examples/framework-react/package.json index 030c7fc88..69bfc446c 100644 --- a/examples/framework-react/package.json +++ b/examples/framework-react/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/react": "^0.0.2", - "astro": "^0.25.3" + "astro": "^0.25.4" }, "dependencies": { "react": "^17.0.2", diff --git a/examples/framework-solid/package.json b/examples/framework-solid/package.json index a75ca71b1..820bbee06 100644 --- a/examples/framework-solid/package.json +++ b/examples/framework-solid/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/solid-js": "^0.0.3", - "astro": "^0.25.3" + "astro": "^0.25.4" }, "dependencies": { "solid-js": "^1.3.13" diff --git a/examples/framework-svelte/package.json b/examples/framework-svelte/package.json index 942099309..f7af94738 100644 --- a/examples/framework-svelte/package.json +++ b/examples/framework-svelte/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/svelte": "^0.0.2", - "astro": "^0.25.3" + "astro": "^0.25.4" }, "dependencies": { "svelte": "^3.46.4" diff --git a/examples/framework-vue/package.json b/examples/framework-vue/package.json index ecd829b5e..eeada1a5e 100644 --- a/examples/framework-vue/package.json +++ b/examples/framework-vue/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/vue": "^0.0.2", - "astro": "^0.25.3" + "astro": "^0.25.4" }, "dependencies": { "vue": "^3.2.31" diff --git a/examples/integrations-playground/package.json b/examples/integrations-playground/package.json index ada918853..6c08c5f46 100644 --- a/examples/integrations-playground/package.json +++ b/examples/integrations-playground/package.json @@ -15,7 +15,7 @@ "@astrojs/sitemap": "^0.0.2", "@astrojs/tailwind": "^0.0.2", "@astrojs/turbolinks": "^0.0.2", - "astro": "^0.25.3" + "astro": "^0.25.4" }, "dependencies": { "@webcomponents/template-shadowroot": "^0.1.0", diff --git a/examples/minimal/package.json b/examples/minimal/package.json index cecbf5c5f..4adc0c827 100644 --- a/examples/minimal/package.json +++ b/examples/minimal/package.json @@ -9,6 +9,6 @@ "preview": "astro preview" }, "devDependencies": { - "astro": "^0.25.3" + "astro": "^0.25.4" } } diff --git a/examples/non-html-pages/package.json b/examples/non-html-pages/package.json index 6cbfb1568..27553f811 100644 --- a/examples/non-html-pages/package.json +++ b/examples/non-html-pages/package.json @@ -9,6 +9,6 @@ "preview": "astro preview" }, "devDependencies": { - "astro": "^0.25.3" + "astro": "^0.25.4" } } diff --git a/examples/portfolio/astro.config.mjs b/examples/portfolio/astro.config.mjs index f0dab7e31..08916b1fe 100644 --- a/examples/portfolio/astro.config.mjs +++ b/examples/portfolio/astro.config.mjs @@ -1,5 +1,5 @@ import { defineConfig } from 'astro/config'; -import preact from '@astrojs/render-preact'; +import preact from '@astrojs/preact'; // https://astro.build/config export default defineConfig({ diff --git a/examples/portfolio/package.json b/examples/portfolio/package.json index 35bdca866..ae5d52396 100644 --- a/examples/portfolio/package.json +++ b/examples/portfolio/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/preact": "^0.0.2", - "astro": "^0.25.3", + "astro": "^0.25.4", "sass": "^1.49.9" }, "dependencies": { diff --git a/examples/portfolio/src/components/PortfolioPreview/index.jsx b/examples/portfolio/src/components/PortfolioPreview/index.jsx index 6957e5884..4f1627604 100644 --- a/examples/portfolio/src/components/PortfolioPreview/index.jsx +++ b/examples/portfolio/src/components/PortfolioPreview/index.jsx @@ -2,16 +2,17 @@ import { h } from 'preact'; import Styles from './styles.module.scss'; function PortfolioPreview({ project }) { + const { frontmatter } = project; return ( <div className={Styles.card}> - <div className={Styles.titleCard} style={`background-image:url(${project.img})`}> - <h1 className={Styles.title}>{project.title}</h1> + <div className={Styles.titleCard} style={`background-image:url(${frontmatter.img})`}> + <h1 className={Styles.title}>{frontmatter.title}</h1> </div> <div className="pa3"> - <p className={`${Styles.desc} mt0 mb2`}>{project.description}</p> + <p className={`${Styles.desc} mt0 mb2`}>{frontmatter.description}</p> <div className={Styles.tags}> Tagged: - {project.tags.map((t) => ( + {frontmatter.tags.map((t) => ( <div className={Styles.tag} data-tag={t}> {t} </div> diff --git a/examples/portfolio/src/pages/index.astro b/examples/portfolio/src/pages/index.astro index ce11119b5..d8a9efcc2 100644 --- a/examples/portfolio/src/pages/index.astro +++ b/examples/portfolio/src/pages/index.astro @@ -7,7 +7,7 @@ import Footer from '../components/Footer/index.jsx'; import PortfolioPreview from '../components/PortfolioPreview/index.jsx'; // Data Fetching: List all Markdown posts in the repo. -const projects = Astro.fetchContent('./project/**/*.md'); +const projects = await Astro.glob('./project/**/*.md'); const featuredProject = projects[0]; // Full Astro Component Syntax: diff --git a/examples/portfolio/src/pages/projects.astro b/examples/portfolio/src/pages/projects.astro index 991c254bc..1aa05e07f 100644 --- a/examples/portfolio/src/pages/projects.astro +++ b/examples/portfolio/src/pages/projects.astro @@ -4,13 +4,9 @@ import Footer from '../components/Footer/index.jsx'; import Nav from '../components/Nav/index.jsx'; import PortfolioPreview from '../components/PortfolioPreview/index.jsx'; -interface MarkdownFrontmatter { - publishDate: number; -} - -const projects = Astro.fetchContent<MarkdownFrontmatter>('./project/**/*.md') - .filter(({ publishDate }) => !!publishDate) - .sort((a, b) => new Date(b.publishDate).valueOf() - new Date(a.publishDate).valueOf()); +const projects = (await Astro.glob('./project/**/*.md')) + .filter(({ frontmatter }) => !!frontmatter.publishDate) + .sort((a, b) => new Date(b.frontmatter.publishDate).valueOf() - new Date(a.frontmatter.publishDate).valueOf()); --- <html lang="en"> diff --git a/examples/ssr/astro.config.mjs b/examples/ssr/astro.config.mjs index f6aba20ce..448d5829d 100644 --- a/examples/ssr/astro.config.mjs +++ b/examples/ssr/astro.config.mjs @@ -6,17 +6,4 @@ import nodejs from '@astrojs/node'; export default defineConfig({ adapter: nodejs(), integrations: [svelte()], - vite: { - server: { - cors: { - credentials: true, - }, - proxy: { - '/api': { - target: 'http://127.0.0.1:8085', - changeOrigin: true, - }, - }, - }, - }, }); diff --git a/examples/ssr/package.json b/examples/ssr/package.json index 884a18a54..401f7e06a 100644 --- a/examples/ssr/package.json +++ b/examples/ssr/package.json @@ -3,9 +3,7 @@ "version": "0.0.1", "private": true, "scripts": { - "dev-api": "node server/dev-api.mjs", - "dev-server": "astro dev --experimental-ssr", - "dev": "concurrently \"npm run dev-api\" \"astro dev --experimental-ssr\"", + "dev": "astro dev --experimental-ssr", "start": "astro dev", "build": "astro build --experimental-ssr", "server": "node server/server.mjs" @@ -13,7 +11,7 @@ "devDependencies": { "@astrojs/svelte": "^0.0.2", "@astrojs/node": "^0.0.2", - "astro": "^0.25.3", + "astro": "^0.25.4", "concurrently": "^7.0.0", "lightcookie": "^1.0.25", "unocss": "^0.15.6", diff --git a/examples/ssr/server/api.mjs b/examples/ssr/server/api.mjs deleted file mode 100644 index 589766ee9..000000000 --- a/examples/ssr/server/api.mjs +++ /dev/null @@ -1,100 +0,0 @@ -import fs from 'fs'; -import lightcookie from 'lightcookie'; - -const dbJSON = fs.readFileSync(new URL('./db.json', import.meta.url)); -const db = JSON.parse(dbJSON); -const products = db.products; -const productMap = new Map(products.map((product) => [product.id, product])); - -// Normally this would be in a database. -const userCartItems = new Map(); - -const routes = [ - { - match: /\/api\/products\/([0-9])+/, - async handle(_req, res, [, idStr]) { - const id = Number(idStr); - if (productMap.has(id)) { - const product = productMap.get(id); - res.writeHead(200, { - 'Content-Type': 'application/json', - }); - res.end(JSON.stringify(product)); - } else { - res.writeHead(404, { - 'Content-Type': 'text/plain', - }); - res.end('Not found'); - } - }, - }, - { - match: /\/api\/products/, - async handle(_req, res) { - res.writeHead(200, { - 'Content-Type': 'application/json', - }); - res.end(JSON.stringify(products)); - }, - }, - { - match: /\/api\/cart/, - async handle(req, res) { - res.writeHead(200, { - 'Content-Type': 'application/json', - }); - let cookie = req.headers.cookie; - let userId = cookie ? lightcookie.parse(cookie)['user-id'] : '1'; // default for testing - if (!userId || !userCartItems.has(userId)) { - res.end(JSON.stringify({ items: [] })); - return; - } - let items = userCartItems.get(userId); - let array = Array.from(items.values()); - res.end(JSON.stringify({ items: array })); - }, - }, - { - match: /\/api\/add-to-cart/, - async handle(req, res) { - let body = ''; - req.on('data', (chunk) => (body += chunk)); - return new Promise((resolve) => { - req.on('end', () => { - let cookie = req.headers.cookie; - let userId = lightcookie.parse(cookie)['user-id']; - let msg = JSON.parse(body); - - if (!userCartItems.has(userId)) { - userCartItems.set(userId, new Map()); - } - - let cart = userCartItems.get(userId); - if (cart.has(msg.id)) { - cart.get(msg.id).count++; - } else { - cart.set(msg.id, { id: msg.id, name: msg.name, count: 1 }); - } - - res.writeHead(200, { - 'Content-Type': 'application/json', - }); - res.end(JSON.stringify({ ok: true })); - }); - }); - }, - }, -]; - -export async function apiHandler(req, res) { - for (const route of routes) { - const match = route.match.exec(req.url); - if (match) { - return route.handle(req, res, match); - } - } - res.writeHead(404, { - 'Content-Type': 'text/plain', - }); - res.end('Not found'); -} diff --git a/examples/ssr/server/dev-api.mjs b/examples/ssr/server/dev-api.mjs deleted file mode 100644 index 305ac609b..000000000 --- a/examples/ssr/server/dev-api.mjs +++ /dev/null @@ -1,17 +0,0 @@ -import { createServer } from 'http'; -import { apiHandler } from './api.mjs'; - -const PORT = process.env.PORT || 8085; - -const server = createServer((req, res) => { - apiHandler(req, res).catch((err) => { - console.error(err); - res.writeHead(500, { - 'Content-Type': 'text/plain', - }); - res.end(err.toString()); - }); -}); - -server.listen(PORT); -console.log(`API running at http://localhost:${PORT}`); diff --git a/examples/ssr/server/server.mjs b/examples/ssr/server/server.mjs index bed49b749..d7a0a7a40 100644 --- a/examples/ssr/server/server.mjs +++ b/examples/ssr/server/server.mjs @@ -1,29 +1,28 @@ import { createServer } from 'http'; import fs from 'fs'; import mime from 'mime'; -import { apiHandler } from './api.mjs'; import { handler as ssrHandler } from '../dist/server/entry.mjs'; const clientRoot = new URL('../dist/client/', import.meta.url); async function handle(req, res) { - ssrHandler(req, res, async () => { - // Did not match an SSR route + ssrHandler(req, res, async (err) => { + if (err) { + res.writeHead(500); + res.end(err.stack); + return; + } - if (/^\/api\//.test(req.url)) { - return apiHandler(req, res); - } else { - let local = new URL('.' + req.url, clientRoot); - try { - const data = await fs.promises.readFile(local); - res.writeHead(200, { - 'Content-Type': mime.getType(req.url), - }); - res.end(data); - } catch { - res.writeHead(404); - res.end(); - } + let local = new URL('.' + req.url, clientRoot); + try { + const data = await fs.promises.readFile(local); + res.writeHead(200, { + 'Content-Type': mime.getType(req.url), + }); + res.end(data); + } catch { + res.writeHead(404); + res.end(); } }); } diff --git a/examples/ssr/src/api.ts b/examples/ssr/src/api.ts index 40058360b..82c82a190 100644 --- a/examples/ssr/src/api.ts +++ b/examples/ssr/src/api.ts @@ -17,11 +17,12 @@ interface Cart { }>; } -const { MODE } = import.meta.env; -const origin = MODE === 'development' ? `http://127.0.0.1:3000` : `http://127.0.0.1:8085`; +function getOrigin(request: Request): string { + return new URL(request.url).origin.replace('localhost', '127.0.0.1'); +} -async function get<T>(endpoint: string, cb: (response: Response) => Promise<T>): Promise<T> { - const response = await fetch(`${origin}${endpoint}`, { +async function get<T>(incomingReq: Request, endpoint: string, cb: (response: Response) => Promise<T>): Promise<T> { + const response = await fetch(`${getOrigin(incomingReq)}${endpoint}`, { credentials: 'same-origin', }); if (!response.ok) { @@ -31,36 +32,36 @@ async function get<T>(endpoint: string, cb: (response: Response) => Promise<T>): return cb(response); } -export async function getProducts(): Promise<Product[]> { - return get<Product[]>('/api/products', async (response) => { +export async function getProducts(incomingReq: Request): Promise<Product[]> { + return get<Product[]>(incomingReq, '/api/products', async (response) => { const products: Product[] = await response.json(); return products; }); } -export async function getProduct(id: number): Promise<Product> { - return get<Product>(`/api/products/${id}`, async (response) => { +export async function getProduct(incomingReq: Request, id: number): Promise<Product> { + return get<Product>(incomingReq, `/api/products/${id}`, async (response) => { const product: Product = await response.json(); return product; }); } -export async function getUser(): Promise<User> { - return get<User>(`/api/user`, async (response) => { +export async function getUser(incomingReq: Request): Promise<User> { + return get<User>(incomingReq, `/api/user`, async (response) => { const user: User = await response.json(); return user; }); } -export async function getCart(): Promise<Cart> { - return get<Cart>(`/api/cart`, async (response) => { +export async function getCart(incomingReq: Request): Promise<Cart> { + return get<Cart>(incomingReq, `/api/cart`, async (response) => { const cart: Cart = await response.json(); return cart; }); } export async function addToUserCart(id: number | string, name: string): Promise<void> { - await fetch(`${origin}/api/add-to-cart`, { + await fetch(`${location.origin}/api/cart`, { credentials: 'same-origin', method: 'POST', mode: 'no-cors', diff --git a/examples/ssr/src/components/Header.astro b/examples/ssr/src/components/Header.astro index c4d925a5f..426fb4be5 100644 --- a/examples/ssr/src/components/Header.astro +++ b/examples/ssr/src/components/Header.astro @@ -3,7 +3,7 @@ import TextDecorationSkip from './TextDecorationSkip.astro'; import Cart from './Cart.svelte'; import { getCart } from '../api'; -const cart = await getCart(); +const cart = await getCart(Astro.request); const cartCount = cart.items.reduce((sum, item) => sum + item.count, 0); --- <style> diff --git a/examples/ssr/server/db.json b/examples/ssr/src/models/db.json index 76f9e4da3..76f9e4da3 100644 --- a/examples/ssr/server/db.json +++ b/examples/ssr/src/models/db.json diff --git a/examples/ssr/src/models/db.ts b/examples/ssr/src/models/db.ts new file mode 100644 index 000000000..0ec181f9a --- /dev/null +++ b/examples/ssr/src/models/db.ts @@ -0,0 +1,6 @@ +import db from './db.json'; + +const products = db.products; +const productMap = new Map(products.map((product) => [product.id, product])); + +export { products, productMap }; diff --git a/examples/ssr/src/models/session.ts b/examples/ssr/src/models/session.ts new file mode 100644 index 000000000..16dce00b4 --- /dev/null +++ b/examples/ssr/src/models/session.ts @@ -0,0 +1,2 @@ +// Normally this would be in a database. +export const userCartItems = new Map(); diff --git a/examples/ssr/src/pages/api/cart.ts b/examples/ssr/src/pages/api/cart.ts new file mode 100644 index 000000000..3d7dd6da0 --- /dev/null +++ b/examples/ssr/src/pages/api/cart.ts @@ -0,0 +1,47 @@ +import lightcookie from 'lightcookie'; +import { userCartItems } from '../../models/session'; + +export function get(_params: any, request: Request) { + let cookie = request.headers.get('cookie'); + let userId = cookie ? lightcookie.parse(cookie)['user-id'] : '1'; // default for testing + if (!userId || !userCartItems.has(userId)) { + return { + body: JSON.stringify({ items: [] }), + }; + } + let items = userCartItems.get(userId); + let array = Array.from(items.values()); + + return { + body: JSON.stringify({ items: array }), + }; +} + +interface AddToCartItem { + id: number; + name: string; +} + +export async function post(_params: any, request: Request) { + const item: AddToCartItem = await request.json(); + + let cookie = request.headers.get('cookie'); + let userId = lightcookie.parse(cookie)['user-id']; + + if (!userCartItems.has(userId)) { + userCartItems.set(userId, new Map()); + } + + let cart = userCartItems.get(userId); + if (cart.has(item.id)) { + cart.get(item.id).count++; + } else { + cart.set(item.id, { id: item.id, name: item.name, count: 1 }); + } + + return { + body: JSON.stringify({ + ok: true, + }), + }; +} diff --git a/examples/ssr/src/pages/api/products.ts b/examples/ssr/src/pages/api/products.ts new file mode 100644 index 000000000..171291004 --- /dev/null +++ b/examples/ssr/src/pages/api/products.ts @@ -0,0 +1,7 @@ +import { products } from '../../models/db'; + +export function get() { + return { + body: JSON.stringify(products), + }; +} diff --git a/examples/ssr/src/pages/api/products/[id].ts b/examples/ssr/src/pages/api/products/[id].ts new file mode 100644 index 000000000..d3cc5e42f --- /dev/null +++ b/examples/ssr/src/pages/api/products/[id].ts @@ -0,0 +1,17 @@ +import { productMap } from '../../../models/db'; + +export function get({ id: idStr }) { + const id = Number(idStr); + if (productMap.has(id)) { + const product = productMap.get(id); + + return { + body: JSON.stringify(product), + }; + } else { + return new Response(null, { + status: 400, + statusText: 'Not found', + }); + } +} diff --git a/examples/ssr/src/pages/cart.astro b/examples/ssr/src/pages/cart.astro index e4a00183e..3277ff2db 100644 --- a/examples/ssr/src/pages/cart.astro +++ b/examples/ssr/src/pages/cart.astro @@ -11,7 +11,7 @@ if(!isLoggedIn(Astro.request)) { // They must be logged in. const user = { name: 'test'}; // getUser? -const cart = await getCart(); +const cart = await getCart(Astro.request); --- <html> <head> diff --git a/examples/ssr/src/pages/index.astro b/examples/ssr/src/pages/index.astro index ea2c6c2f6..8eb04ffa6 100644 --- a/examples/ssr/src/pages/index.astro +++ b/examples/ssr/src/pages/index.astro @@ -5,7 +5,7 @@ import ProductListing from '../components/ProductListing.astro'; import { getProducts } from '../api'; import '../styles/common.css'; -const products = await getProducts(); +const products = await getProducts(Astro.request); --- <html> <head> diff --git a/examples/ssr/src/pages/products/[id].astro b/examples/ssr/src/pages/products/[id].astro index 37fe7e0b4..f6ac67f82 100644 --- a/examples/ssr/src/pages/products/[id].astro +++ b/examples/ssr/src/pages/products/[id].astro @@ -5,8 +5,8 @@ import AddToCart from '../../components/AddToCart.svelte'; import { getProduct } from '../../api'; import '../../styles/common.css'; -const id = Number(Astro.request.params.id); -const product = await getProduct(id); +const id = Number(Astro.params.id); +const product = await getProduct(Astro.request, id); --- <html lang="en"> diff --git a/examples/ssr/tsconfig.json b/examples/ssr/tsconfig.json index e0065a323..ee0432bb3 100644 --- a/examples/ssr/tsconfig.json +++ b/examples/ssr/tsconfig.json @@ -3,6 +3,7 @@ "lib": ["ES2015", "DOM"], "module": "ES2022", "moduleResolution": "node", + "resolveJsonModule": true, "types": ["astro/env"] } } diff --git a/examples/starter/package.json b/examples/starter/package.json index 0fff1a509..65ea2b04d 100644 --- a/examples/starter/package.json +++ b/examples/starter/package.json @@ -9,6 +9,6 @@ "preview": "astro preview" }, "devDependencies": { - "astro": "^0.25.3" + "astro": "^0.25.4" } } diff --git a/examples/subpath/package.json b/examples/subpath/package.json index cc4c33c3c..f48f47a11 100644 --- a/examples/subpath/package.json +++ b/examples/subpath/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/react": "^0.0.2", - "astro": "^0.25.3", + "astro": "^0.25.4", "sass": "^1.49.9" }, "dependencies": { diff --git a/examples/with-markdown-plugins/package.json b/examples/with-markdown-plugins/package.json index 52495596a..7c02a8014 100644 --- a/examples/with-markdown-plugins/package.json +++ b/examples/with-markdown-plugins/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/markdown-remark": "^0.7.0", - "astro": "^0.25.3", + "astro": "^0.25.4", "hast-util-select": "5.0.1", "rehype-autolink-headings": "^6.1.1", "rehype-slug": "^5.0.1", diff --git a/examples/with-markdown-shiki/package.json b/examples/with-markdown-shiki/package.json index c1feb2baa..33de85830 100644 --- a/examples/with-markdown-shiki/package.json +++ b/examples/with-markdown-shiki/package.json @@ -10,6 +10,6 @@ }, "devDependencies": { "@astrojs/markdown-remark": "^0.7.0", - "astro": "^0.25.3" + "astro": "^0.25.4" } } diff --git a/examples/with-markdown/package.json b/examples/with-markdown/package.json index 3f2e894a3..843ee33ff 100644 --- a/examples/with-markdown/package.json +++ b/examples/with-markdown/package.json @@ -14,7 +14,7 @@ "@astrojs/react": "^0.0.2", "@astrojs/svelte": "^0.0.2", "@astrojs/vue": "^0.0.2", - "astro": "^0.25.3" + "astro": "^0.25.4" }, "dependencies": { "preact": "^10.6.6", diff --git a/examples/with-nanostores/package.json b/examples/with-nanostores/package.json index 5bfc50268..828a8a608 100644 --- a/examples/with-nanostores/package.json +++ b/examples/with-nanostores/package.json @@ -25,6 +25,6 @@ "@astrojs/solid-js": "^0.0.3", "@astrojs/svelte": "^0.0.2", "@astrojs/vue": "^0.0.2", - "astro": "^0.25.3" + "astro": "^0.25.4" } } diff --git a/examples/with-tailwindcss/package.json b/examples/with-tailwindcss/package.json index 8b48d6084..04cfa9258 100644 --- a/examples/with-tailwindcss/package.json +++ b/examples/with-tailwindcss/package.json @@ -10,7 +10,7 @@ }, "devDependencies": { "@astrojs/tailwind": "^0.0.2", - "astro": "^0.25.3", + "astro": "^0.25.4", "autoprefixer": "^10.4.4", "canvas-confetti": "^1.5.1", "postcss": "^8.4.12", diff --git a/examples/with-vite-plugin-pwa/package.json b/examples/with-vite-plugin-pwa/package.json index 47051bf98..4ac168012 100644 --- a/examples/with-vite-plugin-pwa/package.json +++ b/examples/with-vite-plugin-pwa/package.json @@ -9,7 +9,7 @@ "preview": "astro preview" }, "devDependencies": { - "astro": "^0.25.3", + "astro": "^0.25.4", "vite-plugin-pwa": "0.11.11", "workbox-window": "^6.5.2" } diff --git a/package.json b/package.json index fc7de1c50..60d98b009 100644 --- a/package.json +++ b/package.json @@ -55,14 +55,14 @@ "@astrojs/webapi": "workspace:*" }, "devDependencies": { - "@changesets/changelog-github": "^0.4.3", - "@changesets/cli": "^2.21.1", + "@changesets/changelog-github": "^0.4.4", + "@changesets/cli": "^2.22.0", "@octokit/action": "^3.18.0", - "@typescript-eslint/eslint-plugin": "^5.16.0", - "@typescript-eslint/parser": "^5.16.0", + "@typescript-eslint/eslint-plugin": "^5.17.0", + "@typescript-eslint/parser": "^5.17.0", "del": "^6.0.0", "esbuild": "0.14.25", - "eslint": "^8.11.0", + "eslint": "^8.12.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-prettier": "^4.0.0", "execa": "^6.1.0", diff --git a/packages/astro/CHANGELOG.md b/packages/astro/CHANGELOG.md index b106e3fa4..7b86e33b4 100644 --- a/packages/astro/CHANGELOG.md +++ b/packages/astro/CHANGELOG.md @@ -1,5 +1,11 @@ # astro +## 0.25.4 + +### Patch Changes + +- [#2907](https://github.com/withastro/astro/pull/2907) [`22b1432e`](https://github.com/withastro/astro/commit/22b1432e3eed6ff40a0ab383c8f1f06f0df10d62) Thanks [@delucis](https://github.com/delucis)! - Fix typing of `integrations` array in user config + ## 0.25.3 ### Patch Changes diff --git a/packages/astro/env.d.ts b/packages/astro/env.d.ts index 88a4bcce3..ebb416dd2 100644 --- a/packages/astro/env.d.ts +++ b/packages/astro/env.d.ts @@ -1,6 +1,6 @@ /// <reference types="vite/client" /> -type Astro = import('./dist/types/@types/astro').AstroGlobal; +type Astro = import('astro').AstroGlobal; // We duplicate the description here because editors won't show the JSDoc comment from the imported type (but will for its properties, ex: Astro.request will show the AstroGlobal.request description) /** diff --git a/packages/astro/package.json b/packages/astro/package.json index d42143865..d475244bb 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "astro", - "version": "0.25.3", + "version": "0.25.4", "description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.", "type": "module", "author": "withastro", @@ -85,6 +85,7 @@ "@proload/core": "^0.2.2", "@proload/plugin-tsm": "^0.1.1", "@web/parse5-utils": "^1.3.0", + "ast-types": "^0.14.2", "boxen": "^6.2.1", "ci-info": "^3.3.0", "common-ancestor-path": "^1.0.1", @@ -97,7 +98,7 @@ "execa": "^6.1.0", "fast-glob": "^3.2.11", "fast-xml-parser": "^4.0.7", - "html-entities": "^2.3.2", + "html-entities": "^2.3.3", "html-escaper": "^3.0.3", "htmlparser2": "^7.2.0", "kleur": "^4.1.4", @@ -109,10 +110,11 @@ "parse5": "^6.0.1", "path-to-regexp": "^6.2.0", "postcss": "^8.4.12", - "postcss-load-config": "^3.1.3", + "postcss-load-config": "^3.1.4", "preferred-pm": "^3.0.3", "prismjs": "^1.27.0", "prompts": "^2.4.2", + "recast": "^0.20.5", "rehype-slug": "^5.0.1", "resolve": "^1.22.0", "rollup": "^2.70.1", @@ -130,7 +132,7 @@ "tsconfig-resolver": "^3.0.1", "vite": "^2.8.6", "yargs-parser": "^21.0.1", - "zod": "^3.14.2" + "zod": "^3.14.3" }, "devDependencies": { "@babel/types": "^7.17.0", diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index a224062b1..47c783e0d 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -1,10 +1,9 @@ import type { AddressInfo } from 'net'; import type * as babel from '@babel/core'; import type * as vite from 'vite'; -import type { z } from 'zod'; +import { z } from 'zod'; import type { AstroConfigSchema } from '../core/config'; import type { AstroComponentFactory, Metadata } from '../runtime/server'; -import type { AstroRequest } from '../core/render/request'; export type { SSRManifest } from '../core/app/types'; export interface AstroBuiltinProps { @@ -51,20 +50,28 @@ export interface BuildConfig { * Docs: https://docs.astro.build/reference/api-reference/#astro-global */ export interface AstroGlobal extends AstroGlobalPartial { + /** get the current canonical URL */ + canonicalURL: URL; + /** get page params (dynamic pages only) */ + params: Params; /** set props for this astro component (along with default values) */ props: Record<string, number | string | any>; /** get information about this page */ - request: AstroRequest; + request: Request; /** see if slots are used */ slots: Record<string, true | undefined> & { has(slotName: string): boolean; render(slotName: string): Promise<string> }; } export interface AstroGlobalPartial { - fetchContent<T = any>(globStr: string): Promise<FetchContentResult<T>[]>; /** * @deprecated since version 0.24. See the {@link https://astro.build/deprecated/resolve upgrade guide} for more details. */ resolve: (path: string) => string; + /** @deprecated Use `Astro.glob()` instead. */ + fetchContent(globStr: string): Promise<any[]>; + glob(globStr: `${any}.astro`): Promise<ComponentInstance[]>; + glob<T extends Record<string, any>>(globStr: `${any}.md`): Promise<MarkdownInstance<T>[]>; + glob<T extends Record<string, any>>(globStr: string): Promise<T[]>; site: URL; } @@ -509,20 +516,13 @@ export interface ComponentInstance { getStaticPaths?: (options: GetStaticPathsOptions) => GetStaticPathsResult; } -/** - * Astro.fetchContent() result - * Docs: https://docs.astro.build/reference/api-reference/#astrofetchcontent - */ -export type FetchContentResult<T> = FetchContentResultBase & T; - -export type FetchContentResultBase = { - astro: { - headers: string[]; - source: string; - html: string; - }; - url: string; -}; +export interface MarkdownInstance<T extends Record<string, any>> { + frontmatter: T; + file: string; + url: string | undefined; + Content: AstroComponentFactory; + getHeaders(): Promise<{ depth: number; slug: string; text: string }[]>; +} export type GetHydrateCallback = () => Promise<(element: Element, innerHTML: string | null) => void>; @@ -636,7 +636,7 @@ export interface EndpointOutput<Output extends Body = Body> { } export interface EndpointHandler { - [method: string]: (params: any, request: AstroRequest) => EndpointOutput | Response; + [method: string]: (params: any, request: Request) => EndpointOutput | Response; } export interface AstroRenderer { diff --git a/packages/astro/src/cli/check.ts b/packages/astro/src/cli/check.ts index 499ac9afd..ffdc246df 100644 --- a/packages/astro/src/cli/check.ts +++ b/packages/astro/src/cli/check.ts @@ -57,7 +57,7 @@ function offsetAt({ line, character }: { line: number; character: number }, text return i; } -function pad(str: string, len: number) { +function generateString(str: string, len: number) { return Array.from({ length: len }, () => str).join(''); } @@ -86,8 +86,8 @@ export async function check(astroConfig: AstroConfig) { const lineNumStr = d.range.start.line.toString(); const lineNumLen = lineNumStr.length; console.error(`${bgWhite(black(lineNumStr))} ${str}`); - let tildes = pad('~', d.range.end.character - d.range.start.character); - let spaces = pad(' ', d.range.start.character + lineNumLen - 1); + let tildes = generateString('~', d.range.end.character - d.range.start.character); + let spaces = generateString(' ', d.range.start.character + lineNumLen - 1); console.error(` ${spaces}${bold(red(tildes))}\n`); result.errors++; break; diff --git a/packages/astro/src/cli/index.ts b/packages/astro/src/cli/index.ts index 4108d4984..5b4f2abbc 100644 --- a/packages/astro/src/cli/index.ts +++ b/packages/astro/src/cli/index.ts @@ -12,8 +12,9 @@ import add from '../core/add/index.js'; import devServer from '../core/dev/index.js'; import preview from '../core/preview/index.js'; import { check } from './check.js'; -import { formatConfigError, loadConfig } from '../core/config.js'; -import { printHelp } from '../core/messages.js'; +import { loadConfig } from '../core/config.js'; +import { printHelp, formatErrorMessage, formatConfigErrorMessage } from '../core/messages.js'; +import { createSafeError } from '../core/util.js'; type Arguments = yargs.Arguments; type CLICommand = 'help' | 'version' | 'add' | 'dev' | 'build' | 'preview' | 'reload' | 'check'; @@ -102,40 +103,33 @@ export async function cli(args: string[]) { // For now, `add` has to resolve the config again internally config = await loadConfig({ cwd: projectRoot, flags }); } catch (err) { - throwAndExit(err); - return; + return throwAndExit(err); } switch (cmd) { case 'add': { try { const packages = flags._.slice(3) as string[]; - await add(packages, { cwd: projectRoot, flags, logging }); - process.exit(0); + return await add(packages, { cwd: projectRoot, flags, logging }); } catch (err) { - throwAndExit(err); + return throwAndExit(err); } - return; } case 'dev': { try { await devServer(config, { logging }); - - await new Promise(() => {}); // don’t close dev server + return await new Promise(() => {}); // lives forever } catch (err) { - throwAndExit(err); + return throwAndExit(err); } - return; } case 'build': { try { - await build(config, { logging }); - process.exit(0); + return await build(config, { logging }); } catch (err) { - throwAndExit(err); + return throwAndExit(err); } - return; } case 'check': { @@ -145,11 +139,10 @@ export async function cli(args: string[]) { case 'preview': { try { - await preview(config, { logging }); // this will keep running + return await preview(config, { logging }); // this will keep running } catch (err) { - throwAndExit(err); + return throwAndExit(err); } - return; } default: { @@ -159,14 +152,11 @@ export async function cli(args: string[]) { } /** Display error and exit */ -function throwAndExit(err: any) { +function throwAndExit(err: unknown) { if (err instanceof z.ZodError) { - console.error(formatConfigError(err)); - } else if (err.stack) { - const [mainMsg, ...stackMsg] = err.stack.split('\n'); - console.error(colors.red(mainMsg) + '\n' + colors.dim(stackMsg.join('\n'))); + console.error(formatConfigErrorMessage(err)); } else { - console.error(colors.red(err.toString() || err)); + console.error(formatErrorMessage(createSafeError(err))); } process.exit(1); } diff --git a/packages/astro/src/core/add/index.ts b/packages/astro/src/core/add/index.ts index 74045cc6e..d1f63a9cf 100644 --- a/packages/astro/src/core/add/index.ts +++ b/packages/astro/src/core/add/index.ts @@ -54,6 +54,7 @@ export default async function add(names: string[], { cwd, flags, logging }: AddO } applyPolyfill(); + // If no integrations were given, prompt the user for some popular ones. if (names.length === 0) { const response = await prompts([ { @@ -72,16 +73,13 @@ export default async function add(names: string[], { cwd, flags, logging }: AddO }, ]); - if (!response.frameworks && !response.addons) { - info(logging, null, msg.cancelled(`Integrations skipped.`, `You can always run ${cyan('astro add')} later!`)); - return; - } - const selected = [response.frameworks ?? [], response.addons ?? []].flat(1); - if (selected.length === 0) { - error(logging, null, `\n${red('No integrations specified!')}\n${dim('Try running')} astro add again.`); - return; - } - names = selected; + names = [...(response.frameworks ?? []), ...(response.addons ?? [])]; + } + + // If still empty after prompting, exit gracefully. + if (names.length === 0) { + error(logging, null, `No integrations specified.`); + return; } // Some packages might have a common alias! We normalize those here. diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts index 404492398..df3c94a68 100644 --- a/packages/astro/src/core/app/index.ts +++ b/packages/astro/src/core/app/index.ts @@ -10,6 +10,7 @@ import { call as callEndpoint } from '../endpoint/index.js'; import { RouteCache } from '../render/route-cache.js'; import { createLinkStylesheetElementSet, createModuleScriptElementWithSrcSet } from '../render/ssr-element.js'; import { prependForwardSlash } from '../path.js'; +import { createRequest } from '../request.js'; export class App { #manifest: Manifest; @@ -17,6 +18,7 @@ export class App { #routeDataToRouteInfo: Map<RouteData, RouteInfo>; #routeCache: RouteCache; #encoder = new TextEncoder(); + #logging = defaultLogOptions; constructor(manifest: Manifest) { this.#manifest = manifest; @@ -63,7 +65,7 @@ export class App { const result = await render({ legacyBuild: false, links, - logging: defaultLogOptions, + logging: this.#logging, markdownRender: manifest.markdown.render, mod, origin: url.origin, @@ -81,8 +83,7 @@ export class App { routeCache: this.#routeCache, site: this.#manifest.site, ssr: true, - method: info.routeData.type === 'endpoint' ? '' : 'GET', - headers: request.headers, + request, }); if (result.type === 'response') { @@ -100,15 +101,14 @@ export class App { }); } - async #callEndpoint(request: Request, routeData: RouteData, mod: ComponentInstance): Promise<Response> { + async #callEndpoint(request: Request, _routeData: RouteData, mod: ComponentInstance): Promise<Response> { const url = new URL(request.url); const handler = mod as unknown as EndpointHandler; const result = await callEndpoint(handler, { - headers: request.headers, logging: defaultLogOptions, - method: request.method, origin: url.origin, pathname: url.pathname, + request, routeCache: this.#routeCache, ssr: true, }); diff --git a/packages/astro/src/core/build/common.ts b/packages/astro/src/core/build/common.ts index 5407f66fd..a29aa356c 100644 --- a/packages/astro/src/core/build/common.ts +++ b/packages/astro/src/core/build/common.ts @@ -4,7 +4,7 @@ import { appendForwardSlash } from '../../core/path.js'; const STATUS_CODE_PAGES = new Set(['/404', '/500']); -export function getOutRoot(astroConfig: AstroConfig): URL { +function getOutRoot(astroConfig: AstroConfig): URL { return new URL('./', astroConfig.dist); } diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index 119274e76..f18f7b2bb 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -1,22 +1,23 @@ +import fs from 'fs'; +import { bgGreen, bgMagenta, black, cyan, dim, green, magenta } from 'kleur/colors'; +import npath from 'path'; import type { OutputAsset, OutputChunk, RollupOutput } from 'rollup'; +import { fileURLToPath } from 'url'; import type { AstroConfig, ComponentInstance, EndpointHandler, SSRLoadedRenderer } from '../../@types/astro'; -import type { PageBuildData, StaticBuildOptions, SingleFileBuiltModule } from './types'; import type { BuildInternals } from '../../core/build/internal.js'; +import { debug, info } from '../../core/logger.js'; +import { appendForwardSlash, prependForwardSlash } from '../../core/path.js'; import type { RenderOptions } from '../../core/render/core'; - -import fs from 'fs'; -import npath from 'path'; -import { fileURLToPath } from 'url'; -import { debug, error, info } from '../../core/logger.js'; -import { prependForwardSlash } from '../../core/path.js'; import { BEFORE_HYDRATION_SCRIPT_ID } from '../../vite-plugin-scripts/index.js'; import { call as callEndpoint } from '../endpoint/index.js'; import { render } from '../render/core.js'; import { createLinkStylesheetElementSet, createModuleScriptElementWithSrcSet } from '../render/ssr-element.js'; -import { getOutFile, getOutRoot, getOutFolder } from './common.js'; -import { getPageDataByComponent, eachPageData } from './internal.js'; -import { bgMagenta, black, cyan, dim, magenta } from 'kleur/colors'; +import { getOutputFilename } from '../util.js'; +import { getOutFile, getOutFolder } from './common.js'; +import { eachPageData, getPageDataByComponent } from './internal.js'; +import type { PageBuildData, SingleFileBuiltModule, StaticBuildOptions } from './types'; import { getTimeStat } from './util.js'; +import { createRequest } from '../request.js'; // Render is usually compute, which Node.js can't parallelize well. // In real world testing, dropping from 10->1 showed a notiable perf @@ -67,7 +68,8 @@ export function chunkIsPage(astroConfig: AstroConfig, output: OutputAsset | Outp } export async function generatePages(result: RollupOutput, opts: StaticBuildOptions, internals: BuildInternals, facadeIdToPageDataMap: Map<string, PageBuildData>) { - info(opts.logging, null, `\n${bgMagenta(black(' generating static routes '))}\n`); + const timer = performance.now(); + info(opts.logging, null, `\n${bgGreen(black(' generating static routes '))}`); const ssr = !!opts.astroConfig._ctx.adapter?.serverEntrypoint; const serverEntry = opts.buildConfig.serverEntry; @@ -78,6 +80,7 @@ export async function generatePages(result: RollupOutput, opts: StaticBuildOptio for (const pageData of eachPageData(internals)) { await generatePage(opts, internals, pageData, ssrEntry); } + info(opts.logging, null, dim(`Completed in ${getTimeStat(timer, performance.now())}.\n`)); } async function generatePage( @@ -109,31 +112,18 @@ async function generatePage( renderers, }; - const icon = pageData.route.type === 'page' ? cyan('</>') : magenta('{-}'); + const icon = pageData.route.type === 'page' ? green('▶') : magenta('λ'); info(opts.logging, null, `${icon} ${pageData.route.component}`); - // Throttle the paths to avoid overloading the CPU with too many tasks. - const renderPromises = []; - for (const paths of throttle(MAX_CONCURRENT_RENDERS, pageData.paths)) { - for (const path of paths) { - renderPromises.push(generatePath(path, opts, generationOptions)); - } - // This blocks generating more paths until these 10 complete. - await Promise.all(renderPromises); + for (let i = 0; i < pageData.paths.length; i++) { + const path = pageData.paths[i]; + await generatePath(path, opts, generationOptions); const timeEnd = performance.now(); const timeChange = getTimeStat(timeStart, timeEnd); - let shouldLogTimeChange = !getTimeStat(timeStart, timeEnd).startsWith('0'); - for (const path of paths) { - const timeIncrease = shouldLogTimeChange ? ` ${dim(`+${timeChange}`)}` : ''; - info(opts.logging, null, ` ${dim('┃')} ${path}${timeIncrease}`); - // Should only log build time on the first generated path - // Logging for all generated paths adds extra noise - shouldLogTimeChange = false; - } - // Reset timeStart for the next batch of rendered paths - timeStart = performance.now(); - // This empties the array without allocating a new one. - renderPromises.length = 0; + const timeIncrease = `(+${timeChange})`; + const filePath = getOutputFilename(opts.astroConfig, path); + const lineIcon = i === pageData.paths.length - 1 ? '└─' : '├─'; + info(opts.logging, null, ` ${cyan(lineIcon)} ${dim(filePath)} ${dim(timeIncrease)}`); } } @@ -175,65 +165,61 @@ async function generatePath(pathname: string, opts: StaticBuildOptions, gopts: G } } - try { - const options: RenderOptions = { - legacyBuild: false, - links, - logging, - markdownRender: astroConfig.markdownOptions.render, - mod, - origin, - pathname, - scripts, - renderers, - async resolve(specifier: string) { - const hashedFilePath = internals.entrySpecifierToBundleMap.get(specifier); - if (typeof hashedFilePath !== 'string') { - // If no "astro:scripts/before-hydration.js" script exists in the build, - // then we can assume that no before-hydration scripts are needed. - // Return this as placeholder, which will be ignored by the browser. - // TODO: In the future, we hope to run this entire script through Vite, - // removing the need to maintain our own custom Vite-mimic resolve logic. - if (specifier === BEFORE_HYDRATION_SCRIPT_ID) { - return 'data:text/javascript;charset=utf-8,//[no before-hydration script]'; - } - throw new Error(`Cannot find the built path for ${specifier}`); + const url = new URL(origin + pathname); + const options: RenderOptions = { + legacyBuild: false, + links, + logging, + markdownRender: astroConfig.markdownOptions.render, + mod, + origin, + pathname, + scripts, + renderers, + async resolve(specifier: string) { + const hashedFilePath = internals.entrySpecifierToBundleMap.get(specifier); + if (typeof hashedFilePath !== 'string') { + // If no "astro:scripts/before-hydration.js" script exists in the build, + // then we can assume that no before-hydration scripts are needed. + // Return this as placeholder, which will be ignored by the browser. + // TODO: In the future, we hope to run this entire script through Vite, + // removing the need to maintain our own custom Vite-mimic resolve logic. + if (specifier === BEFORE_HYDRATION_SCRIPT_ID) { + return 'data:text/javascript;charset=utf-8,//[no before-hydration script]'; } - const relPath = npath.posix.relative(pathname, '/' + hashedFilePath); - const fullyRelativePath = relPath[0] === '.' ? relPath : './' + relPath; - return fullyRelativePath; - }, - method: 'GET', - headers: new Headers(), - route: pageData.route, - routeCache, - site: astroConfig.buildOptions.site, - ssr: opts.astroConfig.buildOptions.experimentalSsr, - }; - - let body: string; - if (pageData.route.type === 'endpoint') { - const result = await callEndpoint(mod as unknown as EndpointHandler, options); - - if (result.type === 'response') { - throw new Error(`Returning a Response from an endpoint is not supported in SSG mode.`); + throw new Error(`Cannot find the built path for ${specifier}`); } - body = result.body; - } else { - const result = await render(options); + const relPath = npath.posix.relative(pathname, '/' + hashedFilePath); + const fullyRelativePath = relPath[0] === '.' ? relPath : './' + relPath; + return fullyRelativePath; + }, + request: createRequest({ url, headers: new Headers(), logging }), + route: pageData.route, + routeCache, + site: astroConfig.buildOptions.site, + ssr: opts.astroConfig.buildOptions.experimentalSsr, + }; - // If there's a redirect or something, just do nothing. - if (result.type !== 'html') { - return; - } - body = result.html; + let body: string; + if (pageData.route.type === 'endpoint') { + const result = await callEndpoint(mod as unknown as EndpointHandler, options); + + if (result.type === 'response') { + throw new Error(`Returning a Response from an endpoint is not supported in SSG mode.`); } + body = result.body; + } else { + const result = await render(options); - const outFolder = getOutFolder(astroConfig, pathname, pageData.route.type); - const outFile = getOutFile(astroConfig, outFolder, pathname, pageData.route.type); - await fs.promises.mkdir(outFolder, { recursive: true }); - await fs.promises.writeFile(outFile, body, 'utf-8'); - } catch (err) { - error(opts.logging, 'build', `Error rendering:`, err); + // If there's a redirect or something, just do nothing. + if (result.type !== 'html') { + return; + } + body = result.html; } + + const outFolder = getOutFolder(astroConfig, pathname, pageData.route.type); + const outFile = getOutFile(astroConfig, outFolder, pathname, pageData.route.type); + await fs.promises.mkdir(outFolder, { recursive: true }); + await fs.promises.writeFile(outFile, body, 'utf-8'); } diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts index 5446e211d..1800c2636 100644 --- a/packages/astro/src/core/build/index.ts +++ b/packages/astro/src/core/build/index.ts @@ -16,6 +16,8 @@ import { staticBuild } from './static-build.js'; import { RouteCache } from '../render/route-cache.js'; import { runHookBuildDone, runHookBuildStart, runHookConfigDone, runHookConfigSetup } from '../../integrations/index.js'; import { getTimeStat } from './util.js'; +import { createSafeError } from '../util.js'; +import { fixViteErrorMessage } from '../errors.js'; export interface BuildOptions { mode?: string; @@ -26,7 +28,7 @@ export interface BuildOptions { export default async function build(config: AstroConfig, options: BuildOptions = { logging: defaultLogOptions }): Promise<void> { config = await runHookConfigSetup({ config, command: 'build' }); const builder = new AstroBuilder(config, options); - await builder.build(); + await builder.run(); } class AstroBuilder { @@ -36,32 +38,30 @@ class AstroBuilder { private origin: string; private routeCache: RouteCache; private manifest: ManifestData; - private viteServer?: vite.ViteDevServer; - private viteConfig?: ViteConfigWithSSR; + private timer: Record<string, number>; constructor(config: AstroConfig, options: BuildOptions) { - applyPolyfill(); - if (!config.buildOptions.site && config.buildOptions.sitemap !== false) { warn(options.logging, 'config', `Set "buildOptions.site" to generate correct canonical URLs and sitemap`); } - - if (options.mode) this.mode = options.mode; + if (options.mode) { + this.mode = options.mode; + } this.config = config; const port = config.devOptions.port; // no need to save this (don’t rely on port in builder) this.logging = options.logging; this.routeCache = new RouteCache(this.logging); this.origin = config.buildOptions.site ? new URL(config.buildOptions.site).origin : `http://localhost:${port}`; this.manifest = createRouteManifest({ config }, this.logging); + this.timer = {}; } - async build() { - info(this.logging, 'build', 'Initial setup...'); - - const { logging, origin } = this; - const timer: Record<string, number> = {}; - timer.init = performance.now(); - timer.viteStart = performance.now(); + /** Setup Vite and run any async setup logic that couldn't run inside of the constructor. */ + private async setup() { + debug('build', 'Initial setup...'); + const { logging } = this; + this.timer.init = performance.now(); + this.timer.viteStart = performance.now(); const viteConfig = await createVite( { mode: this.mode, @@ -74,10 +74,14 @@ class AstroBuilder { ); await runHookConfigDone({ config: this.config }); warnIfUsingExperimentalSSR(logging, this.config); - this.viteConfig = viteConfig; const viteServer = await vite.createServer(viteConfig); - this.viteServer = viteServer; - debug('build', timerMessage('Vite started', timer.viteStart)); + debug('build', timerMessage('Vite started', this.timer.viteStart)); + return { viteConfig, viteServer }; + } + + /** Run the build logic. build() is marked private because usage should go through ".run()" */ + private async build({ viteConfig, viteServer }: { viteConfig: ViteConfigWithSSR; viteServer: vite.ViteDevServer }) { + const { origin } = this; const buildConfig: BuildConfig = { client: new URL('./client/', this.config.dist), server: new URL('./server/', this.config.dist), @@ -86,15 +90,15 @@ class AstroBuilder { }; await runHookBuildStart({ config: this.config, buildConfig }); - info(this.logging, 'build', 'Collecting page data...'); - timer.loadStart = performance.now(); + info(this.logging, 'build', 'Collecting build information...'); + this.timer.loadStart = performance.now(); const { assets, allPages } = await collectPagesData({ astroConfig: this.config, logging: this.logging, manifest: this.manifest, origin, routeCache: this.routeCache, - viteServer: this.viteServer, + viteServer, ssr: this.config.buildOptions.experimentalSsr, }); @@ -104,21 +108,21 @@ class AstroBuilder { // TODO: add better type inference to data.preload[1] const frontmatter = (data.preload[1] as any).frontmatter; if (Boolean(frontmatter.draft) && !this.config.buildOptions.drafts) { - debug('build', timerMessage(`Skipping draft page ${page}`, timer.loadStart)); + debug('build', timerMessage(`Skipping draft page ${page}`, this.timer.loadStart)); delete allPages[page]; } } }); - debug('build', timerMessage('All pages loaded', timer.loadStart)); + debug('build', timerMessage('All pages loaded', this.timer.loadStart)); // The names of each pages const pageNames: string[] = []; // Bundle the assets in your final build: This currently takes the HTML output // of every page (stored in memory) and bundles the assets pointed to on those pages. - timer.buildStart = performance.now(); - info(this.logging, 'build', colors.dim(`Completed in ${getTimeStat(timer.init, performance.now())}`)); + this.timer.buildStart = performance.now(); + info(this.logging, 'build', colors.dim(`Completed in ${getTimeStat(this.timer.init, performance.now())}.`)); // Use the new faster static based build. if (!this.config.buildOptions.legacyBuild) { @@ -130,7 +134,7 @@ class AstroBuilder { origin: this.origin, pageNames, routeCache: this.routeCache, - viteConfig: this.viteConfig, + viteConfig, buildConfig, }); } else { @@ -141,13 +145,13 @@ class AstroBuilder { origin: this.origin, pageNames, routeCache: this.routeCache, - viteConfig: this.viteConfig, - viteServer: this.viteServer, + viteConfig, + viteServer, }); } // Write any additionally generated assets to disk. - timer.assetsStart = performance.now(); + this.timer.assetsStart = performance.now(); Object.keys(assets).map((k) => { if (!assets[k]) return; const filePath = new URL(`file://${k}`); @@ -155,11 +159,11 @@ class AstroBuilder { fs.writeFileSync(filePath, assets[k], 'utf8'); delete assets[k]; // free up memory }); - debug('build', timerMessage('Additional assets copied', timer.assetsStart)); + debug('build', timerMessage('Additional assets copied', this.timer.assetsStart)); // Build your final sitemap. if (this.config.buildOptions.sitemap && this.config.buildOptions.site) { - timer.sitemapStart = performance.now(); + this.timer.sitemapStart = performance.now(); const sitemapFilter = this.config.buildOptions.sitemapFilter ? (this.config.buildOptions.sitemapFilter as (page: string) => boolean) : undefined; const sitemap = generateSitemap( pageNames.map((pageName) => new URL(pageName, this.config.buildOptions.site).href), @@ -168,16 +172,27 @@ class AstroBuilder { const sitemapPath = new URL('./sitemap.xml', this.config.dist); await fs.promises.mkdir(new URL('./', sitemapPath), { recursive: true }); await fs.promises.writeFile(sitemapPath, sitemap, 'utf8'); - debug('build', timerMessage('Sitemap built', timer.sitemapStart)); + debug('build', timerMessage('Sitemap built', this.timer.sitemapStart)); } // You're done! Time to clean up. await viteServer.close(); await runHookBuildDone({ config: this.config, pages: pageNames, routes: Object.values(allPages).map((pd) => pd.route) }); - if (logging.level && levels[logging.level] <= levels['info']) { + if (this.logging.level && levels[this.logging.level] <= levels['info']) { const buildMode = this.config.buildOptions.experimentalSsr ? 'ssr' : 'static'; - await this.printStats({ logging, timeStart: timer.init, pageCount: pageNames.length, buildMode }); + await this.printStats({ logging: this.logging, timeStart: this.timer.init, pageCount: pageNames.length, buildMode }); + } + } + + /** Build the given Astro project. */ + async run() { + const setupData = await this.setup(); + try { + await this.build(setupData); + } catch (_err) { + debugger; + throw fixViteErrorMessage(createSafeError(_err), setupData.viteServer); } } @@ -188,14 +203,12 @@ class AstroBuilder { let messages: string[] = []; if (buildMode === 'static') { - const timePerPage = Math.round(buildTime / pageCount); - const perPageMsg = colors.dim(`(${colors.bold(`${timePerPage}ms`)} avg per page + resources)`); - messages = [`${pageCount} pages built in`, colors.bold(total), perPageMsg]; + messages = [`${pageCount} page(s) built in`, colors.bold(total)]; } else { messages = ['Server built in', colors.bold(total)]; } info(logging, 'build', messages.join(' ')); - info(logging, 'build', `🚀 ${colors.cyan(colors.bold('Done'))}`); + info(logging, 'build', `${colors.bold('Complete!')}`); } } diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts index f5e54b7bf..b166948f1 100644 --- a/packages/astro/src/core/build/static-build.ts +++ b/packages/astro/src/core/build/static-build.ts @@ -41,7 +41,6 @@ export async function staticBuild(opts: StaticBuildOptions) { const timer: Record<string, number> = {}; timer.buildStart = performance.now(); - info(opts.logging, 'build', 'Discovering entrypoints...'); for (const [component, pageData] of Object.entries(allPages)) { const astroModuleURL = new URL('./' + component, astroConfig.projectRoot); @@ -97,7 +96,7 @@ export async function staticBuild(opts: StaticBuildOptions) { timer.ssr = performance.now(); info(opts.logging, 'build', 'Building for SSR...'); const ssrResult = (await ssrBuild(opts, internals, pageInput)) as RollupOutput; - info(opts.logging, 'build', dim(`Completed in ${getTimeStat(timer.ssr, performance.now())}`)); + info(opts.logging, 'build', dim(`Completed in ${getTimeStat(timer.ssr, performance.now())}.`)); timer.generate = performance.now(); if (opts.buildConfig.staticMode) { @@ -107,7 +106,6 @@ export async function staticBuild(opts: StaticBuildOptions) { info(opts.logging, null, `\n${bgMagenta(black(' finalizing server assets '))}\n`); await ssrMoveAssets(opts); } - info(opts.logging, null, dim(`Completed in ${getTimeStat(timer.generate, performance.now())}\n`)); } async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, input: Set<string>) { @@ -171,7 +169,7 @@ async function clientBuild(opts: StaticBuildOptions, internals: BuildInternals, } // TODO: use vite.mergeConfig() here? - info(opts.logging, null, `\n${bgGreen(black(' building resources '))}\n`); + info(opts.logging, null, `\n${bgGreen(black(' building client '))}`); const out = isBuildingToSSR(astroConfig) ? opts.buildConfig.client : astroConfig.dist; @@ -210,7 +208,7 @@ async function clientBuild(opts: StaticBuildOptions, internals: BuildInternals, server: viteConfig.server, base: appendForwardSlash(astroConfig.buildOptions.site ? new URL(astroConfig.buildOptions.site).pathname : '/'), }); - info(opts.logging, null, dim(`Completed in ${getTimeStat(timer, performance.now())}\n`)); + info(opts.logging, null, dim(`Completed in ${getTimeStat(timer, performance.now())}.\n`)); return buildResult; } diff --git a/packages/astro/src/core/build/vite-plugin-ssr.ts b/packages/astro/src/core/build/vite-plugin-ssr.ts index efa54cc01..f057dc2ce 100644 --- a/packages/astro/src/core/build/vite-plugin-ssr.ts +++ b/packages/astro/src/core/build/vite-plugin-ssr.ts @@ -18,6 +18,7 @@ const manifestReplace = '@@ASTRO_MANIFEST_REPLACE@@'; export function vitePluginSSR(buildOpts: StaticBuildOptions, internals: BuildInternals, adapter: AstroAdapter): VitePlugin { return { name: '@astrojs/vite-plugin-astro-ssr', + enforce: 'post', options(opts) { return addRollupInput(opts, [virtualModuleId]); }, diff --git a/packages/astro/src/core/config.ts b/packages/astro/src/core/config.ts index 07f56f21e..8e4547d0a 100644 --- a/packages/astro/src/core/config.ts +++ b/packages/astro/src/core/config.ts @@ -327,11 +327,6 @@ export async function resolveConfig(userConfig: AstroUserConfig, root: string, f return validatedConfig; } -export function formatConfigError(err: z.ZodError) { - const errorList = err.issues.map((issue) => ` ! ${colors.bold(issue.path.join('.'))} ${colors.red(issue.message + '.')}`); - return `${colors.red('[config]')} Astro found issue(s) with your configuration:\n${errorList.join('\n')}`; -} - function mergeConfigRecursively(defaults: Record<string, any>, overrides: Record<string, any>, rootPath: string) { const merged: Record<string, any> = { ...defaults }; for (const key in overrides) { diff --git a/packages/astro/src/core/dev/index.ts b/packages/astro/src/core/dev/index.ts index 166009cda..cc1e7bde2 100644 --- a/packages/astro/src/core/dev/index.ts +++ b/packages/astro/src/core/dev/index.ts @@ -7,7 +7,7 @@ import { createVite } from '../create-vite.js'; import { defaultLogOptions, info, LogOptions, warn, warnIfUsingExperimentalSSR } from '../logger.js'; import * as msg from '../messages.js'; import { apply as applyPolyfill } from '../polyfill.js'; -import { getResolvedHostForVite } from './util.js'; +import { getResolvedHostForVite } from '../util.js'; export interface DevOptions { logging: LogOptions; diff --git a/packages/astro/src/core/dev/util.ts b/packages/astro/src/core/dev/util.ts deleted file mode 100644 index 9b0c974fd..000000000 --- a/packages/astro/src/core/dev/util.ts +++ /dev/null @@ -1,50 +0,0 @@ -import type { AstroConfig } from '../../@types/astro'; - -export const localIps = new Set(['localhost', '127.0.0.1']); - -/** Pad string () */ -export function pad(input: string, minLength: number, dir?: 'left' | 'right'): string { - let output = input; - while (output.length < minLength) { - output = dir === 'left' ? ' ' + output : output + ' '; - } - return output; -} - -export function emoji(char: string, fallback: string) { - return process.platform !== 'win32' ? char : fallback; -} - -// TODO: remove once --hostname is baselined -export function getResolvedHostForVite(config: AstroConfig) { - if (config.devOptions.host === false && config.devOptions.hostname !== 'localhost') { - return config.devOptions.hostname; - } else { - return config.devOptions.host; - } -} - -export function getLocalAddress(serverAddress: string, config: AstroConfig): string { - // TODO: remove once --hostname is baselined - const host = getResolvedHostForVite(config); - if (typeof host === 'boolean' || host === 'localhost') { - return 'localhost'; - } else { - return serverAddress; - } -} - -export type NetworkLogging = 'none' | 'host-to-expose' | 'visible'; - -export function getNetworkLogging(config: AstroConfig): NetworkLogging { - // TODO: remove once --hostname is baselined - const host = getResolvedHostForVite(config); - - if (host === false) { - return 'host-to-expose'; - } else if (typeof host === 'string' && localIps.has(host)) { - return 'none'; - } else { - return 'visible'; - } -} diff --git a/packages/astro/src/core/endpoint/dev/index.ts b/packages/astro/src/core/endpoint/dev/index.ts index 3190a500f..da3671bc0 100644 --- a/packages/astro/src/core/endpoint/dev/index.ts +++ b/packages/astro/src/core/endpoint/dev/index.ts @@ -1,21 +1,12 @@ import type { EndpointHandler } from '../../../@types/astro'; import type { SSROptions } from '../../render/dev'; - import { preload } from '../../render/dev/index.js'; -import { errorHandler } from '../../render/dev/error.js'; import { call as callEndpoint } from '../index.js'; -import { getParamsAndProps, GetParamsAndPropsError } from '../../render/core.js'; -import { createRequest } from '../../render/request.js'; export async function call(ssrOpts: SSROptions) { - try { - const [, mod] = await preload(ssrOpts); - return await callEndpoint(mod as unknown as EndpointHandler, { - ...ssrOpts, - ssr: ssrOpts.astroConfig.buildOptions.experimentalSsr, - }); - } catch (e: unknown) { - await errorHandler(e, { viteServer: ssrOpts.viteServer, filePath: ssrOpts.filePath }); - throw e; - } + const [, mod] = await preload(ssrOpts); + return await callEndpoint(mod as unknown as EndpointHandler, { + ...ssrOpts, + ssr: ssrOpts.astroConfig.buildOptions.experimentalSsr, + }); } diff --git a/packages/astro/src/core/endpoint/index.ts b/packages/astro/src/core/endpoint/index.ts index 745811354..8f59faad6 100644 --- a/packages/astro/src/core/endpoint/index.ts +++ b/packages/astro/src/core/endpoint/index.ts @@ -2,9 +2,8 @@ import type { EndpointHandler } from '../../@types/astro'; import type { RenderOptions } from '../render/core'; import { renderEndpoint } from '../../runtime/server/index.js'; import { getParamsAndProps, GetParamsAndPropsError } from '../render/core.js'; -import { createRequest } from '../render/request.js'; -export type EndpointOptions = Pick<RenderOptions, 'logging' | 'headers' | 'method' | 'origin' | 'route' | 'routeCache' | 'pathname' | 'route' | 'site' | 'ssr'>; +export type EndpointOptions = Pick<RenderOptions, 'logging' | 'origin' | 'request' | 'route' | 'routeCache' | 'pathname' | 'route' | 'site' | 'ssr'>; type EndpointCallResult = | { @@ -23,9 +22,8 @@ export async function call(mod: EndpointHandler, opts: EndpointOptions): Promise throw new Error(`[getStaticPath] route pattern matched, but no matching static path found. (${opts.pathname})`); } const [params] = paramsAndPropsResp; - const request = createRequest(opts.method, opts.pathname, opts.headers, opts.origin, opts.site, opts.ssr); - const response = await renderEndpoint(mod, request, params); + const response = await renderEndpoint(mod, opts.request, params); if (response instanceof Response) { return { diff --git a/packages/astro/src/core/errors.ts b/packages/astro/src/core/errors.ts new file mode 100644 index 000000000..0150978dc --- /dev/null +++ b/packages/astro/src/core/errors.ts @@ -0,0 +1,78 @@ +import type { BuildResult } from 'esbuild'; +import type { ViteDevServer } from 'vite'; +import type { SSRError } from '../@types/astro'; +import eol from 'eol'; +import fs from 'fs'; +import { codeFrame, createSafeError } from './util.js'; + +export interface ErrorWithMetadata { + [name: string]: any; + message: string; + stack: string; + id?: string; + frame?: string; + plugin?: string; + pluginCode?: string; + loc?: { + file?: string; + line: number; + column: number; + }; +} + +export function cleanErrorStack(stack: string) { + return stack + .split(/\n/g) + .filter((l) => /^\s*at/.test(l)) + .join('\n'); +} + +/** Update the error message to correct any vite-isms that we don't want to expose to the user. */ +export function fixViteErrorMessage(_err: unknown, server: ViteDevServer) { + const err = createSafeError(_err); + // Vite will give you better stacktraces, using sourcemaps. + server.ssrFixStacktrace(err); + // Fix: Astro.glob() compiles to import.meta.glob() by the time Vite sees it, + // so we need to update this error message in case it originally came from Astro.glob(). + if (err.message === 'import.meta.glob() can only accept string literals.') { + err.message = 'Astro.glob() and import.meta.glob() can only accept string literals.'; + } + return err; +} + +/** + * Takes any error-like object and returns a standardized Error + metadata object. + * Useful for consistent reporting regardless of where the error surfaced from. + */ +export function collectErrorMetadata(e: any): ErrorWithMetadata { + // normalize error stack line-endings to \n + if ((e as any).stack) { + (e as any).stack = eol.lf((e as any).stack); + } + + // Astro error (thrown by esbuild so it needs to be formatted for Vite) + if (Array.isArray((e as any).errors)) { + const { location, pluginName, text } = (e as BuildResult).errors[0]; + const err = e as SSRError; + if (location) { + err.loc = { file: location.file, line: location.line, column: location.column }; + err.id = err.id || location?.file; + } + const possibleFilePath = err.pluginCode || err.id || location?.file; + if (possibleFilePath && !err.frame) { + try { + const fileContents = fs.readFileSync(possibleFilePath, 'utf8'); + err.frame = codeFrame(fileContents, err.loc); + } catch { + // do nothing, code frame isn't that big a deal + } + } + if (pluginName) { + err.plugin = pluginName; + } + return err; + } + + // Generic error (probably from Vite, and already formatted) + return e; +} diff --git a/packages/astro/src/core/messages.ts b/packages/astro/src/core/messages.ts index e3a7741c4..888e6fcf4 100644 --- a/packages/astro/src/core/messages.ts +++ b/packages/astro/src/core/messages.ts @@ -2,12 +2,13 @@ * Dev server messages (organized here to prevent clutter) */ -import stripAnsi from 'strip-ansi'; import { bold, dim, red, green, underline, yellow, bgYellow, cyan, bgGreen, black, bgRed, bgWhite } from 'kleur/colors'; -import { pad, emoji, getLocalAddress, getNetworkLogging } from './dev/util.js'; import os from 'os'; import type { AddressInfo } from 'net'; import type { AstroConfig } from '../@types/astro'; +import { collectErrorMetadata, cleanErrorStack } from './errors.js'; +import { ZodError } from 'zod'; +import { emoji, getLocalAddress, getResolvedHostForVite, padMultilineString } from './util.js'; const PREFIX_PADDING = 6; @@ -18,15 +19,15 @@ export function req({ url, statusCode, reqTime }: { url: string; statusCode: num else if (statusCode >= 400) color = yellow; else if (statusCode >= 300) color = dim; else if (statusCode >= 200) color = green; - return `${bold(color(pad(`${statusCode}`, PREFIX_PADDING)))} ${pad(url, 40)} ${reqTime ? dim(Math.round(reqTime) + 'ms') : ''}`.trim(); + return `${bold(color(`${statusCode}`.padStart(PREFIX_PADDING)))} ${url.padStart(40)} ${reqTime ? dim(Math.round(reqTime) + 'ms') : ''}`.trim(); } export function reload({ file }: { file: string }): string { - return `${green(pad('reload', PREFIX_PADDING))} ${file}`; + return `${green('reload'.padStart(PREFIX_PADDING))} ${file}`; } export function hmr({ file }: { file: string }): string { - return `${green(pad('update', PREFIX_PADDING))} ${file}`; + return `${green('update'.padStart(PREFIX_PADDING))} ${file}`; } /** Display dev server host and startup time */ @@ -91,7 +92,7 @@ export function success(message: string, tip?: string) { const badge = bgGreen(black(` success `)); const headline = green(message); const footer = tip ? `\n ▶ ${tip}` : undefined; - return ['', badge, headline, footer] + return ['', `${badge} ${headline}`, footer] .filter((v) => v !== undefined) .map((msg) => ` ${msg}`) .join('\n'); @@ -101,7 +102,7 @@ export function failure(message: string, tip?: string) { const badge = bgRed(black(` error `)); const headline = red(message); const footer = tip ? `\n ▶ ${tip}` : undefined; - return ['', badge, headline, footer] + return ['', `${badge} ${headline}`, footer] .filter((v) => v !== undefined) .map((msg) => ` ${msg}`) .join('\n'); @@ -111,7 +112,7 @@ export function cancelled(message: string, tip?: string) { const badge = bgYellow(black(` cancelled `)); const headline = yellow(message); const footer = tip ? `\n ▶ ${tip}` : undefined; - return ['', badge, headline, footer] + return ['', `${badge} ${headline}`, footer] .filter((v) => v !== undefined) .map((msg) => ` ${msg}`) .join('\n'); @@ -122,15 +123,45 @@ export function portInUse({ port }: { port: number }): string { return `Port ${port} in use. Trying a new one…`; } -/** Pretty-print errors */ -export function err(error: Error): string { - if (!error.stack) return stripAnsi(error.message); - let message = stripAnsi(error.message); - let stack = stripAnsi(error.stack); - const split = stack.indexOf(message) + message.length; - message = stack.slice(0, split); - stack = stack.slice(split).replace(/^\n+/, ''); - return `${message}\n${dim(stack)}`; +const LOCAL_IP_HOSTS = new Set(['localhost', '127.0.0.1']); + +export function getNetworkLogging(config: AstroConfig): 'none' | 'host-to-expose' | 'visible' { + // TODO: remove once --hostname is baselined + const host = getResolvedHostForVite(config); + + if (host === false) { + return 'host-to-expose'; + } else if (typeof host === 'string' && LOCAL_IP_HOSTS.has(host)) { + return 'none'; + } else { + return 'visible'; + } +} + +export function formatConfigErrorMessage(err: ZodError) { + const errorList = err.issues.map((issue) => ` ! ${bold(issue.path.join('.'))} ${red(issue.message + '.')}`); + return `${red('[config]')} Astro found issue(s) with your configuration:\n${errorList.join('\n')}`; +} + +export function formatErrorMessage(_err: Error, args: string[] = []): string { + const err = collectErrorMetadata(_err); + args.push(`${bgRed(black(` error `))}${red(bold(padMultilineString(err.message)))}`); + if (err.id) { + args.push(` ${bold('File:')}`); + args.push(red(` ${err.id}`)); + } + if (err.frame) { + args.push(` ${bold('Code:')}`); + args.push(red(padMultilineString(err.frame, 4))); + } + if (args.length === 1 && err.stack) { + args.push(dim(cleanErrorStack(err.stack))); + } else if (err.stack) { + args.push(` ${bold('Stacktrace:')}`); + args.push(dim(cleanErrorStack(err.stack))); + args.push(``); + } + return args.join('\n'); } export function printHelp({ @@ -157,7 +188,7 @@ export function printHelp({ let raw = ''; for (const row of rows) { - raw += `${opts.prefix}${bold(pad(`${row[0]}`, opts.padding - opts.prefix.length))}`; + raw += `${opts.prefix}${bold(`${row[0]}`.padStart(opts.padding - opts.prefix.length))}`; if (split) raw += '\n '; raw += dim(row[1]) + '\n'; } diff --git a/packages/astro/src/core/render/core.ts b/packages/astro/src/core/render/core.ts index a1ea94f65..3cb109b76 100644 --- a/packages/astro/src/core/render/core.ts +++ b/packages/astro/src/core/render/core.ts @@ -1,6 +1,5 @@ import type { ComponentInstance, EndpointHandler, MarkdownRenderOptions, Params, Props, SSRLoadedRenderer, RouteData, SSRElement } from '../../@types/astro'; import type { LogOptions } from '../logger.js'; -import type { AstroRequest } from './request'; import { renderHead, renderPage } from '../../runtime/server/index.js'; import { getParams } from '../routing/index.js'; @@ -71,12 +70,11 @@ export interface RenderOptions { routeCache: RouteCache; site?: string; ssr: boolean; - method: string; - headers: Headers; + request: Request; } export async function render(opts: RenderOptions): Promise<{ type: 'html'; html: string } | { type: 'response'; response: Response }> { - const { headers, legacyBuild, links, logging, origin, markdownRender, method, mod, pathname, scripts, renderers, resolve, route, routeCache, site, ssr } = opts; + const { legacyBuild, links, logging, origin, markdownRender, mod, pathname, scripts, renderers, request, resolve, route, routeCache, site, ssr } = opts; const paramsAndPropsRes = await getParamsAndProps({ logging, @@ -107,11 +105,10 @@ export async function render(opts: RenderOptions): Promise<{ type: 'html'; html: pathname, resolve, renderers, + request, site, scripts, ssr, - method, - headers, }); let page = await renderPage(result, Component, pageProps, null); diff --git a/packages/astro/src/core/render/dev/css.ts b/packages/astro/src/core/render/dev/css.ts index 82141c5cb..baded71a9 100644 --- a/packages/astro/src/core/render/dev/css.ts +++ b/packages/astro/src/core/render/dev/css.ts @@ -29,10 +29,15 @@ export function getStylesForURL(filePath: URL, viteServer: vite.ViteDevServer): : // Otherwise, you are following an import in the module import tree. // You are safe to use getModuleById() here because Vite has already // resolved the correct `id` for you, by creating the import you followed here. - new Set([viteServer.moduleGraph.getModuleById(id)!]); + new Set([viteServer.moduleGraph.getModuleById(id)]); // Collect all imported modules for the module(s). for (const entry of moduleEntriesForId) { + // Handle this in case an module entries weren't found for ID + // This seems possible with some virtual IDs (ex: `astro:markdown/*.md`) + if (!entry) { + continue; + } if (id === entry.id) { scanned.add(id); for (const importedModule of entry.importedModules) { diff --git a/packages/astro/src/core/render/dev/error.ts b/packages/astro/src/core/render/dev/error.ts deleted file mode 100644 index 352211b1f..000000000 --- a/packages/astro/src/core/render/dev/error.ts +++ /dev/null @@ -1,44 +0,0 @@ -import type { BuildResult } from 'esbuild'; -import type * as vite from 'vite'; -import type { SSRError } from '../../../@types/astro'; - -import eol from 'eol'; -import fs from 'fs'; -import { codeFrame } from '../../util.js'; - -interface ErrorHandlerOptions { - filePath: URL; - viteServer: vite.ViteDevServer; -} - -export async function errorHandler(e: unknown, { viteServer, filePath }: ErrorHandlerOptions) { - // normalize error stack line-endings to \n - if ((e as any).stack) { - (e as any).stack = eol.lf((e as any).stack); - } - - // fix stack trace with Vite (this searches its module graph for matches) - if (e instanceof Error) { - viteServer.ssrFixStacktrace(e); - } - - // Astro error (thrown by esbuild so it needs to be formatted for Vite) - if (Array.isArray((e as any).errors)) { - const { location, pluginName, text } = (e as BuildResult).errors[0]; - const err = e as SSRError; - if (location) err.loc = { file: location.file, line: location.line, column: location.column }; - let src = err.pluginCode; - if (!src && err.id && fs.existsSync(err.id)) src = await fs.promises.readFile(err.id, 'utf8'); - if (!src) src = await fs.promises.readFile(filePath, 'utf8'); - err.frame = codeFrame(src, err.loc); - err.id = location?.file; - err.message = `${location?.file}: ${text} -${err.frame} -`; - if (pluginName) err.plugin = pluginName; - throw err; - } - - // Generic error (probably from Vite, and already formatted) - throw e; -} diff --git a/packages/astro/src/core/render/dev/index.ts b/packages/astro/src/core/render/dev/index.ts index d16cb8923..b96a431ae 100644 --- a/packages/astro/src/core/render/dev/index.ts +++ b/packages/astro/src/core/render/dev/index.ts @@ -7,7 +7,6 @@ import { prependForwardSlash } from '../../../core/path.js'; import { RouteCache } from '../route-cache.js'; import { createModuleScriptElementWithSrcSet } from '../ssr-element.js'; import { getStylesForURL } from './css.js'; -import { errorHandler } from './error.js'; import { getHmrScript } from './hmr.js'; import { injectTags } from './html.js'; export interface SSROptions { @@ -29,10 +28,8 @@ export interface SSROptions { routeCache: RouteCache; /** Vite instance */ viteServer: vite.ViteDevServer; - /** Method */ - method: string; - /** Headers */ - headers: Headers; + /** Request */ + request: Request; } export type ComponentPreload = [SSRLoadedRenderer[], ComponentInstance]; @@ -65,7 +62,7 @@ export async function preload({ astroConfig, filePath, viteServer }: Pick<SSROpt /** use Vite to SSR */ export async function render(renderers: SSRLoadedRenderer[], mod: ComponentInstance, ssrOpts: SSROptions): Promise<RenderResponse> { - const { astroConfig, filePath, logging, mode, origin, pathname, method, headers, route, routeCache, viteServer } = ssrOpts; + const { astroConfig, filePath, logging, mode, origin, pathname, request, route, routeCache, viteServer } = ssrOpts; const legacy = astroConfig.buildOptions.legacyBuild; // Add hoisted script tags @@ -145,12 +142,11 @@ export async function render(renderers: SSRLoadedRenderer[], mod: ComponentInsta } }, renderers, + request, route, routeCache, site: astroConfig.buildOptions.site, ssr: astroConfig.buildOptions.experimentalSsr, - method, - headers, }); if (route?.type === 'endpoint' || content.type === 'response') { @@ -216,11 +212,6 @@ export async function render(renderers: SSRLoadedRenderer[], mod: ComponentInsta } export async function ssr(preloadedComponent: ComponentPreload, ssrOpts: SSROptions): Promise<RenderResponse> { - try { - const [renderers, mod] = preloadedComponent; - return await render(renderers, mod, ssrOpts); // note(drew): without "await", errors won’t get caught by errorHandler() - } catch (e: unknown) { - await errorHandler(e, { viteServer: ssrOpts.viteServer, filePath: ssrOpts.filePath }); - throw e; - } + const [renderers, mod] = preloadedComponent; + return await render(renderers, mod, ssrOpts); // NOTE: without "await", errors won’t get caught below } diff --git a/packages/astro/src/core/render/request.ts b/packages/astro/src/core/render/request.ts deleted file mode 100644 index 5956c7867..000000000 --- a/packages/astro/src/core/render/request.ts +++ /dev/null @@ -1,50 +0,0 @@ -import type { Params } from '../../@types/astro'; -import { canonicalURL as utilCanonicalURL } from '../util.js'; - -type Site = string | undefined; - -export interface AstroRequest { - /** get the current page URL */ - url: URL; - - /** get the current canonical URL */ - canonicalURL: URL; - - /** get page params (dynamic pages only) */ - params: Params; - - headers: Headers; - - method: string; -} - -export type AstroRequestSSR = AstroRequest; - -export function createRequest(method: string, pathname: string, headers: Headers, origin: string, site: Site, ssr: boolean): AstroRequest { - const url = new URL('.' + pathname, new URL(origin)); - - const canonicalURL = utilCanonicalURL('.' + pathname, site ?? url.origin); - - const request: AstroRequest = { - url, - canonicalURL, - params: {}, - headers, - method, - }; - - if (!ssr) { - // Headers are only readable if using SSR-mode. If not, make it an empty headers - // object, so you can't do something bad. - request.headers = new Headers(); - - // Disallow using query params. - request.url = new URL(request.url); - - for (const [key] of request.url.searchParams) { - request.url.searchParams.delete(key); - } - } - - return request; -} diff --git a/packages/astro/src/core/render/result.ts b/packages/astro/src/core/render/result.ts index 8b14c99bd..6f03d4806 100644 --- a/packages/astro/src/core/render/result.ts +++ b/packages/astro/src/core/render/result.ts @@ -3,7 +3,7 @@ import type { AstroGlobal, AstroGlobalPartial, MarkdownParser, MarkdownRenderOpt import { renderSlot } from '../../runtime/server/index.js'; import { LogOptions, warn } from '../logger.js'; import { isCSSRequest } from './dev/css.js'; -import { createRequest } from './request.js'; +import { canonicalURL as utilCanonicalURL } from '../util.js'; import { isScriptRequest } from './script.js'; function onlyAvailableInSSR(name: string) { @@ -26,8 +26,7 @@ export interface CreateResultArgs { site: string | undefined; links?: Set<SSRElement>; scripts?: Set<SSRElement>; - headers: Headers; - method: string; + request: Request; } class Slots { @@ -72,10 +71,10 @@ class Slots { } export function createResult(args: CreateResultArgs): SSRResult { - const { legacyBuild, markdownRender, method, origin, headers, params, pathname, renderers, resolve, site } = args; + const { legacyBuild, markdownRender, origin, params, pathname, renderers, request, resolve, site } = args; - const request = createRequest(method, pathname, headers, origin, site, args.ssr); - request.params = params; + const url = new URL(request.url); + const canonicalURL = utilCanonicalURL('.' + pathname, site ?? url.origin); // Create the result object that will be passed into the render function. // This object starts here as an empty shell (not yet the result) but then @@ -90,6 +89,8 @@ export function createResult(args: CreateResultArgs): SSRResult { const Astro = { __proto__: astroGlobal, + canonicalURL, + params, props, request, redirect: args.ssr diff --git a/packages/astro/src/core/request.ts b/packages/astro/src/core/request.ts new file mode 100644 index 000000000..e94f1372b --- /dev/null +++ b/packages/astro/src/core/request.ts @@ -0,0 +1,41 @@ +import type { IncomingHttpHeaders } from 'http'; +import type { LogOptions } from './logger'; +import { warn } from './logger.js'; + +type HeaderType = Headers | Record<string, any> | IncomingHttpHeaders; +type RequestBody = ArrayBuffer | Blob | ReadableStream | URLSearchParams | FormData; + +export interface CreateRequestOptions { + url: URL | string; + headers: HeaderType; + method?: string; + body?: RequestBody | undefined; + logging: LogOptions; +} + +export function createRequest({ url, headers, method = 'GET', body = undefined, logging }: CreateRequestOptions): Request { + let headersObj = headers instanceof Headers ? headers : new Headers(Object.entries(headers as Record<string, any>)); + + const request = new Request(url.toString(), { + method: method, + headers: headersObj, + body, + }); + + Object.defineProperties(request, { + canonicalURL: { + get() { + warn(logging, 'deprecation', `Astro.request.canonicalURL has been moved to Astro.canonicalURL`); + return undefined; + }, + }, + params: { + get() { + warn(logging, 'deprecation', `Astro.request.params has been moved to Astro.params`); + return undefined; + }, + }, + }); + + return request; +} diff --git a/packages/astro/src/core/util.ts b/packages/astro/src/core/util.ts index 6787f177b..ca98419da 100644 --- a/packages/astro/src/core/util.ts +++ b/packages/astro/src/core/util.ts @@ -1,11 +1,12 @@ -import type { AstroConfig } from '../@types/astro'; -import type { ErrorPayload } from 'vite'; import eol from 'eol'; +import fs from 'fs'; import path from 'path'; +import resolve from 'resolve'; import slash from 'slash'; -import fs from 'fs'; import { fileURLToPath, pathToFileURL } from 'url'; -import resolve from 'resolve'; +import type { ErrorPayload } from 'vite'; +import type { AstroConfig } from '../@types/astro'; +import { removeEndingForwardSlash } from './path.js'; /** Normalize URL to its canonical form */ export function canonicalURL(url: string, base?: string): URL { @@ -35,6 +36,28 @@ export function arraify<T>(target: T | T[]): T[] { return Array.isArray(target) ? target : [target]; } +export function padMultilineString(source: string, n = 2) { + const lines = source.split(/\r?\n/); + return lines.map((l) => ` `.repeat(n) + l).join(`\n`); +} + +const STATUS_CODE_REGEXP = /^\/?[0-9]{3}$/; + +/** + * Get the correct output filename for a route, based on your config. + * Handles both "/foo" and "foo" `name` formats. + * Handles `/404` and `/` correctly. + */ +export function getOutputFilename(astroConfig: AstroConfig, name: string) { + if (name === '/' || name === '') { + return path.posix.join(name, 'index.html'); + } + if (astroConfig.buildOptions.pageUrlFormat === 'directory' && !STATUS_CODE_REGEXP.test(name)) { + return path.posix.join(name, 'index.html'); + } + return `${removeEndingForwardSlash(name || 'index')}.html`; +} + /** is a specifier an npm package? */ export function parseNpmName(spec: string): { scope?: string; name: string; subpath?: string } | undefined { // not an npm package @@ -137,6 +160,28 @@ export function isBuildingToSSR(config: AstroConfig): boolean { return !!config._ctx.adapter?.serverEntrypoint; } +export function emoji(char: string, fallback: string) { + return process.platform !== 'win32' ? char : fallback; +} + +// TODO: remove once --hostname is baselined +export function getResolvedHostForVite(config: AstroConfig) { + if (config.devOptions.host === false && config.devOptions.hostname !== 'localhost') { + return config.devOptions.hostname; + } else { + return config.devOptions.host; + } +} + +export function getLocalAddress(serverAddress: string, config: AstroConfig): string { + const host = getResolvedHostForVite(config); + if (typeof host === 'boolean' || host === 'localhost') { + return 'localhost'; + } else { + return serverAddress; + } +} + // Vendored from https://github.com/genmon/aboutfeeds/blob/main/tools/pretty-feed-v3.xsl /** Basic stylesheet for RSS feeds */ export const PRETTY_FEED_V3 = `<?xml version="1.0" encoding="utf-8"?> diff --git a/packages/astro/src/runtime/server/index.ts b/packages/astro/src/runtime/server/index.ts index d977219ac..7f314f721 100644 --- a/packages/astro/src/runtime/server/index.ts +++ b/packages/astro/src/runtime/server/index.ts @@ -1,6 +1,5 @@ import shorthash from 'shorthash'; import type { AstroComponentMetadata, AstroGlobalPartial, EndpointHandler, Params, SSRElement, SSRLoadedRenderer, SSRResult } from '../../@types/astro'; -import type { AstroRequest } from '../../core/render/request'; import { escapeHTML, HTMLString, markHTMLString } from './escape.js'; import { extractDirectives, generateHydrateScript, serializeProps } from './hydration.js'; import { serializeListValue } from './util.js'; @@ -277,34 +276,25 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr } /** Create the Astro.fetchContent() runtime function. */ -function createFetchContentFn(url: URL, site: URL) { - let sitePathname = site.pathname; - const fetchContent = (importMetaGlobResult: Record<string, any>) => { - let allEntries = [...Object.entries(importMetaGlobResult)]; +function createDeprecatedFetchContentFn() { + return () => { + throw new Error('Deprecated: Astro.fetchContent() has been replaced with Astro.glob().'); + }; +} + +/** Create the Astro.glob() runtime function. */ +function createAstroGlobFn() { + const globHandler = (importMetaGlobResult: Record<string, any>, globValue: () => any) => { + let allEntries = [...Object.values(importMetaGlobResult)]; if (allEntries.length === 0) { - throw new Error(`[${url.pathname}] Astro.fetchContent() no matches found.`); + throw new Error(`Astro.glob(${JSON.stringify(globValue())}) - no matches found.`); } - return allEntries - .map(([spec, mod]) => { - // Only return Markdown files for now. - if (!mod.frontmatter) { - return; - } - const urlSpec = new URL(spec, url).pathname; - return { - ...mod.frontmatter, - Content: mod.default, - content: mod.metadata, - file: new URL(spec, url), - url: urlSpec.includes('/pages/') ? urlSpec.replace(/^.*\/pages\//, sitePathname).replace(/(\/index)?\.md$/, '') : undefined, - }; - }) - .filter(Boolean); + // Map over the `import()` promises, calling to load them. + return Promise.all(allEntries.map((fn) => fn())); }; - // This has to be cast because the type of fetchContent is the type of the function - // that receives the import.meta.glob result, but the user is using it as - // another type. - return fetchContent as unknown as AstroGlobalPartial['fetchContent']; + // Cast the return type because the argument that the user sees (string) is different from the argument + // that the runtime sees post-compiler (Record<string, Module>). + return globHandler as unknown as AstroGlobalPartial['glob']; } // This is used to create the top-level Astro global; the one that you can use @@ -313,10 +303,10 @@ export function createAstro(filePathname: string, _site: string, projectRootStr: const site = new URL(_site); const url = new URL(filePathname, site); const projectRoot = new URL(projectRootStr); - const fetchContent = createFetchContentFn(url, site); return { site, - fetchContent, + fetchContent: createDeprecatedFetchContentFn(), + glob: createAstroGlobFn(), // INVESTIGATE is there a use-case for multi args? resolve(...segments: string[]) { let resolved = segments.reduce((u, segment) => new URL(segment, u), url).pathname; @@ -397,7 +387,7 @@ export function defineScriptVars(vars: Record<any, any>) { } // Renders an endpoint request to completion, returning the body. -export async function renderEndpoint(mod: EndpointHandler, request: AstroRequest, params: Params) { +export async function renderEndpoint(mod: EndpointHandler, request: Request, params: Params) { const chosenMethod = request.method?.toLowerCase() ?? 'get'; const handler = mod[chosenMethod]; diff --git a/packages/astro/src/vite-plugin-astro-postprocess/index.ts b/packages/astro/src/vite-plugin-astro-postprocess/index.ts index fc40f9891..58bd7566d 100644 --- a/packages/astro/src/vite-plugin-astro-postprocess/index.ts +++ b/packages/astro/src/vite-plugin-astro-postprocess/index.ts @@ -1,10 +1,12 @@ -import type * as t from '@babel/types'; +import { parse as babelParser } from '@babel/parser'; +import type { ArrowFunctionExpressionKind, CallExpressionKind, StringLiteralKind } from 'ast-types/gen/kinds'; +import type { NodePath } from 'ast-types/lib/node-path'; +import { parse, print, types, visit } from 'recast'; import type { Plugin } from 'vite'; import type { AstroConfig } from '../@types/astro'; -import * as babelTraverse from '@babel/traverse'; -import * as babel from '@babel/core'; - +// Check for `Astro.glob()`. Be very forgiving of whitespace. False positives are okay. +const ASTRO_GLOB_REGEX = /Astro2?\s*\.\s*glob\s*\(/; interface AstroPluginOptions { config: AstroConfig; } @@ -21,55 +23,58 @@ export default function astro({ config }: AstroPluginOptions): Plugin { return null; } - // Optimization: only run on a probably match - // Open this up if need for post-pass extends past fetchContent - if (!code.includes('fetchContent')) { + // Optimization: Detect usage with a quick string match. + // Only perform the transform if this function is found + if (!ASTRO_GLOB_REGEX.test(code)) { return null; } - // Handle the second-pass JS AST Traversal - const result = await babel.transformAsync(code, { - sourceType: 'module', - sourceMaps: true, - plugins: [ - () => { - return { - visitor: { - StringLiteral(path: babelTraverse.NodePath<t.StringLiteral>) { - if ( - path.parent.type !== 'CallExpression' || - path.parent.callee.type !== 'MemberExpression' || - !validAstroGlobalNames.has((path.parent.callee.object as any).name) || - (path.parent.callee.property as any).name !== 'fetchContent' - ) { - return; - } - const { value } = path.node; - if (/[a-z]\:\/\//.test(value)) { - return; - } - path.replaceWith({ - type: 'CallExpression', - callee: { - type: 'MemberExpression', - object: { type: 'MetaProperty', meta: { type: 'Identifier', name: 'import' }, property: { type: 'Identifier', name: 'meta' } }, - property: { type: 'Identifier', name: 'globEager' }, - computed: false, - }, - arguments: [path.node], - } as any); - }, - }, - }; - }, - ], + const ast = parse(code, { + // We need to use the babel parser because `import.meta.hot` is not + // supported by esprima (default parser). In the future, we should + // experiment with other parsers if Babel is too slow or heavy. + parser: { parse: babelParser }, }); - // Undocumented baby behavior, but possible according to Babel types. - if (!result || !result.code) { - return null; - } + visit(ast, { + visitCallExpression: function (path) { + // Filter out anything that isn't `Astro.glob()` or `Astro2.glob()` + if ( + !types.namedTypes.MemberExpression.check(path.node.callee) || + !types.namedTypes.Identifier.check(path.node.callee.property) || + !(path.node.callee.property.name === 'glob') || + !types.namedTypes.Identifier.check(path.node.callee.object) || + !(path.node.callee.object.name === 'Astro' || path.node.callee.object.name === 'Astro2') + ) { + this.traverse(path); + return; + } + + // Wrap the `Astro.glob()` argument with `import.meta.glob`. + const argsPath = path.get('arguments', 0) as NodePath; + const args = argsPath.value; + argsPath.replace( + { + type: 'CallExpression', + callee: { + type: 'MemberExpression', + object: { type: 'MetaProperty', meta: { type: 'Identifier', name: 'import' }, property: { type: 'Identifier', name: 'meta' } }, + property: { type: 'Identifier', name: 'glob' }, + computed: false, + }, + arguments: [args], + } as CallExpressionKind, + { + type: 'ArrowFunctionExpression', + body: args, + params: [], + } as ArrowFunctionExpressionKind + ); + return false; + }, + }); + const result = print(ast); return { code: result.code, map: result.map }; }, }; diff --git a/packages/astro/src/vite-plugin-astro-server/index.ts b/packages/astro/src/vite-plugin-astro-server/index.ts index bc45596da..4a5b1a5fc 100644 --- a/packages/astro/src/vite-plugin-astro-server/index.ts +++ b/packages/astro/src/vite-plugin-astro-server/index.ts @@ -2,7 +2,7 @@ import type * as vite from 'vite'; import type http from 'http'; import type { AstroConfig, ManifestData } from '../@types/astro'; import type { RenderResponse, SSROptions } from '../core/render/dev/index'; -import { info, warn, error, LogOptions } from '../core/logger.js'; +import { debug, info, warn, error, LogOptions } from '../core/logger.js'; import { getParamsAndProps, GetParamsAndPropsError } from '../core/render/core.js'; import { createRouteManifest, matchRoute } from '../core/routing/index.js'; import stripAnsi from 'strip-ansi'; @@ -10,11 +10,11 @@ import { createSafeError } from '../core/util.js'; import { ssr, preload } from '../core/render/dev/index.js'; import { call as callEndpoint } from '../core/endpoint/dev/index.js'; import * as msg from '../core/messages.js'; - import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js'; import serverErrorTemplate from '../template/5xx.js'; import { RouteCache } from '../core/render/route-cache.js'; -import { AstroRequest } from '../core/render/request.js'; +import { fixViteErrorMessage } from '../core/errors.js'; +import { createRequest } from '../core/request.js'; interface AstroPluginOptions { config: AstroConfig; @@ -117,9 +117,36 @@ async function handleRequest( const site = config.buildOptions.site ? new URL(config.buildOptions.site) : undefined; const devRoot = site ? site.pathname : '/'; const origin = `${viteServer.config.server.https ? 'https' : 'http'}://${req.headers.host}`; + const buildingToSSR = !!config._ctx.adapter?.serverEntrypoint; const url = new URL(origin + req.url); const pathname = decodeURI(url.pathname); const rootRelativeUrl = pathname.substring(devRoot.length - 1); + if (!buildingToSSR) { + // Prevent user from depending on search params when not doing SSR. + for (const [key] of url.searchParams) { + url.searchParams.delete(key); + } + } + + let body: ArrayBuffer | undefined = undefined; + if (!(req.method === 'GET' || req.method === 'HEAD')) { + let bytes: string[] = []; + await new Promise((resolve) => { + req.setEncoding('utf-8'); + req.on('data', (bts) => bytes.push(bts)); + req.on('close', resolve); + }); + body = new TextEncoder().encode(bytes.join('')).buffer; + } + + // Headers are only available when using SSR. + const request = createRequest({ + url, + headers: buildingToSSR ? req.headers : new Headers(), + method: req.method, + body, + logging, + }); try { if (!pathname.startsWith(devRoot)) { @@ -166,10 +193,9 @@ async function handleRequest( filePath: filePathCustom404, logging, mode: 'development', - method: 'GET', - headers: new Headers(Object.entries(req.headers as Record<string, any>)), origin, pathname: rootRelativeUrl, + request, route: routeCustom404, routeCache, viteServer, @@ -190,8 +216,7 @@ async function handleRequest( route, routeCache, viteServer, - method: req.method || 'GET', - headers: new Headers(Object.entries(req.headers as Record<string, any>)), + request, }; // Route successfully matched! Render it. @@ -207,11 +232,10 @@ async function handleRequest( const result = await ssr(preloadedComponent, options); return await writeSSRResult(result, res, statusCode); } - } catch (_err: any) { + } catch (_err) { debugger; - info(logging, 'serve', msg.req({ url: pathname, statusCode: 500 })); - const err = createSafeError(_err); - error(logging, 'error', msg.err(err)); + const err = fixViteErrorMessage(createSafeError(_err), viteServer); + error(logging, null, msg.formatErrorMessage(err)); handle500Response(viteServer, origin, req, res, err); } } diff --git a/packages/astro/src/vite-plugin-build-html/index.ts b/packages/astro/src/vite-plugin-build-html/index.ts index 1dc6e3392..ad5b8ba14 100644 --- a/packages/astro/src/vite-plugin-build-html/index.ts +++ b/packages/astro/src/vite-plugin-build-html/index.ts @@ -1,21 +1,23 @@ -import type { AstroConfig } from '../@types/astro'; -import type { LogOptions } from '../core/logger.js'; -import type { ViteDevServer, Plugin as VitePlugin } from 'vite'; -import type { OutputChunk, PreRenderedChunk, PluginContext } from 'rollup'; -import type { AllPagesData } from '../core/build/types'; -import type { BuildInternals } from '../core/build/internal'; +import { createElement, createScript, getAttribute, hasAttribute, insertBefore, remove, setAttribute } from '@web/parse5-utils'; +import { promises as fs } from 'fs'; import parse5 from 'parse5'; -import srcsetParse from 'srcset-parse'; import * as npath from 'path'; -import { promises as fs } from 'fs'; -import { getAttribute, hasAttribute, insertBefore, remove, createScript, createElement, setAttribute } from '@web/parse5-utils'; -import { addRollupInput } from './add-rollup-input.js'; -import { findAssets, findExternalScripts, findInlineScripts, findInlineStyles, getTextContent, getAttributes } from './extract-assets.js'; -import { isBuildableImage, isBuildableLink, isHoistedScript, isInSrcDirectory, hasSrcSet } from './util.js'; +import type { OutputChunk, PluginContext, PreRenderedChunk } from 'rollup'; +import srcsetParse from 'srcset-parse'; +import type { Plugin as VitePlugin, ViteDevServer } from 'vite'; +import type { AstroConfig } from '../@types/astro'; +import type { BuildInternals } from '../core/build/internal'; +import type { AllPagesData } from '../core/build/types'; +import type { LogOptions } from '../core/logger.js'; +import { prependDotSlash } from '../core/path.js'; import { render as ssrRender } from '../core/render/dev/index.js'; -import { getAstroStyleId, getAstroPageStyleId } from '../vite-plugin-build-css/index.js'; -import { prependDotSlash, removeEndingForwardSlash } from '../core/path.js'; import { RouteCache } from '../core/render/route-cache.js'; +import { getOutputFilename } from '../core/util.js'; +import { getAstroPageStyleId, getAstroStyleId } from '../vite-plugin-build-css/index.js'; +import { addRollupInput } from './add-rollup-input.js'; +import { findAssets, findExternalScripts, findInlineScripts, findInlineStyles, getAttributes, getTextContent } from './extract-assets.js'; +import { hasSrcSet, isBuildableImage, isBuildableLink, isHoistedScript, isInSrcDirectory } from './util.js'; +import { createRequest } from '../core/request.js'; // This package isn't real ESM, so have to coerce it const matchSrcset: typeof srcsetParse = (srcsetParse as any).default; @@ -25,7 +27,6 @@ const ASTRO_PAGE_PREFIX = '@astro-page'; const ASTRO_SCRIPT_PREFIX = '@astro-script'; const ASTRO_EMPTY = '@astro-empty'; -const STATUS_CODE_REGEXP = /^[0-9]{3}$/; interface PluginOptions { astroConfig: AstroConfig; @@ -87,8 +88,11 @@ export function rollupPluginAstroScanHTML(options: PluginOptions): VitePlugin { astroConfig, filePath: new URL(`./${component}`, astroConfig.projectRoot), logging, - headers: new Headers(), - method: 'GET', + request: createRequest({ + url: new URL(origin + pathname), + headers: new Headers(), + logging, + }), mode: 'production', origin, pathname, @@ -487,14 +491,7 @@ export function rollupPluginAstroScanHTML(options: PluginOptions): VitePlugin { const outHTML = parse5.serialize(document); const name = pathname.substr(1); - let outPath: string; - - // Output directly to 404.html rather than 404/index.html - if (astroConfig.buildOptions.pageUrlFormat === 'file' || STATUS_CODE_REGEXP.test(name)) { - outPath = `${removeEndingForwardSlash(name || 'index')}.html`; - } else { - outPath = npath.posix.join(name, 'index.html'); - } + const outPath = getOutputFilename(astroConfig, name); this.emitFile({ fileName: outPath, diff --git a/packages/astro/src/vite-plugin-markdown/index.ts b/packages/astro/src/vite-plugin-markdown/index.ts index c3c75b93d..a250da2af 100644 --- a/packages/astro/src/vite-plugin-markdown/index.ts +++ b/packages/astro/src/vite-plugin-markdown/index.ts @@ -2,14 +2,20 @@ import { transform } from '@astrojs/compiler'; import ancestor from 'common-ancestor-path'; import esbuild from 'esbuild'; import fs from 'fs'; +import matter from 'gray-matter'; +import { fileURLToPath } from 'url'; import type { Plugin } from 'vite'; import type { AstroConfig } from '../@types/astro'; import { PAGE_SSR_SCRIPT_ID } from '../vite-plugin-scripts/index.js'; +import { virtualModuleId as pagesVirtualModuleId } from '../core/build/vite-plugin-pages.js'; interface AstroPluginOptions { config: AstroConfig; } +const VIRTUAL_MODULE_ID_PREFIX = 'astro:markdown'; +const VIRTUAL_MODULE_ID = '\0' + VIRTUAL_MODULE_ID_PREFIX; + // TODO: Clean up some of the shared logic between this Markdown plugin and the Astro plugin. // Both end up connecting a `load()` hook to the Astro compiler, and share some copy-paste // logic in how that is done. @@ -23,14 +29,88 @@ export default function markdown({ config }: AstroPluginOptions): Plugin { return filename; } + // Weird Vite behavior: Vite seems to use a fake "index.html" importer when you + // have `enforce: pre`. This can probably be removed once the vite issue is fixed. + // see: https://github.com/vitejs/vite/issues/5981 + const fakeRootImporter = fileURLToPath(new URL('index.html', config.projectRoot)); + function isRootImport(importer: string | undefined) { + if (!importer) { + return true; + } + if (importer === fakeRootImporter) { + return true; + } + if (importer === '\0' + pagesVirtualModuleId) { + return true; + } + return false; + } + return { name: 'astro:markdown', - enforce: 'pre', // run transforms before other plugins can + enforce: 'pre', + async resolveId(id, importer, options) { + // Resolve virtual modules as-is. + if (id.startsWith(VIRTUAL_MODULE_ID)) { + return id; + } + // Resolve any .md files with the `?content` cache buster. This should only come from + // an already-resolved JS module wrapper. Needed to prevent infinite loops in Vite. + // Unclear if this is expected or if cache busting is just working around a Vite bug. + if (id.endsWith('.md?content')) { + const resolvedId = await this.resolve(id, importer, { skipSelf: true, ...options }); + return resolvedId?.id.replace('?content', ''); + } + // If the markdown file is imported from another file via ESM, resolve a JS representation + // that defers the markdown -> HTML rendering until it is needed. This is especially useful + // when fetching and then filtering many markdown files, like with import.meta.glob() or Astro.glob(). + // Otherwise, resolve directly to the actual component. + if (id.endsWith('.md') && !isRootImport(importer)) { + const resolvedId = await this.resolve(id, importer, { skipSelf: true, ...options }); + if (resolvedId) { + return VIRTUAL_MODULE_ID + resolvedId.id; + } + } + // In all other cases, we do nothing and rely on normal Vite resolution. + return undefined; + }, async load(id) { + // A markdown file has been imported via ESM! + // Return the file's JS representation, including all Markdown + // frontmatter and a deferred `import() of the compiled markdown content. + if (id.startsWith(VIRTUAL_MODULE_ID)) { + const sitePathname = config.buildOptions.site ? new URL(config.buildOptions.site).pathname : '/'; + const fileId = id.substring(VIRTUAL_MODULE_ID.length); + const fileUrl = fileId.includes('/pages/') ? fileId.replace(/^.*\/pages\//, sitePathname).replace(/(\/index)?\.md$/, '') : undefined; + const source = await fs.promises.readFile(fileId, 'utf8'); + const { data: frontmatter } = matter(source); + return { + code: ` + // Static + export const frontmatter = ${JSON.stringify(frontmatter)}; + export const file = ${JSON.stringify(fileId)}; + export const url = ${JSON.stringify(fileUrl)}; + + // Deferred + export default async function load() { + return (await import(${JSON.stringify(fileId + '?content')})); + }; + export function Content(...args) { + return load().then((m) => m.default(...args)) + } + Content.isAstroComponentFactory = true; + export function getHeaders() { + return load().then((m) => m.metadata.headers) + };`, + map: null, + }; + } + + // A markdown file is being rendered! This markdown file was either imported + // directly as a page in Vite, or it was a deferred render from a JS module. + // This returns the compiled markdown -> astro component that renders to HTML. if (id.endsWith('.md')) { const source = await fs.promises.readFile(id, 'utf8'); - - // Transform from `.md` to valid `.astro` let render = config.markdownOptions.render; let renderOpts = {}; if (Array.isArray(render)) { @@ -40,8 +120,6 @@ export default function markdown({ config }: AstroPluginOptions): Plugin { if (typeof render === 'string') { ({ default: render } = await import(render)); } - let renderResult = await render(source, renderOpts); - let { frontmatter, metadata, code: astroResult } = renderResult; const filename = normalizeFilename(id); const fileUrl = new URL(`file://${filename}`); @@ -49,6 +127,9 @@ export default function markdown({ config }: AstroPluginOptions): Plugin { const hasInjectedScript = isPage && config._ctx.scripts.some((s) => s.stage === 'page-ssr'); // Extract special frontmatter keys + const { data: frontmatter, content: markdownContent } = matter(source); + let renderResult = await render(markdownContent, renderOpts); + let { code: astroResult, metadata } = renderResult; const { layout = '', components = '', setup = '', ...content } = frontmatter; content.astro = metadata; const prelude = `--- @@ -83,8 +164,7 @@ export const frontmatter = ${JSON.stringify(content)}; ${tsResult}`; // Compile from `.ts` to `.js` - const { code, map } = await esbuild.transform(tsResult, { loader: 'ts', sourcemap: 'inline', sourcefile: id }); - + const { code } = await esbuild.transform(tsResult, { loader: 'ts', sourcemap: false, sourcefile: id }); return { code, map: null, diff --git a/packages/astro/test/astro-global.test.js b/packages/astro/test/astro-global.test.js index d46c994ec..8330be821 100644 --- a/packages/astro/test/astro-global.test.js +++ b/packages/astro/test/astro-global.test.js @@ -25,7 +25,7 @@ describe('Astro.*', () => { expect($('#nested-child-pathname').text()).to.equal('/'); }); - it('Astro.request.canonicalURL', async () => { + it('Astro.canonicalURL', async () => { // given a URL, expect the following canonical URL const canonicalURLs = { '/index.html': 'https://mysite.dev/blog/', @@ -48,7 +48,7 @@ describe('Astro.*', () => { expect($('#site').attr('href')).to.equal('https://mysite.dev/blog/'); }); - it('Astro.fetchContent() returns the correct "url" property, including buildOptions.site subpath', async () => { + it('Astro.glob() correctly returns an array of all posts', async () => { const html = await fixture.readFile('/posts/1/index.html'); const $ = cheerio.load(html); expect($('.post-url').attr('href')).to.equal('/blog/post/post-2'); diff --git a/packages/astro/test/cli.test.js b/packages/astro/test/cli.test.js index d84ca56e4..c23fca34f 100644 --- a/packages/astro/test/cli.test.js +++ b/packages/astro/test/cli.test.js @@ -28,7 +28,7 @@ describe('astro cli', () => { it('astro build', async () => { const projectRootURL = new URL('./fixtures/astro-basic/', import.meta.url); const proc = await cli('build', '--project-root', fileURLToPath(projectRootURL)); - expect(proc.stdout).to.include('Done'); + expect(proc.stdout).to.include('Complete'); }); it('astro dev welcome', async () => { diff --git a/packages/astro/test/config-validate.test.js b/packages/astro/test/config-validate.test.js index b1079b6f4..c543a013c 100644 --- a/packages/astro/test/config-validate.test.js +++ b/packages/astro/test/config-validate.test.js @@ -1,7 +1,8 @@ import { expect } from 'chai'; import { z } from 'zod'; import stripAnsi from 'strip-ansi'; -import { formatConfigError, validateConfig } from '../dist/core/config.js'; +import { formatConfigErrorMessage } from '../dist/core/messages.js'; +import { validateConfig } from '../dist/core/config.js'; describe('Config Validation', () => { it('empty user config is valid', async () => { @@ -22,7 +23,7 @@ describe('Config Validation', () => { it('A validation error can be formatted correctly', async () => { const configError = await validateConfig({ buildOptions: { sitemap: 42 } }, process.cwd()).catch((err) => err); expect(configError instanceof z.ZodError).to.equal(true); - const formattedError = stripAnsi(formatConfigError(configError)); + const formattedError = stripAnsi(formatConfigErrorMessage(configError)); expect(formattedError).to.equal( `[config] Astro found issue(s) with your configuration: ! buildOptions.sitemap Expected boolean, received number.` @@ -37,7 +38,7 @@ describe('Config Validation', () => { }; const configError = await validateConfig(veryBadConfig, process.cwd()).catch((err) => err); expect(configError instanceof z.ZodError).to.equal(true); - const formattedError = stripAnsi(formatConfigError(configError)); + const formattedError = stripAnsi(formatConfigErrorMessage(configError)); expect(formattedError).to.equal( `[config] Astro found issue(s) with your configuration: ! pages Expected string, received object. diff --git a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/[...calledTwiceTest].astro b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/[...calledTwiceTest].astro index 19800e1ae..08b6af30c 100644 --- a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/[...calledTwiceTest].astro +++ b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/[...calledTwiceTest].astro @@ -10,7 +10,7 @@ export function getStaticPaths({ paginate }) { {params: {calledTwiceTest: 'c'}}, ]; } -const { params } = Astro.request; +const { params } = Astro; --- <html> diff --git a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/blog/[year]/[slug].astro b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/blog/[year]/[slug].astro index b5c8ec282..12e686366 100644 --- a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/blog/[year]/[slug].astro +++ b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/blog/[year]/[slug].astro @@ -6,7 +6,7 @@ export async function getStaticPaths() { ] } -const { year, slug } = Astro.request.params +const { year, slug } = Astro.params --- <html> @@ -14,4 +14,4 @@ const { year, slug } = Astro.request.params <title>{year} | {slug}</title> </head> <body></body> -</html>
\ No newline at end of file +</html> diff --git a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/pizza/[...pizza].astro b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/pizza/[...pizza].astro index 02ef8ef47..a58b314e3 100644 --- a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/pizza/[...pizza].astro +++ b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/pizza/[...pizza].astro @@ -8,7 +8,7 @@ export function getStaticPaths() { params: { pizza: 'grimaldis/new-york' }, }] } -const { pizza } = Astro.request.params +const { pizza } = Astro.params --- <html lang="en"> <head> @@ -19,4 +19,4 @@ const { pizza } = Astro.request.params <body> <h1>Welcome to {pizza ?? 'The landing page'}</h1> </body> -</html>
\ No newline at end of file +</html> diff --git a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/pizza/[cheese]-[topping].astro b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/pizza/[cheese]-[topping].astro index 353805c5c..a698a76d7 100644 --- a/packages/astro/test/fixtures/astro-get-static-paths/src/pages/pizza/[cheese]-[topping].astro +++ b/packages/astro/test/fixtures/astro-get-static-paths/src/pages/pizza/[cheese]-[topping].astro @@ -6,7 +6,7 @@ export function getStaticPaths() { params: { cheese: 'provolone', topping: 'sausage' }, }] } -const { cheese, topping } = Astro.request.params +const { cheese, topping } = Astro.params --- <html lang="en"> <head> @@ -18,4 +18,4 @@ const { cheese, topping } = Astro.request.params <h1>🍕 It's pizza time</h1> <p>{cheese}-{topping}</p> </body> -</html>
\ No newline at end of file +</html> diff --git a/packages/astro/test/fixtures/astro-global/src/components/Child.astro b/packages/astro/test/fixtures/astro-global/src/components/Child.astro index 28c84dab2..911e5464b 100644 --- a/packages/astro/test/fixtures/astro-global/src/components/Child.astro +++ b/packages/astro/test/fixtures/astro-global/src/components/Child.astro @@ -1,5 +1,5 @@ --- import NestedChild from './NestedChild.astro'; --- -<div id="child-pathname">{Astro.request.url.pathname}</div> -<NestedChild />
\ No newline at end of file +<div id="child-pathname">{new URL(Astro.request.url).pathname}</div> +<NestedChild /> diff --git a/packages/astro/test/fixtures/astro-global/src/components/NestedChild.astro b/packages/astro/test/fixtures/astro-global/src/components/NestedChild.astro index 9beea4278..809a0d68d 100644 --- a/packages/astro/test/fixtures/astro-global/src/components/NestedChild.astro +++ b/packages/astro/test/fixtures/astro-global/src/components/NestedChild.astro @@ -1 +1 @@ -<div id="nested-child-pathname">{Astro.request.url.pathname}</div>
\ No newline at end of file +<div id="nested-child-pathname">{new URL(Astro.request.url).pathname}</div> diff --git a/packages/astro/test/fixtures/astro-global/src/layouts/post.astro b/packages/astro/test/fixtures/astro-global/src/layouts/post.astro index 87e5cc448..ba9377278 100644 --- a/packages/astro/test/fixtures/astro-global/src/layouts/post.astro +++ b/packages/astro/test/fixtures/astro-global/src/layouts/post.astro @@ -4,7 +4,7 @@ const { content } = Astro.props; <html> <head> <title>{content.title}</title> - <link rel="canonical" href={Astro.request.canonicalURL.href}> + <link rel="canonical" href={Astro.canonicalURL.href}> </head> <body> <slot></slot> diff --git a/packages/astro/test/fixtures/astro-global/src/pages/index.astro b/packages/astro/test/fixtures/astro-global/src/pages/index.astro index 4906384c4..437495995 100644 --- a/packages/astro/test/fixtures/astro-global/src/pages/index.astro +++ b/packages/astro/test/fixtures/astro-global/src/pages/index.astro @@ -4,10 +4,10 @@ import Child from '../components/Child.astro'; <html> <head> <title>Test</title> - <link rel="canonical" href={Astro.request.canonicalURL.href}> + <link rel="canonical" href={Astro.canonicalURL.href}> </head> <body> - <div id="pathname">{Astro.request.url.pathname}</div> + <div id="pathname">{new URL(Astro.request.url).pathname}</div> <a id="site" href={Astro.site}>Home</a> <Child /> diff --git a/packages/astro/test/fixtures/astro-global/src/pages/posts/[page].astro b/packages/astro/test/fixtures/astro-global/src/pages/posts/[page].astro index e684161e6..1a21cf475 100644 --- a/packages/astro/test/fixtures/astro-global/src/pages/posts/[page].astro +++ b/packages/astro/test/fixtures/astro-global/src/pages/posts/[page].astro @@ -1,10 +1,10 @@ --- -export function getStaticPaths({paginate}) { - const data = Astro.fetchContent('../post/*.md'); +export async function getStaticPaths({paginate}) { + const data = await Astro.glob('../post/*.md'); return paginate(data, {pageSize: 1}); } const { page } = Astro.props; -const { params, canonicalURL} = Astro.request; +const { params, canonicalURL} = Astro; --- <html> @@ -15,7 +15,7 @@ const { params, canonicalURL} = Astro.request; <body> {page.data.map((data) => ( <div> - <h1>{data.title}</h1> + <h1>{data.frontmatter.title}</h1> <a class="post-url" href={data.url}>Read</a> </div> ))} diff --git a/packages/astro/test/fixtures/astro-pagination/src/pages/index.astro b/packages/astro/test/fixtures/astro-pagination/src/pages/index.astro index db72daff5..afd2203de 100644 --- a/packages/astro/test/fixtures/astro-pagination/src/pages/index.astro +++ b/packages/astro/test/fixtures/astro-pagination/src/pages/index.astro @@ -3,10 +3,10 @@ <html> <head> <title>Test</title> - <link rel="canonical" href={Astro.request.canonicalURL.href}> + <link rel="canonical" href={Astro.canonicalURL.href}> </head> <body> - <div id="pathname">{Astro.request.url.pathname}</div> + <div id="pathname">{new URL(Astro.request.url).pathname}</div> <a id="site" href={Astro.site}>Home</a> </body> </html> diff --git a/packages/astro/test/fixtures/astro-pagination/src/pages/posts/[slug]/[page].astro b/packages/astro/test/fixtures/astro-pagination/src/pages/posts/[slug]/[page].astro index b3dc4be87..ba51548a1 100644 --- a/packages/astro/test/fixtures/astro-pagination/src/pages/posts/[slug]/[page].astro +++ b/packages/astro/test/fixtures/astro-pagination/src/pages/posts/[slug]/[page].astro @@ -1,8 +1,8 @@ --- -export function getStaticPaths({paginate}) { - const allPosts = Astro.fetchContent('../../post/*.md'); +export async function getStaticPaths({paginate}) { + const allPosts = await Astro.glob('../../post/*.md'); return ['red', 'blue'].map((filter) => { - const filteredPosts = allPosts.filter((post) => post.tag === filter); + const filteredPosts = allPosts.filter((post) => post.frontmatter.tag === filter); return paginate(filteredPosts, { params: { slug: filter }, props: { filter }, @@ -11,7 +11,7 @@ export function getStaticPaths({paginate}) { }); } const { page, filter } = Astro.props; -const { params, canonicalURL} = Astro.request; +const { params, canonicalURL} = Astro; --- <html> diff --git a/packages/astro/test/fixtures/astro-pagination/src/pages/posts/named-root-page/[page].astro b/packages/astro/test/fixtures/astro-pagination/src/pages/posts/named-root-page/[page].astro index d70f0673c..a3efb9b45 100644 --- a/packages/astro/test/fixtures/astro-pagination/src/pages/posts/named-root-page/[page].astro +++ b/packages/astro/test/fixtures/astro-pagination/src/pages/posts/named-root-page/[page].astro @@ -1,10 +1,10 @@ --- export async function getStaticPaths({paginate}) { - const data = Astro.fetchContent('../../post/*.md'); + const data = await Astro.glob('../../post/*.md'); return paginate(data, {pageSize: 1}); } const { page } = Astro.props; -const { params, canonicalURL} = Astro.request; +const { params, canonicalURL} = Astro; --- <html> diff --git a/packages/astro/test/fixtures/astro-pagination/src/pages/posts/optional-root-page/[...page].astro b/packages/astro/test/fixtures/astro-pagination/src/pages/posts/optional-root-page/[...page].astro index d70f0673c..a3efb9b45 100644 --- a/packages/astro/test/fixtures/astro-pagination/src/pages/posts/optional-root-page/[...page].astro +++ b/packages/astro/test/fixtures/astro-pagination/src/pages/posts/optional-root-page/[...page].astro @@ -1,10 +1,10 @@ --- export async function getStaticPaths({paginate}) { - const data = Astro.fetchContent('../../post/*.md'); + const data = await Astro.glob('../../post/*.md'); return paginate(data, {pageSize: 1}); } const { page } = Astro.props; -const { params, canonicalURL} = Astro.request; +const { params, canonicalURL} = Astro; --- <html> diff --git a/packages/astro/test/fixtures/astro-sitemap-rss/src/pages/episodes/[...page].astro b/packages/astro/test/fixtures/astro-sitemap-rss/src/pages/episodes/[...page].astro index 0c0c676ee..3732c4ba3 100644 --- a/packages/astro/test/fixtures/astro-sitemap-rss/src/pages/episodes/[...page].astro +++ b/packages/astro/test/fixtures/astro-sitemap-rss/src/pages/episodes/[...page].astro @@ -1,6 +1,6 @@ --- -export function getStaticPaths({paginate, rss}) { - const episodes = Astro.fetchContent('../episode/*.md').sort((a, b) => new Date(b.pubDate) - new Date(a.pubDate)); +export async function getStaticPaths({paginate, rss}) { + const episodes = (await Astro.glob('../episode/*.md')).sort((a, b) => new Date(b.frontmatter.pubDate) - new Date(a.frontmatter.pubDate)); rss({ title: 'MF Doomcast', description: 'The podcast about the things you find on a picnic, or at a picnic table', @@ -11,13 +11,13 @@ export function getStaticPaths({paginate, rss}) { customData: `<language>en-us</language>` + `<itunes:author>MF Doom</itunes:author>`, items: episodes.map((episode) => ({ - title: episode.title, + title: episode.frontmatter.title, link: episode.url, - description: episode.description, - pubDate: episode.pubDate + 'Z', - customData: `<itunes:episodeType>${episode.type}</itunes:episodeType>` + - `<itunes:duration>${episode.duration}</itunes:duration>` + - `<itunes:explicit>${episode.explicit || false}</itunes:explicit>`, + description: episode.frontmatter.description, + pubDate: episode.frontmatter.pubDate + 'Z', + customData: `<itunes:episodeType>${episode.frontmatter.type}</itunes:episodeType>` + + `<itunes:duration>${episode.frontmatter.duration}</itunes:duration>` + + `<itunes:explicit>${episode.frontmatter.explicit || false}</itunes:explicit>`, })), dest: '/custom/feed.xml', }); @@ -31,13 +31,13 @@ export function getStaticPaths({paginate, rss}) { customData: `<language>en-us</language>` + `<itunes:author>MF Doom</itunes:author>`, items: episodes.map((episode) => ({ - title: episode.title, + title: episode.frontmatter.title, link: `https://example.com${episode.url}/`, - description: episode.description, - pubDate: episode.pubDate + 'Z', - customData: `<itunes:episodeType>${episode.type}</itunes:episodeType>` + - `<itunes:duration>${episode.duration}</itunes:duration>` + - `<itunes:explicit>${episode.explicit || false}</itunes:explicit>`, + description: episode.frontmatter.description, + pubDate: episode.frontmatter.pubDate + 'Z', + customData: `<itunes:episodeType>${episode.frontmatter.type}</itunes:episodeType>` + + `<itunes:duration>${episode.frontmatter.duration}</itunes:duration>` + + `<itunes:explicit>${episode.frontmatter.explicit || false}</itunes:explicit>`, })), dest: '/custom/feed-pregenerated-urls.xml', }); @@ -53,6 +53,6 @@ const { page } = Astro.props; <link rel="alternate" type="application/rss+2.0" href="/rss.xml" /> </head> <body> - {page.data.map((ep) => (<li>{ep.title}</li>))} + {page.data.map((ep) => (<li>{ep.frontmatter.title}</li>))} </body> </html> diff --git a/packages/astro/test/fixtures/debug-component/src/pages/posts/[slug].astro b/packages/astro/test/fixtures/debug-component/src/pages/posts/[slug].astro index 8b6ae00e9..ed85be913 100644 --- a/packages/astro/test/fixtures/debug-component/src/pages/posts/[slug].astro +++ b/packages/astro/test/fixtures/debug-component/src/pages/posts/[slug].astro @@ -3,15 +3,13 @@ import Debug from 'astro/debug'; // all the content that should be generated export async function getStaticPaths() { - const data = Astro.fetchContent('../../data/posts/*.md') + const data = await Astro.glob('../../data/posts/*.md') - const allArticles = data.map(({ astro, file, url, ...article }) => { + const allArticles = data.map((article) => { return { - params: { slug: article.slug }, + params: { slug: article.frontmatter.slug }, props: { article: article, - content: astro.html, - md: astro.source, } } }) diff --git a/packages/astro/test/fixtures/ssr-dynamic/src/pages/[id].astro b/packages/astro/test/fixtures/ssr-dynamic/src/pages/[id].astro index b976757e2..8ba5cc82e 100644 --- a/packages/astro/test/fixtures/ssr-dynamic/src/pages/[id].astro +++ b/packages/astro/test/fixtures/ssr-dynamic/src/pages/[id].astro @@ -1,9 +1,10 @@ --- -const val = Number(Astro.request.params.id); +const val = Number(Astro.params.id); --- <html> <head> <title>Test app</title> + <style>body { font-size: 11px; }</style> </head> <body> <h1>Item { val }</h1> diff --git a/packages/astro/test/fixtures/static build/src/pages/index.astro b/packages/astro/test/fixtures/static build/src/pages/index.astro index b1bd2067e..763046d0a 100644 --- a/packages/astro/test/fixtures/static build/src/pages/index.astro +++ b/packages/astro/test/fixtures/static build/src/pages/index.astro @@ -2,7 +2,7 @@ import MainHead from '../components/MainHead.astro'; import Nav from '../components/Nav/index.jsx'; import { test as ssrConfigTest } from '@test/static-build-pkg'; -let allPosts = await Astro.fetchContent('./posts/*.md'); +let allPosts = await Astro.glob('./posts/*.md'); --- <html> <head> diff --git a/packages/astro/test/ssr-dynamic.test.js b/packages/astro/test/ssr-dynamic.test.js index 843243425..d938e5c95 100644 --- a/packages/astro/test/ssr-dynamic.test.js +++ b/packages/astro/test/ssr-dynamic.test.js @@ -19,12 +19,23 @@ describe('Dynamic pages in SSR', () => { await fixture.build(); }); - it('Do not have to implement getStaticPaths', async () => { + async function fetchHTML(path) { const app = await fixture.loadTestAdapterApp(); - const request = new Request('http://example.com/123'); + const request = new Request('http://example.com' + path); const response = await app.render(request); const html = await response.text(); + return html; + } + + it('Do not have to implement getStaticPaths', async () => { + const html = await fetchHTML('/123'); const $ = cheerioLoad(html); expect($('h1').text()).to.equal('Item 123'); }); + + it('Includes page styles', async () => { + const html = await fetchHTML('/123'); + const $ = cheerioLoad(html); + expect($('link').length).to.equal(1); + }); }); diff --git a/packages/astro/test/static-build.test.js b/packages/astro/test/static-build.test.js index 89860505e..47707ea27 100644 --- a/packages/astro/test/static-build.test.js +++ b/packages/astro/test/static-build.test.js @@ -21,7 +21,7 @@ describe('Static build', () => { expect(html).to.be.a('string'); }); - it('can build pages using fetchContent', async () => { + it('can build pages using Astro.glob()', async () => { const html = await fixture.readFile('/index.html'); const $ = cheerioLoad(html); const link = $('.posts a'); diff --git a/packages/integrations/svelte/package.json b/packages/integrations/svelte/package.json index f38db4f32..abe58baac 100644 --- a/packages/integrations/svelte/package.json +++ b/packages/integrations/svelte/package.json @@ -32,7 +32,7 @@ }, "dependencies": { "@sveltejs/vite-plugin-svelte": "^1.0.0-next.40", - "postcss-load-config": "^3.1.3", + "postcss-load-config": "^3.1.4", "svelte-preprocess": "^4.10.4" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 075679e07..997848edc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,14 +5,14 @@ importers: .: specifiers: '@astrojs/webapi': workspace:* - '@changesets/changelog-github': ^0.4.3 - '@changesets/cli': ^2.21.1 + '@changesets/changelog-github': ^0.4.4 + '@changesets/cli': ^2.22.0 '@octokit/action': ^3.18.0 - '@typescript-eslint/eslint-plugin': ^5.16.0 - '@typescript-eslint/parser': ^5.16.0 + '@typescript-eslint/eslint-plugin': ^5.17.0 + '@typescript-eslint/parser': ^5.17.0 del: ^6.0.0 esbuild: 0.14.25 - eslint: ^8.11.0 + eslint: ^8.12.0 eslint-config-prettier: ^8.5.0 eslint-plugin-prettier: ^4.0.0 execa: ^6.1.0 @@ -24,16 +24,16 @@ importers: dependencies: '@astrojs/webapi': link:packages/webapi devDependencies: - '@changesets/changelog-github': 0.4.3 - '@changesets/cli': 2.21.1 + '@changesets/changelog-github': 0.4.4 + '@changesets/cli': 2.22.0 '@octokit/action': 3.18.0 - '@typescript-eslint/eslint-plugin': 5.16.0_bc68a9cd5bf604202498b1a9faaf9387 - '@typescript-eslint/parser': 5.16.0_eslint@8.11.0+typescript@4.6.3 + '@typescript-eslint/eslint-plugin': 5.17.0_689ff565753ecf7c3328c07fad067df5 + '@typescript-eslint/parser': 5.17.0_eslint@8.12.0+typescript@4.6.3 del: 6.0.0 esbuild: 0.14.25 - eslint: 8.11.0 - eslint-config-prettier: 8.5.0_eslint@8.11.0 - eslint-plugin-prettier: 4.0.0_e2923b5169e23c4db59b86a638c599a3 + eslint: 8.12.0 + eslint-config-prettier: 8.5.0_eslint@8.12.0 + eslint-plugin-prettier: 4.0.0_b253a92c95b42c3296c682f11cccb3bd execa: 6.1.0 prettier: 2.6.1 pretty-bytes: 6.0.0 @@ -44,7 +44,7 @@ importers: examples/blog: specifiers: '@astrojs/preact': ^0.0.2 - astro: ^0.25.3 + astro: ^0.25.4 preact: ^10.6.6 dependencies: preact: 10.6.6 @@ -55,7 +55,7 @@ importers: examples/blog-multiple-authors: specifiers: '@astrojs/preact': ^0.0.2 - astro: ^0.25.3 + astro: ^0.25.4 preact: ^10.6.6 sass: ^1.49.9 dependencies: @@ -67,14 +67,14 @@ importers: examples/component: specifiers: - astro: ^0.25.3 + astro: ^0.25.4 devDependencies: astro: link:../../packages/astro examples/component/demo: specifiers: '@example/my-component': workspace:* - astro: ^0.25.3 + astro: ^0.25.4 devDependencies: '@example/my-component': link:../packages/my-component astro: link:../../../packages/astro @@ -90,7 +90,7 @@ importers: '@docsearch/css': ^3.0.0 '@docsearch/react': ^3.0.0 '@types/react': ^17.0.43 - astro: ^0.25.3 + astro: ^0.25.4 preact: ^10.6.6 react: ^17.0.2 react-dom: ^17.0.2 @@ -109,13 +109,13 @@ importers: examples/env-vars: specifiers: - astro: ^0.25.3 + astro: ^0.25.4 devDependencies: astro: link:../../packages/astro examples/framework-alpine: specifiers: - astro: ^0.25.3 + astro: ^0.25.4 devDependencies: astro: link:../../packages/astro @@ -123,7 +123,7 @@ importers: specifiers: '@astrojs/lit': ^0.0.2 '@webcomponents/template-shadowroot': ^0.1.0 - astro: ^0.25.3 + astro: ^0.25.4 lit: ^2.2.1 dependencies: '@webcomponents/template-shadowroot': 0.1.0 @@ -141,7 +141,7 @@ importers: '@astrojs/svelte': ^0.0.2 '@astrojs/vue': ^0.0.2 '@webcomponents/template-shadowroot': ^0.1.0 - astro: ^0.25.3 + astro: ^0.25.4 lit: ^2.2.1 preact: ^10.6.6 react: ^17.0.2 @@ -170,7 +170,7 @@ importers: examples/framework-preact: specifiers: '@astrojs/preact': ^0.0.2 - astro: ^0.25.3 + astro: ^0.25.4 preact: ^10.6.6 dependencies: preact: 10.6.6 @@ -181,7 +181,7 @@ importers: examples/framework-react: specifiers: '@astrojs/react': ^0.0.2 - astro: ^0.25.3 + astro: ^0.25.4 react: ^17.0.2 react-dom: ^17.0.2 dependencies: @@ -194,7 +194,7 @@ importers: examples/framework-solid: specifiers: '@astrojs/solid-js': ^0.0.3 - astro: ^0.25.3 + astro: ^0.25.4 solid-js: ^1.3.13 dependencies: solid-js: 1.3.13 @@ -205,7 +205,7 @@ importers: examples/framework-svelte: specifiers: '@astrojs/svelte': ^0.0.2 - astro: ^0.25.3 + astro: ^0.25.4 svelte: ^3.46.4 dependencies: svelte: 3.46.4 @@ -216,7 +216,7 @@ importers: examples/framework-vue: specifiers: '@astrojs/vue': ^0.0.2 - astro: ^0.25.3 + astro: ^0.25.4 vue: ^3.2.31 dependencies: vue: 3.2.31 @@ -233,7 +233,7 @@ importers: '@astrojs/tailwind': ^0.0.2 '@astrojs/turbolinks': ^0.0.2 '@webcomponents/template-shadowroot': ^0.1.0 - astro: ^0.25.3 + astro: ^0.25.4 lit: ^2.2.1 preact: ^10.6.6 react: ^17.0.2 @@ -261,20 +261,20 @@ importers: examples/minimal: specifiers: - astro: ^0.25.3 + astro: ^0.25.4 devDependencies: astro: link:../../packages/astro examples/non-html-pages: specifiers: - astro: ^0.25.3 + astro: ^0.25.4 devDependencies: astro: link:../../packages/astro examples/portfolio: specifiers: '@astrojs/preact': ^0.0.2 - astro: ^0.25.3 + astro: ^0.25.4 preact: ^10.6.6 sass: ^1.49.9 dependencies: @@ -288,7 +288,7 @@ importers: specifiers: '@astrojs/node': ^0.0.2 '@astrojs/svelte': ^0.0.2 - astro: ^0.25.3 + astro: ^0.25.4 concurrently: ^7.0.0 lightcookie: ^1.0.25 svelte: ^3.46.4 @@ -307,14 +307,14 @@ importers: examples/starter: specifiers: - astro: ^0.25.3 + astro: ^0.25.4 devDependencies: astro: link:../../packages/astro examples/subpath: specifiers: '@astrojs/react': ^0.0.2 - astro: ^0.25.3 + astro: ^0.25.4 react: ^17.0.2 react-dom: ^17.0.2 sass: ^1.49.9 @@ -333,7 +333,7 @@ importers: '@astrojs/react': ^0.0.2 '@astrojs/svelte': ^0.0.2 '@astrojs/vue': ^0.0.2 - astro: ^0.25.3 + astro: ^0.25.4 preact: ^10.6.6 react: ^17.0.2 react-dom: ^17.0.2 @@ -356,7 +356,7 @@ importers: examples/with-markdown-plugins: specifiers: '@astrojs/markdown-remark': ^0.7.0 - astro: ^0.25.3 + astro: ^0.25.4 hast-util-select: 5.0.1 rehype-autolink-headings: ^6.1.1 rehype-slug: ^5.0.1 @@ -374,7 +374,7 @@ importers: examples/with-markdown-shiki: specifiers: '@astrojs/markdown-remark': ^0.7.0 - astro: ^0.25.3 + astro: ^0.25.4 devDependencies: '@astrojs/markdown-remark': link:../../packages/markdown/remark astro: link:../../packages/astro @@ -389,7 +389,7 @@ importers: '@nanostores/preact': ^0.1.3 '@nanostores/react': ^0.1.5 '@nanostores/vue': ^0.4.1 - astro: ^0.25.3 + astro: ^0.25.4 nanostores: ^0.5.12 preact: ^10.6.6 react: ^17.0.2 @@ -417,7 +417,7 @@ importers: examples/with-tailwindcss: specifiers: '@astrojs/tailwind': ^0.0.2 - astro: ^0.25.3 + astro: ^0.25.4 autoprefixer: ^10.4.4 canvas-confetti: ^1.5.1 postcss: ^8.4.12 @@ -432,7 +432,7 @@ importers: examples/with-vite-plugin-pwa: specifiers: - astro: ^0.25.3 + astro: ^0.25.4 vite-plugin-pwa: 0.11.11 workbox-window: ^6.5.2 devDependencies: @@ -474,6 +474,7 @@ importers: '@types/send': ^0.17.1 '@types/yargs-parser': ^21.0.0 '@web/parse5-utils': ^1.3.0 + ast-types: ^0.14.2 astro-scripts: workspace:* boxen: ^6.2.1 chai: ^4.3.6 @@ -489,7 +490,7 @@ importers: execa: ^6.1.0 fast-glob: ^3.2.11 fast-xml-parser: ^4.0.7 - html-entities: ^2.3.2 + html-entities: ^2.3.3 html-escaper: ^3.0.3 htmlparser2: ^7.2.0 kleur: ^4.1.4 @@ -502,10 +503,11 @@ importers: parse5: ^6.0.1 path-to-regexp: ^6.2.0 postcss: ^8.4.12 - postcss-load-config: ^3.1.3 + postcss-load-config: ^3.1.4 preferred-pm: ^3.0.3 prismjs: ^1.27.0 prompts: ^2.4.2 + recast: ^0.20.5 rehype-slug: ^5.0.1 resolve: ^1.22.0 rollup: ^2.70.1 @@ -525,7 +527,7 @@ importers: type-fest: ^2.12.1 vite: ^2.8.6 yargs-parser: ^21.0.1 - zod: ^3.14.2 + zod: ^3.14.3 dependencies: '@astrojs/compiler': 0.13.1 '@astrojs/language-server': 0.13.2 @@ -539,6 +541,7 @@ importers: '@proload/core': 0.2.2 '@proload/plugin-tsm': 0.1.1_@proload+core@0.2.2 '@web/parse5-utils': 1.3.0 + ast-types: 0.14.2 boxen: 6.2.1 ci-info: 3.3.0 common-ancestor-path: 1.0.1 @@ -551,7 +554,7 @@ importers: execa: 6.1.0 fast-glob: 3.2.11 fast-xml-parser: 4.0.7 - html-entities: 2.3.2 + html-entities: 2.3.3 html-escaper: 3.0.3 htmlparser2: 7.2.0 kleur: 4.1.4 @@ -563,10 +566,11 @@ importers: parse5: 6.0.1 path-to-regexp: 6.2.0 postcss: 8.4.12 - postcss-load-config: 3.1.3 + postcss-load-config: 3.1.4_postcss@8.4.12 preferred-pm: 3.0.3 prismjs: 1.27.0 prompts: 2.4.2 + recast: 0.20.5 rehype-slug: 5.0.1 resolve: 1.22.0 rollup: 2.70.1 @@ -584,7 +588,7 @@ importers: tsconfig-resolver: 3.0.1 vite: 2.8.6_sass@1.49.9 yargs-parser: 21.0.1 - zod: 3.14.2 + zod: 3.14.3 devDependencies: '@babel/types': 7.17.0 '@types/babel__core': 7.1.19 @@ -1299,13 +1303,13 @@ importers: '@sveltejs/vite-plugin-svelte': ^1.0.0-next.40 astro: workspace:* astro-scripts: workspace:* - postcss-load-config: ^3.1.3 + postcss-load-config: ^3.1.4 svelte: ^3.46.4 svelte-preprocess: ^4.10.4 dependencies: '@sveltejs/vite-plugin-svelte': 1.0.0-next.40_svelte@3.46.4 - postcss-load-config: 3.1.3 - svelte-preprocess: 4.10.4_6ccb891c442782d29dbf23417a615415 + postcss-load-config: 3.1.4 + svelte-preprocess: 4.10.4_ec4868a778d68da3f0d21a10f4ea83cd devDependencies: astro: link:../../astro astro-scripts: link:../../../scripts @@ -3083,14 +3087,14 @@ packages: hasBin: true dev: false - /@changesets/apply-release-plan/5.0.5: - resolution: {integrity: sha512-CxL9dkhzjHiVmXCyHgsLCQj7i/coFTMv/Yy0v6BC5cIWZkQml+lf7zvQqAcFXwY7b54HxRWZPku02XFB53Q0Uw==} + /@changesets/apply-release-plan/6.0.0: + resolution: {integrity: sha512-gp6nIdVdfYdwKww2+f8whckKmvfE4JEm4jJgBhTmooi0uzHWhnxvk6JIzQi89qEAMINN0SeVNnXiAtbFY0Mj3w==} dependencies: '@babel/runtime': 7.17.8 - '@changesets/config': 1.7.0 + '@changesets/config': 2.0.0 '@changesets/get-version-range-type': 0.3.2 - '@changesets/git': 1.3.1 - '@changesets/types': 4.1.0 + '@changesets/git': 1.3.2 + '@changesets/types': 5.0.0 '@manypkg/get-packages': 1.1.3 detect-indent: 6.1.0 fs-extra: 7.0.1 @@ -3101,51 +3105,51 @@ packages: semver: 5.7.1 dev: true - /@changesets/assemble-release-plan/5.1.1: - resolution: {integrity: sha512-TQRZnK1sqYuoibJdSwpqE81rfDh0Xrkkr/M6bCQZ1ogGoRJNVbNYDWvNfkNvR4rEdRylri8cfKzffo/ruoy8QA==} + /@changesets/assemble-release-plan/5.1.2: + resolution: {integrity: sha512-nOFyDw4APSkY/vh5WNwGEtThPgEjVShp03PKVdId6wZTJALVcAALCSLmDRfeqjE2z9EsGJb7hZdDlziKlnqZgw==} dependencies: '@babel/runtime': 7.17.8 '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.1 - '@changesets/types': 4.1.0 + '@changesets/get-dependents-graph': 1.3.2 + '@changesets/types': 5.0.0 '@manypkg/get-packages': 1.1.3 semver: 5.7.1 dev: true - /@changesets/changelog-git/0.1.10: - resolution: {integrity: sha512-4t7zqPOv3aDZp4Y+AyDhiOG2ypaUXDpOz+MT1wOk3uSZNv78AaDByam0hdk5kfYuH1RlMecWU4/U5lO1ZL5eaA==} + /@changesets/changelog-git/0.1.11: + resolution: {integrity: sha512-sWJvAm+raRPeES9usNpZRkooeEB93lOpUN0Lmjz5vhVAb7XGIZrHEJ93155bpE1S0c4oJ5Di9ZWgzIwqhWP/Wg==} dependencies: - '@changesets/types': 4.1.0 + '@changesets/types': 5.0.0 dev: true - /@changesets/changelog-github/0.4.3: - resolution: {integrity: sha512-93X4arork7DV4+tVYeNlOTrw7HOXIvvd41yRPY9atJ+nS32W0uS+ewkZdc6WThuqmwGx9xaU+pxHtVLeYJTF0A==} + /@changesets/changelog-github/0.4.4: + resolution: {integrity: sha512-htSILqCkyYtTB5/LoVKwx7GCJQGxAiBcYbfUKWiz/QoDARuM01owYtMXhV6/iytJZq/Dqqz3PjMZUNB4MphpbQ==} dependencies: '@changesets/get-github-info': 0.5.0 - '@changesets/types': 4.1.0 + '@changesets/types': 5.0.0 dotenv: 8.6.0 transitivePeerDependencies: - encoding dev: true - /@changesets/cli/2.21.1: - resolution: {integrity: sha512-4AJKo/UW0P217m2VHjiuhZy+CstLw54eu9I1fsY7tst76GeEN7mX0mVrTNEisR6CvOH7wLav3ITqvDcKVPbKsw==} + /@changesets/cli/2.22.0: + resolution: {integrity: sha512-4bA3YoBkd5cm5WUxmrR2N9WYE7EeQcM+R3bVYMUj2NvffkQVpU3ckAI+z8UICoojq+HRl2OEwtz+S5UBmYY4zw==} hasBin: true dependencies: '@babel/runtime': 7.17.8 - '@changesets/apply-release-plan': 5.0.5 - '@changesets/assemble-release-plan': 5.1.1 - '@changesets/changelog-git': 0.1.10 - '@changesets/config': 1.7.0 + '@changesets/apply-release-plan': 6.0.0 + '@changesets/assemble-release-plan': 5.1.2 + '@changesets/changelog-git': 0.1.11 + '@changesets/config': 2.0.0 '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.1 - '@changesets/get-release-plan': 3.0.7 - '@changesets/git': 1.3.1 + '@changesets/get-dependents-graph': 1.3.2 + '@changesets/get-release-plan': 3.0.8 + '@changesets/git': 1.3.2 '@changesets/logger': 0.0.5 - '@changesets/pre': 1.0.10 - '@changesets/read': 0.5.4 - '@changesets/types': 4.1.0 - '@changesets/write': 0.1.7 + '@changesets/pre': 1.0.11 + '@changesets/read': 0.5.5 + '@changesets/types': 5.0.0 + '@changesets/write': 0.1.8 '@manypkg/get-packages': 1.1.3 '@types/is-ci': 3.0.0 '@types/semver': 6.2.3 @@ -3159,19 +3163,20 @@ packages: outdent: 0.5.0 p-limit: 2.3.0 preferred-pm: 3.0.3 + resolve-from: 5.0.0 semver: 5.7.1 spawndamnit: 2.0.0 term-size: 2.2.1 tty-table: 2.8.13 dev: true - /@changesets/config/1.7.0: - resolution: {integrity: sha512-Ctk6ZO5Ay6oZ95bbKXyA2a1QG0jQUePaGCY6BKkZtUG4PgysesfmiQOPgOY5OsRMt8exJeo6l+DJ75YiKmh0rQ==} + /@changesets/config/2.0.0: + resolution: {integrity: sha512-r5bIFY6CN3K6SQ+HZbjyE3HXrBIopONR47mmX7zUbORlybQXtympq9rVAOzc0Oflbap8QeIexc+hikfZoREXDg==} dependencies: '@changesets/errors': 0.1.4 - '@changesets/get-dependents-graph': 1.3.1 + '@changesets/get-dependents-graph': 1.3.2 '@changesets/logger': 0.0.5 - '@changesets/types': 4.1.0 + '@changesets/types': 5.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 micromatch: 4.0.5 @@ -3183,10 +3188,10 @@ packages: extendable-error: 0.1.7 dev: true - /@changesets/get-dependents-graph/1.3.1: - resolution: {integrity: sha512-HwUs8U0XK/ZqCQon1/80jJEyswS8JVmTiHTZslrTpuavyhhhxrSpO1eVCdKgaVHBRalOw3gRzdS3uzkmqYsQSQ==} + /@changesets/get-dependents-graph/1.3.2: + resolution: {integrity: sha512-tsqA6qZRB86SQuApSoDvI8yEWdyIlo/WLI4NUEdhhxLMJ0dapdeT6rUZRgSZzK1X2nv5YwR0MxQBbDAiDibKrg==} dependencies: - '@changesets/types': 4.1.0 + '@changesets/types': 5.0.0 '@manypkg/get-packages': 1.1.3 chalk: 2.4.2 fs-extra: 7.0.1 @@ -3202,15 +3207,15 @@ packages: - encoding dev: true - /@changesets/get-release-plan/3.0.7: - resolution: {integrity: sha512-zDp6RIEKvERIF4Osy8sJ5BzqTiiLMhPWBO02y6w3nzTQJ0VBMaTs4hhwImQ/54O9I34eUHR3D0DwmwGQ27ifaw==} + /@changesets/get-release-plan/3.0.8: + resolution: {integrity: sha512-TJYiWNuP0Lzu2dL/KHuk75w7TkiE5HqoYirrXF7SJIxkhlgH9toQf2C7IapiFTObtuF1qDN8HJAX1CuIOwXldg==} dependencies: '@babel/runtime': 7.17.8 - '@changesets/assemble-release-plan': 5.1.1 - '@changesets/config': 1.7.0 - '@changesets/pre': 1.0.10 - '@changesets/read': 0.5.4 - '@changesets/types': 4.1.0 + '@changesets/assemble-release-plan': 5.1.2 + '@changesets/config': 2.0.0 + '@changesets/pre': 1.0.11 + '@changesets/read': 0.5.5 + '@changesets/types': 5.0.0 '@manypkg/get-packages': 1.1.3 dev: true @@ -3218,12 +3223,12 @@ packages: resolution: {integrity: sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg==} dev: true - /@changesets/git/1.3.1: - resolution: {integrity: sha512-yg60QUi38VA0XGXdBy9SRYJhs8xJHE97Z1CaB/hFyByBlh5k1i+avFNBvvw66MsoT/aiml6y9scIG6sC8R5mfg==} + /@changesets/git/1.3.2: + resolution: {integrity: sha512-p5UL+urAg0Nnpt70DLiBe2iSsMcDubTo9fTOD/61krmcJ466MGh71OHwdAwu1xG5+NKzeysdy1joRTg8CXcEXA==} dependencies: '@babel/runtime': 7.17.8 '@changesets/errors': 0.1.4 - '@changesets/types': 4.1.0 + '@changesets/types': 5.0.0 '@manypkg/get-packages': 1.1.3 is-subdir: 1.2.0 spawndamnit: 2.0.0 @@ -3235,31 +3240,31 @@ packages: chalk: 2.4.2 dev: true - /@changesets/parse/0.3.12: - resolution: {integrity: sha512-FOBz2L1dT9PcvyQU1Qp2sQ0B4Jw7EgRDAKFVzAQwhzXqCq03TcE7vgKU6VSksCJAioMYDowdVVHNnv/Uak6yZQ==} + /@changesets/parse/0.3.13: + resolution: {integrity: sha512-wh9Ifa0dungY6d2nMz6XxF6FZ/1I7j+mEgPAqrIyKS64nifTh1Ua82qKKMMK05CL7i4wiB2NYc3SfnnCX3RVeA==} dependencies: - '@changesets/types': 4.1.0 + '@changesets/types': 5.0.0 js-yaml: 3.14.1 dev: true - /@changesets/pre/1.0.10: - resolution: {integrity: sha512-cZC1C1wTSC17/TcTWivAQ4LAXz5jEYDuy3UeZiBz1wnTTzMHyTHLLwJi60juhl4hawXunDLw0mwZkcpS8Ivitg==} + /@changesets/pre/1.0.11: + resolution: {integrity: sha512-CXZnt4SV9waaC9cPLm7818+SxvLKIDHUxaiTXnJYDp1c56xIexx1BNfC1yMuOdzO2a3rAIcZua5Odxr3dwSKfg==} dependencies: '@babel/runtime': 7.17.8 '@changesets/errors': 0.1.4 - '@changesets/types': 4.1.0 + '@changesets/types': 5.0.0 '@manypkg/get-packages': 1.1.3 fs-extra: 7.0.1 dev: true - /@changesets/read/0.5.4: - resolution: {integrity: sha512-12dTx+p5ztFs9QgJDGHRHR6HzTIbHct9S4lK2I/i6Qkz1cNfAPVIbdoMCdbPIWeLank9muMUjiiFmCWJD7tQIg==} + /@changesets/read/0.5.5: + resolution: {integrity: sha512-bzonrPWc29Tsjvgh+8CqJ0apQOwWim0zheeD4ZK44ApSa/GudnZJTODtA3yNOOuQzeZmL0NUebVoHIurtIkA7w==} dependencies: '@babel/runtime': 7.17.8 - '@changesets/git': 1.3.1 + '@changesets/git': 1.3.2 '@changesets/logger': 0.0.5 - '@changesets/parse': 0.3.12 - '@changesets/types': 4.1.0 + '@changesets/parse': 0.3.13 + '@changesets/types': 5.0.0 chalk: 2.4.2 fs-extra: 7.0.1 p-filter: 2.1.0 @@ -3269,11 +3274,15 @@ packages: resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} dev: true - /@changesets/write/0.1.7: - resolution: {integrity: sha512-6r+tc6u2l5BBIwEAh7ivRYWFir+XKiw0q/6Hx6NJA4dSN5fNu9uyWRQ+IMHCllD9dBcsh+e79sOepc+xT8l28g==} + /@changesets/types/5.0.0: + resolution: {integrity: sha512-IT1kBLSbAgTS4WtpU6P5ko054hq12vk4tgeIFRVE7Vnm4a/wgbNvBalgiKP0MjEXbCkZbItiGQHkCGxYWR55sA==} + dev: true + + /@changesets/write/0.1.8: + resolution: {integrity: sha512-oIHeFVMuP6jf0TPnKPpaFpvvAf3JBc+s2pmVChbeEgQTBTALoF51Z9kqxQfG4XONZPHZnqkmy564c7qohhhhTQ==} dependencies: '@babel/runtime': 7.17.8 - '@changesets/types': 4.1.0 + '@changesets/types': 5.0.0 fs-extra: 7.0.1 human-id: 1.0.2 prettier: 1.19.1 @@ -3913,8 +3922,8 @@ packages: ci-info: 3.3.0 dev: true - /@types/json-schema/7.0.10: - resolution: {integrity: sha512-BLO9bBq59vW3fxCpD4o0N4U+DXsvwvIcl+jofw0frQo/GrBFC+/jRZj1E7kgp6dvTyNmA4y6JCV5Id/r3mNP5A==} + /@types/json-schema/7.0.11: + resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} dev: true /@types/json5/0.0.30: @@ -4082,8 +4091,8 @@ packages: resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} dev: true - /@typescript-eslint/eslint-plugin/5.16.0_bc68a9cd5bf604202498b1a9faaf9387: - resolution: {integrity: sha512-SJoba1edXvQRMmNI505Uo4XmGbxCK9ARQpkvOd00anxzri9RNQk0DDCxD+LIl+jYhkzOJiOMMKYEHnHEODjdCw==} + /@typescript-eslint/eslint-plugin/5.17.0_689ff565753ecf7c3328c07fad067df5: + resolution: {integrity: sha512-qVstvQilEd89HJk3qcbKt/zZrfBZ+9h2ynpAGlWjWiizA7m/MtLT9RoX6gjtpE500vfIg8jogAkDzdCxbsFASQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -4093,12 +4102,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.16.0_eslint@8.11.0+typescript@4.6.3 - '@typescript-eslint/scope-manager': 5.16.0 - '@typescript-eslint/type-utils': 5.16.0_eslint@8.11.0+typescript@4.6.3 - '@typescript-eslint/utils': 5.16.0_eslint@8.11.0+typescript@4.6.3 + '@typescript-eslint/parser': 5.17.0_eslint@8.12.0+typescript@4.6.3 + '@typescript-eslint/scope-manager': 5.17.0 + '@typescript-eslint/type-utils': 5.17.0_eslint@8.12.0+typescript@4.6.3 + '@typescript-eslint/utils': 5.17.0_eslint@8.12.0+typescript@4.6.3 debug: 4.3.4 - eslint: 8.11.0 + eslint: 8.12.0 functional-red-black-tree: 1.0.1 ignore: 5.2.0 regexpp: 3.2.0 @@ -4109,8 +4118,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser/5.16.0_eslint@8.11.0+typescript@4.6.3: - resolution: {integrity: sha512-fkDq86F0zl8FicnJtdXakFs4lnuebH6ZADDw6CYQv0UZeIjHvmEw87m9/29nk2Dv5Lmdp0zQ3zDQhiMWQf/GbA==} + /@typescript-eslint/parser/5.17.0_eslint@8.12.0+typescript@4.6.3: + resolution: {integrity: sha512-aRzW9Jg5Rlj2t2/crzhA2f23SIYFlF9mchGudyP0uiD6SenIxzKoLjwzHbafgHn39dNV/TV7xwQkLfFTZlJ4ig==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -4119,26 +4128,26 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.16.0 - '@typescript-eslint/types': 5.16.0 - '@typescript-eslint/typescript-estree': 5.16.0_typescript@4.6.3 + '@typescript-eslint/scope-manager': 5.17.0 + '@typescript-eslint/types': 5.17.0 + '@typescript-eslint/typescript-estree': 5.17.0_typescript@4.6.3 debug: 4.3.4 - eslint: 8.11.0 + eslint: 8.12.0 typescript: 4.6.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager/5.16.0: - resolution: {integrity: sha512-P+Yab2Hovg8NekLIR/mOElCDPyGgFZKhGoZA901Yax6WR6HVeGLbsqJkZ+Cvk5nts/dAlFKm8PfL43UZnWdpIQ==} + /@typescript-eslint/scope-manager/5.17.0: + resolution: {integrity: sha512-062iCYQF/doQ9T2WWfJohQKKN1zmmXVfAcS3xaiialiw8ZUGy05Em6QVNYJGO34/sU1a7a+90U3dUNfqUDHr3w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.16.0 - '@typescript-eslint/visitor-keys': 5.16.0 + '@typescript-eslint/types': 5.17.0 + '@typescript-eslint/visitor-keys': 5.17.0 dev: true - /@typescript-eslint/type-utils/5.16.0_eslint@8.11.0+typescript@4.6.3: - resolution: {integrity: sha512-SKygICv54CCRl1Vq5ewwQUJV/8padIWvPgCxlWPGO/OgQLCijY9G7lDu6H+mqfQtbzDNlVjzVWQmeqbLMBLEwQ==} + /@typescript-eslint/type-utils/5.17.0_eslint@8.12.0+typescript@4.6.3: + resolution: {integrity: sha512-3hU0RynUIlEuqMJA7dragb0/75gZmwNwFf/QJokWzPehTZousP/MNifVSgjxNcDCkM5HI2K22TjQWUmmHUINSg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -4147,22 +4156,22 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/utils': 5.16.0_eslint@8.11.0+typescript@4.6.3 + '@typescript-eslint/utils': 5.17.0_eslint@8.12.0+typescript@4.6.3 debug: 4.3.4 - eslint: 8.11.0 + eslint: 8.12.0 tsutils: 3.21.0_typescript@4.6.3 typescript: 4.6.3 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types/5.16.0: - resolution: {integrity: sha512-oUorOwLj/3/3p/HFwrp6m/J2VfbLC8gjW5X3awpQJ/bSG+YRGFS4dpsvtQ8T2VNveV+LflQHjlLvB6v0R87z4g==} + /@typescript-eslint/types/5.17.0: + resolution: {integrity: sha512-AgQ4rWzmCxOZLioFEjlzOI3Ch8giDWx8aUDxyNw9iOeCvD3GEYAB7dxWGQy4T/rPVe8iPmu73jPHuaSqcjKvxw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.16.0_typescript@4.6.3: - resolution: {integrity: sha512-SE4VfbLWUZl9MR+ngLSARptUv2E8brY0luCdgmUevU6arZRY/KxYoLI/3V/yxaURR8tLRN7bmZtJdgmzLHI6pQ==} + /@typescript-eslint/typescript-estree/5.17.0_typescript@4.6.3: + resolution: {integrity: sha512-X1gtjEcmM7Je+qJRhq7ZAAaNXYhTgqMkR10euC4Si6PIjb+kwEQHSxGazXUQXFyqfEXdkGf6JijUu5R0uceQzg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -4170,8 +4179,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.16.0 - '@typescript-eslint/visitor-keys': 5.16.0 + '@typescript-eslint/types': 5.17.0 + '@typescript-eslint/visitor-keys': 5.17.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -4182,29 +4191,29 @@ packages: - supports-color dev: true - /@typescript-eslint/utils/5.16.0_eslint@8.11.0+typescript@4.6.3: - resolution: {integrity: sha512-iYej2ER6AwmejLWMWzJIHy3nPJeGDuCqf8Jnb+jAQVoPpmWzwQOfa9hWVB8GIQE5gsCv/rfN4T+AYb/V06WseQ==} + /@typescript-eslint/utils/5.17.0_eslint@8.12.0+typescript@4.6.3: + resolution: {integrity: sha512-DVvndq1QoxQH+hFv+MUQHrrWZ7gQ5KcJzyjhzcqB1Y2Xes1UQQkTRPUfRpqhS8mhTWsSb2+iyvDW1Lef5DD7vA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@types/json-schema': 7.0.10 - '@typescript-eslint/scope-manager': 5.16.0 - '@typescript-eslint/types': 5.16.0 - '@typescript-eslint/typescript-estree': 5.16.0_typescript@4.6.3 - eslint: 8.11.0 + '@types/json-schema': 7.0.11 + '@typescript-eslint/scope-manager': 5.17.0 + '@typescript-eslint/types': 5.17.0 + '@typescript-eslint/typescript-estree': 5.17.0_typescript@4.6.3 + eslint: 8.12.0 eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@8.11.0 + eslint-utils: 3.0.0_eslint@8.12.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys/5.16.0: - resolution: {integrity: sha512-jqxO8msp5vZDhikTwq9ubyMHqZ67UIvawohr4qF3KhlpL7gzSjOd+8471H3nh5LyABkaI85laEKKU8SnGUK5/g==} + /@typescript-eslint/visitor-keys/5.17.0: + resolution: {integrity: sha512-6K/zlc4OfCagUu7Am/BD5k8PSWQOgh34Nrv9Rxe2tBzlJ7uOeJ/h7ugCGDCeEZHT6k2CJBhbk9IsbkPI0uvUkA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.16.0 + '@typescript-eslint/types': 5.17.0 eslint-visitor-keys: 3.3.0 dev: true @@ -4641,6 +4650,13 @@ packages: tslib: 2.3.1 dev: true + /ast-types/0.14.2: + resolution: {integrity: sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==} + engines: {node: '>=4'} + dependencies: + tslib: 2.3.1 + dev: false + /async/0.9.2: resolution: {integrity: sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=} dev: true @@ -4658,7 +4674,7 @@ packages: postcss: ^8.1.0 dependencies: browserslist: 4.20.2 - caniuse-lite: 1.0.30001320 + caniuse-lite: 1.0.30001322 fraction.js: 4.2.0 normalize-range: 0.1.2 picocolors: 1.0.0 @@ -4827,8 +4843,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001320 - electron-to-chromium: 1.4.93 + caniuse-lite: 1.0.30001322 + electron-to-chromium: 1.4.98 escalade: 3.1.1 node-releases: 2.0.2 picocolors: 1.0.0 @@ -4902,8 +4918,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - /caniuse-lite/1.0.30001320: - resolution: {integrity: sha512-MWPzG54AGdo3nWx7zHZTefseM5Y1ccM7hlQKHRqJkPozUaw3hNbBTMmLn16GG2FUzjR13Cr3NPfhIieX5PzXDA==} + /caniuse-lite/1.0.30001322: + resolution: {integrity: sha512-neRmrmIrCGuMnxGSoh+x7zYtQFFgnSY2jaomjU56sCkTA6JINqQrxutF459JpWcWRajvoyn95sOXq4Pqrnyjew==} /canvas-confetti/1.5.1: resolution: {integrity: sha512-Ncz+oZJP6OvY7ti4E1slxVlyAV/3g7H7oQtcCDXgwGgARxPnwYY9PW5Oe+I8uvspYNtuHviAdgA0LfcKFWJfpg==} @@ -4978,11 +4994,11 @@ packages: resolution: {integrity: sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=} dev: true - /cheerio-select/1.5.0: - resolution: {integrity: sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==} + /cheerio-select/1.6.0: + resolution: {integrity: sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==} dependencies: - css-select: 4.2.1 - css-what: 5.1.0 + css-select: 4.3.0 + css-what: 6.0.1 domelementtype: 2.2.0 domhandler: 4.3.1 domutils: 2.8.0 @@ -4992,7 +5008,7 @@ packages: resolution: {integrity: sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==} engines: {node: '>= 6'} dependencies: - cheerio-select: 1.5.0 + cheerio-select: 1.6.0 dom-serializer: 1.3.2 domhandler: 4.3.1 htmlparser2: 6.1.0 @@ -5199,11 +5215,11 @@ packages: engines: {node: '>=8'} dev: true - /css-select/4.2.1: - resolution: {integrity: sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==} + /css-select/4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} dependencies: boolbase: 1.0.0 - css-what: 5.1.0 + css-what: 6.0.1 domhandler: 4.3.1 domutils: 2.8.0 nth-check: 2.0.1 @@ -5212,8 +5228,8 @@ packages: /css-selector-parser/1.4.1: resolution: {integrity: sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==} - /css-what/5.1.0: - resolution: {integrity: sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==} + /css-what/6.0.1: + resolution: {integrity: sha512-z93ZGFLNc6yaoXAmVhqoSIb+BduplteCt1fepvwhBUQK6MNE4g6fgjpuZKJKp0esUe+vXWlIkwZZjNWoOKw0ZA==} engines: {node: '>= 6'} dev: true @@ -5508,8 +5524,8 @@ packages: jake: 10.8.4 dev: true - /electron-to-chromium/1.4.93: - resolution: {integrity: sha512-ywq9Pc5Gwwpv7NG767CtoU8xF3aAUQJjH9//Wy3MBCg4w5JSLbJUq2L8IsCdzPMjvSgxuue9WcVaTOyyxCL0aQ==} + /electron-to-chromium/1.4.98: + resolution: {integrity: sha512-1IdsuSAnIGVxoYT1LkcUFb9MfjRxdHhCU9qiaDzhl1XvYgK9c8E2O9aJOPgGMQ68CSI8NxmLwrYhjvGauT8yuw==} /emmet/2.3.6: resolution: {integrity: sha512-pLS4PBPDdxuUAmw7Me7+TcHbykTsBKN/S9XJbUOMFQrNv9MoshzyMFK/R57JBm94/6HSL4vHnDeEmxlC82NQ4A==} @@ -5555,8 +5571,8 @@ packages: dependencies: is-arrayish: 0.2.1 - /es-abstract/1.19.1: - resolution: {integrity: sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==} + /es-abstract/1.19.2: + resolution: {integrity: sha512-gfSBJoZdlL2xRiOCy0g8gLMryhoe1TlimjzU99L/31Z8QEGIhVQI+EWwt5lT+AuU9SnorVupXFqqOGqGfsyO6w==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.2 @@ -5608,8 +5624,8 @@ packages: requiresBuild: true optional: true - /esbuild-android-64/0.14.27: - resolution: {integrity: sha512-LuEd4uPuj/16Y8j6kqy3Z2E9vNY9logfq8Tq+oTE2PZVuNs3M1kj5Qd4O95ee66yDGb3isaOCV7sOLDwtMfGaQ==} + /esbuild-android-64/0.14.28: + resolution: {integrity: sha512-A52C3zq+9tNwCqZ+4kVLBxnk/WnrYM8P2+QNvNE9B6d2OVPs214lp3g6UyO+dKDhUdefhfPCuwkP8j2A/+szNA==} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -5625,8 +5641,8 @@ packages: requiresBuild: true optional: true - /esbuild-android-arm64/0.14.27: - resolution: {integrity: sha512-E8Ktwwa6vX8q7QeJmg8yepBYXaee50OdQS3BFtEHKrzbV45H4foMOeEE7uqdjGQZFBap5VAqo7pvjlyA92wznQ==} + /esbuild-android-arm64/0.14.28: + resolution: {integrity: sha512-sm0fDEGElZhMC3HLZeECI2juE4aG7uPfMBMqNUhy9CeX399Pz8rC6e78OXMXInGjSdEAwQmCOHmfsP7uv3Q8rA==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -5642,8 +5658,8 @@ packages: requiresBuild: true optional: true - /esbuild-darwin-64/0.14.27: - resolution: {integrity: sha512-czw/kXl/1ZdenPWfw9jDc5iuIYxqUxgQ/Q+hRd4/3udyGGVI31r29LCViN2bAJgGvQkqyLGVcG03PJPEXQ5i2g==} + /esbuild-darwin-64/0.14.28: + resolution: {integrity: sha512-nzDd7mQ44FvsFHtOafZdBgn3Li5SMsnMnoz1J2MM37xJmR3wGNTFph88KypjHgWqwbxCI7MXS1U+sN4qDeeW6Q==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -5659,8 +5675,8 @@ packages: requiresBuild: true optional: true - /esbuild-darwin-arm64/0.14.27: - resolution: {integrity: sha512-BEsv2U2U4o672oV8+xpXNxN9bgqRCtddQC6WBh4YhXKDcSZcdNh7+6nS+DM2vu7qWIWNA4JbRG24LUUYXysimQ==} + /esbuild-darwin-arm64/0.14.28: + resolution: {integrity: sha512-XEq/bLR/glsUl+uGrBimQzOVs/CmwI833fXUhP9xrLI3IJ+rKyrZ5IA8u+1crOEf1LoTn8tV+hInmX6rGjbScw==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -5676,8 +5692,8 @@ packages: requiresBuild: true optional: true - /esbuild-freebsd-64/0.14.27: - resolution: {integrity: sha512-7FeiFPGBo+ga+kOkDxtPmdPZdayrSzsV9pmfHxcyLKxu+3oTcajeZlOO1y9HW+t5aFZPiv7czOHM4KNd0tNwCA==} + /esbuild-freebsd-64/0.14.28: + resolution: {integrity: sha512-rTKLgUj/HEcPeE5XZ7IZwWpFx7IWMfprN7QRk/TUJE1s1Ipb58esboIesUpjirJz/BwrgHq+FDG9ChAI8dZAtQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -5693,8 +5709,8 @@ packages: requiresBuild: true optional: true - /esbuild-freebsd-arm64/0.14.27: - resolution: {integrity: sha512-8CK3++foRZJluOWXpllG5zwAVlxtv36NpHfsbWS7TYlD8S+QruXltKlXToc/5ZNzBK++l6rvRKELu/puCLc7jA==} + /esbuild-freebsd-arm64/0.14.28: + resolution: {integrity: sha512-sBffxD1UMOsB7aWMoExmipycjcy3HJGwmqE4GQZUTZvdiH4GhjgUiVdtPyt7kSCdL40JqnWQJ4b1l8Y51oCF4Q==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -5710,8 +5726,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-32/0.14.27: - resolution: {integrity: sha512-qhNYIcT+EsYSBClZ5QhLzFzV5iVsP1YsITqblSaztr3+ZJUI+GoK8aXHyzKd7/CKKuK93cxEMJPpfi1dfsOfdw==} + /esbuild-linux-32/0.14.28: + resolution: {integrity: sha512-+Wxidh3fBEQ9kHcCsD4etlBTMb1n6QY2uXv3rFhVn88CY/JP782MhA57/ipLMY4kOLeSKEuFGN4rtjHuhmRMig==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -5727,8 +5743,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-64/0.14.27: - resolution: {integrity: sha512-ESjck9+EsHoTaKWlFKJpPZRN26uiav5gkI16RuI8WBxUdLrrAlYuYSndxxKgEn1csd968BX/8yQZATYf/9+/qg==} + /esbuild-linux-64/0.14.28: + resolution: {integrity: sha512-7+xgsC4LvR6cnzaBdiljNnPDjbkwzahogN+S9uy9AoYw7ZjPnnXc6sjQAVCbqGb7MEgrWdpa6u/Tao79i4lWxg==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -5744,8 +5760,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-arm/0.14.27: - resolution: {integrity: sha512-JnnmgUBdqLQO9hoNZQqNHFWlNpSX82vzB3rYuCJMhtkuaWQEmQz6Lec1UIxJdC38ifEghNTBsF9bbe8dFilnCw==} + /esbuild-linux-arm/0.14.28: + resolution: {integrity: sha512-L5isjmlLbh9E0WVllXiVETbScgMbth/+XkXQii1WwgO1RvLIfaGrVFz8d2n6EH/ImtgYxPYGx+OcvIKQBc91Rg==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -5761,8 +5777,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-arm64/0.14.27: - resolution: {integrity: sha512-no6Mi17eV2tHlJnqBHRLekpZ2/VYx+NfGxKcBE/2xOMYwctsanCaXxw4zapvNrGE9X38vefVXLz6YCF8b1EHiQ==} + /esbuild-linux-arm64/0.14.28: + resolution: {integrity: sha512-EjRHgwg+kgXABzyoPGPOPg4d5wZqRnZ/ZAxBDzLY+i6DS8OUfTSlZHWIOZzU4XF7125WxRBg9ULbrFJBl+57Eg==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -5778,8 +5794,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-mips64le/0.14.27: - resolution: {integrity: sha512-NolWP2uOvIJpbwpsDbwfeExZOY1bZNlWE/kVfkzLMsSgqeVcl5YMen/cedRe9mKnpfLli+i0uSp7N+fkKNU27A==} + /esbuild-linux-mips64le/0.14.28: + resolution: {integrity: sha512-krx9SSg7yfiUKk64EmjefOyiEF6nv2bRE4um/LiTaQ6Y/6FP4UF3/Ou/AxZVyR154uSRq63xejcAsmswXAYRsw==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -5795,8 +5811,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-ppc64le/0.14.27: - resolution: {integrity: sha512-/7dTjDvXMdRKmsSxKXeWyonuGgblnYDn0MI1xDC7J1VQXny8k1qgNp6VmrlsawwnsymSUUiThhkJsI+rx0taNA==} + /esbuild-linux-ppc64le/0.14.28: + resolution: {integrity: sha512-LD0Xxu9g+DNuhsEBV5QuVZ4uKVBMup0xPIruLweuAf9/mHXFnaCuNXUBF5t0DxKl7GQ5MSioKtnb92oMo+QXEw==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -5812,8 +5828,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-riscv64/0.14.27: - resolution: {integrity: sha512-D+aFiUzOJG13RhrSmZgrcFaF4UUHpqj7XSKrIiCXIj1dkIkFqdrmqMSOtSs78dOtObWiOrFCDDzB24UyeEiNGg==} + /esbuild-linux-riscv64/0.14.28: + resolution: {integrity: sha512-L/DWfRh2P0vxq4Y+qieSNXKGdMg+e9Qe8jkbN2/8XSGYDTPzO2OcAxSujob4qIh7iSl+cknbXV+BvH0YFR0jbg==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -5829,8 +5845,8 @@ packages: requiresBuild: true optional: true - /esbuild-linux-s390x/0.14.27: - resolution: {integrity: sha512-CD/D4tj0U4UQjELkdNlZhQ8nDHU5rBn6NGp47Hiz0Y7/akAY5i0oGadhEIg0WCY/HYVXFb3CsSPPwaKcTOW3bg==} + /esbuild-linux-s390x/0.14.28: + resolution: {integrity: sha512-rrgxmsbmL8QQknWGnAL9bGJRQYLOi2AzXy5OTwfhxnj9eqjo5mSVbJXjgiq5LPUAMQZGdPH5yaNK0obAXS81Zw==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -5846,8 +5862,8 @@ packages: requiresBuild: true optional: true - /esbuild-netbsd-64/0.14.27: - resolution: {integrity: sha512-h3mAld69SrO1VoaMpYl3a5FNdGRE/Nqc+E8VtHOag4tyBwhCQXxtvDDOAKOUQexBGca0IuR6UayQ4ntSX5ij1Q==} + /esbuild-netbsd-64/0.14.28: + resolution: {integrity: sha512-h8wntIyOR8/xMVVM6TvJxxWKh4AjmLK87IPKpuVi8Pq0kyk0RMA+eo4PFGk5j2XK0D7dj8PcSF5NSlP9kN/j0A==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -5863,8 +5879,8 @@ packages: requiresBuild: true optional: true - /esbuild-openbsd-64/0.14.27: - resolution: {integrity: sha512-xwSje6qIZaDHXWoPpIgvL+7fC6WeubHHv18tusLYMwL+Z6bEa4Pbfs5IWDtQdHkArtfxEkIZz77944z8MgDxGw==} + /esbuild-openbsd-64/0.14.28: + resolution: {integrity: sha512-HBv18rVapbuDx52/fhZ/c/w6TXyaQAvRxiDDn5Hz/pBcwOs3cdd2WxeIKlWmDoqm2JMx5EVlq4IWgoaRX9mVkw==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -5880,8 +5896,8 @@ packages: requiresBuild: true optional: true - /esbuild-sunos-64/0.14.27: - resolution: {integrity: sha512-/nBVpWIDjYiyMhuqIqbXXsxBc58cBVH9uztAOIfWShStxq9BNBik92oPQPJ57nzWXRNKQUEFWr4Q98utDWz7jg==} + /esbuild-sunos-64/0.14.28: + resolution: {integrity: sha512-zlIxePhZxKYheR2vBCgPVvTixgo/ozOfOMoP6RZj8dxzquU1NgeyhjkcRXucbLCtmoNJ+i4PtWwPZTLuDd3bGg==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -5897,8 +5913,8 @@ packages: requiresBuild: true optional: true - /esbuild-windows-32/0.14.27: - resolution: {integrity: sha512-Q9/zEjhZJ4trtWhFWIZvS/7RUzzi8rvkoaS9oiizkHTTKd8UxFwn/Mm2OywsAfYymgUYm8+y2b+BKTNEFxUekw==} + /esbuild-windows-32/0.14.28: + resolution: {integrity: sha512-am9DIJxXlld1BOAY/VlvBQHMUCPL7S3gB/lnXIY3M4ys0gfuRqPf4EvMwZMzYUbFKBY+/Qb8SRgPRRGhwnJ8Kg==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -5914,8 +5930,8 @@ packages: requiresBuild: true optional: true - /esbuild-windows-64/0.14.27: - resolution: {integrity: sha512-b3y3vTSl5aEhWHK66ngtiS/c6byLf6y/ZBvODH1YkBM+MGtVL6jN38FdHUsZasCz9gFwYs/lJMVY9u7GL6wfYg==} + /esbuild-windows-64/0.14.28: + resolution: {integrity: sha512-78PhySDnmRZlsPNp/W/5Fim8iivlBQQxfhBFIqR7xwvfDmCFUSByyMKP7LCHgNtb04yNdop8nJJkJaQ8Xnwgiw==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -5931,8 +5947,8 @@ packages: requiresBuild: true optional: true - /esbuild-windows-arm64/0.14.27: - resolution: {integrity: sha512-I/reTxr6TFMcR5qbIkwRGvldMIaiBu2+MP0LlD7sOlNXrfqIl9uNjsuxFPGEG4IRomjfQ5q8WT+xlF/ySVkqKg==} + /esbuild-windows-arm64/0.14.28: + resolution: {integrity: sha512-VhXGBTo6HELD8zyHXynV6+L2jWx0zkKnGx4TmEdSBK7UVFACtOyfUqpToG0EtnYyRZ0HESBhzPSVpP781ovmvA==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -5967,32 +5983,32 @@ packages: esbuild-windows-64: 0.14.25 esbuild-windows-arm64: 0.14.25 - /esbuild/0.14.27: - resolution: {integrity: sha512-MZQt5SywZS3hA9fXnMhR22dv0oPGh6QtjJRIYbgL1AeqAoQZE+Qn5ppGYQAoHv/vq827flj4tIJ79Mrdiwk46Q==} + /esbuild/0.14.28: + resolution: {integrity: sha512-YLNprkCcMVKQ5sekmCKEQ3Obu/L7s6+iij38xNKyBeSmSsTWur4Ky/9zB3XIGT8SCJITG/bZwAR2l7YOAXch4Q==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - esbuild-android-64: 0.14.27 - esbuild-android-arm64: 0.14.27 - esbuild-darwin-64: 0.14.27 - esbuild-darwin-arm64: 0.14.27 - esbuild-freebsd-64: 0.14.27 - esbuild-freebsd-arm64: 0.14.27 - esbuild-linux-32: 0.14.27 - esbuild-linux-64: 0.14.27 - esbuild-linux-arm: 0.14.27 - esbuild-linux-arm64: 0.14.27 - esbuild-linux-mips64le: 0.14.27 - esbuild-linux-ppc64le: 0.14.27 - esbuild-linux-riscv64: 0.14.27 - esbuild-linux-s390x: 0.14.27 - esbuild-netbsd-64: 0.14.27 - esbuild-openbsd-64: 0.14.27 - esbuild-sunos-64: 0.14.27 - esbuild-windows-32: 0.14.27 - esbuild-windows-64: 0.14.27 - esbuild-windows-arm64: 0.14.27 + esbuild-android-64: 0.14.28 + esbuild-android-arm64: 0.14.28 + esbuild-darwin-64: 0.14.28 + esbuild-darwin-arm64: 0.14.28 + esbuild-freebsd-64: 0.14.28 + esbuild-freebsd-arm64: 0.14.28 + esbuild-linux-32: 0.14.28 + esbuild-linux-64: 0.14.28 + esbuild-linux-arm: 0.14.28 + esbuild-linux-arm64: 0.14.28 + esbuild-linux-mips64le: 0.14.28 + esbuild-linux-ppc64le: 0.14.28 + esbuild-linux-riscv64: 0.14.28 + esbuild-linux-s390x: 0.14.28 + esbuild-netbsd-64: 0.14.28 + esbuild-openbsd-64: 0.14.28 + esbuild-sunos-64: 0.14.28 + esbuild-windows-32: 0.14.28 + esbuild-windows-64: 0.14.28 + esbuild-windows-arm64: 0.14.28 dev: false /escalade/3.1.1: @@ -6026,16 +6042,16 @@ packages: source-map: 0.6.1 dev: true - /eslint-config-prettier/8.5.0_eslint@8.11.0: + /eslint-config-prettier/8.5.0_eslint@8.12.0: resolution: {integrity: sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.11.0 + eslint: 8.12.0 dev: true - /eslint-plugin-prettier/4.0.0_e2923b5169e23c4db59b86a638c599a3: + /eslint-plugin-prettier/4.0.0_b253a92c95b42c3296c682f11cccb3bd: resolution: {integrity: sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==} engines: {node: '>=6.0.0'} peerDependencies: @@ -6046,8 +6062,8 @@ packages: eslint-config-prettier: optional: true dependencies: - eslint: 8.11.0 - eslint-config-prettier: 8.5.0_eslint@8.11.0 + eslint: 8.12.0 + eslint-config-prettier: 8.5.0_eslint@8.12.0 prettier: 2.6.1 prettier-linter-helpers: 1.0.0 dev: true @@ -6068,13 +6084,13 @@ packages: estraverse: 5.3.0 dev: true - /eslint-utils/3.0.0_eslint@8.11.0: + /eslint-utils/3.0.0_eslint@8.12.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} peerDependencies: eslint: '>=5' dependencies: - eslint: 8.11.0 + eslint: 8.12.0 eslint-visitor-keys: 2.1.0 dev: true @@ -6088,8 +6104,8 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.11.0: - resolution: {integrity: sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==} + /eslint/8.12.0: + resolution: {integrity: sha512-it1oBL9alZg1S8UycLm5YDMAkIhtH6FtAzuZs6YvoGVldWjbS08BkAdb/ymP9LlAyq8koANu32U7Ib/w+UNh8Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: @@ -6102,7 +6118,7 @@ packages: doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.1.1 - eslint-utils: 3.0.0_eslint@8.11.0 + eslint-utils: 3.0.0_eslint@8.12.0 eslint-visitor-keys: 3.3.0 espree: 9.3.1 esquery: 1.4.0 @@ -6790,6 +6806,10 @@ packages: resolution: {integrity: sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ==} dev: false + /html-entities/2.3.3: + resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==} + dev: false + /html-escaper/3.0.3: resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} dev: false @@ -7164,7 +7184,7 @@ packages: dependencies: available-typed-arrays: 1.0.5 call-bind: 1.0.2 - es-abstract: 1.19.1 + es-abstract: 1.19.2 foreach: 2.0.5 has-tostringtag: 1.0.0 dev: false @@ -8119,6 +8139,12 @@ packages: resolution: {integrity: sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + dev: true + + /nanoid/3.3.2: + resolution: {integrity: sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true /nanostores/0.5.12: resolution: {integrity: sha512-5BccS7nNInTc7Noz2gv19gyx5h5y6m72nj6ZnCTV98GdFdwvcFJf2MMl+7VsX76E1toV1YrLqlDn+R+OF73PVg==} @@ -8527,16 +8553,36 @@ packages: camelcase-css: 2.0.1 postcss: 8.4.12 - /postcss-load-config/3.1.3: - resolution: {integrity: sha512-5EYgaM9auHGtO//ljHH+v/aC/TQ5LHXtL7bQajNAUBKUVKiYE8rYpFms7+V26D9FncaGe2zwCoPQsFKb5zF/Hw==} + /postcss-load-config/3.1.4: + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.0.5 + yaml: 1.10.2 + dev: false + + /postcss-load-config/3.1.4_postcss@8.4.12: + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} engines: {node: '>= 10'} peerDependencies: + postcss: '>=8.0.9' ts-node: '>=9.0.0' peerDependenciesMeta: + postcss: + optional: true ts-node: optional: true dependencies: lilconfig: 2.0.5 + postcss: 8.4.12 yaml: 1.10.2 /postcss-nested/5.0.6_postcss@8.4.12: @@ -8562,7 +8608,7 @@ packages: resolution: {integrity: sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==} engines: {node: ^10 || ^12 || >=14} dependencies: - nanoid: 3.3.1 + nanoid: 3.3.2 picocolors: 1.0.0 source-map-js: 1.0.2 @@ -8823,6 +8869,16 @@ packages: dependencies: picomatch: 2.3.1 + /recast/0.20.5: + resolution: {integrity: sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ==} + engines: {node: '>= 4'} + dependencies: + ast-types: 0.14.2 + esprima: 4.0.1 + source-map: 0.6.1 + tslib: 2.3.1 + dev: false + /redent/3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} engines: {node: '>=8'} @@ -9489,7 +9545,7 @@ packages: dependencies: call-bind: 1.0.2 define-properties: 1.1.3 - es-abstract: 1.19.1 + es-abstract: 1.19.2 get-intrinsic: 1.1.1 has-symbols: 1.0.3 internal-slot: 1.0.3 @@ -9652,7 +9708,7 @@ packages: svelte: 3.46.4 dev: false - /svelte-preprocess/4.10.4_6ccb891c442782d29dbf23417a615415: + /svelte-preprocess/4.10.4_ec4868a778d68da3f0d21a10f4ea83cd: resolution: {integrity: sha512-fuwol0N4UoHsNQolLFbMqWivqcJ9N0vfWO9IuPAiX/5okfoGXURyJ6nECbuEIv0nU3M8Xe2I1ONNje2buk7l6A==} engines: {node: '>= 9.11.2'} requiresBuild: true @@ -9697,7 +9753,7 @@ packages: '@types/sass': 1.43.1 detect-indent: 6.1.0 magic-string: 0.25.9 - postcss-load-config: 3.1.3 + postcss-load-config: 3.1.4 sorcery: 0.10.0 strip-indent: 3.0.0 svelte: 3.46.4 @@ -9794,7 +9850,7 @@ packages: object-hash: 2.2.0 postcss: 8.4.12 postcss-js: 4.0.0_postcss@8.4.12 - postcss-load-config: 3.1.3 + postcss-load-config: 3.1.4_postcss@8.4.12 postcss-nested: 5.0.6_postcss@8.4.12 postcss-selector-parser: 6.0.9 postcss-value-parser: 4.2.0 @@ -9954,7 +10010,7 @@ packages: engines: {node: '>=12'} hasBin: true dependencies: - esbuild: 0.14.27 + esbuild: 0.14.25 dev: false /tsutils/3.21.0_typescript@4.6.3: @@ -10464,7 +10520,7 @@ packages: stylus: optional: true dependencies: - esbuild: 0.14.27 + esbuild: 0.14.28 postcss: 8.4.12 resolve: 1.22.0 rollup: 2.70.1 @@ -10488,7 +10544,7 @@ packages: stylus: optional: true dependencies: - esbuild: 0.14.27 + esbuild: 0.14.28 postcss: 8.4.12 resolve: 1.22.0 rollup: 2.70.1 @@ -10640,7 +10696,7 @@ packages: dependencies: available-typed-arrays: 1.0.5 call-bind: 1.0.2 - es-abstract: 1.19.1 + es-abstract: 1.19.2 foreach: 2.0.5 has-tostringtag: 1.0.0 is-typed-array: 1.1.8 @@ -10952,8 +11008,8 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - /zod/3.14.2: - resolution: {integrity: sha512-iF+wrtzz7fQfkmn60PG6XFxaWBhYYKzp2i+nv24WbLUWb2JjymdkHlzBwP0erpc78WotwP5g9AAu7Sk8GWVVNw==} + /zod/3.14.3: + resolution: {integrity: sha512-OzwRCSXB1+/8F6w6HkYHdbuWysYWnAF4fkRgKDcSFc54CE+Sv0rHXKfeNUReGCrHukm1LNpi6AYeXotznhYJbQ==} dev: false /zwitch/2.0.2: diff --git a/scripts/stats/stats.csv b/scripts/stats/stats.csv index 1ff8ca327..a582bd823 100644 --- a/scripts/stats/stats.csv +++ b/scripts/stats/stats.csv @@ -1,4 +1,5 @@ Date,Commits (24hr),Issues (24hr),Issues:BUG (24hr),Issues:RFC (24hr),Issues:DOC (24hr),PRs (24hr),Open PRs,Open Issues,Bugs: Needs Triage,Bugs: Accepted,RFC: In Progress,RFC: Accepted,Date (ISO) +"Tuesday, March 29, 2022",19,8,8,0,0,9,5,88,41,41,0,0,"2022-03-29T12:06:39.897Z" "Monday, March 28, 2022",1,7,7,0,0,2,8,83,36,41,0,0,"2022-03-28T12:02:00.954Z" "Sunday, March 27, 2022",1,2,2,0,0,2,6,77,29,41,0,0,"2022-03-27T12:01:52.463Z" "Saturday, March 26, 2022",22,5,5,0,0,12,5,75,27,41,0,0,"2022-03-26T12:03:34.243Z" |