diff options
author | 2022-04-02 14:15:41 -0600 | |
---|---|---|
committer | 2022-04-02 14:15:41 -0600 | |
commit | 1335797903a57716e9a02b0ffd8ca636b3883c62 (patch) | |
tree | d8835124fec7ab80bfbf25c6d9c5a57039a1c56d | |
parent | d63213f1198293e72bb9d9734bf4ec8309c515d4 (diff) | |
download | astro-1335797903a57716e9a02b0ffd8ca636b3883c62.tar.gz astro-1335797903a57716e9a02b0ffd8ca636b3883c62.tar.zst astro-1335797903a57716e9a02b0ffd8ca636b3883c62.zip |
update prettier width (#2968)
146 files changed, 2135 insertions, 484 deletions
diff --git a/.prettierrc.json b/.prettierrc.json index d5bbca6c4..b0a1a2a07 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,5 +1,5 @@ { - "printWidth": 180, + "printWidth": 100, "semi": true, "singleQuote": true, "tabWidth": 2, diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 431773d2f..d8411afe0 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,4 +1,9 @@ { - "recommendations": ["astro-build.astro-vscode", "esbenp.prettier-vscode", "editorconfig.editorconfig", "dbaeumer.vscode-eslint"], + "recommendations": [ + "astro-build.astro-vscode", + "esbenp.prettier-vscode", + "editorconfig.editorconfig", + "dbaeumer.vscode-eslint" + ], "unwantedRecommendations": [] } diff --git a/examples/blog/src/styles/blog.css b/examples/blog/src/styles/blog.css index 234e0162a..2a722d237 100644 --- a/examples/blog/src/styles/blog.css +++ b/examples/blog/src/styles/blog.css @@ -1,8 +1,10 @@ :root { - --font-fallback: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji; + --font-fallback: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, + Apple Color Emoji, Segoe UI Emoji; --font-body: 'IBM Plex Sans', var(--font-fallback); - --font-mono: 'IBM Plex Mono', Consolas, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', - 'Liberation Mono', 'Nimbus Mono L', Monaco, 'Courier New', Courier, monospace; + --font-mono: 'IBM Plex Mono', Consolas, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', + 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', + 'Nimbus Mono L', Monaco, 'Courier New', Courier, monospace; --color-white: #fff; --color-black: #000014; diff --git a/examples/docs/src/components/Header/LanguageSelect.tsx b/examples/docs/src/components/Header/LanguageSelect.tsx index 7fd3af229..a895cc7cc 100644 --- a/examples/docs/src/components/Header/LanguageSelect.tsx +++ b/examples/docs/src/components/Header/LanguageSelect.tsx @@ -6,8 +6,19 @@ import { KNOWN_LANGUAGES, langPathRegex } from '../../languages'; const LanguageSelect: FunctionalComponent<{ lang: string }> = ({ lang }) => { return ( <div class="language-select-wrapper"> - <svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 88.6 77.3" height="1.2em" width="1.2em"> - <path fill="currentColor" d="M61,24.6h7.9l18.7,51.6h-7.7l-5.4-15.5H54.3l-5.6,15.5h-7.2L61,24.6z M72.6,55l-8-22.8L56.3,55H72.6z" /> + <svg + aria-hidden="true" + focusable="false" + role="img" + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 88.6 77.3" + height="1.2em" + width="1.2em" + > + <path + fill="currentColor" + d="M61,24.6h7.9l18.7,51.6h-7.7l-5.4-15.5H54.3l-5.6,15.5h-7.2L61,24.6z M72.6,55l-8-22.8L56.3,55H72.6z" + /> <path fill="currentColor" d="M53.6,60.6c-10-4-16-9-22-14c0,0,1.3,1.3,0,0c-6,5-20,13-20,13l-4-6c8-5,10-6,19-13c-2.1-1.9-12-13-13-19h8 c4,9,10,14,10,14c10-8,10-19,10-19h8c0,0-1,13-12,24l0,0c5,5,10,9,19,13L53.6,60.6z M1.6,16.6h56v-8h-23v-7h-9v7h-24V16.6z" diff --git a/examples/docs/src/components/Header/Search.tsx b/examples/docs/src/components/Header/Search.tsx index ebc563c61..4d06ce00b 100644 --- a/examples/docs/src/components/Header/Search.tsx +++ b/examples/docs/src/components/Header/Search.tsx @@ -41,7 +41,13 @@ export default function Search() { <> <button type="button" ref={searchButtonRef} onClick={onOpen} className="search-input"> <svg width="24" height="24" fill="none"> - <path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" /> + <path + d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" + stroke="currentColor" + strokeWidth="2" + strokeLinecap="round" + strokeLinejoin="round" + /> </svg> <span>Search</span> <span className="search-hint"> diff --git a/examples/docs/src/components/Header/SidebarToggle.tsx b/examples/docs/src/components/Header/SidebarToggle.tsx index 90b180461..2be9dee9a 100644 --- a/examples/docs/src/components/Header/SidebarToggle.tsx +++ b/examples/docs/src/components/Header/SidebarToggle.tsx @@ -15,9 +15,26 @@ const MenuToggle: FunctionalComponent = () => { }, [sidebarShown]); return ( - <button type="button" aria-pressed={sidebarShown ? 'true' : 'false'} id="menu-toggle" onClick={() => setSidebarShown(!sidebarShown)}> - <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 24 24" stroke="currentColor"> - <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" /> + <button + type="button" + aria-pressed={sidebarShown ? 'true' : 'false'} + id="menu-toggle" + onClick={() => setSidebarShown(!sidebarShown)} + > + <svg + xmlns="http://www.w3.org/2000/svg" + width="1em" + height="1em" + fill="none" + viewBox="0 0 24 24" + stroke="currentColor" + > + <path + stroke-linecap="round" + stroke-linejoin="round" + stroke-width="2" + d="M4 6h16M4 12h16M4 18h16" + /> </svg> <span className="sr-only">Toggle sidebar</span> </button> diff --git a/examples/docs/src/components/RightSidebar/TableOfContents.tsx b/examples/docs/src/components/RightSidebar/TableOfContents.tsx index 578d2aa98..537508ab4 100644 --- a/examples/docs/src/components/RightSidebar/TableOfContents.tsx +++ b/examples/docs/src/components/RightSidebar/TableOfContents.tsx @@ -33,7 +33,11 @@ const TableOfContents: FunctionalComponent<{ headers: any[] }> = ({ headers = [] {headers .filter(({ depth }) => depth > 1 && depth < 4) .map((header) => ( - <li class={`header-link depth-${header.depth} ${activeId === header.slug ? 'active' : ''}`.trim()}> + <li + class={`header-link depth-${header.depth} ${ + activeId === header.slug ? 'active' : '' + }`.trim()} + > <a href={`#${header.slug}`}>{header.text}</a> </li> ))} diff --git a/examples/docs/src/components/RightSidebar/ThemeToggleButton.tsx b/examples/docs/src/components/RightSidebar/ThemeToggleButton.tsx index 6bdf45f02..a3f31288d 100644 --- a/examples/docs/src/components/RightSidebar/ThemeToggleButton.tsx +++ b/examples/docs/src/components/RightSidebar/ThemeToggleButton.tsx @@ -6,14 +6,26 @@ import './ThemeToggleButton.css'; const themes = ['light', 'dark']; const icons = [ - <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="currentColor"> + <svg + xmlns="http://www.w3.org/2000/svg" + width="20" + height="20" + viewBox="0 0 20 20" + fill="currentColor" + > <path fillRule="evenodd" d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" clipRule="evenodd" /> </svg>, - <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20" fill="currentColor"> + <svg + xmlns="http://www.w3.org/2000/svg" + width="20" + height="20" + viewBox="0 0 20 20" + fill="currentColor" + > <path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" /> </svg>, ]; diff --git a/examples/docs/src/config.ts b/examples/docs/src/config.ts index 174765d27..537723f43 100644 --- a/examples/docs/src/config.ts +++ b/examples/docs/src/config.ts @@ -7,7 +7,9 @@ export const SITE = { export const OPEN_GRAPH = { image: { src: 'https://github.com/withastro/astro/blob/main/assets/social/banner.jpg?raw=true', - alt: 'astro logo on a starry expanse of space,' + ' with a purple saturn-like planet floating in the right foreground', + alt: + 'astro logo on a starry expanse of space,' + + ' with a purple saturn-like planet floating in the right foreground', }, twitter: 'astrodotbuild', }; diff --git a/examples/docs/src/styles/theme.css b/examples/docs/src/styles/theme.css index 830bed8dd..1dad9dc70 100644 --- a/examples/docs/src/styles/theme.css +++ b/examples/docs/src/styles/theme.css @@ -1,8 +1,10 @@ :root { - --font-fallback: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji; + --font-fallback: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, + Apple Color Emoji, Segoe UI Emoji; --font-body: system-ui, var(--font-fallback); - --font-mono: 'IBM Plex Mono', Consolas, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', - 'Liberation Mono', 'Nimbus Mono L', Monaco, 'Courier New', Courier, monospace; + --font-mono: 'IBM Plex Mono', Consolas, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', + 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', + 'Nimbus Mono L', Monaco, 'Courier New', Courier, monospace; /* * Variables with --color-base prefix define diff --git a/examples/portfolio/src/components/Nav/index.jsx b/examples/portfolio/src/components/Nav/index.jsx index d74961d6d..b7cd28f36 100644 --- a/examples/portfolio/src/components/Nav/index.jsx +++ b/examples/portfolio/src/components/Nav/index.jsx @@ -24,7 +24,13 @@ function Nav() { </svg> </a> <a className={Styles.social} href="https://dev.to/me"> - <svg className={Styles.socialicon} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 40" style="enable-background:new 0 0 50 40" xmlSpace="preserve"> + <svg + className={Styles.socialicon} + xmlns="http://www.w3.org/2000/svg" + viewBox="0 0 50 40" + style="enable-background:new 0 0 50 40" + xmlSpace="preserve" + > <path d="M15.7 15.5c-.4-.3-.7-.4-1.1-.4h-1.7v10.1h1.7c.4 0 .8-.1 1.1-.4.4-.3.6-.7.6-1.3v-6.7c0-.6-.2-1-.6-1.3z" /> <path d="M47 0H3C1.3 0 0 1.3 0 3v34c0 1.7 1.3 3 3 3h44c1.7 0 3-1.3 3-3V3c0-1.7-1.3-3-3-3zM19.1 23.5c0 1.3-.4 2.4-1.3 3.2-.8.9-1.9 1.3-3.3 1.3h-4.4V12.3h4.5c1.3 0 2.4.4 3.2 1.3.8.8 1.3 1.9 1.3 3.2v6.7zm9.1-8.4h-5.1v3.6h3.1v2.8h-3.1v3.7h5.1V28h-5.9c-.6 0-1-.2-1.4-.6-.4-.4-.6-.8-.6-1.4V14.2c0-.6.2-1 .6-1.4.4-.4.8-.6 1.4-.6h5.9v2.9zM37.5 26c-.6 1.3-1.3 2-2.2 2-.9 0-1.7-.7-2.2-2l-3.7-13.8h3.1L35.3 23l2.8-10.8h3.1L37.5 26z" /> </svg> diff --git a/examples/ssr/src/api.ts b/examples/ssr/src/api.ts index 82c82a190..939130506 100644 --- a/examples/ssr/src/api.ts +++ b/examples/ssr/src/api.ts @@ -21,7 +21,11 @@ function getOrigin(request: Request): string { return new URL(request.url).origin.replace('localhost', '127.0.0.1'); } -async function get<T>(incomingReq: Request, endpoint: string, cb: (response: Response) => Promise<T>): Promise<T> { +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', }); diff --git a/examples/starter/src/styles/global.css b/examples/starter/src/styles/global.css index a9f830eda..8ef8122cb 100644 --- a/examples/starter/src/styles/global.css +++ b/examples/starter/src/styles/global.css @@ -4,7 +4,8 @@ } :root { - font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, + Apple Color Emoji, Segoe UI Emoji; font-size: 1rem; --user-font-scale: 1rem - 16px; font-size: clamp(0.875rem, 0.4626rem + 1.0309vw + var(--user-font-scale), 1.125rem); diff --git a/examples/starter/src/styles/home.css b/examples/starter/src/styles/home.css index b3cbd02d0..147f95776 100644 --- a/examples/starter/src/styles/home.css +++ b/examples/starter/src/styles/home.css @@ -1,6 +1,7 @@ :root { - --font-mono: Consolas, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', - 'Nimbus Mono L', Monaco, 'Courier New', Courier, monospace; + --font-mono: Consolas, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', 'Lucida Sans Typewriter', + 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', 'Nimbus Mono L', Monaco, + 'Courier New', Courier, monospace; --color-light: #f3f4f6; } diff --git a/examples/with-markdown-plugins/astro.config.mjs b/examples/with-markdown-plugins/astro.config.mjs index 114cbbd0a..4872caac7 100644 --- a/examples/with-markdown-plugins/astro.config.mjs +++ b/examples/with-markdown-plugins/astro.config.mjs @@ -6,6 +6,11 @@ export default defineConfig({ // Enable Custom Markdown options, plugins, etc. markdown: { remarkPlugins: ['remark-code-titles'], - rehypePlugins: [['rehype-autolink-headings', { behavior: 'prepend' }], ['rehype-toc', { headings: ['h2', 'h3'] }], [addClasses, { 'h1,h2,h3': 'title' }], 'rehype-slug'], + rehypePlugins: [ + ['rehype-autolink-headings', { behavior: 'prepend' }], + ['rehype-toc', { headings: ['h2', 'h3'] }], + [addClasses, { 'h1,h2,h3': 'title' }], + 'rehype-slug', + ], }, }); diff --git a/examples/with-nanostores/src/styles/global.css b/examples/with-nanostores/src/styles/global.css index a9f830eda..8ef8122cb 100644 --- a/examples/with-nanostores/src/styles/global.css +++ b/examples/with-nanostores/src/styles/global.css @@ -4,7 +4,8 @@ } :root { - font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, + Apple Color Emoji, Segoe UI Emoji; font-size: 1rem; --user-font-scale: 1rem - 16px; font-size: clamp(0.875rem, 0.4626rem + 1.0309vw + var(--user-font-scale), 1.125rem); diff --git a/examples/with-nanostores/src/styles/home.css b/examples/with-nanostores/src/styles/home.css index 5770429d1..c2f50cb19 100644 --- a/examples/with-nanostores/src/styles/home.css +++ b/examples/with-nanostores/src/styles/home.css @@ -1,6 +1,7 @@ :root { - --font-mono: Consolas, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', 'Lucida Sans Typewriter', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', - 'Nimbus Mono L', Monaco, 'Courier New', Courier, monospace; + --font-mono: Consolas, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', 'Lucida Sans Typewriter', + 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', 'Nimbus Mono L', Monaco, + 'Courier New', Courier, monospace; --color-light: #f3f4f6; } diff --git a/packages/astro-prism/internal.mjs b/packages/astro-prism/internal.mjs index 0a118ba1b..22a5f9d48 100644 --- a/packages/astro-prism/internal.mjs +++ b/packages/astro-prism/internal.mjs @@ -8,7 +8,9 @@ export function addAstro(Prism) { scriptLang = 'typescript'; } else { scriptLang = 'javascript'; - console.warn('Prism TypeScript language not loaded, Astro scripts will be treated as JavaScript.'); + console.warn( + 'Prism TypeScript language not loaded, Astro scripts will be treated as JavaScript.' + ); } let script = Prism.util.clone(Prism.languages[scriptLang]); @@ -38,10 +40,14 @@ export function addAstro(Prism) { spread = re(spread).source; Prism.languages.astro = Prism.languages.extend('markup', script); - Prism.languages.astro.tag.pattern = re(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[^]|[^\\"])*"|'(?:\\[^]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source); + Prism.languages.astro.tag.pattern = re( + /<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[^]|[^\\"])*"|'(?:\\[^]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/ + .source + ); Prism.languages.astro.tag.inside['tag'].pattern = /^<\/?[^\s>\/]*/i; - Prism.languages.astro.tag.inside['attr-value'].pattern = /=(?!\{)(?:"(?:\\[^]|[^\\"])*"|'(?:\\[^]|[^\\'])*'|[^\s'">]+)/i; + Prism.languages.astro.tag.inside['attr-value'].pattern = + /=(?!\{)(?:"(?:\\[^]|[^\\"])*"|'(?:\\[^]|[^\\'])*'|[^\s'">]+)/i; Prism.languages.astro.tag.inside['tag'].inside['class-name'] = /^[A-Z]\w*(?:\.[A-Z]\w*)*$/; Prism.languages.astro.tag.inside['comment'] = script['comment']; @@ -109,7 +115,11 @@ export function addAstro(Prism) { if (token.content[0].content[0].content === '</') { // Closing tag - if (openedTags.length > 0 && openedTags[openedTags.length - 1].tagName === stringifyToken(token.content[0].content[1])) { + if ( + openedTags.length > 0 && + openedTags[openedTags.length - 1].tagName === + stringifyToken(token.content[0].content[1]) + ) { // Pop matching opening tag openedTags.pop(); } @@ -127,7 +137,12 @@ export function addAstro(Prism) { } else if (openedTags.length > 0 && token.type === 'punctuation' && token.content === '{') { // Here we might have entered a Astro context inside a tag openedTags[openedTags.length - 1].openedBraces++; - } else if (openedTags.length > 0 && openedTags[openedTags.length - 1].openedBraces > 0 && token.type === 'punctuation' && token.content === '}') { + } else if ( + openedTags.length > 0 && + openedTags[openedTags.length - 1].openedBraces > 0 && + token.type === 'punctuation' && + token.content === '}' + ) { // Here we might have left a Astro context inside a tag openedTags[openedTags.length - 1].openedBraces--; } else { @@ -141,7 +156,10 @@ export function addAstro(Prism) { let plainText = stringifyToken(token); // And merge text with adjacent text - if (i < tokens.length - 1 && (typeof tokens[i + 1] === 'string' || tokens[i + 1].type === 'plain-text')) { + if ( + i < tokens.length - 1 && + (typeof tokens[i + 1] === 'string' || tokens[i + 1].type === 'plain-text') + ) { plainText += stringifyToken(tokens[i + 1]); tokens.splice(i + 1, 1); } diff --git a/packages/astro/astro.js b/packages/astro/astro.js index 0f458bb6d..69ea565f7 100755 --- a/packages/astro/astro.js +++ b/packages/astro/astro.js @@ -9,7 +9,8 @@ const CI_INSTRUCTIONS = { NETLIFY: 'https://docs.netlify.com/configure-builds/manage-dependencies/#node-js-and-javascript', - GITHUB_ACTIONS: 'https://docs.github.com/en/actions/guides/building-and-testing-nodejs#specifying-the-nodejs-version', + GITHUB_ACTIONS: + 'https://docs.github.com/en/actions/guides/building-and-testing-nodejs#specifying-the-nodejs-version', VERCEL: 'https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-version', }; @@ -17,7 +18,10 @@ const CI_INSTRUCTIONS = { async function main() { // Check for ESM support. // Load the "supports-esm" package in an way that works in both ESM & CJS. - let supportsESM = typeof require !== 'undefined' ? require('supports-esm') : (await import('supports-esm')).default; + let supportsESM = + typeof require !== 'undefined' + ? require('supports-esm') + : (await import('supports-esm')).default; // Check for CJS->ESM named export support. // "path-to-regexp" is a real-world package that we depend on, that only @@ -79,7 +83,9 @@ Please upgrade Node.js to a supported version: "${engines}"\n`); break; } } - console.log(`${ci.name} CI Environment Detected!\nAdditional steps may be needed to set your Node.js version:`); + console.log( + `${ci.name} CI Environment Detected!\nAdditional steps may be needed to set your Node.js version:` + ); console.log(`Documentation: https://docs.astro.build/guides/deploy`); if (CI_INSTRUCTIONS[platform]) { console.log(`${ci.name} Documentation: ${CI_INSTRUCTIONS[platform]}`); diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index e1a82c8f8..854e7e377 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -56,7 +56,10 @@ export interface AstroGlobal extends AstroGlobalPartial { /** get information about this page */ request: Request; /** see if slots are used */ - slots: Record<string, true | undefined> & { has(slotName: string): boolean; render(slotName: string, args?: any[]): Promise<string> }; + slots: Record<string, true | undefined> & { + has(slotName: string): boolean; + render(slotName: string, args?: any[]): Promise<string>; + }; } export interface AstroGlobalPartial { @@ -560,7 +563,12 @@ export interface AstroConfig extends z.output<typeof AstroConfigSchema> { }; } -export type AsyncRendererComponentFn<U> = (Component: any, props: any, children: string | undefined, metadata?: AstroComponentMetadata) => Promise<U>; +export type AsyncRendererComponentFn<U> = ( + Component: any, + props: any, + children: string | undefined, + metadata?: AstroComponentMetadata +) => Promise<U>; /** Generic interface for a component (Astro, Svelte, React, etc.) */ export interface ComponentInstance { @@ -578,7 +586,9 @@ export interface MarkdownInstance<T extends Record<string, any>> { getHeaders(): Promise<{ depth: number; slug: string; text: string }[]>; } -export type GetHydrateCallback = () => Promise<(element: Element, innerHTML: string | null) => void>; +export type GetHydrateCallback = () => Promise< + (element: Element, innerHTML: string | null) => void +>; /** * getStaticPaths() options @@ -606,14 +616,20 @@ export interface JSXTransformConfig { plugins?: babel.PluginItem[]; } -export type JSXTransformFn = (options: { mode: string; ssr: boolean }) => Promise<JSXTransformConfig>; +export type JSXTransformFn = (options: { + mode: string; + ssr: boolean; +}) => Promise<JSXTransformConfig>; export interface ManifestData { routes: RouteData[]; } export type MarkdownRenderOptions = [string | MarkdownParser, Record<string, any>]; -export type MarkdownParser = (contents: string, options?: Record<string, any>) => MarkdownParserResponse | PromiseLike<MarkdownParserResponse>; +export type MarkdownParser = ( + contents: string, + options?: Record<string, any> +) => MarkdownParserResponse | PromiseLike<MarkdownParserResponse>; export interface MarkdownParserResponse { frontmatter: { @@ -731,13 +747,23 @@ export interface AstroIntegration { // more generalized. Consider the SSR use-case as well. // injectElement: (stage: vite.HtmlTagDescriptor, element: string) => void; }) => void; - 'astro:config:done'?: (options: { config: AstroConfig; setAdapter: (adapter: AstroAdapter) => void }) => void | Promise<void>; + 'astro:config:done'?: (options: { + config: AstroConfig; + setAdapter: (adapter: AstroAdapter) => void; + }) => void | Promise<void>; 'astro:server:setup'?: (options: { server: vite.ViteDevServer }) => void | Promise<void>; 'astro:server:start'?: (options: { address: AddressInfo }) => void | Promise<void>; 'astro:server:done'?: () => void | Promise<void>; 'astro:build:start'?: (options: { buildConfig: BuildConfig }) => void | Promise<void>; - 'astro:build:setup'?: (options: { vite: ViteConfigWithSSR; target: 'client' | 'server' }) => void; - 'astro:build:done'?: (options: { pages: { pathname: string }[]; dir: URL; routes: RouteData[] }) => void | Promise<void>; + 'astro:build:setup'?: (options: { + vite: ViteConfigWithSSR; + target: 'client' | 'server'; + }) => void; + 'astro:build:done'?: (options: { + pages: { pathname: string }[]; + dir: URL; + routes: RouteData[]; + }) => void | Promise<void>; }; } @@ -821,7 +847,11 @@ export interface SSRResult { styles: Set<SSRElement>; scripts: Set<SSRElement>; links: Set<SSRElement>; - createAstro(Astro: AstroGlobalPartial, props: Record<string, any>, slots: Record<string, any> | null): AstroGlobal; + createAstro( + Astro: AstroGlobalPartial, + props: Record<string, any>, + slots: Record<string, any> | null + ): AstroGlobal; resolve: (s: string) => Promise<string>; _metadata: SSRMetadata; } diff --git a/packages/astro/src/cli/check.ts b/packages/astro/src/cli/check.ts index c691a33a3..bda394014 100644 --- a/packages/astro/src/cli/check.ts +++ b/packages/astro/src/cli/check.ts @@ -8,7 +8,11 @@ import * as path from 'path'; import { pathToFileURL } from 'url'; import * as fs from 'fs'; -async function openAllDocuments(workspaceUri: URL, filePathsToIgnore: string[], checker: AstroCheck) { +async function openAllDocuments( + workspaceUri: URL, + filePathsToIgnore: string[], + checker: AstroCheck +) { const files = await glob('**/*.astro', { cwd: workspaceUri.pathname, ignore: ['node_modules/**'].concat(filePathsToIgnore.map((ignore) => `${ignore}/**`)), @@ -79,7 +83,11 @@ export async function check(astroConfig: AstroConfig) { diag.diagnostics.forEach((d) => { switch (d.severity) { case DiagnosticSeverity.Error: { - console.error(`${bold(cyan(path.relative(root.pathname, diag.filePath)))}:${bold(yellow(d.range.start.line))}:${bold(yellow(d.range.start.character))} - ${d.message}`); + console.error( + `${bold(cyan(path.relative(root.pathname, diag.filePath)))}:${bold( + yellow(d.range.start.line) + )}:${bold(yellow(d.range.start.character))} - ${d.message}` + ); let startOffset = offsetAt({ line: d.range.start.line, character: 0 }, diag.text); let endOffset = offsetAt({ line: d.range.start.line + 1, character: 0 }, diag.text); let str = diag.text.substring(startOffset, endOffset - 1); diff --git a/packages/astro/src/core/add/babel.ts b/packages/astro/src/core/add/babel.ts index 8ec31cd46..0c302803d 100644 --- a/packages/astro/src/core/add/babel.ts +++ b/packages/astro/src/core/add/babel.ts @@ -14,4 +14,5 @@ export async function generate(ast: t.File) { return code; } -export const parse = (code: string) => parser.parse(code, { sourceType: 'unambiguous', plugins: ['typescript'] }); +export const parse = (code: string) => + parser.parse(code, { sourceType: 'unambiguous', plugins: ['typescript'] }); diff --git a/packages/astro/src/core/add/index.ts b/packages/astro/src/core/add/index.ts index c181d6aae..5de4cf2c2 100644 --- a/packages/astro/src/core/add/index.ts +++ b/packages/astro/src/core/add/index.ts @@ -50,7 +50,9 @@ export default async function add(names: string[], { cwd, flags, logging }: AddO configURL = await resolveConfigURL({ cwd, flags }); if (configURL?.pathname.endsWith('package.json')) { - throw new Error(`Unable to use astro add with package.json#astro configuration! Try migrating to \`astro.config.mjs\` and try again.`); + throw new Error( + `Unable to use astro add with package.json#astro configuration! Try migrating to \`astro.config.mjs\` and try again.` + ); } applyPolyfill(); @@ -102,7 +104,13 @@ export default async function add(names: string[], { cwd, flags, logging }: AddO debug('add', 'Parsed astro config'); const defineConfig = t.identifier('defineConfig'); - ensureImport(ast, t.importDeclaration([t.importSpecifier(defineConfig, defineConfig)], t.stringLiteral('astro/config'))); + ensureImport( + ast, + t.importDeclaration( + [t.importSpecifier(defineConfig, defineConfig)], + t.stringLiteral('astro/config') + ) + ); wrapDefaultExport(ast, defineConfig); debug('add', 'Astro config ensured `defineConfig`'); @@ -136,9 +144,13 @@ export default async function add(names: string[], { cwd, flags, logging }: AddO case UpdateResult.none: { const pkgURL = new URL('./package.json', configURL); if (existsSync(fileURLToPath(pkgURL))) { - const { dependencies = {}, devDependencies = {} } = await fs.readFile(fileURLToPath(pkgURL)).then((res) => JSON.parse(res.toString())); + const { dependencies = {}, devDependencies = {} } = await fs + .readFile(fileURLToPath(pkgURL)) + .then((res) => JSON.parse(res.toString())); const deps = Object.keys(Object.assign(dependencies, devDependencies)); - const missingDeps = integrations.filter((integration) => !deps.includes(integration.packageName)); + const missingDeps = integrations.filter( + (integration) => !deps.includes(integration.packageName) + ); if (missingDeps.length === 0) { info(logging, null, msg.success(`Configuration up-to-date.`)); return; @@ -156,7 +168,11 @@ export default async function add(names: string[], { cwd, flags, logging }: AddO case UpdateResult.updated: { const len = integrations.length; if (integrations.find((integration) => integration.id === 'tailwind')) { - const possibleConfigFiles = ['./tailwind.config.cjs', './tailwind.config.mjs', './tailwind.config.js'].map((p) => fileURLToPath(new URL(p, configURL))); + const possibleConfigFiles = [ + './tailwind.config.cjs', + './tailwind.config.mjs', + './tailwind.config.js', + ].map((p) => fileURLToPath(new URL(p, configURL))); let alreadyConfigured = false; for (const possibleConfigPath of possibleConfigFiles) { if (existsSync(possibleConfigPath)) { @@ -165,9 +181,19 @@ export default async function add(names: string[], { cwd, flags, logging }: AddO } } if (!alreadyConfigured) { - info(logging, null, `\n ${magenta(`Astro will generate a minimal ${bold('./tailwind.config.cjs')} file.`)}\n`); + info( + logging, + null, + `\n ${magenta( + `Astro will generate a minimal ${bold('./tailwind.config.cjs')} file.` + )}\n` + ); if (await askToContinue({ flags })) { - await fs.writeFile(fileURLToPath(new URL('./tailwind.config.cjs', configURL)), CONSTS.TAILWIND_CONFIG_STUB, { encoding: 'utf-8' }); + await fs.writeFile( + fileURLToPath(new URL('./tailwind.config.cjs', configURL)), + CONSTS.TAILWIND_CONFIG_STUB, + { encoding: 'utf-8' } + ); debug('add', `Generated default ./tailwind.config.cjs file`); } } else { @@ -175,11 +201,24 @@ export default async function add(names: string[], { cwd, flags, logging }: AddO } } const list = integrations.map((integration) => ` - ${integration.packageName}`).join('\n'); - info(logging, null, msg.success(`Added the following integration${len === 1 ? '' : 's'} to your project:\n${list}`)); + info( + logging, + null, + msg.success( + `Added the following integration${len === 1 ? '' : 's'} to your project:\n${list}` + ) + ); return; } case UpdateResult.cancelled: { - info(logging, null, msg.cancelled(`Dependencies ${bold('NOT')} installed.`, `Be sure to install them manually before continuing!`)); + info( + logging, + null, + msg.cancelled( + `Dependencies ${bold('NOT')} installed.`, + `Be sure to install them manually before continuing!` + ) + ); return; } case UpdateResult.failure: { @@ -193,7 +232,8 @@ async function parseAstroConfig(configURL: URL): Promise<t.File> { const result = parse(source); if (!result) throw new Error('Unknown error parsing astro config'); - if (result.errors.length > 0) throw new Error('Error parsing astro config: ' + JSON.stringify(result.errors)); + if (result.errors.length > 0) + throw new Error('Error parsing astro config: ' + JSON.stringify(result.errors)); return result; } @@ -217,7 +257,13 @@ Documentation: https://docs.astro.build/en/guides/integrations-guide/`; async function addIntegration(ast: t.File, integration: IntegrationInfo) { const integrationId = t.identifier(toIdent(integration.id)); - ensureImport(ast, t.importDeclaration([t.importDefaultSpecifier(integrationId)], t.stringLiteral(integration.packageName))); + ensureImport( + ast, + t.importDeclaration( + [t.importDefaultSpecifier(integrationId)], + t.stringLiteral(integration.packageName) + ) + ); visit(ast, { // eslint-disable-next-line @typescript-eslint/no-shadow @@ -241,14 +287,20 @@ async function addIntegration(ast: t.File, integration: IntegrationInfo) { const integrationCall = t.callExpression(integrationId, []); if (!integrationsProp) { - configObject.properties.push(t.objectProperty(t.identifier('integrations'), t.arrayExpression([integrationCall]))); + configObject.properties.push( + t.objectProperty(t.identifier('integrations'), t.arrayExpression([integrationCall])) + ); return; } - if (integrationsProp.value.type !== 'ArrayExpression') throw new Error('Unable to parse integrations'); + if (integrationsProp.value.type !== 'ArrayExpression') + throw new Error('Unable to parse integrations'); const existingIntegrationCall = integrationsProp.value.elements.find( - (expr) => t.isCallExpression(expr) && t.isIdentifier(expr.callee) && expr.callee.name === integrationId.name + (expr) => + t.isCallExpression(expr) && + t.isIdentifier(expr.callee) && + expr.callee.name === integrationId.name ); if (existingIntegrationCall) return; @@ -265,7 +317,17 @@ const enum UpdateResult { failure, } -async function updateAstroConfig({ configURL, ast, flags, logging }: { configURL: URL; ast: t.File; flags: yargs.Arguments; logging: LogOptions }): Promise<UpdateResult> { +async function updateAstroConfig({ + configURL, + ast, + flags, + logging, +}: { + configURL: URL; + ast: t.File; + flags: yargs.Arguments; + logging: LogOptions; +}): Promise<UpdateResult> { const input = await fs.readFile(fileURLToPath(configURL), { encoding: 'utf-8' }); let output = await generate(ast); const comment = '// https://astro.build/config'; @@ -299,9 +361,18 @@ async function updateAstroConfig({ configURL, ast, flags, logging }: { configURL diffed = diffed.replace(newContent, coloredOutput); } - const message = `\n${boxen(diffed, { margin: 0.5, padding: 0.5, borderStyle: 'round', title: configURL.pathname.split('/').pop() })}\n`; - - info(logging, null, `\n ${magenta('Astro will make the following changes to your config file:')}\n${message}`); + const message = `\n${boxen(diffed, { + margin: 0.5, + padding: 0.5, + borderStyle: 'round', + title: configURL.pathname.split('/').pop(), + })}\n`; + + info( + logging, + null, + `\n ${magenta('Astro will make the following changes to your config file:')}\n${message}` + ); if (await askToContinue({ flags })) { await fs.writeFile(fileURLToPath(configURL), output, { encoding: 'utf-8' }); @@ -318,7 +389,13 @@ interface InstallCommand { flags: string[]; dependencies: string[]; } -async function getInstallIntegrationsCommand({ integrations, cwd = process.cwd() }: { integrations: IntegrationInfo[]; cwd?: string }): Promise<InstallCommand | null> { +async function getInstallIntegrationsCommand({ + integrations, + cwd = process.cwd(), +}: { + integrations: IntegrationInfo[]; + cwd?: string; +}): Promise<InstallCommand | null> { const pm = await preferredPM(cwd); debug('add', `package manager: ${JSON.stringify(pm)}`); if (!pm) return null; @@ -359,14 +436,30 @@ async function tryToInstallIntegrations({ info(logging, null); return UpdateResult.none; } else { - const coloredOutput = `${bold(installCommand.pm)} ${installCommand.command} ${installCommand.flags.join(' ')} ${cyan(installCommand.dependencies.join(' '))}`; - const message = `\n${boxen(coloredOutput, { margin: 0.5, padding: 0.5, borderStyle: 'round' })}\n`; - info(logging, null, `\n ${magenta('Astro will run the following command:')}\n ${dim('If you skip this step, you can always run it yourself later')}\n${message}`); + const coloredOutput = `${bold(installCommand.pm)} ${ + installCommand.command + } ${installCommand.flags.join(' ')} ${cyan(installCommand.dependencies.join(' '))}`; + const message = `\n${boxen(coloredOutput, { + margin: 0.5, + padding: 0.5, + borderStyle: 'round', + })}\n`; + info( + logging, + null, + `\n ${magenta('Astro will run the following command:')}\n ${dim( + 'If you skip this step, you can always run it yourself later' + )}\n${message}` + ); if (await askToContinue({ flags })) { const spinner = ora('Installing dependencies...').start(); try { - await execa(installCommand.pm, [installCommand.command, ...installCommand.flags, ...installCommand.dependencies], { cwd }); + await execa( + installCommand.pm, + [installCommand.command, ...installCommand.flags, ...installCommand.dependencies], + { cwd } + ); spinner.succeed(); return UpdateResult.updated; } catch (err) { @@ -405,7 +498,9 @@ export async function validateIntegrations(integrations: string[]): Promise<Inte return res.json(); }); - let dependencies: IntegrationInfo['dependencies'] = [[result['name'], `^${result['version']}`]]; + let dependencies: IntegrationInfo['dependencies'] = [ + [result['name'], `^${result['version']}`], + ]; if (result['peerDependencies']) { for (const peer in result['peerDependencies']) { diff --git a/packages/astro/src/core/add/wrapper.ts b/packages/astro/src/core/add/wrapper.ts index a8f6b3bc8..c86e87698 100644 --- a/packages/astro/src/core/add/wrapper.ts +++ b/packages/astro/src/core/add/wrapper.ts @@ -4,7 +4,12 @@ export function wrapDefaultExport(ast: t.File, functionIdentifier: t.Identifier) visit(ast, { ExportDefaultDeclaration(path) { if (!t.isExpression(path.node.declaration)) return; - if (t.isCallExpression(path.node.declaration) && t.isIdentifier(path.node.declaration.callee) && path.node.declaration.callee.name === functionIdentifier.name) return; + if ( + t.isCallExpression(path.node.declaration) && + t.isIdentifier(path.node.declaration.callee) && + path.node.declaration.callee.name === functionIdentifier.name + ) + return; path.node.declaration = t.callExpression(functionIdentifier, [path.node.declaration]); }, }); diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts index ee66df9d1..2175b8e9f 100644 --- a/packages/astro/src/core/app/index.ts +++ b/packages/astro/src/core/app/index.ts @@ -1,4 +1,9 @@ -import type { ComponentInstance, EndpointHandler, ManifestData, RouteData } from '../../@types/astro'; +import type { + ComponentInstance, + EndpointHandler, + ManifestData, + RouteData, +} from '../../@types/astro'; import type { SSRManifest as Manifest, RouteInfo } from './types'; import type { LogOptions } from '../logger/core.js'; @@ -9,7 +14,10 @@ import { matchRoute } from '../routing/match.js'; import { render } from '../render/core.js'; import { call as callEndpoint } from '../endpoint/index.js'; import { RouteCache } from '../render/route-cache.js'; -import { createLinkStylesheetElementSet, createModuleScriptElementWithSrcSet } from '../render/ssr-element.js'; +import { + createLinkStylesheetElementSet, + createModuleScriptElementWithSrcSet, +} from '../render/ssr-element.js'; import { prependForwardSlash } from '../path.js'; import { createRequest } from '../request.js'; @@ -58,7 +66,11 @@ export class App { } } - async #renderPage(request: Request, routeData: RouteData, mod: ComponentInstance): Promise<Response> { + async #renderPage( + request: Request, + routeData: RouteData, + mod: ComponentInstance + ): Promise<Response> { const url = new URL(request.url); const manifest = this.#manifest; const renderers = manifest.renderers; @@ -105,7 +117,11 @@ 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, { diff --git a/packages/astro/src/core/app/types.ts b/packages/astro/src/core/app/types.ts index 0d395c776..27af8b665 100644 --- a/packages/astro/src/core/app/types.ts +++ b/packages/astro/src/core/app/types.ts @@ -1,4 +1,10 @@ -import type { RouteData, SerializedRouteData, MarkdownRenderOptions, ComponentInstance, SSRLoadedRenderer } from '../../@types/astro'; +import type { + RouteData, + SerializedRouteData, + MarkdownRenderOptions, + ComponentInstance, + SSRLoadedRenderer, +} from '../../@types/astro'; export type ComponentPath = string; @@ -28,4 +34,7 @@ export type SerializedSSRManifest = Omit<SSRManifest, 'routes'> & { routes: SerializedRouteInfo[]; }; -export type AdapterCreateExports<T = any> = (manifest: SSRManifest, args?: T) => Record<string, any>; +export type AdapterCreateExports<T = any> = ( + manifest: SSRManifest, + args?: T +) => Record<string, any>; diff --git a/packages/astro/src/core/build/common.ts b/packages/astro/src/core/build/common.ts index 32c206fd6..6b5423857 100644 --- a/packages/astro/src/core/build/common.ts +++ b/packages/astro/src/core/build/common.ts @@ -8,7 +8,11 @@ function getOutRoot(astroConfig: AstroConfig): URL { return new URL('./', astroConfig.outDir); } -export function getOutFolder(astroConfig: AstroConfig, pathname: string, routeType: RouteType): URL { +export function getOutFolder( + astroConfig: AstroConfig, + pathname: string, + routeType: RouteType +): URL { const outRoot = getOutRoot(astroConfig); // This is the root folder to write to. @@ -30,7 +34,12 @@ export function getOutFolder(astroConfig: AstroConfig, pathname: string, routeTy } } -export function getOutFile(astroConfig: AstroConfig, outFolder: URL, pathname: string, routeType: RouteType): URL { +export function getOutFile( + astroConfig: AstroConfig, + outFolder: URL, + pathname: string, + routeType: RouteType +): URL { switch (routeType) { case 'endpoint': return new URL(npath.basename(pathname), outFolder); diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index 109aa0904..909c0f65a 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -4,7 +4,12 @@ import { bgGreen, 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 { + AstroConfig, + ComponentInstance, + EndpointHandler, + SSRLoadedRenderer, +} from '../../@types/astro'; import type { BuildInternals } from '../../core/build/internal.js'; import { debug, info } from '../logger/core.js'; import { prependForwardSlash } from '../../core/path.js'; @@ -12,7 +17,10 @@ import type { RenderOptions } from '../../core/render/core'; 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 { + createLinkStylesheetElementSet, + createModuleScriptElementWithSrcSet, +} from '../render/ssr-element.js'; import { getOutputFilename, isBuildingToSSR } from '../util.js'; import { getOutFile, getOutFolder } from './common.js'; import { eachPageData, getPageDataByComponent } from './internal.js'; @@ -56,19 +64,30 @@ export function rootRelativeFacadeId(facadeId: string, astroConfig: AstroConfig) } // Determines of a Rollup chunk is an entrypoint page. -export function chunkIsPage(astroConfig: AstroConfig, output: OutputAsset | OutputChunk, internals: BuildInternals) { +export function chunkIsPage( + astroConfig: AstroConfig, + output: OutputAsset | OutputChunk, + internals: BuildInternals +) { if (output.type !== 'chunk') { return false; } const chunk = output as OutputChunk; if (chunk.facadeModuleId) { - const facadeToEntryId = prependForwardSlash(rootRelativeFacadeId(chunk.facadeModuleId, astroConfig)); + const facadeToEntryId = prependForwardSlash( + rootRelativeFacadeId(chunk.facadeModuleId, astroConfig) + ); return internals.entrySpecifierToBundleMap.has(facadeToEntryId); } return false; } -export async function generatePages(result: RollupOutput, opts: StaticBuildOptions, internals: BuildInternals, facadeIdToPageDataMap: Map<string, PageBuildData>) { +export async function generatePages( + result: RollupOutput, + opts: StaticBuildOptions, + internals: BuildInternals, + facadeIdToPageDataMap: Map<string, PageBuildData> +) { const timer = performance.now(); info(opts.logging, null, `\n${bgGreen(black(' generating static routes '))}`); @@ -101,7 +120,9 @@ async function generatePage( const pageModule = ssrEntry.pageMap.get(pageData.component); if (!pageModule) { - throw new Error(`Unable to find the module for ${pageData.component}. This is unexpected and likely a bug in Astro, please report.`); + throw new Error( + `Unable to find the module for ${pageData.component}. This is unexpected and likely a bug in Astro, please report.` + ); } const generationOptions: Readonly<GeneratePathOptions> = { @@ -141,7 +162,11 @@ function addPageName(pathname: string, opts: StaticBuildOptions): void { opts.pageNames.push(pathname.replace(/\/?$/, '/').replace(/^\//, '')); } -async function generatePath(pathname: string, opts: StaticBuildOptions, gopts: GeneratePathOptions) { +async function generatePath( + pathname: string, + opts: StaticBuildOptions, + gopts: GeneratePathOptions +) { const { astroConfig, logging, origin, routeCache } = opts; const { mod, internals, linkIds, hoistedId, pageData, renderers } = gopts; @@ -197,7 +222,9 @@ async function generatePath(pathname: string, opts: StaticBuildOptions, gopts: G request: createRequest({ url, headers: new Headers(), logging }), route: pageData.route, routeCache, - site: astroConfig.site ? new URL(astroConfig.base, astroConfig.site).toString() : astroConfig.site, + site: astroConfig.site + ? new URL(astroConfig.base, astroConfig.site).toString() + : astroConfig.site, ssr: isBuildingToSSR(opts.astroConfig), }; diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts index c206bc1ba..ae6d9ff3e 100644 --- a/packages/astro/src/core/build/index.ts +++ b/packages/astro/src/core/build/index.ts @@ -7,13 +7,25 @@ import { apply as applyPolyfill } from '../polyfill.js'; import { performance } from 'perf_hooks'; import * as vite from 'vite'; import { createVite, ViteConfigWithSSR } from '../create-vite.js'; -import { debug, info, levels, timerMessage, warn, warnIfUsingExperimentalSSR } from '../logger/core.js'; +import { + debug, + info, + levels, + timerMessage, + warn, + warnIfUsingExperimentalSSR, +} from '../logger/core.js'; import { nodeLogOptions } from '../logger/node.js'; import { createRouteManifest } from '../routing/index.js'; import { collectPagesData } from './page-data.js'; import { staticBuild } from './static-build.js'; import { RouteCache } from '../render/route-cache.js'; -import { runHookBuildDone, runHookBuildStart, runHookConfigDone, runHookConfigSetup } from '../../integrations/index.js'; +import { + runHookBuildDone, + runHookBuildStart, + runHookConfigDone, + runHookConfigSetup, +} from '../../integrations/index.js'; import { getTimeStat } from './util.js'; import { createSafeError, isBuildingToSSR } from '../util.js'; import { fixViteErrorMessage } from '../errors.js'; @@ -24,7 +36,10 @@ export interface BuildOptions { } /** `astro build` */ -export default async function build(config: AstroConfig, options: BuildOptions = { logging: nodeLogOptions }): Promise<void> { +export default async function build( + config: AstroConfig, + options: BuildOptions = { logging: nodeLogOptions } +): Promise<void> { applyPolyfill(); const builder = new AstroBuilder(config, options); await builder.run(); @@ -46,7 +61,9 @@ class AstroBuilder { this.config = config; this.logging = options.logging; this.routeCache = new RouteCache(this.logging); - this.origin = config.site ? new URL(config.site).origin : `http://localhost:${config.server.port}`; + this.origin = config.site + ? new URL(config.site).origin + : `http://localhost:${config.server.port}`; this.manifest = createRouteManifest({ config }, this.logging); this.timer = {}; } @@ -76,7 +93,13 @@ class AstroBuilder { } /** Run the build logic. build() is marked private because usage should go through ".run()" */ - private async build({ viteConfig, viteServer }: { viteConfig: ViteConfigWithSSR; viteServer: vite.ViteDevServer }) { + private async build({ + viteConfig, + viteServer, + }: { + viteConfig: ViteConfigWithSSR; + viteServer: vite.ViteDevServer; + }) { const { origin } = this; const buildConfig: BuildConfig = { client: new URL('./client/', this.config.outDir), @@ -118,7 +141,11 @@ class AstroBuilder { // 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. this.timer.buildStart = performance.now(); - info(this.logging, 'build', colors.dim(`Completed in ${getTimeStat(this.timer.init, performance.now())}.`)); + info( + this.logging, + 'build', + colors.dim(`Completed in ${getTimeStat(this.timer.init, performance.now())}.`) + ); await staticBuild({ allPages, @@ -145,11 +172,20 @@ class AstroBuilder { // 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) }); + await runHookBuildDone({ + config: this.config, + pages: pageNames, + routes: Object.values(allPages).map((pd) => pd.route), + }); if (this.logging.level && levels[this.logging.level] <= levels['info']) { const buildMode = isBuildingToSSR(this.config) ? 'ssr' : 'static'; - await this.printStats({ logging: this.logging, timeStart: this.timer.init, pageCount: pageNames.length, buildMode }); + await this.printStats({ + logging: this.logging, + timeStart: this.timer.init, + pageCount: pageNames.length, + buildMode, + }); } } @@ -165,7 +201,17 @@ class AstroBuilder { } /** Stats */ - private async printStats({ logging, timeStart, pageCount, buildMode }: { logging: LogOptions; timeStart: number; pageCount: number; buildMode: 'static' | 'ssr' }) { + private async printStats({ + logging, + timeStart, + pageCount, + buildMode, + }: { + logging: LogOptions; + timeStart: number; + pageCount: number; + buildMode: 'static' | 'ssr'; + }) { const buildTime = performance.now() - timeStart; const total = getTimeStat(timeStart, performance.now()); diff --git a/packages/astro/src/core/build/internal.ts b/packages/astro/src/core/build/internal.ts index 674a657b6..d74722b1a 100644 --- a/packages/astro/src/core/build/internal.ts +++ b/packages/astro/src/core/build/internal.ts @@ -76,13 +76,22 @@ export function createBuildInternals(): BuildInternals { }; } -export function trackPageData(internals: BuildInternals, component: string, pageData: PageBuildData, componentModuleId: string, componentURL: URL): void { +export function trackPageData( + internals: BuildInternals, + component: string, + pageData: PageBuildData, + componentModuleId: string, + componentURL: URL +): void { pageData.moduleSpecifier = componentModuleId; internals.pagesByComponent.set(component, pageData); internals.pagesByViteID.set(viteID(componentURL), pageData); } -export function* getPageDatasByChunk(internals: BuildInternals, chunk: RenderedChunk): Generator<PageBuildData, void, unknown> { +export function* getPageDatasByChunk( + internals: BuildInternals, + chunk: RenderedChunk +): Generator<PageBuildData, void, unknown> { const pagesByViteID = internals.pagesByViteID; for (const [modulePath] of Object.entries(chunk.modules)) { if (pagesByViteID.has(modulePath)) { @@ -91,14 +100,20 @@ export function* getPageDatasByChunk(internals: BuildInternals, chunk: RenderedC } } -export function getPageDataByComponent(internals: BuildInternals, component: string): PageBuildData | undefined { +export function getPageDataByComponent( + internals: BuildInternals, + component: string +): PageBuildData | undefined { if (internals.pagesByComponent.has(component)) { return internals.pagesByComponent.get(component); } return undefined; } -export function getPageDataByViteID(internals: BuildInternals, viteid: ViteID): PageBuildData | undefined { +export function getPageDataByViteID( + internals: BuildInternals, + viteid: ViteID +): PageBuildData | undefined { if (internals.pagesByViteID.has(viteid)) { return internals.pagesByViteID.get(viteid); } diff --git a/packages/astro/src/core/build/page-data.ts b/packages/astro/src/core/build/page-data.ts index 60afee834..18823c462 100644 --- a/packages/astro/src/core/build/page-data.ts +++ b/packages/astro/src/core/build/page-data.ts @@ -28,7 +28,9 @@ export interface CollectPagesDataResult { } // Examines the routes and returns a collection of information about each page. -export async function collectPagesData(opts: CollectPagesDataOptions): Promise<CollectPagesDataResult> { +export async function collectPagesData( + opts: CollectPagesDataOptions +): Promise<CollectPagesDataResult> { const { astroConfig, logging, manifest, origin, routeCache, viteServer } = opts; const assets: Record<string, string> = {}; @@ -75,7 +77,10 @@ export async function collectPagesData(opts: CollectPagesDataOptions): Promise<C clearInterval(routeCollectionLogTimeout); if (buildMode === 'static') { const html = `${route.pathname}`.replace(/\/?$/, '/index.html'); - debug('build', `├── ${colors.bold(colors.green('✔'))} ${route.component} → ${colors.yellow(html)}`); + debug( + 'build', + `├── ${colors.bold(colors.green('✔'))} ${route.component} → ${colors.yellow(html)}` + ); } else { debug('build', `├── ${colors.bold(colors.green('✔'))} ${route.component}`); } @@ -93,7 +98,12 @@ export async function collectPagesData(opts: CollectPagesDataOptions): Promise<C const result = await getStaticPathsForRoute(opts, route) .then((_result) => { const label = _result.staticPaths.length === 1 ? 'page' : 'pages'; - debug('build', `├── ${colors.bold(colors.green('✔'))} ${route.component} → ${colors.magenta(`[${_result.staticPaths.length} ${label}]`)}`); + debug( + 'build', + `├── ${colors.bold(colors.green('✔'))} ${route.component} → ${colors.magenta( + `[${_result.staticPaths.length} ${label}]` + )}` + ); return _result; }) .catch((err) => { @@ -108,7 +118,9 @@ export async function collectPagesData(opts: CollectPagesDataOptions): Promise<C if (content) { const rssFile = new URL(url.replace(/^\/?/, './'), astroConfig.outDir); if (assets[fileURLToPath(rssFile)]) { - throw new Error(`[getStaticPaths] RSS feed ${url} already exists.\nUse \`rss(data, {url: '...'})\` to choose a unique, custom URL. (${route.component})`); + throw new Error( + `[getStaticPaths] RSS feed ${url} already exists.\nUse \`rss(data, {url: '...'})\` to choose a unique, custom URL. (${route.component})` + ); } assets[fileURLToPath(rssFile)] = content; } @@ -124,7 +136,9 @@ export async function collectPagesData(opts: CollectPagesDataOptions): Promise<C assets[fileURLToPath(stylesheetFile)] = content; } } - const finalPaths = result.staticPaths.map((staticPath) => staticPath.params && route.generate(staticPath.params)).filter(Boolean); + const finalPaths = result.staticPaths + .map((staticPath) => staticPath.params && route.generate(staticPath.params)) + .filter(Boolean); allPages[route.component] = { component: route.component, route, @@ -146,7 +160,10 @@ export async function collectPagesData(opts: CollectPagesDataOptions): Promise<C return { assets, allPages }; } -async function getStaticPathsForRoute(opts: CollectPagesDataOptions, route: RouteData): Promise<RouteCacheEntry> { +async function getStaticPathsForRoute( + opts: CollectPagesDataOptions, + route: RouteData +): Promise<RouteCacheEntry> { const { astroConfig, logging, routeCache, ssr, viteServer } = opts; if (!viteServer) throw new Error(`vite.createServer() not called!`); const filePath = new URL(`./${route.component}`, astroConfig.root); diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts index 4c2a32e29..bddf4ceca 100644 --- a/packages/astro/src/core/build/static-build.ts +++ b/packages/astro/src/core/build/static-build.ts @@ -64,7 +64,9 @@ export async function staticBuild(opts: StaticBuildOptions) { // Any hydration directive like astro/client/idle.js ...metadata.hydrationDirectiveSpecifiers(), // The client path for each renderer - ...renderers.filter((renderer) => !!renderer.clientEntrypoint).map((renderer) => renderer.clientEntrypoint!), + ...renderers + .filter((renderer) => !!renderer.clientEntrypoint) + .map((renderer) => renderer.clientEntrypoint!), ]); // Add hoisted scripts @@ -149,7 +151,8 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp }), ...(viteConfig.plugins || []), // SSR needs to be last - isBuildingToSSR(opts.astroConfig) && vitePluginSSR(opts, internals, opts.astroConfig._ctx.adapter!), + isBuildingToSSR(opts.astroConfig) && + vitePluginSSR(opts, internals, opts.astroConfig._ctx.adapter!), ], publicDir: ssr ? false : viteConfig.publicDir, root: viteConfig.root, @@ -166,7 +169,11 @@ async function ssrBuild(opts: StaticBuildOptions, internals: BuildInternals, inp return await vite.build(viteBuildConfig); } -async function clientBuild(opts: StaticBuildOptions, internals: BuildInternals, input: Set<string>) { +async function clientBuild( + opts: StaticBuildOptions, + internals: BuildInternals, + input: Set<string> +) { const { astroConfig, viteConfig } = opts; const timer = performance.now(); const ssr = isBuildingToSSR(astroConfig); @@ -260,7 +267,9 @@ async function copyFiles(fromFolder: URL, toFolder: URL) { async function ssrMoveAssets(opts: StaticBuildOptions) { info(opts.logging, 'build', 'Rearranging server assets...'); - const serverRoot = opts.buildConfig.staticMode ? opts.buildConfig.client : opts.buildConfig.server; + const serverRoot = opts.buildConfig.staticMode + ? opts.buildConfig.client + : opts.buildConfig.server; const clientRoot = opts.buildConfig.client; const serverAssets = new URL('./assets/', serverRoot); const clientAssets = new URL('./assets/', clientRoot); diff --git a/packages/astro/src/core/build/types.d.ts b/packages/astro/src/core/build/types.d.ts index 9bdab7582..30ea53901 100644 --- a/packages/astro/src/core/build/types.d.ts +++ b/packages/astro/src/core/build/types.d.ts @@ -1,5 +1,12 @@ import type { ComponentPreload } from '../render/dev/index'; -import type { AstroConfig, BuildConfig, ManifestData, RouteData, ComponentInstance, SSRLoadedRenderer } from '../../@types/astro'; +import type { + AstroConfig, + BuildConfig, + ManifestData, + RouteData, + ComponentInstance, + SSRLoadedRenderer, +} from '../../@types/astro'; import type { ViteConfigWithSSR } from '../../create-vite'; import type { LogOptions } from '../../logger'; import type { RouteCache } from '../../render/route-cache.js'; diff --git a/packages/astro/src/core/build/vite-plugin-hoisted-scripts.ts b/packages/astro/src/core/build/vite-plugin-hoisted-scripts.ts index 1dafef0b4..a355fb282 100644 --- a/packages/astro/src/core/build/vite-plugin-hoisted-scripts.ts +++ b/packages/astro/src/core/build/vite-plugin-hoisted-scripts.ts @@ -8,7 +8,10 @@ function virtualHoistedEntry(id: string) { return id.endsWith('.astro/hoisted.js') || id.endsWith('.md/hoisted.js'); } -export function vitePluginHoistedScripts(astroConfig: AstroConfig, internals: BuildInternals): VitePlugin { +export function vitePluginHoistedScripts( + astroConfig: AstroConfig, + internals: BuildInternals +): VitePlugin { return { name: '@astro/rollup-plugin-astro-hoisted-scripts', @@ -35,7 +38,11 @@ export function vitePluginHoistedScripts(astroConfig: AstroConfig, internals: Bu // Find all page entry points and create a map of the entry point to the hashed hoisted script. // This is used when we render so that we can add the script to the head. for (const [id, output] of Object.entries(bundle)) { - if (output.type === 'chunk' && output.facadeModuleId && virtualHoistedEntry(output.facadeModuleId)) { + if ( + output.type === 'chunk' && + output.facadeModuleId && + virtualHoistedEntry(output.facadeModuleId) + ) { const facadeId = output.facadeModuleId!; const pathname = facadeId.slice(0, facadeId.length - '/hoisted.js'.length); diff --git a/packages/astro/src/core/build/vite-plugin-ssr.ts b/packages/astro/src/core/build/vite-plugin-ssr.ts index 367341f23..c0243f717 100644 --- a/packages/astro/src/core/build/vite-plugin-ssr.ts +++ b/packages/astro/src/core/build/vite-plugin-ssr.ts @@ -15,7 +15,11 @@ export const virtualModuleId = '@astrojs-ssr-virtual-entry'; const resolvedVirtualModuleId = '\0' + virtualModuleId; const manifestReplace = '@@ASTRO_MANIFEST_REPLACE@@'; -export function vitePluginSSR(buildOpts: StaticBuildOptions, internals: BuildInternals, adapter: AstroAdapter): VitePlugin { +export function vitePluginSSR( + buildOpts: StaticBuildOptions, + internals: BuildInternals, + adapter: AstroAdapter +): VitePlugin { return { name: '@astrojs/vite-plugin-astro-ssr', enforce: 'post', @@ -91,7 +95,8 @@ function buildManifest(opts: StaticBuildOptions, internals: BuildInternals): Ser // HACK! Patch this special one. const entryModules = Object.fromEntries(internals.entrySpecifierToBundleMap.entries()); - entryModules[BEFORE_HYDRATION_SCRIPT_ID] = 'data:text/javascript;charset=utf-8,//[no before-hydration script]'; + entryModules[BEFORE_HYDRATION_SCRIPT_ID] = + 'data:text/javascript;charset=utf-8,//[no before-hydration script]'; const ssrManifest: SerializedSSRManifest = { routes, diff --git a/packages/astro/src/core/config.ts b/packages/astro/src/core/config.ts index 2549ca3d9..547e64fa8 100644 --- a/packages/astro/src/core/config.ts +++ b/packages/astro/src/core/config.ts @@ -124,7 +124,9 @@ export const AstroConfigSchema = z.object({ // preprocess (val) => (Array.isArray(val) ? val.flat(Infinity).filter(Boolean) : val), // validate - z.array(z.object({ name: z.string(), hooks: z.object({}).passthrough().default({}) })).default([]) + z + .array(z.object({ name: z.string(), hooks: z.object({}).passthrough().default({}) })) + .default([]) ), style: z .object({ @@ -168,7 +170,11 @@ export const AstroConfigSchema = z.object({ }); /** Turn raw config values into normalized values */ -export async function validateConfig(userConfig: any, root: string, cmd: string): Promise<AstroConfig> { +export async function validateConfig( + userConfig: any, + root: string, + cmd: string +): Promise<AstroConfig> { const fileProtocolRoot = pathToFileURL(root + path.sep); // Manual deprecation checks /* eslint-disable no-console */ @@ -176,8 +182,12 @@ export async function validateConfig(userConfig: any, root: string, cmd: string) console.error('Astro "renderers" are now "integrations"!'); console.error('Update your configuration and install new dependencies:'); try { - const rendererKeywords = userConfig.renderers.map((r: string) => r.replace('@astrojs/renderer-', '')); - const rendererImports = rendererKeywords.map((r: string) => ` import ${r} from '@astrojs/${r === 'solid' ? 'solid-js' : r}';`).join('\n'); + const rendererKeywords = userConfig.renderers.map((r: string) => + r.replace('@astrojs/renderer-', '') + ); + const rendererImports = rendererKeywords + .map((r: string) => ` import ${r} from '@astrojs/${r === 'solid' ? 'solid-js' : r}';`) + .join('\n'); const rendererIntegrations = rendererKeywords.map((r: string) => ` ${r}(),`).join('\n'); console.error(''); console.error(colors.dim(' // astro.config.js')); @@ -208,7 +218,9 @@ export async function validateConfig(userConfig: any, root: string, cmd: string) } } if (oldConfig) { - throw new Error(`Legacy configuration detected. Please update your configuration to the new format!\nSee https://astro.build/config for more information.`); + throw new Error( + `Legacy configuration detected. Please update your configuration to the new format!\nSee https://astro.build/config for more information.` + ); } /* eslint-enable no-console */ @@ -233,7 +245,8 @@ export async function validateConfig(userConfig: any, root: string, cmd: string) .transform((val) => new URL(appendForwardSlash(val), fileProtocolRoot)), server: z.preprocess( // preprocess - (val) => (typeof val === 'function' ? val({ command: cmd === 'dev' ? 'dev' : 'preview' }) : val), + (val) => + typeof val === 'function' ? val({ command: cmd === 'dev' ? 'dev' : 'preview' }) : val, // validate z .object({ @@ -265,7 +278,10 @@ export async function validateConfig(userConfig: any, root: string, cmd: string) _ctx: { scripts: [], renderers: [], adapter: undefined }, }; // Final-Pass Validation (perform checks that require the full config object) - if (!result.experimental?.integrations && !result.integrations.every((int) => int.name.startsWith('@astrojs/'))) { + if ( + !result.experimental?.integrations && + !result.integrations.every((int) => int.name.startsWith('@astrojs/')) + ) { throw new Error( [ `Astro integrations are still experimental.`, @@ -288,9 +304,11 @@ function resolveFlags(flags: Partial<Flags>): CLIFlags { site: typeof flags.site === 'string' ? flags.site : undefined, port: typeof flags.port === 'number' ? flags.port : undefined, config: typeof flags.config === 'string' ? flags.config : undefined, - host: typeof flags.host === 'string' || typeof flags.host === 'boolean' ? flags.host : undefined, + host: + typeof flags.host === 'string' || typeof flags.host === 'boolean' ? flags.host : undefined, experimentalSsr: typeof flags.experimentalSsr === 'boolean' ? flags.experimentalSsr : false, - experimentalIntegrations: typeof flags.experimentalIntegrations === 'boolean' ? flags.experimentalIntegrations : false, + experimentalIntegrations: + typeof flags.experimentalIntegrations === 'boolean' ? flags.experimentalIntegrations : false, drafts: typeof flags.drafts === 'boolean' ? flags.drafts : false, }; } @@ -301,15 +319,21 @@ function mergeCLIFlags(astroConfig: AstroUserConfig, flags: CLIFlags, cmd: strin astroConfig.experimental = astroConfig.experimental || {}; astroConfig.markdown = astroConfig.markdown || {}; if (typeof flags.site === 'string') astroConfig.site = flags.site; - if (typeof flags.experimentalSsr === 'boolean') astroConfig.experimental.ssr = flags.experimentalSsr; - if (typeof flags.experimentalIntegrations === 'boolean') astroConfig.experimental.integrations = flags.experimentalIntegrations; + if (typeof flags.experimentalSsr === 'boolean') + astroConfig.experimental.ssr = flags.experimentalSsr; + if (typeof flags.experimentalIntegrations === 'boolean') + astroConfig.experimental.integrations = flags.experimentalIntegrations; if (typeof flags.drafts === 'boolean') astroConfig.markdown.drafts = flags.drafts; - // @ts-expect-error astroConfig.server may be a function, but TS doesn't like attaching properties to a function. - // TODO: Come back here and refactor to remove this expected error. - if (typeof flags.port === 'number') astroConfig.server.port = flags.port; - // @ts-expect-error astroConfig.server may be a function, but TS doesn't like attaching properties to a function. - // TODO: Come back here and refactor to remove this expected error. - if (typeof flags.host === 'string' || typeof flags.host === 'boolean') astroConfig.server.host = flags.host; + if (typeof flags.port === 'number') { + // @ts-expect-error astroConfig.server may be a function, but TS doesn't like attaching properties to a function. + // TODO: Come back here and refactor to remove this expected error. + astroConfig.server.port = flags.port; + } + if (typeof flags.host === 'string' || typeof flags.host === 'boolean') { + // @ts-expect-error astroConfig.server may be a function, but TS doesn't like attaching properties to a function. + // TODO: Come back here and refactor to remove this expected error. + astroConfig.server.host = flags.host; + } return astroConfig; } @@ -325,7 +349,9 @@ interface LoadConfigOptions { * Note: currently the same as loadConfig but only returns the `filePath` * instead of the resolved config */ -export async function resolveConfigURL(configOptions: Pick<LoadConfigOptions, 'cwd' | 'flags'>): Promise<URL | undefined> { +export async function resolveConfigURL( + configOptions: Pick<LoadConfigOptions, 'cwd' | 'flags'> +): Promise<URL | undefined> { const root = configOptions.cwd ? path.resolve(configOptions.cwd) : process.cwd(); const flags = resolveFlags(configOptions.flags || {}); let userConfigPath: string | undefined; @@ -363,14 +389,23 @@ export async function loadConfig(configOptions: LoadConfigOptions): Promise<Astr } /** Attempt to resolve an Astro configuration object. Normalize, validate, and return. */ -export async function resolveConfig(userConfig: AstroUserConfig, root: string, flags: CLIFlags = {}, cmd: string): Promise<AstroConfig> { +export async function resolveConfig( + userConfig: AstroUserConfig, + root: string, + flags: CLIFlags = {}, + cmd: string +): Promise<AstroConfig> { const mergedConfig = mergeCLIFlags(userConfig, flags, cmd); const validatedConfig = await validateConfig(mergedConfig, root, cmd); return validatedConfig; } -function mergeConfigRecursively(defaults: Record<string, any>, overrides: Record<string, any>, rootPath: string) { +function mergeConfigRecursively( + defaults: Record<string, any>, + overrides: Record<string, any>, + rootPath: string +) { const merged: Record<string, any> = { ...defaults }; for (const key in overrides) { const value = overrides[key]; @@ -405,6 +440,10 @@ function mergeConfigRecursively(defaults: Record<string, any>, overrides: Record return merged; } -export function mergeConfig(defaults: Record<string, any>, overrides: Record<string, any>, isRoot = true): Record<string, any> { +export function mergeConfig( + defaults: Record<string, any>, + overrides: Record<string, any>, + isRoot = true +): Record<string, any> { return mergeConfigRecursively(defaults, overrides, isRoot ? '' : '.'); } diff --git a/packages/astro/src/core/create-vite.ts b/packages/astro/src/core/create-vite.ts index 47a79b84b..982421043 100644 --- a/packages/astro/src/core/create-vite.ts +++ b/packages/astro/src/core/create-vite.ts @@ -43,7 +43,10 @@ interface CreateViteOptions { } /** Return a common starting point for all Vite actions */ -export async function createVite(commandConfig: ViteConfigWithSSR, { astroConfig, logging, mode }: CreateViteOptions): Promise<ViteConfigWithSSR> { +export async function createVite( + commandConfig: ViteConfigWithSSR, + { astroConfig, logging, mode }: CreateViteOptions +): Promise<ViteConfigWithSSR> { // Scan for any third-party Astro packages. Vite needs these to be passed to `ssr.noExternal`. const astroPackages = await getAstroPackages(astroConfig); // Start with the Vite configuration that Astro core needs @@ -72,7 +75,10 @@ export async function createVite(commandConfig: ViteConfigWithSSR, { astroConfig envPrefix: 'PUBLIC_', server: { force: true, // force dependency rebuild (TODO: enabled only while next is unstable; eventually only call in "production" mode?) - hmr: process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'production' ? false : undefined, // disable HMR for test + hmr: + process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'production' + ? false + : undefined, // disable HMR for test // handle Vite URLs proxy: { // add proxies here @@ -127,7 +133,11 @@ async function getAstroPackages({ root }: AstroConfig): Promise<string[]> { const depPkgPath = fileURLToPath(depPkgUrl); if (!fs.existsSync(depPkgPath)) return false; - const { dependencies = {}, peerDependencies = {}, keywords = [] } = JSON.parse(fs.readFileSync(depPkgPath, 'utf-8')); + const { + dependencies = {}, + peerDependencies = {}, + keywords = [], + } = JSON.parse(fs.readFileSync(depPkgPath, 'utf-8')); // Attempt: package relies on `astro`. ✅ Definitely an Astro package if (peerDependencies.astro || dependencies.astro) return true; // Attempt: package is tagged with `astro` or `astro-component`. ✅ Likely a community package @@ -181,7 +191,10 @@ function isCommonNotAstro(dep: string): boolean { return ( COMMON_DEPENDENCIES_NOT_ASTRO.includes(dep) || COMMON_PREFIXES_NOT_ASTRO.some( - (prefix) => (prefix.startsWith('@') ? dep.startsWith(prefix) : dep.substring(dep.lastIndexOf('/') + 1).startsWith(prefix)) // check prefix omitting @scope/ + (prefix) => + prefix.startsWith('@') + ? dep.startsWith(prefix) + : dep.substring(dep.lastIndexOf('/') + 1).startsWith(prefix) // check prefix omitting @scope/ ) ); } diff --git a/packages/astro/src/core/dev/index.ts b/packages/astro/src/core/dev/index.ts index b46d1abab..a1e7e528c 100644 --- a/packages/astro/src/core/dev/index.ts +++ b/packages/astro/src/core/dev/index.ts @@ -2,7 +2,13 @@ import type { AddressInfo } from 'net'; import { performance } from 'perf_hooks'; import * as vite from 'vite'; import type { AstroConfig } from '../../@types/astro'; -import { runHookConfigDone, runHookConfigSetup, runHookServerDone, runHookServerSetup, runHookServerStart } from '../../integrations/index.js'; +import { + runHookConfigDone, + runHookConfigSetup, + runHookServerDone, + runHookServerSetup, + runHookServerStart, +} from '../../integrations/index.js'; import { createVite } from '../create-vite.js'; import { info, LogOptions, warn, warnIfUsingExperimentalSSR } from '../logger/core.js'; import { nodeLogOptions } from '../logger/node.js'; @@ -19,7 +25,10 @@ export interface DevServer { } /** `astro dev` */ -export default async function dev(config: AstroConfig, options: DevOptions = { logging: nodeLogOptions }): Promise<DevServer> { +export default async function dev( + config: AstroConfig, + options: DevOptions = { logging: nodeLogOptions } +): Promise<DevServer> { const devStart = performance.now(); applyPolyfill(); config = await runHookConfigSetup({ config, command: 'dev' }); @@ -39,7 +48,17 @@ export default async function dev(config: AstroConfig, options: DevOptions = { l const devServerAddressInfo = viteServer.httpServer!.address() as AddressInfo; const site = config.site ? new URL(config.base, config.site) : undefined; - info(options.logging, null, msg.devStart({ startupTime: performance.now() - devStart, config, devServerAddressInfo, site, https: !!viteConfig.server?.https })); + info( + options.logging, + null, + msg.devStart({ + startupTime: performance.now() - devStart, + config, + devServerAddressInfo, + site, + https: !!viteConfig.server?.https, + }) + ); const currentVersion = process.env.PACKAGE_VERSION ?? '0.0.0'; if (currentVersion.includes('-')) { diff --git a/packages/astro/src/core/endpoint/index.ts b/packages/astro/src/core/endpoint/index.ts index 8f59faad6..de51be2c4 100644 --- a/packages/astro/src/core/endpoint/index.ts +++ b/packages/astro/src/core/endpoint/index.ts @@ -3,7 +3,10 @@ import type { RenderOptions } from '../render/core'; import { renderEndpoint } from '../../runtime/server/index.js'; import { getParamsAndProps, GetParamsAndPropsError } from '../render/core.js'; -export type EndpointOptions = Pick<RenderOptions, 'logging' | 'origin' | 'request' | 'route' | 'routeCache' | 'pathname' | 'route' | 'site' | 'ssr'>; +export type EndpointOptions = Pick< + RenderOptions, + 'logging' | 'origin' | 'request' | 'route' | 'routeCache' | 'pathname' | 'route' | 'site' | 'ssr' +>; type EndpointCallResult = | { @@ -15,11 +18,16 @@ type EndpointCallResult = response: Response; }; -export async function call(mod: EndpointHandler, opts: EndpointOptions): Promise<EndpointCallResult> { +export async function call( + mod: EndpointHandler, + opts: EndpointOptions +): Promise<EndpointCallResult> { const paramsAndPropsResp = await getParamsAndProps({ ...opts, mod: mod as any }); if (paramsAndPropsResp === GetParamsAndPropsError.NoMatchingStaticPath) { - throw new Error(`[getStaticPath] route pattern matched, but no matching static path found. (${opts.pathname})`); + throw new Error( + `[getStaticPath] route pattern matched, but no matching static path found. (${opts.pathname})` + ); } const [params] = paramsAndPropsResp; diff --git a/packages/astro/src/core/logger/core.ts b/packages/astro/src/core/logger/core.ts index 0ac93e59b..834305856 100644 --- a/packages/astro/src/core/logger/core.ts +++ b/packages/astro/src/core/logger/core.ts @@ -47,7 +47,12 @@ export const levels: Record<LoggerLevel, number> = { }; /** Full logging API */ -export function log(opts: LogOptions, level: LoggerLevel, type: string | null, ...args: Array<any>) { +export function log( + opts: LogOptions, + level: LoggerLevel, + type: string | null, + ...args: Array<any> +) { const logLevel = opts.level; const dest = opts.dest; const event: LogMessage = { @@ -120,7 +125,8 @@ if (typeof process !== 'undefined') { /** Print out a timer message for debug() */ export function timerMessage(message: string, startTime: number = Date.now()) { let timeDiff = Date.now() - startTime; - let timeDisplay = timeDiff < 750 ? `${Math.round(timeDiff)}ms` : `${(timeDiff / 1000).toFixed(1)}s`; + let timeDisplay = + timeDiff < 750 ? `${Math.round(timeDiff)}ms` : `${(timeDiff / 1000).toFixed(1)}s`; return `${message} ${dim(timeDisplay)}`; } diff --git a/packages/astro/src/core/logger/node.ts b/packages/astro/src/core/logger/node.ts index f83483859..bd6fecf28 100644 --- a/packages/astro/src/core/logger/node.ts +++ b/packages/astro/src/core/logger/node.ts @@ -127,5 +127,8 @@ export const logger = { export function enableVerboseLogging() { //debugPackage.enable('*,-babel'); debug('cli', '--verbose flag enabled! Enabling: DEBUG="*,-babel"'); - debug('cli', 'Tip: Set the DEBUG env variable directly for more control. Example: "DEBUG=astro:*,vite:* astro build".'); + debug( + 'cli', + 'Tip: Set the DEBUG env variable directly for more control. Example: "DEBUG=astro:*,vite:* astro build".' + ); } diff --git a/packages/astro/src/core/messages.ts b/packages/astro/src/core/messages.ts index 248bc1823..fdec71396 100644 --- a/packages/astro/src/core/messages.ts +++ b/packages/astro/src/core/messages.ts @@ -2,7 +2,20 @@ * Dev server messages (organized here to prevent clutter) */ -import { bold, dim, red, green, underline, yellow, bgYellow, cyan, bgGreen, black, bgRed, bgWhite } from 'kleur/colors'; +import { + bold, + dim, + red, + green, + underline, + yellow, + bgYellow, + cyan, + bgGreen, + black, + bgRed, + bgWhite, +} from 'kleur/colors'; import os from 'os'; import type { AddressInfo } from 'net'; import type { AstroConfig } from '../@types/astro'; @@ -13,13 +26,23 @@ import { emoji, getLocalAddress, padMultilineString } from './util.js'; const PREFIX_PADDING = 6; /** Display */ -export function req({ url, statusCode, reqTime }: { url: string; statusCode: number; reqTime?: number }): string { +export function req({ + url, + statusCode, + reqTime, +}: { + url: string; + statusCode: number; + reqTime?: number; +}): string { let color = dim; if (statusCode >= 500) color = red; else if (statusCode >= 400) color = yellow; else if (statusCode >= 300) color = dim; else if (statusCode >= 200) color = green; - return `${bold(color(`${statusCode}`.padStart(PREFIX_PADDING)))} ${url.padStart(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 { @@ -53,17 +76,23 @@ export function devStart({ const { address: networkAddress, port } = devServerAddressInfo; const localAddress = getLocalAddress(networkAddress, config.server.host); const networkLogging = getNetworkLogging(config.server.host); - const toDisplayUrl = (hostname: string) => `${https ? 'https' : 'http'}://${hostname}:${port}${rootPath}`; + const toDisplayUrl = (hostname: string) => + `${https ? 'https' : 'http'}://${hostname}:${port}${rootPath}`; let addresses = []; if (networkLogging === 'none') { addresses = [`${localPrefix}${bold(cyan(toDisplayUrl(localAddress)))}`]; } else if (networkLogging === 'host-to-expose') { - addresses = [`${localPrefix}${bold(cyan(toDisplayUrl(localAddress)))}`, `${networkPrefix}${dim('use --host to expose')}`]; + addresses = [ + `${localPrefix}${bold(cyan(toDisplayUrl(localAddress)))}`, + `${networkPrefix}${dim('use --host to expose')}`, + ]; } else { addresses = Object.values(os.networkInterfaces()) .flatMap((networkInterface) => networkInterface ?? []) - .filter((networkInterface) => networkInterface?.address && networkInterface?.family === 'IPv4') + .filter( + (networkInterface) => networkInterface?.address && networkInterface?.family === 'IPv4' + ) .map(({ address }) => { if (address.includes('127.0.0.1')) { const displayAddress = address.replace('127.0.0.1', localAddress); @@ -76,7 +105,14 @@ export function devStart({ .sort((msg) => (msg.startsWith(localPrefix) ? -1 : 1)); } - const messages = [`${emoji('🚀 ', '')}${bgGreen(black(` astro `))} ${green(`v${version}`)} ${dim(`started in ${Math.round(startupTime)}ms`)}`, '', ...addresses, '']; + const messages = [ + `${emoji('🚀 ', '')}${bgGreen(black(` astro `))} ${green(`v${version}`)} ${dim( + `started in ${Math.round(startupTime)}ms` + )}`, + '', + ...addresses, + '', + ]; return messages.map((msg) => ` ${msg}`).join('\n'); } @@ -136,8 +172,12 @@ export function getNetworkLogging(host: string | boolean): 'none' | 'host-to-exp } 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')}`; + 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 { @@ -196,7 +236,12 @@ export function printHelp({ let message = []; if (headline) { - message.push(linebreak(), ` ${bgGreen(black(` ${commandName} `))} ${green(`v${process.env.PACKAGE_VERSION ?? ''}`)} ${headline}`); + message.push( + linebreak(), + ` ${bgGreen(black(` ${commandName} `))} ${green( + `v${process.env.PACKAGE_VERSION ?? ''}` + )} ${headline}` + ); } if (usage) { @@ -204,7 +249,11 @@ export function printHelp({ } if (commands) { - message.push(linebreak(), title('Commands'), table(commands, { padding: 28, prefix: ' astro ' })); + message.push( + linebreak(), + title('Commands'), + table(commands, { padding: 28, prefix: ' astro ' }) + ); } if (flags) { diff --git a/packages/astro/src/core/preview/index.ts b/packages/astro/src/core/preview/index.ts index b4fd2c0ea..1d68bd0f1 100644 --- a/packages/astro/src/core/preview/index.ts +++ b/packages/astro/src/core/preview/index.ts @@ -24,7 +24,10 @@ export interface PreviewServer { const HAS_FILE_EXTENSION_REGEXP = /^.*\.[^\\]+$/; /** The primary dev action */ -export default async function preview(config: AstroConfig, { logging }: PreviewOptions): Promise<PreviewServer> { +export default async function preview( + config: AstroConfig, + { logging }: PreviewOptions +): Promise<PreviewServer> { const startServerTime = performance.now(); const defaultOrigin = 'http://localhost'; const trailingSlash = config.trailingSlash; @@ -61,7 +64,10 @@ export default async function preview(config: AstroConfig, { logging }: PreviewO case hasTrailingSlash && trailingSlash == 'never' && !isRoot: sendError('Not Found (trailingSlash is set to "never")'); return; - case !hasTrailingSlash && trailingSlash == 'always' && !isRoot && !HAS_FILE_EXTENSION_REGEXP.test(pathname): + case !hasTrailingSlash && + trailingSlash == 'always' && + !isRoot && + !HAS_FILE_EXTENSION_REGEXP.test(pathname): sendError('Not Found (trailingSlash is set to "always")'); return; default: { @@ -87,7 +93,17 @@ export default async function preview(config: AstroConfig, { logging }: PreviewO httpServer = server.listen(port, host, async () => { if (!showedListenMsg) { const devServerAddressInfo = server.address() as AddressInfo; - info(logging, null, msg.devStart({ startupTime: performance.now() - timerStart, config, devServerAddressInfo, https: false, site: baseURL })); + info( + logging, + null, + msg.devStart({ + startupTime: performance.now() - timerStart, + config, + devServerAddressInfo, + https: false, + site: baseURL, + }) + ); } showedListenMsg = true; resolve(); diff --git a/packages/astro/src/core/render/core.ts b/packages/astro/src/core/render/core.ts index ca0de3ae6..1be4cb0c2 100644 --- a/packages/astro/src/core/render/core.ts +++ b/packages/astro/src/core/render/core.ts @@ -1,4 +1,13 @@ -import type { ComponentInstance, EndpointHandler, MarkdownRenderOptions, Params, Props, SSRLoadedRenderer, RouteData, SSRElement } from '../../@types/astro'; +import type { + ComponentInstance, + EndpointHandler, + MarkdownRenderOptions, + Params, + Props, + SSRLoadedRenderer, + RouteData, + SSRElement, +} from '../../@types/astro'; import type { LogOptions } from '../logger/core.js'; import { renderHead, renderPage } from '../../runtime/server/index.js'; @@ -19,7 +28,9 @@ export const enum GetParamsAndPropsError { NoMatchingStaticPath, } -export async function getParamsAndProps(opts: GetParamsAndPropsOptions): Promise<[Params, Props] | GetParamsAndPropsError> { +export async function getParamsAndProps( + opts: GetParamsAndPropsOptions +): Promise<[Params, Props] | GetParamsAndPropsError> { const { logging, mod, route, routeCache, pathname, ssr } = opts; // Handle dynamic routes let params: Params = {}; @@ -73,8 +84,26 @@ export interface RenderOptions { request: Request; } -export async function render(opts: RenderOptions): Promise<{ type: 'html'; html: string } | { type: 'response'; response: Response }> { - const { legacyBuild, links, logging, origin, markdownRender, mod, pathname, scripts, renderers, request, resolve, route, routeCache, site, ssr } = opts; +export async function render( + opts: RenderOptions +): Promise<{ type: 'html'; html: string } | { type: 'response'; response: Response }> { + const { + legacyBuild, + links, + logging, + origin, + markdownRender, + mod, + pathname, + scripts, + renderers, + request, + resolve, + route, + routeCache, + site, + ssr, + } = opts; const paramsAndPropsRes = await getParamsAndProps({ logging, @@ -86,14 +115,18 @@ export async function render(opts: RenderOptions): Promise<{ type: 'html'; html: }); if (paramsAndPropsRes === GetParamsAndPropsError.NoMatchingStaticPath) { - throw new Error(`[getStaticPath] route pattern matched, but no matching static path found. (${pathname})`); + throw new Error( + `[getStaticPath] route pattern matched, but no matching static path found. (${pathname})` + ); } const [params, pageProps] = paramsAndPropsRes; // Validate the page component before rendering the page const Component = await mod.default; - if (!Component) throw new Error(`Expected an exported Astro component but received typeof ${typeof Component}`); - if (!Component.isAstroComponentFactory) throw new Error(`Unable to SSR non-Astro component (${route?.component})`); + if (!Component) + throw new Error(`Expected an exported Astro component but received typeof ${typeof Component}`); + if (!Component.isAstroComponentFactory) + throw new Error(`Unable to SSR non-Astro component (${route?.component})`); const result = createResult({ legacyBuild, diff --git a/packages/astro/src/core/render/dev/html.ts b/packages/astro/src/core/render/dev/html.ts index d7596fb6d..243eeb295 100644 --- a/packages/astro/src/core/render/dev/html.ts +++ b/packages/astro/src/core/render/dev/html.ts @@ -98,7 +98,10 @@ function serializeTag({ tag, attrs, children }: vite.HtmlTagDescriptor, indent = if (unaryTags.has(tag)) { return `<${tag}${serializeAttrs(attrs)}>`; } else { - return `<${tag}${serializeAttrs(attrs)}>${serializeTags(children, incrementIndent(indent))}</${tag}>`; + return `<${tag}${serializeAttrs(attrs)}>${serializeTags( + children, + incrementIndent(indent) + )}</${tag}>`; } } diff --git a/packages/astro/src/core/render/dev/index.ts b/packages/astro/src/core/render/dev/index.ts index d2d3642da..39e3ad552 100644 --- a/packages/astro/src/core/render/dev/index.ts +++ b/packages/astro/src/core/render/dev/index.ts @@ -1,7 +1,15 @@ import astroRemark from '@astrojs/markdown-remark'; import { fileURLToPath } from 'url'; import type * as vite from 'vite'; -import type { AstroConfig, AstroRenderer, ComponentInstance, RouteData, RuntimeMode, SSRElement, SSRLoadedRenderer } from '../../../@types/astro'; +import type { + AstroConfig, + AstroRenderer, + ComponentInstance, + RouteData, + RuntimeMode, + SSRElement, + SSRLoadedRenderer, +} from '../../../@types/astro'; import { LogOptions } from '../../logger/core.js'; import { render as coreRender } from '../core.js'; import { prependForwardSlash } from '../../../core/path.js'; @@ -37,24 +45,38 @@ export interface SSROptions { export type ComponentPreload = [SSRLoadedRenderer[], ComponentInstance]; -export type RenderResponse = { type: 'html'; html: string } | { type: 'response'; response: Response }; +export type RenderResponse = + | { type: 'html'; html: string } + | { type: 'response'; response: Response }; const svelteStylesRE = /svelte\?svelte&type=style/; -async function loadRenderer(viteServer: vite.ViteDevServer, renderer: AstroRenderer): Promise<SSRLoadedRenderer> { +async function loadRenderer( + viteServer: vite.ViteDevServer, + renderer: AstroRenderer +): Promise<SSRLoadedRenderer> { // Vite modules can be out-of-date when using an un-resolved url // We also encountered inconsistencies when using the resolveUrl and resolveId helpers // We've found that pulling the ID directly from the urlToModuleMap is the most stable! - const id = viteServer.moduleGraph.urlToModuleMap.get(renderer.serverEntrypoint)?.id ?? renderer.serverEntrypoint; + const id = + viteServer.moduleGraph.urlToModuleMap.get(renderer.serverEntrypoint)?.id ?? + renderer.serverEntrypoint; const mod = (await viteServer.ssrLoadModule(id)) as { default: SSRLoadedRenderer['ssr'] }; return { ...renderer, ssr: mod.default }; } -export async function loadRenderers(viteServer: vite.ViteDevServer, astroConfig: AstroConfig): Promise<SSRLoadedRenderer[]> { +export async function loadRenderers( + viteServer: vite.ViteDevServer, + astroConfig: AstroConfig +): Promise<SSRLoadedRenderer[]> { return Promise.all(astroConfig._ctx.renderers.map((r) => loadRenderer(viteServer, r))); } -export async function preload({ astroConfig, filePath, viteServer }: Pick<SSROptions, 'astroConfig' | 'filePath' | 'viteServer'>): Promise<ComponentPreload> { +export async function preload({ + astroConfig, + filePath, + viteServer, +}: Pick<SSROptions, 'astroConfig' | 'filePath' | 'viteServer'>): Promise<ComponentPreload> { // Important: This needs to happen first, in case a renderer provides polyfills. const renderers = await loadRenderers(viteServer, astroConfig); // Load the module from the Vite SSR Runtime. @@ -64,13 +86,32 @@ 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, request, route, routeCache, viteServer } = ssrOpts; +export async function render( + renderers: SSRLoadedRenderer[], + mod: ComponentInstance, + ssrOpts: SSROptions +): Promise<RenderResponse> { + const { + astroConfig, + filePath, + logging, + mode, + origin, + pathname, + request, + route, + routeCache, + viteServer, + } = ssrOpts; // TODO: clean up "legacy" flag passed through helper functions const isLegacyBuild = false; // Add hoisted script tags - const scripts = createModuleScriptElementWithSrcSet(!isLegacyBuild && mod.hasOwnProperty('$$metadata') ? Array.from(mod.$$metadata.hoistedScriptPaths()) : []); + const scripts = createModuleScriptElementWithSrcSet( + !isLegacyBuild && mod.hasOwnProperty('$$metadata') + ? Array.from(mod.$$metadata.hoistedScriptPaths()) + : [] + ); // Inject HMR scripts if (mod.hasOwnProperty('$$metadata') && mode === 'development' && !isLegacyBuild) { @@ -79,7 +120,10 @@ export async function render(renderers: SSRLoadedRenderer[], mod: ComponentInsta children: '', }); scripts.add({ - props: { type: 'module', src: new URL('../../../runtime/client/hmr.js', import.meta.url).pathname }, + props: { + type: 'module', + src: new URL('../../../runtime/client/hmr.js', import.meta.url).pathname, + }, children: '', }); } @@ -203,7 +247,10 @@ export async function render(renderers: SSRLoadedRenderer[], mod: ComponentInsta }; } -export async function ssr(preloadedComponent: ComponentPreload, ssrOpts: SSROptions): Promise<RenderResponse> { +export async function ssr( + preloadedComponent: ComponentPreload, + ssrOpts: SSROptions +): Promise<RenderResponse> { 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/paginate.ts b/packages/astro/src/core/render/paginate.ts index 96d8a435a..f9da47a26 100644 --- a/packages/astro/src/core/render/paginate.ts +++ b/packages/astro/src/core/render/paginate.ts @@ -1,7 +1,17 @@ -import { GetStaticPathsResult, Page, PaginateFunction, Params, Props, RouteData } from '../../@types/astro'; +import { + GetStaticPathsResult, + Page, + PaginateFunction, + Params, + Props, + RouteData, +} from '../../@types/astro'; export function generatePaginateFunction(routeMatch: RouteData): PaginateFunction { - return function paginateUtility(data: any[], args: { pageSize?: number; params?: Params; props?: Props } = {}) { + return function paginateUtility( + data: any[], + args: { pageSize?: number; params?: Params; props?: Props } = {} + ) { let { pageSize: _pageSize, params: _params, props: _props } = args; const pageSize = _pageSize || 10; const paramName = 'page'; @@ -41,8 +51,20 @@ export function generatePaginateFunction(routeMatch: RouteData): PaginateFunctio lastPage: lastPage, url: { current: routeMatch.generate({ ...params }), - next: pageNum === lastPage ? undefined : routeMatch.generate({ ...params, page: String(pageNum + 1) }), - prev: pageNum === 1 ? undefined : routeMatch.generate({ ...params, page: !includesFirstPageNumber && pageNum - 1 === 1 ? undefined : String(pageNum - 1) }), + next: + pageNum === lastPage + ? undefined + : routeMatch.generate({ ...params, page: String(pageNum + 1) }), + prev: + pageNum === 1 + ? undefined + : routeMatch.generate({ + ...params, + page: + !includesFirstPageNumber && pageNum - 1 === 1 + ? undefined + : String(pageNum - 1), + }), }, } as Page, }, diff --git a/packages/astro/src/core/render/result.ts b/packages/astro/src/core/render/result.ts index 217044177..241807a1f 100644 --- a/packages/astro/src/core/render/result.ts +++ b/packages/astro/src/core/render/result.ts @@ -1,5 +1,14 @@ import { bold } from 'kleur/colors'; -import type { AstroGlobal, AstroGlobalPartial, MarkdownParser, MarkdownRenderOptions, Params, SSRElement, SSRLoadedRenderer, SSRResult } from '../../@types/astro'; +import type { + AstroGlobal, + AstroGlobalPartial, + MarkdownParser, + MarkdownRenderOptions, + Params, + SSRElement, + SSRLoadedRenderer, + SSRResult, +} from '../../@types/astro'; import { renderSlot } from '../../runtime/server/index.js'; import { LogOptions, warn } from '../logger/core.js'; import { createCanonicalURL, isCSSRequest } from './util.js'; @@ -45,7 +54,9 @@ class Slots { if (slots) { for (const key of Object.keys(slots)) { if ((this as any)[key] !== undefined) { - throw new Error(`Unable to create a slot named "${key}". "${key}" is a reserved slot name!\nPlease update the name of this slot.`); + throw new Error( + `Unable to create a slot named "${key}". "${key}" is a reserved slot name!\nPlease update the name of this slot.` + ); } Object.defineProperty(this, key, { get() { @@ -75,10 +86,14 @@ class Slots { const expression = getFunctionExpression(component); if (expression) { const slot = expression(...args); - return await renderSlot(this.#result, slot).then((res) => (res != null ? String(res) : res)); + return await renderSlot(this.#result, slot).then((res) => + res != null ? String(res) : res + ); } } - const content = await renderSlot(this.#result, this.#slots[name]).then((res) => (res != null ? String(res) : res)); + const content = await renderSlot(this.#result, this.#slots[name]).then((res) => + res != null ? String(res) : res + ); if (cacheable) this.#cache.set(name, content); return content; } @@ -98,7 +113,11 @@ export function createResult(args: CreateResultArgs): SSRResult { scripts: args.scripts ?? new Set<SSRElement>(), links: args.links ?? new Set<SSRElement>(), /** This function returns the `Astro` faux-global */ - createAstro(astroGlobal: AstroGlobalPartial, props: Record<string, any>, slots: Record<string, any> | null) { + createAstro( + astroGlobal: AstroGlobalPartial, + props: Record<string, any>, + slots: Record<string, any> | null + ) { const astroSlots = new Slots(result, slots); const Astro = { @@ -142,7 +161,9 @@ or consider make it a module like so: warn( args.logging, `deprecation`, - `${bold('Astro.resolve()')} is deprecated. We see that you are trying to resolve ${path}. + `${bold( + 'Astro.resolve()' + )} is deprecated. We see that you are trying to resolve ${path}. ${extra}` ); // Intentionally return an empty string so that it is not relied upon. diff --git a/packages/astro/src/core/render/route-cache.ts b/packages/astro/src/core/render/route-cache.ts index 1b60bd0db..f9ef8209d 100644 --- a/packages/astro/src/core/render/route-cache.ts +++ b/packages/astro/src/core/render/route-cache.ts @@ -1,8 +1,19 @@ -import type { ComponentInstance, GetStaticPathsItem, GetStaticPathsResult, GetStaticPathsResultKeyed, Params, RouteData, RSS } from '../../@types/astro'; +import type { + ComponentInstance, + GetStaticPathsItem, + GetStaticPathsResult, + GetStaticPathsResultKeyed, + Params, + RouteData, + RSS, +} from '../../@types/astro'; import { LogOptions, warn, debug } from '../logger/core.js'; import { generatePaginateFunction } from './paginate.js'; -import { validateGetStaticPathsModule, validateGetStaticPathsResult } from '../routing/validation.js'; +import { + validateGetStaticPathsModule, + validateGetStaticPathsResult, +} from '../routing/validation.js'; type RSSFn = (...args: any[]) => any; @@ -19,7 +30,13 @@ interface CallGetStaticPathsOptions { ssr: boolean; } -export async function callGetStaticPaths({ isValidate, logging, mod, route, ssr }: CallGetStaticPathsOptions): Promise<RouteCacheEntry> { +export async function callGetStaticPaths({ + isValidate, + logging, + mod, + route, + ssr, +}: CallGetStaticPathsOptions): Promise<RouteCacheEntry> { validateGetStaticPathsModule(mod, { ssr }); const resultInProgress = { rss: [] as RSS[], @@ -80,7 +97,11 @@ export class RouteCache { // Warn here so that an unexpected double-call of getStaticPaths() // isn't invisible and developer can track down the issue. if (this.cache[route.component]) { - warn(this.logging, 'routeCache', `Internal Warning: route cache overwritten. (${route.component})`); + warn( + this.logging, + 'routeCache', + `Internal Warning: route cache overwritten. (${route.component})` + ); } this.cache[route.component] = entry; } @@ -98,5 +119,7 @@ export function findPathItemByKey(staticPaths: GetStaticPathsResultKeyed, params } debug('findPathItemByKey', `Unexpected cache miss looking for ${paramsKey}`); - matchedStaticPath = staticPaths.find(({ params: _params }) => JSON.stringify(_params) === paramsKey); + matchedStaticPath = staticPaths.find( + ({ params: _params }) => JSON.stringify(_params) === paramsKey + ); } diff --git a/packages/astro/src/core/render/rss.ts b/packages/astro/src/core/render/rss.ts index 89c4ac40c..38a10604f 100644 --- a/packages/astro/src/core/render/rss.ts +++ b/packages/astro/src/core/render/rss.ts @@ -9,8 +9,10 @@ export function validateRSS(args: GenerateRSSArgs): void { const { rssData, srcFile } = args; if (!rssData.title) throw new Error(`[${srcFile}] rss.title required`); if (!rssData.description) throw new Error(`[${srcFile}] rss.description required`); - if ((rssData as any).item) throw new Error(`[${srcFile}] \`item: Function\` should be \`items: Item[]\``); - if (!Array.isArray(rssData.items)) throw new Error(`[${srcFile}] rss.items should be an array of items`); + if ((rssData as any).item) + throw new Error(`[${srcFile}] \`item: Function\` should be \`items: Item[]\``); + if (!Array.isArray(rssData.items)) + throw new Error(`[${srcFile}] rss.items should be an array of items`); } type GenerateRSSArgs = { site: string; rssData: RSS; srcFile: string }; @@ -19,7 +21,10 @@ type GenerateRSSArgs = { site: string; rssData: RSS; srcFile: string }; export function generateRSS(args: GenerateRSSArgs): string { validateRSS(args); const { srcFile, rssData, site } = args; - if ((rssData as any).item) throw new Error(`[${srcFile}] rss() \`item()\` function was deprecated, and is now \`items: object[]\`.`); + if ((rssData as any).item) + throw new Error( + `[${srcFile}] rss() \`item()\` function was deprecated, and is now \`items: object[]\`.` + ); let xml = `<?xml version="1.0" encoding="UTF-8"?>`; if (typeof rssData.stylesheet === 'string') { @@ -45,12 +50,27 @@ export function generateRSS(args: GenerateRSSArgs): string { for (const result of rssData.items) { xml += `<item>`; // validate - if (typeof result !== 'object') throw new Error(`[${srcFile}] rss.items expected an object. got: "${JSON.stringify(result)}"`); - if (!result.title) throw new Error(`[${srcFile}] rss.items required "title" property is missing. got: "${JSON.stringify(result)}"`); - if (!result.link) throw new Error(`[${srcFile}] rss.items required "link" property is missing. got: "${JSON.stringify(result)}"`); + if (typeof result !== 'object') + throw new Error( + `[${srcFile}] rss.items expected an object. got: "${JSON.stringify(result)}"` + ); + if (!result.title) + throw new Error( + `[${srcFile}] rss.items required "title" property is missing. got: "${JSON.stringify( + result + )}"` + ); + if (!result.link) + throw new Error( + `[${srcFile}] rss.items required "link" property is missing. got: "${JSON.stringify( + result + )}"` + ); xml += `<title><![CDATA[${result.title}]]></title>`; // If the item's link is already a valid URL, don't mess with it. - const itemLink = isValidURL(result.link) ? result.link : createCanonicalURL(result.link, site).href; + const itemLink = isValidURL(result.link) + ? result.link + : createCanonicalURL(result.link, site).href; xml += `<link>${itemLink}</link>`; xml += `<guid>${itemLink}</guid>`; if (result.description) xml += `<description><![CDATA[${result.description}]]></description>`; @@ -87,7 +107,9 @@ export function generateRSSStylesheet() { export function generateRssFunction(site: string | undefined, route: RouteData): RSSFunction { return function rssUtility(args: RSS): RSSResult { if (!site) { - throw new Error(`[${route.component}] rss() tried to generate RSS but "site" missing in astro.config.mjs`); + throw new Error( + `[${route.component}] rss() tried to generate RSS but "site" missing in astro.config.mjs` + ); } let result: RSSResult = {} as any; const { dest, ...rssData } = args; diff --git a/packages/astro/src/core/render/ssr-element.ts b/packages/astro/src/core/render/ssr-element.ts index 88c387db1..628294f44 100644 --- a/packages/astro/src/core/render/ssr-element.ts +++ b/packages/astro/src/core/render/ssr-element.ts @@ -35,6 +35,9 @@ export function createModuleScriptElementWithSrc(src: string, site?: string): SS }; } -export function createModuleScriptElementWithSrcSet(srces: string[], site?: string): Set<SSRElement> { +export function createModuleScriptElementWithSrcSet( + srces: string[], + site?: string +): Set<SSRElement> { return new Set<SSRElement>(srces.map((src) => createModuleScriptElementWithSrc(src, site))); } diff --git a/packages/astro/src/core/render/util.ts b/packages/astro/src/core/render/util.ts index 9acf2d9d3..6ef412a9c 100644 --- a/packages/astro/src/core/render/util.ts +++ b/packages/astro/src/core/render/util.ts @@ -19,7 +19,16 @@ export function isValidURL(url: string): boolean { } // https://vitejs.dev/guide/features.html#css-pre-processors -export const STYLE_EXTENSIONS = new Set(['.css', '.pcss', '.postcss', '.scss', '.sass', '.styl', '.stylus', '.less']); +export const STYLE_EXTENSIONS = new Set([ + '.css', + '.pcss', + '.postcss', + '.scss', + '.sass', + '.styl', + '.stylus', + '.less', +]); const cssRe = new RegExp( `\\.(${Array.from(STYLE_EXTENSIONS) diff --git a/packages/astro/src/core/request.ts b/packages/astro/src/core/request.ts index 8b5c40748..abccbf995 100644 --- a/packages/astro/src/core/request.ts +++ b/packages/astro/src/core/request.ts @@ -13,8 +13,17 @@ export interface CreateRequestOptions { 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>)); +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, @@ -25,7 +34,11 @@ export function createRequest({ url, headers, method = 'GET', body = undefined, Object.defineProperties(request, { canonicalURL: { get() { - warn(logging, 'deprecation', `Astro.request.canonicalURL has been moved to Astro.canonicalURL`); + warn( + logging, + 'deprecation', + `Astro.request.canonicalURL has been moved to Astro.canonicalURL` + ); return undefined; }, }, diff --git a/packages/astro/src/core/routing/manifest/create.ts b/packages/astro/src/core/routing/manifest/create.ts index 905f0ed74..ec1d6a578 100644 --- a/packages/astro/src/core/routing/manifest/create.ts +++ b/packages/astro/src/core/routing/manifest/create.ts @@ -79,7 +79,8 @@ function getPattern(segments: Part[][], addTrailingSlash: AstroConfig['trailingS }) .join(''); - const trailing = addTrailingSlash && segments.length ? getTrailingSlashPattern(addTrailingSlash) : '$'; + const trailing = + addTrailingSlash && segments.length ? getTrailingSlashPattern(addTrailingSlash) : '$'; return new RegExp(`^${pathname || '\\/'}${trailing}`); } @@ -155,7 +156,10 @@ function comparator(a: Item, b: Item) { } if (!aSubPart.dynamic && aSubPart.content !== bSubPart.content) { - return bSubPart.content.length - aSubPart.content.length || (aSubPart.content < bSubPart.content ? -1 : 1); + return ( + bSubPart.content.length - aSubPart.content.length || + (aSubPart.content < bSubPart.content ? -1 : 1) + ); } } @@ -168,7 +172,10 @@ function comparator(a: Item, b: Item) { } /** Create manifest of all static routes */ -export function createRouteManifest({ config, cwd }: { config: AstroConfig; cwd?: string }, logging: LogOptions): ManifestData { +export function createRouteManifest( + { config, cwd }: { config: AstroConfig; cwd?: string }, + logging: LogOptions +): ManifestData { const components: string[] = []; const routes: RouteData[] = []; const validPageExtensions: Set<string> = new Set(['.astro', '.md']); @@ -196,7 +203,9 @@ export function createRouteManifest({ config, cwd }: { config: AstroConfig; cwd? } const segment = isDir ? basename : name; if (/^\$/.test(segment)) { - throw new Error(`Invalid route ${file} — Astro's Collections API has been replaced by dynamic route params.`); + throw new Error( + `Invalid route ${file} — Astro's Collections API has been replaced by dynamic route params.` + ); } if (/\]\[/.test(segment)) { throw new Error(`Invalid route ${file} — parameters must be separated`); @@ -269,7 +278,9 @@ export function createRouteManifest({ config, cwd }: { config: AstroConfig; cwd? const trailingSlash = item.isPage ? config.trailingSlash : 'never'; const pattern = getPattern(segments, trailingSlash); const generate = getGenerator(segments, trailingSlash); - const pathname = segments.every((segment) => segment.length === 1 && !segment[0].dynamic) ? `/${segments.map((segment) => segment[0].content).join('/')}` : null; + const pathname = segments.every((segment) => segment.length === 1 && !segment[0].dynamic) + ? `/${segments.map((segment) => segment[0].content).join('/')}` + : null; routes.push({ type: item.isPage ? 'page' : 'endpoint', diff --git a/packages/astro/src/core/routing/manifest/serialization.ts b/packages/astro/src/core/routing/manifest/serialization.ts index 8e3a42204..e167eb374 100644 --- a/packages/astro/src/core/routing/manifest/serialization.ts +++ b/packages/astro/src/core/routing/manifest/serialization.ts @@ -1,6 +1,12 @@ import type { RouteData, SerializedRouteData } from '../../../@types/astro'; -function createRouteData(pattern: RegExp, params: string[], component: string, pathname: string | undefined, type: 'page' | 'endpoint'): RouteData { +function createRouteData( + pattern: RegExp, + params: string[], + component: string, + pathname: string | undefined, + type: 'page' | 'endpoint' +): RouteData { return { type, pattern, diff --git a/packages/astro/src/core/routing/validation.ts b/packages/astro/src/core/routing/validation.ts index 80f50e19e..a82ba58a3 100644 --- a/packages/astro/src/core/routing/validation.ts +++ b/packages/astro/src/core/routing/validation.ts @@ -12,26 +12,48 @@ export function validateGetStaticPathsModule(mod: ComponentInstance, { ssr }: Va throw new Error(`[createCollection] deprecated. Please use getStaticPaths() instead.`); } if (!mod.getStaticPaths && !ssr) { - throw new Error(`[getStaticPaths] getStaticPaths() function is required. Make sure that you \`export\` the function from your component.`); + throw new Error( + `[getStaticPaths] getStaticPaths() function is required. Make sure that you \`export\` the function from your component.` + ); } } /** Throw error for malformed getStaticPaths() response */ export function validateGetStaticPathsResult(result: GetStaticPathsResult, logging: LogOptions) { if (!Array.isArray(result)) { - throw new Error(`[getStaticPaths] invalid return value. Expected an array of path objects, but got \`${JSON.stringify(result)}\`.`); + throw new Error( + `[getStaticPaths] invalid return value. Expected an array of path objects, but got \`${JSON.stringify( + result + )}\`.` + ); } result.forEach((pathObject) => { if (!pathObject.params) { - warn(logging, 'getStaticPaths', `invalid path object. Expected an object with key \`params\`, but got \`${JSON.stringify(pathObject)}\`. Skipped.`); + warn( + logging, + 'getStaticPaths', + `invalid path object. Expected an object with key \`params\`, but got \`${JSON.stringify( + pathObject + )}\`. Skipped.` + ); return; } for (const [key, val] of Object.entries(pathObject.params)) { if (!(typeof val === 'undefined' || typeof val === 'string')) { - warn(logging, 'getStaticPaths', `invalid path param: ${key}. A string value was expected, but got \`${JSON.stringify(val)}\`.`); + warn( + logging, + 'getStaticPaths', + `invalid path param: ${key}. A string value was expected, but got \`${JSON.stringify( + val + )}\`.` + ); } if (val === '') { - warn(logging, 'getStaticPaths', `invalid path param: ${key}. \`undefined\` expected for an optional param, but got empty string.`); + warn( + logging, + 'getStaticPaths', + `invalid path param: ${key}. \`undefined\` expected for an optional param, but got empty string.` + ); } } }); diff --git a/packages/astro/src/core/util.ts b/packages/astro/src/core/util.ts index 5ac1686aa..703e01ec9 100644 --- a/packages/astro/src/core/util.ts +++ b/packages/astro/src/core/util.ts @@ -41,7 +41,9 @@ export function getOutputFilename(astroConfig: AstroConfig, name: string) { } /** is a specifier an npm package? */ -export function parseNpmName(spec: string): { scope?: string; name: string; subpath?: string } | undefined { +export function parseNpmName( + spec: string +): { scope?: string; name: string; subpath?: string } | undefined { // not an npm package if (!spec || spec[0] === '.' || spec[0] === '/') return undefined; @@ -66,7 +68,9 @@ export function parseNpmName(spec: string): { scope?: string; name: string; subp /** Coalesce any throw variable to an Error instance. */ export function createSafeError(err: any): Error { - return err instanceof Error || (err && err.name && err.message) ? err : new Error(JSON.stringify(err)); + return err instanceof Error || (err && err.name && err.message) + ? err + : new Error(JSON.stringify(err)); } /** generate code frame from esbuild error */ @@ -90,7 +94,10 @@ export function codeFrame(src: string, loc: ErrorPayload['err']['loc']): string const isFocusedLine = lineNo === loc.line - 1; output += isFocusedLine ? '> ' : ' '; output += `${lineNo + 1} | ${lines[lineNo]}\n`; - if (isFocusedLine) output += `${[...new Array(gutterWidth)].join(' ')} | ${[...new Array(loc.column)].join(' ')}^\n`; + if (isFocusedLine) + output += `${[...new Array(gutterWidth)].join(' ')} | ${[...new Array(loc.column)].join( + ' ' + )}^\n`; } return output; } diff --git a/packages/astro/src/integrations/index.ts b/packages/astro/src/integrations/index.ts index 1b0b04e39..9e96b1a5a 100644 --- a/packages/astro/src/integrations/index.ts +++ b/packages/astro/src/integrations/index.ts @@ -5,7 +5,13 @@ import { mergeConfig } from '../core/config.js'; import ssgAdapter from '../adapter-ssg/index.js'; import type { ViteConfigWithSSR } from '../core/create-vite.js'; -export async function runHookConfigSetup({ config: _config, command }: { config: AstroConfig; command: 'dev' | 'build' }): Promise<AstroConfig> { +export async function runHookConfigSetup({ + config: _config, + command, +}: { + config: AstroConfig; + command: 'dev' | 'build'; +}): Promise<AstroConfig> { if (_config.adapter) { _config.integrations.push(_config.adapter); } @@ -38,7 +44,9 @@ export async function runHookConfigDone({ config }: { config: AstroConfig }) { config, setAdapter(adapter) { if (config._ctx.adapter && config._ctx.adapter.name !== adapter.name) { - throw new Error(`Adapter already set to ${config._ctx.adapter.name}. You can only have one adapter.`); + throw new Error( + `Adapter already set to ${config._ctx.adapter.name}. You can only have one adapter.` + ); } config._ctx.adapter = adapter; }, @@ -60,7 +68,13 @@ export async function runHookConfigDone({ config }: { config: AstroConfig }) { } } -export async function runHookServerSetup({ config, server }: { config: AstroConfig; server: ViteDevServer }) { +export async function runHookServerSetup({ + config, + server, +}: { + config: AstroConfig; + server: ViteDevServer; +}) { for (const integration of config.integrations) { if (integration.hooks['astro:server:setup']) { await integration.hooks['astro:server:setup']({ server }); @@ -68,7 +82,13 @@ export async function runHookServerSetup({ config, server }: { config: AstroConf } } -export async function runHookServerStart({ config, address }: { config: AstroConfig; address: AddressInfo }) { +export async function runHookServerStart({ + config, + address, +}: { + config: AstroConfig; + address: AddressInfo; +}) { for (const integration of config.integrations) { if (integration.hooks['astro:server:start']) { await integration.hooks['astro:server:start']({ address }); @@ -84,7 +104,13 @@ export async function runHookServerDone({ config }: { config: AstroConfig }) { } } -export async function runHookBuildStart({ config, buildConfig }: { config: AstroConfig; buildConfig: BuildConfig }) { +export async function runHookBuildStart({ + config, + buildConfig, +}: { + config: AstroConfig; + buildConfig: BuildConfig; +}) { for (const integration of config.integrations) { if (integration.hooks['astro:build:start']) { await integration.hooks['astro:build:start']({ buildConfig }); @@ -92,7 +118,15 @@ export async function runHookBuildStart({ config, buildConfig }: { config: Astro } } -export async function runHookBuildSetup({ config, vite, target }: { config: AstroConfig; vite: ViteConfigWithSSR; target: 'server' | 'client' }) { +export async function runHookBuildSetup({ + config, + vite, + target, +}: { + config: AstroConfig; + vite: ViteConfigWithSSR; + target: 'server' | 'client'; +}) { for (const integration of config.integrations) { if (integration.hooks['astro:build:setup']) { await integration.hooks['astro:build:setup']({ vite, target }); @@ -100,10 +134,22 @@ export async function runHookBuildSetup({ config, vite, target }: { config: Astr } } -export async function runHookBuildDone({ config, pages, routes }: { config: AstroConfig; pages: string[]; routes: RouteData[] }) { +export async function runHookBuildDone({ + config, + pages, + routes, +}: { + config: AstroConfig; + pages: string[]; + routes: RouteData[]; +}) { for (const integration of config.integrations) { if (integration.hooks['astro:build:done']) { - await integration.hooks['astro:build:done']({ pages: pages.map((p) => ({ pathname: p })), dir: config.outDir, routes }); + await integration.hooks['astro:build:done']({ + pages: pages.map((p) => ({ pathname: p })), + dir: config.outDir, + routes, + }); } } } diff --git a/packages/astro/src/runtime/client/idle.ts b/packages/astro/src/runtime/client/idle.ts index 4d7d52245..627d896db 100644 --- a/packages/astro/src/runtime/client/idle.ts +++ b/packages/astro/src/runtime/client/idle.ts @@ -4,7 +4,11 @@ import type { GetHydrateCallback, HydrateOptions } from '../../@types/astro'; * Hydrate this component as soon as the main thread is free * (or after a short delay, if `requestIdleCallback`) isn't supported */ -export default async function onIdle(astroId: string, options: HydrateOptions, getHydrateCallback: GetHydrateCallback) { +export default async function onIdle( + astroId: string, + options: HydrateOptions, + getHydrateCallback: GetHydrateCallback +) { const cb = async () => { const roots = document.querySelectorAll(`astro-root[uid="${astroId}"]`); if (roots.length === 0) { diff --git a/packages/astro/src/runtime/client/load.ts b/packages/astro/src/runtime/client/load.ts index a9a6fcf6b..cf4cd83af 100644 --- a/packages/astro/src/runtime/client/load.ts +++ b/packages/astro/src/runtime/client/load.ts @@ -3,7 +3,11 @@ import type { GetHydrateCallback, HydrateOptions } from '../../@types/astro'; /** * Hydrate this component immediately */ -export default async function onLoad(astroId: string, options: HydrateOptions, getHydrateCallback: GetHydrateCallback) { +export default async function onLoad( + astroId: string, + options: HydrateOptions, + getHydrateCallback: GetHydrateCallback +) { const roots = document.querySelectorAll(`astro-root[uid="${astroId}"]`); if (roots.length === 0) { throw new Error(`Unable to find the root for the component ${options.name}`); diff --git a/packages/astro/src/runtime/client/media.ts b/packages/astro/src/runtime/client/media.ts index 56d67d95f..32e883908 100644 --- a/packages/astro/src/runtime/client/media.ts +++ b/packages/astro/src/runtime/client/media.ts @@ -3,7 +3,11 @@ import type { GetHydrateCallback, HydrateOptions } from '../../@types/astro'; /** * Hydrate this component when a matching media query is found */ -export default async function onMedia(astroId: string, options: HydrateOptions, getHydrateCallback: GetHydrateCallback) { +export default async function onMedia( + astroId: string, + options: HydrateOptions, + getHydrateCallback: GetHydrateCallback +) { const roots = document.querySelectorAll(`astro-root[uid="${astroId}"]`); if (roots.length === 0) { throw new Error(`Unable to find the root for the component ${options.name}`); diff --git a/packages/astro/src/runtime/client/only.ts b/packages/astro/src/runtime/client/only.ts index 472a6badd..6400d44b8 100644 --- a/packages/astro/src/runtime/client/only.ts +++ b/packages/astro/src/runtime/client/only.ts @@ -3,7 +3,11 @@ import type { GetHydrateCallback, HydrateOptions } from '../../@types/astro'; /** * Hydrate this component immediately */ -export default async function onLoad(astroId: string, options: HydrateOptions, getHydrateCallback: GetHydrateCallback) { +export default async function onLoad( + astroId: string, + options: HydrateOptions, + getHydrateCallback: GetHydrateCallback +) { const roots = document.querySelectorAll(`astro-root[uid="${astroId}"]`); if (roots.length === 0) { throw new Error(`Unable to find the root for the component ${options.name}`); diff --git a/packages/astro/src/runtime/client/visible.ts b/packages/astro/src/runtime/client/visible.ts index 1e6f7ea3c..e0c1fdc73 100644 --- a/packages/astro/src/runtime/client/visible.ts +++ b/packages/astro/src/runtime/client/visible.ts @@ -5,7 +5,11 @@ import type { GetHydrateCallback, HydrateOptions } from '../../@types/astro'; * We target the children because `astro-root` is set to `display: contents` * which doesn't work with IntersectionObserver */ -export default async function onVisible(astroId: string, options: HydrateOptions, getHydrateCallback: GetHydrateCallback) { +export default async function onVisible( + astroId: string, + options: HydrateOptions, + getHydrateCallback: GetHydrateCallback +) { const roots = document.querySelectorAll(`astro-root[uid="${astroId}"]`); if (roots.length === 0) { throw new Error(`Unable to find the root for the component ${options.name}`); diff --git a/packages/astro/src/runtime/server/hydration.ts b/packages/astro/src/runtime/server/hydration.ts index c963e42c8..e7267fe16 100644 --- a/packages/astro/src/runtime/server/hydration.ts +++ b/packages/astro/src/runtime/server/hydration.ts @@ -58,12 +58,21 @@ export function extractDirectives(inputProps: Record<string | number, any>): Ext // throw an error if an invalid hydration directive was provided if (HydrationDirectives.indexOf(extracted.hydration.directive) < 0) { - throw new Error(`Error: invalid hydration directive "${key}". Supported hydration methods: ${HydrationDirectives.map((d) => `"client:${d}"`).join(', ')}`); + throw new Error( + `Error: invalid hydration directive "${key}". Supported hydration methods: ${HydrationDirectives.map( + (d) => `"client:${d}"` + ).join(', ')}` + ); } // throw an error if the query wasn't provided for client:media - if (extracted.hydration.directive === 'media' && typeof extracted.hydration.value !== 'string') { - throw new Error('Error: Media query must be provided for "client:media", similar to client:media="(max-width: 600px)"'); + if ( + extracted.hydration.directive === 'media' && + typeof extracted.hydration.value !== 'string' + ) { + throw new Error( + 'Error: Media query must be provided for "client:media", similar to client:media="(max-width: 600px)"' + ); } break; @@ -88,20 +97,27 @@ interface HydrateScriptOptions { } /** For hydrated components, generate a <script type="module"> to load the component */ -export async function generateHydrateScript(scriptOptions: HydrateScriptOptions, metadata: Required<AstroComponentMetadata>): Promise<SSRElement> { +export async function generateHydrateScript( + scriptOptions: HydrateScriptOptions, + metadata: Required<AstroComponentMetadata> +): Promise<SSRElement> { const { renderer, result, astroId, props } = scriptOptions; const { hydrate, componentUrl, componentExport } = metadata; if (!componentExport) { - throw new Error(`Unable to resolve a componentExport for "${metadata.displayName}"! Please open an issue.`); + throw new Error( + `Unable to resolve a componentExport for "${metadata.displayName}"! Please open an issue.` + ); } let hydrationSource = ``; hydrationSource += renderer.clientEntrypoint - ? `const [{ ${componentExport.value}: Component }, { default: hydrate }] = await Promise.all([import("${await result.resolve(componentUrl)}"), import("${await result.resolve( - renderer.clientEntrypoint - )}")]); + ? `const [{ ${ + componentExport.value + }: Component }, { default: hydrate }] = await Promise.all([import("${await result.resolve( + componentUrl + )}"), import("${await result.resolve(renderer.clientEntrypoint)}")]); return (el, children) => hydrate(el)(Component, ${serializeProps(props)}, children); ` : `await import("${await result.resolve(componentUrl)}"); @@ -113,7 +129,9 @@ export async function generateHydrateScript(scriptOptions: HydrateScriptOptions, props: { type: 'module', 'data-astro-component-hydration': true }, children: `import setup from '${await result.resolve(hydrationSpecifier(hydrate))}'; ${`import '${await result.resolve('astro:scripts/before-hydration.js')}';`} -setup("${astroId}", {name:"${metadata.displayName}",${metadata.hydrateArgs ? `value: ${JSON.stringify(metadata.hydrateArgs)}` : ''}}, async () => { +setup("${astroId}", {name:"${metadata.displayName}",${ + metadata.hydrateArgs ? `value: ${JSON.stringify(metadata.hydrateArgs)}` : '' + }}, async () => { ${hydrationSource} }); `, diff --git a/packages/astro/src/runtime/server/index.ts b/packages/astro/src/runtime/server/index.ts index 271a16ffc..61ad2d0e7 100644 --- a/packages/astro/src/runtime/server/index.ts +++ b/packages/astro/src/runtime/server/index.ts @@ -1,5 +1,13 @@ import shorthash from 'shorthash'; -import type { AstroComponentMetadata, AstroGlobalPartial, EndpointHandler, Params, SSRElement, SSRLoadedRenderer, SSRResult } from '../../@types/astro'; +import type { + AstroComponentMetadata, + AstroGlobalPartial, + EndpointHandler, + Params, + SSRElement, + SSRLoadedRenderer, + SSRResult, +} from '../../@types/astro'; import { escapeHTML, HTMLString, markHTMLString } from './escape.js'; import { extractDirectives, generateHydrateScript, serializeProps } from './hydration.js'; import { serializeListValue } from './util.js'; @@ -8,7 +16,8 @@ export { markHTMLString, markHTMLString as unescapeHTML } from './escape.js'; export type { Metadata } from './metadata'; export { createMetadata } from './metadata.js'; -const voidElementNames = /^(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/i; +const voidElementNames = + /^(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/i; const htmlBooleanAttributes = /^(allowfullscreen|async|autofocus|autoplay|controls|default|defer|disabled|disablepictureinpicture|disableremoteplayback|formnovalidate|hidden|loop|nomodule|novalidate|open|playsinline|readonly|required|reversed|scoped|seamless|itemscope)$/i; const htmlEnumAttributes = /^(contenteditable|draggable|spellcheck|value)$/i; @@ -40,7 +49,10 @@ async function _render(child: any): Promise<any> { } // Add a comment explaining why each of these are needed. // Maybe create clearly named function for what this is doing. - else if (child instanceof AstroComponent || Object.prototype.toString.call(child) === '[object AstroComponent]') { + else if ( + child instanceof AstroComponent || + Object.prototype.toString.call(child) === '[object AstroComponent]' + ) { return markHTMLString(await renderAstroComponent(child)); } else { return child; @@ -76,7 +88,9 @@ export class AstroComponent { } function isAstroComponent(obj: any): obj is AstroComponent { - return typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object AstroComponent]'; + return ( + typeof obj === 'object' && Object.prototype.toString.call(obj) === '[object AstroComponent]' + ); } export async function render(htmlParts: TemplateStringsArray, ...expressions: any[]) { @@ -128,7 +142,13 @@ function formatList(values: string[]): string { return `${values.slice(0, -1).join(', ')} or ${values[values.length - 1]}`; } -export async function renderComponent(result: SSRResult, displayName: string, Component: unknown, _props: Record<string | number, any>, slots: any = {}) { +export async function renderComponent( + result: SSRResult, + displayName: string, + Component: unknown, + _props: Record<string | number, any>, + slots: any = {} +) { Component = await Component; const children = await renderSlot(result, slots?.default); @@ -145,7 +165,9 @@ export async function renderComponent(result: SSRResult, displayName: string, Co } if (Component === null && !_props['client:only']) { - throw new Error(`Unable to render ${displayName} because it is ${Component}!\nDid you forget to import the component or is it possible there is a typo?`); + throw new Error( + `Unable to render ${displayName} because it is ${Component}!\nDid you forget to import the component or is it possible there is a typo?` + ); } const { renderers } = result._metadata; @@ -162,7 +184,12 @@ export async function renderComponent(result: SSRResult, displayName: string, Co } const probableRendererNames = guessRenderers(metadata.componentUrl); - if (Array.isArray(renderers) && renderers.length === 0 && typeof Component !== 'string' && !componentIsHTMLElement(Component)) { + if ( + Array.isArray(renderers) && + renderers.length === 0 && + typeof Component !== 'string' && + !componentIsHTMLElement(Component) + ) { const message = `Unable to render ${metadata.displayName}! There are no \`integrations\` set in your \`astro.config.mjs\` file. @@ -189,7 +216,9 @@ Did you mean to add ${formatList(probableRendererNames.map((r) => '`' + r + '`') // Attempt: use explicitly passed renderer name if (metadata.hydrateArgs) { const rendererName = metadata.hydrateArgs; - renderer = renderers.filter(({ name }) => name === `@astrojs/${rendererName}` || name === rendererName)[0]; + renderer = renderers.filter( + ({ name }) => name === `@astrojs/${rendererName}` || name === rendererName + )[0]; } // Attempt: user only has a single renderer, default to that if (!renderer && renderers.length === 1) { @@ -198,7 +227,9 @@ Did you mean to add ${formatList(probableRendererNames.map((r) => '`' + r + '`') // Attempt: can we guess the renderer from the export extension? if (!renderer) { const extname = metadata.componentUrl?.split('.').pop(); - renderer = renderers.filter(({ name }) => name === `@astrojs/${extname}` || name === extname)[0]; + renderer = renderers.filter( + ({ name }) => name === `@astrojs/${extname}` || name === extname + )[0]; } } @@ -209,7 +240,9 @@ Did you mean to add ${formatList(probableRendererNames.map((r) => '`' + r + '`') throw new Error(`Unable to render ${metadata.displayName}! Using the \`client:only\` hydration strategy, Astro needs a hint to use the correct renderer. -Did you mean to pass <${metadata.displayName} client:only="${probableRendererNames.map((r) => r.replace('@astrojs/', '')).join('|')}" /> +Did you mean to pass <${metadata.displayName} client:only="${probableRendererNames + .map((r) => r.replace('@astrojs/', '')) + .join('|')}" /> `); } else if (typeof Component !== 'string') { const matchingRenderers = renderers.filter((r) => probableRendererNames.includes(r.name)); @@ -217,7 +250,9 @@ Did you mean to pass <${metadata.displayName} client:only="${probableRendererNam if (matchingRenderers.length === 0) { throw new Error(`Unable to render ${metadata.displayName}! -There ${plural ? 'are' : 'is'} ${renderers.length} renderer${plural ? 's' : ''} configured in your \`astro.config.mjs\` file, +There ${plural ? 'are' : 'is'} ${renderers.length} renderer${ + plural ? 's' : '' + } configured in your \`astro.config.mjs\` file, but ${plural ? 'none were' : 'it was not'} able to server-side render ${metadata.displayName}. Did you mean to enable ${formatList(probableRendererNames.map((r) => '`' + r + '`'))}?`); @@ -253,7 +288,9 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr if (!html && typeof Component === 'string') { html = await renderAstroComponent( await render`<${Component}${spreadAttributes(props)}${markHTMLString( - (children == null || children == '') && voidElementNames.test(Component) ? `/>` : `>${children}</${Component}>` + (children == null || children == '') && voidElementNames.test(Component) + ? `/>` + : `>${children}</${Component}>` )}` ); } @@ -263,16 +300,29 @@ If you're still stuck, please open an issue on GitHub or join us at https://astr } // Include componentExport name, componentUrl, and props in hash to dedupe identical islands - const astroId = shorthash.unique(`<!--${metadata.componentExport!.value}:${metadata.componentUrl}-->\n${html}\n${serializeProps(props)}`); + const astroId = shorthash.unique( + `<!--${metadata.componentExport!.value}:${metadata.componentUrl}-->\n${html}\n${serializeProps( + props + )}` + ); // Rather than appending this inline in the page, puts this into the `result.scripts` set that will be appended to the head. // INVESTIGATE: This will likely be a problem in streaming because the `<head>` will be gone at this point. - result.scripts.add(await generateHydrateScript({ renderer: renderer!, result, astroId, props }, metadata as Required<AstroComponentMetadata>)); + result.scripts.add( + await generateHydrateScript( + { renderer: renderer!, result, astroId, props }, + metadata as Required<AstroComponentMetadata> + ) + ); // Render a template if no fragment is provided. const needsAstroTemplate = children && !/<\/?astro-fragment\>/.test(html); const template = needsAstroTemplate ? `<template data-astro-template>${children}</template>` : ''; - return markHTMLString(`<astro-root uid="${astroId}"${needsAstroTemplate ? ' tmpl' : ''}>${html ?? ''}${template}</astro-root>`); + return markHTMLString( + `<astro-root uid="${astroId}"${needsAstroTemplate ? ' tmpl' : ''}>${ + html ?? '' + }${template}</astro-root>` + ); } /** Create the Astro.fetchContent() runtime function. */ @@ -299,7 +349,11 @@ function createAstroGlobFn() { // This is used to create the top-level Astro global; the one that you can use // Inside of getStaticPaths. -export function createAstro(filePathname: string, _site: string, projectRootStr: string): AstroGlobalPartial { +export function createAstro( + filePathname: string, + _site: string, + projectRootStr: string +): AstroGlobalPartial { const site = new URL(_site); const url = new URL(filePathname, site); const projectRoot = new URL(projectRootStr); @@ -320,7 +374,8 @@ export function createAstro(filePathname: string, _site: string, projectRootStr: }; } -const toAttributeString = (value: any, shouldEscape = true) => (shouldEscape ? String(value).replace(/&/g, '&').replace(/"/g, '"') : value); +const toAttributeString = (value: any, shouldEscape = true) => + shouldEscape ? String(value).replace(/&/g, '&').replace(/"/g, '"') : value; const STATIC_DIRECTIVES = new Set(['set:html', 'set:text']); @@ -392,7 +447,9 @@ export async function renderEndpoint(mod: EndpointHandler, request: Request, par const handler = mod[chosenMethod]; if (!handler || typeof handler !== 'function') { - throw new Error(`Endpoint handler not found! Expected an exported function for "${chosenMethod}"`); + throw new Error( + `Endpoint handler not found! Expected an exported function for "${chosenMethod}"` + ); } return await handler.call(mod, params, request); @@ -409,7 +466,12 @@ async function replaceHeadInjection(result: SSRResult, html: string): Promise<st } // Calls a component and renders it into a string of HTML -export async function renderToString(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any): Promise<string> { +export async function renderToString( + result: SSRResult, + componentFactory: AstroComponentFactory, + props: any, + children: any +): Promise<string> { const Component = await componentFactory(result, props, children); if (!isAstroComponent(Component)) { const response: Response = Component; @@ -458,7 +520,9 @@ export async function renderPage( const uniqueElements = (item: any, index: number, all: any[]) => { const props = JSON.stringify(item.props); const children = item.children; - return index === all.findIndex((i) => JSON.stringify(i.props) === props && i.children == children); + return ( + index === all.findIndex((i) => JSON.stringify(i.props) === props && i.children == children) + ); }; // Renders a page to completion by first calling the factory callback, waiting for its result, and then appending @@ -487,12 +551,19 @@ export async function renderHead(result: SSRResult): Promise<string> { }); }); if (needsHydrationStyles) { - styles.push(renderElement('style', { props: { 'astro-style': true }, children: 'astro-root, astro-fragment { display: contents; }' })); + styles.push( + renderElement('style', { + props: { 'astro-style': true }, + children: 'astro-root, astro-fragment { display: contents; }', + }) + ); } const links = Array.from(result.links) .filter(uniqueElements) .map((link) => renderElement('link', link, false)); - return markHTMLString(links.join('\n') + styles.join('\n') + scripts.join('\n') + '\n' + '<!--astro:head:injected-->'); + return markHTMLString( + links.join('\n') + styles.join('\n') + scripts.join('\n') + '\n' + '<!--astro:head:injected-->' + ); } export async function renderAstroComponent(component: InstanceType<typeof AstroComponent>) { @@ -511,7 +582,12 @@ function componentIsHTMLElement(Component: unknown) { return typeof HTMLElement !== 'undefined' && HTMLElement.isPrototypeOf(Component as object); } -export async function renderHTMLElement(result: SSRResult, constructor: typeof HTMLElement, props: any, slots: any) { +export async function renderHTMLElement( + result: SSRResult, + constructor: typeof HTMLElement, + props: any, + slots: any +) { const name = getHTMLElementName(constructor); let attrHTML = ''; @@ -520,11 +596,15 @@ export async function renderHTMLElement(result: SSRResult, constructor: typeof H attrHTML += ` ${attr}="${toAttributeString(await props[attr])}"`; } - return markHTMLString(`<${name}${attrHTML}>${await renderSlot(result, slots?.default)}</${name}>`); + return markHTMLString( + `<${name}${attrHTML}>${await renderSlot(result, slots?.default)}</${name}>` + ); } function getHTMLElementName(constructor: typeof HTMLElement) { - const definedName = (customElements as CustomElementRegistry & { getName(_constructor: typeof HTMLElement): string }).getName(constructor); + const definedName = ( + customElements as CustomElementRegistry & { getName(_constructor: typeof HTMLElement): string } + ).getName(constructor); if (definedName) return definedName; const assignedName = constructor.name @@ -535,7 +615,11 @@ function getHTMLElementName(constructor: typeof HTMLElement) { return assignedName; } -function renderElement(name: string, { props: _props, children = '' }: SSRElement, shouldEscape = true) { +function renderElement( + name: string, + { props: _props, children = '' }: SSRElement, + shouldEscape = true +) { // Do not print `hoist`, `lang`, `is:global` const { lang: _, 'data-astro-id': astroId, 'define:vars': defineVars, ...props } = _props; if (defineVars) { diff --git a/packages/astro/src/template/4xx.ts b/packages/astro/src/template/4xx.ts index 6d5c051f7..e498d7e30 100644 --- a/packages/astro/src/template/4xx.ts +++ b/packages/astro/src/template/4xx.ts @@ -15,7 +15,13 @@ interface ErrorTemplateOptions { } /** Display all errors */ -export default function template({ title, pathname, statusCode = 404, tabTitle, body }: ErrorTemplateOptions): string { +export default function template({ + title, + pathname, + statusCode = 404, + tabTitle, + body, +}: ErrorTemplateOptions): string { return `<!doctype html> <html lang="en"> <head> @@ -46,7 +52,9 @@ export default function template({ title, pathname, statusCode = 404, tabTitle, <body> <main class="center"> <svg class="astro" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M163.008 18.929c1.944 2.413 2.935 5.67 4.917 12.181l43.309 142.27a180.277 180.277 0 00-51.778-17.53l-28.198-95.29a3.67 3.67 0 00-7.042.01l-27.857 95.232a180.225 180.225 0 00-52.01 17.557l43.52-142.281c1.99-6.502 2.983-9.752 4.927-12.16a15.999 15.999 0 016.484-4.798c2.872-1.154 6.271-1.154 13.07-1.154h31.085c6.807 0 10.211 0 13.086 1.157a16.004 16.004 0 016.487 4.806z" fill="white"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M168.19 180.151c-7.139 6.105-21.39 10.268-37.804 10.268-20.147 0-37.033-6.272-41.513-14.707-1.602 4.835-1.961 10.367-1.961 13.902 0 0-1.056 17.355 11.015 29.426 0-6.268 5.081-11.349 11.349-11.349 10.743 0 10.731 9.373 10.721 16.977v.679c0 11.542 7.054 21.436 17.086 25.606a23.27 23.27 0 01-2.339-10.2c0-11.008 6.463-15.107 13.974-19.87 5.976-3.79 12.616-8.001 17.192-16.449a31.024 31.024 0 003.743-14.82c0-3.299-.513-6.479-1.463-9.463z" fill="#ff5d01"></path></svg> - <h1>${statusCode ? `<span class="statusCode">${statusCode}: </span> ` : ''}<span class="statusMessage">${title}</span></h1> + <h1>${ + statusCode ? `<span class="statusCode">${statusCode}: </span> ` : '' + }<span class="statusMessage">${title}</span></h1> ${ body || ` diff --git a/packages/astro/src/template/5xx.ts b/packages/astro/src/template/5xx.ts index ee1f17fa6..a40c3e47d 100644 --- a/packages/astro/src/template/5xx.ts +++ b/packages/astro/src/template/5xx.ts @@ -17,7 +17,14 @@ interface ErrorTemplateOptions { } /** Display all errors */ -export default function template({ title, url, message, stack, statusCode, tabTitle }: ErrorTemplateOptions): string { +export default function template({ + title, + url, + message, + stack, + statusCode, + tabTitle, +}: ErrorTemplateOptions): string { let error = url ? message.replace(url, '') : message; return `<!doctype html> <html lang="en"> @@ -60,7 +67,9 @@ export default function template({ title, url, message, stack, statusCode, tabTi <main class="wrapper"> <header> <svg class="astro" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M163.008 18.929c1.944 2.413 2.935 5.67 4.917 12.181l43.309 142.27a180.277 180.277 0 00-51.778-17.53l-28.198-95.29a3.67 3.67 0 00-7.042.01l-27.857 95.232a180.225 180.225 0 00-52.01 17.557l43.52-142.281c1.99-6.502 2.983-9.752 4.927-12.16a15.999 15.999 0 016.484-4.798c2.872-1.154 6.271-1.154 13.07-1.154h31.085c6.807 0 10.211 0 13.086 1.157a16.004 16.004 0 016.487 4.806z" fill="white"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M168.19 180.151c-7.139 6.105-21.39 10.268-37.804 10.268-20.147 0-37.033-6.272-41.513-14.707-1.602 4.835-1.961 10.367-1.961 13.902 0 0-1.056 17.355 11.015 29.426 0-6.268 5.081-11.349 11.349-11.349 10.743 0 10.731 9.373 10.721 16.977v.679c0 11.542 7.054 21.436 17.086 25.606a23.27 23.27 0 01-2.339-10.2c0-11.008 6.463-15.107 13.974-19.87 5.976-3.79 12.616-8.001 17.192-16.449a31.024 31.024 0 003.743-14.82c0-3.299-.513-6.479-1.463-9.463z" fill="#ff5d01"></path></svg> - <h1>${statusCode ? `<span class="statusCode">${statusCode}: </span> ` : ''}<span class="statusMessage">${title}</span></h1> + <h1>${ + statusCode ? `<span class="statusCode">${statusCode}: </span> ` : '' + }<span class="statusMessage">${title}</span></h1> </header> <pre>${encode(error)}</pre> ${url ? `<a target="_blank" href="${url}">${url}</a>` : ''} diff --git a/packages/astro/src/vite-plugin-astro-postprocess/index.ts b/packages/astro/src/vite-plugin-astro-postprocess/index.ts index 58bd7566d..3e53e5044 100644 --- a/packages/astro/src/vite-plugin-astro-postprocess/index.ts +++ b/packages/astro/src/vite-plugin-astro-postprocess/index.ts @@ -1,5 +1,9 @@ import { parse as babelParser } from '@babel/parser'; -import type { ArrowFunctionExpressionKind, CallExpressionKind, StringLiteralKind } from 'ast-types/gen/kinds'; +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'; @@ -58,7 +62,11 @@ export default function astro({ config }: AstroPluginOptions): Plugin { type: 'CallExpression', callee: { type: 'MemberExpression', - object: { type: 'MetaProperty', meta: { type: 'Identifier', name: 'import' }, property: { type: 'Identifier', name: 'meta' } }, + object: { + type: 'MetaProperty', + meta: { type: 'Identifier', name: 'import' }, + property: { type: 'Identifier', name: 'meta' }, + }, property: { type: 'Identifier', name: 'glob' }, computed: false, }, diff --git a/packages/astro/src/vite-plugin-astro-server/index.ts b/packages/astro/src/vite-plugin-astro-server/index.ts index 46ee6b607..dba3b861b 100644 --- a/packages/astro/src/vite-plugin-astro-server/index.ts +++ b/packages/astro/src/vite-plugin-astro-server/index.ts @@ -22,7 +22,11 @@ interface AstroPluginOptions { logging: LogOptions; } -const BAD_VITE_MIDDLEWARE = ['viteIndexHtmlMiddleware', 'vite404Middleware', 'viteSpaFallbackMiddleware']; +const BAD_VITE_MIDDLEWARE = [ + 'viteIndexHtmlMiddleware', + 'vite404Middleware', + 'viteSpaFallbackMiddleware', +]; function removeViteHttpMiddleware(server: vite.Connect.Server) { for (let i = server.stack.length - 1; i > 0; i--) { // @ts-expect-error using internals until https://github.com/vitejs/vite/pull/4640 is merged @@ -62,7 +66,11 @@ async function writeWebResponse(res: http.ServerResponse, webResponse: Response) res.end(); } -async function writeSSRResult(result: RenderResponse, res: http.ServerResponse, statusCode: 200 | 404) { +async function writeSSRResult( + result: RenderResponse, + res: http.ServerResponse, + statusCode: 200 | 404 +) { if (result.type === 'response') { const { response } = result; await writeWebResponse(res, response); @@ -73,7 +81,12 @@ async function writeSSRResult(result: RenderResponse, res: http.ServerResponse, writeHtmlResponse(res, statusCode, html); } -async function handle404Response(origin: string, config: AstroConfig, req: http.IncomingMessage, res: http.ServerResponse) { +async function handle404Response( + origin: string, + config: AstroConfig, + req: http.IncomingMessage, + res: http.ServerResponse +) { const site = config.site ? new URL(config.base, config.site) : undefined; const devRoot = site ? site.pathname : '/'; const pathname = decodeURI(new URL(origin + req.url).pathname); @@ -81,12 +94,23 @@ async function handle404Response(origin: string, config: AstroConfig, req: http. if (pathname === '/' && !pathname.startsWith(devRoot)) { html = subpathNotUsedTemplate(devRoot, pathname); } else { - html = notFoundTemplate({ statusCode: 404, title: 'Not found', tabTitle: '404: Not Found', pathname }); + html = notFoundTemplate({ + statusCode: 404, + title: 'Not found', + tabTitle: '404: Not Found', + pathname, + }); } writeHtmlResponse(res, 404, html); } -async function handle500Response(viteServer: vite.ViteDevServer, origin: string, req: http.IncomingMessage, res: http.ServerResponse, err: any) { +async function handle500Response( + viteServer: vite.ViteDevServer, + origin: string, + req: http.IncomingMessage, + res: http.ServerResponse, + err: any +) { const pathname = decodeURI(new URL(origin + req.url).pathname); const html = serverErrorTemplate({ statusCode: 500, @@ -188,12 +212,20 @@ async function handleRequest( ssr: isBuildingToSSR(config), }); if (paramsAndPropsRes === GetParamsAndPropsError.NoMatchingStaticPath) { - warn(logging, 'getStaticPaths', `Route pattern matched, but no matching static path found. (${pathname})`); + warn( + logging, + 'getStaticPaths', + `Route pattern matched, but no matching static path found. (${pathname})` + ); log404(logging, pathname); const routeCustom404 = getCustom404Route(config, manifest); if (routeCustom404) { const filePathCustom404 = new URL(`./${routeCustom404.component}`, config.root); - const preloadedCompCustom404 = await preload({ astroConfig: config, filePath: filePathCustom404, viteServer }); + const preloadedCompCustom404 = await preload({ + astroConfig: config, + filePath: filePathCustom404, + viteServer, + }); const result = await ssr(preloadedCompCustom404, { astroConfig: config, filePath: filePathCustom404, diff --git a/packages/astro/src/vite-plugin-astro/compile.ts b/packages/astro/src/vite-plugin-astro/compile.ts index 9048c4830..afa4cd637 100644 --- a/packages/astro/src/vite-plugin-astro/compile.ts +++ b/packages/astro/src/vite-plugin-astro/compile.ts @@ -34,7 +34,13 @@ function safelyReplaceImportPlaceholder(code: string) { const configCache = new WeakMap<AstroConfig, CompilationCache>(); -async function compile(config: AstroConfig, filename: string, source: string, viteTransform: TransformHook, opts: { ssr: boolean }): Promise<CompileResult> { +async function compile( + config: AstroConfig, + filename: string, + source: string, + viteTransform: TransformHook, + opts: { ssr: boolean } +): Promise<CompileResult> { const filenameURL = new URL(`file://${filename}`); const normalizedID = fileURLToPath(filenameURL); const pathname = filenameURL.pathname.substr(config.root.pathname.length - 1); @@ -51,7 +57,9 @@ async function compile(config: AstroConfig, filename: string, source: string, vi site: config.site ? new URL(config.base, config.site).toString() : undefined, sourcefile: filename, sourcemap: 'both', - internalURL: `/@fs${prependForwardSlash(viteID(new URL('../runtime/server/index.js', import.meta.url)))}`, + internalURL: `/@fs${prependForwardSlash( + viteID(new URL('../runtime/server/index.js', import.meta.url)) + )}`, // TODO: baseline flag experimentalStaticExtraction: true, preprocessStyle: async (value: string, attrs: Record<string, string>) => { @@ -59,16 +67,19 @@ async function compile(config: AstroConfig, filename: string, source: string, vi try { // In the static build, grab any @import as CSS dependencies for HMR. - value.replace(/(?:@import)\s(?:url\()?\s?["\'](.*?)["\']\s?\)?(?:[^;]*);?/gi, (match, spec) => { - rawCSSDeps.add(spec); - // If the language is CSS: prevent `@import` inlining to prevent scoping of imports. - // Otherwise: Sass, etc. need to see imports for variables, so leave in for their compiler to handle. - if (lang === '.css') { - return createImportPlaceholder(spec); - } else { - return match; + value.replace( + /(?:@import)\s(?:url\()?\s?["\'](.*?)["\']\s?\)?(?:[^;]*);?/gi, + (match, spec) => { + rawCSSDeps.add(spec); + // If the language is CSS: prevent `@import` inlining to prevent scoping of imports. + // Otherwise: Sass, etc. need to see imports for variables, so leave in for their compiler to handle. + if (lang === '.css') { + return createImportPlaceholder(spec); + } else { + return match; + } } - }); + ); const result = await transformWithVite({ value, @@ -120,7 +131,13 @@ export function invalidateCompilation(config: AstroConfig, filename: string) { } } -export async function cachedCompilation(config: AstroConfig, filename: string, source: string, viteTransform: TransformHook, opts: { ssr: boolean }): Promise<CompileResult> { +export async function cachedCompilation( + config: AstroConfig, + filename: string, + source: string, + viteTransform: TransformHook, + opts: { ssr: boolean } +): Promise<CompileResult> { let cache: CompilationCache; if (!configCache.has(config)) { cache = new Map(); diff --git a/packages/astro/src/vite-plugin-astro/hmr.ts b/packages/astro/src/vite-plugin-astro/hmr.ts index 82b31b998..433b15901 100644 --- a/packages/astro/src/vite-plugin-astro/hmr.ts +++ b/packages/astro/src/vite-plugin-astro/hmr.ts @@ -13,7 +13,10 @@ interface TrackCSSDependenciesOptions { deps: Set<string>; } -export async function trackCSSDependencies(this: RollupPluginContext, opts: TrackCSSDependenciesOptions): Promise<void> { +export async function trackCSSDependencies( + this: RollupPluginContext, + opts: TrackCSSDependenciesOptions +): Promise<void> { const { viteDevServer, filename, deps, id } = opts; // Dev, register CSS dependencies for HMR. if (viteDevServer) { diff --git a/packages/astro/src/vite-plugin-astro/index.ts b/packages/astro/src/vite-plugin-astro/index.ts index b8c82d456..d82bd2f33 100644 --- a/packages/astro/src/vite-plugin-astro/index.ts +++ b/packages/astro/src/vite-plugin-astro/index.ts @@ -105,10 +105,17 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu throw new Error(`Requests for Astro CSS must include an index.`); } - const transformResult = await cachedCompilation(config, filename, source, viteTransform, { ssr: Boolean(opts?.ssr) }); + const transformResult = await cachedCompilation(config, filename, source, viteTransform, { + ssr: Boolean(opts?.ssr), + }); // Track any CSS dependencies so that HMR is triggered when they change. - await trackCSSDependencies.call(this, { viteDevServer, id, filename, deps: transformResult.rawCSSDeps }); + await trackCSSDependencies.call(this, { + viteDevServer, + id, + filename, + deps: transformResult.rawCSSDeps, + }); const csses = transformResult.css; const code = csses[query.index]; @@ -120,7 +127,9 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu throw new Error(`Requests for hoisted scripts must include an index`); } - const transformResult = await cachedCompilation(config, filename, source, viteTransform, { ssr: Boolean(opts?.ssr) }); + const transformResult = await cachedCompilation(config, filename, source, viteTransform, { + ssr: Boolean(opts?.ssr), + }); const scripts = transformResult.scripts; const hoistedScript = scripts[query.index]; @@ -139,13 +148,18 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu } return { - code: hoistedScript.type === 'inline' ? hoistedScript.code! : `import "${hoistedScript.src!}";`, + code: + hoistedScript.type === 'inline' + ? hoistedScript.code! + : `import "${hoistedScript.src!}";`, }; } } try { - const transformResult = await cachedCompilation(config, filename, source, viteTransform, { ssr: Boolean(opts?.ssr) }); + const transformResult = await cachedCompilation(config, filename, source, viteTransform, { + ssr: Boolean(opts?.ssr), + }); // Compile all TypeScript to JavaScript. // Also, catches invalid JS/TS in the compiled output before returning. @@ -182,12 +196,19 @@ export default function astro({ config, logging }: AstroPluginOptions): vite.Plu const scannedFrontmatter = FRONTMATTER_PARSE_REGEXP.exec(source); if (scannedFrontmatter) { try { - await esbuild.transform(scannedFrontmatter[1], { loader: 'ts', sourcemap: false, sourcefile: id }); + await esbuild.transform(scannedFrontmatter[1], { + loader: 'ts', + sourcemap: false, + sourcefile: id, + }); } catch (frontmatterErr: any) { // Improve the error by replacing the phrase "unexpected end of file" // with "unexpected end of frontmatter" in the esbuild error message. if (frontmatterErr && frontmatterErr.message) { - frontmatterErr.message = frontmatterErr.message.replace('end of file', 'end of frontmatter'); + frontmatterErr.message = frontmatterErr.message.replace( + 'end of file', + 'end of frontmatter' + ); } throw frontmatterErr; } diff --git a/packages/astro/src/vite-plugin-astro/styles.ts b/packages/astro/src/vite-plugin-astro/styles.ts index 85467506e..d9fb5eaf8 100644 --- a/packages/astro/src/vite-plugin-astro/styles.ts +++ b/packages/astro/src/vite-plugin-astro/styles.ts @@ -2,7 +2,11 @@ import type * as vite from 'vite'; import { STYLE_EXTENSIONS } from '../core/render/util.js'; -export type TransformHook = (code: string, id: string, ssr?: boolean) => Promise<vite.TransformResult>; +export type TransformHook = ( + code: string, + id: string, + ssr?: boolean +) => Promise<vite.TransformResult>; /** Load vite:css’ transform() hook */ export function getViteTransform(viteConfig: vite.ResolvedConfig): TransformHook { @@ -21,7 +25,13 @@ interface TransformWithViteOptions { } /** Transform style using Vite hook */ -export async function transformWithVite({ value, lang, transformHook, id, ssr }: TransformWithViteOptions): Promise<vite.TransformResult | null> { +export async function transformWithVite({ + value, + lang, + transformHook, + id, + ssr, +}: TransformWithViteOptions): Promise<vite.TransformResult | null> { if (!STYLE_EXTENSIONS.has(lang)) { return null; // only preprocess langs supported by Vite } diff --git a/packages/astro/src/vite-plugin-build-css/index.ts b/packages/astro/src/vite-plugin-build-css/index.ts index 11eb6b096..686dc3e52 100644 --- a/packages/astro/src/vite-plugin-build-css/index.ts +++ b/packages/astro/src/vite-plugin-build-css/index.ts @@ -5,7 +5,11 @@ import * as path from 'path'; import esbuild from 'esbuild'; import { Plugin as VitePlugin } from 'vite'; import { isCSSRequest } from '../core/render/util.js'; -import { getPageDatasByChunk, getPageDataByViteID, hasPageDataByViteID } from '../core/build/internal.js'; +import { + getPageDatasByChunk, + getPageDataByViteID, + hasPageDataByViteID, +} from '../core/build/internal.js'; const PLUGIN_NAME = '@astrojs/rollup-plugin-build-css'; @@ -52,7 +56,11 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin { const { internals, legacy } = options; const styleSourceMap = new Map<string, string>(); - function* walkStyles(ctx: PluginContext, id: string, seen = new Set<string>()): Generator<[string, string], void, unknown> { + function* walkStyles( + ctx: PluginContext, + id: string, + seen = new Set<string>() + ): Generator<[string, string], void, unknown> { seen.add(id); if (styleSourceMap.has(id)) { yield [id, styleSourceMap.get(id)!]; @@ -203,12 +211,19 @@ export function rollupPluginAstroBuildCSS(options: PluginOptions): VitePlugin { // Delete CSS chunks so JS is not produced for them. async generateBundle(opts, bundle) { const hasPureCSSChunks = internals.pureCSSChunks.size; - const pureChunkFilenames = new Set([...internals.pureCSSChunks].map((chunk) => chunk.fileName)); + const pureChunkFilenames = new Set( + [...internals.pureCSSChunks].map((chunk) => chunk.fileName) + ); const emptyChunkFiles = [...pureChunkFilenames] .map((file) => path.basename(file)) .join('|') .replace(/\./g, '\\.'); - const emptyChunkRE = new RegExp(opts.format === 'es' ? `\\bimport\\s*"[^"]*(?:${emptyChunkFiles})";\n?` : `\\brequire\\(\\s*"[^"]*(?:${emptyChunkFiles})"\\);\n?`, 'g'); + const emptyChunkRE = new RegExp( + opts.format === 'es' + ? `\\bimport\\s*"[^"]*(?:${emptyChunkFiles})";\n?` + : `\\brequire\\(\\s*"[^"]*(?:${emptyChunkFiles})"\\);\n?`, + 'g' + ); // Crawl the module graph to find CSS chunks to create if (!legacy) { diff --git a/packages/astro/src/vite-plugin-build-html/extract-assets.ts b/packages/astro/src/vite-plugin-build-html/extract-assets.ts index 5d9638630..ffc0446a3 100644 --- a/packages/astro/src/vite-plugin-build-html/extract-assets.ts +++ b/packages/astro/src/vite-plugin-build-html/extract-assets.ts @@ -12,7 +12,9 @@ function getSrcSetUrls(srcset: string) { return []; } const srcsetParts = srcset.includes(',') ? srcset.split(',') : [srcset]; - const urls = srcsetParts.map((url) => url.trim()).map((url) => (url.includes(' ') ? url.split(' ')[0] : url)); + const urls = srcsetParts + .map((url) => url.trim()) + .map((url) => (url.includes(' ') ? url.split(' ')[0] : url)); return urls; } @@ -116,9 +118,20 @@ export function isHashedAsset(node: Element) { } } -export function resolveAssetFilePath(browserPath: string, htmlDir: string, projectRootDir: string, absolutePathPrefix?: string) { - const _browserPath = absolutePathPrefix && browserPath[0] === '/' ? '/' + npath.posix.relative(absolutePathPrefix, browserPath) : browserPath; - return npath.join(_browserPath.startsWith('/') ? projectRootDir : htmlDir, _browserPath.split('/').join(npath.sep)); +export function resolveAssetFilePath( + browserPath: string, + htmlDir: string, + projectRootDir: string, + absolutePathPrefix?: string +) { + const _browserPath = + absolutePathPrefix && browserPath[0] === '/' + ? '/' + npath.posix.relative(absolutePathPrefix, browserPath) + : browserPath; + return npath.join( + _browserPath.startsWith('/') ? projectRootDir : htmlDir, + _browserPath.split('/').join(npath.sep) + ); } export function getSourceAttribute(node: Element) { diff --git a/packages/astro/src/vite-plugin-build-html/index.ts b/packages/astro/src/vite-plugin-build-html/index.ts index 32c59e531..9221028f2 100644 --- a/packages/astro/src/vite-plugin-build-html/index.ts +++ b/packages/astro/src/vite-plugin-build-html/index.ts @@ -1,4 +1,12 @@ -import { createElement, createScript, getAttribute, hasAttribute, insertBefore, remove, setAttribute } from '@web/parse5-utils'; +import { + createElement, + createScript, + getAttribute, + hasAttribute, + insertBefore, + remove, + setAttribute, +} from '@web/parse5-utils'; import { promises as fs } from 'fs'; import parse5 from 'parse5'; import * as npath from 'path'; @@ -15,8 +23,21 @@ 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 { + 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 @@ -45,7 +66,8 @@ function relativePath(from: string, to: string): string { } export function rollupPluginAstroScanHTML(options: PluginOptions): VitePlugin { - const { astroConfig, internals, logging, origin, allPages, routeCache, viteServer, pageNames } = options; + const { astroConfig, internals, logging, origin, allPages, routeCache, viteServer, pageNames } = + options; // The filepath root of the src folder const srcRoot = astroConfig.srcDir.pathname; @@ -322,7 +344,12 @@ export function rollupPluginAstroScanHTML(options: PluginOptions): VitePlugin { // Keep track of links added so we don't do so twice. const linkChunksAdded = new Set<string>(); - const appendStyleChunksBefore = (ref: parse5.Element, pathname: string, referenceIds: string[] | undefined, attrs: Record<string, any> = {}) => { + const appendStyleChunksBefore = ( + ref: parse5.Element, + pathname: string, + referenceIds: string[] | undefined, + attrs: Record<string, any> = {} + ) => { let added = false; if (referenceIds) { const lastNode = ref; @@ -433,7 +460,12 @@ export function rollupPluginAstroScanHTML(options: PluginOptions): VitePlugin { if (!pageCSSAdded) { const attrs = getAttributes(node); delete attrs['data-astro-injected']; - pageCSSAdded = appendStyleChunksBefore(node, pathname, cssChunkMap.get(styleId), attrs); + pageCSSAdded = appendStyleChunksBefore( + node, + pathname, + cssChunkMap.get(styleId), + attrs + ); } remove(node); break; diff --git a/packages/astro/src/vite-plugin-build-html/util.ts b/packages/astro/src/vite-plugin-build-html/util.ts index f42db5e72..8380b55fd 100644 --- a/packages/astro/src/vite-plugin-build-html/util.ts +++ b/packages/astro/src/vite-plugin-build-html/util.ts @@ -12,7 +12,12 @@ function startsWithSrcRoot(pathname: string, srcRoot: string, srcRootWeb: string ); // Windows fix: some paths are missing leading "/" } -export function isInSrcDirectory(node: parse5.Element, attr: string, srcRoot: string, srcRootWeb: string): boolean { +export function isInSrcDirectory( + node: parse5.Element, + attr: string, + srcRoot: string, + srcRootWeb: string +): boolean { const value = getAttribute(node, attr); return value ? startsWithSrcRoot(value, srcRoot, srcRootWeb) : false; } @@ -21,7 +26,11 @@ export function isAstroInjectedLink(node: parse5.Element): boolean { return isStylesheetLink(node) && getAttribute(node, 'data-astro-injected') === ''; } -export function isBuildableLink(node: parse5.Element, srcRoot: string, srcRootWeb: string): boolean { +export function isBuildableLink( + node: parse5.Element, + srcRoot: string, + srcRootWeb: string +): boolean { if (isAstroInjectedLink(node)) { return true; } @@ -34,7 +43,11 @@ export function isBuildableLink(node: parse5.Element, srcRoot: string, srcRootWe return startsWithSrcRoot(href, srcRoot, srcRootWeb); } -export function isBuildableImage(node: parse5.Element, srcRoot: string, srcRootWeb: string): boolean { +export function isBuildableImage( + node: parse5.Element, + srcRoot: string, + srcRootWeb: string +): boolean { if (getTagName(node) === 'img') { const src = getAttribute(node, 'src'); return src ? startsWithSrcRoot(src, srcRoot, srcRootWeb) : false; diff --git a/packages/astro/src/vite-plugin-config-alias/index.ts b/packages/astro/src/vite-plugin-config-alias/index.ts index f87a2c74d..d07dcb631 100644 --- a/packages/astro/src/vite-plugin-config-alias/index.ts +++ b/packages/astro/src/vite-plugin-config-alias/index.ts @@ -14,7 +14,10 @@ export declare interface Alias { const normalize = (pathname: string) => String(pathname).split(path.sep).join(path.posix.sep); /** Returns the results of a config file if it exists, otherwise null. */ -const getExistingConfig = (searchName: string, cwd: string | undefined): tsr.TsConfigResultSuccess | null => { +const getExistingConfig = ( + searchName: string, + cwd: string | undefined +): tsr.TsConfigResultSuccess | null => { const config = tsr.tsconfigResolverSync({ cwd, searchName }); return config.exists ? config : null; @@ -35,24 +38,37 @@ const getConfigAlias = (cwd: string | undefined): Alias[] | null => { if (!compilerOptions.baseUrl) return null; // resolve the base url from the configuration file directory - const baseUrl = path.posix.resolve(path.posix.dirname(normalize(config.path).replace(/^\/?/, '/')), normalize(compilerOptions.baseUrl)); + const baseUrl = path.posix.resolve( + path.posix.dirname(normalize(config.path).replace(/^\/?/, '/')), + normalize(compilerOptions.baseUrl) + ); /** List of compiled alias expressions. */ const aliases: Alias[] = []; // compile any alias expressions and push them to the list - for (let [alias, values] of Object.entries(Object(compilerOptions.paths) as { [key: string]: string[] })) { + for (let [alias, values] of Object.entries( + Object(compilerOptions.paths) as { [key: string]: string[] } + )) { values = [].concat(values as never); /** Regular Expression used to match a given path. */ - const find = new RegExp(`^${[...alias].map((segment) => (segment === '*' ? '(.+)' : segment.replace(/[\\^$*+?.()|[\]{}]/, '\\$&'))).join('')}$`); + const find = new RegExp( + `^${[...alias] + .map((segment) => + segment === '*' ? '(.+)' : segment.replace(/[\\^$*+?.()|[\]{}]/, '\\$&') + ) + .join('')}$` + ); /** Internal index used to calculate the matching id in a replacement. */ let matchId = 0; for (let value of values) { /** String used to replace a matched path. */ - const replacement = [...path.posix.resolve(baseUrl, value)].map((segment) => (segment === '*' ? `$${++matchId}` : segment === '$' ? '$$' : segment)).join(''); + const replacement = [...path.posix.resolve(baseUrl, value)] + .map((segment) => (segment === '*' ? `$${++matchId}` : segment === '$' ? '$$' : segment)) + .join(''); aliases.push({ find, replacement }); } @@ -70,7 +86,10 @@ const getConfigAlias = (cwd: string | undefined): Alias[] | null => { }; /** Returns a Vite plugin used to alias pathes from tsconfig.json and jsconfig.json. */ -export default function configAliasVitePlugin(astroConfig: { root?: URL; [key: string]: unknown }): vite.PluginOption { +export default function configAliasVitePlugin(astroConfig: { + root?: URL; + [key: string]: unknown; +}): vite.PluginOption { /** Aliases from the tsconfig.json or jsconfig.json configuration. */ const configAlias = getConfigAlias(astroConfig.root && url.fileURLToPath(astroConfig.root)); @@ -94,7 +113,10 @@ export default function configAliasVitePlugin(astroConfig: { root?: URL; [key: s const aliasedSourceId = sourceId.replace(alias.find, alias.replacement); /** Resolved ID conditionally handled by any other resolver. (this also gives priority to all other resolvers) */ - const resolvedAliasedId = await this.resolve(aliasedSourceId, importer, { skipSelf: true, ...options }); + const resolvedAliasedId = await this.resolve(aliasedSourceId, importer, { + skipSelf: true, + ...options, + }); // if the existing resolvers find the file, return that resolution if (resolvedAliasedId) return resolvedAliasedId; diff --git a/packages/astro/src/vite-plugin-env/index.ts b/packages/astro/src/vite-plugin-env/index.ts index 2c2d2bba8..7a716019e 100644 --- a/packages/astro/src/vite-plugin-env/index.ts +++ b/packages/astro/src/vite-plugin-env/index.ts @@ -12,9 +12,15 @@ interface EnvPluginOptions { function getPrivateEnv(viteConfig: vite.ResolvedConfig, astroConfig: AstroConfig) { let envPrefixes: string[] = ['PUBLIC_']; if (viteConfig.envPrefix) { - envPrefixes = Array.isArray(viteConfig.envPrefix) ? viteConfig.envPrefix : [viteConfig.envPrefix]; + envPrefixes = Array.isArray(viteConfig.envPrefix) + ? viteConfig.envPrefix + : [viteConfig.envPrefix]; } - const fullEnv = loadEnv(viteConfig.mode, viteConfig.envDir ?? fileURLToPath(astroConfig.root), ''); + const fullEnv = loadEnv( + viteConfig.mode, + viteConfig.envDir ?? fileURLToPath(astroConfig.root), + '' + ); const privateKeys = Object.keys(fullEnv).filter((key) => { // don't expose any variables also on `process.env` // note: this filters out `CLI_ARGS=1` passed to node! @@ -44,7 +50,9 @@ function getReferencedPrivateKeys(source: string, privateEnv: Record<string, any return references; } -export default function envVitePlugin({ config: astroConfig }: EnvPluginOptions): vite.PluginOption { +export default function envVitePlugin({ + config: astroConfig, +}: EnvPluginOptions): vite.PluginOption { let privateEnv: Record<string, any> | null; let config: vite.ResolvedConfig; let replacements: Record<string, string>; @@ -69,7 +77,10 @@ export default function envVitePlugin({ config: astroConfig }: EnvPluginOptions) if (typeof privateEnv === 'undefined') { privateEnv = getPrivateEnv(config, astroConfig); if (privateEnv) { - const entries = Object.entries(privateEnv).map(([key, value]) => [`import.meta.env.${key}`, value]); + const entries = Object.entries(privateEnv).map(([key, value]) => [ + `import.meta.env.${key}`, + value, + ]); replacements = Object.fromEntries(entries); // These additional replacements are needed to match Vite replacements = Object.assign(replacements, { diff --git a/packages/astro/src/vite-plugin-integrations-container/index.ts b/packages/astro/src/vite-plugin-integrations-container/index.ts index 8defa16b5..da14e43f9 100644 --- a/packages/astro/src/vite-plugin-integrations-container/index.ts +++ b/packages/astro/src/vite-plugin-integrations-container/index.ts @@ -3,7 +3,11 @@ import { AstroConfig } from '../@types/astro.js'; import { runHookServerSetup } from '../integrations/index.js'; /** Connect Astro integrations into Vite, as needed. */ -export default function astroIntegrationsContainerPlugin({ config }: { config: AstroConfig }): VitePlugin { +export default function astroIntegrationsContainerPlugin({ + config, +}: { + config: AstroConfig; +}): VitePlugin { return { name: 'astro:integration-container', configureServer(server) { diff --git a/packages/astro/src/vite-plugin-jsx/index.ts b/packages/astro/src/vite-plugin-jsx/index.ts index b04152a9a..dee04c0b1 100644 --- a/packages/astro/src/vite-plugin-jsx/index.ts +++ b/packages/astro/src/vite-plugin-jsx/index.ts @@ -30,7 +30,9 @@ function getEsbuildLoader(fileExt: string): string { function collectJSXRenderers(renderers: AstroRenderer[]): Map<string, AstroRenderer> { const renderersWithJSXSupport = renderers.filter((r) => r.jsxImportSource); - return new Map(renderersWithJSXSupport.map((r) => [r.jsxImportSource, r] as [string, AstroRenderer])); + return new Map( + renderersWithJSXSupport.map((r) => [r.jsxImportSource, r] as [string, AstroRenderer]) + ); } interface TransformJSXOptions { @@ -41,7 +43,13 @@ interface TransformJSXOptions { ssr: boolean; } -async function transformJSX({ code, mode, id, ssr, renderer }: TransformJSXOptions): Promise<TransformResult> { +async function transformJSX({ + code, + mode, + id, + ssr, + renderer, +}: TransformJSXOptions): Promise<TransformResult> { const { jsxTransformOptions } = renderer; const options = await jsxTransformOptions!({ mode, ssr }); const plugins = [...(options.plugins || [])]; @@ -117,7 +125,13 @@ export default function jsx({ config, logging }: AstroPluginJSXOptions): Plugin sourcefile: id, sourcemap: 'inline', }); - return transformJSX({ code: jsxCode, id, renderer: [...jsxRenderers.values()][0], mode, ssr }); + return transformJSX({ + code: jsxCode, + id, + renderer: [...jsxRenderers.values()][0], + mode, + ssr, + }); } // Attempt: Multiple JSX renderers @@ -165,7 +179,13 @@ export default function jsx({ config, logging }: AstroPluginJSXOptions): Plugin const jsxRenderer = jsxRenderers.get(importSource); // if renderer not installed for this JSX source, throw error if (!jsxRenderer) { - error(logging, 'renderer', `${colors.yellow(id)} No renderer installed for ${importSource}. Try adding \`@astrojs/${importSource}\` to your project.`); + error( + logging, + 'renderer', + `${colors.yellow( + id + )} No renderer installed for ${importSource}. Try adding \`@astrojs/${importSource}\` to your project.` + ); return null; } // downlevel any non-standard syntax, but preserve JSX @@ -175,7 +195,13 @@ export default function jsx({ config, logging }: AstroPluginJSXOptions): Plugin sourcefile: id, sourcemap: 'inline', }); - return await transformJSX({ code: jsxCode, id, renderer: jsxRenderers.get(importSource) as AstroRenderer, mode, ssr }); + return await transformJSX({ + code: jsxCode, + id, + renderer: jsxRenderers.get(importSource) as AstroRenderer, + mode, + ssr, + }); } // if we still can’t tell, throw error @@ -185,7 +211,9 @@ export default function jsx({ config, logging }: AstroPluginJSXOptions): Plugin 'renderer', `${colors.yellow(id)} Unable to resolve a renderer that handles this file! With more than one renderer enabled, you should include an import or use a pragma comment. -Add ${colors.cyan(IMPORT_STATEMENTS[defaultRenderer] || `import '${defaultRenderer}';`)} or ${colors.cyan(`/* jsxImportSource: ${defaultRenderer} */`)} to this file. +Add ${colors.cyan( + IMPORT_STATEMENTS[defaultRenderer] || `import '${defaultRenderer}';` + )} or ${colors.cyan(`/* jsxImportSource: ${defaultRenderer} */`)} to this file. ` ); return null; diff --git a/packages/astro/src/vite-plugin-markdown/index.ts b/packages/astro/src/vite-plugin-markdown/index.ts index 2f5314ac2..615894fca 100644 --- a/packages/astro/src/vite-plugin-markdown/index.ts +++ b/packages/astro/src/vite-plugin-markdown/index.ts @@ -82,9 +82,13 @@ export default function markdown({ config }: AstroPluginOptions): Plugin { // 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.site ? appendForwardSlash(new URL(config.base, config.site).pathname) : '/'; + const sitePathname = config.site + ? appendForwardSlash(new URL(config.base, config.site).pathname) + : '/'; const fileId = id.substring(VIRTUAL_MODULE_ID.length); - const fileUrl = fileId.includes('/pages/') ? fileId.replace(/^.*\/pages\//, sitePathname).replace(/(\/index)?\.md$/, '') : undefined; + 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 { @@ -160,7 +164,11 @@ export const frontmatter = ${JSON.stringify(content)}; ${tsResult}`; // Compile from `.ts` to `.js` - const { code } = await esbuild.transform(tsResult, { loader: 'ts', sourcemap: false, sourcefile: id }); + const { code } = await esbuild.transform(tsResult, { + loader: 'ts', + sourcemap: false, + sourcefile: id, + }); return { code, map: null, diff --git a/packages/astro/src/vite-plugin-scripts/index.ts b/packages/astro/src/vite-plugin-scripts/index.ts index 0d1601bba..20f4fdafe 100644 --- a/packages/astro/src/vite-plugin-scripts/index.ts +++ b/packages/astro/src/vite-plugin-scripts/index.ts @@ -5,7 +5,9 @@ import { AstroConfig, InjectedScriptStage } from '../@types/astro.js'; // inject these as ESM imports into actual code, where they would not // resolve correctly. const SCRIPT_ID_PREFIX = `astro:scripts/`; -export const BEFORE_HYDRATION_SCRIPT_ID = `${SCRIPT_ID_PREFIX}${'before-hydration' as InjectedScriptStage}.js`; +export const BEFORE_HYDRATION_SCRIPT_ID = `${SCRIPT_ID_PREFIX}${ + 'before-hydration' as InjectedScriptStage +}.js`; export const PAGE_SCRIPT_ID = `${SCRIPT_ID_PREFIX}${'page' as InjectedScriptStage}.js`; export const PAGE_SSR_SCRIPT_ID = `${SCRIPT_ID_PREFIX}${'page-ssr' as InjectedScriptStage}.js`; @@ -45,7 +47,9 @@ export default function astroScriptsPlugin({ config }: { config: AstroConfig }): // for the frontend AND some hydrated components exist in // the final build. We can detect this by looking for a // `astro/client/*` input, which signifies both conditions are met. - const hasHydratedComponents = Array.isArray(options.input) && options.input.some((input) => input.startsWith('astro/client')); + const hasHydratedComponents = + Array.isArray(options.input) && + options.input.some((input) => input.startsWith('astro/client')); const hasHydrationScripts = config._ctx.scripts.some((s) => s.stage === 'before-hydration'); if (hasHydratedComponents && hasHydrationScripts) { this.emitFile({ diff --git a/packages/astro/test/0-css.test.js b/packages/astro/test/0-css.test.js index 9633127c9..9d08c1aa9 100644 --- a/packages/astro/test/0-css.test.js +++ b/packages/astro/test/0-css.test.js @@ -214,37 +214,49 @@ describe('CSS', function () { it('<style>', async () => { const el = $('#svelte-css'); const classes = el.attr('class').split(' '); - const scopedClass = classes.find((name) => name !== 'svelte-css' && /^svelte-[A-Za-z0-9-]+/.test(name)); + const scopedClass = classes.find( + (name) => name !== 'svelte-css' && /^svelte-[A-Za-z0-9-]+/.test(name) + ); // 1. check HTML expect(el.attr('class')).to.include('svelte-css'); // 2. check CSS - expect(bundledCSS).to.match(new RegExp(`.svelte-css.${scopedClass}[^{]*{font-family:Comic Sans MS`)); + expect(bundledCSS).to.match( + new RegExp(`.svelte-css.${scopedClass}[^{]*{font-family:Comic Sans MS`) + ); }); it('<style lang="sass">', async () => { const el = $('#svelte-sass'); const classes = el.attr('class').split(' '); - const scopedClass = classes.find((name) => name !== 'svelte-sass' && /^svelte-[A-Za-z0-9-]+/.test(name)); + const scopedClass = classes.find( + (name) => name !== 'svelte-sass' && /^svelte-[A-Za-z0-9-]+/.test(name) + ); // 1. check HTML expect(el.attr('class')).to.include('svelte-sass'); // 2. check CSS - expect(bundledCSS).to.match(new RegExp(`.svelte-sass.${scopedClass}[^{]*{font-family:Comic Sans MS`)); + expect(bundledCSS).to.match( + new RegExp(`.svelte-sass.${scopedClass}[^{]*{font-family:Comic Sans MS`) + ); }); it('<style lang="scss">', async () => { const el = $('#svelte-scss'); const classes = el.attr('class').split(' '); - const scopedClass = classes.find((name) => name !== 'svelte-scss' && /^svelte-[A-Za-z0-9-]+/.test(name)); + const scopedClass = classes.find( + (name) => name !== 'svelte-scss' && /^svelte-[A-Za-z0-9-]+/.test(name) + ); // 1. check HTML expect(el.attr('class')).to.include('svelte-scss'); // 2. check CSS - expect(bundledCSS).to.match(new RegExp(`.svelte-scss.${scopedClass}[^{]*{font-family:Comic Sans MS`)); + expect(bundledCSS).to.match( + new RegExp(`.svelte-scss.${scopedClass}[^{]*{font-family:Comic Sans MS`) + ); }); }); }); @@ -285,7 +297,14 @@ describe('CSS', function () { }); it('resolves Styles from React', async () => { - const styles = ['ReactCSS.css', 'ReactModules.module.css', 'ReactModules.module.scss', 'ReactModules.module.sass', 'ReactSass.sass', 'ReactScss.scss']; + const styles = [ + 'ReactCSS.css', + 'ReactModules.module.css', + 'ReactModules.module.scss', + 'ReactModules.module.sass', + 'ReactSass.sass', + 'ReactScss.scss', + ]; for (const style of styles) { const href = $(`link[href$="${style}"]`).attr('href'); expect((await fixture.fetch(href)).status, style).to.equal(200); @@ -293,7 +312,11 @@ describe('CSS', function () { }); it('resolves CSS from Svelte', async () => { - const scripts = ['SvelteCSS.svelte?svelte&type=style&lang.css', 'SvelteSass.svelte?svelte&type=style&lang.css', 'SvelteScss.svelte?svelte&type=style&lang.css']; + const scripts = [ + 'SvelteCSS.svelte?svelte&type=style&lang.css', + 'SvelteSass.svelte?svelte&type=style&lang.css', + 'SvelteScss.svelte?svelte&type=style&lang.css', + ]; for (const script of scripts) { const src = $(`script[src$="${script}"]`).attr('src'); expect((await fixture.fetch(src)).status, script).to.equal(200); diff --git a/packages/astro/test/astro-basic.test.js b/packages/astro/test/astro-basic.test.js index 0b421a026..e6d59af49 100644 --- a/packages/astro/test/astro-basic.test.js +++ b/packages/astro/test/astro-basic.test.js @@ -104,7 +104,9 @@ describe('Astro basics', () => { expect($('body > :nth-child(3)').prop('outerHTML')).to.equal('<input type="text">'); // <Input type="select"><option>option</option></Input> - expect($('body > :nth-child(4)').prop('outerHTML')).to.equal('<select><option>option</option></select>'); + expect($('body > :nth-child(4)').prop('outerHTML')).to.equal( + '<select><option>option</option></select>' + ); // <Input type="textarea">textarea</Input> expect($('body > :nth-child(5)').prop('outerHTML')).to.equal('<textarea>textarea</textarea>'); diff --git a/packages/astro/test/astro-children.test.js b/packages/astro/test/astro-children.test.js index 73e896474..3d6ff54c0 100644 --- a/packages/astro/test/astro-children.test.js +++ b/packages/astro/test/astro-children.test.js @@ -75,8 +75,14 @@ describe('Component children', () => { expect($('#ssr-only').children()).to.have.lengthOf(0); // test 2: If client, and no children are rendered, a template is. - expect($('#client').parent().children()).to.have.lengthOf(2, 'rendered the client component and a template'); - expect($('#client').parent().find('template[data-astro-template]')).to.have.lengthOf(1, 'Found 1 template'); + expect($('#client').parent().children()).to.have.lengthOf( + 2, + 'rendered the client component and a template' + ); + expect($('#client').parent().find('template[data-astro-template]')).to.have.lengthOf( + 1, + 'Found 1 template' + ); // test 3: If client, and children are rendered, no template is. expect($('#client-render').parent().children()).to.have.lengthOf(1); diff --git a/packages/astro/test/astro-component-code.test.js b/packages/astro/test/astro-component-code.test.js index 26aec0138..783fa734d 100644 --- a/packages/astro/test/astro-component-code.test.js +++ b/packages/astro/test/astro-component-code.test.js @@ -14,7 +14,10 @@ describe('<Code>', () => { let html = await fixture.readFile('/no-lang/index.html'); const $ = cheerio.load(html); expect($('pre')).to.have.lengthOf(1); - expect($('pre').attr('style')).to.equal('background-color: #0d1117; overflow-x: auto;', 'applies default and overflow'); + expect($('pre').attr('style')).to.equal( + 'background-color: #0d1117; overflow-x: auto;', + 'applies default and overflow' + ); expect($('pre > code')).to.have.lengthOf(1); // test: contains some generated spans @@ -36,7 +39,10 @@ describe('<Code>', () => { const $ = cheerio.load(html); expect($('pre')).to.have.lengthOf(1); expect($('pre').attr('class')).to.equal('astro-code'); - expect($('pre').attr('style')).to.equal('background-color: #2e3440ff; overflow-x: auto;', 'applies custom theme'); + expect($('pre').attr('style')).to.equal( + 'background-color: #2e3440ff; overflow-x: auto;', + 'applies custom theme' + ); }); it('<Code wrap>', async () => { @@ -45,7 +51,9 @@ describe('<Code>', () => { const $ = cheerio.load(html); expect($('pre')).to.have.lengthOf(1); // test: applies wrap overflow - expect($('pre').attr('style')).to.equal('background-color: #0d1117; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;'); + expect($('pre').attr('style')).to.equal( + 'background-color: #0d1117; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;' + ); } { let html = await fixture.readFile('/wrap-false/index.html'); diff --git a/packages/astro/test/astro-css-bundling.test.js b/packages/astro/test/astro-css-bundling.test.js index abddfa6f4..ea589816e 100644 --- a/packages/astro/test/astro-css-bundling.test.js +++ b/packages/astro/test/astro-css-bundling.test.js @@ -9,7 +9,14 @@ const EXPECTED_CSS = { '/one/index.html': ['/assets/'], '/two/index.html': ['/assets/'], }; -const UNEXPECTED_CSS = ['/src/components/nav.css', '../css/typography.css', '../css/colors.css', '../css/page-index.css', '../css/page-one.css', '../css/page-two.css']; +const UNEXPECTED_CSS = [ + '/src/components/nav.css', + '../css/typography.css', + '../css/colors.css', + '../css/page-index.css', + '../css/page-one.css', + '../css/page-two.css', +]; describe('CSS Bundling', function () { let fixture; diff --git a/packages/astro/test/astro-markdown-plugins.test.js b/packages/astro/test/astro-markdown-plugins.test.js index 6277bbf0d..35a3f829d 100644 --- a/packages/astro/test/astro-markdown-plugins.test.js +++ b/packages/astro/test/astro-markdown-plugins.test.js @@ -10,8 +10,15 @@ describe('Astro Markdown plugins', () => { fixture = await loadFixture({ root: './fixtures/astro-markdown-plugins/', markdown: { - remarkPlugins: ['remark-code-titles', ['rehype-autolink-headings', { behavior: 'prepend' }]], - rehypePlugins: [['rehype-toc', { headings: ['h2', 'h3'] }], [addClasses, { 'h1,h2,h3': 'title' }], 'rehype-slug'], + remarkPlugins: [ + 'remark-code-titles', + ['rehype-autolink-headings', { behavior: 'prepend' }], + ], + rehypePlugins: [ + ['rehype-toc', { headings: ['h2', 'h3'] }], + [addClasses, { 'h1,h2,h3': 'title' }], + 'rehype-slug', + ], }, }); await fixture.build(); diff --git a/packages/astro/test/astro-markdown-shiki.test.js b/packages/astro/test/astro-markdown-shiki.test.js index d8cd43fcb..e4b945a0d 100644 --- a/packages/astro/test/astro-markdown-shiki.test.js +++ b/packages/astro/test/astro-markdown-shiki.test.js @@ -126,7 +126,8 @@ describe('Astro Markdown Shiki', () => { describe('Wrap', () => { describe('wrap = true', () => { - const style = 'background-color: #0d1117; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;'; + const style = + 'background-color: #0d1117; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;'; let fixture; before(async () => { diff --git a/packages/astro/test/astro-pagination.test.js b/packages/astro/test/astro-pagination.test.js index 7090cec4f..80c460f94 100644 --- a/packages/astro/test/astro-pagination.test.js +++ b/packages/astro/test/astro-pagination.test.js @@ -15,13 +15,21 @@ describe('Pagination', () => { }); it('optional root page', async () => { - for (const file of ['/posts/optional-root-page/index.html', '/posts/optional-root-page/2/index.html', '/posts/optional-root-page/3/index.html']) { + for (const file of [ + '/posts/optional-root-page/index.html', + '/posts/optional-root-page/2/index.html', + '/posts/optional-root-page/3/index.html', + ]) { expect(await fixture.readFile(file)).to.be.ok; } }); it('named root page', async () => { - for (const file of ['/posts/named-root-page/1/index.html', '/posts/named-root-page/2/index.html', '/posts/named-root-page/3/index.html']) { + for (const file of [ + '/posts/named-root-page/1/index.html', + '/posts/named-root-page/2/index.html', + '/posts/named-root-page/3/index.html', + ]) { expect(await fixture.readFile(file)).to.be.ok; } }); diff --git a/packages/astro/test/cli.test.js b/packages/astro/test/cli.test.js index bb56b9150..369c12103 100644 --- a/packages/astro/test/cli.test.js +++ b/packages/astro/test/cli.test.js @@ -48,7 +48,10 @@ describe('astro cli', () => { const networkLogFlags = [['--host'], ['--host', '0.0.0.0']]; networkLogFlags.forEach(([flag, flagValue]) => { it(`astro ${cmd} ${flag} ${flagValue ?? ''} - network log`, async () => { - const { local, network } = await cliServerLogSetupWithFixture(flagValue ? [flag, flagValue] : [flag], cmd); + const { local, network } = await cliServerLogSetupWithFixture( + flagValue ? [flag, flagValue] : [flag], + cmd + ); expect(local).to.not.be.undefined; expect(network).to.not.be.undefined; @@ -56,11 +59,23 @@ describe('astro cli', () => { const localURL = new URL(local); const networkURL = new URL(network); - expect(localURL.hostname).to.be.equal(flagValue ?? 'localhost', `Expected local URL to be on localhost`); + expect(localURL.hostname).to.be.equal( + flagValue ?? 'localhost', + `Expected local URL to be on localhost` + ); // Note: our tests run in parallel so this could be 3000+! - expect(Number.parseInt(localURL.port)).to.be.greaterThanOrEqual(3000, `Expected Port to be >= 3000`); - expect(networkURL.port).to.be.equal(localURL.port, `Expected local and network ports to be equal`); - expect(isIPv4(networkURL.hostname)).to.be.equal(true, `Expected network URL to respect --host flag`); + expect(Number.parseInt(localURL.port)).to.be.greaterThanOrEqual( + 3000, + `Expected Port to be >= 3000` + ); + expect(networkURL.port).to.be.equal( + localURL.port, + `Expected local and network ports to be equal` + ); + expect(isIPv4(networkURL.hostname)).to.be.equal( + true, + `Expected network URL to respect --host flag` + ); }); }); diff --git a/packages/astro/test/config-validate.test.js b/packages/astro/test/config-validate.test.js index c3bed9d46..e90eea69c 100644 --- a/packages/astro/test/config-validate.test.js +++ b/packages/astro/test/config-validate.test.js @@ -40,7 +40,10 @@ describe('Config Validation', () => { }); it('ignores falsey "integration" values', async () => { - const result = await validateConfig({ integrations: [0, false, null, undefined] }, process.cwd()); + const result = await validateConfig( + { integrations: [0, false, null, undefined] }, + process.cwd() + ); expect(result.integrations).to.deep.equal([]); }); it('normalizes "integration" values', async () => { @@ -48,7 +51,10 @@ describe('Config Validation', () => { expect(result.integrations).to.deep.equal([{ name: '@astrojs/a', hooks: {} }]); }); it('flattens array "integration" values', async () => { - const result = await validateConfig({ integrations: [{ name: '@astrojs/a' }, [{ name: '@astrojs/b' }, { name: '@astrojs/c' }]] }, process.cwd()); + const result = await validateConfig( + { integrations: [{ name: '@astrojs/a' }, [{ name: '@astrojs/b' }, { name: '@astrojs/c' }]] }, + process.cwd() + ); expect(result.integrations).to.deep.equal([ { name: '@astrojs/a', hooks: {} }, { name: '@astrojs/b', hooks: {} }, @@ -56,11 +62,17 @@ describe('Config Validation', () => { ]); }); it('blocks third-party "integration" values', async () => { - const configError = await validateConfig({ integrations: [{ name: '@my-plugin/a' }] }, process.cwd()).catch((err) => err); + const configError = await validateConfig( + { integrations: [{ name: '@my-plugin/a' }] }, + process.cwd() + ).catch((err) => err); expect(configError).to.be.instanceOf(Error); expect(configError.message).to.include('Astro integrations are still experimental.'); }); it('allows third-party "integration" values with the --experimental-integrations flag', async () => { - await validateConfig({ integrations: [{ name: '@my-plugin/a' }], experimental: { integrations: true } }, process.cwd()).catch((err) => err); + await validateConfig( + { integrations: [{ name: '@my-plugin/a' }], experimental: { integrations: true } }, + process.cwd() + ).catch((err) => err); }); }); diff --git a/packages/astro/test/config.test.js b/packages/astro/test/config.test.js index 5c78efa0c..1f255097c 100644 --- a/packages/astro/test/config.test.js +++ b/packages/astro/test/config.test.js @@ -31,10 +31,17 @@ describe('config', () => { it('can be specified via --host flag', async () => { const projectRootURL = new URL('./fixtures/astro-basic/', import.meta.url); - const { network } = await cliServerLogSetup(['--root', fileURLToPath(projectRootURL), '--host']); + const { network } = await cliServerLogSetup([ + '--root', + fileURLToPath(projectRootURL), + '--host', + ]); const networkURL = new URL(network); - expect(isIPv4(networkURL.hostname)).to.be.equal(true, `Expected network URL to respect --host flag`); + expect(isIPv4(networkURL.hostname)).to.be.equal( + true, + `Expected network URL to respect --host flag` + ); }); }); @@ -42,10 +49,18 @@ describe('config', () => { it('can be passed via --config', async () => { const projectRootURL = new URL('./fixtures/astro-basic/', import.meta.url); const configFileURL = new URL('./fixtures/config-path/config/my-config.mjs', import.meta.url); - const { network } = await cliServerLogSetup(['--root', fileURLToPath(projectRootURL), '--config', configFileURL.pathname]); + const { network } = await cliServerLogSetup([ + '--root', + fileURLToPath(projectRootURL), + '--config', + configFileURL.pathname, + ]); const networkURL = new URL(network); - expect(isIPv4(networkURL.hostname)).to.be.equal(true, `Expected network URL to respect --host flag`); + expect(isIPv4(networkURL.hostname)).to.be.equal( + true, + `Expected network URL to respect --host flag` + ); }); }); diff --git a/packages/astro/test/fetch.test.js b/packages/astro/test/fetch.test.js index 2fcb7be9f..c548aa3f1 100644 --- a/packages/astro/test/fetch.test.js +++ b/packages/astro/test/fetch.test.js @@ -18,7 +18,10 @@ describe('Global Fetch', () => { it('Is available in Astro components', async () => { const html = await fixture.readFile('/index.html'); const $ = cheerio.load(html); - expect($('#astro-component').text()).to.equal('function', 'Fetch supported in .astro components'); + expect($('#astro-component').text()).to.equal( + 'function', + 'Fetch supported in .astro components' + ); }); it('Is available in non-Astro components', async () => { const html = await fixture.readFile('/index.html'); @@ -31,6 +34,9 @@ describe('Global Fetch', () => { const html = await fixture.readFile('/index.html'); const $ = cheerio.load(html); expect($('#already-imported').text()).to.equal('function', 'Existing fetch imports respected'); - expect($('#custom-declaration').text()).to.equal('number', 'Custom fetch declarations respected'); + expect($('#custom-declaration').text()).to.equal( + 'number', + 'Custom fetch declarations respected' + ); }); }); diff --git a/packages/astro/test/lit-element.test.js b/packages/astro/test/lit-element.test.js index 6c939dbd3..6b8690fff 100644 --- a/packages/astro/test/lit-element.test.js +++ b/packages/astro/test/lit-element.test.js @@ -36,7 +36,9 @@ describe('LitElement test', function () { expect($('my-element').html()).to.include(`<div>Testing...</div>`); // test 3: string reactive property set - expect(stripExpressionMarkers($('my-element').html())).to.include(`<div id="str">initialized</div>`); + expect(stripExpressionMarkers($('my-element').html())).to.include( + `<div id="str">initialized</div>` + ); // test 4: boolean reactive property correctly set // <my-element bool="false"> Lit will equate to true because it uses @@ -45,7 +47,9 @@ describe('LitElement test', function () { // test 5: object reactive property set // by default objects will be stringifed to [object Object] - expect(stripExpressionMarkers($('my-element').html())).to.include(`<div id="data">data: 1</div>`); + expect(stripExpressionMarkers($('my-element').html())).to.include( + `<div id="data">data: 1</div>` + ); // test 6: reactive properties are not rendered as attributes expect($('my-element').attr('obj')).to.equal(undefined); diff --git a/packages/astro/test/tailwindcss.test.js b/packages/astro/test/tailwindcss.test.js index e4c0bb55b..762728310 100644 --- a/packages/astro/test/tailwindcss.test.js +++ b/packages/astro/test/tailwindcss.test.js @@ -38,7 +38,9 @@ describe('Tailwind', () => { expect(bundledCSS, 'includes responsive classes').to.match(/\.lg\\:py-3{/); // tailwind escapes brackets, `font-[900]` compiles to `font-\[900\]` - expect(bundledCSS, 'supports arbitrary value classes').to.match(/\.font-\\\[900\\\]{font-weight:900}/); + expect(bundledCSS, 'supports arbitrary value classes').to.match( + /\.font-\\\[900\\\]{font-weight:900}/ + ); }); it('maintains classes in HTML', async () => { diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js index 4e0295da4..ab04f9604 100644 --- a/packages/astro/test/test-utils.js +++ b/packages/astro/test/test-utils.js @@ -55,7 +55,8 @@ polyfill(globalThis, { * .clean() - Async. Removes the project’s dist folder. */ export async function loadFixture(inlineConfig) { - if (!inlineConfig || !inlineConfig.root) throw new Error("Must provide { root: './fixtures/...' }"); + if (!inlineConfig || !inlineConfig.root) + throw new Error("Must provide { root: './fixtures/...' }"); // load config let cwd = inlineConfig.root; @@ -93,12 +94,14 @@ export async function loadFixture(inlineConfig) { return devResult; }, config, - fetch: (url, init) => fetch(`http://${'127.0.0.1'}:${config.server.port}${url.replace(/^\/?/, '/')}`, init), + fetch: (url, init) => + fetch(`http://${'127.0.0.1'}:${config.server.port}${url.replace(/^\/?/, '/')}`, init), preview: async (opts = {}) => { const previewServer = await preview(config, { logging, ...opts }); return previewServer; }, - readFile: (filePath) => fs.promises.readFile(new URL(filePath.replace(/^\//, ''), config.outDir), 'utf8'), + readFile: (filePath) => + fs.promises.readFile(new URL(filePath.replace(/^\//, ''), config.outDir), 'utf8'), readdir: (fp) => fs.promises.readdir(new URL(fp.replace(/^\//, ''), config.outDir)), clean: () => fs.promises.rm(config.outDir, { maxRetries: 10, recursive: true, force: true }), loadTestAdapterApp: async () => { @@ -120,7 +123,11 @@ function merge(a, b) { const c = {}; for (const k of allKeys) { const needsObjectMerge = - typeof a[k] === 'object' && typeof b[k] === 'object' && (Object.keys(a[k]).length || Object.keys(b[k]).length) && !Array.isArray(a[k]) && !Array.isArray(b[k]); + typeof a[k] === 'object' && + typeof b[k] === 'object' && + (Object.keys(a[k]).length || Object.keys(b[k]).length) && + !Array.isArray(a[k]) && + !Array.isArray(b[k]); if (needsObjectMerge) { c[k] = merge(a[k] || {}, b[k] || {}); continue; diff --git a/packages/create-astro/src/index.ts b/packages/create-astro/src/index.ts index f41f2a87c..ec54d250c 100644 --- a/packages/create-astro/src/index.ts +++ b/packages/create-astro/src/index.ts @@ -28,14 +28,20 @@ export function mkdirp(dir: string) { } } -const { version } = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf-8')); +const { version } = JSON.parse( + fs.readFileSync(new URL('../package.json', import.meta.url), 'utf-8') +); const POSTPROCESS_FILES = ['package.json', 'astro.config.mjs', 'CHANGELOG.md']; // some files need processing after copying. export async function main() { logger.debug('Verbose logging turned on'); console.log(`\n${bold('Welcome to Astro!')} ${gray(`(create-astro v${version})`)}`); - console.log(`If you encounter a problem, visit ${cyan('https://github.com/withastro/astro/issues')} to search or file a new issue.\n`); + console.log( + `If you encounter a problem, visit ${cyan( + 'https://github.com/withastro/astro/issues' + )} to search or file a new issue.\n` + ); let spinner = ora({ color: 'green', text: 'Prepare for liftoff.' }); @@ -74,7 +80,9 @@ export async function main() { const hash = args.commit ? `#${args.commit}` : ''; - const templateTarget = options.template.includes('/') ? options.template : `withastro/astro/examples/${options.template}#latest`; + const templateTarget = options.template.includes('/') + ? options.template + : `withastro/astro/examples/${options.template}#latest`; const emitter = degit(`${templateTarget}${hash}`, { cache: false, @@ -118,13 +126,25 @@ export async function main() { // Warning for issue #655 if (err.message === 'zlib: unexpected end of file') { - console.log(yellow("This seems to be a cache related problem. Remove the folder '~/.degit/github/withastro' to fix this error.")); - console.log(yellow('For more information check out this issue: https://github.com/withastro/astro/issues/655')); + console.log( + yellow( + "This seems to be a cache related problem. Remove the folder '~/.degit/github/withastro' to fix this error." + ) + ); + console.log( + yellow( + 'For more information check out this issue: https://github.com/withastro/astro/issues/655' + ) + ); } // Helpful message when encountering the "could not find commit hash for ..." error if (err.code === 'MISSING_REF') { - console.log(yellow("This seems to be an issue with degit. Please check if you have 'git' installed on your system, and install it if you don't have (https://git-scm.com).")); + console.log( + yellow( + "This seems to be an issue with degit. Please check if you have 'git' installed on your system, and install it if you don't have (https://git-scm.com)." + ) + ); console.log( yellow( "If you do have 'git' installed, please run this command with the --verbose flag and file a new issue with the command output here: https://github.com/withastro/astro/issues" @@ -178,8 +198,13 @@ export async function main() { ) ).flat(1); // merge and sort dependencies - packageJSON.devDependencies = { ...(packageJSON.devDependencies ?? {}), ...Object.fromEntries(integrationEntries) }; - packageJSON.devDependencies = Object.fromEntries(Object.entries(packageJSON.devDependencies).sort((a, b) => a[0].localeCompare(b[0]))); + packageJSON.devDependencies = { + ...(packageJSON.devDependencies ?? {}), + ...Object.fromEntries(integrationEntries), + }; + packageJSON.devDependencies = Object.fromEntries( + Object.entries(packageJSON.devDependencies).sort((a, b) => a[0].localeCompare(b[0])) + ); await fs.promises.writeFile(fileLoc, JSON.stringify(packageJSON, undefined, 2)); break; } @@ -196,7 +221,9 @@ export async function main() { const component = COUNTER_COMPONENTS[integration.id as keyof typeof COUNTER_COMPONENTS]; const componentName = path.basename(component.filename, path.extname(component.filename)); const absFileLoc = path.resolve(cwd, component.filename); - importStatements.push(`import ${componentName} from '${component.filename.replace(/^src/, '..')}';`); + importStatements.push( + `import ${componentName} from '${component.filename.replace(/^src/, '..')}';` + ); components.push(`<${componentName} client:visible />`); await fs.promises.writeFile(absFileLoc, component.content); }) @@ -225,7 +252,11 @@ export async function main() { } console.log(` ${i++}: ${bold(cyan('npm install'))} (or pnpm install, yarn, etc)`); - console.log(` ${i++}: ${bold(cyan('git init && git add -A && git commit -m "Initial commit"'))} (optional step)`); + console.log( + ` ${i++}: ${bold( + cyan('git init && git add -A && git commit -m "Initial commit"') + )} (optional step)` + ); console.log(` ${i++}: ${bold(cyan('npm run dev'))} (or pnpm, yarn, etc)`); console.log(`\nTo close the dev server, hit ${bold(cyan('Ctrl-C'))}`); diff --git a/packages/create-astro/src/logger.ts b/packages/create-astro/src/logger.ts index afde6a2af..65f354632 100644 --- a/packages/create-astro/src/logger.ts +++ b/packages/create-astro/src/logger.ts @@ -96,7 +96,12 @@ export const levels: Record<LoggerLevel, number> = { }; /** Full logging API */ -export function log(opts: LogOptions = {}, level: LoggerLevel, type: string | null, ...args: Array<any>) { +export function log( + opts: LogOptions = {}, + level: LoggerLevel, + type: string | null, + ...args: Array<any> +) { const logLevel = opts.level ?? defaultLogOptions.level; const dest = opts.dest ?? defaultLogOptions.dest; const event: LogMessage = { diff --git a/packages/create-astro/test/create-astro.test.js b/packages/create-astro/test/create-astro.test.js index 15e1991f1..86a64e1f5 100644 --- a/packages/create-astro/test/create-astro.test.js +++ b/packages/create-astro/test/create-astro.test.js @@ -108,11 +108,17 @@ async function testAll() { await Promise.all( TEMPLATES.map(async ({ value: template }) => { // setup: `npm init astro` - await execa('../../create-astro.mjs', [template, '--template', template, '--commit', GITHUB_SHA, '--force-overwrite'], { - cwd: FIXTURES_DIR, - }); + await execa( + '../../create-astro.mjs', + [template, '--template', template, '--commit', GITHUB_SHA, '--force-overwrite'], + { + cwd: FIXTURES_DIR, + } + ); // setup: `pnpm install` (note: running multiple `pnpm`s in parallel in CI will conflict) - await execa('pnpm', ['install', '--no-package-lock', '--silent'], { cwd: path.join(FIXTURES_DIR, template) }); + await execa('pnpm', ['install', '--no-package-lock', '--silent'], { + cwd: path.join(FIXTURES_DIR, template), + }); }) ); diff --git a/packages/integrations/lit/client-shim.js b/packages/integrations/lit/client-shim.js index cab3fe4d9..e9cf1aecf 100644 --- a/packages/integrations/lit/client-shim.js +++ b/packages/integrations/lit/client-shim.js @@ -1,9 +1,15 @@ async function polyfill() { - const { hydrateShadowRoots } = await import('@webcomponents/template-shadowroot/template-shadowroot.js'); + const { hydrateShadowRoots } = await import( + '@webcomponents/template-shadowroot/template-shadowroot.js' + ); hydrateShadowRoots(document.body); } -const polyfillCheckEl = new DOMParser().parseFromString(`<p><template shadowroot="open"></template></p>`, 'text/html', { includeShadowRoots: true }).querySelector('p'); +const polyfillCheckEl = new DOMParser() + .parseFromString(`<p><template shadowroot="open"></template></p>`, 'text/html', { + includeShadowRoots: true, + }) + .querySelector('p'); if (!polyfillCheckEl || !polyfillCheckEl.shadowRoot) { polyfill(); diff --git a/packages/integrations/lit/client-shim.min.js b/packages/integrations/lit/client-shim.min.js index 0c6a452d8..f9fe14fdd 100644 --- a/packages/integrations/lit/client-shim.min.js +++ b/packages/integrations/lit/client-shim.min.js @@ -8,7 +8,8 @@ var b = (t, n) => { function s() { if (d === void 0) { let t = document.createElement('div'); - (t.innerHTML = '<div><template shadowroot="open"></template></div>'), (d = !!t.firstElementChild.shadowRoot); + (t.innerHTML = '<div><template shadowroot="open"></template></div>'), + (d = !!t.firstElementChild.shadowRoot); } return d; } @@ -18,7 +19,9 @@ var p, c, f, u = i(() => { - (p = (t) => t.parentElement === null), (c = (t) => t.tagName === 'TEMPLATE'), (f = (t) => t.nodeType === Node.ELEMENT_NODE); + (p = (t) => t.parentElement === null), + (c = (t) => t.tagName === 'TEMPLATE'), + (f = (t) => t.nodeType === Node.ELEMENT_NODE); }); var h, E = i(() => { @@ -52,7 +55,8 @@ var h, (e = r), o !== void 0 && o.parentElement.removeChild(o); break; } - let l = (n = e.parentElement) === null || n === void 0 ? void 0 : n.nextElementSibling; + let l = + (n = e.parentElement) === null || n === void 0 ? void 0 : n.nextElementSibling; if (l != null) { (e = l), o !== void 0 && o.parentElement.removeChild(o); break; @@ -75,5 +79,9 @@ async function g() { let { hydrateShadowRoots: t } = await Promise.resolve().then(() => (S(), v)); t(document.body); } -var x = new DOMParser().parseFromString('<p><template shadowroot="open"></template></p>', 'text/html', { includeShadowRoots: !0 }).querySelector('p'); +var x = new DOMParser() + .parseFromString('<p><template shadowroot="open"></template></p>', 'text/html', { + includeShadowRoots: !0, + }) + .querySelector('p'); (!x || !x.shadowRoot) && g(); diff --git a/packages/integrations/lit/src/index.ts b/packages/integrations/lit/src/index.ts index bf256eb84..f945f1ca3 100644 --- a/packages/integrations/lit/src/index.ts +++ b/packages/integrations/lit/src/index.ts @@ -13,7 +13,12 @@ function getViteConfiguration() { exclude: ['@astrojs/lit/server.js'], }, ssr: { - external: ['lit-element/lit-element.js', '@lit-labs/ssr/lib/install-global-dom-shim.js', '@lit-labs/ssr/lib/render-lit-html.js', '@lit-labs/ssr/lib/lit-element-renderer.js'], + external: [ + 'lit-element/lit-element.js', + '@lit-labs/ssr/lib/install-global-dom-shim.js', + '@lit-labs/ssr/lib/render-lit-html.js', + '@lit-labs/ssr/lib/lit-element-renderer.js', + ], }, }; } @@ -24,7 +29,10 @@ export default function (): AstroIntegration { hooks: { 'astro:config:setup': ({ updateConfig, addRenderer, injectScript }) => { // Inject the necessary polyfills on every page (inlined for speed). - injectScript('head-inline', readFileSync(new URL('../client-shim.min.js', import.meta.url), { encoding: 'utf-8' })); + injectScript( + 'head-inline', + readFileSync(new URL('../client-shim.min.js', import.meta.url), { encoding: 'utf-8' }) + ); // Inject the hydration code, before a component is hydrated. injectScript('before-hydration', `import '@astrojs/lit/hydration-support.js';`); // Add the lit renderer so that Astro can understand lit components. diff --git a/packages/integrations/partytown/src/index.ts b/packages/integrations/partytown/src/index.ts index bddbeae62..ebd133e33 100644 --- a/packages/integrations/partytown/src/index.ts +++ b/packages/integrations/partytown/src/index.ts @@ -23,10 +23,19 @@ export default function createPlugin(): AstroIntegration { config = _config; }, 'astro:server:setup': ({ server }) => { - server.middlewares.use(sirv(partytownLibDirectory, { mount: '/~partytown', dev: true, etag: true, extensions: [] })); + server.middlewares.use( + sirv(partytownLibDirectory, { + mount: '/~partytown', + dev: true, + etag: true, + extensions: [], + }) + ); }, 'astro:build:done': async () => { - await copyLibFiles(fileURLToPath(new URL('~partytown', config.outDir)), { debugDir: false }); + await copyLibFiles(fileURLToPath(new URL('~partytown', config.outDir)), { + debugDir: false, + }); }, }, }; diff --git a/packages/integrations/partytown/src/sirv.ts b/packages/integrations/partytown/src/sirv.ts index 860a715bf..aab0c7d96 100644 --- a/packages/integrations/partytown/src/sirv.ts +++ b/packages/integrations/partytown/src/sirv.ts @@ -223,7 +223,8 @@ export default function (dir, opts = {}) { } } - let data = lookup(pathname, extns) || (isSPA && !isMatch(pathname, ignores) && lookup(fallback, extns)); + let data = + lookup(pathname, extns) || (isSPA && !isMatch(pathname, ignores) && lookup(fallback, extns)); if (!data) return next ? next() : isNotFound(req, res); if (isEtag && req.headers['if-none-match'] === data.headers['ETag']) { diff --git a/packages/integrations/preact/client.js b/packages/integrations/preact/client.js index 85c18c76c..5ece5ddb2 100644 --- a/packages/integrations/preact/client.js +++ b/packages/integrations/preact/client.js @@ -1,4 +1,8 @@ import { h, render } from 'preact'; import StaticHtml from './static-html.js'; -export default (element) => (Component, props, children) => render(h(Component, props, children != null ? h(StaticHtml, { value: children }) : children), element); +export default (element) => (Component, props, children) => + render( + h(Component, props, children != null ? h(StaticHtml, { value: children }) : children), + element + ); diff --git a/packages/integrations/preact/server.js b/packages/integrations/preact/server.js index 25b1a1530..0729f42e9 100644 --- a/packages/integrations/preact/server.js +++ b/packages/integrations/preact/server.js @@ -25,7 +25,9 @@ function check(Component, props, children) { } function renderToStaticMarkup(Component, props, children) { - const html = render(h(Component, props, children != null ? h(StaticHtml, { value: children }) : children)); + const html = render( + h(Component, props, children != null ? h(StaticHtml, { value: children }) : children) + ); return { html }; } diff --git a/packages/integrations/preact/src/index.ts b/packages/integrations/preact/src/index.ts index c96bf1190..0b0896210 100644 --- a/packages/integrations/preact/src/index.ts +++ b/packages/integrations/preact/src/index.ts @@ -21,7 +21,12 @@ function getRenderer() { function getViteConfiguration() { return { optimizeDeps: { - include: ['@astrojs/preact/client.js', 'preact', 'preact/jsx-runtime', 'preact-render-to-string'], + include: [ + '@astrojs/preact/client.js', + 'preact', + 'preact/jsx-runtime', + 'preact-render-to-string', + ], exclude: ['@astrojs/preact/server.js'], }, ssr: { diff --git a/packages/integrations/react/client-v17.js b/packages/integrations/react/client-v17.js index a6bc7d3bc..64284a0b0 100644 --- a/packages/integrations/react/client-v17.js +++ b/packages/integrations/react/client-v17.js @@ -7,7 +7,9 @@ export default (element) => (Component, props, children) => createElement( Component, { ...props, suppressHydrationWarning: true }, - children != null ? createElement(StaticHtml, { value: children, suppressHydrationWarning: true }) : children + children != null + ? createElement(StaticHtml, { value: children, suppressHydrationWarning: true }) + : children ), element ); diff --git a/packages/integrations/react/client.js b/packages/integrations/react/client.js index 11d63cfcb..7eba8984c 100644 --- a/packages/integrations/react/client.js +++ b/packages/integrations/react/client.js @@ -8,6 +8,8 @@ export default (element) => (Component, props, children) => createElement( Component, { ...props, suppressHydrationWarning: true }, - children != null ? createElement(StaticHtml, { value: children, suppressHydrationWarning: true }) : children + children != null + ? createElement(StaticHtml, { value: children, suppressHydrationWarning: true }) + : children ) ); diff --git a/packages/integrations/react/server-v17.js b/packages/integrations/react/server-v17.js index 1c0c41286..b48d7b6f4 100644 --- a/packages/integrations/react/server-v17.js +++ b/packages/integrations/react/server-v17.js @@ -5,7 +5,11 @@ import StaticHtml from './static-html.js'; const reactTypeof = Symbol.for('react.element'); function errorIsComingFromPreactComponent(err) { - return err.message && (err.message.startsWith("Cannot read property '__H'") || err.message.includes("(reading '__H')")); + return ( + err.message && + (err.message.startsWith("Cannot read property '__H'") || + err.message.includes("(reading '__H')")) + ); } function check(Component, props, children) { diff --git a/packages/integrations/react/server.js b/packages/integrations/react/server.js index e102b57fe..6ae49e7bc 100644 --- a/packages/integrations/react/server.js +++ b/packages/integrations/react/server.js @@ -5,7 +5,11 @@ import StaticHtml from './static-html.js'; const reactTypeof = Symbol.for('react.element'); function errorIsComingFromPreactComponent(err) { - return err.message && (err.message.startsWith("Cannot read property '__H'") || err.message.includes("(reading '__H')")); + return ( + err.message && + (err.message.startsWith("Cannot read property '__H'") || + err.message.includes("(reading '__H')")) + ); } function check(Component, props, children) { diff --git a/packages/integrations/react/src/index.ts b/packages/integrations/react/src/index.ts index 25899a025..a283938c3 100644 --- a/packages/integrations/react/src/index.ts +++ b/packages/integrations/react/src/index.ts @@ -4,8 +4,12 @@ import { version as ReactVersion } from 'react-dom'; function getRenderer() { return { name: '@astrojs/react', - clientEntrypoint: ReactVersion.startsWith('18.') ? '@astrojs/react/client.js' : '@astrojs/react/client-v17.js', - serverEntrypoint: ReactVersion.startsWith('18.') ? '@astrojs/react/server.js' : '@astrojs/react/server-v17.js', + clientEntrypoint: ReactVersion.startsWith('18.') + ? '@astrojs/react/client.js' + : '@astrojs/react/client-v17.js', + serverEntrypoint: ReactVersion.startsWith('18.') + ? '@astrojs/react/server.js' + : '@astrojs/react/server-v17.js', jsxImportSource: 'react', jsxTransformOptions: async () => { const { @@ -34,14 +38,28 @@ function getRenderer() { function getViteConfiguration() { return { optimizeDeps: { - include: [ReactVersion.startsWith('18.') ? '@astrojs/react/client.js' : '@astrojs/react/client-v17.js', 'react', 'react/jsx-runtime', 'react/jsx-dev-runtime', 'react-dom'], - exclude: [ReactVersion.startsWith('18.') ? '@astrojs/react/server.js' : '@astrojs/react/server-v17.js'], + include: [ + ReactVersion.startsWith('18.') + ? '@astrojs/react/client.js' + : '@astrojs/react/client-v17.js', + 'react', + 'react/jsx-runtime', + 'react/jsx-dev-runtime', + 'react-dom', + ], + exclude: [ + ReactVersion.startsWith('18.') + ? '@astrojs/react/server.js' + : '@astrojs/react/server-v17.js', + ], }, resolve: { dedupe: ['react', 'react-dom'], }, ssr: { - external: ReactVersion.startsWith('18.') ? ['react-dom/server', 'react-dom/client'] : ['react-dom/server.js', 'react-dom/client.js'], + external: ReactVersion.startsWith('18.') + ? ['react-dom/server', 'react-dom/client'] + : ['react-dom/server.js', 'react-dom/client.js'], }, }; } diff --git a/packages/integrations/react/static-html.js b/packages/integrations/react/static-html.js index 47130d786..ecd76ae9b 100644 --- a/packages/integrations/react/static-html.js +++ b/packages/integrations/react/static-html.js @@ -9,7 +9,10 @@ import { createElement as h } from 'react'; */ const StaticHtml = ({ value }) => { if (!value) return null; - return h('astro-fragment', { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: value } }); + return h('astro-fragment', { + suppressHydrationWarning: true, + dangerouslySetInnerHTML: { __html: value }, + }); }; /** diff --git a/packages/integrations/sitemap/src/index.ts b/packages/integrations/sitemap/src/index.ts index ef1538ce6..70441cb8e 100644 --- a/packages/integrations/sitemap/src/index.ts +++ b/packages/integrations/sitemap/src/index.ts @@ -38,7 +38,10 @@ function generateSitemap(pages: string[]) { return sitemap; } -export default function createPlugin({ filter, canonicalURL }: SitemapOptions = {}): AstroIntegration { +export default function createPlugin({ + filter, + canonicalURL, +}: SitemapOptions = {}): AstroIntegration { let config: AstroConfig; return { name: '@astrojs/sitemap', @@ -49,7 +52,9 @@ export default function createPlugin({ filter, canonicalURL }: SitemapOptions = 'astro:build:done': async ({ pages, dir }) => { const finalSiteUrl = canonicalURL || config.site; if (!finalSiteUrl) { - console.warn('The Sitemap integration requires either the `site` astro.config option or `canonicalURL` integration option. Skipping.'); + console.warn( + 'The Sitemap integration requires either the `site` astro.config option or `canonicalURL` integration option. Skipping.' + ); return; } let pageUrls = pages.map((p) => new URL(p.pathname, finalSiteUrl).href); diff --git a/packages/integrations/solid/server.js b/packages/integrations/solid/server.js index d32d60a64..ccee482ea 100644 --- a/packages/integrations/solid/server.js +++ b/packages/integrations/solid/server.js @@ -19,7 +19,9 @@ function renderToStaticMarkup(Component, props, children) { children: children != null ? ssr(`<astro-fragment>${children}</astro-fragment>`) : children, }) ); - return { html: html + `<script>window._$HY||(_$HY={events:[],completed:new WeakSet,r:{}})</script>` }; + return { + html: html + `<script>window._$HY||(_$HY={events:[],completed:new WeakSet,r:{}})</script>`, + }; } export default { diff --git a/packages/integrations/svelte/Wrapper.svelte.ssr.js b/packages/integrations/svelte/Wrapper.svelte.ssr.js index 9bca437b5..e6a4781a7 100644 --- a/packages/integrations/svelte/Wrapper.svelte.ssr.js +++ b/packages/integrations/svelte/Wrapper.svelte.ssr.js @@ -8,7 +8,12 @@ const App = create_ssr_component(($$result, $$props, $$bindings, slots) => { children.default = () => `<astro-fragment>${__astro_children}</astro-fragment>`; } - return `${validate_component(Component || missing_component, 'svelte:component').$$render($$result, Object.assign(props), {}, children)}`; + return `${validate_component(Component || missing_component, 'svelte:component').$$render( + $$result, + Object.assign(props), + {}, + children + )}`; }); export default App; diff --git a/packages/integrations/svelte/server.js b/packages/integrations/svelte/server.js index c51b2f4b4..3c989cd5a 100644 --- a/packages/integrations/svelte/server.js +++ b/packages/integrations/svelte/server.js @@ -5,7 +5,11 @@ function check(Component) { } async function renderToStaticMarkup(Component, props, children) { - const { html } = SvelteWrapper.render({ __astro_component: Component, __astro_children: children, ...props }); + const { html } = SvelteWrapper.render({ + __astro_component: Component, + __astro_children: children, + ...props, + }); return { html }; } diff --git a/packages/integrations/tailwind/src/index.ts b/packages/integrations/tailwind/src/index.ts index 2f469b507..3efd8fde8 100644 --- a/packages/integrations/tailwind/src/index.ts +++ b/packages/integrations/tailwind/src/index.ts @@ -67,14 +67,22 @@ export default function tailwindIntegration(options: TailwindOptions): AstroInte const userConfig = await getUserConfig(config.root, customConfigPath); if (customConfigPath && !userConfig?.value) { - throw new Error(`Could not find a Tailwind config at ${JSON.stringify(customConfigPath)}. Does the file exist?`); + throw new Error( + `Could not find a Tailwind config at ${JSON.stringify( + customConfigPath + )}. Does the file exist?` + ); } - const tailwindConfig: TailwindConfig = (userConfig?.value as TailwindConfig) ?? getDefaultTailwindConfig(config.srcDir); + const tailwindConfig: TailwindConfig = + (userConfig?.value as TailwindConfig) ?? getDefaultTailwindConfig(config.srcDir); if (applyAstroConfigPreset && userConfig?.value) { // apply Astro config as a preset to user config // this avoids merging or applying nested spread operators ourselves - tailwindConfig.presets = [getDefaultTailwindConfig(config.srcDir), ...(tailwindConfig.presets || [])]; + tailwindConfig.presets = [ + getDefaultTailwindConfig(config.srcDir), + ...(tailwindConfig.presets || []), + ]; } config.style.postcss.plugins.push(tailwindPlugin(tailwindConfig)); diff --git a/packages/integrations/turbolinks/src/index.ts b/packages/integrations/turbolinks/src/index.ts index 3299736ba..fbf893f68 100644 --- a/packages/integrations/turbolinks/src/index.ts +++ b/packages/integrations/turbolinks/src/index.ts @@ -8,7 +8,10 @@ export default function createPlugin(): AstroIntegration { // This gets injected into the user's page, so we need to re-export Turbolinks // from our own package so that package managers like pnpm don't get mad and // can follow the import correctly. - injectScript('page', `import {Turbolinks} from "@astrojs/turbolinks/client.js"; Turbolinks.start();`); + injectScript( + 'page', + `import {Turbolinks} from "@astrojs/turbolinks/client.js"; Turbolinks.start();` + ); }, }, }; diff --git a/packages/markdown/remark/src/index.ts b/packages/markdown/remark/src/index.ts index 0fb398bc7..c15cf502d 100644 --- a/packages/markdown/remark/src/index.ts +++ b/packages/markdown/remark/src/index.ts @@ -23,7 +23,10 @@ import matter from 'gray-matter'; export { AstroMarkdownOptions, MarkdownRenderingOptions, ShikiConfig, Plugin }; /** Internal utility for rendering a full markdown file and extracting Frontmatter data */ -export async function renderMarkdownWithFrontmatter(contents: string, opts?: MarkdownRenderingOptions | null) { +export async function renderMarkdownWithFrontmatter( + contents: string, + opts?: MarkdownRenderingOptions | null +) { const { data: frontmatter, content } = matter(contents); const value = await renderMarkdown(content, opts); return { ...value, frontmatter }; @@ -73,7 +76,15 @@ export async function renderMarkdown(content: string, opts?: MarkdownRenderingOp parser.use([remarkPrism(scopedClassName)]); } - parser.use([[markdownToHtml as any, { allowDangerousHtml: true, passThrough: ['raw', 'mdxTextExpression', 'mdxJsxTextElement', 'mdxJsxFlowElement'] }]]); + parser.use([ + [ + markdownToHtml as any, + { + allowDangerousHtml: true, + passThrough: ['raw', 'mdxTextExpression', 'mdxJsxTextElement', 'mdxJsxFlowElement'], + }, + ], + ]); loadedRehypePlugins.forEach(([plugin, opts]) => { parser.use([[plugin, opts]]); @@ -88,7 +99,10 @@ export async function renderMarkdown(content: string, opts?: MarkdownRenderingOp let result: string; try { - const vfile = await parser.use([rehypeCollectHeaders]).use(rehypeStringify, { allowDangerousHtml: true }).process(content); + const vfile = await parser + .use([rehypeCollectHeaders]) + .use(rehypeStringify, { allowDangerousHtml: true }) + .process(content); result = vfile.toString(); } catch (err) { console.error(err); diff --git a/packages/markdown/remark/src/rehype-islands.ts b/packages/markdown/remark/src/rehype-islands.ts index 868f9096e..bbd584792 100644 --- a/packages/markdown/remark/src/rehype-islands.ts +++ b/packages/markdown/remark/src/rehype-islands.ts @@ -2,7 +2,11 @@ import { SKIP, visit as _visit } from 'unist-util-visit'; // This is a workaround. // It fixes a compatibility issue between different, incompatible ASTs given by plugins to Unist -const visit = _visit as (node: any, type: string, callback?: (node: any, index: number, parent: any) => any) => any; +const visit = _visit as ( + node: any, + type: string, + callback?: (node: any, index: number, parent: any) => any +) => any; // This fixes some confusing bugs coming from somewhere inside of our Markdown pipeline. // `unist`/`remark`/`rehype` (not sure) often generate malformed HTML inside of <astro-root> @@ -18,7 +22,11 @@ export default function rehypeIslands(): any { // Sometimes comments can be trapped as text, which causes them to be escaped // This casts them back to real HTML comments if (parent && child.value.indexOf('<!--') > -1 && index != null) { - parent.children.splice(index, 1, { ...child, type: 'comment', value: child.value.replace('<!--', '').replace('-->', '').trim() }); + parent.children.splice(index, 1, { + ...child, + type: 'comment', + value: child.value.replace('<!--', '').replace('-->', '').trim(), + }); return [SKIP, index]; } // For some reason `rehype` likes to inject extra linebreaks, diff --git a/packages/markdown/remark/src/remark-prism.ts b/packages/markdown/remark/src/remark-prism.ts index 6d3e4e664..544de1540 100644 --- a/packages/markdown/remark/src/remark-prism.ts +++ b/packages/markdown/remark/src/remark-prism.ts @@ -56,7 +56,9 @@ function transformer(className: MaybeString) { if (className) { classes.push(className); } - node.value = `<pre class="${classes.join(' ')}"><code is:raw class="${classLanguage}">${html}</code></pre>`; + node.value = `<pre class="${classes.join( + ' ' + )}"><code is:raw class="${classLanguage}">${html}</code></pre>`; return node; }; return visit(tree, 'code', visitor); diff --git a/packages/markdown/remark/src/remark-shiki.ts b/packages/markdown/remark/src/remark-shiki.ts index f34fa26ef..314a0e38e 100644 --- a/packages/markdown/remark/src/remark-shiki.ts +++ b/packages/markdown/remark/src/remark-shiki.ts @@ -37,7 +37,10 @@ export interface ShikiConfig { */ const highlighterCacheAsync = new Map<string, Promise<shiki.Highlighter>>(); -const remarkShiki = async ({ langs = [], theme = 'github-dark', wrap = false }: ShikiConfig, scopedClassName?: string | null) => { +const remarkShiki = async ( + { langs = [], theme = 'github-dark', wrap = false }: ShikiConfig, + scopedClassName?: string | null +) => { const cacheID: string = typeof theme === 'string' ? theme : theme.name; let highlighterAsync = highlighterCacheAsync.get(cacheID); if (!highlighterAsync) { @@ -63,15 +66,24 @@ const remarkShiki = async ({ langs = [], theme = 'github-dark', wrap = false }: // <span class="line" // Replace "shiki" class naming with "astro" and add "is:raw". - html = html.replace('<pre class="shiki"', `<pre is:raw class="astro-code${scopedClassName ? ' ' + scopedClassName : ''}"`); + html = html.replace( + '<pre class="shiki"', + `<pre is:raw class="astro-code${scopedClassName ? ' ' + scopedClassName : ''}"` + ); // Replace "shiki" css variable naming with "astro". - html = html.replace(/style="(background-)?color: var\(--shiki-/g, 'style="$1color: var(--astro-code-'); + html = html.replace( + /style="(background-)?color: var\(--shiki-/g, + 'style="$1color: var(--astro-code-' + ); // Handle code wrapping // if wrap=null, do nothing. if (wrap === false) { html = html.replace(/style="(.*?)"/, 'style="$1; overflow-x: auto;"'); } else if (wrap === true) { - html = html.replace(/style="(.*?)"/, 'style="$1; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;"'); + html = html.replace( + /style="(.*?)"/, + 'style="$1; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;"' + ); } // Apply scopedClassName to all nested lines diff --git a/packages/markdown/remark/src/remark-unwrap.ts b/packages/markdown/remark/src/remark-unwrap.ts index 6da2a496a..3ce7a72c0 100644 --- a/packages/markdown/remark/src/remark-unwrap.ts +++ b/packages/markdown/remark/src/remark-unwrap.ts @@ -2,7 +2,11 @@ import { visit as _visit, SKIP } from 'unist-util-visit'; // This is a workaround. // It fixes a compatibility issue between different, incompatible ASTs given by plugins to Unist -const visit = _visit as (node: any, type: string, callback?: (node: any, index: number, parent: any) => any) => any; +const visit = _visit as ( + node: any, + type: string, + callback?: (node: any, index: number, parent: any) => any +) => any; // Remove the wrapping paragraph for <astro-root> islands export default function remarkUnwrap() { @@ -33,6 +37,8 @@ export default function remarkUnwrap() { }; function containsAstroRootNode(node: any) { - return node.children.map((child: any) => astroRootNodes.has(child)).reduce((all: boolean, v: boolean) => (all ? all : v), false); + return node.children + .map((child: any) => astroRootNodes.has(child)) + .reduce((all: boolean, v: boolean) => (all ? all : v), false); } } diff --git a/packages/renderers/renderer-lit/client-shim.js b/packages/renderers/renderer-lit/client-shim.js index cab3fe4d9..e9cf1aecf 100644 --- a/packages/renderers/renderer-lit/client-shim.js +++ b/packages/renderers/renderer-lit/client-shim.js @@ -1,9 +1,15 @@ async function polyfill() { - const { hydrateShadowRoots } = await import('@webcomponents/template-shadowroot/template-shadowroot.js'); + const { hydrateShadowRoots } = await import( + '@webcomponents/template-shadowroot/template-shadowroot.js' + ); hydrateShadowRoots(document.body); } -const polyfillCheckEl = new DOMParser().parseFromString(`<p><template shadowroot="open"></template></p>`, 'text/html', { includeShadowRoots: true }).querySelector('p'); +const polyfillCheckEl = new DOMParser() + .parseFromString(`<p><template shadowroot="open"></template></p>`, 'text/html', { + includeShadowRoots: true, + }) + .querySelector('p'); if (!polyfillCheckEl || !polyfillCheckEl.shadowRoot) { polyfill(); diff --git a/packages/renderers/renderer-lit/index.js b/packages/renderers/renderer-lit/index.js index e6abec137..b051bc3a5 100644 --- a/packages/renderers/renderer-lit/index.js +++ b/packages/renderers/renderer-lit/index.js @@ -3,7 +3,9 @@ const NODE_VERSION = parseFloat(process.versions.node); if (NODE_VERSION < 13.9) { - throw new Error(`Package @lit-labs/ssr requires Node version v13.9 or higher. Please update Node to use @astrojs/renderer-lit`); + throw new Error( + `Package @lit-labs/ssr requires Node version v13.9 or higher. Please update Node to use @astrojs/renderer-lit` + ); } export default { diff --git a/packages/renderers/renderer-preact/client.js b/packages/renderers/renderer-preact/client.js index 85c18c76c..5ece5ddb2 100644 --- a/packages/renderers/renderer-preact/client.js +++ b/packages/renderers/renderer-preact/client.js @@ -1,4 +1,8 @@ import { h, render } from 'preact'; import StaticHtml from './static-html.js'; -export default (element) => (Component, props, children) => render(h(Component, props, children != null ? h(StaticHtml, { value: children }) : children), element); +export default (element) => (Component, props, children) => + render( + h(Component, props, children != null ? h(StaticHtml, { value: children }) : children), + element + ); diff --git a/packages/renderers/renderer-preact/compat/index.js b/packages/renderers/renderer-preact/compat/index.js index 3f993ec2f..a5580f04d 100644 --- a/packages/renderers/renderer-preact/compat/index.js +++ b/packages/renderers/renderer-preact/compat/index.js @@ -21,7 +21,12 @@ export default { dedupe: ['react', 'react-dom'], }, optimizeDeps: { - include: ['@astrojs/renderer-preact/client.js', 'preact/compat', 'preact/compat/jsx-runtime', 'preact-render-to-string'], + include: [ + '@astrojs/renderer-preact/client.js', + 'preact/compat', + 'preact/compat/jsx-runtime', + 'preact-render-to-string', + ], }, ssr: { external: ['preact-render-to-string'], diff --git a/packages/renderers/renderer-preact/index.js b/packages/renderers/renderer-preact/index.js index 59e900ebe..fe0a24528 100644 --- a/packages/renderers/renderer-preact/index.js +++ b/packages/renderers/renderer-preact/index.js @@ -14,7 +14,12 @@ export default { viteConfig() { return { optimizeDeps: { - include: ['@astrojs/renderer-preact/client.js', 'preact', 'preact/jsx-runtime', 'preact-render-to-string'], + include: [ + '@astrojs/renderer-preact/client.js', + 'preact', + 'preact/jsx-runtime', + 'preact-render-to-string', + ], exclude: ['@astrojs/renderer-preact/server.js'], }, ssr: { diff --git a/packages/renderers/renderer-preact/server.js b/packages/renderers/renderer-preact/server.js index 25b1a1530..0729f42e9 100644 --- a/packages/renderers/renderer-preact/server.js +++ b/packages/renderers/renderer-preact/server.js @@ -25,7 +25,9 @@ function check(Component, props, children) { } function renderToStaticMarkup(Component, props, children) { - const html = render(h(Component, props, children != null ? h(StaticHtml, { value: children }) : children)); + const html = render( + h(Component, props, children != null ? h(StaticHtml, { value: children }) : children) + ); return { html }; } diff --git a/packages/renderers/renderer-react/client.js b/packages/renderers/renderer-react/client.js index a6bc7d3bc..64284a0b0 100644 --- a/packages/renderers/renderer-react/client.js +++ b/packages/renderers/renderer-react/client.js @@ -7,7 +7,9 @@ export default (element) => (Component, props, children) => createElement( Component, { ...props, suppressHydrationWarning: true }, - children != null ? createElement(StaticHtml, { value: children, suppressHydrationWarning: true }) : children + children != null + ? createElement(StaticHtml, { value: children, suppressHydrationWarning: true }) + : children ), element ); diff --git a/packages/renderers/renderer-react/index.js b/packages/renderers/renderer-react/index.js index 6dd5106dc..698f2a13c 100644 --- a/packages/renderers/renderer-react/index.js +++ b/packages/renderers/renderer-react/index.js @@ -22,7 +22,13 @@ export default { viteConfig() { return { optimizeDeps: { - include: ['@astrojs/renderer-react/client.js', 'react', 'react/jsx-runtime', 'react/jsx-dev-runtime', 'react-dom'], + include: [ + '@astrojs/renderer-react/client.js', + 'react', + 'react/jsx-runtime', + 'react/jsx-dev-runtime', + 'react-dom', + ], exclude: ['@astrojs/renderer-react/server.js'], }, resolve: { diff --git a/packages/renderers/renderer-react/server.js b/packages/renderers/renderer-react/server.js index 1c0c41286..b48d7b6f4 100644 --- a/packages/renderers/renderer-react/server.js +++ b/packages/renderers/renderer-react/server.js @@ -5,7 +5,11 @@ import StaticHtml from './static-html.js'; const reactTypeof = Symbol.for('react.element'); function errorIsComingFromPreactComponent(err) { - return err.message && (err.message.startsWith("Cannot read property '__H'") || err.message.includes("(reading '__H')")); + return ( + err.message && + (err.message.startsWith("Cannot read property '__H'") || + err.message.includes("(reading '__H')")) + ); } function check(Component, props, children) { diff --git a/packages/renderers/renderer-react/static-html.js b/packages/renderers/renderer-react/static-html.js index 47130d786..ecd76ae9b 100644 --- a/packages/renderers/renderer-react/static-html.js +++ b/packages/renderers/renderer-react/static-html.js @@ -9,7 +9,10 @@ import { createElement as h } from 'react'; */ const StaticHtml = ({ value }) => { if (!value) return null; - return h('astro-fragment', { suppressHydrationWarning: true, dangerouslySetInnerHTML: { __html: value } }); + return h('astro-fragment', { + suppressHydrationWarning: true, + dangerouslySetInnerHTML: { __html: value }, + }); }; /** diff --git a/packages/renderers/renderer-solid/index.js b/packages/renderers/renderer-solid/index.js index b0b9aaab5..42715ffe6 100644 --- a/packages/renderers/renderer-solid/index.js +++ b/packages/renderers/renderer-solid/index.js @@ -18,7 +18,13 @@ export default { // We inject the dev mode only if the user explicitely wants it or if we are in dev (serve) mode const replaceDev = options.mode === 'development' || options.command === 'serve'; - const nestedDeps = ['solid-js', 'solid-js/web', 'solid-js/store', 'solid-js/html', 'solid-js/h']; + const nestedDeps = [ + 'solid-js', + 'solid-js/web', + 'solid-js/store', + 'solid-js/html', + 'solid-js/h', + ]; return { /** diff --git a/packages/renderers/renderer-solid/server.js b/packages/renderers/renderer-solid/server.js index d32d60a64..ccee482ea 100644 --- a/packages/renderers/renderer-solid/server.js +++ b/packages/renderers/renderer-solid/server.js @@ -19,7 +19,9 @@ function renderToStaticMarkup(Component, props, children) { children: children != null ? ssr(`<astro-fragment>${children}</astro-fragment>`) : children, }) ); - return { html: html + `<script>window._$HY||(_$HY={events:[],completed:new WeakSet,r:{}})</script>` }; + return { + html: html + `<script>window._$HY||(_$HY={events:[],completed:new WeakSet,r:{}})</script>`, + }; } export default { diff --git a/packages/renderers/renderer-svelte/Wrapper.svelte.ssr.js b/packages/renderers/renderer-svelte/Wrapper.svelte.ssr.js index 9bca437b5..e6a4781a7 100644 --- a/packages/renderers/renderer-svelte/Wrapper.svelte.ssr.js +++ b/packages/renderers/renderer-svelte/Wrapper.svelte.ssr.js @@ -8,7 +8,12 @@ const App = create_ssr_component(($$result, $$props, $$bindings, slots) => { children.default = () => `<astro-fragment>${__astro_children}</astro-fragment>`; } - return `${validate_component(Component || missing_component, 'svelte:component').$$render($$result, Object.assign(props), {}, children)}`; + return `${validate_component(Component || missing_component, 'svelte:component').$$render( + $$result, + Object.assign(props), + {}, + children + )}`; }); export default App; diff --git a/packages/renderers/renderer-svelte/server.js b/packages/renderers/renderer-svelte/server.js index c51b2f4b4..3c989cd5a 100644 --- a/packages/renderers/renderer-svelte/server.js +++ b/packages/renderers/renderer-svelte/server.js @@ -5,7 +5,11 @@ function check(Component) { } async function renderToStaticMarkup(Component, props, children) { - const { html } = SvelteWrapper.render({ __astro_component: Component, __astro_children: children, ...props }); + const { html } = SvelteWrapper.render({ + __astro_component: Component, + __astro_children: children, + ...props, + }); return { html }; } diff --git a/scripts/cmd/build.js b/scripts/cmd/build.js index 3a182c656..b2d402890 100644 --- a/scripts/cmd/build.js +++ b/scripts/cmd/build.js @@ -26,9 +26,17 @@ export default async function build(...args) { const patterns = args .filter((f) => !!f) // remove empty args .map((f) => f.replace(/^'/, '').replace(/'$/, '')); // Needed for Windows: glob strings contain surrounding string chars??? remove these - let entryPoints = [].concat(...(await Promise.all(patterns.map((pattern) => glob(pattern, { filesOnly: true, absolute: true }))))); + let entryPoints = [].concat( + ...(await Promise.all( + patterns.map((pattern) => glob(pattern, { filesOnly: true, absolute: true })) + )) + ); - const { type = 'module', version, dependencies = {} } = await fs.readFile('./package.json').then((res) => JSON.parse(res.toString())); + const { + type = 'module', + version, + dependencies = {}, + } = await fs.readFile('./package.json').then((res) => JSON.parse(res.toString())); // expose PACKAGE_VERSION on process.env for CLI utils config.define = { 'process.env.PACKAGE_VERSION': JSON.stringify(version) }; const format = type === 'module' ? 'esm' : 'cjs'; @@ -56,7 +64,9 @@ export default async function build(...args) { console.error(dim(`[${date}] `) + red(error || result.errors.join('\n'))); } else { if (result.warnings.length) { - console.log(dim(`[${date}] `) + yellow('⚠ updated with warnings:\n' + result.warnings.join('\n'))); + console.log( + dim(`[${date}] `) + yellow('⚠ updated with warnings:\n' + result.warnings.join('\n')) + ); } console.log(dim(`[${date}] `) + green('✔ updated')); } diff --git a/scripts/cmd/copy.js b/scripts/cmd/copy.js index 925990fe4..1700e56c4 100644 --- a/scripts/cmd/copy.js +++ b/scripts/cmd/copy.js @@ -63,7 +63,9 @@ export default async function copy() { await Promise.all( files.map((file) => { const dest = resolve(file.replace(/^[^/]+/, 'dist')); - return fs.mkdir(dirname(dest), { recursive: true }).then(() => fs.copyFile(resolve(file), dest)); + return fs + .mkdir(dirname(dest), { recursive: true }) + .then(() => fs.copyFile(resolve(file), dest)); }) ); } diff --git a/scripts/memory/index.js b/scripts/memory/index.js index a1e34e144..da55acb71 100644 --- a/scripts/memory/index.js +++ b/scripts/memory/index.js @@ -35,7 +35,9 @@ const startSize = v8.getHeapStatistics().used_heap_size; // HUMAN mode: Runs forever. Optimized for accurate results on each snapshot Slower than CI. if (!isCI) { - console.log(`Greetings, human. This test will run forever. Run with the "--ci" flag to finish with a result.`); + console.log( + `Greetings, human. This test will run forever. Run with the "--ci" flag to finish with a result.` + ); let i = 1; while (i++) { await run(); @@ -62,7 +64,9 @@ const TEST_THRESHOLD = 1.5; const isPass = percentage < TEST_THRESHOLD; console.log(``); console.log(`Result: ${isPass ? 'PASS' : 'FAIL'} (${percentage * 100}%)`); -console.log(`Memory usage began at ${prettyBytes(startSize)} and finished at ${prettyBytes(endSize)}.`); +console.log( + `Memory usage began at ${prettyBytes(startSize)} and finished at ${prettyBytes(endSize)}.` +); console.log(`The threshold for a probable memory leak is ${TEST_THRESHOLD * 100}%`); console.log(``); console.log(`Exiting...`); diff --git a/scripts/notify/index.js b/scripts/notify/index.js index a0505c9ae..fa699372a 100755 --- a/scripts/notify/index.js +++ b/scripts/notify/index.js @@ -5,7 +5,16 @@ import { readFile } from 'node:fs/promises'; const baseUrl = new URL('https://github.com/withastro/astro/blob/main/'); const emojis = ['🎉', '🥳', '🚀', '🧑🚀', '🎊', '🏆', '✅', '🤩', '🤖', '🙌']; -const descriptors = ['new releases', 'hot and fresh updates', 'shiny updates', 'exciting changes', 'package updates', 'awesome updates', 'bug fixes and features', 'updates']; +const descriptors = [ + 'new releases', + 'hot and fresh updates', + 'shiny updates', + 'exciting changes', + 'package updates', + 'awesome updates', + 'bug fixes and features', + 'updates', +]; const verbs = [ 'just went out!', 'just launched!', @@ -47,7 +56,9 @@ const plurals = new Map([ ]); function pluralize(text) { - return text.replace(/(\[([^\]]+)\])/gm, (_, _full, match) => (plurals.has(match) ? plurals.get(match) : `${match}s`)); + return text.replace(/(\[([^\]]+)\])/gm, (_, _full, match) => + plurals.has(match) ? plurals.get(match) : `${match}s` + ); } function singularlize(text) { @@ -57,7 +68,9 @@ function singularlize(text) { const packageMap = new Map(); async function generatePackageMap() { const packageRoot = new URL('../../packages/', import.meta.url); - const packages = await glob(['*/package.json', '*/*/package.json'], { cwd: fileURLToPath(packageRoot) }); + const packages = await glob(['*/package.json', '*/*/package.json'], { + cwd: fileURLToPath(packageRoot), + }); await Promise.all( packages.map(async (pkg) => { const pkgFile = fileURLToPath(new URL(pkg, packageRoot)); @@ -77,7 +90,11 @@ async function run() { if (!p) { throw new Error(`Unable to find entrypoint for "${name}"!`); } - return { name, version, url: new URL(`${p}/CHANGELOG.md#${version.replace(/\./g, '')}`, baseUrl).toString() }; + return { + name, + version, + url: new URL(`${p}/CHANGELOG.md#${version.replace(/\./g, '')}`, baseUrl).toString(), + }; }) ); @@ -87,7 +104,9 @@ async function run() { if (packages.length === 1) { const { name, version, url } = packages[0]; - console.log(`${emoji} \`${name}@${version}\` ${singularlize(verb)}\nRead the [release notes →](<${url}>)`); + console.log( + `${emoji} \`${name}@${version}\` ${singularlize(verb)}\nRead the [release notes →](<${url}>)` + ); } else { console.log(`${emoji} Some ${descriptor} ${pluralize(verb)}\n`); for (const { name, version, url } of packages) { diff --git a/scripts/stats/index.js b/scripts/stats/index.js index 435bb5c56..659df2f2b 100644 --- a/scripts/stats/index.js +++ b/scripts/stats/index.js @@ -78,12 +78,21 @@ export async function run() { per_page: 100, since: twentyFourHoursAgo.toISOString(), }); - const issuesLastTwentyFourHours = allIssuesLastTwentyFourHours.filter((iss) => new Date(iss.created_at) > twentyFourHoursAgo && !iss.pull_request); - const pullsLastTwentyFourHours = allIssuesLastTwentyFourHours.filter((iss) => new Date(iss.created_at) > twentyFourHoursAgo && iss.pull_request); + const issuesLastTwentyFourHours = allIssuesLastTwentyFourHours.filter( + (iss) => new Date(iss.created_at) > twentyFourHoursAgo && !iss.pull_request + ); + const pullsLastTwentyFourHours = allIssuesLastTwentyFourHours.filter( + (iss) => new Date(iss.created_at) > twentyFourHoursAgo && iss.pull_request + ); const entry = [ // Date (Human Readable) - `"${new Date().toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}"`, + `"${new Date().toLocaleDateString('en-US', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric', + })}"`, // Commits in last 24 hours (await countCommits(twentyFourHoursAgo)).length, // New Issues(All) in last 24 hours @@ -103,7 +112,8 @@ export async function run() { // Bugs: Needs Triage (await countCards(COLUMN_ID_BUGS_NEEDS_TRIAGE)).length, // Bugs: Accepted - (await countCards(COLUMN_ID_BUGS_ACCEPTED)).length + (await countCards(COLUMN_ID_BUGS_PRIORITIZED)).length, + (await countCards(COLUMN_ID_BUGS_ACCEPTED)).length + + (await countCards(COLUMN_ID_BUGS_PRIORITIZED)).length, // RFC: In Progress 0, // (await countCards(COLUMN_ID_RFCS_IN_PROGRESS)).length, // RFC: Accepted diff --git a/scripts/utils/svelte-plugin.js b/scripts/utils/svelte-plugin.js index 29e60c2d5..4bbd8cdaf 100644 --- a/scripts/utils/svelte-plugin.js +++ b/scripts/utils/svelte-plugin.js @@ -26,7 +26,12 @@ const handleLoad = async (args, generate, { isDev }) => { let { js, warnings } = compile(source, { ...compileOptions, filename }); let contents = js.code + `\n//# sourceMappingURL=` + js.map.toUrl(); - return { loader: 'js', contents, resolveDir: dirname(path), warnings: warnings.map((w) => convertMessage(w)) }; + return { + loader: 'js', + contents, + resolveDir: dirname(path), + warnings: warnings.map((w) => convertMessage(w)), + }; } catch (e) { return { errors: [convertMessage(e)] }; } @@ -54,8 +59,12 @@ export default function sveltePlugin({ isDev = false }) { }; } }); - build.onLoad({ filter: /.*/, namespace: 'svelte:client' }, (args) => handleLoad(args, 'dom', { isDev })); - build.onLoad({ filter: /.*/, namespace: 'svelte:server' }, (args) => handleLoad(args, 'ssr', { isDev })); + build.onLoad({ filter: /.*/, namespace: 'svelte:client' }, (args) => + handleLoad(args, 'dom', { isDev }) + ); + build.onLoad({ filter: /.*/, namespace: 'svelte:server' }, (args) => + handleLoad(args, 'ssr', { isDev }) + ); }, }; } |