diff --git a/examples/ssr/astro.config.mjs b/examples/ssr/astro.config.mjs index 4b01264ec..fd25be136 100644 --- a/examples/ssr/astro.config.mjs +++ b/examples/ssr/astro.config.mjs @@ -5,13 +5,13 @@ export default defineConfig({ vite: { server: { cors: { - credentials: true + credentials: true, }, proxy: { '/api': { target: 'http://127.0.0.1:8085', changeOrigin: true, - } + }, }, }, }, diff --git a/examples/ssr/server/api.mjs b/examples/ssr/server/api.mjs index 9bb0be72a..589766ee9 100644 --- a/examples/ssr/server/api.mjs +++ b/examples/ssr/server/api.mjs @@ -41,36 +41,36 @@ const routes = [ match: /\/api\/cart/, async handle(req, res) { res.writeHead(200, { - 'Content-Type': 'application/json' + 'Content-Type': 'application/json', }); let cookie = req.headers.cookie; let userId = cookie ? lightcookie.parse(cookie)['user-id'] : '1'; // default for testing - if(!userId || !userCartItems.has(userId)) { + if (!userId || !userCartItems.has(userId)) { res.end(JSON.stringify({ items: [] })); return; } let items = userCartItems.get(userId); let array = Array.from(items.values()); res.end(JSON.stringify({ items: array })); - } + }, }, { match: /\/api\/add-to-cart/, async handle(req, res) { let body = ''; - req.on('data', chunk => body += chunk); - return new Promise(resolve => { + req.on('data', (chunk) => (body += chunk)); + return new Promise((resolve) => { req.on('end', () => { let cookie = req.headers.cookie; let userId = lightcookie.parse(cookie)['user-id']; let msg = JSON.parse(body); - if(!userCartItems.has(userId)) { + if (!userCartItems.has(userId)) { userCartItems.set(userId, new Map()); } let cart = userCartItems.get(userId); - if(cart.has(msg.id)) { + if (cart.has(msg.id)) { cart.get(msg.id).count++; } else { cart.set(msg.id, { id: msg.id, name: msg.name, count: 1 }); @@ -82,8 +82,8 @@ const routes = [ res.end(JSON.stringify({ ok: true })); }); }); - } - } + }, + }, ]; export async function apiHandler(req, res) { diff --git a/examples/ssr/src/api.ts b/examples/ssr/src/api.ts index b71990f3f..40058360b 100644 --- a/examples/ssr/src/api.ts +++ b/examples/ssr/src/api.ts @@ -22,7 +22,7 @@ const origin = MODE === 'development' ? `http://127.0.0.1:3000` : `http://127.0. async function get(endpoint: string, cb: (response: Response) => Promise): Promise { const response = await fetch(`${origin}${endpoint}`, { - credentials: 'same-origin' + credentials: 'same-origin', }); if (!response.ok) { // TODO make this better... @@ -46,14 +46,14 @@ export async function getProduct(id: number): Promise { } export async function getUser(): Promise { - return get(`/api/user`, async response => { + return get(`/api/user`, async (response) => { const user: User = await response.json(); return user; }); } export async function getCart(): Promise { - return get(`/api/cart`, async response => { + return get(`/api/cart`, async (response) => { const cart: Cart = await response.json(); return cart; }); @@ -66,11 +66,11 @@ export async function addToUserCart(id: number | string, name: string): Promise< mode: 'no-cors', headers: { 'Content-Type': 'application/json', - 'Cache': 'no-cache' + Cache: 'no-cache', }, body: JSON.stringify({ id, - name - }) + name, + }), }); } diff --git a/examples/ssr/src/models/user.ts b/examples/ssr/src/models/user.ts index ecd839d46..a2812a8ad 100644 --- a/examples/ssr/src/models/user.ts +++ b/examples/ssr/src/models/user.ts @@ -1,6 +1,5 @@ import lightcookie from 'lightcookie'; - export function isLoggedIn(request: Request): boolean { const cookie = request.headers.get('cookie'); const parsed = lightcookie.parse(cookie); diff --git a/examples/ssr/src/pages/login.form.js b/examples/ssr/src/pages/login.form.js index 9875ae160..134b0185f 100644 --- a/examples/ssr/src/pages/login.form.js +++ b/examples/ssr/src/pages/login.form.js @@ -1,10 +1,9 @@ - export function post(params, request) { return new Response(null, { status: 301, headers: { - 'Location': '/', - 'Set-Cookie': 'user-id=1; Path=/; Max-Age=2592000' - } + Location: '/', + 'Set-Cookie': 'user-id=1; Path=/; Max-Age=2592000', + }, }); } diff --git a/packages/astro/src/core/app/index.ts b/packages/astro/src/core/app/index.ts index fc5ffcced..fab55c9af 100644 --- a/packages/astro/src/core/app/index.ts +++ b/packages/astro/src/core/app/index.ts @@ -37,7 +37,7 @@ export class App { if (!routeData) { return new Response(null, { status: 404, - statusText: 'Not found' + statusText: 'Not found', }); } } @@ -75,13 +75,13 @@ export class App { headers: request.headers, }); - if(result.type === 'response') { + if (result.type === 'response') { return result.response; } let html = result.html; return new Response(html, { - status: 200 + status: 200, }); } async #loadRenderers(): Promise { diff --git a/packages/astro/src/core/app/node.ts b/packages/astro/src/core/app/node.ts index 46ba710c2..8d6968c69 100644 --- a/packages/astro/src/core/app/node.ts +++ b/packages/astro/src/core/app/node.ts @@ -11,7 +11,7 @@ function createRequestFromNodeRequest(req: IncomingMessage): Request { const entries = Object.entries(req.headers as Record); let request = new Request(url, { method: req.method || 'GET', - headers: new Headers(entries) + headers: new Headers(entries), }); return request; } diff --git a/packages/astro/src/core/build/static-build.ts b/packages/astro/src/core/build/static-build.ts index ea4c89011..3c75435a7 100644 --- a/packages/astro/src/core/build/static-build.ts +++ b/packages/astro/src/core/build/static-build.ts @@ -402,23 +402,22 @@ async function generatePath(pathname: string, opts: StaticBuildOptions, gopts: G route: pageData.route, routeCache, site: astroConfig.buildOptions.site, - ssr: opts.astroConfig.buildOptions.experimentalSsr - } + ssr: opts.astroConfig.buildOptions.experimentalSsr, + }; let body: string; - if(pageData.route.type === 'endpoint') { - + if (pageData.route.type === 'endpoint') { const result = await callEndpoint(mod as unknown as EndpointHandler, options); - if(result.type === 'response') { - throw new Error(`Returning a Response from an endpoint is not supported in SSG mode.`) + if (result.type === 'response') { + throw new Error(`Returning a Response from an endpoint is not supported in SSG mode.`); } body = result.body; } else { const result = await render(options); // If there's a redirect or something, just do nothing. - if(result.type !== 'html') { + if (result.type !== 'html') { return; } body = result.html; diff --git a/packages/astro/src/core/endpoint/dev/index.ts b/packages/astro/src/core/endpoint/dev/index.ts index d05ae3f5f..3190a500f 100644 --- a/packages/astro/src/core/endpoint/dev/index.ts +++ b/packages/astro/src/core/endpoint/dev/index.ts @@ -7,15 +7,13 @@ import { call as callEndpoint } from '../index.js'; import { getParamsAndProps, GetParamsAndPropsError } from '../../render/core.js'; import { createRequest } from '../../render/request.js'; - export async function call(ssrOpts: SSROptions) { try { const [, mod] = await preload(ssrOpts); return await callEndpoint(mod as unknown as EndpointHandler, { ...ssrOpts, - ssr: ssrOpts.astroConfig.buildOptions.experimentalSsr + ssr: ssrOpts.astroConfig.buildOptions.experimentalSsr, }); - } catch (e: unknown) { await errorHandler(e, { viteServer: ssrOpts.viteServer, filePath: ssrOpts.filePath }); throw e; diff --git a/packages/astro/src/core/endpoint/index.ts b/packages/astro/src/core/endpoint/index.ts index f10efcc9f..745811354 100644 --- a/packages/astro/src/core/endpoint/index.ts +++ b/packages/astro/src/core/endpoint/index.ts @@ -4,48 +4,38 @@ import { renderEndpoint } from '../../runtime/server/index.js'; import { getParamsAndProps, GetParamsAndPropsError } from '../render/core.js'; import { createRequest } from '../render/request.js'; -export type EndpointOptions = Pick; +export type EndpointOptions = Pick; -type EndpointCallResult = { - type: 'simple', - body: string -} | { - type: 'response', - response: Response -}; +type EndpointCallResult = + | { + type: 'simple'; + body: string; + } + | { + type: 'response'; + response: Response; + }; export async function call(mod: EndpointHandler, opts: EndpointOptions): Promise { - const paramsAndPropsResp = await getParamsAndProps({ ...opts, mod: (mod as any) }); + 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})`); } const [params] = paramsAndPropsResp; - const request = createRequest(opts.method, opts.pathname, opts.headers, opts.origin, - opts.site, opts.ssr); + const request = createRequest(opts.method, opts.pathname, opts.headers, opts.origin, opts.site, opts.ssr); const response = await renderEndpoint(mod, request, params); - if(response instanceof Response) { + if (response instanceof Response) { return { type: 'response', - response + response, }; } return { type: 'simple', - body: response.body + body: response.body, }; } diff --git a/packages/astro/src/core/render/core.ts b/packages/astro/src/core/render/core.ts index 71b4d03e7..7d969240c 100644 --- a/packages/astro/src/core/render/core.ts +++ b/packages/astro/src/core/render/core.ts @@ -74,7 +74,7 @@ export interface RenderOptions { headers: Headers; } -export async function render(opts: RenderOptions): Promise<{ type: 'html', html: string } | { type: 'response', response: Response }> { +export async function render(opts: RenderOptions): Promise<{ type: 'html'; html: string } | { type: 'response'; response: Response }> { const { headers, legacyBuild, links, logging, origin, markdownRender, method, mod, pathname, scripts, renderers, resolve, route, routeCache, site, ssr } = opts; const paramsAndPropsRes = await getParamsAndProps({ @@ -109,12 +109,12 @@ export async function render(opts: RenderOptions): Promise<{ type: 'html', html: scripts, ssr, method, - headers + headers, }); let page = await renderPage(result, Component, pageProps, null); - if(page.type === 'response') { + if (page.type === 'response') { return page; } @@ -130,9 +130,9 @@ export async function render(opts: RenderOptions): Promise<{ type: 'html', html: if (!legacyBuild && !/\n' + html; } - + return { type: 'html', - html + html, }; } diff --git a/packages/astro/src/core/render/dev/index.ts b/packages/astro/src/core/render/dev/index.ts index 3d92bf945..288ab97a0 100644 --- a/packages/astro/src/core/render/dev/index.ts +++ b/packages/astro/src/core/render/dev/index.ts @@ -41,9 +41,7 @@ export interface SSROptions { export type ComponentPreload = [Renderer[], 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/; @@ -186,7 +184,7 @@ export async function render(renderers: Renderer[], mod: ComponentInstance, ssrO return { type: 'html', - html + html, }; } diff --git a/packages/astro/src/core/render/request.ts b/packages/astro/src/core/render/request.ts index b969ec4d7..5956c7867 100644 --- a/packages/astro/src/core/render/request.ts +++ b/packages/astro/src/core/render/request.ts @@ -18,10 +18,9 @@ export interface AstroRequest { method: string; } -export type AstroRequestSSR = AstroRequest +export type AstroRequestSSR = AstroRequest; -export function createRequest(method: string, pathname: string, headers: Headers, - origin: string, site: Site, ssr: boolean): AstroRequest { +export function createRequest(method: string, pathname: string, headers: Headers, origin: string, site: Site, ssr: boolean): AstroRequest { const url = new URL('.' + pathname, new URL(origin)); const canonicalURL = utilCanonicalURL('.' + pathname, site ?? url.origin); @@ -31,10 +30,10 @@ export function createRequest(method: string, pathname: string, headers: Headers canonicalURL, params: {}, headers, - method + method, }; - if(!ssr) { + if (!ssr) { // Headers are only readable if using SSR-mode. If not, make it an empty headers // object, so you can't do something bad. request.headers = new Headers(); @@ -42,7 +41,7 @@ export function createRequest(method: string, pathname: string, headers: Headers // Disallow using query params. request.url = new URL(request.url); - for(const [key] of request.url.searchParams) { + for (const [key] of request.url.searchParams) { request.url.searchParams.delete(key); } } diff --git a/packages/astro/src/core/render/result.ts b/packages/astro/src/core/render/result.ts index 1086686cc..f43382bb3 100644 --- a/packages/astro/src/core/render/result.ts +++ b/packages/astro/src/core/render/result.ts @@ -9,9 +9,9 @@ import { renderSlot } from '../../runtime/server/index.js'; import { warn, LogOptions } from '../logger.js'; function onlyAvailableInSSR(name: string) { - return function() { + return function () { // TODO add more guidance when we have docs and adapters. - throw new Error(`Oops, you are trying to use ${name}, which is only available with SSR.`) + throw new Error(`Oops, you are trying to use ${name}, which is only available with SSR.`); }; } @@ -94,14 +94,16 @@ export function createResult(args: CreateResultArgs): SSRResult { __proto__: astroGlobal, props, request, - redirect: args.ssr ? (path: string) => { - return new Response(null, { - status: 301, - headers: { - Location: path - } - }); - } : onlyAvailableInSSR('Astro.redirect'), + redirect: args.ssr + ? (path: string) => { + return new Response(null, { + status: 301, + headers: { + Location: path, + }, + }); + } + : onlyAvailableInSSR('Astro.redirect'), resolve(path: string) { if (!legacyBuild) { let extra = `This can be replaced with a dynamic import like so: await import("${path}")`; diff --git a/packages/astro/src/runtime/server/index.ts b/packages/astro/src/runtime/server/index.ts index 14d9ce256..7d7088ad8 100644 --- a/packages/astro/src/runtime/server/index.ts +++ b/packages/astro/src/runtime/server/index.ts @@ -434,10 +434,9 @@ async function replaceHeadInjection(result: SSRResult, html: string): Promise { +export async function renderToString(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any): Promise { const Component = await componentFactory(result, props, children); - if(!isAstroComponent(Component)) { + if (!isAstroComponent(Component)) { throw new Error('Cannot return a Response from a nested component.'); } @@ -450,20 +449,20 @@ export async function renderPage( componentFactory: AstroComponentFactory, props: any, children: any -): Promise<{ type: 'html', html: string } | { type: 'response', response: Response }> { +): Promise<{ type: 'html'; html: string } | { type: 'response'; response: Response }> { const response = await componentFactory(result, props, children); - if(isAstroComponent(response)) { + if (isAstroComponent(response)) { let template = await renderAstroComponent(response); const html = await replaceHeadInjection(result, template); return { type: 'html', - html + html, }; } else { return { type: 'response', - response + response, }; } } diff --git a/packages/astro/src/vite-plugin-astro-server/index.ts b/packages/astro/src/vite-plugin-astro-server/index.ts index 32e6adf03..900216377 100644 --- a/packages/astro/src/vite-plugin-astro-server/index.ts +++ b/packages/astro/src/vite-plugin-astro-server/index.ts @@ -43,12 +43,12 @@ function writeHtmlResponse(res: http.ServerResponse, statusCode: number, html: s async function writeWebResponse(res: http.ServerResponse, webResponse: Response) { const { status, headers, body } = webResponse; res.writeHead(status, Object.fromEntries(headers.entries())); - if(body) { + if (body) { const reader = body.getReader(); - while(true) { + while (true) { const { done, value } = await reader.read(); - if(done) break; - if(value) { + if (done) break; + if (value) { res.write(value); } } @@ -57,7 +57,7 @@ async function writeWebResponse(res: http.ServerResponse, webResponse: Response) } async function writeSSRResult(result: RenderResponse, res: http.ServerResponse, statusCode: 200 | 404) { - if(result.type === 'response') { + if (result.type === 'response') { const { response } = result; await writeWebResponse(res, response); return; @@ -194,9 +194,9 @@ async function handleRequest( }; // Route successfully matched! Render it. - if(route.type === 'endpoint') { + if (route.type === 'endpoint') { const result = await callEndpoint(options); - if(result.type === 'response') { + if (result.type === 'response') { await writeWebResponse(res, result.response); } else { res.writeHead(200); diff --git a/packages/astro/src/vite-plugin-build-html/index.ts b/packages/astro/src/vite-plugin-build-html/index.ts index 3f67d9375..73051978a 100644 --- a/packages/astro/src/vite-plugin-build-html/index.ts +++ b/packages/astro/src/vite-plugin-build-html/index.ts @@ -97,7 +97,7 @@ export function rollupPluginAstroBuildHTML(options: PluginOptions): VitePlugin { viteServer, }); - if(response.type !== 'html') { + if (response.type !== 'html') { continue; }